Represents types that are generic containers of two elements.

This concept basically represents types that are like `std::pair`

. The motivation for making such a precise concept is similar to the motivation behind the `Sequence`

concept; there are many different implementations of `std::pair`

in different libraries, and we would like to manipulate any of them generically.

Since a `Product`

is basically a pair, it is unsurprising that the operations provided by this concept are getting the first and second element of a pair, creating a pair from two elements and other simmilar operations.

- Note
- Mathematically, this concept represents types that are category theoretical products. This is also where the name comes from.

`first`

, `second`

and `make`

`first`

and `second`

must obviously return the first and the second element of the pair, respectively. `make`

must take two arguments `x`

and `y`

representing the first and the second element of the pair, and return a pair `p`

such that `first(p) == x`

and `second(p) == y`

.

// Copyright Louis Dionne 2013-2016

// Distributed under the Boost Software License, Version 1.0.

// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

#include <boost/hana/first.hpp>

#include <boost/hana/pair.hpp>

#include <boost/hana/second.hpp>

namespace hana = boost::hana;

int main() { }

For a model `P`

of `Product`

, the following laws must be satisfied. For every data types `X`

and `Y`

, there must be a unique function \( \mathtt{make} : X \times Y \to P \) such that for every `x`

, `y`

,

- Note
- This law is less general than the universal property typically used to define category theoretical products, but it is vastly enough for what we need.

This is basically saying that a `Product`

must be the most general object able to contain a pair of objects `(P1, P2)`

, but nothing more. Since the categorical product is defined by a universal property, all the models of this concept are isomorphic, and the isomorphism is unique. In other words, there is one and only one way to convert one `Product`

to another.

Another property that must be satisfied by `first`

and `second`

is that of move-independence, which ensures that we can optimally decompose a `Product`

into its two members without making redundant copies.

`Comparable`

(free model)

Two products`x`

and`y`

are equal iff they are equal element-wise, by comparing the first element before the second element.// Copyright Louis Dionne 2013-2016// Distributed under the Boost Software License, Version 1.0.// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)#include <boost/hana/assert.hpp>#include <boost/hana/equal.hpp>#include <boost/hana/not_equal.hpp>#include <boost/hana/pair.hpp>#include <string>namespace hana = boost::hana;using namespace std::literals;int main() {static_assert(hana::make_pair('x', 2) != hana::make_pair('y', 2), "");}`Orderable`

(free model)

Products are ordered using a lexicographical ordering as-if they were 2-element tuples.`Foldable`

(free model)

Folding a`Product`

`p`

is equivalent to folding a list containing`first(p)`

and`second(p)`

, in that order.

## Variables | |

constexpr auto | boost::hana::first |

Returns the first element of a pair.Note that if the `Product` actually stores the elements it contains, `hana::first` is required to return a lvalue reference, a lvalue reference to const or a rvalue reference to the first element, where the type of reference must match that of the pair passed to `first` . If the `Product` does not store the elements it contains (i.e. it generates them on demand), this requirement is dropped. More... | |

constexpr auto | boost::hana::second |

Returns the second element of a pair.Note that if the `Product` actually stores the elements it contains, `hana::second` is required to return a lvalue reference, a lvalue reference to const or a rvalue reference to the second element, where the type of reference must match that of the pair passed to `second` . If the `Product` does not store the elements it contains (i.e. it generates them on demand), this requirement is dropped. More... | |

constexpr auto boost::hana::first |

`#include <boost/hana/fwd/first.hpp>`

return tag-dispatched;

}

constexpr auto product

Compute the product of the numbers of a structure.More generally, product will take any foldable stru...

Returns the first element of a pair.Note that if the `Product`

actually stores the elements it contains, `hana::first`

is required to return a lvalue reference, a lvalue reference to const or a rvalue reference to the first element, where the type of reference must match that of the pair passed to `first`

. If the `Product`

does not store the elements it contains (i.e. it generates them on demand), this requirement is dropped.

// Copyright Louis Dionne 2013-2016

// Distributed under the Boost Software License, Version 1.0.

// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

#include <boost/hana/first.hpp>

#include <boost/hana/pair.hpp>

namespace hana = boost::hana;

int main() { }

constexpr auto boost::hana::second |

`#include <boost/hana/fwd/second.hpp>`

return tag-dispatched;

}

constexpr auto product

Compute the product of the numbers of a structure.More generally, product will take any foldable stru...

Returns the second element of a pair.Note that if the `Product`

actually stores the elements it contains, `hana::second`

is required to return a lvalue reference, a lvalue reference to const or a rvalue reference to the second element, where the type of reference must match that of the pair passed to `second`

. If the `Product`

does not store the elements it contains (i.e. it generates them on demand), this requirement is dropped.

// Copyright Louis Dionne 2013-2016

// Distributed under the Boost Software License, Version 1.0.

// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

#include <boost/hana/second.hpp>

#include <boost/hana/pair.hpp>

namespace hana = boost::hana;

int main() { }