Boost.Hana  1.5.0
Your standard library for metaprogramming
Product

Description

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.

Minimal complete definition

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-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
static_assert(hana::first(hana::make<hana::pair_tag>(1, 'x')) == 1, "");
static_assert(hana::second(hana::make<hana::pair_tag>(1, 'x')) == 'x', "");
int main() { }

Laws

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,

x == first(make<P>(x, y))
y == second(make<P>(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.

Refined concepts

  1. 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-2017
    // 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 <string>
    namespace hana = boost::hana;
    using namespace std::literals;
    int main() {
    BOOST_HANA_RUNTIME_CHECK(hana::make_pair(1, "234"s) == hana::make_pair(1ll, "234"s));
    static_assert(hana::make_pair('x', 2) != hana::make_pair('y', 2), "");
    }
  2. Orderable (free model)
    Products are ordered using a lexicographical ordering as-if they were 2-element tuples.
  3. Foldable (free model)
    Folding a Product p is equivalent to folding a list containing first(p) and second(p), in that order.

Concrete models

hana::pair

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...
 

Variable Documentation

constexpr auto boost::hana::first

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

Initial value:
= [](auto&& product) -> decltype(auto) {
return tag-dispatched;
}
constexpr auto product
Compute the product of the numbers of a structure.More generally, product will take any foldable stru...
Definition: product.hpp:57

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.

Example

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
static_assert(hana::first(hana::make_pair(1, 'x')) == 1, "");
int main() { }
constexpr auto boost::hana::second

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

Initial value:
= [](auto&& product) -> decltype(auto) {
return tag-dispatched;
}
constexpr auto product
Compute the product of the numbers of a structure.More generally, product will take any foldable stru...
Definition: product.hpp:57

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.

Example

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
static_assert(hana::second(hana::make_pair(1, 'x')) == 'x', "");
int main() { }