diff options
Diffstat (limited to 'boost/hana/fwd/concept/product.hpp')
-rw-r--r-- | boost/hana/fwd/concept/product.hpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/boost/hana/fwd/concept/product.hpp b/boost/hana/fwd/concept/product.hpp new file mode 100644 index 0000000000..f3b2feb705 --- /dev/null +++ b/boost/hana/fwd/concept/product.hpp @@ -0,0 +1,103 @@ +/*! +@file +Forward declares `boost::hana::Product`. + +@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) + */ + +#ifndef BOOST_HANA_FWD_CONCEPT_PRODUCT_HPP +#define BOOST_HANA_FWD_CONCEPT_PRODUCT_HPP + +#include <boost/hana/config.hpp> + + +BOOST_HANA_NAMESPACE_BEGIN + //! @ingroup group-concepts + //! @defgroup group-Product Product + //! 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][1]. 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`. + //! @include example/product/make.cpp + //! + //! + //! 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 + //! @f$ \mathtt{make} : X \times Y \to P @f$ such that for every `x`, `y`, + //! @code + //! x == first(make<P>(x, y)) + //! y == second(make<P>(x, y)) + //! @endcode + //! + //! @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 @ref 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)\n + //! Two products `x` and `y` are equal iff they are equal element-wise, + //! by comparing the first element before the second element. + //! @include example/product/comparable.cpp + //! + //! 2. `Orderable` (free model)\n + //! Products are ordered using a lexicographical ordering as-if they + //! were 2-element tuples. + //! + //! 3. `Foldable` (free model)\n + //! Folding a `Product` `p` is equivalent to folding a list containing + //! `first(p)` and `second(p)`, in that order. + //! + //! + //! Concrete models + //! --------------- + //! `hana::pair` + //! + //! + //! [1]: http://en.wikipedia.org/wiki/Product_(category_theory) + template <typename P> + struct Product; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_FWD_CONCEPT_PRODUCT_HPP |