diff --git a/boost_1_63_0/libs/hana/doc/html/Boost.png b/boost_1_63_0/libs/hana/doc/html/Boost.png new file mode 100644 index 0000000..b4d51fc Binary files /dev/null and b/boost_1_63_0/libs/hana/doc/html/Boost.png differ diff --git a/boost_1_63_0/libs/hana/doc/html/accessors_8hpp.html b/boost_1_63_0/libs/hana/doc/html/accessors_8hpp.html new file mode 100644 index 0000000..b03ea9b --- /dev/null +++ b/boost_1_63_0/libs/hana/doc/html/accessors_8hpp.html @@ -0,0 +1,161 @@ + + + + + +
+ + + +Defines boost::hana::accessors.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::accessors.
Defines the BOOST_HANA_ADAPT_ADT macro.
+More...
Defines the BOOST_HANA_ADAPT_ADT macro.
Defines the BOOST_HANA_ADAPT_STRUCT macro.
+More...
Defines the BOOST_HANA_ADAPT_STRUCT macro.
Defines boost::hana::adjust.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::adjust.
Defines boost::hana::adjust_if.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::adjust_if.
Defines boost::hana::detail::operators::adl.
+More...
+Classes | |
| struct | boost::hana::detail::operators::adl<... > |
Enables ADL in the hana::detail::operators namespace. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::operators::adl.
Defines several constexpr algorithms.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines several constexpr algorithms.
Defines boost::hana::all.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::all.
Defines boost::hana::all_of.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::all_of.
Defines boost::hana::always.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::always |
Return a constant function returning x regardless of the argument(s) it is invoked with. More... | |
Defines boost::hana::always.
Defines boost::hana::and_.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::and_.
| ▼Nboost | |
| ▼Nfusion | |
| Cdeque | Adapter for Boost.Fusion deques |
| Clist | Adapter for Boost.Fusion lists |
| Ctuple | Adapter for Boost.Fusion tuples |
| Cvector | Adapter for Boost.Fusion vectors |
| ▼Nhana | Namespace containing everything in the library |
| ▼Nat_key_detail | |
| Cadvance_until | |
| ▼Nconstant_detail | |
| Cwhich | |
| ▼Ndetail | |
| ▼Noperators | |
| Cadl | Enables ADL in the hana::detail::operators namespace |
| Cany_of | Returns whether the Predicate is satisfied by any of the T... |
| Carray | A minimal std::array with better constexpr support |
| CCanonicalConstant | Tag representing a canonical Constant |
| Ccreate | Implementation of the generic std::make_xxx pattern for arbitrary xxxs |
| Cdecay | Equivalent to std::decay, except faster |
| Cfirst_unsatisfied_index | Returns the index of the first element which does not satisfy Pred, or sizeof...(Xs) if no such element exists |
| Chas_duplicates | Returns whether any of the Ts are duplicate w.r.t. hana::equal |
| Cindex_if | Returns the index of the first element of the pack<> that satisfies the predicate, or the size of the pack if there is no such element |
| Cnested_by | Provides a .by static constexpr function object |
| Cnested_than | Provides a .than static constexpr function object |
| Cnested_to | Provides a .to static constexpr function object |
| Cstd_common_type | Equivalent to std::common_type, except it is SFINAE-friendly and does not support custom specializations |
| Ctype_at | Classic MPL-style metafunction returning the nth element of a type parameter pack |
| Cwrong | Equivalent to a type-dependent std::false_type |
| ▼Nexperimental | |
| Ctypes | Container optimized for holding types |
| Cbasic_tuple | Stripped down version of hana::tuple |
| Cbasic_tuple_tag | Tag representing hana::basic_tuple |
| Cbasic_type | Base class of hana::type; used for pattern-matching |
| Ccommon | Metafunction returning the common data type between two data types |
| Cdefault_ | Mark a tag-dispatched method implementation as a default implementation |
| Cembedding | Marks a conversion between data types as being an embedding |
| Chas_common | Metafunction returning whether two data types share a common data type |
| Cintegral_constant | Compile-time value of an integral type |
| Cintegral_constant_tag | Tag representing hana::integral_constant |
| CIntegralConstant | The IntegralConstant concept represents compile-time integral values |
| Cis_convertible | Returns whether there is a Hana-conversion from a data type to another |
| Cis_default | Returns whether a tag-dispatched method implementation is a default implementation |
| Cis_embedded | Returns whether a data type can be embedded into another data type |
| Clazy | hana::lazy implements superficial laziness via a monadic interface |
| Clazy_tag | Tag representing hana::lazy |
| Cmap | Basic associative container requiring unique, Comparable and Hashable keys |
| Cmap_tag | Tag representing hana::maps |
| Coptional | Optional value whose optional-ness is known at compile-time |
| Coptional_tag | Tag representing a hana::optional |
| Cpair | Generic container for two elements |
| Cpair_tag | Tag representing hana::pair |
| Crange | Compile-time half-open interval of hana::integral_constants |
| Crange_tag | Tag representing a hana::range |
| Cset | Basic unordered container requiring unique, Comparable and Hashable keys |
| Cset_tag | Tag representing the hana::set container |
| Cstring | Compile-time string |
| Cstring_tag | Tag representing a compile-time string |
| Ctag_of | Metafunction returning the tag associated to T |
| Ctuple | General purpose index-based heterogeneous sequence with a fixed length |
| Ctuple_tag | Tag representing hana::tuples |
| Ctype | C++ type in value-level representation |
| Ctype_tag | Tag representing hana::type |
| Cwhen | Enable a partial specialization only if a boolean condition is true |
| ▼Nmpl | |
| Cintegral_c | Adapter for IntegralConstants from the Boost.MPL |
| Clist | Adapter for Boost.MPL lists |
| Cvector | Adapter for Boost.MPL vectors |
| Ctuple | Adapter for boost::tuples |
| ▼Nstd | |
| Carray | Adaptation of std::array for Hana |
| Cinteger_sequence | Adaptation of std::integer_sequence for Hana |
| Cintegral_constant | Adapter for std::integral_constants |
| Cpair | Adaptation of std::pair for Hana |
| Cratio | Adaptation of std::ratio for Hana |
| Ctuple | Adapter for std::tuples |
Defines boost::hana::any.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::any.
Defines boost::hana::any_of.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::any_of.
Defines boost::hana::ap.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::ap.
Defines boost::hana::append.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::append.
Defines boost::hana::apply.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::apply |
| Invokes a Callable with the given arguments. More... | |
Defines boost::hana::apply.
Defines boost::hana::arg.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<std::size_t n> | |
| constexpr auto | boost::hana::arg |
Return the nth passed argument. More... | |
Defines boost::hana::arg.
Defines arithmetic operators. +More...
++Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines arithmetic operators.
+Defines macros to perform different kinds of assertions. +More...
++Macros | |
| #define | BOOST_HANA_RUNTIME_ASSERT(condition) unspecified |
| Expands to a runtime assertion. More... | |
| #define | BOOST_HANA_RUNTIME_ASSERT_MSG(condition, message) unspecified |
Equivalent to BOOST_HANA_RUNTIME_ASSERT, but allows providing a custom failure message. More... | |
| #define | BOOST_HANA_CONSTANT_ASSERT(condition) unspecified |
Compile-time assertion for Constants. More... | |
| #define | BOOST_HANA_CONSTANT_ASSERT_MSG(condition, message) unspecified |
Equivalent to BOOST_HANA_CONSTANT_ASSERT, but allows providing a custom failure message. More... | |
| #define | BOOST_HANA_ASSERT(condition) unspecified |
| Expands to the strongest form of assertion possible for the given condition. More... | |
| #define | BOOST_HANA_ASSERT_MSG(condition, message) unspecified |
Equivalent to BOOST_HANA_ASSERT, but allows providing a custom failure message. More... | |
| #define | BOOST_HANA_CONSTEXPR_ASSERT(condition) unspecified |
Expands to a static assertion or a runtime assertion, depending on whether constexpr lambdas are supported. More... | |
| +#define | BOOST_HANA_CONSTEXPR_ASSERT_MSG(condition, message) unspecified |
Equivalent to BOOST_HANA_CONSTEXPR_ASSERT, but allows providing a custom failure message. | |
| +#define | BOOST_HANA_RUNTIME_CHECK_MSG(condition, message) |
Equivalent to BOOST_HANA_RUNTIME_ASSERT_MSG, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
| +#define | BOOST_HANA_RUNTIME_CHECK(...) |
Equivalent to BOOST_HANA_RUNTIME_ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
| +#define | BOOST_HANA_CONSTANT_CHECK_MSG(condition, message) |
Equivalent to BOOST_HANA_CONSTANT_ASSERT_MSG, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
| +#define | BOOST_HANA_CONSTANT_CHECK(...) |
Equivalent to BOOST_HANA_CONSTANT_ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
| +#define | BOOST_HANA_CHECK_MSG(condition, message) |
Equivalent to BOOST_HANA_ASSERT_MSG, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
| +#define | BOOST_HANA_CHECK(...) |
Equivalent to BOOST_HANA__ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
| +#define | BOOST_HANA_CONSTEXPR_CHECK_MSG(condition, message) BOOST_HANA_RUNTIME_CHECK_MSG(condition, message) \ |
Equivalent to BOOST_HANA_CONSTEXPR_ASSERT_MSG, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
| +#define | BOOST_HANA_CONSTEXPR_CHECK(...) |
Equivalent to BOOST_HANA_CONSTEXPR_ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
Defines macros to perform different kinds of assertions.
+Defines boost::hana::at and boost::hana::at_c.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::at and boost::hana::at_c.
Defines boost::hana::at_key.
+More...
+Classes | |
| struct | boost::hana::at_key_detail::advance_until< Xs, Pred, i, N, Done > |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::at_key.
Defines boost::hana::back.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::back.
Defines boost::hana::basic_tuple.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::basic_tuple.
Defines the Logical and Comparable models of boost::hana::integral_constant.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
| boost::hana::literals | |
| Namespace containing C++14 user-defined literals provided by Hana. | |
+Functions | |
| template<char... c> | |
| constexpr auto | boost::hana::literals::operator""_c () |
Creates a hana::integral_constant from a literal. More... | |
Defines the Logical and Comparable models of boost::hana::integral_constant.
Adapts boost::fusion::vector for use with Hana.
+More...
+Classes | |
| struct | boost::fusion::vector< T > |
| Adapter for Boost.Fusion vectors. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Adapts boost::fusion::vector for use with Hana.
Adapts boost::mpl::vector for use with Hana.
+More...
+Classes | |
| struct | boost::mpl::vector< T > |
| Adapter for Boost.MPL vectors. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Adapts boost::mpl::vector for use with Hana.
Includes all the adaptors for external Boost libraries. +More...
+Includes all the adaptors for external Boost libraries.
+when_valid seems to trigger ambiguous partial specializations on GCC. Defines boost::hana::detail::CanonicalConstant.
+More...
+Classes | |
| struct | boost::hana::detail::CanonicalConstant< T > |
Tag representing a canonical Constant. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::CanonicalConstant.
Defines boost::hana::capture.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::capture |
| Create a function capturing the given variables. More... | |
Defines boost::hana::capture.
Defines boost::hana::cartesian_product.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::cartesian_product.
Defines boost::hana::chain.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::chain.
| |
| CanonicalConstant (boost::hana::detail) | |
| |
| IntegralConstant (boost::hana) | |
| |
| advance_until (boost::hana::at_key_detail) | |
| any_of (boost::hana::detail) | |
| array (boost::hana::detail) | |
| adl (boost::hana::detail::operators) | |
| array (std) | |
| |
| basic_tuple (boost::hana) | |
| basic_tuple_tag (boost::hana) | |
| basic_type (boost::hana) | |
| |
| common (boost::hana) | |
| create (boost::hana::detail) | |
| |
| deque (boost::fusion) | |
| default_ (boost::hana) | |
| decay (boost::hana::detail) | |
| |
| embedding (boost::hana) | |
| |
| first_unsatisfied_index (boost::hana::detail) | |
| |
| has_duplicates (boost::hana::detail) | |
| has_common (boost::hana) | |
| |
| index_if (boost::hana::detail) | |
| integral_constant (boost::hana) | |
| integral_constant_tag (boost::hana) | |
| is_convertible (boost::hana) | |
| is_default (boost::hana) | |
| is_embedded (boost::hana) | |
| integral_c (boost::mpl) | |
| integer_sequence (std) | |
| integral_constant (std) | |
| |
| list (boost::fusion) | |
| lazy (boost::hana) | |
| lazy_tag (boost::hana) | |
| list (boost::mpl) | |
| |
| map (boost::hana) | |
| map_tag (boost::hana) | |
| |
| nested_by (boost::hana::detail) | |
| nested_than (boost::hana::detail) | |
| nested_to (boost::hana::detail) | |
| |
| optional (boost::hana) | |
| optional_tag (boost::hana) | |
| |
| pair (boost::hana) | |
| pair_tag (boost::hana) | |
| pair (std) | |
| |
| range (boost::hana) | |
| range_tag (boost::hana) | |
| ratio (std) | |
| |
| std_common_type (boost::hana::detail) | |
| set (boost::hana) | |
| set_tag (boost::hana) | |
| string (boost::hana) | |
| string_tag (boost::hana) | |
| |
| tuple (boost::fusion) | |
| type_at (boost::hana::detail) | |
| types (boost::hana::experimental) | |
| tag_of (boost::hana) | |
| tuple (boost::hana) | |
| tuple_tag (boost::hana) | |
| type (boost::hana) | |
| type_tag (boost::hana) | |
| tuple (boost) | |
| tuple (std) | |
| |
| vector (boost::fusion) | |
| vector (boost::mpl) | |
| |
| which (boost::hana::constant_detail) | |
Adaptation of std::ratio for Hana.
Comparablestd::ratios are compared for equality using std::ratio_equal. Orderablestd::ratios are ordered using std::ratio_less. Monoid, Group, Ring, and EuclideanRingstd::ratios are added, subtracted, multiplied and divided using std::ratio_add, std::ratio_subtract, std::ratio_multiply and std::ratio_divide, respectively. Furthermore, the neutral element for the additive operation is std::ratio<0, 1>{}, and the neutral element for the multiplicative operation is std::ratio<1, 1>{}. Defines boost::hana::comparing.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::comparing.
Defines boost::hana::compose.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::compose |
| Return the composition of two functions or more. More... | |
Defines boost::hana::compose.
Defines boost::hana::concat.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::concat.
Defines boost::hana::Applicative.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Applicative.
Defines boost::hana::Comonad.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Comonad.
Defines boost::hana::Comparable.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Comparable.
Defines boost::hana::Constant.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Constant.
Defines boost::hana::EuclideanRing.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::EuclideanRing.
Defines boost::hana::Foldable.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Foldable.
Defines boost::hana::Functor.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Functor.
Defines boost::hana::Group.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Group.
Defines boost::hana::Hashable.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Hashable.
Defines boost::hana::IntegralConstant.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::IntegralConstant.
Defines boost::hana::Iterable.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Iterable.
Defines boost::hana::Logical.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Logical.
Defines boost::hana::Metafunction.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Metafunction.
Defines boost::hana::Monad.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Monad.
Defines boost::hana::MonadPlus.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::MonadPlus.
Defines boost::hana::Monoid.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Monoid.
Defines boost::hana::Orderable.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Orderable.
Defines boost::hana::Product.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Product.
Defines boost::hana::Ring.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Ring.
Defines boost::hana::Searchable.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Searchable.
Defines boost::hana::Sequence.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Sequence.
Defines boost::hana::Struct.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::Struct.
Master header for the boost/hana/concept/ subdirectory.
+More...
Master header for the boost/hana/concept/ subdirectory.
Defines concepts from the Standard library. +More...
++Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines concepts from the Standard library.
+Defines configuration macros used throughout the library. +More...
++Macros | |
| #define | BOOST_HANA_CONFIG_DISABLE_ASSERTIONS |
Disables the BOOST_HANA_*_ASSERT macro & friends. More... | |
| #define | BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS |
| Disables concept checks in interface methods. More... | |
| #define | BOOST_HANA_CONFIG_ENABLE_STRING_UDL |
| Enables usage of the "string literal operator template" GNU extension. More... | |
| #define | BOOST_HANA_CONFIG_ENABLE_DEBUG_MODE |
| Enables additional assertions and sanity checks to be done by Hana. More... | |
Defines configuration macros used throughout the library.
+Defines boost::hana::contains and boost::hana::in.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::contains and boost::hana::in.
Defines boost::hana::common and boost::hana::common_t.
+More...
+Classes | |
| struct | boost::hana::has_common< T, U, typename > |
| Metafunction returning whether two data types share a common data type. More... | |
| struct | boost::hana::constant_detail::which< A, B, C > |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::common and boost::hana::common_t.
Defines boost::hana::default_ and boost::hana::is_default.
+More...
+Classes | |
| struct | boost::hana::is_default< Method, typename > |
| Returns whether a tag-dispatched method implementation is a default implementation. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::default_ and boost::hana::is_default.
Defines boost::hana::is_a and boost::hana::is_an.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::is_a and boost::hana::is_an.
Defines boost::hana::make.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::make.
Defines boost::hana::tag_of and boost::hana::tag_of_t.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::tag_of and boost::hana::tag_of_t.
Defines boost::hana::to and related utilities.
+More...
+Classes | |
| struct | boost::hana::is_convertible< From, To, typename > |
| Returns whether there is a Hana-conversion from a data type to another. More... | |
| struct | boost::hana::is_embedded< From, To, typename > |
| Returns whether a data type can be embedded into another data type. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::to and related utilities.
Defines boost::hana::when and boost::hana::when_valid.
+More...
Defines boost::hana::when and boost::hana::when_valid.
Defines the Core module. +More...
+Defines the Core module.
+Defines boost::hana::count.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::count.
Defines boost::hana::count_if.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::count_if.
Defines boost::hana::detail::create.
+More...
+Classes | |
| struct | boost::hana::detail::create< T > |
Implementation of the generic std::make_xxx pattern for arbitrary xxxs. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::create.
Defines boost::hana::curry.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<std::size_t n> | |
| constexpr auto | boost::hana::curry |
| Curry a function up to the given number of arguments. More... | |
Defines boost::hana::curry.
Defines boost::hana::cycle.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::cycle.
Defines a replacement for std::decay, which is sometimes too slow at compile-time.
+More...
+Classes | |
| struct | boost::hana::detail::decay< T, U > |
Equivalent to std::decay, except faster. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines a replacement for std::decay, which is sometimes too slow at compile-time.
Defines the BOOST_HANA_DEFINE_STRUCT macro.
+More...
Defines the BOOST_HANA_DEFINE_STRUCT macro.
Defines boost::hana::demux.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::demux |
| Invoke a function with the results of invoking other functions on its arguments. More... | |
Defines boost::hana::demux.
Defines boost::hana::detail::dependent_on.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::dependent_on.
decltype_ can be confusing, and hana::typeid_ should be preferred instead. decltype_ may be removed in the next major version of the library.Adapts boost::fusion::deque for use with Hana.
+More...
+Classes | |
| struct | boost::fusion::deque< T > |
| Adapter for Boost.Fusion deques. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Adapts boost::fusion::deque for use with Hana.
Defines boost::hana::detail::any_of.
+More...
+Classes | |
| struct | boost::hana::detail::any_of< Predicate, T > |
Returns whether the Predicate is satisfied by any of the T.... More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::any_of.
Defines boost::hana::detail::array.
+More...
+Classes | |
| struct | boost::hana::detail::array< T, Size > |
A minimal std::array with better constexpr support. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::array.
Defines the barebones boost::hana::integral_constant template, but no operations on it.
+More...
+Classes | |
| struct | boost::hana::integral_constant_tag< T > |
Tag representing hana::integral_constant. More... | |
| struct | boost::hana::integral_constant< T, v > |
| Compile-time value of an integral type. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines the barebones boost::hana::integral_constant template, but no operations on it.
Defines operators for Comparables. +More...
++Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines operators for Comparables.
+Defines operators for Iterables. +More...
++Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines operators for Iterables.
+Defines logical operators. +More...
++Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines logical operators.
+Defines operators for Monads. +More...
++Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines operators for Monads.
+Defines operators for Orderables. +More...
++Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines operators for Orderables.
+Defines operators for Searchables. +More...
++Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines operators for Searchables.
+Defines boost::hana::detail::variadic::at.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::variadic::at.
Defines boost::hana::difference.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::difference.
+Directories |
+Files | |
| file | algorithm.hpp |
Defines several constexpr algorithms. | |
| file | any_of.hpp |
Defines boost::hana::detail::any_of. | |
| file | array.hpp |
Defines boost::hana::detail::array. | |
| file | canonical_constant.hpp |
Defines boost::hana::detail::CanonicalConstant. | |
| file | concepts.hpp |
| Defines concepts from the Standard library. | |
| file | create.hpp |
Defines boost::hana::detail::create. | |
| file | decay.hpp |
Defines a replacement for std::decay, which is sometimes too slow at compile-time. | |
| file | dependent_on.hpp |
Defines boost::hana::detail::dependent_on. | |
| file | dispatch_if.hpp |
Defines BOOST_HANA_DISPATCH_IF. | |
| file | fast_and.hpp |
Defines boost::hana::detail::fast_and. | |
| file | first_unsatisfied_index.hpp |
Defines boost::hana::detail::first_unsatisfied_index. | |
| file | has_common_embedding.hpp |
Defines boost::hana::detail::has_[nontrivial_]common_embedding. | |
| file | has_duplicates.hpp |
Defines boost::hana::detail::has_duplicates. | |
| file | hash_table.hpp |
Defines boost::hana::detail::hash_table. | |
| file | index_if.hpp |
Defines boost::hana::detail::index_if. | |
| file | integral_constant.hpp |
Defines the barebones boost::hana::integral_constant template, but no operations on it. | |
| file | intrinsics.hpp |
| Defines macros for commonly used type traits. | |
| file | nested_by.hpp |
Defines boost::hana::detail::nested_by. | |
| file | nested_by_fwd.hpp |
Forward declares boost::hana::detail::nested_by. | |
| file | nested_than.hpp |
Defines boost::hana::detail::nested_than. | |
| file | nested_than_fwd.hpp |
Forward declares boost::hana::detail::nested_than. | |
| file | nested_to.hpp |
Defines boost::hana::detail::nested_to. | |
| file | nested_to_fwd.hpp |
Forward declares boost::hana::detail::nested_to. | |
| file | preprocessor.hpp |
| Defines generally useful preprocessor macros. | |
| file | std_common_type.hpp |
Defines a SFINAE-friendly version of std::common_type. | |
| file | struct_macros.hpp |
Defines the BOOST_HANA_DEFINE_STRUCT, BOOST_HANA_ADAPT_STRUCT, and BOOST_HANA_ADAPT_ADT macros. | |
| file | type_at.hpp |
Defines boost::hana::detail::type_at. | |
| file | type_foldl1.hpp |
Defines boost::hana::detail::type_foldl1. | |
| file | type_foldr1.hpp |
Defines boost::hana::detail::type_foldr1. | |
| file | unpack_flatten.hpp |
Defines boost::hana::detail::unpack_flatten. | |
| file | void_t.hpp |
Defines an equivalent to the proposed std::void_t. | |
| file | wrong.hpp |
Defines boost::hana::detail::wrong. | |
+Files | |
| file | adl.hpp |
Defines boost::hana::detail::operators::adl. | |
| file | arithmetic.hpp |
| Defines arithmetic operators. | |
| file | comparable.hpp |
| Defines operators for Comparables. | |
| file | iterable.hpp |
| Defines operators for Iterables. | |
| file | logical.hpp |
| Defines logical operators. | |
| file | monad.hpp |
| Defines operators for Monads. | |
| file | orderable.hpp |
| Defines operators for Orderables. | |
| file | searchable.hpp |
| Defines operators for Searchables. | |
+Directories |
+Files | |
| file | hana.hpp |
| Includes all the library components except the adapters for external libraries. | |
+Files | |
| file | types.hpp |
Defines boost::hana::experimental::types. | |
+Directories |
+Files | |
| file | at.hpp |
Defines boost::hana::detail::variadic::at. | |
| file | drop_into.hpp |
Defines boost::hana::detail::variadic::drop_into. | |
| file | foldl1.hpp |
Defines boost::hana::detail::variadic::foldl1. | |
| file | foldr1.hpp |
Defines boost::hana::detail::variadic::foldr1. | |
| file | reverse_apply.hpp |
Defines boost::hana::detail::variadic::reverse_apply. | |
| file | split_at.hpp |
Defines boost::hana::detail::variadic::split_at. | |
| file | take.hpp |
Defines boost::hana::detail::variadic::take. | |
+Files | |
| file | common.hpp |
Defines boost::hana::common and boost::hana::common_t. | |
| file | default.hpp |
Defines boost::hana::default_ and boost::hana::is_default. | |
| file | dispatch.hpp |
| Includes all the headers needed to setup tag-dispatching. | |
| file | is_a.hpp |
Defines boost::hana::is_a and boost::hana::is_an. | |
| file | make.hpp |
Defines boost::hana::make. | |
| file | tag_of.hpp |
Defines boost::hana::tag_of and boost::hana::tag_of_t. | |
| file | to.hpp |
Defines boost::hana::to and related utilities. | |
| file | when.hpp |
Defines boost::hana::when and boost::hana::when_valid. | |
+Directories |
+Files | |
| file | deque.hpp |
Adapts boost::fusion::deque for use with Hana. | |
| file | list.hpp |
Adapts boost::fusion::list for use with Hana. | |
| file | tuple.hpp |
Adapts boost::fusion::tuple for use with Hana. | |
| file | vector.hpp |
Adapts boost::fusion::vector for use with Hana. | |
+Files | |
| file | common.hpp |
| Defines common methods for all Boost.Fusion sequences. | |
+Directories |
+Files | |
| file | fusion.hpp |
| Includes all the adaptors for the Boost.Fusion library. | |
| file | mpl.hpp |
| Includes all the adaptors for the Boost.MPL library. | |
| file | tuple.hpp |
Adapts boost::tuple for use with Hana. | |
+Files | |
| file | applicative.hpp |
Forward declares boost::hana::Applicative. | |
| file | comonad.hpp |
Forward declares boost::hana::Comonad. | |
| file | comparable.hpp |
Forward declares boost::hana::Comparable. | |
| file | constant.hpp |
Forward declares boost::hana::Constant. | |
| file | euclidean_ring.hpp |
Forward declares boost::hana::EuclideanRing. | |
| file | foldable.hpp |
Forward declares boost::hana::Foldable. | |
| file | functor.hpp |
Forward declares boost::hana::Functor. | |
| file | group.hpp |
Forward declares boost::hana::Group. | |
| file | hashable.hpp |
Forward declares boost::hana::Hashable. | |
| file | integral_constant.hpp |
Forward declares boost::hana::IntegralConstant. | |
| file | iterable.hpp |
Forward declares boost::hana::Iterable. | |
| file | logical.hpp |
Forward declares boost::hana::Logical. | |
| file | metafunction.hpp |
Forward declares boost::hana::Metafunction. | |
| file | monad.hpp |
Forward declares boost::hana::Monad. | |
| file | monad_plus.hpp |
Forward declares boost::hana::MonadPlus. | |
| file | monoid.hpp |
Forward declares boost::hana::Monoid. | |
| file | orderable.hpp |
Forward declares boost::hana::Orderable. | |
| file | product.hpp |
Forward declares boost::hana::Product. | |
| file | ring.hpp |
Forward declares boost::hana::Ring. | |
| file | searchable.hpp |
Forward declares boost::hana::Searchable. | |
| file | sequence.hpp |
Forward declares boost::hana::Sequence. | |
| file | struct.hpp |
Forward declares boost::hana::Struct. | |
+Files | |
| file | applicative.hpp |
Defines boost::hana::Applicative. | |
| file | comonad.hpp |
Defines boost::hana::Comonad. | |
| file | comparable.hpp |
Defines boost::hana::Comparable. | |
| file | constant.hpp |
Defines boost::hana::Constant. | |
| file | euclidean_ring.hpp |
Defines boost::hana::EuclideanRing. | |
| file | foldable.hpp |
Defines boost::hana::Foldable. | |
| file | functor.hpp |
Defines boost::hana::Functor. | |
| file | group.hpp |
Defines boost::hana::Group. | |
| file | hashable.hpp |
Defines boost::hana::Hashable. | |
| file | integral_constant.hpp |
Defines boost::hana::IntegralConstant. | |
| file | iterable.hpp |
Defines boost::hana::Iterable. | |
| file | logical.hpp |
Defines boost::hana::Logical. | |
| file | metafunction.hpp |
Defines boost::hana::Metafunction. | |
| file | monad.hpp |
Defines boost::hana::Monad. | |
| file | monad_plus.hpp |
Defines boost::hana::MonadPlus. | |
| file | monoid.hpp |
Defines boost::hana::Monoid. | |
| file | orderable.hpp |
Defines boost::hana::Orderable. | |
| file | product.hpp |
Defines boost::hana::Product. | |
| file | ring.hpp |
Defines boost::hana::Ring. | |
| file | searchable.hpp |
Defines boost::hana::Searchable. | |
| file | sequence.hpp |
Defines boost::hana::Sequence. | |
| file | struct.hpp |
Defines boost::hana::Struct. | |
+Files | |
| file | integral_c.hpp |
| Adapts Boost.MPL IntegralConstants for use with Hana. | |
| file | list.hpp |
Adapts boost::mpl::list for use with Hana. | |
| file | vector.hpp |
Adapts boost::mpl::vector for use with Hana. | |
+Files | |
| file | common.hpp |
Forward declares boost::hana::common and boost::hana::common_t. | |
| file | default.hpp |
Forward declares boost::hana::default_ and boost::hana::is_default. | |
| file | is_a.hpp |
Forward declares boost::hana::is_a and boost::hana::is_an. | |
| file | make.hpp |
Forward declares boost::hana::make. | |
| file | tag_of.hpp |
Forward declares boost::hana::tag_of and boost::hana::tag_of_t. | |
| file | to.hpp |
Forward declares boost::hana::to and related utilities. | |
| file | when.hpp |
Forward declares boost::hana::when and boost::hana::when_valid. | |
+Directories |
+Files | |
| file | accessors.hpp |
Forward declares boost::hana::accessors. | |
| file | adapt_adt.hpp |
Documents the BOOST_HANA_ADAPT_ADT macro. | |
| file | adapt_struct.hpp |
Documents the BOOST_HANA_ADAPT_STRUCT macro. | |
| file | adjust.hpp |
Forward declares boost::hana::adjust. | |
| file | adjust_if.hpp |
Forward declares boost::hana::adjust_if. | |
| file | all.hpp |
Forward declares boost::hana::all. | |
| file | all_of.hpp |
Forward declares boost::hana::all_of. | |
| file | and.hpp |
Forward declares boost::hana::and_. | |
| file | any.hpp |
Forward declares boost::hana::any. | |
| file | any_of.hpp |
Forward declares boost::hana::any_of. | |
| file | ap.hpp |
Forward declares boost::hana::ap. | |
| file | append.hpp |
Forward declares boost::hana::append. | |
| file | at.hpp |
Forward declares boost::hana::at and boost::hana::at_c. | |
| file | at_key.hpp |
Forward declares boost::hana::at_key. | |
| file | back.hpp |
Forward declares boost::hana::back. | |
| file | basic_tuple.hpp |
Forward declares boost::hana::basic_tuple. | |
| file | bool.hpp |
| Includes boost/hana/fwd/integral_constant.hpp. | |
| file | cartesian_product.hpp |
Forward declares boost::hana::cartesian_product. | |
| file | chain.hpp |
Forward declares boost::hana::chain. | |
| file | comparing.hpp |
Forward declares boost::hana::comparing. | |
| file | concat.hpp |
Forward declares boost::hana::concat. | |
| file | contains.hpp |
Forward declares boost::hana::contains and boost::hana::in. | |
| file | core.hpp |
| Forward declares the Core module. | |
| file | count.hpp |
Forward declares boost::hana::count. | |
| file | count_if.hpp |
Forward declares boost::hana::count_if. | |
| file | cycle.hpp |
Forward declares boost::hana::cycle. | |
| file | define_struct.hpp |
Documents the BOOST_HANA_DEFINE_STRUCT macro. | |
| file | difference.hpp |
Forward declares boost::hana::difference. | |
| file | div.hpp |
Forward declares boost::hana::div. | |
| file | drop_back.hpp |
Forward declares boost::hana::drop_back. | |
| file | drop_front.hpp |
Forward declares boost::hana::drop_front. | |
| file | drop_front_exactly.hpp |
Forward declares boost::hana::drop_front_exactly. | |
| file | drop_while.hpp |
Forward declares boost::hana::drop_while. | |
| file | duplicate.hpp |
Forward declares boost::hana::duplicate. | |
| file | empty.hpp |
Forward declares boost::hana::empty. | |
| file | equal.hpp |
Forward declares boost::hana::equal. | |
| file | erase_key.hpp |
Forward declares boost::hana::erase_key. | |
| file | eval.hpp |
Forward declares boost::hana::eval. | |
| file | eval_if.hpp |
Forward declares boost::hana::eval_if. | |
| file | extend.hpp |
Forward declares boost::hana::extend. | |
| file | extract.hpp |
Forward declares boost::hana::extract. | |
| file | fill.hpp |
Forward declares boost::hana::fill. | |
| file | filter.hpp |
Forward declares boost::hana::filter. | |
| file | find.hpp |
Forward declares boost::hana::find. | |
| file | find_if.hpp |
Forward declares boost::hana::find_if. | |
| file | first.hpp |
Forward declares boost::hana::first. | |
| file | flatten.hpp |
Forward declares boost::hana::flatten. | |
| file | fold.hpp |
Forward declares boost::hana::fold. | |
| file | fold_left.hpp |
Forward declares boost::hana::fold_left. | |
| file | fold_right.hpp |
Forward declares boost::hana::fold_right. | |
| file | for_each.hpp |
Forward declares boost::hana::for_each. | |
| file | front.hpp |
Forward declares boost::hana::front. | |
| file | fuse.hpp |
Forward declares boost::hana::fuse. | |
| file | greater.hpp |
Forward declares boost::hana::greater. | |
| file | greater_equal.hpp |
Forward declares boost::hana::greater_equal. | |
| file | group.hpp |
Forward declares boost::hana::group. | |
| file | hash.hpp |
Forward declares boost::hana::hash. | |
| file | if.hpp |
Forward declares boost::hana::if_. | |
| file | insert.hpp |
Forward declares boost::hana::insert. | |
| file | insert_range.hpp |
Forward declares boost::hana::insert_range. | |
| file | integral_constant.hpp |
Forward declares boost::hana::integral_constant. | |
| file | intersection.hpp |
Forward declares boost::hana::intersection. | |
| file | intersperse.hpp |
Forward declares boost::hana::intersperse. | |
| file | is_disjoint.hpp |
Forward declares boost::hana::is_disjoint. | |
| file | is_empty.hpp |
Forward declares boost::hana::is_empty. | |
| file | is_subset.hpp |
Forward declares boost::hana::is_subset. | |
| file | keys.hpp |
Forward declares boost::hana::keys. | |
| file | lazy.hpp |
Forward declares boost::hana::lazy. | |
| file | length.hpp |
Forward declares boost::hana::length. | |
| file | less.hpp |
Forward declares boost::hana::less. | |
| file | less_equal.hpp |
Forward declares boost::hana::less_equal. | |
| file | lexicographical_compare.hpp |
Forward declares boost::hana::lexicographical_compare. | |
| file | lift.hpp |
Forward declares boost::hana::lift. | |
| file | map.hpp |
Forward declares boost::hana::map. | |
| file | max.hpp |
Forward declares boost::hana::max. | |
| file | maximum.hpp |
Forward declares boost::hana::maximum. | |
| file | members.hpp |
Forward declares boost::hana::members. | |
| file | min.hpp |
Forward declares boost::hana::min. | |
| file | minimum.hpp |
Forward declares boost::hana::minimum. | |
| file | minus.hpp |
Forward declares boost::hana::minus. | |
| file | mod.hpp |
Forward declares boost::hana::mod. | |
| file | monadic_compose.hpp |
Forward declares boost::hana::monadic_compose. | |
| file | monadic_fold_left.hpp |
Forward declares boost::hana::monadic_fold_left. | |
| file | monadic_fold_right.hpp |
Forward declares boost::hana::monadic_fold_right. | |
| file | mult.hpp |
Forward declares boost::hana::mult. | |
| file | negate.hpp |
Forward declares boost::hana::negate. | |
| file | none.hpp |
Forward declares boost::hana::none. | |
| file | none_of.hpp |
Forward declares boost::hana::none_of. | |
| file | not.hpp |
Forward declares boost::hana::not_. | |
| file | not_equal.hpp |
Forward declares boost::hana::not_equal. | |
| file | one.hpp |
Forward declares boost::hana::one. | |
| file | optional.hpp |
Forward declares boost::hana::optional. | |
| file | or.hpp |
Forward declares boost::hana::or_. | |
| file | ordering.hpp |
Forward declares boost::hana::ordering. | |
| file | pair.hpp |
Forward declares boost::hana::pair. | |
| file | partition.hpp |
Forward declares boost::hana::partition. | |
| file | permutations.hpp |
Forward declares boost::hana::permutations. | |
| file | plus.hpp |
Forward declares boost::hana::plus. | |
| file | power.hpp |
Forward declares boost::hana::power. | |
| file | prefix.hpp |
Forward declares boost::hana::prefix. | |
| file | prepend.hpp |
Forward declares boost::hana::prepend. | |
| file | product.hpp |
Forward declares boost::hana::product. | |
| file | range.hpp |
Forward declares boost::hana::range. | |
| file | remove.hpp |
Forward declares boost::hana::remove. | |
| file | remove_at.hpp |
Forward declares boost::hana::remove_at and boost::hana::remove_at_c. | |
| file | remove_if.hpp |
Forward declares boost::hana::remove_if. | |
| file | remove_range.hpp |
Forward declares boost::hana::remove_range and boost::hana::remove_range_c. | |
| file | repeat.hpp |
Forward declares boost::hana::repeat. | |
| file | replace.hpp |
Forward declares boost::hana::replace. | |
| file | replace_if.hpp |
Forward declares boost::hana::replace_if. | |
| file | replicate.hpp |
Forward declares boost::hana::replicate. | |
| file | reverse.hpp |
Forward declares boost::hana::reverse. | |
| file | reverse_fold.hpp |
Forward declares boost::hana::reverse_fold. | |
| file | scan_left.hpp |
Forward declares boost::hana::scan_left. | |
| file | scan_right.hpp |
Forward declares boost::hana::scan_right. | |
| file | second.hpp |
Forward declares boost::hana::second. | |
| file | set.hpp |
Forward declares boost::hana::set. | |
| file | size.hpp |
Forward declares boost::hana::size. | |
| file | slice.hpp |
Forward declares boost::hana::slice and boost::hana::slice_c. | |
| file | sort.hpp |
Forward declares boost::hana::sort. | |
| file | span.hpp |
Forward declares boost::hana::span. | |
| file | string.hpp |
Forward declares boost::hana::string. | |
| file | suffix.hpp |
Forward declares boost::hana::suffix. | |
| file | sum.hpp |
Forward declares boost::hana::sum. | |
| file | symmetric_difference.hpp |
Forward declares boost::hana::symmetric_difference. | |
| file | take_back.hpp |
Forward declares boost::hana::take_back. | |
| file | take_front.hpp |
Forward declares boost::hana::take_front and boost::hana::take_front_c. | |
| file | take_while.hpp |
Forward declares boost::hana::take_while. | |
| file | tap.hpp |
Forward declares boost::hana::tap. | |
| file | then.hpp |
Forward declares boost::hana::then. | |
| file | transform.hpp |
Forward declares boost::hana::transform. | |
| file | tuple.hpp |
Forward declares boost::hana::tuple. | |
| file | type.hpp |
Forward declares boost::hana::type and related utilities. | |
| file | unfold_left.hpp |
Forward declares boost::hana::unfold_left. | |
| file | unfold_right.hpp |
Forward declares boost::hana::unfold_right. | |
| file | union.hpp |
Forward declares boost::hana::union_. | |
| file | unique.hpp |
Forward declares boost::hana::unique. | |
| file | unpack.hpp |
Forward declares boost::hana::unpack. | |
| file | value.hpp |
Forward declares boost::hana::value. | |
| file | while.hpp |
Forward declares boost::hana::while_. | |
| file | zero.hpp |
Forward declares boost::hana::zero. | |
| file | zip.hpp |
Forward declares boost::hana::zip. | |
| file | zip_shortest.hpp |
Forward declares boost::hana::zip_shortest. | |
| file | zip_shortest_with.hpp |
Forward declares boost::hana::zip_shortest_with. | |
| file | zip_with.hpp |
Forward declares boost::hana::zip_with. | |
+Files | |
| file | flat.hpp |
Defines boost::hana::detail::variadic::reverse_apply_flat. | |
| file | unrolled.hpp |
Defines boost::hana::detail::variadic::reverse_apply_unrolled. | |
+Files | |
| file | always.hpp |
Defines boost::hana::always. | |
| file | apply.hpp |
Defines boost::hana::apply. | |
| file | arg.hpp |
Defines boost::hana::arg. | |
| file | capture.hpp |
Defines boost::hana::capture. | |
| file | compose.hpp |
Defines boost::hana::compose. | |
| file | curry.hpp |
Defines boost::hana::curry. | |
| file | demux.hpp |
Defines boost::hana::demux. | |
| file | fix.hpp |
Defines boost::hana::fix. | |
| file | flip.hpp |
Defines boost::hana::flip. | |
| file | id.hpp |
Defines boost::hana::id. | |
| file | infix.hpp |
Defines boost::hana::infix. | |
| file | iterate.hpp |
Defines boost::hana::iterate. | |
| file | lockstep.hpp |
Defines boost::hana::lockstep. | |
| file | on.hpp |
Defines boost::hana::on. | |
| file | overload.hpp |
Defines boost::hana::overload. | |
| file | overload_linearly.hpp |
Defines boost::hana::overload_linearly. | |
| file | partial.hpp |
Defines boost::hana::partial. | |
| file | placeholder.hpp |
Defines boost::hana::_. | |
| file | reverse_partial.hpp |
Defines boost::hana::reverse_partial. | |
+Directories |
+Files | |
| file | array.hpp |
Adapts std::array for use with Hana. | |
| file | integer_sequence.hpp |
Adapts std::integer_sequence for use with Hana. | |
| file | integral_constant.hpp |
Adapts std::integral_constant for use with Hana. | |
| file | pair.hpp |
Adapts std::pair for use with Hana. | |
| file | ratio.hpp |
Adapts std::ratio for use with Hana. | |
| file | tuple.hpp |
Adapts std::tuple for use with Hana. | |
| file | vector.hpp |
Adapts std::vector for use with Hana. | |
Includes all the headers needed to setup tag-dispatching. +More...
+Includes all the headers needed to setup tag-dispatching.
+Defines BOOST_HANA_DISPATCH_IF.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Macros | |
| #define | BOOST_HANA_DISPATCH_IF(IMPL, ...) IMPL |
| Dispatch to the given implementation method only when a condition is satisfied. More... | |
Defines BOOST_HANA_DISPATCH_IF.
Defines boost::hana::div.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::div.
Defines boost::hana::drop_back.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::drop_back.
Defines boost::hana::drop_front.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::drop_front.
Defines boost::hana::drop_front_exactly.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::drop_front_exactly.
Defines boost::hana::detail::variadic::drop_into.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::variadic::drop_into.
Defines boost::hana::drop_while.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::drop_while.
Defines boost::hana::duplicate.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::duplicate.
Defines boost::hana::empty.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::empty.
Defines boost::hana::equal.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::equal.
Defines boost::hana::erase_key.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::erase_key.
Defines boost::hana::eval.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::eval.
Defines boost::hana::eval_if.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::eval_if.
Defines common methods for all Boost.Fusion sequences. +More...
++Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines common methods for all Boost.Fusion sequences.
+Adapts boost::fusion::tuple for use with Hana.
+More...
+Classes | |
| struct | boost::fusion::tuple< T > |
| Adapter for Boost.Fusion tuples. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Adapts boost::fusion::tuple for use with Hana.
In the current version of Boost.Fusion, boost::fusion::tuple is basically an alias to boost::fusion::vector, so both data types share the same implementation in Hana.
Adapts boost::tuple for use with Hana.
+More...
+Classes | |
| struct | boost::tuple< T > |
Adapter for boost::tuples. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Adapts boost::tuple for use with Hana.
Adapts std::array for use with Hana.
+More...
+Classes | |
| struct | std::array< T, N > |
Adaptation of std::array for Hana. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Adapts std::array for use with Hana.
Adapts std::integral_constant for use with Hana.
+More...
+Classes | |
| struct | std::integral_constant< T, v > |
Adapter for std::integral_constants. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Adapts std::integral_constant for use with Hana.
Adapts std::pair for use with Hana.
+More...
+Classes | |
| struct | std::pair< First, Second > |
Adaptation of std::pair for Hana. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Adapts std::pair for use with Hana.
Adapts std::tuple for use with Hana.
+More...
+Classes | |
| struct | std::tuple< T > |
Adapter for std::tuples. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Adapts std::tuple for use with Hana.
Defines boost::hana::extend.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::extend.
Defines boost::hana::extract.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::extract.
Defines boost::hana::detail::fast_and.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::fast_and.
Defines boost::hana::fill.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::fill.
Defines boost::hana::filter.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::filter.
Defines boost::hana::find.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::find.
Defines boost::hana::find_if.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::find_if.
Defines boost::hana::first.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::first.
Defines boost::hana::detail::first_unsatisfied_index.
+More...
+Classes | |
| struct | boost::hana::detail::first_unsatisfied_index< Pred > |
Returns the index of the first element which does not satisfy Pred, or sizeof...(Xs) if no such element exists. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::first_unsatisfied_index.
Defines boost::hana::fix.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::fix |
| Return a function computing the fixed point of a function. More... | |
Defines boost::hana::fix.
Defines boost::hana::detail::variadic::reverse_apply_flat.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::variadic::reverse_apply_flat.
Defines boost::hana::flatten.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::flatten.
Defines boost::hana::flip.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::flip |
| Invoke a function with its two first arguments reversed. More... | |
Defines boost::hana::flip.
Defines boost::hana::fold.
+More...
Defines boost::hana::fold.
Defines boost::hana::fold_left.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::fold_left.
Defines boost::hana::fold_right.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::fold_right.
Defines boost::hana::detail::variadic::foldl1.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::variadic::foldl1.
Defines boost::hana::detail::variadic::foldr1.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::variadic::foldr1.
Defines boost::hana::for_each.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::for_each.
Defines boost::hana::front.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::front.
Defines the Functional module. +More...
+Defines the Functional module.
+Defines boost::hana::fuse.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::fuse.
Adapts boost::fusion::list for use with Hana.
+More...
+Classes | |
| struct | boost::fusion::list< T > |
| Adapter for Boost.Fusion lists. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Adapts boost::fusion::list for use with Hana.
Includes all the adaptors for the Boost.Fusion library. +More...
+Includes all the adaptors for the Boost.Fusion library.
+Forward declares boost::hana::accessors.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<typename S > | |
| constexpr auto | boost::hana::accessors |
Returns a Sequence of pairs representing the accessors of the data structure.Given a Struct S, accessors<S>() is a Sequence of Products where the first element of each pair is the "name" of a member of the Struct, and the second element of each pair is a function that can be used to access that member when given an object of the proper data type. As described in the global documentation for Struct, the accessor functions in this sequence must be move-independent. More... | |
Forward declares boost::hana::accessors.
Documents the BOOST_HANA_ADAPT_ADT macro.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Functions | |
| auto | boost::hana::BOOST_HANA_ADAPT_ADT (...) |
Defines a model of Struct with the given accessors.Using this macro at global scope will define a model of the Struct concept for the given type. This can be used to easily adapt existing user-defined types in a ad-hoc manner. Unlike BOOST_HANA_ADAPT_STRUCT, this macro requires specifying the way to retrieve each member by providing a function that does the extraction. More... | |
Documents the BOOST_HANA_ADAPT_ADT macro.
Documents the BOOST_HANA_ADAPT_STRUCT macro.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Functions | |
| auto | boost::hana::BOOST_HANA_ADAPT_STRUCT (...) |
Defines a model of Struct with the given members.Using this macro at global scope will define a model of the Struct concept for the given type. This can be used to easily adapt existing user-defined types in a ad-hoc manner. Unlike the BOOST_HANA_DEFINE_STRUCT macro, this macro does not require the types of the members to be specified. More... | |
Documents the BOOST_HANA_ADAPT_STRUCT macro.
Forward declares boost::hana::adjust.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::adjust |
| Apply a function on all the elements of a structure that compare equal to some value. More... | |
Forward declares boost::hana::adjust.
Forward declares boost::hana::adjust_if.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::adjust_if |
Apply a function on all the elements of a structure satisfying a predicate.Given a Functor, a predicate pred and a function f, adjust_if will adjust the elements of the Functor that satisfy the predicate with the function f. In other words, adjust_if will return a new Functor equal to the original one, except that the elements satisfying the predicate will be transformed with the given function. Elements for which the predicate is not satisfied are left untouched, and they are kept as-is in the resulting Functor. More... | |
Forward declares boost::hana::adjust_if.
Forward declares boost::hana::all.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::all |
Returns whether all the keys of the structure are true-valued.The keys of the structure must be Logicals. If the structure is not finite, a false-valued key must appear at a finite "index" in order for this method to finish. More... | |
Forward declares boost::hana::all.
Forward declares boost::hana::all_of.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::all_of |
Returns whether all the keys of the structure satisfy the predicate.If the structure is not finite, predicate has to return a false- valued Logical after looking at a finite number of keys for this method to finish. More... | |
Forward declares boost::hana::all_of.
Forward declares boost::hana::and_.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::and_ |
Return whether all the arguments are true-valued.and_ can be called with one argument or more. When called with two arguments, and_ uses tag-dispatching to find the right implementation. Otherwise,. More... | |
Forward declares boost::hana::and_.
Forward declares boost::hana::any.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::any |
Returns whether any key of the structure is true-valued.The keys of the structure must be Logicals. If the structure is not finite, a true-valued key must appear at a finite "index" in order for this method to finish. More... | |
Forward declares boost::hana::any.
Forward declares boost::hana::any_of.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::any_of |
Returns whether any key of the structure satisfies the predicate.If the structure is not finite, predicate has to be satisfied after looking at a finite number of keys for this method to finish. More... | |
Forward declares boost::hana::any_of.
Forward declares boost::hana::ap.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::ap |
Lifted application.Specifically, ap applies a structure containing functions to a structure containing values, and returns a new structure containing values. The exact way in which the functions are applied to the values depends on the Applicative. More... | |
Forward declares boost::hana::ap.
Forward declares boost::hana::append.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::append |
Append an element to a monadic structure.Given an element x and a monadic structure xs, append returns a new monadic structure which is the result of lifting x into the monadic structure and then combining that (to the right) with xs. In other words,. More... | |
Forward declares boost::hana::append.
Forward declares boost::hana::at and boost::hana::at_c.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::at |
Returns the nth element of an iterable.Given an Iterable and an IntegralConstant index, at returns the element located at the index in the linearization of the iterable. Specifically, given an iterable xs with a linearization of [x1, ..., xN], at(xs, k) is equivalent to xk. More... | |
| template<std::size_t n> | |
| constexpr auto | boost::hana::at_c |
Equivalent to at; provided for convenience. More... | |
Forward declares boost::hana::at and boost::hana::at_c.
Forward declares boost::hana::at_key.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::at_key |
Returns the value associated to the given key in a structure, or fail.Given a key and a Searchable structure, at_key returns the first value whose key is equal to the given key, and fails at compile-time if no such key exists. This requires the key to be compile-time Comparable, exactly like for find. at_key satisfies the following: More... | |
Forward declares boost::hana::at_key.
Forward declares boost::hana::back.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::back |
Returns the last element of a non-empty and finite iterable.Given a non-empty and finite iterable xs with a linearization of [x1, ..., xN], back(xs) is equal to xN. Equivalently, back(xs) must be equivalent to at_c<N-1>(xs), and that regardless of the value category of xs (back must respect the reference semantics of at). More... | |
Forward declares boost::hana::back.
Forward declares boost::hana::basic_tuple.
+More...
+Classes | |
| struct | boost::hana::basic_tuple< Xs > |
Stripped down version of hana::tuple. More... | |
| struct | boost::hana::basic_tuple_tag |
Tag representing hana::basic_tuple. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::basic_tuple.
Includes boost/hana/fwd/integral_constant.hpp. +More...
+Includes boost/hana/fwd/integral_constant.hpp.
+Forward declares boost::hana::cartesian_product.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::cartesian_product |
Computes the cartesian product of a sequence of sequences.Given a sequence of sequences, cartesian_product returns a new sequence of sequences containing the cartesian product of the original sequences. For this method to finish, a finite number of finite sequences must be provided. More... | |
Forward declares boost::hana::cartesian_product.
Forward declares boost::hana::chain.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::chain |
Feed a monadic value into a monadic computation.Given a monadic value and a monadic function, chain feeds the monadic value into the function, thus performing some Monad-specific effects, and returns the result. An implementation of chain must satisfy. More... | |
Forward declares boost::hana::chain.
Forward declares boost::hana::comparing.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::comparing |
Returns a function performing equal after applying a transformation to both arguments.comparing creates an equivalence relation based on the result of applying a function to some objects, which is especially useful in conjunction with algorithms that accept a custom predicate that must represent an equivalence relation. More... | |
Forward declares boost::hana::comparing.
Forward declares boost::hana::concat.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::concat |
Combine two monadic structures together.Given two monadic structures, concat combines them together and returns a new monadic structure. The exact definition of concat will depend on the exact model of MonadPlus at hand, but for sequences it corresponds intuitively to simple concatenation. More... | |
Forward declares boost::hana::concat.
Forward declares boost::hana::Applicative.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Applicative.
Forward declares boost::hana::Comonad.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Comonad.
Forward declares boost::hana::Comparable.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Comparable.
Forward declares boost::hana::Constant.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Constant.
Forward declares boost::hana::EuclideanRing.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::EuclideanRing.
Forward declares boost::hana::Foldable.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Foldable.
Forward declares boost::hana::Functor.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Functor.
Forward declares boost::hana::Group.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Group.
Forward declares boost::hana::Hashable.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Hashable.
Forward declares boost::hana::IntegralConstant.
+More...
+Classes | |
| struct | boost::hana::IntegralConstant< C > |
The IntegralConstant concept represents compile-time integral values. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::IntegralConstant.
Forward declares boost::hana::Iterable.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Iterable.
Forward declares boost::hana::Logical.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Logical.
Forward declares boost::hana::Metafunction.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Metafunction.
Forward declares boost::hana::Monad.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Monad.
Forward declares boost::hana::MonadPlus.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::MonadPlus.
Forward declares boost::hana::Monoid.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Monoid.
Forward declares boost::hana::Orderable.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Orderable.
Forward declares boost::hana::Product.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Product.
Forward declares boost::hana::Ring.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Ring.
Forward declares boost::hana::Searchable.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Searchable.
Forward declares boost::hana::Sequence.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Sequence.
Forward declares boost::hana::Struct.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::Struct.
Forward declares boost::hana::contains and boost::hana::in.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::contains |
Returns whether the key occurs in the structure.Given a Searchable structure xs and a key, contains returns whether any of the keys of the structure is equal to the given key. If the structure is not finite, an equal key has to appear at a finite position in the structure for this method to finish. For convenience, contains can also be applied in infix notation. More... | |
| constexpr auto | boost::hana::in = hana::infix(hana::flip(hana::contains)) |
Return whether the key occurs in the structure.Specifically, this is equivalent to contains, except in takes its arguments in reverse order. Like contains, in can also be applied in infix notation for increased expressiveness. This function is not a method that can be overriden; it is just a convenience function provided with the concept. More... | |
Forward declares boost::hana::contains and boost::hana::in.
Forward declares boost::hana::common and boost::hana::common_t.
+More...
+Classes | |
| struct | boost::hana::common< T, U, enabler > |
| Metafunction returning the common data type between two data types. More... | |
| struct | boost::hana::has_common< T, U, typename > |
| Metafunction returning whether two data types share a common data type. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Typedefs | |
| template<typename T , typename U > | |
| using | boost::hana::common_t = typename common< T, U >::type |
Alias to common<T, U>::type, provided for convenience. More... | |
Forward declares boost::hana::common and boost::hana::common_t.
Forward declares boost::hana::default_ and boost::hana::is_default.
+More...
+Classes | |
| struct | boost::hana::default_ |
| Mark a tag-dispatched method implementation as a default implementation. More... | |
| struct | boost::hana::is_default< Method, typename > |
| Returns whether a tag-dispatched method implementation is a default implementation. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::default_ and boost::hana::is_default.
Forward declares boost::hana::is_a and boost::hana::is_an.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<typename Tag , typename optional_T > | |
| constexpr auto | boost::hana::is_a = see-documentation |
| Returns whether the tag of an object matches a given tag. More... | |
| +template<typename Tag , typename... T> | |
| constexpr auto | boost::hana::is_an = is_a<Tag, T...> |
Equivalent to is_a; provided for consistency with the rules of the English language. | |
Forward declares boost::hana::is_a and boost::hana::is_an.
Forward declares boost::hana::make.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<typename Tag > | |
| constexpr auto | boost::hana::make |
| Create an object of the given tag with the given arguments. More... | |
Forward declares boost::hana::make.
Forward declares boost::hana::tag_of and boost::hana::tag_of_t.
+More...
+Classes | |
| struct | boost::hana::tag_of< T, enabler > |
Metafunction returning the tag associated to T. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Typedefs | |
| template<typename T > | |
| using | boost::hana::tag_of_t = typename hana::tag_of< T >::type |
Alias to tag_of<T>::type, provided for convenience. More... | |
Forward declares boost::hana::tag_of and boost::hana::tag_of_t.
Forward declares boost::hana::to and related utilities.
+More...
+Classes | |
| struct | boost::hana::is_convertible< From, To, typename > |
| Returns whether there is a Hana-conversion from a data type to another. More... | |
| struct | boost::hana::embedding< bool > |
| Marks a conversion between data types as being an embedding. More... | |
| struct | boost::hana::is_embedded< From, To, typename > |
| Returns whether a data type can be embedded into another data type. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<typename To > | |
| constexpr auto | boost::hana::to |
| Converts an object from one data type to another. More... | |
Forward declares boost::hana::to and related utilities.
Forward declares boost::hana::when and boost::hana::when_valid.
+More...
+Classes | |
| struct | boost::hana::when< condition > |
| Enable a partial specialization only if a boolean condition is true. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Typedefs | |
| template<typename... > | |
| using | boost::hana::when_valid = when< true > |
Variant of when allowing specializations to be enabled only if an expression is well-formed. More... | |
Forward declares boost::hana::when and boost::hana::when_valid.
Forward declares the Core module. +More...
+Forward declares the Core module.
+Forward declares boost::hana::count.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::count |
Return the number of elements in the structure that compare equal to a given value.Given a Foldable structure xs and a value value, count returns an unsigned integral, or a Constant thereof, representing the number of elements of xs that compare equal to value. For this method to be well-defined, all the elements of the structure must be Comparable with the given value. More... | |
Forward declares boost::hana::count.
Forward declares boost::hana::count_if.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::count_if |
Return the number of elements in the structure for which the predicate is satisfied.Specifically, returns an object of an unsigned integral type, or a Constant holding such an object, which represents the number of elements in the structure satisfying the given predicate. More... | |
Forward declares boost::hana::count_if.
Forward declares boost::hana::cycle.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::cycle |
Combine a monadic structure with itself n times.Given a monadic structure xs and a non-negative number n, cycle returns a new monadic structure which is the result of combining xs with itself n times using the concat operation. In other words,. More... | |
Forward declares boost::hana::cycle.
Documents the BOOST_HANA_DEFINE_STRUCT macro.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Functions | |
| auto | boost::hana::BOOST_HANA_DEFINE_STRUCT (...) |
Defines members of a structure, while at the same time modeling Struct.Using this macro in the body of a user-defined type will define the given members inside that type, and will also provide a model of the Struct concept for that user-defined type. This macro is often the easiest way to define a model of the Struct concept. More... | |
Documents the BOOST_HANA_DEFINE_STRUCT macro.
Forward declares boost::hana::difference.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::difference.
Forward declares boost::hana::div.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::div |
| Generalized integer division. More... | |
Forward declares boost::hana::div.
Forward declares boost::hana::drop_back.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::drop_back |
Drop the last n elements of a finite sequence, and return the rest.Given a finite Sequence xs with a linearization of [x1, ..., xm] and a non-negative IntegralConstant n, drop_back(xs, n) is a sequence with the same tag as xs whose linearization is [x1, ..., xm-n]. If n is not given, it defaults to an IntegralConstant with a value equal to 1. More... | |
Forward declares boost::hana::drop_back.
Forward declares boost::hana::drop_front.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::drop_front |
Drop the first n elements of an iterable, and return the rest.Given an Iterable xs with a linearization of [x1, x2, ...] and a non-negative IntegralConstant n, drop_front(xs, n) is an iterable with the same tag as xs whose linearization is [xn+1, xn+2, ...]. In particular, note that this function does not mutate the original iterable in any way. If n is not given, it defaults to an IntegralConstant with a value equal to 1. More... | |
Forward declares boost::hana::drop_front.
Forward declares boost::hana::drop_front_exactly.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::drop_front_exactly |
Drop the first n elements of an iterable, and return the rest.Given an Iterable xs with a linearization of [x1, x2, ...] and a non-negative IntegralConstant n, drop_front_exactly(xs, n) is an iterable with the same tag as xs whose linearization is [xn+1, xn+2, ...]. In particular, note that this function does not mutate the original iterable in any way. If n is not given, it defaults to an IntegralConstant with a value equal to 1. More... | |
Forward declares boost::hana::drop_front_exactly.
Forward declares boost::hana::drop_while.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::drop_while |
Drop elements from an iterable up to, but excluding, the first element for which the predicate is not satisfied.Specifically, drop_while returns an iterable containing all the elements of the original iterable except for those in the range delimited by [head, e), where head is the first element and e is the first element for which the predicate is not satisfied. If the iterable is not finite, the predicate has to return a false- valued Logical at a finite index for this method to return. More... | |
Forward declares boost::hana::drop_while.
Forward declares boost::hana::duplicate.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::duplicate |
Add an extra layer of comonadic context to a comonadic value.Given a value already in a comonadic context, duplicate wraps this value with an additional layer of comonadic context. This can be seen as the dual operation to flatten from the Monad concept. More... | |
Forward declares boost::hana::duplicate.
Forward declares boost::hana::empty.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<typename M > | |
| constexpr auto | boost::hana::empty |
Identity of the monadic combination concat.Signature+Given a MonadPlusM, the signature is \( \mathtt{empty}_M : \emptyset \to M(T) \). More... | |
Forward declares boost::hana::empty.
Forward declares boost::hana::equal.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::equal |
Returns a Logical representing whether x is equal to y.The equal function can be called in two different ways. First, it can be called like a normal function: More... | |
Forward declares boost::hana::equal.
Forward declares boost::hana::erase_key.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::erase_key.
Forward declares boost::hana::eval.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::eval.
Forward declares boost::hana::eval_if.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::eval_if |
Conditionally execute one of two branches based on a condition.Given a condition and two branches in the form of lambdas or hana::lazys, eval_if will evaluate the branch selected by the condition with eval and return the result. The exact requirements for what the branches may be are the same requirements as those for the eval function. More... | |
Forward declares boost::hana::eval_if.
Forward declares boost::hana::extend.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::extend |
Comonadic application of a function to a comonadic value.Given a comonadic value and a function accepting a comonadic input, extend returns the result of applying the function to that input inside the comonadic context. More... | |
Forward declares boost::hana::extend.
Forward declares boost::hana::extract.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::extract |
Extract a value in a given comonadic context.Given a value inside a comonadic context, extract it from that context, performing whatever effects are mandated by that context. This can be seen as the dual operation to the lift method of the Applicative concept. More... | |
Forward declares boost::hana::extract.
Forward declares boost::hana::fill.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::fill |
| Replace all the elements of a structure with a fixed value. More... | |
Forward declares boost::hana::fill.
Forward declares boost::hana::filter.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::filter |
Filter a monadic structure using a custom predicate.Given a monadic structure and a predicate, filter returns a new monadic structure containing only those elements that satisfy the predicate. This is a generalization of the usual filter function for sequences; it works for any MonadPlus. Intuitively, filter is somewhat equivalent to: More... | |
Forward declares boost::hana::filter.
Forward declares boost::hana::find.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::find |
Finds the value associated to the given key in a structure.Given a key and a Searchable structure, find returns the just the first value whose key is equal to the given key, or nothing if there is no such key. Comparison is done with equal. find satisfies the following: More... | |
Forward declares boost::hana::find.
Forward declares boost::hana::find_if.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::find_if |
Finds the value associated to the first key satisfying a predicate.Given a Searchable structure xs and a predicate pred, find_if(xs, pred) returns just the first element whose key satisfies the predicate, or nothing if there is no such element. More... | |
Forward declares boost::hana::find_if.
Forward declares boost::hana::first.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+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... | |
Forward declares boost::hana::first.
Forward declares boost::hana::flatten.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::flatten |
Collapse two levels of monadic structure into a single level.Given a monadic value wrapped into two levels of monad, flatten removes one such level. An implementation of flatten must satisfy. More... | |
Forward declares boost::hana::flatten.
Forward declares boost::hana::fold.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::fold = fold_left |
Equivalent to fold_left; provided for convenience.fold is equivalent to fold_left. However, it is not tag-dispatched on its own because it is just an alias to fold_left. Also note that fold can be called with or without an initial state, just like fold_left: More... | |
Forward declares boost::hana::fold.
Forward declares boost::hana::fold_left.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::fold_left |
Left-fold of a structure using a binary operation and an optional initial reduction state.fold_left is a left-associative fold using a binary operation. Given a structure containing x1, ..., xn, a function f and an optional initial state, fold_left applies f as follows. More... | |
Forward declares boost::hana::fold_left.
Forward declares boost::hana::fold_right.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::fold_right |
Right-fold of a structure using a binary operation and an optional initial reduction state.fold_right is a right-associative fold using a binary operation. Given a structure containing x1, ..., xn, a function f and an optional initial state, fold_right applies f as follows. More... | |
Forward declares boost::hana::fold_right.
Forward declares boost::hana::for_each.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::for_each |
Perform an action on each element of a foldable, discarding the result each time.Iteration is done from left to right, i.e. in the same order as when using fold_left. If the structure is not finite, this method will not terminate. More... | |
Forward declares boost::hana::for_each.
Forward declares boost::hana::front.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::front |
Returns the first element of a non-empty iterable.Given a non-empty Iterable xs with a linearization of [x1, ..., xN], front(xs) is equal to x1. If xs is empty, it is an error to use this function. Equivalently, front(xs) must be equivalent to at_c<0>(xs), and that regardless of the value category of xs (front must respect the reference semantics of at). More... | |
Forward declares boost::hana::front.
Forward declares boost::hana::fuse.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::fuse |
Transform a function taking multiple arguments into a function that can be called with a compile-time Foldable. More... | |
Forward declares boost::hana::fuse.
Forward declares boost::hana::greater.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::greater |
Returns a Logical representing whether x is greater than y. More... | |
Forward declares boost::hana::greater.
Forward declares boost::hana::greater_equal.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::greater_equal |
Returns a Logical representing whether x is greater than or equal to y. More... | |
Forward declares boost::hana::greater_equal.
Forward declares boost::hana::group.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::group |
Group adjacent elements of a sequence that all respect a binary predicate, by default equality.Given a finite Sequence and an optional predicate (by default equal), group returns a sequence of subsequences representing groups of adjacent elements that are "equal" with respect to the predicate. In other words, the groups are such that the predicate is satisfied when it is applied to any two adjacent elements in that group. The sequence returned by group is such that the concatenation of its elements is equal to the original sequence, which is equivalent to saying that the order of the elements is not changed. More... | |
Forward declares boost::hana::group.
Forward declares boost::hana::hash.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::hash |
Returns a hana::type representing the compile-time hash of an object.Given an arbitrary object x, hana::hash returns a hana::type representing the hash of x. In normal programming, hashes are usually numerical values that can be used e.g. as indices in an array as part of the implementation of a hash table. In the context of metaprogramming, we are interested in type-level hashes instead. Thus, hana::hash must return a hana::type object instead of an integer. This hana::type must somehow summarize the object being hashed, but that summary may of course lose some information. More... | |
Forward declares boost::hana::hash.
Forward declares boost::hana::if_.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::if_ |
Conditionally return one of two values based on a condition.Specifically, then is returned iff cond is true-valued, and else_ is returned otherwise. Note that some Logical models may allow then and else_ to have different types, while others may require both values to have the same type. More... | |
Forward declares boost::hana::if_.
Forward declares boost::hana::insert.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr insert_t | boost::hana::insert {} |
Insert a value at a given index in a sequence.Given a sequence, an index and an element to insert, insert inserts the element at the given index. More... | |
Forward declares boost::hana::insert.
Forward declares boost::hana::insert_range.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::insert_range |
Insert several values at a given index in a sequence.Given a sequence, an index and any Foldable containing elements to insert, insert_range inserts the elements in the Foldable at the given index of the sequence. More... | |
Forward declares boost::hana::insert_range.
Forward declares boost::hana::integral_constant.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
| boost::hana::literals | |
| Namespace containing C++14 user-defined literals provided by Hana. | |
+Functions | |
| template<char... c> | |
| constexpr auto | boost::hana::literals::operator""_c () |
Creates a hana::integral_constant from a literal. More... | |
Forward declares boost::hana::integral_constant.
Forward declares boost::hana::intersection.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::intersection.
Forward declares boost::hana::intersperse.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::intersperse |
Insert a value between each pair of elements in a finite sequence.Given a finite Sequence xs with a linearization of [x1, x2, ..., xn], intersperse(xs, z) is a new sequence with a linearization of [x1, z, x2, z, x3, ..., xn-1, z, xn]. In other words, it inserts the z element between every pair of elements of the original sequence. If the sequence is empty or has a single element, intersperse returns the sequence as-is. In all cases, the sequence must be finite. More... | |
Forward declares boost::hana::intersperse.
Forward declares boost::hana::is_disjoint.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::is_disjoint |
Returns whether two Searchables are disjoint.Given two Searchables xs and ys, is_disjoint returns a Logical representing whether the keys in xs are disjoint from the keys in ys, i.e. whether both structures have no keys in common. More... | |
Forward declares boost::hana::is_disjoint.
Forward declares boost::hana::is_empty.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::is_empty |
Returns whether the iterable is empty.Given an Iterable xs, is_empty returns whether xs contains no more elements. In other words, it returns whether trying to extract the tail of xs would be an error. In the current version of the library, is_empty must return an IntegralConstant holding a value convertible to bool. This is because only compile-time Iterables are supported right now. More... | |
Forward declares boost::hana::is_empty.
Forward declares boost::hana::is_subset.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::is_subset |
Returns whether a structure contains a subset of the keys of another structure.Given two Searchables xs and ys, is_subset returns a Logical representing whether xs is a subset of ys. In other words, it returns whether all the keys of xs are also present in ys. This method does not return whether xs is a strict subset of ys; if xs and ys are equal, all the keys of xs are also present in ys, and is_subset returns true. More... | |
Forward declares boost::hana::is_subset.
Forward declares boost::hana::keys.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr keys_t | boost::hana::keys {} |
Returns a Sequence containing the name of the members of the data structure.Given a Struct object, keys returns a Sequence containing the name of all the members of the Struct, in the same order as they appear in the accessors sequence. More... | |
Forward declares boost::hana::keys.
Forward declares boost::hana::lazy.
+More...
+Classes | |
| struct | boost::hana::lazy< implementation_defined > |
hana::lazy implements superficial laziness via a monadic interface. More... | |
| struct | boost::hana::lazy_tag |
Tag representing hana::lazy. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::lazy.
Forward declares boost::hana::length.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::length |
Return the number of elements in a foldable structure.Given a Foldable xs, length(xs) must return an object of an unsigned integral type, or an IntegralConstant holding such an object, which represents the number of elements in the structure. More... | |
Forward declares boost::hana::length.
Forward declares boost::hana::less.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::less |
Returns a Logical representing whether x is less than y. More... | |
Forward declares boost::hana::less.
Forward declares boost::hana::less_equal.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::less_equal |
Returns a Logical representing whether x is less than or equal to y. More... | |
Forward declares boost::hana::less_equal.
Forward declares boost::hana::lexicographical_compare.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::lexicographical_compare |
Short-circuiting lexicographical comparison of two Iterables with an optional custom predicate, by default hana::less.Given two Iterables xs and ys and a binary predicate pred, lexicographical_compare returns whether xs is to be considered less than ys in a lexicographical ordering. Specifically, let's denote the linearizations of xs and ys by [x1, x2, ...] and [y1, y2, ...], respectively. If the first couple satisfying the predicate is of the form xi, yi, lexicographical_compare returns true. Otherwise, if the first couple to satisfy the predicate is of the form yi, xi, lexicographical_compare returns false. If no such couple can be found, lexicographical_compare returns whether xs has fewer elements than ys. More... | |
Forward declares boost::hana::lexicographical_compare.
Forward declares boost::hana::lift.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<typename A > | |
| constexpr auto | boost::hana::lift |
Lift a value into an Applicative structure.lift<A> takes a normal value and embeds it into a structure whose shape is represented by the A Applicative. Note that the value may be a function, in which case the created structure may be applied to another Applicative structure containing values. More... | |
Forward declares boost::hana::lift.
Forward declares boost::hana::map.
+More...
+Classes | |
| struct | boost::hana::map_tag |
Tag representing hana::maps. More... | |
| struct | boost::hana::map< Pairs > |
Basic associative container requiring unique, Comparable and Hashable keys. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::map.
Forward declares boost::hana::max.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::max |
Returns the greatest of its arguments according to the less ordering. More... | |
Forward declares boost::hana::max.
Forward declares boost::hana::maximum.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::maximum |
Return the greatest element of a non-empty structure with respect to a predicate, by default less.Given a non-empty structure and an optional binary predicate (less by default), maximum returns the greatest element of the structure, i.e. an element which is greater than or equal to every other element in the structure, according to the predicate. More... | |
Forward declares boost::hana::maximum.
Forward declares boost::hana::members.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::members |
Returns a Sequence containing the members of a Struct.Given a Struct object, members returns a Sequence containing all the members of the Struct, in the same order as their respective accessor appears in the accessors sequence. More... | |
Forward declares boost::hana::members.
Forward declares boost::hana::min.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::min |
Returns the smallest of its arguments according to the less ordering. More... | |
Forward declares boost::hana::min.
Forward declares boost::hana::minimum.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::minimum |
Return the least element of a non-empty structure with respect to a predicate, by default less.Given a non-empty structure and an optional binary predicate (less by default), minimum returns the least element of the structure, i.e. an element which is less than or equal to every other element in the structure, according to the predicate. More... | |
Forward declares boost::hana::minimum.
Forward declares boost::hana::minus.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::minus |
Subtract two elements of a group.Specifically, this performs the Monoid operation on the first argument and on the inverse of the second argument, thus being equivalent to: More... | |
Forward declares boost::hana::minus.
Forward declares boost::hana::mod.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::mod |
Generalized integer modulus.Given two elements of an EuclideanRing x and y, with y nonzero, mod returns the modulus of the division of x by y. In other words, mod can be seen as an equivalent to %. More... | |
Forward declares boost::hana::mod.
Forward declares boost::hana::monadic_compose.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::monadic_compose |
Composition of monadic functions.Given two monadic functions f and g, monadic_compose returns a new function equivalent to the composition of f with g, except the result of g is chained into f instead of simply passed to it, as with normal composition. monadic_compose satisfies. More... | |
Forward declares boost::hana::monadic_compose.
Forward declares boost::hana::monadic_fold_left.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<typename M > | |
| constexpr auto | boost::hana::monadic_fold_left |
| Monadic left-fold of a structure with a binary operation and an optional initial reduction state. More... | |
Forward declares boost::hana::monadic_fold_left.
Forward declares boost::hana::monadic_fold_right.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<typename M > | |
| constexpr auto | boost::hana::monadic_fold_right |
| Monadic right-fold of a structure with a binary operation and an optional initial reduction state. More... | |
Forward declares boost::hana::monadic_fold_right.
Forward declares boost::hana::mult.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::mult |
Associative operation of a Ring. More... | |
Forward declares boost::hana::mult.
Forward declares boost::hana::negate.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::negate |
| Return the inverse of an element of a group. More... | |
Forward declares boost::hana::negate.
Forward declares boost::hana::none.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::none |
Returns whether all of the keys of the structure are false-valued.The keys of the structure must be Logicals. If the structure is not finite, a true-valued key must appear at a finite "index" in order for this method to finish. More... | |
Forward declares boost::hana::none.
Forward declares boost::hana::none_of.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::none_of |
Returns whether none of the keys of the structure satisfy the predicate.If the structure is not finite, predicate has to return a true- valued Logical after looking at a finite number of keys for this method to finish. More... | |
Forward declares boost::hana::none_of.
Forward declares boost::hana::not_.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::not_ |
Negates a Logical.This method returns a Logical with the same tag, but whose truth-value is negated. Specifically, not_(x) returns a false-valued Logical if x is a true-valued Logical, and a true-valued one otherwise. More... | |
Forward declares boost::hana::not_.
Forward declares boost::hana::not_equal.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::not_equal |
Returns a Logical representing whether x is not equal to y.The not_equal function can be called in two different ways. First, it can be called like a normal function: More... | |
Forward declares boost::hana::not_equal.
Forward declares boost::hana::one.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<typename R > | |
| constexpr auto | boost::hana::one |
Identity of the Ring multiplication. More... | |
Forward declares boost::hana::one.
Forward declares boost::hana::optional.
+More...
+Classes | |
| struct | boost::hana::optional< T > |
| Optional value whose optional-ness is known at compile-time. More... | |
| struct | boost::hana::optional_tag |
Tag representing a hana::optional. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::optional.
Forward declares boost::hana::or_.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::or_ |
Return whether any of the arguments is true-valued.or_ can be called with one argument or more. When called with two arguments, or_ uses tag-dispatching to find the right implementation. Otherwise,. More... | |
Forward declares boost::hana::or_.
Forward declares boost::hana::ordering.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::ordering |
Returns a function performing less after applying a transformation to both arguments.ordering creates a total order based on the result of applying a function to some objects, which is especially useful in conjunction with algorithms that accept a custom predicate that must represent a total order. More... | |
Forward declares boost::hana::ordering.
Forward declares boost::hana::pair.
+More...
+Classes | |
| struct | boost::hana::pair< First, Second > |
| Generic container for two elements. More... | |
| struct | boost::hana::pair_tag |
Tag representing hana::pair. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::pair.
Forward declares boost::hana::partition.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::partition |
Partition a sequence based on a predicate.Specifically, returns an unspecified Product whose first element is a sequence of the elements satisfying the predicate, and whose second element is a sequence of the elements that do not satisfy the predicate. More... | |
Forward declares boost::hana::partition.
Forward declares boost::hana::permutations.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::permutations |
Return a sequence of all the permutations of the given sequence.Specifically, permutations(xs) is a sequence whose elements are permutations of the original sequence xs. The permutations are not guaranteed to be in any specific order. Also note that the number of permutations grows very rapidly as the length of the original sequence increases. The growth rate is O(length(xs)!); with a sequence xs of length only 8, permutations(xs) contains over 40 000 elements! More... | |
Forward declares boost::hana::permutations.
Forward declares boost::hana::plus.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::plus |
Associative binary operation on a Monoid. More... | |
Forward declares boost::hana::plus.
Forward declares boost::hana::power.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::power |
Elevate a ring element to its nth power.Specifically, power(x, n), is equivalent to multiplying x with itself n times using the Ring's multiplication. If the power is equal to zero, the Ring's identity (one) is returned. More... | |
Forward declares boost::hana::power.
Forward declares boost::hana::prefix.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::prefix |
Inserts a value before each element of a monadic structure.Given a monadic structure xs and a value z called the prefix, prefix returns a new monadic structure. prefix satisfies. More... | |
Forward declares boost::hana::prefix.
Forward declares boost::hana::prepend.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::prepend |
Prepend an element to a monadic structure.Given a monadic structure xs and an element x, prepend returns a new monadic structure which is the result of lifting x into the monadic structure and then combining that (to the left) with xs. In other words,. More... | |
Forward declares boost::hana::prepend.
Forward declares boost::hana::product.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::product = see documentation |
Compute the product of the numbers of a structure.More generally, product will take any foldable structure containing objects forming a Ring and reduce them using the Ring's binary operation. The initial state for folding is the identity of the Ring's operation. It is sometimes necessary to specify the Ring to use; this is possible by using product<R>. If no Ring is specified, the structure will use the Ring formed by the elements it contains (if it knows it), or integral_constant_tag<int> otherwise. Hence,. More... | |
Forward declares boost::hana::product.
Forward declares boost::hana::range.
+More...
+Classes | |
| struct | boost::hana::range< T, from, to > |
Compile-time half-open interval of hana::integral_constants. More... | |
| struct | boost::hana::range_tag |
Tag representing a hana::range. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::range.
Forward declares boost::hana::remove.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::remove |
Remove all the elements of a monadic structure that are equal to some value.Given a monadic structure xs and a value, remove returns a new monadic structure equal to xs without all its elements that are equal to the given value. remove is equivalent to remove_if with the equal.to(value) predicate, i.e. More... | |
Forward declares boost::hana::remove.
Forward declares boost::hana::remove_at and boost::hana::remove_at_c.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::remove_at |
Remove the element at a given index from a sequence.remove_at returns a new sequence identical to the original, except that the element at the given index is removed. Specifically, remove_at([x0, ..., xn-1, xn, xn+1, ..., xm], n) is a new sequence equivalent to [x0, ..., xn-1, xn+1, ..., xm]. More... | |
| template<std::size_t n> | |
| constexpr auto | boost::hana::remove_at_c |
Equivalent to remove_at; provided for convenience. More... | |
Forward declares boost::hana::remove_at and boost::hana::remove_at_c.
Forward declares boost::hana::remove_if.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::remove_if |
Remove all the elements of a monadic structure that satisfy some predicate.Given a monadic structure xs and a unary predicate, remove_if returns a new monadic structure equal to xs without all its elements that satisfy the predicate. This is equivalent to filter with a negated predicate, i.e. More... | |
Forward declares boost::hana::remove_if.
Forward declares boost::hana::remove_range and boost::hana::remove_range_c.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::remove_range |
Remove the elements inside a given range of indices from a sequence.remove_range returns a new sequence identical to the original, except that elements at indices in the provided range are removed. Specifically, remove_range([x0, ..., xn], from, to) is a new sequence equivalent to [x0, ..., x_from-1, x_to, ..., xn]. More... | |
| template<std::size_t from, std::size_t to> | |
| constexpr auto | boost::hana::remove_range_c |
Equivalent to remove_range; provided for convenience. More... | |
Forward declares boost::hana::remove_range and boost::hana::remove_range_c.
Forward declares boost::hana::repeat.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::repeat |
Invokes a nullary function n times.Given an IntegralConstant n and a nullary function f, repeat(n, f) will call f n times. In particular, any decent compiler should expand repeat(n, f) to. More... | |
Forward declares boost::hana::repeat.
Forward declares boost::hana::replace.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::replace |
Replace all the elements of a structure that compare equal to some value with some new fixed value. More... | |
Forward declares boost::hana::replace.
Forward declares boost::hana::replace_if.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::replace_if |
Replace all the elements of a structure satisfying a predicate with a fixed value. More... | |
Forward declares boost::hana::replace_if.
Forward declares boost::hana::replicate.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<typename M > | |
| constexpr auto | boost::hana::replicate |
Create a monadic structure by combining a lifted value with itself n times.Given a value x, a non-negative IntegralConstant n and the tag of a monadic structure M, replicate creates a new monadic structure which is the result of combining x with itself n times inside the monadic structure. In other words, replicate simply lifts x into the monadic structure, and then combines that with itself n times: More... | |
Forward declares boost::hana::replicate.
Forward declares boost::hana::reverse.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::reverse |
Reverse a sequence.Specifically, reverse(xs) is a new sequence containing the same elements as xs, except in reverse order. More... | |
Forward declares boost::hana::reverse.
Forward declares boost::hana::reverse_fold.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::reverse_fold |
Equivalent to reverse_fold in Boost.Fusion and Boost.MPL.This method has the same semantics as reverse_fold in Boost.Fusion and Boost.MPL, with the extension that an initial state is not required. This method is equivalent to fold_right, except that the accumulating function must take its arguments in reverse order, to match the order used in Fusion. In other words,. More... | |
Forward declares boost::hana::reverse_fold.
Forward declares boost::hana::scan_left.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::scan_left |
Fold a Sequence to the left and return a list containing the successive reduction states.Like fold_left, scan_left reduces a sequence to a single value using a binary operation. However, unlike fold_left, it builds up a sequence of the intermediary results computed along the way and returns that instead of only the final reduction state. Like fold_left, scan_left can be used with or without an initial reduction state. More... | |
Forward declares boost::hana::scan_left.
Forward declares boost::hana::scan_right.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::scan_right |
Fold a Sequence to the right and return a list containing the successive reduction states.Like fold_right, scan_right reduces a sequence to a single value using a binary operation. However, unlike fold_right, it builds up a sequence of the intermediary results computed along the way and returns that instead of only the final reduction state. Like fold_right, scan_right can be used with or without an initial reduction state. More... | |
Forward declares boost::hana::scan_right.
Forward declares boost::hana::second.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| 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... | |
Forward declares boost::hana::second.
Forward declares boost::hana::set.
+More...
+Classes | |
| struct | boost::hana::set< implementation_defined > |
Basic unordered container requiring unique, Comparable and Hashable keys. More... | |
| struct | boost::hana::set_tag |
Tag representing the hana::set container. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::set.
Forward declares boost::hana::size.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::size = hana::length |
Equivalent to length; provided for consistency with the standard library.This method is an alias to length provided for convenience and consistency with the standard library. As an alias, size is not tag-dispatched on its own and length should be customized instead. More... | |
Forward declares boost::hana::size.
Forward declares boost::hana::slice and boost::hana::slice_c.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::slice |
Extract the elements of a Sequence at the given indices.Given an arbitrary sequence of indices, slice returns a new sequence of the elements of the original sequence that appear at those indices. In other words,. More... | |
| template<std::size_t from, std::size_t to> | |
| constexpr auto | boost::hana::slice_c |
Shorthand to slice a contiguous range of elements.slice_c is simply a shorthand to slice a contiguous range of elements. In particular, slice_c<from, to>(xs) is equivalent to slice(xs, range_c<std::size_t, from, to>), which simply slices all the elements of xs contained in the half-open interval delimited by [from, to). Like for slice, the indices used with slice_c are 0-based and they must be in the bounds of the sequence being sliced. More... | |
Forward declares boost::hana::slice and boost::hana::slice_c.
Forward declares boost::hana::sort.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::sort |
Sort a sequence, optionally based on a custom predicate.Given a Sequence and an optional predicate (by default less), sort returns a new sequence containing the same elements as the original, except they are ordered in such a way that if x comes before y in the sequence, then either predicate(x, y) is true, or both predicate(x, y) and predicate(y, x) are false. More... | |
Forward declares boost::hana::sort.
Forward declares boost::hana::span.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::span |
Returns a Product containing the longest prefix of a sequence satisfying a predicate, and the rest of the sequence.The first component of the returned Product is a sequence for which all elements satisfy the given predicate. The second component of the returned Product is a sequence containing the remainder of the argument. Both or either sequences may be empty, depending on the input argument. More specifically,. More... | |
Forward declares boost::hana::span.
Forward declares boost::hana::string.
+More...
+Classes | |
| struct | boost::hana::string< implementation_defined > |
| Compile-time string. More... | |
| struct | boost::hana::string_tag |
| Tag representing a compile-time string. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
| boost::hana::literals | |
| Namespace containing C++14 user-defined literals provided by Hana. | |
+Functions | |
| template<typename CharT , CharT... s> | |
| constexpr auto | boost::hana::literals::operator""_s () |
| Creates a compile-time string from a string literal. More... | |
Forward declares boost::hana::string.
Forward declares boost::hana::suffix.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::suffix |
Inserts a value after each element of a monadic structure.Given a monadic structure xs and a value z (called the suffix), suffix returns a new monadic structure such that. More... | |
Forward declares boost::hana::suffix.
Forward declares boost::hana::sum.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::sum = see documentation |
Compute the sum of the numbers of a structure.More generally, sum will take any foldable structure containing objects forming a Monoid and reduce them using the Monoid's binary operation. The initial state for folding is the identity of the Monoid. It is sometimes necessary to specify the Monoid to use; this is possible by using sum<M>. If no Monoid is specified, the structure will use the Monoid formed by the elements it contains (if it knows it), or integral_constant_tag<int> otherwise. Hence,. More... | |
Forward declares boost::hana::sum.
Forward declares boost::hana::symmetric_difference.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::symmetric_difference.
Forward declares boost::hana::take_back.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::take_back |
Returns the last n elements of a sequence, or the whole sequence if the sequence has less than n elements.Given a Sequence xs and an IntegralConstant n, take_back(xs, n) is a new sequence containing the last n elements of xs, in the same order. If length(xs) <= n, the whole sequence is returned and no error is triggered. More... | |
Forward declares boost::hana::take_back.
Forward declares boost::hana::take_front and boost::hana::take_front_c.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::take_front |
Returns the first n elements of a sequence, or the whole sequence if the sequence has less than n elements.Given a Sequence xs and an IntegralConstant n, take_front(xs, n) is a new sequence containing the first n elements of xs, in the same order. If length(xs) <= n, the whole sequence is returned and no error is triggered. More... | |
| template<std::size_t n> | |
| constexpr auto | boost::hana::take_front_c |
Equivalent to take_front; provided for convenience. More... | |
Forward declares boost::hana::take_front and boost::hana::take_front_c.
Forward declares boost::hana::take_while.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::take_while |
Take elements from a sequence while the predicate is satisfied.Specifically, take_while returns a new sequence containing the longest prefix of xs in which all the elements satisfy the given predicate. More... | |
Forward declares boost::hana::take_while.
Forward declares boost::hana::tap.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<typename M > | |
| constexpr auto | boost::hana::tap |
Tap inside a monadic chain.Given a function f, tap<M> returns a new function which performs f on its argument and then returns the argument lifted in the M Monad. Combined with the property that chain(m, lift<M>) == m, this provides a way of executing an action inside a monadic chain without influencing its overall result. This is useful to e.g. insert debug statements or perform actions that are not tied to the chain but that need to be executed inside of it. More... | |
Forward declares boost::hana::tap.
Forward declares boost::hana::then.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::then |
| Sequentially compose two monadic actions, discarding any value produced by the first but not its effects. More... | |
Forward declares boost::hana::then.
Forward declares boost::hana::transform.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::transform |
Map a function over a Functor. More... | |
Forward declares boost::hana::transform.
Forward declares boost::hana::tuple.
+More...
+Classes | |
| struct | boost::hana::tuple< Xn > |
| General purpose index-based heterogeneous sequence with a fixed length. More... | |
| struct | boost::hana::tuple_tag |
Tag representing hana::tuples. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::tuple.
Forward declares boost::hana::type and related utilities.
+More...
+Classes | |
| struct | boost::hana::basic_type< T > |
Base class of hana::type; used for pattern-matching. More... | |
| struct | boost::hana::type< T > |
| C++ type in value-level representation. More... | |
| struct | boost::hana::type_tag |
Tag representing hana::type. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<template< typename... > class F> | |
| constexpr auto | boost::hana::template_ |
Lift a template to a Metafunction.Given a template class or template alias f, template_<f> is a Metafunction satisfying. More... | |
| template<template< typename... > class F> | |
| constexpr auto | boost::hana::metafunction |
Lift a MPL-style metafunction to a Metafunction.Given a MPL-style metafunction, metafunction<f> is a Metafunction satisfying. More... | |
| template<typename F > | |
| constexpr auto | boost::hana::metafunction_class |
Lift a MPL-style metafunction class to a Metafunction.Given a MPL-style metafunction class, metafunction_class<f> is a Metafunction satisfying. More... | |
| constexpr auto | boost::hana::integral |
Turn a Metafunction into a function taking types and returning a default-constructed object.Given a Metafunction f, integral returns a new Metafunction that default-constructs an object of the type returned by f. More specifically, the following holds: More... | |
| template<template< typename... > class F> | |
| constexpr auto | boost::hana::trait = hana::integral(hana::metafunction<F>) |
Alias to integral(metafunction<F>), provided for convenience. More... | |
Forward declares boost::hana::type and related utilities.
Forward declares boost::hana::unfold_left.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<typename S > | |
| constexpr auto | boost::hana::unfold_left |
Dual operation to fold_left for sequences.While fold_left reduces a structure to a summary value from the left, unfold_left builds a sequence from a seed value and a function, starting from the left. More... | |
Forward declares boost::hana::unfold_left.
Forward declares boost::hana::unfold_right.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<typename S > | |
| constexpr auto | boost::hana::unfold_right |
Dual operation to fold_right for sequences.While fold_right reduces a structure to a summary value from the right, unfold_right builds a sequence from a seed value and a function, starting from the right. More... | |
Forward declares boost::hana::unfold_right.
Forward declares boost::hana::union_.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Forward declares boost::hana::union_.
Forward declares boost::hana::unique.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::unique |
Removes all consecutive duplicate elements from a Sequence.Given a Sequence and an optional binary predicate, unique returns a new sequence containing only the first element of every subrange of the original sequence whose elements are all equal. In other words, it turns a sequence of the form [a, a, b, c, c, c, d, d, d, a] into a sequence [a, b, c, d, a]. The equality of two elements is determined by the provided predicate, or by equal if no predicate is provided. More... | |
Forward declares boost::hana::unique.
Forward declares boost::hana::unpack.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::unpack |
Invoke a function with the elements of a Foldable as arguments.Given a function and a foldable structure whose length can be known at compile-time, unpack invokes the function with the contents of that structure. In other words, unpack(xs, f) is equivalent to f(x...), where x... are the elements of the structure. The length of the structure must be known at compile-time, because the version of f's operator() that will be compiled depends on the number of arguments it is called with, which has to be known at compile-time. More... | |
Forward declares boost::hana::unpack.
Forward declares boost::hana::value.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<typename T > | |
| constexpr auto | boost::hana::value |
Return the compile-time value associated to a constant.This function returns the value associated to a Constant. That value is always a constant expression. The normal way of using value on an object c is. More... | |
| constexpr auto | boost::hana::value_of |
Equivalent to value, but can be passed to higher-order algorithms.This function object is equivalent to value, except it can be passed to higher order algorithms because it is a function object. value can't be passed to higher-order algorithms because it is implemented as an overloaded function. More... | |
Forward declares boost::hana::value.
Forward declares boost::hana::while_.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::while_ |
Apply a function to an initial state while some predicate is satisfied.This method is a natural extension of the while language construct to manipulate a state whose type may change from one iteration to another. However, note that having a state whose type changes from one iteration to the other is only possible as long as the predicate returns a Logical whose truth value is known at compile-time. More... | |
Forward declares boost::hana::while_.
Forward declares boost::hana::zero.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<typename M > | |
| constexpr auto | boost::hana::zero |
Identity of plus. More... | |
Forward declares boost::hana::zero.
Forward declares boost::hana::zip.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::zip |
Zip one sequence or more.Given n sequences s1, ..., sn, zip produces a sequence whose i-th element is a tuple of (s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip produces a sequence of the form. More... | |
Forward declares boost::hana::zip.
Forward declares boost::hana::zip_shortest.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::zip_shortest |
Zip one sequence or more.Given n sequences s1, ..., sn, zip_shortest produces a sequence whose i-th element is a tuple of (s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip_shortest produces a sequence of the form. More... | |
Forward declares boost::hana::zip_shortest.
Forward declares boost::hana::zip_shortest_with.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::zip_shortest_with |
Zip one sequence or more with a given function.Given a n-ary function f and n sequences s1, ..., sn, zip_shortest_with produces a sequence whose i-th element is f(s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip_shortest_with produces a sequence of the form. More... | |
Forward declares boost::hana::zip_shortest_with.
Forward declares boost::hana::zip_with.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::zip_with |
Zip one sequence or more with a given function.Given a n-ary function f and n sequences s1, ..., sn, zip_with produces a sequence whose i-th element is f(s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip_with produces a sequence of the form. More... | |
Forward declares boost::hana::zip_with.
Defines boost::hana::greater.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::greater.
Defines boost::hana::greater_equal.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::greater_equal.
Defines boost::hana::group.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::group.
The Applicative concept represents Functors with the ability to lift values and combine computations.
A Functor can only take a normal function and map it over a structure containing values to obtain a new structure containing values. Intuitively, an Applicative can also take a value and lift it into the structure. In addition, an Applicative can take a structure containing functions and apply it to a structure containing values to obtain a new structure containing values. By currying the function(s) inside the structure, it is then also possible to apply n-ary functions to n structures containing values.
lift and ap satisfying the laws below. An Applicative must also be a Functor.
Given an Applicative F, the following laws must be satisfied:
xs of tag F(A), xs of tag F(A) and functions-in-an-applicative \( fs : F(B \to C) \), \( gs : F(A \to B) \), x of tag A and functions \( f : A \to B \), x of tag A and functions-in-an-applicative \( fs : F(A \to B) \), where apply(-, x) denotes the partial application of the apply function from the Functional module to the x argument.As a consequence of these laws, the model of Functor for F will satisfy the following for all objects xs of tag F(A) and functions \( f : A \to B \):
Functor (free model)Applicative F can be made a Functor by setting hana::lazy, hana::optional, hana::tuple
An applicative transformation is a function \( t : F(X) \to G(X) \) between two Applicatives F and G, where X can be any tag, and which preserves the operations of an Applicative. In other words, for all objects x of tag X, functions-in-an-applicative \( fs : F(X \to Y) \) and objects xs of tag F(X),
+Variables | |
| constexpr auto | boost::hana::ap |
Lifted application.Specifically, ap applies a structure containing functions to a structure containing values, and returns a new structure containing values. The exact way in which the functions are applied to the values depends on the Applicative. More... | |
| template<typename A > | |
| constexpr auto | boost::hana::lift |
Lift a value into an Applicative structure.lift<A> takes a normal value and embeds it into a structure whose shape is represented by the A Applicative. Note that the value may be a function, in which case the created structure may be applied to another Applicative structure containing values. More... | |
| constexpr auto boost::hana::ap | +
#include <boost/hana/fwd/ap.hpp>
Lifted application.Specifically, ap applies a structure containing functions to a structure containing values, and returns a new structure containing values. The exact way in which the functions are applied to the values depends on the Applicative.
ap can be called with two arguments or more; the functions in the f structure are curried and then applied to the values in each x... structure using the binary form of ap. Note that this requires the number of x... must match the arity of the functions in the f structure. In other words, ap(f, x1, ..., xN) is equivalent to
where f' is f but containing curried functions instead and x <ap> y is just ap(x, y) written in infix notation to emphasize the left associativity.
Given an Applicative A, the signature is \( \mathtt{ap} : A(T_1 \times \cdots \times T_n \to U) \times A(T_1) \times \cdots \times A(T_n) \to A(U) \).
| f | A structure containing function(s). |
| x... | Structure(s) containing value(s) and on which f is applied. The number of structures must match the arity of the functions in the f structure. |
| constexpr auto boost::hana::lift | +
#include <boost/hana/fwd/lift.hpp>
Lift a value into an Applicative structure.lift<A> takes a normal value and embeds it into a structure whose shape is represented by the A Applicative. Note that the value may be a function, in which case the created structure may be applied to another Applicative structure containing values.
Given an Applicative A, the signature is \( \mathtt{lift}_A : T \to A(T) \).
| A | A tag representing the Applicative into which the value is lifted. |
| x | The value to lift into the applicative. |
The Comonad concept represents context-sensitive computations and data.
Formally, the Comonad concept is dual to the Monad concept. But unless you're a mathematician, you don't care about that and it's fine. So intuitively, a Comonad represents context sensitive values and computations. First, Comonads make it possible to extract context-sensitive values from their context with extract. In contrast, Monads make it possible to wrap raw values into a given context with lift (from Applicative).
Secondly, Comonads make it possible to apply context-sensitive values to functions accepting those, and to return the result as a context-sensitive value using extend. In contrast, Monads make it possible to apply a monadic value to a function accepting a normal value and returning a monadic value, and to return the result as a monadic value (with chain).
Finally, Comonads make it possible to wrap a context-sensitive value into an extra layer of context using duplicate, while Monads make it possible to take a value with an extra layer of context and to strip it with flatten.
Whereas lift, chain and flatten from Applicative and Monad have signatures
+\begin{align*} \mathtt{lift}_M &: T \to M(T) \\ \mathtt{chain} &: M(T) \times (T \to M(U)) \to M(U) \\ \mathtt{flatten} &: M(M(T)) \to M(T) \end{align*} +
+extract, extend and duplicate from Comonad have signatures
+\begin{align*} \mathtt{extract} &: W(T) \to T \\ \mathtt{extend} &: W(T) \times (W(T) \to U) \to W(U) \\ \mathtt{duplicate} &: W(T) \to W(W(T)) \end{align*} +
+Notice how the "arrows" are reversed. This symmetry is essentially what we mean by Comonad being the dual of Monad.
+extract and (extend or duplicate) satisfying the laws below. A Comonad must also be a Functor.
For all Comonads w, the following laws must be satisfied:
Functor, hence the requirement that a Comonad also is a Functor.+Variables | |
| constexpr auto | boost::hana::duplicate |
Add an extra layer of comonadic context to a comonadic value.Given a value already in a comonadic context, duplicate wraps this value with an additional layer of comonadic context. This can be seen as the dual operation to flatten from the Monad concept. More... | |
| constexpr auto | boost::hana::extend |
Comonadic application of a function to a comonadic value.Given a comonadic value and a function accepting a comonadic input, extend returns the result of applying the function to that input inside the comonadic context. More... | |
| constexpr auto | boost::hana::extract |
Extract a value in a given comonadic context.Given a value inside a comonadic context, extract it from that context, performing whatever effects are mandated by that context. This can be seen as the dual operation to the lift method of the Applicative concept. More... | |
| constexpr auto boost::hana::duplicate | +
#include <boost/hana/fwd/duplicate.hpp>
Add an extra layer of comonadic context to a comonadic value.Given a value already in a comonadic context, duplicate wraps this value with an additional layer of comonadic context. This can be seen as the dual operation to flatten from the Monad concept.
Given a Comonad W, the signature is \( \mathtt{duplicate} : W(T) \to W(W(T)) \)
| w | The value to wrap in an additional level of comonadic context. |
| constexpr auto boost::hana::extend | +
#include <boost/hana/fwd/extend.hpp>
Comonadic application of a function to a comonadic value.Given a comonadic value and a function accepting a comonadic input, extend returns the result of applying the function to that input inside the comonadic context.
Given a Comonad W and a function of type \( W(T) \to U \), the signature is \( \mathtt{extend} : W(T) \times (W(T) \to U) \to W(U) \)
| w | A comonadic value to call the function with. |
| f | A function of signature \( W(T) \to U \) to be applied to its comonadic argument inside the comonadic context. |
| constexpr auto boost::hana::extract | +
#include <boost/hana/fwd/extract.hpp>
Extract a value in a given comonadic context.Given a value inside a comonadic context, extract it from that context, performing whatever effects are mandated by that context. This can be seen as the dual operation to the lift method of the Applicative concept.
Given a Comonad W, the signature is \( \mathtt{extract} : W(T) \to T \)
| w | The value to be extracted inside a comonadic context. |
The Comparable concept defines equality and inequality.
Intuitively, Comparable objects must define a binary predicate named equal that returns whether both objects represent the same abstract value. In other words, equal must check for deep equality. Since "representing the same abstract value" is difficult to express formally, the exact meaning of equality is partially left to interpretation by the programmer with the following guidelines:
+
equal value.4/8 should be equal to an object representing a fraction as 2/4, because they both represent the mathematical object 1/2.Moreover, equal must exhibit properties that make it intuitive to use for determining the equivalence of objects, which is formalized by the laws for Comparable.
equalequal is defined, not_equal is implemented by default as its complement. For all objects x, y of a Comparable tag, equal must define an equivalence relation, and not_equal must be its complement. In other words, for all objects a, b, c with a Comparable tag, the following must hold:
hana::integral_constant, hana::map, hana::optional, hana::pair, hana::range, hana::set, hana::string, hana::tuple, hana::type
EqualityComparable data types Two data types T and U that model the cross-type EqualityComparable concept presented in N3351 automatically model the Comparable concept by setting
Note that this also makes EqualityComparable types in the usual sense models of Comparable in the same way.
Let A and B be two Comparable tags. A function \(f : A \to B\) is said to be equality-preserving if it preserves the structure of the Comparable concept, which can be rigorously stated as follows. For all objects x, y of tag A,
Equivalently, we simply require that f is a function in the usual mathematical sense. Another property is injectivity, which can be viewed as being a "lossless" mapping. This property can be stated as
This is equivalent to saying that f maps distinct elements to distinct elements, hence the "lossless" analogy. In other words, f will not collapse distinct elements from its domain into a single element in its image, thus losing information.
These functions are very important, especially equality-preserving ones, because they allow us to reason simply about programs. Also note that the property of being equality-preserving is taken for granted in mathematics because it is part of the definition of a function. We feel it is important to make the distinction here because programming has evolved differently and as a result programmers are used to work with functions that do not preserve equality.
+The equal and not_equal methods are "overloaded" to handle distinct tags with certain properties. Specifically, they are defined for distinct tags A and B such that
A and B share a common tag C, as determined by the common metafunctionA, B and C are all Comparable when taken individuallyis_embedding metafunction.The method definitions for tags satisfying the above properties are
equal In the context of programming with heterogeneous values, it is useful to have unrelated objects compare false instead of triggering an error. For this reason, equal adopts a special behavior for unrelated objects of tags T and U that do not satisfy the above requirements for the cross-type overloads. Specifically, when T and U are unrelated (i.e. T can't be converted to U and vice-versa), comparing objects with those tags yields a compile-time false value. This has the effect that unrelated objects like float and std::string will compare false, while comparing related objects that can not be safely embedded into the same super structure (like long long and float because of the precision loss) will trigger a compile-time assertion. Also note that for any tag T for which the minimal complete definition of Comparable is not provided, a compile-time assertion will also be triggered because T and T trivially share the common tag T, which is the expected behavior. This design choice aims to provide more flexibility for comparing objects, while still rejecting usage patterns that are most likely programming errors.
+Variables | |
| constexpr auto | boost::hana::comparing |
Returns a function performing equal after applying a transformation to both arguments.comparing creates an equivalence relation based on the result of applying a function to some objects, which is especially useful in conjunction with algorithms that accept a custom predicate that must represent an equivalence relation. More... | |
| constexpr auto | boost::hana::equal |
Returns a Logical representing whether x is equal to y.The equal function can be called in two different ways. First, it can be called like a normal function: More... | |
| constexpr auto | boost::hana::not_equal |
Returns a Logical representing whether x is not equal to y.The not_equal function can be called in two different ways. First, it can be called like a normal function: More... | |
| constexpr auto boost::hana::comparing | +
#include <boost/hana/fwd/comparing.hpp>
Returns a function performing equal after applying a transformation to both arguments.comparing creates an equivalence relation based on the result of applying a function to some objects, which is especially useful in conjunction with algorithms that accept a custom predicate that must represent an equivalence relation.
Specifically, comparing is such that
or, equivalently,
Comparable concept.Given a Logical Bool and a Comparable B, the signature is \( \mathtt{comparing} : (A \to B) \to (A \times A \to Bool) \).
| constexpr auto boost::hana::equal | +
#include <boost/hana/fwd/equal.hpp>
Returns a Logical representing whether x is equal to y.The equal function can be called in two different ways. First, it can be called like a normal function:
However, it may also be partially applied to an argument by using equal.to:
In other words, equal.to(x) is a function object that is equivalent to partial(equal, x). This is provided to enhance the readability of some constructs, especially when using higher order algorithms.
Given a Logical Bool and two Comparables A and B that share a common embedding, the signature is \( \mathtt{equal} : A \times B \to Bool \).
| x,y | Two objects to compare for equality. |
++ +Rationale for the arity of
+equalIt is a valid question whether
equalshould accept more than 2 arguments and have semantics matching those of Python's==. This is not supported right now for the following reasons:+
+- It was implemented in the MPL11, but it was not shown to be useful so far.
+- It does not make sense for
+not_equalto have an arity of more than 2, onlyequalcould maybe have those semantics, which would break symmetry.
| constexpr auto boost::hana::not_equal | +
#include <boost/hana/fwd/not_equal.hpp>
Returns a Logical representing whether x is not equal to y.The not_equal function can be called in two different ways. First, it can be called like a normal function:
However, it may also be partially applied to an argument by using not_equal.to:
In other words, not_equal.to(x) is a function object that is equivalent to partial(not_equal, x). This is provided to enhance the readability of some constructs, especially when using higher order algorithms.
Given a Logical Bool and two Comparables A and B that share a common embedding, the signature is \( \mathtt{not\_equal} : A \times B \to Bool \).
| x,y | Two objects to compare for inequality. |
The Constant concept represents data that can be manipulated at compile-time.
At its core, Constant is simply a generalization of the principle behind std::integral_constant to all types that can be constructed at compile-time, i.e. to all types with a constexpr constructor (also called Literal types). More specifically, a Constant is an object from which a constexpr value may be obtained (through the value method) regardless of the constexprness of the object itself.
All Constants must be somewhat equivalent, in the following sense. Let C(T) and D(U) denote the tags of Constants holding objects of type T and U, respectively. Then, an object with tag D(U) must be convertible to an object with tag C(T) whenever U is convertible to T, has determined by is_convertible. The interpretation here is that a Constant is just a box holding an object of some type, and it should be possible to swap between boxes whenever the objects inside the boxes can be swapped.
Because of this last requirement, one could be tempted to think that specialized "boxes" like std::integral_constant are prevented from being Constants because they are not able to hold objects of any type T (std::integral_constant may only hold integral types). This is false; the requirement should be interpreted as saying that whenever C(T) is meaningful (e.g. only when T is integral for std::integral_constant) and there exists a conversion from U to T, then a conversion from D(U) to C(T) should also exist. The precise requirements for being a Constant are embodied in the following laws.
value and to, satisfying the laws below.
Let c be an object of with tag C, which represents a Constant holding an object with tag T. The first law ensures that the value of the wrapped object is always a constant expression by requiring the following to be well-formed:
This means that the value function must return an object that can be constructed at compile-time. It is important to note how value only receives the type of the object and not the object itself. This is the core of the Constant concept; it means that the only information required to implement value must be stored in the type of its argument, and hence be available statically.
The second law that must be satisfied ensures that Constants are basically dumb boxes, which makes it possible to provide models for many concepts without much work from the user. The law simply asks for the following expression to be valid:
where, i is an arbitrary Constant holding an internal value with a tag that can be converted to T, as determined by the hana::is_convertible metafunction. In other words, whenever U is convertible to T, a Constant holding a U is convertible to a Constant holding a T, if such a Constant can be created.
Finally, the tag C must provide a nested value_type alias to T, which allows us to query the tag of the inner value held by objects with tag C. In other words, the following must be true for any object c with tag C:
In certain cases, a Constant can automatically be made a model of another concept. In particular, if a Constant C is holding an object of tag T, and if T models a concept X, then C may in most cases model X by simply performing whatever operation is required on its underlying value, and then wrapping the result back in a C.
More specifically, if a Constant C has an underlying value (C::value_type) which is a model of Comparable, Orderable, Logical, or Monoid up to EuclideanRing, then C must also be a model of those concepts. In other words, when C::value_type models one of the listed concepts, C itself must also model that concept. However, note that free models are provided for all of those concepts, so no additional work must be done.
While it would be possible in theory to provide models for concepts like Foldable too, only a couple of concepts are useful to have as Constant in practice. Providing free models for the concepts listed above is useful because it allows various types of integral constants (std::integral_constant, mpl::integral_c, etc...) to easily have models for them just by defining the Constant concept.
Constant is actually the canonical embedding of the subcategory of constexpr things into the Hana category, which contains everything in this library. Hence, whatever is true in that subcategory is also true here, via this functor. This is why we can provide models of any concept that works on constexpr things for Constants, by simply passing them through that embedding.Any Constant c holding an underlying value of tag T is convertible to any tag U such that T is convertible to U. Specifically, the conversion is equivalent to
Also, those conversions are marked as an embedding whenever the conversion of underlying types is an embedding. This is to allow Constants to inter-operate with constexpr objects easily:
Strictly speaking, this is sometimes a violation of what it means to be an embedding. Indeed, while there exists an embedding from any Constant to a constexpr object (since Constant is just the canonical inclusion), there is no embedding from a Constant to a runtime object since we would lose the ability to define the value method (the constexprness of the object would have been lost). Since there is no way to distinguish constexpr and non-constexpr objects based on their type, Hana has no way to know whether the conversion is to a constexpr object of not. In other words, the to method has no way to differentiate between
which is an embedding, and
which isn't. To be on the safer side, we could mark the conversion as not-an-embedding. However, if e.g. the conversion from integral_constant_tag<int> to int was not marked as an embedding, we would have to write plus(to<int>(int_<1>), 1) instead of just plus(int_<1>, 1), which is cumbersome. Hence, the conversion is marked as an embedding, but this also means that code like
will be considered valid, which implicitly loses the fact that int_<1> is a Constant, and hence does not follow the usual rules for cross-type operations in Hana.
Because of the requirement that Constants be interchangeable when their contents are compatible, two Constants A and B will have a common data type whenever A::value_type and B::value_type have one. Their common data type is an unspecified Constant C such that C::value_type is exactly common_t<A::value_type, B::value_type>. A specialization of the common metafunction is provided for Constants to reflect this.
In the same vein, a common data type is also provided from any constant A to a type T such that A::value_type and T share a common type. The common type between A and T is obviously the common type between A::value_type and T. As explained above in the section on conversions, this is sometimes a violation of the definition of a common type, because there must be an embedding to the common type, which is not always the case. For the same reasons as explained above, this common type is still provided.
+Variables | |
| template<typename T > | |
| constexpr auto | boost::hana::value |
Return the compile-time value associated to a constant.This function returns the value associated to a Constant. That value is always a constant expression. The normal way of using value on an object c is. More... | |
| constexpr auto | boost::hana::value_of |
Equivalent to value, but can be passed to higher-order algorithms.This function object is equivalent to value, except it can be passed to higher order algorithms because it is a function object. value can't be passed to higher-order algorithms because it is implemented as an overloaded function. More... | |
| constexpr auto boost::hana::value | +
#include <boost/hana/fwd/value.hpp>
Return the compile-time value associated to a constant.This function returns the value associated to a Constant. That value is always a constant expression. The normal way of using value on an object c is.
However, for convenience, an overload of value is provided so that it can be called as:
This overload works by taking a const& to its argument, and then forwarding to the first version of value. Since it does not use its argument, the result can still be a constant expression, even if the argument is not a constant expression.
value<T>() is tag-dispatched as value_impl<C>::apply<T>(), where C is the tag of T.hana::value is an overloaded function, not a function object. Hence, it can't be passed to higher-order algorithms. If you need an equivalent function object, use hana::value_of instead.Referenced by boost::hana::literals::operator""_c(), boost::hana::literals::operator""_s(), and boost::hana::optional< T >::optional().
+ +| constexpr auto boost::hana::value_of | +
#include <boost/hana/fwd/value.hpp>
Equivalent to value, but can be passed to higher-order algorithms.This function object is equivalent to value, except it can be passed to higher order algorithms because it is a function object. value can't be passed to higher-order algorithms because it is implemented as an overloaded function.
value, and hence it is not tag-dispatched and can't be customized.The EuclideanRing concept represents a commutative Ring that can also be endowed with a division algorithm.
A Ring defines a binary operation often called multiplication that can be used to combine two elements of the ring into a new element of the ring. An Euclidean ring, also called an Euclidean domain, adds the ability to define a special function that generalizes the Euclidean division of integers.
+However, an Euclidean ring must also satisfy one more property, which is that of having no non-zero zero divisors. In a Ring (R, +, *), it follows quite easily from the axioms that x * 0 == 0 for any ring element x. However, there is nothing that mandates 0 to be the only ring element sending other elements to 0. Hence, in some Rings, it is possible to have elements x and y such that x * y == 0 while not having x == 0 nor y == 0. We call these elements divisors of zero, or zero divisors. For example, this situation arises in the Ring of integers modulo 4 (the set {0, 1, 2, 3}) with addition and multiplication mod 4 as binary operations. In this case, we have that
even though 2 != 0 (mod 4).
Following this line of thought, an Euclidean ring requires its only zero divisor is zero itself. In other words, the multiplication in an Euclidean won't send two non-zero elements to zero. Also note that since multiplication in a Ring is not necessarily commutative, it is not always the case that
To be rigorous, we should then distinguish between elements that are zero divisors when multiplied to the right and to the left. Fortunately, the concept of an Euclidean ring requires the Ring multiplication to be commutative. Hence,
and we do not have to distinguish between left and right zero divisors.
+Typical examples of Euclidean rings include integers and polynomials over a field. The method names used here refer to the Euclidean ring of integers under the usual addition, multiplication and division operations.
+div and mod satisfying the laws below
To simplify the reading, we will use the +, *, / and % operators with infix notation to denote the application of the corresponding methods in Monoid, Group, Ring and EuclideanRing. For all objects a and b of an EuclideanRing R, the following laws must be satisfied:
Monoid, Group, Ring
A data type T is integral if std::is_integral<T>::value is true. For a non-boolean integral data type T, a model of EuclideanRing is automatically defined by using the Ring model provided for arithmetic data types and setting
bool is the same as for not providing Monoid, Group and Ring models.+Variables | |
| constexpr auto | boost::hana::div |
| Generalized integer division. More... | |
| constexpr auto | boost::hana::mod |
Generalized integer modulus.Given two elements of an EuclideanRing x and y, with y nonzero, mod returns the modulus of the division of x by y. In other words, mod can be seen as an equivalent to %. More... | |
| constexpr auto boost::hana::div | +
#include <boost/hana/fwd/div.hpp>
Generalized integer division.
+The div method is "overloaded" to handle distinct data types with certain properties. Specifically, div is defined for distinct data types A and B such that
A and B share a common data type C, as determined by the common metafunctionA, B and C are all EuclideanRings when taken individuallyto<C> : A -> B and to<C> : B -> C are Ring-embeddings, as determined by the is_embedding metafunction.In that case, the div method is defined as
| constexpr auto boost::hana::mod | +
#include <boost/hana/fwd/mod.hpp>
Generalized integer modulus.Given two elements of an EuclideanRing x and y, with y nonzero, mod returns the modulus of the division of x by y. In other words, mod can be seen as an equivalent to %.
The mod method is "overloaded" to handle distinct data types with certain properties. Specifically, mod is defined for distinct data types A and B such that
A and B share a common data type C, as determined by the common metafunctionA, B and C are all EuclideanRings when taken individuallyto<C> : A -> B and to<C> : B -> C are Ring-embeddings, as determined by the is_embedding metafunction.In that case, mod is defined as
The Foldable concept represents data structures that can be reduced to a single value.
Generally speaking, folding refers to the concept of summarizing a complex structure as a single value, by successively applying a binary operation which reduces two elements of the structure to a single value. Folds come in many flavors; left folds, right folds, folds with and without an initial reduction state, and their monadic variants. This concept is able to express all of these fold variants.
+Another way of seeing Foldable is as data structures supporting internal iteration with the ability to accumulate a result. By internal iteration, we mean that the loop control is in the hand of the structure, not the caller. Hence, it is the structure who decides when the iteration stops, which is normally when the whole structure has been consumed. Since C++ is an eager language, this requires Foldable structures to be finite, or otherwise one would need to loop indefinitely to consume the whole structure.
Foldable only works for finite structures may seem overly restrictive in comparison to the Haskell definition of Foldable, a finer grained separation of the concepts should mitigate the issue. For iterating over possibly infinite data structures, see the Iterable concept. For searching a possibly infinite data structure, see the Searchable concept.fold_left or unpack
However, please note that a minimal complete definition provided through unpack will be much more compile-time efficient than one provided through fold_left.
hana::map, hana::optional, hana::pair, hana::set, hana::range, hana::tuple
Foldable Intuitively, for a Foldable structure xs, the linearization of xs is the sequence of all the elements in xs as if they had been put in a list:
Note that it is always possible to produce such a linearization for a finite Foldable by setting
for an appropriate definition of [] and prepend. The notion of linearization is useful for expressing various properties of Foldable structures, and is used across the documentation. Also note that Iterables define an extended version of this allowing for infinite structures.
A compile-time Foldable is a Foldable whose total length is known at compile-time. In other words, it is a Foldable whose length method returns a Constant of an unsigned integral type. When folding a compile-time Foldable, the folding can be unrolled, because the final number of steps of the algorithm is known at compile-time.
Additionally, the unpack method is only available to compile-time Foldables. This is because the return type of unpack depends on the number of objects in the structure. Being able to resolve unpack's return type at compile-time hence requires the length of the structure to be known at compile-time too.
In the current version of the library, only compile-time Foldables are supported. While it would be possible in theory to support runtime Foldables too, doing so efficiently requires more research.
Sequences Given a tag S which is a Sequence, an object whose tag is a model of the Foldable concept can be converted to an object of tag S. In other words, a Foldable can be converted to a Sequence S, by simply taking the linearization of the Foldable and creating the sequence with that. More specifically, given a Foldable xs with a linearization of [x1, ..., xn] and a Sequence tag S, to<S>(xs) is equivalent to make<S>(x1, ..., xn).
Builtin arrays whose size is known can be folded as-if they were homogeneous tuples. However, note that builtin arrays can't be made more than Foldable (e.g. Iterable) because they can't be empty and they also can't be returned from functions.
A monadic fold is a fold in which subsequent calls to the binary function are chained with the monadic chain operator of the corresponding Monad. This allows a structure to be folded in a custom monadic context. For example, performing a monadic fold with the hana::optional monad would require the binary function to return the result as a hana::optional, and the fold would abort and return nothing whenever one of the accumulation step would fail (i.e. return nothing). If, however, all the reduction steps succeed, then just the result would be returned. Different monads will of course result in different effects.
+Variables | |
| constexpr auto | boost::hana::count |
Return the number of elements in the structure that compare equal to a given value.Given a Foldable structure xs and a value value, count returns an unsigned integral, or a Constant thereof, representing the number of elements of xs that compare equal to value. For this method to be well-defined, all the elements of the structure must be Comparable with the given value. More... | |
| constexpr auto | boost::hana::count_if |
Return the number of elements in the structure for which the predicate is satisfied.Specifically, returns an object of an unsigned integral type, or a Constant holding such an object, which represents the number of elements in the structure satisfying the given predicate. More... | |
| constexpr auto | boost::hana::fold = fold_left |
Equivalent to fold_left; provided for convenience.fold is equivalent to fold_left. However, it is not tag-dispatched on its own because it is just an alias to fold_left. Also note that fold can be called with or without an initial state, just like fold_left: More... | |
| constexpr auto | boost::hana::fold_left |
Left-fold of a structure using a binary operation and an optional initial reduction state.fold_left is a left-associative fold using a binary operation. Given a structure containing x1, ..., xn, a function f and an optional initial state, fold_left applies f as follows. More... | |
| constexpr auto | boost::hana::fold_right |
Right-fold of a structure using a binary operation and an optional initial reduction state.fold_right is a right-associative fold using a binary operation. Given a structure containing x1, ..., xn, a function f and an optional initial state, fold_right applies f as follows. More... | |
| constexpr auto | boost::hana::for_each |
Perform an action on each element of a foldable, discarding the result each time.Iteration is done from left to right, i.e. in the same order as when using fold_left. If the structure is not finite, this method will not terminate. More... | |
| constexpr auto | boost::hana::fuse |
Transform a function taking multiple arguments into a function that can be called with a compile-time Foldable. More... | |
| constexpr auto | boost::hana::length |
Return the number of elements in a foldable structure.Given a Foldable xs, length(xs) must return an object of an unsigned integral type, or an IntegralConstant holding such an object, which represents the number of elements in the structure. More... | |
| constexpr auto | boost::hana::maximum |
Return the greatest element of a non-empty structure with respect to a predicate, by default less.Given a non-empty structure and an optional binary predicate (less by default), maximum returns the greatest element of the structure, i.e. an element which is greater than or equal to every other element in the structure, according to the predicate. More... | |
| constexpr auto | boost::hana::minimum |
Return the least element of a non-empty structure with respect to a predicate, by default less.Given a non-empty structure and an optional binary predicate (less by default), minimum returns the least element of the structure, i.e. an element which is less than or equal to every other element in the structure, according to the predicate. More... | |
| template<typename M > | |
| constexpr auto | boost::hana::monadic_fold_left |
| Monadic left-fold of a structure with a binary operation and an optional initial reduction state. More... | |
| template<typename M > | |
| constexpr auto | boost::hana::monadic_fold_right |
| Monadic right-fold of a structure with a binary operation and an optional initial reduction state. More... | |
| constexpr auto | boost::hana::product = see documentation |
Compute the product of the numbers of a structure.More generally, product will take any foldable structure containing objects forming a Ring and reduce them using the Ring's binary operation. The initial state for folding is the identity of the Ring's operation. It is sometimes necessary to specify the Ring to use; this is possible by using product<R>. If no Ring is specified, the structure will use the Ring formed by the elements it contains (if it knows it), or integral_constant_tag<int> otherwise. Hence,. More... | |
| constexpr auto | boost::hana::reverse_fold |
Equivalent to reverse_fold in Boost.Fusion and Boost.MPL.This method has the same semantics as reverse_fold in Boost.Fusion and Boost.MPL, with the extension that an initial state is not required. This method is equivalent to fold_right, except that the accumulating function must take its arguments in reverse order, to match the order used in Fusion. In other words,. More... | |
| constexpr auto | boost::hana::size = hana::length |
Equivalent to length; provided for consistency with the standard library.This method is an alias to length provided for convenience and consistency with the standard library. As an alias, size is not tag-dispatched on its own and length should be customized instead. More... | |
| constexpr auto | boost::hana::sum = see documentation |
Compute the sum of the numbers of a structure.More generally, sum will take any foldable structure containing objects forming a Monoid and reduce them using the Monoid's binary operation. The initial state for folding is the identity of the Monoid. It is sometimes necessary to specify the Monoid to use; this is possible by using sum<M>. If no Monoid is specified, the structure will use the Monoid formed by the elements it contains (if it knows it), or integral_constant_tag<int> otherwise. Hence,. More... | |
| constexpr auto | boost::hana::unpack |
Invoke a function with the elements of a Foldable as arguments.Given a function and a foldable structure whose length can be known at compile-time, unpack invokes the function with the contents of that structure. In other words, unpack(xs, f) is equivalent to f(x...), where x... are the elements of the structure. The length of the structure must be known at compile-time, because the version of f's operator() that will be compiled depends on the number of arguments it is called with, which has to be known at compile-time. More... | |
| constexpr auto boost::hana::count | +
#include <boost/hana/fwd/count.hpp>
Return the number of elements in the structure that compare equal to a given value.Given a Foldable structure xs and a value value, count returns an unsigned integral, or a Constant thereof, representing the number of elements of xs that compare equal to value. For this method to be well-defined, all the elements of the structure must be Comparable with the given value.
| xs | The structure whose elements are counted. |
| value | A value compared with each element in the structure. Elements that compare equal to this value are counted, others are not. |
| constexpr auto boost::hana::count_if | +
#include <boost/hana/fwd/count_if.hpp>
Return the number of elements in the structure for which the predicate is satisfied.Specifically, returns an object of an unsigned integral type, or a Constant holding such an object, which represents the number of elements in the structure satisfying the given predicate.
| xs | The structure whose elements are counted. |
| predicate | A function called as predicate(x), where x is an element of the structure, and returning a Logical representing whether x should be counted. |
| constexpr auto boost::hana::fold = fold_left | +
#include <boost/hana/fwd/fold.hpp>
Equivalent to fold_left; provided for convenience.fold is equivalent to fold_left. However, it is not tag-dispatched on its own because it is just an alias to fold_left. Also note that fold can be called with or without an initial state, just like fold_left:
| constexpr auto boost::hana::fold_left | +
#include <boost/hana/fwd/fold_left.hpp>
Left-fold of a structure using a binary operation and an optional initial reduction state.fold_left is a left-associative fold using a binary operation. Given a structure containing x1, ..., xn, a function f and an optional initial state, fold_left applies f as follows.
When the structure is empty, two things may arise. If an initial state was provided, it is returned as-is. Otherwise, if the no-state version of the function was used, an error is triggered. When the stucture contains a single element and the no-state version of the function was used, that single element is returned as is.
+Given a Foldable F and an optional initial state of tag S, the signatures for fold_left are
+\[ \mathtt{fold\_left} : F(T) \times S \times (S \times T \to S) \to S \] +
+for the variant with an initial state, and
+\[ \mathtt{fold\_left} : F(T) \times (T \times T \to T) \to T \] +
+for the variant without an initial state.
+| xs | The structure to fold. |
| state | The initial value used for folding. |
| f | A binary function called as f(state, x), where state is the result accumulated so far and x is an element in the structure. For left folds without an initial state, the function is called as f(x1, x2), where x1 and x2 are elements of the structure. |
| constexpr auto boost::hana::fold_right | +
#include <boost/hana/fwd/fold_right.hpp>
Right-fold of a structure using a binary operation and an optional initial reduction state.fold_right is a right-associative fold using a binary operation. Given a structure containing x1, ..., xn, a function f and an optional initial state, fold_right applies f as follows.
fold_left.When the structure is empty, two things may arise. If an initial state was provided, it is returned as-is. Otherwise, if the no-state version of the function was used, an error is triggered. When the stucture contains a single element and the no-state version of the function was used, that single element is returned as is.
+Given a Foldable F and an optional initial state of tag S, the signatures for fold_right are
+\[ \mathtt{fold\_right} : F(T) \times S \times (T \times S \to S) \to S \] +
+for the variant with an initial state, and
+\[ \mathtt{fold\_right} : F(T) \times (T \times T \to T) \to T \] +
+for the variant without an initial state.
+| xs | The structure to fold. |
| state | The initial value used for folding. |
| f | A binary function called as f(x, state), where state is the result accumulated so far and x is an element in the structure. For right folds without an initial state, the function is called as f(x1, x2), where x1 and x2 are elements of the structure. |
| constexpr auto boost::hana::for_each | +
#include <boost/hana/fwd/for_each.hpp>
Perform an action on each element of a foldable, discarding the result each time.Iteration is done from left to right, i.e. in the same order as when using fold_left. If the structure is not finite, this method will not terminate.
| xs | The structure to iterate over. |
| f | A function called as f(x) for each element x of the structure. The result of f(x), whatever it is, is ignored. |
| constexpr auto boost::hana::fuse | +
#include <boost/hana/fwd/fuse.hpp>
Transform a function taking multiple arguments into a function that can be called with a compile-time Foldable.
This function is provided for convenience as a different way of calling unpack. Specifically, fuse(f) is a function such that
where x... are the elements in the foldable. This function is useful when one wants to create a function that accepts a foldable which is not known yet.
unpack instead.| constexpr auto boost::hana::length | +
#include <boost/hana/fwd/length.hpp>
Return the number of elements in a foldable structure.Given a Foldable xs, length(xs) must return an object of an unsigned integral type, or an IntegralConstant holding such an object, which represents the number of elements in the structure.
Foldables are supported in the library right now, length must always return an IntegralConstant.| constexpr auto boost::hana::maximum | +
#include <boost/hana/fwd/maximum.hpp>
Return the greatest element of a non-empty structure with respect to a predicate, by default less.Given a non-empty structure and an optional binary predicate (less by default), maximum returns the greatest element of the structure, i.e. an element which is greater than or equal to every other element in the structure, according to the predicate.
If the structure contains heterogeneous objects, then the predicate must return a compile-time Logical. If no predicate is provided, the elements in the structure must be Orderable, or compile-time Orderable if the structure is heterogeneous.
Given a Foldable F, a Logical Bool and a predicate \( \mathtt{pred} : T \times T \to Bool \), maximum has the following signatures. For the variant with a provided predicate,
+\[ \mathtt{maximum} : F(T) \times (T \times T \to Bool) \to T \] +
+for the variant without a custom predicate, T is required to be Orderable. The signature is then
+\[ \mathtt{maximum} : F(T) \to T \] +
+| xs | The structure to find the greatest element of. |
| predicate | A function called as predicate(x, y), where x and y are elements of the structure. predicate should be a strict weak ordering on the elements of the structure and its return value should be a Logical, or a compile-time Logical if the structure is heterogeneous. |
maximum.by) maximum can be called in a third way, which provides a nice syntax especially when working with the ordering combinator:
where maximum(-, predicate) denotes the partial application of maximum to predicate.
Both the non-predicated version and the predicated versions of maximum are tag-dispatched methods, and hence they can be customized independently. One reason for this is that some structures are able to provide a much more efficient implementation of maximum when the less predicate is used. Here is how the different versions of maximum are dispatched:
Also note that maximum.by is not tag-dispatched on its own, since it is just syntactic sugar for calling the corresponding maximum.
| constexpr auto boost::hana::minimum | +
#include <boost/hana/fwd/minimum.hpp>
Return the least element of a non-empty structure with respect to a predicate, by default less.Given a non-empty structure and an optional binary predicate (less by default), minimum returns the least element of the structure, i.e. an element which is less than or equal to every other element in the structure, according to the predicate.
If the structure contains heterogeneous objects, then the predicate must return a compile-time Logical. If no predicate is provided, the elements in the structure must be Orderable, or compile-time Orderable if the structure is heterogeneous.
Given a Foldable F, a Logical Bool and a predicate \( \mathtt{pred} : T \times T \to Bool \), minimum has the following signatures. For the variant with a provided predicate,
+\[ \mathtt{minimum} : F(T) \times (T \times T \to Bool) \to T \] +
+for the variant without a custom predicate, T is required to be Orderable. The signature is then
+\[ \mathtt{minimum} : F(T) \to T \] +
+| xs | The structure to find the least element of. |
| predicate | A function called as predicate(x, y), where x and y are elements of the structure. predicate should be a strict weak ordering on the elements of the structure and its return value should be a Logical, or a compile-time Logical if the structure is heterogeneous. |
minimum.by) minimum can be called in a third way, which provides a nice syntax especially when working with the ordering combinator:
where minimum(-, predicate) denotes the partial application of minimum to predicate.
Both the non-predicated version and the predicated versions of minimum are tag-dispatched methods, and hence they can be customized independently. One reason for this is that some structures are able to provide a much more efficient implementation of minimum when the less predicate is used. Here is how the different versions of minimum are dispatched:
Also note that minimum.by is not tag-dispatched on its own, since it is just syntactic sugar for calling the corresponding minimum.
| constexpr auto boost::hana::monadic_fold_left | +
#include <boost/hana/fwd/monadic_fold_left.hpp>
Monadic left-fold of a structure with a binary operation and an optional initial reduction state.
+hana::fold_left, and to have read the primer on monadic folds.monadic_fold_left<M> is a left-associative monadic fold. Given a Foldable with linearization [x1, ..., xn], a function f and an optional initial state, monadic_fold_left<M> applies f as follows:
where f(-, xk) denotes the partial application of f to xk, and | is just the operator version of the monadic chain.
When the structure is empty, one of two things may happen. If an initial state was provided, it is lifted to the given Monad and returned as-is. Otherwise, if the no-state version of the function was used, an error is triggered. When the stucture contains a single element and the no-state version of the function was used, that single element is lifted into the given Monad and returned as is.
+Given a Monad M, a Foldable F, an initial state of tag S, and a function \( f : S \times T \to M(S) \), the signatures of monadic_fold_left<M> are
+\[ \mathtt{monadic\_fold\_left}_M : F(T) \times S \times (S \times T \to M(S)) \to M(S) \] +
+for the version with an initial state, and
+\[ \mathtt{monadic\_fold\_left}_M : F(T) \times (T \times T \to M(T)) \to M(T) \] +
+for the version without an initial state.
+| M | The Monad representing the monadic context in which the fold happens. The return type of f must be in that Monad. |
| xs | The structure to fold. |
| state | The initial value used for folding. If the structure is empty, this value is lifted in to the M Monad and then returned as-is. |
| f | A binary function called as f(state, x), where state is the result accumulated so far and x is an element in the structure. The function must return its result inside the M Monad. |
| constexpr auto boost::hana::monadic_fold_right | +
#include <boost/hana/fwd/monadic_fold_right.hpp>
Monadic right-fold of a structure with a binary operation and an optional initial reduction state.
+hana::fold_right, and to have read the primer on monadic folds.monadic_fold_right<M> is a right-associative monadic fold. Given a structure containing x1, ..., xn, a function f and an optional initial state, monadic_fold_right<M> applies f as follows
where f(xk, -) denotes the partial application of f to xk, and | is just the operator version of the monadic chain. It is worth noting that the order in which the binary function should expect its arguments is reversed from monadic_fold_left<M>.
When the structure is empty, one of two things may happen. If an initial state was provided, it is lifted to the given Monad and returned as-is. Otherwise, if the no-state version of the function was used, an error is triggered. When the stucture contains a single element and the no-state version of the function was used, that single element is lifted into the given Monad and returned as is.
+Given a Monad M, a Foldable F, an initial state of tag S, and a function \( f : T \times S \to M(S) \), the signatures of monadic_fold_right<M> are
+\[ \mathtt{monadic\_fold\_right}_M : F(T) \times S \times (T \times S \to M(S)) \to M(S) \] +
+for the version with an initial state, and
+\[ \mathtt{monadic\_fold\_right}_M : F(T) \times (T \times T \to M(T)) \to M(T) \] +
+for the version without an initial state.
+| M | The Monad representing the monadic context in which the fold happens. The return type of f must be in that Monad. |
| xs | The structure to fold. |
| state | The initial value used for folding. If the structure is empty, this value is lifted in to the M Monad and then returned as-is. |
| f | A binary function called as f(x, state), where state is the result accumulated so far and x is an element in the structure. The function must return its result inside the M Monad. |
| constexpr auto boost::hana::product = see documentation | +
#include <boost/hana/fwd/product.hpp>
Compute the product of the numbers of a structure.More generally, product will take any foldable structure containing objects forming a Ring and reduce them using the Ring's binary operation. The initial state for folding is the identity of the Ring's operation. It is sometimes necessary to specify the Ring to use; this is possible by using product<R>. If no Ring is specified, the structure will use the Ring formed by the elements it contains (if it knows it), or integral_constant_tag<int> otherwise. Hence,.
For numbers, this will just compute the product of the numbers in the xs structure.
mult on any two adjacent elements of the structure, which requires each pair of adjacent element to at least have a common Ring embedding. The meaning of "adjacent" as used here is that two elements of the structure x and y are adjacent if and only if they are adjacent in the linearization of that structure, as documented by the Iterable concept.sum to understand why the Ring must sometimes be specified explicitly.| constexpr auto boost::hana::reverse_fold | +
#include <boost/hana/fwd/reverse_fold.hpp>
Equivalent to reverse_fold in Boost.Fusion and Boost.MPL.This method has the same semantics as reverse_fold in Boost.Fusion and Boost.MPL, with the extension that an initial state is not required. This method is equivalent to fold_right, except that the accumulating function must take its arguments in reverse order, to match the order used in Fusion. In other words,.
fold_right. As an alias, reverse_fold is not tag-dispatched on its own and fold_right should be customized instead.Given a Foldable F and an optional initial state of tag S, the signatures for reverse_fold are
+\[ \mathtt{reverse\_fold} : F(T) \times S \times (S \times T \to S) \to S \] +
+for the variant with an initial state, and
+\[ \mathtt{reverse\_fold} : F(T) \times (T \times T \to T) \to T \] +
+for the variant without an initial state.
+| xs | The structure to fold. |
| state | The initial value used for folding. |
| f | A binary function called as f(state, x), where state is the result accumulated so far and x is an element in the structure. For reverse folds without an initial state, the function is called as f(x1, x2), where x1 and x2 are elements of the structure. |
| constexpr auto boost::hana::size = hana::length | +
#include <boost/hana/fwd/size.hpp>
Equivalent to length; provided for consistency with the standard library.This method is an alias to length provided for convenience and consistency with the standard library. As an alias, size is not tag-dispatched on its own and length should be customized instead.
| constexpr auto boost::hana::sum = see documentation | +
#include <boost/hana/fwd/sum.hpp>
Compute the sum of the numbers of a structure.More generally, sum will take any foldable structure containing objects forming a Monoid and reduce them using the Monoid's binary operation. The initial state for folding is the identity of the Monoid. It is sometimes necessary to specify the Monoid to use; this is possible by using sum<M>. If no Monoid is specified, the structure will use the Monoid formed by the elements it contains (if it knows it), or integral_constant_tag<int> otherwise. Hence,.
For numbers, this will just compute the sum of the numbers in the xs structure.
plus on any two adjacent elements of the structure, which requires each pair of adjacent element to at least have a common Monoid embedding. The meaning of "adjacent" as used here is that two elements of the structure x and y are adjacent if and only if they are adjacent in the linearization of that structure, as documented by the Iterable concept.Monoid by using sum<M>? This is because sequence tags like tuple_tag are not parameterized (by design). Hence, we do not know what kind of objects are in the sequence, so we can't know a 0 value of which type should be returned when the sequence is empty. Therefore, the type of the 0 to return in the empty case must be specified explicitly. Other foldable structures like hana::ranges will ignore the suggested Monoid because they know the tag of the objects they contain. This inconsistent behavior is a limitation of the current design with non-parameterized tags, but we have no good solution for now.
| constexpr auto boost::hana::unpack | +
#include <boost/hana/fwd/unpack.hpp>
Invoke a function with the elements of a Foldable as arguments.Given a function and a foldable structure whose length can be known at compile-time, unpack invokes the function with the contents of that structure. In other words, unpack(xs, f) is equivalent to f(x...), where x... are the elements of the structure. The length of the structure must be known at compile-time, because the version of f's operator() that will be compiled depends on the number of arguments it is called with, which has to be known at compile-time.
To create a function that accepts a foldable instead of variadic arguments, see fuse instead.
| xs | The structure to expand into the function. |
| f | A function to be invoked as f(x...), where x... are the elements of the structure as-if they had been linearized with to<tuple_tag>. |
unpack's name and parameter order It has been suggested a couple of times that unpack be called apply instead, and that the parameter order be reversed to match that of the proposed std::apply function. However, the name apply is already used to denote normal function application, an use which is consistent with the Boost MPL library and with the rest of the world, especially the functional programming community. Furthermore, the author of this library considers the proposed std::apply to have both an unfortunate name and an unfortunate parameter order. Indeed, taking the function as the first argument means that using std::apply with a lambda function looks like
which is undeniably ugly because of the trailing , tuple) part on the last line. On the other hand, taking the function as a second argument allows one to write
which looks much nicer. Because of these observations, the author of this library feels justified to use unpack instead of apply, and to use a sane parameter order.
The Functor concept represents types that can be mapped over.
Intuitively, a Functor is some kind of box that can hold generic data and map a function over this data to create a new, transformed box. Because we are only interested in mapping a function over the contents of a black box, the only real requirement for being a functor is to provide a function which can do the mapping, along with a couple of guarantees that the mapping is well-behaved. Those requirements are made precise in the laws below. The pattern captured by Functor is very general, which makes it widely useful. A lot of objects can be made Functors in one way or another, the most obvious example being sequences with the usual mapping of the function on each element. While this documentation will not go into much more details about the nature of functors, the Typeclassopedia is a nice Haskell-oriented resource for such information.
Functors are parametric data types which are parameterized over the data type of the objects they contain. Like everywhere else in Hana, this parametricity is only at the documentation level and it is not enforced.
+In this library, the mapping function is called transform after the std::transform algorithm, but other programming languages have given it different names (usually map).
transformtransform is specified, adjust_if is defined analogously to adjust_ifadjust_if is specified, transform is defined analogously to Let xs be a Functor with tag F(A), \( f : A \to B \) and \( g : B \to C \). The following laws must be satisfied:
The first line says that mapping the identity function should not do anything, which precludes the functor from doing something nasty behind the scenes. The second line states that mapping the composition of two functions is the same as mapping the first function, and then the second on the result. While the usual functor laws are usually restricted to the above, this library includes other convenience methods and they should satisfy the following equations. Let xs be a Functor with tag F(A), \( f : A \to A \), \( \mathrm{pred} : A \to \mathrm{Bool} \) for some Logical Bool, and oldval, newval, value objects of tag A. Then,
The default definition of the methods will satisfy these equations.
+hana::lazy, hana::optional, hana::tuple
A mapping between two functors which also preserves the functor laws is called a natural transformation (the term comes from category theory). A natural transformation is a function f from a functor F to a functor G such that for every other function g with an appropriate signature and for every object xs of tag F(X),
There are several examples of such transformations, like to<tuple_tag> when applied to an optional value. Indeed, for any function g and hana::optional opt,
Of course, natural transformations are not limited to the to<...> functions. However, note that any conversion function between Functors should be natural for the behavior of the conversion to be intuitive.
+Variables | |
| constexpr auto | boost::hana::adjust |
| Apply a function on all the elements of a structure that compare equal to some value. More... | |
| constexpr auto | boost::hana::adjust_if |
Apply a function on all the elements of a structure satisfying a predicate.Given a Functor, a predicate pred and a function f, adjust_if will adjust the elements of the Functor that satisfy the predicate with the function f. In other words, adjust_if will return a new Functor equal to the original one, except that the elements satisfying the predicate will be transformed with the given function. Elements for which the predicate is not satisfied are left untouched, and they are kept as-is in the resulting Functor. More... | |
| constexpr auto | boost::hana::fill |
| Replace all the elements of a structure with a fixed value. More... | |
| constexpr auto | boost::hana::replace |
Replace all the elements of a structure that compare equal to some value with some new fixed value. More... | |
| constexpr auto | boost::hana::replace_if |
Replace all the elements of a structure satisfying a predicate with a fixed value. More... | |
| constexpr auto | boost::hana::transform |
Map a function over a Functor. More... | |
| constexpr auto boost::hana::adjust | +
#include <boost/hana/fwd/adjust.hpp>
Apply a function on all the elements of a structure that compare equal to some value.
+Given F a Functor and U a type that can be compared with T's, the signature is \( \mathtt{adjust} : F(T) \times U \times (T \to T) \to F(T) \)
| xs | The structure to adjust with f. |
| value | An object that is compared with each element x of the structure. Elements of the structure that compare equal to value are adjusted with the f function. |
| f | A function called as f(x) on the element(s) of the structure that compare equal to value. |
| constexpr auto boost::hana::adjust_if | +
#include <boost/hana/fwd/adjust_if.hpp>
Apply a function on all the elements of a structure satisfying a predicate.Given a Functor, a predicate pred and a function f, adjust_if will adjust the elements of the Functor that satisfy the predicate with the function f. In other words, adjust_if will return a new Functor equal to the original one, except that the elements satisfying the predicate will be transformed with the given function. Elements for which the predicate is not satisfied are left untouched, and they are kept as-is in the resulting Functor.
Given a Functor F and a Logical Bool, the signature is \( \mathtt{adjust_if} : F(T) \times (T \to Bool) \times (T \to T) \to F(T) \)
| xs | The structure to adjust with f. |
| pred | A function called as pred(x) for each element of the Functor, and returning whether f should be applied on that element. |
| f | A function called as f(x) on the element(s) of the Functor that satisfy the predicate. |
| constexpr auto boost::hana::fill | +
#include <boost/hana/fwd/fill.hpp>
Replace all the elements of a structure with a fixed value.
+Given F a Functor, the signature is \( \mathtt{fill} : F(T) \times U \to F(U) \)
| xs | The structure to fill with a value. |
| value | A value by which every element x of the structure is replaced, unconditionally. |
| constexpr auto boost::hana::replace | +
#include <boost/hana/fwd/replace.hpp>
Replace all the elements of a structure that compare equal to some value with some new fixed value.
Given F a Functor and U a type that can be compared with T, the signature is \( \mathtt{replace} : F(T) \times U \times T \to F(T) \)
| xs | The structure to replace elements of. |
| oldval | An object compared with each element of the structure. Elements of the structure that compare equal to oldval are replaced by newval in the new structure. |
| newval | A value by which every element x of the structure that compares equal to oldval is replaced. |
| constexpr auto boost::hana::replace_if | +
#include <boost/hana/fwd/replace_if.hpp>
Replace all the elements of a structure satisfying a predicate with a fixed value.
Given F a Functor and Bool a Logical, the signature is \( \mathtt{replace_if} : F(T) \times (T \to Bool) \times T \to F(T) \)
| xs | The structure to replace elements of. |
| predicate | A function called as predicate(x) for element(s) x of the structure and returning a Logical representing whether x should be replaced by value. |
| value | A value by which every element x of the structure for which predicate returns a true-valued Logical is replaced. |
| constexpr auto boost::hana::transform | +
#include <boost/hana/fwd/transform.hpp>
Map a function over a Functor.
Given F a Functor, the signature is \( \mathtt{transform} : F(T) \times (T \to U) \to F(U) \)
| xs | The structure to map f over. |
| f | A function called as f(x) on element(s) x of the structure, and returning a new value to replace x in the structure. |
The Group concept represents Monoids where all objects have an inverse w.r.t. the Monoid's binary operation.
A Group is an algebraic structure built on top of a Monoid which adds the ability to invert the action of the Monoid's binary operation on any element of the set. Specifically, a Group is a Monoid (S, +) such that every element s in S has an inverse (say s') which is such that
There are many examples of Groups, one of which would be the additive Monoid on integers, where the inverse of any integer n is the integer -n. The method names used here refer to exactly this model.
minusminus is specified, the negate method is defaulted by setting negatenegate is specified, the minus method is defaulted by setting For all objects x of a Group G, the following laws must be satisfied:
Monoid
A data type T is arithmetic if std::is_arithmetic<T>::value is true. For a non-boolean arithmetic data type T, a model of Group is automatically defined by setting
bool is the same as for not providing a Monoid model.Let A and B be two Groups. A function f : A -> B is said to be a Group morphism if it preserves the group structure between A and B. Rigorously, for all objects x, y of data type A,
Because of the Group structure, it is easy to prove that the following will then also be satisfied:
Functions with these properties interact nicely with Groups, which is why they are given such a special treatment.
+Variables | |
| constexpr auto | boost::hana::minus |
Subtract two elements of a group.Specifically, this performs the Monoid operation on the first argument and on the inverse of the second argument, thus being equivalent to: More... | |
| constexpr auto | boost::hana::negate |
| Return the inverse of an element of a group. More... | |
| constexpr auto boost::hana::minus | +
#include <boost/hana/fwd/minus.hpp>
Subtract two elements of a group.Specifically, this performs the Monoid operation on the first argument and on the inverse of the second argument, thus being equivalent to:
The minus method is "overloaded" to handle distinct data types with certain properties. Specifically, minus is defined for distinct data types A and B such that
A and B share a common data type C, as determined by the common metafunctionA, B and C are all Groups when taken individuallyto<C> : A -> B and to<C> : B -> C are Group-embeddings, as determined by the is_embedding metafunction.The definition of minus for data types satisfying the above properties is obtained by setting
| constexpr auto boost::hana::negate | +
#include <boost/hana/fwd/negate.hpp>
Return the inverse of an element of a group.
+The Hashable concept represents objects that can be normalized to a type-level hash.
In day to day programming, hashes are very important as a way to efficiently lookup objects in maps. While the implementation of maps is very different, the same idea of using hashes for efficient lookup applies in metaprogramming. The Hashable concept represents objects that can be summarized (possibly with loss of information) to a type, in a way suitable for use in hash-based data structures. Of course, in order for a hash to be well-behaved, it must obey some laws that are explained below.
hash, satisfying the laws below
First, hana::hash must return a hana::type. Furthermore, for any two Hashable objects x and y, it must be the case that
where == denotes hana::equal. In other words, any two objects that compare equal (with hana::equal) must also have the same hash. However, the reverse is not true, and two different objects may have the same hash. This situation of two different objects having the same hash is called a collision.
hana::integral_constant, hana::type, hana::string
IntegralConstants Any IntegralConstant is Hashable, by normalizing its value to a hana::integral_constant. The type of the value held in the normalized integral_constant is unsigned long long for unsigned integral types, and signed long long for signed integral types.
+Variables | |
| constexpr auto | boost::hana::hash |
Returns a hana::type representing the compile-time hash of an object.Given an arbitrary object x, hana::hash returns a hana::type representing the hash of x. In normal programming, hashes are usually numerical values that can be used e.g. as indices in an array as part of the implementation of a hash table. In the context of metaprogramming, we are interested in type-level hashes instead. Thus, hana::hash must return a hana::type object instead of an integer. This hana::type must somehow summarize the object being hashed, but that summary may of course lose some information. More... | |
| constexpr auto boost::hana::hash | +
#include <boost/hana/fwd/hash.hpp>
Returns a hana::type representing the compile-time hash of an object.Given an arbitrary object x, hana::hash returns a hana::type representing the hash of x. In normal programming, hashes are usually numerical values that can be used e.g. as indices in an array as part of the implementation of a hash table. In the context of metaprogramming, we are interested in type-level hashes instead. Thus, hana::hash must return a hana::type object instead of an integer. This hana::type must somehow summarize the object being hashed, but that summary may of course lose some information.
In order for the hash function to be defined properly, it must be the case that whenever x is equal to y, then hash(x) is equal to hash(y). This ensures that hana::hash is a function in the mathematical sense of the term.
Given a Hashable H, the signature is \( \mathtt{hash} : H \to \mathtt{type\_tag} \)
| x | An object whose hash is to be computed. |
The Iterable concept represents data structures supporting external iteration.
Intuitively, an Iterable can be seen as a kind of container whose elements can be pulled out one at a time. An Iterable also provides a way to know when the container is empty, i.e. when there are no more elements to pull out.
Whereas Foldable represents data structures supporting internal iteration with the ability to accumulate a result, the Iterable concept allows inverting the control of the iteration. This is more flexible than Foldable, since it allows iterating over only some part of the structure. This, in turn, allows Iterable to work on infinite structures, while trying to fold such a structure would never finish.
at, drop_front and is_empty
Iterable Intuitively, for an Iterable structure xs, the linearization of xs is the sequence of all the elements in xs as if they had been put in a (possibly infinite) list:
The nth element of the linearization of an Iterable can be accessed with the at function. In other words, at(xs, n) == xn.
Note that this notion is precisely the extension of the linearization notion of Foldables to the infinite case. This notion is useful for expressing various properties of Iterables, and is used for that elsewhere in the documentation.
Iterables A compile-time Iterable is an Iterable for which is_empty returns a compile-time Logical. These structures allow iteration to be done at compile-time, in the sense that the "loop" doing the iteration can be unrolled because the total length of the structure is kown at compile-time.
In particular, note that being a compile-time Iterable has nothing to do with being finite or infinite. For example, it would be possible to create a sequence representing the Pythagorean triples as integral_constants. Such a sequence would be infinite, but iteration on the sequence would still be done at compile-time. However, if one tried to iterate over all the elements of the sequence, the compiler would loop indefinitely, in contrast to your program looping indefinitely if the sequence was a runtime one.
In the current version of the library, only compile-time Iterables are supported. While it would be possible in theory to support runtime Iterables, doing it efficiently is the subject of some research. In particular, follow this issue for the current status of runtime Iterables.
First, we require the equality of two Iterables to be related to the equality of the elements in their linearizations. More specifically, if xs and ys are two Iterables of data type It, then
This conveys that two Iterables must have the same linearization in order to be considered equal.
Secondly, since every Iterable is also a Searchable, we require the models of Iterable and Searchable to be consistent. This is made precise by the following laws. For any Iterable xs with a linearization of [x1, x2, x3, ...],
for some finite index i. Furthermore,
or nothing if no such xi exists.
Searchable (free model)Iterable gives rise to a model of Searchable, where the keys and the values are both the elements in the structure. Searching for a key is just doing a linear search through the elements of the structure. Foldable for finite IterablesIterable gives rise to a model of Foldable. For these models to be consistent, we require the models of both Foldable and Iterable to have the same linearization.Iterables are also Searchables and their models have to be consistent. By the laws presented here, it also means that the Foldable model for finite Iterables has to be consistent with the Searchable model.For convenience, finite Iterables must only provide a definition of length to model the Foldable concept; defining the more powerful unpack or fold_left is not necessary (but still possible). The default implementation of unpack derived from Iterable + length uses the fact that at(xs, i) denotes the ith element of xs's linearization, and that the linearization of a finite Iterable must be the same as its linearization as a Foldable.
hana::tuple, hana::string, hana::range
+Variables | |
| constexpr auto | boost::hana::at |
Returns the nth element of an iterable.Given an Iterable and an IntegralConstant index, at returns the element located at the index in the linearization of the iterable. Specifically, given an iterable xs with a linearization of [x1, ..., xN], at(xs, k) is equivalent to xk. More... | |
| template<std::size_t n> | |
| constexpr auto | boost::hana::at_c |
Equivalent to at; provided for convenience. More... | |
| constexpr auto | boost::hana::back |
Returns the last element of a non-empty and finite iterable.Given a non-empty and finite iterable xs with a linearization of [x1, ..., xN], back(xs) is equal to xN. Equivalently, back(xs) must be equivalent to at_c<N-1>(xs), and that regardless of the value category of xs (back must respect the reference semantics of at). More... | |
| constexpr auto | boost::hana::drop_front |
Drop the first n elements of an iterable, and return the rest.Given an Iterable xs with a linearization of [x1, x2, ...] and a non-negative IntegralConstant n, drop_front(xs, n) is an iterable with the same tag as xs whose linearization is [xn+1, xn+2, ...]. In particular, note that this function does not mutate the original iterable in any way. If n is not given, it defaults to an IntegralConstant with a value equal to 1. More... | |
| constexpr auto | boost::hana::drop_front_exactly |
Drop the first n elements of an iterable, and return the rest.Given an Iterable xs with a linearization of [x1, x2, ...] and a non-negative IntegralConstant n, drop_front_exactly(xs, n) is an iterable with the same tag as xs whose linearization is [xn+1, xn+2, ...]. In particular, note that this function does not mutate the original iterable in any way. If n is not given, it defaults to an IntegralConstant with a value equal to 1. More... | |
| constexpr auto | boost::hana::drop_while |
Drop elements from an iterable up to, but excluding, the first element for which the predicate is not satisfied.Specifically, drop_while returns an iterable containing all the elements of the original iterable except for those in the range delimited by [head, e), where head is the first element and e is the first element for which the predicate is not satisfied. If the iterable is not finite, the predicate has to return a false- valued Logical at a finite index for this method to return. More... | |
| constexpr auto | boost::hana::front |
Returns the first element of a non-empty iterable.Given a non-empty Iterable xs with a linearization of [x1, ..., xN], front(xs) is equal to x1. If xs is empty, it is an error to use this function. Equivalently, front(xs) must be equivalent to at_c<0>(xs), and that regardless of the value category of xs (front must respect the reference semantics of at). More... | |
| constexpr auto | boost::hana::is_empty |
Returns whether the iterable is empty.Given an Iterable xs, is_empty returns whether xs contains no more elements. In other words, it returns whether trying to extract the tail of xs would be an error. In the current version of the library, is_empty must return an IntegralConstant holding a value convertible to bool. This is because only compile-time Iterables are supported right now. More... | |
| constexpr auto | boost::hana::lexicographical_compare |
Short-circuiting lexicographical comparison of two Iterables with an optional custom predicate, by default hana::less.Given two Iterables xs and ys and a binary predicate pred, lexicographical_compare returns whether xs is to be considered less than ys in a lexicographical ordering. Specifically, let's denote the linearizations of xs and ys by [x1, x2, ...] and [y1, y2, ...], respectively. If the first couple satisfying the predicate is of the form xi, yi, lexicographical_compare returns true. Otherwise, if the first couple to satisfy the predicate is of the form yi, xi, lexicographical_compare returns false. If no such couple can be found, lexicographical_compare returns whether xs has fewer elements than ys. More... | |
| constexpr auto boost::hana::at | +
#include <boost/hana/fwd/at.hpp>
Returns the nth element of an iterable.Given an Iterable and an IntegralConstant index, at returns the element located at the index in the linearization of the iterable. Specifically, given an iterable xs with a linearization of [x1, ..., xN], at(xs, k) is equivalent to xk.
If the Iterable actually stores the elements it contains, at is required to return a lvalue reference, a lvalue reference to const or a rvalue reference to the matching element, where the type of reference must match that of the iterable passed to at. If the Iterable does not store the elements it contains (i.e. it generates them on demand), this requirement is dropped.
| xs | The iterable in which an element is retrieved. The iterable must contain at least n + 1 elements. |
| n | A non-negative IntegralConstant representing the 0-based index of the element to return. It is an error to call at with an index that out of bounds of the iterable. |
| constexpr auto boost::hana::at_c | +
#include <boost/hana/fwd/at.hpp>
Equivalent to at; provided for convenience.
hana::at_c<n> is an overloaded function, not a function object. Hence, it can't be passed to higher-order algorithms. This is done for compile-time performance reasons.| constexpr auto boost::hana::back | +
#include <boost/hana/fwd/back.hpp>
Returns the last element of a non-empty and finite iterable.Given a non-empty and finite iterable xs with a linearization of [x1, ..., xN], back(xs) is equal to xN. Equivalently, back(xs) must be equivalent to at_c<N-1>(xs), and that regardless of the value category of xs (back must respect the reference semantics of at).
| constexpr auto boost::hana::drop_front | +
#include <boost/hana/fwd/drop_front.hpp>
Drop the first n elements of an iterable, and return the rest.Given an Iterable xs with a linearization of [x1, x2, ...] and a non-negative IntegralConstant n, drop_front(xs, n) is an iterable with the same tag as xs whose linearization is [xn+1, xn+2, ...]. In particular, note that this function does not mutate the original iterable in any way. If n is not given, it defaults to an IntegralConstant with a value equal to 1.
In case length(xs) <= n, drop_front will simply drop the whole iterable without failing, thus returning an empty iterable. This is different from drop_front_exactly, which expects n <= length(xs) but can be better optimized because of this additional guarantee.
| xs | The iterable from which elements are dropped. |
| n | A non-negative IntegralConstant representing the number of elements to be dropped from the iterable. If n is not given, it defaults to an IntegralConstant with a value equal to 1. |
| constexpr auto boost::hana::drop_front_exactly | +
#include <boost/hana/fwd/drop_front_exactly.hpp>
Drop the first n elements of an iterable, and return the rest.Given an Iterable xs with a linearization of [x1, x2, ...] and a non-negative IntegralConstant n, drop_front_exactly(xs, n) is an iterable with the same tag as xs whose linearization is [xn+1, xn+2, ...]. In particular, note that this function does not mutate the original iterable in any way. If n is not given, it defaults to an IntegralConstant with a value equal to 1.
It is an error to use drop_front_exactly with n > length(xs). This additional guarantee allows drop_front_exactly to be better optimized than the drop_front function, which allows n > length(xs).
| xs | The iterable from which elements are dropped. |
| n | A non-negative IntegralConstant representing the number of elements to be dropped from the iterable. In addition to being non-negative, n must be less than or equal to the number of elements in xs. If n is not given, it defaults to an IntegralConstant with a value equal to 1. |
| constexpr auto boost::hana::drop_while | +
#include <boost/hana/fwd/drop_while.hpp>
Drop elements from an iterable up to, but excluding, the first element for which the predicate is not satisfied.Specifically, drop_while returns an iterable containing all the elements of the original iterable except for those in the range delimited by [head, e), where head is the first element and e is the first element for which the predicate is not satisfied. If the iterable is not finite, the predicate has to return a false- valued Logical at a finite index for this method to return.
| iterable | The iterable from which elements are dropped. |
| predicate | A function called as predicate(x), where x is an element of the structure, and returning a Logical representing whether x should be dropped from the structure. In the current version of the library, predicate should return a compile-time Logical. |
| constexpr auto boost::hana::front | +
#include <boost/hana/fwd/front.hpp>
Returns the first element of a non-empty iterable.Given a non-empty Iterable xs with a linearization of [x1, ..., xN], front(xs) is equal to x1. If xs is empty, it is an error to use this function. Equivalently, front(xs) must be equivalent to at_c<0>(xs), and that regardless of the value category of xs (front must respect the reference semantics of at).
| constexpr auto boost::hana::is_empty | +
#include <boost/hana/fwd/is_empty.hpp>
Returns whether the iterable is empty.Given an Iterable xs, is_empty returns whether xs contains no more elements. In other words, it returns whether trying to extract the tail of xs would be an error. In the current version of the library, is_empty must return an IntegralConstant holding a value convertible to bool. This is because only compile-time Iterables are supported right now.
| constexpr auto boost::hana::lexicographical_compare | +
#include <boost/hana/fwd/lexicographical_compare.hpp>
Short-circuiting lexicographical comparison of two Iterables with an optional custom predicate, by default hana::less.Given two Iterables xs and ys and a binary predicate pred, lexicographical_compare returns whether xs is to be considered less than ys in a lexicographical ordering. Specifically, let's denote the linearizations of xs and ys by [x1, x2, ...] and [y1, y2, ...], respectively. If the first couple satisfying the predicate is of the form xi, yi, lexicographical_compare returns true. Otherwise, if the first couple to satisfy the predicate is of the form yi, xi, lexicographical_compare returns false. If no such couple can be found, lexicographical_compare returns whether xs has fewer elements than ys.
Given two Iterables It1(T) and It2(T) and a predicate \( pred : T \times T \to Bool \) (where Bool is some Logical), lexicographical_compare has the following signatures. For the variant with a provided predicate,
+\[ \mathtt{lexicographical\_compare} : It1(T) \times It2(T) \times (T \times T \to Bool) \to Bool \] +
+for the variant without a custom predicate, T is required to be Orderable. The signature is then
+\[ \mathtt{lexicographical\_compare} : It1(T) \times It2(T) \to Bool \] +
+| xs,ys | Two Iterables to compare lexicographically. |
| pred | A binary function called as pred(x, y) and pred(y, x), where x and y are elements of xs and ys, respectively. pred must return a Logical representing whether its first argument is to be considered as less than its second argument. Also note that pred must define a total ordering as defined by the Orderable concept. When pred is not provided, it defaults to less. |
Referenced by boost::hana::literals::operator""_s().
+ +The Logical concept represents types with a truth value.
Intuitively, a Logical is just a bool, or something that can act like one. However, in the context of programming with heterogeneous objects, it becomes extremely important to distinguish between those objects whose truth value is known at compile-time, and those whose truth value is only known at runtime. The reason why this is so important is because it is possible to branch at compile-time on a condition whose truth value is known at compile-time, and hence the return type of the enclosing function can depend on that truth value. However, if the truth value is only known at runtime, then the compiler has to compile both branches (because any or both of them may end up being used), which creates the additional requirement that both branches must evaluate to the same type.
More specifically, Logical (almost) represents a boolean algebra, which is a mathematical structure encoding the usual properties that allow us to reason with bool. The exact properties that must be satisfied by any model of Logical are rigorously stated in the laws below.
A Logical x is said to be true-valued, or sometimes also just true as an abuse of notation, if
Similarly, x is false-valued, or sometimes just false, if
This provides a standard way of converting any Logical to a straight bool. The notion of truth value suggests another definition, which is that of logical equivalence. We will say that two Logicals x and y are logically equivalent if they have the same truth value. To denote that some expressions p and q of a Logical data type are logically equivalent, we will sometimes also write
which is very common in mathematics. The intuition behind this notation is that whenever p is true-valued, then q should be; but when p is false-valued, then q should be too. Hence, p should be true-valued when (and only when) q is true-valued.
eval_if, not_ and while_
All the other functions can be defined in those terms:
As outlined above, the Logical concept almost represents a boolean algebra. The rationale for this laxity is to allow things like integers to act like Logicals, which is aligned with C++, even though they do not form a boolean algebra. Even though we depart from the usual axiomatization of boolean algebras, we have found through experience that the definition of a Logical given here is largely compatible with intuition.
The following laws must be satisfied for any data type L modeling the Logical concept. Let a, b and c be objects of a Logical data type, and let t and f be arbitrary true-valued and false-valued Logicals of that data type, respectively. Then,
++Why is the above not a boolean algebra?
+If you look closely, you will find that we depart from the usual boolean algebras because:
+
+- we do not require the elements representing truth and falsity to be unique
+- we do not enforce commutativity of the
+and_andor_operations- because we do not enforce commutativity, the identity laws become left-identity laws
+
A data type T is arithmetic if std::is_arithmetic<T>::value is true. For an arithmetic data type T, a model of Logical is provided automatically by using the result of the builtin implicit conversion to bool as a truth value. Specifically, the minimal complete definition for those data types is
++Rationale for not providing a model for all contextually convertible to bool data types
+The
+not_method can not be implemented in a meaningful way for all of those types. For example, one can not cast a pointer typeT*to bool and then back again toT*in a meaningful way. With an arithmetic typeT, however, it is possible to cast fromTto bool and then toTagain; the result will be0or1depending on the truth value. If you want to use a pointer type or something similar in a conditional, it is suggested to explicitly convert it to bool by usingto<bool>.
+Variables | |
| constexpr auto | boost::hana::and_ |
Return whether all the arguments are true-valued.and_ can be called with one argument or more. When called with two arguments, and_ uses tag-dispatching to find the right implementation. Otherwise,. More... | |
| constexpr auto | boost::hana::eval_if |
Conditionally execute one of two branches based on a condition.Given a condition and two branches in the form of lambdas or hana::lazys, eval_if will evaluate the branch selected by the condition with eval and return the result. The exact requirements for what the branches may be are the same requirements as those for the eval function. More... | |
| constexpr auto | boost::hana::if_ |
Conditionally return one of two values based on a condition.Specifically, then is returned iff cond is true-valued, and else_ is returned otherwise. Note that some Logical models may allow then and else_ to have different types, while others may require both values to have the same type. More... | |
| constexpr auto | boost::hana::not_ |
Negates a Logical.This method returns a Logical with the same tag, but whose truth-value is negated. Specifically, not_(x) returns a false-valued Logical if x is a true-valued Logical, and a true-valued one otherwise. More... | |
| constexpr auto | boost::hana::or_ |
Return whether any of the arguments is true-valued.or_ can be called with one argument or more. When called with two arguments, or_ uses tag-dispatching to find the right implementation. Otherwise,. More... | |
| constexpr auto | boost::hana::while_ |
Apply a function to an initial state while some predicate is satisfied.This method is a natural extension of the while language construct to manipulate a state whose type may change from one iteration to another. However, note that having a state whose type changes from one iteration to the other is only possible as long as the predicate returns a Logical whose truth value is known at compile-time. More... | |
| constexpr auto boost::hana::and_ | +
#include <boost/hana/fwd/and.hpp>
Return whether all the arguments are true-valued.and_ can be called with one argument or more. When called with two arguments, and_ uses tag-dispatching to find the right implementation. Otherwise,.
| constexpr auto boost::hana::eval_if | +
#include <boost/hana/fwd/eval_if.hpp>
Conditionally execute one of two branches based on a condition.Given a condition and two branches in the form of lambdas or hana::lazys, eval_if will evaluate the branch selected by the condition with eval and return the result. The exact requirements for what the branches may be are the same requirements as those for the eval function.
eval_if By passing a unary callable to eval_if, it is possible to defer the compile-time evaluation of selected expressions inside the lambda. This is useful when instantiating a branch would trigger a compile-time error; we only want the branch to be instantiated when that branch is selected. Here's how it can be achieved.
For simplicity, we'll use a unary lambda as our unary callable. Our lambda must accept a parameter (usually called _), which can be used to defer the compile-time evaluation of expressions as required. For example,
What happens here is that eval_if will call eval on the selected branch. In turn, eval will call the selected branch either with nothing – for the then branch – or with hana::id – for the else branch. Hence, _(x) is always the same as x, but the compiler can't tell until the lambda has been called! Hence, the compiler has to wait before it instantiates the body of the lambda and no infinite recursion happens. However, this trick to delay the instantiation of the lambda's body can only be used when the condition is known at compile-time, because otherwise both branches have to be instantiated inside the eval_if anyway.
There are several caveats to note with this approach to lazy branching. First, because we're using lambdas, it means that the function's result can't be used in a constant expression. This is a limitation of the current language.
+The second caveat is that compilers currently have several bugs regarding deeply nested lambdas with captures. So you always risk crashing the compiler, but this is a question of time before it is not a problem anymore.
+Finally, it means that conditionals can't be written directly inside unevaluated contexts. The reason is that a lambda can't appear in an unevaluated context, for example in decltype. One way to workaround this is to completely lift your type computations into variable templates instead. For example, instead of writing
you could instead write
+++Note: This example would actually be implemented more easily with partial specializations, but my bag of good examples is empty at the time of writing this.
+
Now, this hoop-jumping only has to be done in one place, because you should use normal function notation everywhere else in your metaprogram to perform type computations. So the syntactic cost is amortized over the whole program.
+Another way to work around this limitation of the language would be to use hana::lazy for the branches. However, this is only suitable when the branches are not too complicated. With hana::lazy, you could write the previous example as
| cond | The condition determining which of the two branches is selected. |
| then | An expression called as eval(then) if cond is true-valued. |
| else_ | A function called as eval(else_) if cond is false-valued. |
| constexpr auto boost::hana::if_ | +
#include <boost/hana/fwd/if.hpp>
Conditionally return one of two values based on a condition.Specifically, then is returned iff cond is true-valued, and else_ is returned otherwise. Note that some Logical models may allow then and else_ to have different types, while others may require both values to have the same type.
| cond | The condition determining which of the two values is returned. |
| then | The value returned when cond is true-valued. |
| else_ | The value returned when cond is false-valued. |
Referenced by boost::hana::literals::operator""_s().
+ +| constexpr auto boost::hana::not_ | +
#include <boost/hana/fwd/not.hpp>
Negates a Logical.This method returns a Logical with the same tag, but whose truth-value is negated. Specifically, not_(x) returns a false-valued Logical if x is a true-valued Logical, and a true-valued one otherwise.
| constexpr auto boost::hana::or_ | +
#include <boost/hana/fwd/or.hpp>
Return whether any of the arguments is true-valued.or_ can be called with one argument or more. When called with two arguments, or_ uses tag-dispatching to find the right implementation. Otherwise,.
| constexpr auto boost::hana::while_ | +
#include <boost/hana/fwd/while.hpp>
Apply a function to an initial state while some predicate is satisfied.This method is a natural extension of the while language construct to manipulate a state whose type may change from one iteration to another. However, note that having a state whose type changes from one iteration to the other is only possible as long as the predicate returns a Logical whose truth value is known at compile-time.
Specifically, while_(pred, state, f) is equivalent to
where f is iterated as long as pred(f(...)) is a true-valued Logical.
| pred | A predicate called on the state or on the result of applying f a certain number of times to the state, and returning whether f should be applied one more time. |
| state | The initial state on which f is applied. |
| f | A function that is iterated on the initial state. Note that the return type of f may change from one iteration to the other, but only while pred returns a compile-time Logical. In other words, decltype(f(stateN)) may differ from decltype(f(stateN+1)), but only if pred(f(stateN)) returns a compile-time Logical. |
A Metafunction is a function that takes hana::types as inputs and returns a hana::type as output.
A Metafunction is an object satisfying the FunctionObject concept, but with additional requirements. First, it must be possible to apply a Metafunction to arguments whose tag is type_tag, and the result of such an application must be an object whose tag is also type_tag. Note that hana::type and hana::basic_type are the only such types.
Secondly, a Metafunction must provide a nested ::apply template which allows performing the same type-level computation as is done by the call operator. In Boost.MPL parlance, a Metafunction F is hence a MetafunctionClass in addition to being a FunctionObject. Rigorously, the following must be satisfied by any object f of type F which is a Metafunction, and for arbitrary types T...:
Thirdly, to ease the inter-operation of values and types, Metafunctions must also allow being called with arguments that are not hana::types. In that case, the result is equivalent to calling the metafunction on the types of the arguments. Rigorously, this means that for arbitrary objects x...,
The Metafunction concept does not have a minimal complete definition in terms of tag-dispatched methods. Instead, the syntactic requirements documented above should be satisfied, and the Metafunction struct should be specialized explicitly in Hana's namespace.
hana::metafunction, hana::metafunction_class, hana::template_
Metafunctions Comparable? When seeing hana::template_, a question that naturally arises is whether Metafunctions should be made Comparable. Indeed, it would seem to make sense to compare two templates F and G with template_<F> == template_<G>. However, in the case where F and/or G are alias templates, it makes sense to talk about two types of comparisons. The first one is shallow comparison, and it determines that two alias templates are equal if they are the same alias template. The second one is deep comparison, and it determines that two template aliases are equal if they alias the same type for any template argument. For example, given F and G defined as
shallow comparison would determine that F and G are different because they are two different template aliases, while deep comparison would determine that F and G are equal because they always expand to the same type, void. Unfortunately, deep comparison is impossible to implement because one would have to check F and G on all possible types. On the other hand, shallow comparison is not satisfactory because Metafunctions are nothing but functions on types, and the equality of two functions is normally defined with deep comparison. Hence, we adopt a conservative stance and avoid providing comparison for Metafunctions.
+Variables | |
| template<template< typename... > class F> | |
| constexpr auto | boost::hana::template_ |
Lift a template to a Metafunction.Given a template class or template alias f, template_<f> is a Metafunction satisfying. More... | |
| template<template< typename... > class F> | |
| constexpr auto | boost::hana::metafunction |
Lift a MPL-style metafunction to a Metafunction.Given a MPL-style metafunction, metafunction<f> is a Metafunction satisfying. More... | |
| template<typename F > | |
| constexpr auto | boost::hana::metafunction_class |
Lift a MPL-style metafunction class to a Metafunction.Given a MPL-style metafunction class, metafunction_class<f> is a Metafunction satisfying. More... | |
| constexpr auto | boost::hana::integral |
Turn a Metafunction into a function taking types and returning a default-constructed object.Given a Metafunction f, integral returns a new Metafunction that default-constructs an object of the type returned by f. More specifically, the following holds: More... | |
| template<template< typename... > class F> | |
| constexpr auto | boost::hana::trait = hana::integral(hana::metafunction<F>) |
Alias to integral(metafunction<F>), provided for convenience. More... | |
| constexpr auto boost::hana::template_ | +
#include <boost/hana/fwd/type.hpp>
Lift a template to a Metafunction.Given a template class or template alias f, template_<f> is a Metafunction satisfying.
template_ can't be SFINAE-friendly right now because of Core issue 1430.| constexpr auto boost::hana::metafunction | +
#include <boost/hana/fwd/type.hpp>
Lift a MPL-style metafunction to a Metafunction.Given a MPL-style metafunction, metafunction<f> is a Metafunction satisfying.
| constexpr auto boost::hana::metafunction_class | +
#include <boost/hana/fwd/type.hpp>
Lift a MPL-style metafunction class to a Metafunction.Given a MPL-style metafunction class, metafunction_class<f> is a Metafunction satisfying.
| constexpr auto boost::hana::integral | +
#include <boost/hana/fwd/type.hpp>
Turn a Metafunction into a function taking types and returning a default-constructed object.Given a Metafunction f, integral returns a new Metafunction that default-constructs an object of the type returned by f. More specifically, the following holds:
The principal use case for integral is to transform Metafunctions returning a type that inherits from a meaningful base like std::integral_constant into functions returning e.g. a hana::integral_constant.
Metafunction because it does not return a type. As such, it would not make sense to make decltype(integral(f)) a MPL metafunction class like the usual Metafunctions are.integral with metafunctions returning std::integral_constants, don't forget to include the boost/hana/ext/std/integral_constant.hpp header to ensure Hana can interoperate with the result.| constexpr auto boost::hana::trait = hana::integral(hana::metafunction<F>) | +
#include <boost/hana/fwd/type.hpp>
Alias to integral(metafunction<F>), provided for convenience.
The Monad concept represents Applicatives with the ability to flatten nested levels of structure.
Historically, Monads are a construction coming from category theory, an abstract branch of mathematics. The functional programming community eventually discovered how Monads could be used to formalize several useful things like side effects, which led to the wide adoption of Monads in that community. However, even in a multi-paradigm language like C++, there are several constructs which turn out to be Monads, like std::optional, std::vector and others.
Everybody tries to introduce Monads with a different analogy, and most people fail. This is called the Monad tutorial fallacy. We will try to avoid this trap by not presenting a specific intuition, and we will instead present what monads are mathematically. For specific intuitions, we will let readers who are new to this concept read one of the many excellent tutorials available online. Understanding Monads might take time at first, but once you get it, a lot of patterns will become obvious Monads; this enlightening will be your reward for the hard work.
There are different ways of defining a Monad; Haskell uses a function called bind (>>=) and another one called return (it has nothing to do with C++'s return statement). They then introduce relationships that must be satisfied for a type to be a Monad with those functions. Mathematicians sometimes use a function called join and another one called unit, or they also sometimes use other category theoretic constructions like functor adjunctions and the Kleisli category.
This library uses a composite approach. First, we use the flatten function (equivalent to join) along with the lift function from Applicative (equivalent to unit) to introduce the notion of monadic function composition. We then write the properties that must be satisfied by a Monad using this monadic composition operator, because we feel it shows the link between Monads and Monoids more clearly than other approaches.
Roughly speaking, we will say that a Monad is an Applicative which also defines a way to compose functions returning a monadic result, as opposed to only being able to compose functions returning a normal result. We will then ask for this composition to be associative and to have a neutral element, just like normal function composition. For usual composition, the neutral element is the identity function id. For monadic composition, the neutral element is the lift function defined by Applicative. This construction is made clearer in the laws below.
First, a Monad must be both a Functor and an Applicative. Also, an implementation of flatten or chain satisfying the laws below for monadic composition must be provided.
ap method for Applicatives may be derived from the minimal complete definition of Monad and Functor; see below for more information.To simplify writing the laws, we use the comparison between functions. For two functions f and g, we define
With the usual composition of functions, we are given two functions \( f : A \to B \) and \( g : B \to C \), and we must produce a new function \( compose(g, f) : A \to C \). This composition of functions is associative, which means that
Also, this composition has an identity element, which is the identity function. This simply means that
This is probably nothing new if you are reading the Monad laws. Now, we can observe that the above is equivalent to saying that functions with the composition operator form a Monoid, where the neutral element is the identity function.
Given an Applicative F, what if we wanted to compose two functions \( f : A \to F(B) \) and \( g : B \to F(C) \)? When the Applicative F is also a Monad, such functions taking normal values but returning monadic values are called monadic functions. To compose them, we obviously can't use normal function composition, since the domains and codomains of f and g do not match properly. Instead, we'll need a new operator – let's call it monadic_compose:
+\[ \mathtt{monadic\_compose} : (B \to F(C)) \times (A \to F(B)) \to (A \to F(C)) \] +
+How could we go about implementing this function? Well, since we know F is an Applicative, the only functions we have are transform (from Functor), and lift and ap (from Applicative). Hence, the only thing we can do at this point while respecting the signatures of f and g is to set (for x of type A)
Indeed, f(x) is of type F(B), so we can map g (which takes B's) on it. Doing so will leave us with a result of type F(F(C)), but what we wanted was a result of type F(C) to respect the signature of monadic_compose. If we had a joker of type \( F(F(C)) \to F(C) \), we could simply set
and we would be happy. It turns out that flatten is precisely this joker. Now, we'll want our joker to satisfy some properties to make sure this composition is associative, just like our normal composition was. These properties are slightly cumbersome to specify, so we won't do it here. Also, we'll need some kind of neutral element for the composition. This neutral element can't be the usual identity function, because it does not have the right type: our neutral element needs to be a function of type \( X \to F(X) \) but the identity function has type \( X \to X \). It is now the right time to observe that lift from Applicative has exactly the right signature, and so we'll take this for our neutral element.
We are now ready to formulate the Monad laws using this composition operator. For a Monad M and functions \( f : A \to M(B) \), \( g : B \to M(C) \) and \( h : C \to M(D) \), the following must be satisfied:
which is to say that M along with monadic composition is a Monoid where the neutral element is lift.
FunctorApplicative (free implementation of ap)Monad and Functor are both satisfied, it is possible to implement ap by setting hana::lazy, hana::optional, hana::tuple
+Variables | |
| constexpr auto | boost::hana::chain |
Feed a monadic value into a monadic computation.Given a monadic value and a monadic function, chain feeds the monadic value into the function, thus performing some Monad-specific effects, and returns the result. An implementation of chain must satisfy. More... | |
| constexpr auto | boost::hana::flatten |
Collapse two levels of monadic structure into a single level.Given a monadic value wrapped into two levels of monad, flatten removes one such level. An implementation of flatten must satisfy. More... | |
| constexpr auto | boost::hana::monadic_compose |
Composition of monadic functions.Given two monadic functions f and g, monadic_compose returns a new function equivalent to the composition of f with g, except the result of g is chained into f instead of simply passed to it, as with normal composition. monadic_compose satisfies. More... | |
| template<typename M > | |
| constexpr auto | boost::hana::tap |
Tap inside a monadic chain.Given a function f, tap<M> returns a new function which performs f on its argument and then returns the argument lifted in the M Monad. Combined with the property that chain(m, lift<M>) == m, this provides a way of executing an action inside a monadic chain without influencing its overall result. This is useful to e.g. insert debug statements or perform actions that are not tied to the chain but that need to be executed inside of it. More... | |
| constexpr auto | boost::hana::then |
| Sequentially compose two monadic actions, discarding any value produced by the first but not its effects. More... | |
| constexpr auto boost::hana::chain | +
#include <boost/hana/fwd/chain.hpp>
Feed a monadic value into a monadic computation.Given a monadic value and a monadic function, chain feeds the monadic value into the function, thus performing some Monad-specific effects, and returns the result. An implementation of chain must satisfy.
For a monad M, given a monadic value of type M(A) and a monadic function \( f : A \to M(B) \), chain has the signature \( \mathtt{chain} : M(A) \times (A \to M(B)) \to M(B) \).
| xs | A monadic value to be fed to the function f. |
| f | A function taking a normal value in the xs structure, and returning a monadic value. This function is called as f(x), where x is an element of the structure xs. |
| constexpr auto boost::hana::flatten | +
#include <boost/hana/fwd/flatten.hpp>
Collapse two levels of monadic structure into a single level.Given a monadic value wrapped into two levels of monad, flatten removes one such level. An implementation of flatten must satisfy.
For Sequences, this simply takes a Sequence of Sequences, and returns a (non-recursively) flattened Sequence.
For a Monad M, the signature of flatten is \( \mathtt{flatten} : M(M(T)) \to M(T) \)
| xs | A value with two levels of monadic structure, which should be collapsed into a single level of structure. |
| constexpr auto boost::hana::monadic_compose | +
#include <boost/hana/fwd/monadic_compose.hpp>
Composition of monadic functions.Given two monadic functions f and g, monadic_compose returns a new function equivalent to the composition of f with g, except the result of g is chained into f instead of simply passed to it, as with normal composition. monadic_compose satisfies.
compose, monadic_compose does not generalize nicely to arities higher than one. Hence, only unary functions may be used with monadic_compose.Given a Monad M and two functions \( f : B \to M(C) \) and \( g : A \to M(B) \), the signature is \( \mathtt{monadic\_compose} : (B \to M(C)) \times (A \to M(B)) \to (A \to M(C)) \).
| f | A monadic function with signature \( B \to M(C) \). |
| g | A monadic function with signature \( A \to M(B) \). |
| constexpr auto boost::hana::tap | +
#include <boost/hana/fwd/tap.hpp>
Tap inside a monadic chain.Given a function f, tap<M> returns a new function which performs f on its argument and then returns the argument lifted in the M Monad. Combined with the property that chain(m, lift<M>) == m, this provides a way of executing an action inside a monadic chain without influencing its overall result. This is useful to e.g. insert debug statements or perform actions that are not tied to the chain but that need to be executed inside of it.
f function. Actually, side effects are the only reason why one might want to use tap. However, one should not rely on the side effects being done in any specific order.| M | The tag (a Monad) of the monads in the tapped monadic chain. |
| f | A function to be executed inside a monadic chain. It will be called as f(x), where x is a value inside the previous monad in the chain. The result of f is always discarded. |
| constexpr auto boost::hana::then | +
#include <boost/hana/fwd/then.hpp>
Sequentially compose two monadic actions, discarding any value produced by the first but not its effects.
+| before | The first Monad in the monadic composition chain. The result of this monad is ignored, but its effects are combined with that of the second monad. |
| xs | The second Monad in the monadic composition chain. |
The MonadPlus concept represents Monads with a monoidal structure.
Intuitively, whereas a Monad can be seen as some kind of container or context, a MonadPlus can be seen as a container or a context that can be concatenated with other containers or contexts. There must also be an identity element for this combining operation. For example, a tuple is a MonadPlus, because tuples can be concatenated and the empty tuple would act as an identity for concatenation. How is this different from a Monad which is also a Monoid? The answer is that the monoidal structure on a MonadPlus must not depend of the contents of the structure; it must not require the contents to be a Monoid in order to work.
+While sequences are not the only possible model for MonadPlus, the method names used here refer to the MonadPlus of sequences under concatenation. Several useful functions generalizing operations on sequences are included with this concept, like append, prepend and filter.
concat and empty
First, a MonadPlus is required to have a monoidal structure. Hence, it is no surprise that for any MonadPlus M, we require M(T) to be a valid monoid. However, we do not enforce that M(T) actually models the Monoid concept provided by Hana. Further, for all objects a, b, c of data type M(T),
Secondly, a MonadPlus is also required to obey the following laws, which represent the fact that empty<M(T)>() must be some kind of absorbing element for the chain operation. For all objects a of data type M(T) and functions \( f : T \to M(U) \),
Functor, Applicative and Monad
+Variables | |
| constexpr auto | boost::hana::append |
Append an element to a monadic structure.Given an element x and a monadic structure xs, append returns a new monadic structure which is the result of lifting x into the monadic structure and then combining that (to the right) with xs. In other words,. More... | |
| constexpr auto | boost::hana::concat |
Combine two monadic structures together.Given two monadic structures, concat combines them together and returns a new monadic structure. The exact definition of concat will depend on the exact model of MonadPlus at hand, but for sequences it corresponds intuitively to simple concatenation. More... | |
| constexpr auto | boost::hana::cycle |
Combine a monadic structure with itself n times.Given a monadic structure xs and a non-negative number n, cycle returns a new monadic structure which is the result of combining xs with itself n times using the concat operation. In other words,. More... | |
| template<typename M > | |
| constexpr auto | boost::hana::empty |
Identity of the monadic combination concat.Signature+Given a MonadPlusM, the signature is \( \mathtt{empty}_M : \emptyset \to M(T) \). More... | |
| constexpr auto | boost::hana::filter |
Filter a monadic structure using a custom predicate.Given a monadic structure and a predicate, filter returns a new monadic structure containing only those elements that satisfy the predicate. This is a generalization of the usual filter function for sequences; it works for any MonadPlus. Intuitively, filter is somewhat equivalent to: More... | |
| constexpr auto | boost::hana::prefix |
Inserts a value before each element of a monadic structure.Given a monadic structure xs and a value z called the prefix, prefix returns a new monadic structure. prefix satisfies. More... | |
| constexpr auto | boost::hana::prepend |
Prepend an element to a monadic structure.Given a monadic structure xs and an element x, prepend returns a new monadic structure which is the result of lifting x into the monadic structure and then combining that (to the left) with xs. In other words,. More... | |
| constexpr auto | boost::hana::remove |
Remove all the elements of a monadic structure that are equal to some value.Given a monadic structure xs and a value, remove returns a new monadic structure equal to xs without all its elements that are equal to the given value. remove is equivalent to remove_if with the equal.to(value) predicate, i.e. More... | |
| constexpr auto | boost::hana::remove_if |
Remove all the elements of a monadic structure that satisfy some predicate.Given a monadic structure xs and a unary predicate, remove_if returns a new monadic structure equal to xs without all its elements that satisfy the predicate. This is equivalent to filter with a negated predicate, i.e. More... | |
| template<typename M > | |
| constexpr auto | boost::hana::replicate |
Create a monadic structure by combining a lifted value with itself n times.Given a value x, a non-negative IntegralConstant n and the tag of a monadic structure M, replicate creates a new monadic structure which is the result of combining x with itself n times inside the monadic structure. In other words, replicate simply lifts x into the monadic structure, and then combines that with itself n times: More... | |
| constexpr auto | boost::hana::suffix |
Inserts a value after each element of a monadic structure.Given a monadic structure xs and a value z (called the suffix), suffix returns a new monadic structure such that. More... | |
| constexpr auto boost::hana::append | +
#include <boost/hana/fwd/append.hpp>
Append an element to a monadic structure.Given an element x and a monadic structure xs, append returns a new monadic structure which is the result of lifting x into the monadic structure and then combining that (to the right) with xs. In other words,.
where Xs is the tag of xs. For sequences, this has the intuitive behavior of simply appending an element to the end of the sequence, hence the name.
++Rationale for not calling this
+push_backSee the rationale for using
+prependinstead ofpush_front.
Given a MonadPlus M, the signature is \( \mathtt{append} : M(T) \times T \to M(T) \).
| xs | A monadic structure that will be combined to the left of the element. |
| x | An element to combine to the right of the monadic structure. |
| constexpr auto boost::hana::concat | +
#include <boost/hana/fwd/concat.hpp>
Combine two monadic structures together.Given two monadic structures, concat combines them together and returns a new monadic structure. The exact definition of concat will depend on the exact model of MonadPlus at hand, but for sequences it corresponds intuitively to simple concatenation.
Also note that combination is not required to be commutative. In other words, there is no requirement that
and indeed it does not hold in general.
+Given a MonadPlus M, the signature of concat is \( \mathtt{concat} : M(T) \times M(T) \to M(T) \).
| xs,ys | Two monadic structures to combine together. |
| constexpr auto boost::hana::cycle | +
#include <boost/hana/fwd/cycle.hpp>
Combine a monadic structure with itself n times.Given a monadic structure xs and a non-negative number n, cycle returns a new monadic structure which is the result of combining xs with itself n times using the concat operation. In other words,.
Also note that since concat is required to be associative, we could also have written
If n is zero, then the identity of concat, empty, is returned. In the case of sequences, this boils down to returning a sequence containing n copies of itself; for other models it might differ.
Given an IntegralConstant C and a MonadPlus M, the signature is \( \mathrm{cycle} : M(T) \times C \to M(T) \).
| xs | A monadic structure to combine with itself a certain number of times. |
| n | A non-negative IntegralConstant representing the number of times to combine the monadic structure with itself. If n is zero, cycle returns empty. |
| constexpr auto boost::hana::empty | +
#include <boost/hana/fwd/empty.hpp>
Identity of the monadic combination concat.
M, the signature is \( \mathtt{empty}_M : \emptyset \to M(T) \).
+| M | The tag of the monadic structure to return. This must be a model of the MonadPlus concept. |
| constexpr auto boost::hana::filter | +
#include <boost/hana/fwd/filter.hpp>
Filter a monadic structure using a custom predicate.Given a monadic structure and a predicate, filter returns a new monadic structure containing only those elements that satisfy the predicate. This is a generalization of the usual filter function for sequences; it works for any MonadPlus. Intuitively, filter is somewhat equivalent to:
In other words, we basically turn a monadic structure containing [x1, ..., xn] into a monadic structure containing
and we then flatten that.
Given a MonadPlus M and an IntegralConstant Bool holding a value of type bool, the signature is \( \mathtt{filter} : M(T) \times (T \to \mathtt{Bool}) \to M(T) \).
| xs | The monadic structure to filter. |
| pred | A function called as pred(x) for each element x in the monadic structure and returning whether that element should be kept in the resulting structure. In the current version of the library, the predicate has to return an IntegralConstant holding a value convertible to a bool. |
| constexpr auto boost::hana::prefix | +
#include <boost/hana/fwd/prefix.hpp>
Inserts a value before each element of a monadic structure.Given a monadic structure xs and a value z called the prefix, prefix returns a new monadic structure. prefix satisfies.
For sequences, this simply corresponds to inserting the prefix before each element of the sequence. For example, given a sequence [x1, ..., xn], prefix will return
As explained above, this can be generalized to other MonadPlus models, with various levels of interest.
+Given a MonadPlus M, the signature is \( \mathrm{prefix} : M(T) \times T \to M(T) \).
| xs | A monadic structure. |
| pref | A value (the prefix) to insert before each element of a monadic structure. |
| constexpr auto boost::hana::prepend | +
#include <boost/hana/fwd/prepend.hpp>
Prepend an element to a monadic structure.Given a monadic structure xs and an element x, prepend returns a new monadic structure which is the result of lifting x into the monadic structure and then combining that (to the left) with xs. In other words,.
For sequences, this has the intuitive behavior of simply prepending an element to the beginning of the sequence, hence the name.
+++Rationale for not calling this
+push_frontWhile
+push_frontis the de-facto name used in the standard library, it also strongly suggests mutation of the underlying sequence, which is not the case here. The author also finds thatpush_frontsuggests too strongly the sole interpretation of putting an element to the front of a sequence, whereasprependis slightly more nuanced and bears its name better for e.g.hana::optional.
Given a MonadPlus M, the signature is \( \mathtt{prepend} : M(T) \times T \to M(T) \).
| xs | A monadic structure that will be combined to the right of the element. |
| x | An element to combine to the left of the monadic structure. |
| constexpr auto boost::hana::remove | +
#include <boost/hana/fwd/remove.hpp>
Remove all the elements of a monadic structure that are equal to some value.Given a monadic structure xs and a value, remove returns a new monadic structure equal to xs without all its elements that are equal to the given value. remove is equivalent to remove_if with the equal.to(value) predicate, i.e.
Given a MonadPlus M and a value of type T, the signature is \( \mathrm{remove} : M(T) \times T \to M(T) \)
| xs | A monadic structure to remove some elements from. |
| value | A value that is compared to every element x of the structure. Elements of the structure that are equal to that value are removed from the structure. This requires every element to be Comparable with value. Furthermore, in the current version of the library, comparing value with any element of the structure must yield a compile-time Logical. |
| constexpr auto boost::hana::remove_if | +
#include <boost/hana/fwd/remove_if.hpp>
Remove all the elements of a monadic structure that satisfy some predicate.Given a monadic structure xs and a unary predicate, remove_if returns a new monadic structure equal to xs without all its elements that satisfy the predicate. This is equivalent to filter with a negated predicate, i.e.
Given a MonadPlus M and a predicate of type \( T \to Bool \) for some compile-time Logical Bool, the signature is \( \mathrm{remove\_if} : M(T) \times (T \to Bool) \to M(T) \)
| xs | A monadic structure to remove some elements from. |
| predicate | A unary predicate called as predicate(x), where x is an element of the structure, and returning whether x should be removed from the structure. In the current version of the library, predicate must return a compile-time Logical. |
| constexpr auto boost::hana::replicate | +
#include <boost/hana/fwd/replicate.hpp>
Create a monadic structure by combining a lifted value with itself n times.Given a value x, a non-negative IntegralConstant n and the tag of a monadic structure M, replicate creates a new monadic structure which is the result of combining x with itself n times inside the monadic structure. In other words, replicate simply lifts x into the monadic structure, and then combines that with itself n times:
If n is zero, then the identity of the concat operation is returned. In the case of sequences, this corresponds to creating a new sequence holding n copies of x.
Given an IntegralConstant C and MonadPlus M, the signature is \( \mathtt{replicate}_M : T \times C \to M(T) \).
| M | The tag of the returned monadic structure. It must be a model of the MonadPlus concept. |
| x | The value to lift into a monadic structure and then combine with itself. |
| n | A non-negative IntegralConstant representing the number of times to combine lift<M>(x) with itself. If n == 0, replicate returns empty<M>(). |
| constexpr auto boost::hana::suffix | +
#include <boost/hana/fwd/suffix.hpp>
Inserts a value after each element of a monadic structure.Given a monadic structure xs and a value z (called the suffix), suffix returns a new monadic structure such that.
For sequences, this simply corresponds to inserting the suffix after each element of the sequence. For example, given a sequence [x1, ..., xn], suffix will return
As explained above, this can be generalized to other MonadPlus models, with various levels of interest.
+Given a MonadPlus M, the signature is \( \mathtt{suffix} : M(T) \times T \to M(T) \).
| xs | A monadic structure. |
| sfx | A value (the suffix) to insert after each element of a monadic structure. |
The Monoid concept represents data types with an associative binary operation that has an identity.
Specifically, a Monoid is a basic algebraic structure typically used in mathematics to construct more complex algebraic structures like Groups, Rings and so on. They are useful in several contexts, notably to define the properties of numbers in a granular way. At its core, a Monoid is a set S of objects along with a binary operation (let's say +) that is associative and that has an identity in S. There are many examples of Monoids:
0 as the identity1 as the identityAs you can see with the integers, there are some sets that can be viewed as a monoid in more than one way, depending on the choice of the binary operation and identity. The method names used here refer to the monoid of integers under addition; plus is the binary operation and zero is the identity element of that operation.
plus and zero satisfying the laws
For all objects x, y and z of a Monoid M, the following laws must be satisfied:
A data type T is arithmetic if std::is_arithmetic<T>::value is true. For a non-boolean arithmetic data type T, a model of Monoid is automatically defined by setting
++Rationale for not making
+boolaMonoidby defaultFirst, it makes no sense whatsoever to define an additive
+Monoidover thebooltype. Also, it could make sense to define aMonoidwith logical conjunction or disjunction. However, C++ allowsbools to be added, and the method names of this concept really suggest addition. In line with the principle of least surprise, no model is provided by default.
Let A and B be two Monoids. A function f : A -> B is said to be a Monoid morphism if it preserves the monoidal structure between A and B. Rigorously, for all objects x, y of data type A,
Functions with these properties interact nicely with Monoids, which is why they are given such a special treatment.
+Variables | |
| constexpr auto | boost::hana::plus |
Associative binary operation on a Monoid. More... | |
| template<typename M > | |
| constexpr auto | boost::hana::zero |
Identity of plus. More... | |
| constexpr auto boost::hana::plus | +
#include <boost/hana/fwd/plus.hpp>
Associative binary operation on a Monoid.
| x,y | Two objects to combine with the Monoid's binary operation. |
The plus method is "overloaded" to handle distinct data types with certain properties. Specifically, plus is defined for distinct data types A and B such that
A and B share a common data type C, as determined by the common metafunctionA, B and C are all Monoids when taken individuallyto<C> : A -> B and to<C> : B -> C are Monoid-embeddings, as determined by the is_embedding metafunction.The definition of plus for data types satisfying the above properties is obtained by setting
| constexpr auto boost::hana::zero | +
#include <boost/hana/fwd/zero.hpp>
Identity of plus.
| M | The tag (a Monoid) of the returned identity. |
The Orderable concept represents totally ordered data types.
Intuitively, Orderable objects must define a binary predicate named less returning whether the first argument is to be considered less than the second argument. The word "total" means that distinct objects must always be ordered; if a and b are not equal, then exactly one of less(a, b) and less(b, a) must be true. This is a contrast with weaker kinds of orders that would allow some objects to be incomparable (neither less than nor greater than). Also note that a non-strict total order may always be obtained from a strict total order (and vice-versa) by setting
The non-strict version is used in the description of the laws because it makes them easier to parse for humans, but they could be formulated equivalently using the strict order.
+less
When less is defined, the other methods are defined from it using the same definition as mandated in the laws below.
Rigorously speaking, a total order <= on a set S is a binary predicate \( <= \;: S \times S \to bool \) such that for all a, b, c in S,
Additionally, the less, greater and greater_equal methods should have the following intuitive meanings:
Comparable (free model)Orderable requires less_equal to be a total order, a model of Comparable may always be obtained by setting hana::integral_constant, hana::optional, hana::pair, hana::string, hana::tuple
LessThanComparable data types Two data types T and U that model the cross-type version of the usual LessThanComparable C++ concept are automatically a model of Orderable by setting
The cross-type version of the LessThanComparable concept is analogous to the cross-type version of the EqualityComparable concept presented in N3351, which is compatible with the usual single type definition. However, note that the LessThanComparable concept only requires < to be a strict weak ordering, which is a weaker requirement than being a total order. Hence, if less is used with objects of a LessThanComparable data type that do not define a total order, some algorithms may have an unexpected behavior. It is the author's opinion that defining operator< as a non-total order is a bad idea, but this is debatable and so the design choice of providing a model for LessThanComparable data types is open to debate. Waiting for some user input.
Let A and B be two Orderable data types. A function \( f : A \to B\) is said to be order-preserving (also called monotone) if it preserves the structure of the Orderable concept, which can be rigorously stated as follows. For all objects x, y of data type A,
Another important property is that of being order-reflecting, which can be stated as
We say that a function is an order-embedding if it is both order-preserving and order-reflecting, i.e. if
The comparison methods (less, less_equal, greater and greater_equal) are "overloaded" to handle distinct data types with certain properties. Specifically, they are defined for distinct data types A and B such that
A and B share a common data type C, as determined by the common metafunctionA, B and C are all Orderable when taken individuallyis_embedding metafunction.The method definitions for data types satisfying the above properties are
The less, greater, less_equal and greater_equal methods can be called in two different ways. First, they can be called like normal functions:
However, they may also be partially applied to an argument as follows:
Take good note that the order of the arguments is reversed, so for example less.than(x)(y) is equivalent to less(y, x), not less(x, y). This is because those variants are meant to be used with higher order algorithms, where the chosen application order makes sense.
+Variables | |
| constexpr auto | boost::hana::greater |
Returns a Logical representing whether x is greater than y. More... | |
| constexpr auto | boost::hana::greater_equal |
Returns a Logical representing whether x is greater than or equal to y. More... | |
| constexpr auto | boost::hana::less |
Returns a Logical representing whether x is less than y. More... | |
| constexpr auto | boost::hana::less_equal |
Returns a Logical representing whether x is less than or equal to y. More... | |
| constexpr auto | boost::hana::max |
Returns the greatest of its arguments according to the less ordering. More... | |
| constexpr auto | boost::hana::min |
Returns the smallest of its arguments according to the less ordering. More... | |
| constexpr auto | boost::hana::ordering |
Returns a function performing less after applying a transformation to both arguments.ordering creates a total order based on the result of applying a function to some objects, which is especially useful in conjunction with algorithms that accept a custom predicate that must represent a total order. More... | |
| constexpr auto boost::hana::greater | +
#include <boost/hana/fwd/greater.hpp>
Returns a Logical representing whether x is greater than y.
Given a Logical Bool and two Orderables A and B with a common embedding, the signature is \( \mathrm{greater} : A \times B \to Bool \).
| x,y | Two objects to compare. |
| constexpr auto boost::hana::greater_equal | +
#include <boost/hana/fwd/greater_equal.hpp>
Returns a Logical representing whether x is greater than or equal to y.
Given a Logical Bool and two Orderables A and B with a common embedding, the signature is \( \mathrm{greater\_equal} : A \times B \to Bool \).
| x,y | Two objects to compare. |
| constexpr auto boost::hana::less | +
#include <boost/hana/fwd/less.hpp>
Returns a Logical representing whether x is less than y.
Given a Logical Bool and two Orderables A and B with a common embedding, the signature is \( \mathrm{less} : A \times B \to Bool \).
| x,y | Two objects to compare. |
| constexpr auto boost::hana::less_equal | +
#include <boost/hana/fwd/less_equal.hpp>
Returns a Logical representing whether x is less than or equal to y.
Given a Logical Bool and two Orderables A and B with a common embedding, the signature is \( \mathrm{less\_equal} : A \times B \to Bool \).
| x,y | Two objects to compare. |
| constexpr auto boost::hana::max | +
#include <boost/hana/fwd/max.hpp>
Returns the greatest of its arguments according to the less ordering.
min for details.| constexpr auto boost::hana::min | +
#include <boost/hana/fwd/min.hpp>
Returns the smallest of its arguments according to the less ordering.
x < y or not. If we wanted to be mathematically correct, we should probably ask that if_(cond, x, y) returns a common data type of x and y, and then the behavior of min would follow naturally. However, I'm unsure whether this is desirable because that's a big requirement.| constexpr auto boost::hana::ordering | +
#include <boost/hana/fwd/ordering.hpp>
Returns a function performing less after applying a transformation to both arguments.ordering creates a total order based on the result of applying a function to some objects, which is especially useful in conjunction with algorithms that accept a custom predicate that must represent a total order.
Specifically, ordering is such that
or, equivalently,
Orderable concept.Given a Logical Bool and an Orderable B, the signature is \( \mathrm{ordering} : (A \to B) \to (A \times A \to Bool) \).
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.
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.
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,
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)x and y are equal iff they are equal element-wise, by comparing the first element before the second element. Orderable (free model)Foldable (free model)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>
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.
| constexpr auto boost::hana::second | +
#include <boost/hana/fwd/second.hpp>
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.
The Ring concept represents Groups that also form a Monoid under a second binary operation that distributes over the first.
A Ring is an algebraic structure built on top of a Group which requires a monoidal structure with respect to a second binary operation. This second binary operation must distribute over the first one. Specifically, a Ring is a triple (S, +, *) such that (S, +) is a Group, (S, *) is a Monoid and * distributes over +, i.e.
The second binary operation is often written * with its identity written 1, in reference to the Ring of integers under multiplication. The method names used here refer to this exact ring.
one and mult satisfying the laws
For all objects x, y, z of a Ring R, the following laws must be satisfied:
Monoid, Group
A data type T is arithmetic if std::is_arithmetic<T>::value is true. For a non-boolean arithmetic data type T, a model of Ring is automatically defined by using the provided Group model and setting
bool is the same as for not providing Monoid and Group models.Let A and B be two Rings. A function f : A -> B is said to be a Ring morphism if it preserves the ring structure between A and B. Rigorously, for all objects x, y of data type A,
Because of the Ring structure, it is easy to prove that the following will then also be satisfied:
which is to say that f will then also be a Group morphism. Functions with these properties interact nicely with Rings, which is why they are given such a special treatment.
+Variables | |
| constexpr auto | boost::hana::mult |
Associative operation of a Ring. More... | |
| template<typename R > | |
| constexpr auto | boost::hana::one |
Identity of the Ring multiplication. More... | |
| constexpr auto | boost::hana::power |
Elevate a ring element to its nth power.Specifically, power(x, n), is equivalent to multiplying x with itself n times using the Ring's multiplication. If the power is equal to zero, the Ring's identity (one) is returned. More... | |
| constexpr auto boost::hana::mult | +
#include <boost/hana/fwd/mult.hpp>
Associative operation of a Ring.
| x,y | Two Ring elements to combine with the Ring binary operation. |
The mult method is "overloaded" to handle distinct data types with certain properties. Specifically, mult is defined for distinct data types A and B such that
A and B share a common data type C, as determined by the common metafunctionA, B and C are all Rings when taken individuallyto<C> : A -> B and to<C> : B -> C are Ring-embeddings, as determined by the is_embedding metafunction.The definition of mult for data types satisfying the above properties is obtained by setting
| constexpr auto boost::hana::one | +
#include <boost/hana/fwd/one.hpp>
Identity of the Ring multiplication.
| R | The tag (must be a model of Ring) of the returned identity. |
| constexpr auto boost::hana::power | +
#include <boost/hana/fwd/power.hpp>
Elevate a ring element to its nth power.Specifically, power(x, n), is equivalent to multiplying x with itself n times using the Ring's multiplication. If the power is equal to zero, the Ring's identity (one) is returned.
| x | A Ring element that is elevated to its nth power. |
| n | A non-negative IntegralConstant representing the power to which x is elevated. |
x is used for tag-dispatching.The Searchable concept represents structures that can be searched.
Intuitively, a Searchable is any structure, finite or infinite, containing elements that can be searched using a predicate. Sometimes, Searchables will associate keys to values; one can search for a key with a predicate, and the value associated to it is returned. This gives rise to map-like data structures. Other times, the elements of the structure that are searched (i.e. those to which the predicate is applied) are the same that are returned, which gives rise to set-like data structures. In general, we will refer to the keys of a Searchable structure as those elements that are used for searching, and to the values of a Searchable as those elements that are returned when a search is successful. As was explained, there is no requirement that both notions differ, and it is often useful to have keys and values coincide (think about std::set).
Some methods like any_of, all_of and none_of allow simple queries to be performed on the keys of the structure, while other methods like find and find_if make it possible to find the value associated to a key. The most specific method should always be used if one cares about performance, because it is usually the case that heavy optimizations can be performed in more specific methods. For example, an associative data structure implemented as a hash table will be much faster to access using find than find_if, because in the second case it will have to do a linear search through all the entries. Similarly, using contains will likely be much faster than any_of with an equivalent predicate.
++Insight
+
+In a lazy evaluation context, anyFoldablecan also become a model ofSearchablebecause we can search lazily through the structure withfold_right. However, in the context of C++, someSearchables can not be folded; think for example of an infinite set.
find_if and any_of
When find_if and any_of are provided, the other functions are implemented according to the laws explained below.
any_of(xs, pred) by checking whether find_if(xs, pred) is an empty optional or not, and then reduce the minimal complete definition to find_if. However, this is not done because that implementation requires the predicate of any_of to return a compile-time Logical, which is more restrictive than what we have right now.In order for the semantics of the methods to be consistent, some properties must be satisfied by any model of the Searchable concept. Rigorously, for any Searchables xs and ys and any predicate p, the following laws should be satisfied:
Additionally, if all the keys of the Searchable are Logicals, the following laws should be satisfied:
hana::map, hana::optional, hana::range, hana::set, hana::string, hana::tuple
Builtin arrays whose size is known can be searched as-if they were homogeneous tuples. However, since arrays can only hold objects of a single type and the predicate to find_if must return a compile-time Logical, the find_if method is fairly useless. For similar reasons, the find method is also fairly useless. This model is provided mainly because of the any_of method & friends, which are both useful and compile-time efficient.
Given two Searchables S1 and S2, a function \( f : S_1(X) \to S_2(X) \) is said to preserve the Searchable structure if for all xs of data type S1(X) and predicates \( \mathtt{pred} : X \to Bool \) (for a Logical Bool),
This is really just a generalization of the following, more intuitive requirements. For all xs of data type S1(X) and x of data type X,
These requirements can be understood as saying that f does not change the content of xs, although it may reorder elements. As usual, such a structure-preserving transformation is said to be an embedding if it is also injective, i.e. if it is a lossless transformation.
+Variables | |
| constexpr auto | boost::hana::all |
Returns whether all the keys of the structure are true-valued.The keys of the structure must be Logicals. If the structure is not finite, a false-valued key must appear at a finite "index" in order for this method to finish. More... | |
| constexpr auto | boost::hana::all_of |
Returns whether all the keys of the structure satisfy the predicate.If the structure is not finite, predicate has to return a false- valued Logical after looking at a finite number of keys for this method to finish. More... | |
| constexpr auto | boost::hana::any |
Returns whether any key of the structure is true-valued.The keys of the structure must be Logicals. If the structure is not finite, a true-valued key must appear at a finite "index" in order for this method to finish. More... | |
| constexpr auto | boost::hana::any_of |
Returns whether any key of the structure satisfies the predicate.If the structure is not finite, predicate has to be satisfied after looking at a finite number of keys for this method to finish. More... | |
| constexpr auto | boost::hana::at_key |
Returns the value associated to the given key in a structure, or fail.Given a key and a Searchable structure, at_key returns the first value whose key is equal to the given key, and fails at compile-time if no such key exists. This requires the key to be compile-time Comparable, exactly like for find. at_key satisfies the following: More... | |
| constexpr auto | boost::hana::contains |
Returns whether the key occurs in the structure.Given a Searchable structure xs and a key, contains returns whether any of the keys of the structure is equal to the given key. If the structure is not finite, an equal key has to appear at a finite position in the structure for this method to finish. For convenience, contains can also be applied in infix notation. More... | |
| constexpr auto | boost::hana::in = hana::infix(hana::flip(hana::contains)) |
Return whether the key occurs in the structure.Specifically, this is equivalent to contains, except in takes its arguments in reverse order. Like contains, in can also be applied in infix notation for increased expressiveness. This function is not a method that can be overriden; it is just a convenience function provided with the concept. More... | |
| constexpr auto | boost::hana::find |
Finds the value associated to the given key in a structure.Given a key and a Searchable structure, find returns the just the first value whose key is equal to the given key, or nothing if there is no such key. Comparison is done with equal. find satisfies the following: More... | |
| constexpr auto | boost::hana::find_if |
Finds the value associated to the first key satisfying a predicate.Given a Searchable structure xs and a predicate pred, find_if(xs, pred) returns just the first element whose key satisfies the predicate, or nothing if there is no such element. More... | |
| constexpr auto | boost::hana::is_disjoint |
Returns whether two Searchables are disjoint.Given two Searchables xs and ys, is_disjoint returns a Logical representing whether the keys in xs are disjoint from the keys in ys, i.e. whether both structures have no keys in common. More... | |
| constexpr auto | boost::hana::is_subset |
Returns whether a structure contains a subset of the keys of another structure.Given two Searchables xs and ys, is_subset returns a Logical representing whether xs is a subset of ys. In other words, it returns whether all the keys of xs are also present in ys. This method does not return whether xs is a strict subset of ys; if xs and ys are equal, all the keys of xs are also present in ys, and is_subset returns true. More... | |
| constexpr auto | boost::hana::none |
Returns whether all of the keys of the structure are false-valued.The keys of the structure must be Logicals. If the structure is not finite, a true-valued key must appear at a finite "index" in order for this method to finish. More... | |
| constexpr auto | boost::hana::none_of |
Returns whether none of the keys of the structure satisfy the predicate.If the structure is not finite, predicate has to return a true- valued Logical after looking at a finite number of keys for this method to finish. More... | |
| constexpr auto boost::hana::all | +
#include <boost/hana/fwd/all.hpp>
Returns whether all the keys of the structure are true-valued.The keys of the structure must be Logicals. If the structure is not finite, a false-valued key must appear at a finite "index" in order for this method to finish.
| constexpr auto boost::hana::all_of | +
#include <boost/hana/fwd/all_of.hpp>
Returns whether all the keys of the structure satisfy the predicate.If the structure is not finite, predicate has to return a false- valued Logical after looking at a finite number of keys for this method to finish.
| xs | The structure to search. |
| predicate | A function called as predicate(k), where k is a key of the structure, and returning a Logical. |
| constexpr auto boost::hana::any | +
#include <boost/hana/fwd/any.hpp>
Returns whether any key of the structure is true-valued.The keys of the structure must be Logicals. If the structure is not finite, a true-valued key must appear at a finite "index" in order for this method to finish.
| constexpr auto boost::hana::any_of | +
#include <boost/hana/fwd/any_of.hpp>
Returns whether any key of the structure satisfies the predicate.If the structure is not finite, predicate has to be satisfied after looking at a finite number of keys for this method to finish.
| xs | The structure to search. |
| predicate | A function called as predicate(k), where k is a key of the structure, and returning a Logical. |
| constexpr auto boost::hana::at_key | +
#include <boost/hana/fwd/at_key.hpp>
Returns the value associated to the given key in a structure, or fail.Given a key and a Searchable structure, at_key returns the first value whose key is equal to the given key, and fails at compile-time if no such key exists. This requires the key to be compile-time Comparable, exactly like for find. at_key satisfies the following:
If the Searchable actually stores the elements it contains, at_key is required to return a lvalue reference, a lvalue reference to const or a rvalue reference to the found value, where the type of reference must match that of the structure passed to at_key. If the Searchable does not store the elements it contains (i.e. it generates them on demand), this requirement is dropped.
| xs | The structure to be searched. |
| key | A key to be searched for in the structure. The key has to be Comparable with the other keys of the structure. In the current version of the library, the comparison of key with any other key of the structure must return a compile-time Logical. |
| constexpr auto boost::hana::contains | +
#include <boost/hana/fwd/contains.hpp>
Returns whether the key occurs in the structure.Given a Searchable structure xs and a key, contains returns whether any of the keys of the structure is equal to the given key. If the structure is not finite, an equal key has to appear at a finite position in the structure for this method to finish. For convenience, contains can also be applied in infix notation.
| xs | The structure to search. |
| key | A key to be searched for in the structure. The key has to be Comparable with the other keys of the structure. |
| constexpr auto boost::hana::in = hana::infix(hana::flip(hana::contains)) | +
#include <boost/hana/fwd/contains.hpp>
Return whether the key occurs in the structure.Specifically, this is equivalent to contains, except in takes its arguments in reverse order. Like contains, in can also be applied in infix notation for increased expressiveness. This function is not a method that can be overriden; it is just a convenience function provided with the concept.
| constexpr auto boost::hana::find | +
#include <boost/hana/fwd/find.hpp>
Finds the value associated to the given key in a structure.Given a key and a Searchable structure, find returns the just the first value whose key is equal to the given key, or nothing if there is no such key. Comparison is done with equal. find satisfies the following:
| xs | The structure to be searched. |
| key | A key to be searched for in the structure. The key has to be Comparable with the other keys of the structure. In the current version of the library, the comparison of key with any other key of the structure must return a compile-time Logical. |
Referenced by boost::hana::literals::operator""_s().
+ +| constexpr auto boost::hana::find_if | +
#include <boost/hana/fwd/find_if.hpp>
Finds the value associated to the first key satisfying a predicate.Given a Searchable structure xs and a predicate pred, find_if(xs, pred) returns just the first element whose key satisfies the predicate, or nothing if there is no such element.
| xs | The structure to be searched. |
| predicate | A function called as predicate(k), where k is a key of the structure, and returning whether k is the key of the element being searched for. In the current version of the library, the predicate has to return an IntegralConstant holding a value that can be converted to bool. |
| constexpr auto boost::hana::is_disjoint | +
#include <boost/hana/fwd/is_disjoint.hpp>
Returns whether two Searchables are disjoint.Given two Searchables xs and ys, is_disjoint returns a Logical representing whether the keys in xs are disjoint from the keys in ys, i.e. whether both structures have no keys in common.
| xs,ys | Two Searchables to test for disjointness. |
| constexpr auto boost::hana::is_subset | +
#include <boost/hana/fwd/is_subset.hpp>
Returns whether a structure contains a subset of the keys of another structure.Given two Searchables xs and ys, is_subset returns a Logical representing whether xs is a subset of ys. In other words, it returns whether all the keys of xs are also present in ys. This method does not return whether xs is a strict subset of ys; if xs and ys are equal, all the keys of xs are also present in ys, and is_subset returns true.
is_subset can also be applied in infix notation.This method is tag-dispatched using the tags of both arguments. It can be called with any two Searchables sharing a common Searchable embedding, as defined in the main documentation of the Searchable concept. When Searchables with two different tags but sharing a common embedding are sent to is_subset, they are first converted to this common Searchable and the is_subset method of the common embedding is then used. Of course, the method can be overriden for custom Searchables for efficieny.
is_subset is supported, it is not currently used by the library because there are no models of Searchable with a common embedding.| xs | The structure to check whether it is a subset of ys. |
| ys | The structure to check whether it is a superset of xs. |
| constexpr auto boost::hana::none | +
#include <boost/hana/fwd/none.hpp>
Returns whether all of the keys of the structure are false-valued.The keys of the structure must be Logicals. If the structure is not finite, a true-valued key must appear at a finite "index" in order for this method to finish.
| constexpr auto boost::hana::none_of | +
#include <boost/hana/fwd/none_of.hpp>
Returns whether none of the keys of the structure satisfy the predicate.If the structure is not finite, predicate has to return a true- valued Logical after looking at a finite number of keys for this method to finish.
| xs | The structure to search. |
| predicate | A function called as predicate(k), where k is a key of the structure, and returning a Logical. |
The Sequence concept represents generic index-based sequences.
Compared to other abstract concepts, the Sequence concept is very specific. It represents generic index-based sequences. The reason why such a specific concept is provided is because there are a lot of models that behave exactly the same while being implemented in wildly different ways. It is useful to regroup all those data types under the same umbrella for the purpose of generic programming.
+In fact, models of this concept are not only similar. They are actually isomorphic, in a sense that we define below, which is a fancy way of rigorously saying that they behave exactly the same to an external observer.
+Iterable, Foldable, and make
The Sequence concept does not provide basic methods that could be used as a minimal complete definition; instead, it borrows methods from other concepts and add laws to them. For this reason, it is necessary to specialize the Sequence metafunction in Hana's namespace to tell Hana that a type is indeed a Sequence. Explicitly specializing the Sequence metafunction can be seen like a seal saying "this data type satisfies the additional laws of a `Sequence`", since those can't be checked by Hana automatically.
The laws for being a Sequence are simple, and their goal is to restrict the semantics that can be associated to the functions provided by other concepts. First, a Sequence must be a finite Iterable (thus a Foldable too). Secondly, for a Sequence tag S, make<S>(x1, ..., xn) must be an object of tag S and whose linearization is [x1, ..., xn]. This basically ensures that objects of tag S are equivalent to their linearization, and that they can be created from such a linearization (with make).
While it would be possible in theory to handle infinite sequences, doing so complicates the implementation of many algorithms. For simplicity, the current version of the library only handles finite sequences. However, note that this does not affect in any way the potential for having infinite Searchables and Iterables.
Comparable (definition provided automatically)Sequences are equal if and only if they contain the same number of elements and their elements at any given index are equal. Orderable (definition provided automatically)Sequences are ordered using the traditional lexicographical ordering. Functor (definition provided automatically)Sequences implement transform as the mapping of a function over each element of the sequence. This is somewhat equivalent to what std::transform does to ranges of iterators. Also note that mapping a function over an empty sequence returns an empty sequence and never applies the function, as would be expected. Applicative (definition provided automatically)lifting a value into a Sequence is the same as creating a singleton sequence containing that value. Second, applying a sequence of functions to a sequence of values will apply each function to all the values in the sequence, and then return a list of all the results. In other words, Example: Monad (definition provided automatically)flatenning a Sequence takes a sequence of sequences and concatenates them to get a larger sequence. In other words, This acts like a std::tuple_cat function, except it receives a sequence of sequences instead of a variadic pack of sequences to flatten.Monad for Sequences can be seen as modeling nondeterminism. A nondeterministic computation can be modeled as a function which returns a sequence of possible results. In this line of thought, chaining a sequence of values into such a function will return a sequence of all the possible output values, i.e. a sequence of all the values applied to all the functions in the sequences.MonadPlus (definition provided automatically)Sequences are models of the MonadPlus concept by considering the empty sequence as the unit of concat, and sequence concatenation as concat. FoldableFoldable for Sequences is uniquely determined by the model of Iterable. IterableIterable for Sequences corresponds to iteration over each element of the sequence, in order. This model is not provided automatically, and it is in fact part of the minimal complete definition for the Sequence concept. Searchable (definition provided automatically)Sequence is equivalent to just searching through a list of the values it contains. The keys and the values on which the search is performed are both the elements of the sequence. +Variables | |
| constexpr auto | boost::hana::cartesian_product |
Computes the cartesian product of a sequence of sequences.Given a sequence of sequences, cartesian_product returns a new sequence of sequences containing the cartesian product of the original sequences. For this method to finish, a finite number of finite sequences must be provided. More... | |
| constexpr auto | boost::hana::drop_back |
Drop the last n elements of a finite sequence, and return the rest.Given a finite Sequence xs with a linearization of [x1, ..., xm] and a non-negative IntegralConstant n, drop_back(xs, n) is a sequence with the same tag as xs whose linearization is [x1, ..., xm-n]. If n is not given, it defaults to an IntegralConstant with a value equal to 1. More... | |
| constexpr auto | boost::hana::group |
Group adjacent elements of a sequence that all respect a binary predicate, by default equality.Given a finite Sequence and an optional predicate (by default equal), group returns a sequence of subsequences representing groups of adjacent elements that are "equal" with respect to the predicate. In other words, the groups are such that the predicate is satisfied when it is applied to any two adjacent elements in that group. The sequence returned by group is such that the concatenation of its elements is equal to the original sequence, which is equivalent to saying that the order of the elements is not changed. More... | |
| constexpr insert_t | boost::hana::insert {} |
Insert a value at a given index in a sequence.Given a sequence, an index and an element to insert, insert inserts the element at the given index. More... | |
| constexpr auto | boost::hana::insert_range |
Insert several values at a given index in a sequence.Given a sequence, an index and any Foldable containing elements to insert, insert_range inserts the elements in the Foldable at the given index of the sequence. More... | |
| constexpr auto | boost::hana::intersperse |
Insert a value between each pair of elements in a finite sequence.Given a finite Sequence xs with a linearization of [x1, x2, ..., xn], intersperse(xs, z) is a new sequence with a linearization of [x1, z, x2, z, x3, ..., xn-1, z, xn]. In other words, it inserts the z element between every pair of elements of the original sequence. If the sequence is empty or has a single element, intersperse returns the sequence as-is. In all cases, the sequence must be finite. More... | |
| constexpr auto | boost::hana::partition |
Partition a sequence based on a predicate.Specifically, returns an unspecified Product whose first element is a sequence of the elements satisfying the predicate, and whose second element is a sequence of the elements that do not satisfy the predicate. More... | |
| constexpr auto | boost::hana::permutations |
Return a sequence of all the permutations of the given sequence.Specifically, permutations(xs) is a sequence whose elements are permutations of the original sequence xs. The permutations are not guaranteed to be in any specific order. Also note that the number of permutations grows very rapidly as the length of the original sequence increases. The growth rate is O(length(xs)!); with a sequence xs of length only 8, permutations(xs) contains over 40 000 elements! More... | |
| constexpr auto | boost::hana::remove_at |
Remove the element at a given index from a sequence.remove_at returns a new sequence identical to the original, except that the element at the given index is removed. Specifically, remove_at([x0, ..., xn-1, xn, xn+1, ..., xm], n) is a new sequence equivalent to [x0, ..., xn-1, xn+1, ..., xm]. More... | |
| template<std::size_t n> | |
| constexpr auto | boost::hana::remove_at_c |
Equivalent to remove_at; provided for convenience. More... | |
| constexpr auto | boost::hana::remove_range |
Remove the elements inside a given range of indices from a sequence.remove_range returns a new sequence identical to the original, except that elements at indices in the provided range are removed. Specifically, remove_range([x0, ..., xn], from, to) is a new sequence equivalent to [x0, ..., x_from-1, x_to, ..., xn]. More... | |
| template<std::size_t from, std::size_t to> | |
| constexpr auto | boost::hana::remove_range_c |
Equivalent to remove_range; provided for convenience. More... | |
| constexpr auto | boost::hana::reverse |
Reverse a sequence.Specifically, reverse(xs) is a new sequence containing the same elements as xs, except in reverse order. More... | |
| constexpr auto | boost::hana::scan_left |
Fold a Sequence to the left and return a list containing the successive reduction states.Like fold_left, scan_left reduces a sequence to a single value using a binary operation. However, unlike fold_left, it builds up a sequence of the intermediary results computed along the way and returns that instead of only the final reduction state. Like fold_left, scan_left can be used with or without an initial reduction state. More... | |
| constexpr auto | boost::hana::scan_right |
Fold a Sequence to the right and return a list containing the successive reduction states.Like fold_right, scan_right reduces a sequence to a single value using a binary operation. However, unlike fold_right, it builds up a sequence of the intermediary results computed along the way and returns that instead of only the final reduction state. Like fold_right, scan_right can be used with or without an initial reduction state. More... | |
| constexpr auto | boost::hana::slice |
Extract the elements of a Sequence at the given indices.Given an arbitrary sequence of indices, slice returns a new sequence of the elements of the original sequence that appear at those indices. In other words,. More... | |
| template<std::size_t from, std::size_t to> | |
| constexpr auto | boost::hana::slice_c |
Shorthand to slice a contiguous range of elements.slice_c is simply a shorthand to slice a contiguous range of elements. In particular, slice_c<from, to>(xs) is equivalent to slice(xs, range_c<std::size_t, from, to>), which simply slices all the elements of xs contained in the half-open interval delimited by [from, to). Like for slice, the indices used with slice_c are 0-based and they must be in the bounds of the sequence being sliced. More... | |
| constexpr auto | boost::hana::sort |
Sort a sequence, optionally based on a custom predicate.Given a Sequence and an optional predicate (by default less), sort returns a new sequence containing the same elements as the original, except they are ordered in such a way that if x comes before y in the sequence, then either predicate(x, y) is true, or both predicate(x, y) and predicate(y, x) are false. More... | |
| constexpr auto | boost::hana::span |
Returns a Product containing the longest prefix of a sequence satisfying a predicate, and the rest of the sequence.The first component of the returned Product is a sequence for which all elements satisfy the given predicate. The second component of the returned Product is a sequence containing the remainder of the argument. Both or either sequences may be empty, depending on the input argument. More specifically,. More... | |
| constexpr auto | boost::hana::take_back |
Returns the last n elements of a sequence, or the whole sequence if the sequence has less than n elements.Given a Sequence xs and an IntegralConstant n, take_back(xs, n) is a new sequence containing the last n elements of xs, in the same order. If length(xs) <= n, the whole sequence is returned and no error is triggered. More... | |
| constexpr auto | boost::hana::take_front |
Returns the first n elements of a sequence, or the whole sequence if the sequence has less than n elements.Given a Sequence xs and an IntegralConstant n, take_front(xs, n) is a new sequence containing the first n elements of xs, in the same order. If length(xs) <= n, the whole sequence is returned and no error is triggered. More... | |
| template<std::size_t n> | |
| constexpr auto | boost::hana::take_front_c |
Equivalent to take_front; provided for convenience. More... | |
| constexpr auto | boost::hana::take_while |
Take elements from a sequence while the predicate is satisfied.Specifically, take_while returns a new sequence containing the longest prefix of xs in which all the elements satisfy the given predicate. More... | |
| template<typename S > | |
| constexpr auto | boost::hana::unfold_left |
Dual operation to fold_left for sequences.While fold_left reduces a structure to a summary value from the left, unfold_left builds a sequence from a seed value and a function, starting from the left. More... | |
| template<typename S > | |
| constexpr auto | boost::hana::unfold_right |
Dual operation to fold_right for sequences.While fold_right reduces a structure to a summary value from the right, unfold_right builds a sequence from a seed value and a function, starting from the right. More... | |
| constexpr auto | boost::hana::unique |
Removes all consecutive duplicate elements from a Sequence.Given a Sequence and an optional binary predicate, unique returns a new sequence containing only the first element of every subrange of the original sequence whose elements are all equal. In other words, it turns a sequence of the form [a, a, b, c, c, c, d, d, d, a] into a sequence [a, b, c, d, a]. The equality of two elements is determined by the provided predicate, or by equal if no predicate is provided. More... | |
| constexpr auto | boost::hana::zip |
Zip one sequence or more.Given n sequences s1, ..., sn, zip produces a sequence whose i-th element is a tuple of (s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip produces a sequence of the form. More... | |
| constexpr auto | boost::hana::zip_shortest |
Zip one sequence or more.Given n sequences s1, ..., sn, zip_shortest produces a sequence whose i-th element is a tuple of (s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip_shortest produces a sequence of the form. More... | |
| constexpr auto | boost::hana::zip_shortest_with |
Zip one sequence or more with a given function.Given a n-ary function f and n sequences s1, ..., sn, zip_shortest_with produces a sequence whose i-th element is f(s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip_shortest_with produces a sequence of the form. More... | |
| constexpr auto | boost::hana::zip_with |
Zip one sequence or more with a given function.Given a n-ary function f and n sequences s1, ..., sn, zip_with produces a sequence whose i-th element is f(s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip_with produces a sequence of the form. More... | |
| constexpr auto boost::hana::cartesian_product | +
#include <boost/hana/fwd/cartesian_product.hpp>
Computes the cartesian product of a sequence of sequences.Given a sequence of sequences, cartesian_product returns a new sequence of sequences containing the cartesian product of the original sequences. For this method to finish, a finite number of finite sequences must be provided.
Given a Sequence S(T), the signature is
+\[ \mathtt{cartesian\_product} : S(S(T)) \to S(S(T)) \] +
+| xs | A sequence of sequences of which the cartesian product is computed. |
| constexpr auto boost::hana::drop_back | +
#include <boost/hana/fwd/drop_back.hpp>
Drop the last n elements of a finite sequence, and return the rest.Given a finite Sequence xs with a linearization of [x1, ..., xm] and a non-negative IntegralConstant n, drop_back(xs, n) is a sequence with the same tag as xs whose linearization is [x1, ..., xm-n]. If n is not given, it defaults to an IntegralConstant with a value equal to 1.
In case length(xs) <= n, drop_back will simply drop the whole sequence without failing, thus returning an empty sequence.
| xs | The sequence from which elements are dropped. |
| n | A non-negative IntegralConstant representing the number of elements to be dropped from the end of the sequence. If n is not given, it defaults to an IntegralConstant with a value equal to 1. |
| constexpr auto boost::hana::group | +
#include <boost/hana/fwd/group.hpp>
Group adjacent elements of a sequence that all respect a binary predicate, by default equality.Given a finite Sequence and an optional predicate (by default equal), group returns a sequence of subsequences representing groups of adjacent elements that are "equal" with respect to the predicate. In other words, the groups are such that the predicate is satisfied when it is applied to any two adjacent elements in that group. The sequence returned by group is such that the concatenation of its elements is equal to the original sequence, which is equivalent to saying that the order of the elements is not changed.
If no predicate is provided, adjacent elements in the sequence must all be compile-time Comparable.
Given a Sequence s with tag S(T), an IntegralConstant Bool holding a value of type bool, and a predicate \( pred : T \times T \to Bool \), group has the following signatures. For the variant with a provided predicate,
+\[ \mathtt{group} : S(T) \times (T \times T \to Bool) \to S(S(T)) \] +
+for the variant without a custom predicate, T is required to be Comparable. The signature is then
+\[ \mathtt{group} : S(T) \to S(S(T)) \] +
+| xs | The sequence to split into groups. |
| predicate | A binary function called as predicate(x, y), where x and y are adjacent elements in the sequence, whether both elements should be in the same group (subsequence) of the result. In the current version of the library, the result returned by predicate must be an IntegralConstant holding a value of a type convertible to bool. Also, predicate has to define an equivalence relation as defined by the Comparable concept. When this predicate is not provided, it defaults to equal, which requires the comparison of any two adjacent elements in the sequence to return a boolean IntegralConstant. |
group.by) group can be called in a third way, which provides a nice syntax especially when working with the comparing combinator:
where group(-, predicate) denotes the partial application of group to predicate.
+
|
+ +related | +
#include <boost/hana/fwd/insert.hpp>
Insert a value at a given index in a sequence.Given a sequence, an index and an element to insert, insert inserts the element at the given index.
| xs | The sequence in which a value should be inserted. |
| n | The index at which an element should be inserted. This must be a non-negative Constant of an integral type, and it must also be true that n < length(xs) if xs is a finite sequence. |
| element | The element to insert in the sequence. |
| constexpr auto boost::hana::insert_range | +
#include <boost/hana/fwd/insert_range.hpp>
Insert several values at a given index in a sequence.Given a sequence, an index and any Foldable containing elements to insert, insert_range inserts the elements in the Foldable at the given index of the sequence.
| xs | The sequence in which values should be inserted. |
| n | The index at which elements should be inserted. This must be a non-negative Constant of an integral type, and it must also be true that n < length(xs) if xs is a finite sequence. |
| elements | A Foldable containing elements to insert in the sequence. |
| constexpr auto boost::hana::intersperse | +
#include <boost/hana/fwd/intersperse.hpp>
Insert a value between each pair of elements in a finite sequence.Given a finite Sequence xs with a linearization of [x1, x2, ..., xn], intersperse(xs, z) is a new sequence with a linearization of [x1, z, x2, z, x3, ..., xn-1, z, xn]. In other words, it inserts the z element between every pair of elements of the original sequence. If the sequence is empty or has a single element, intersperse returns the sequence as-is. In all cases, the sequence must be finite.
| xs | The sequence in which a value is interspersed. |
| z | The value to be inserted between every pair of elements of the sequence. |
| constexpr auto boost::hana::partition | +
#include <boost/hana/fwd/partition.hpp>
Partition a sequence based on a predicate.Specifically, returns an unspecified Product whose first element is a sequence of the elements satisfying the predicate, and whose second element is a sequence of the elements that do not satisfy the predicate.
Given a Sequence S(T), an IntegralConstant Bool holding a value of type bool, and a predicate \( T \to Bool \), partition has the following signature:
+\[ \mathtt{partition} : S(T) \times (T \to Bool) \to S(T) \times S(T) \] +
+| xs | The sequence to be partitioned. |
| predicate | A function called as predicate(x) for each element x in the sequence, and returning whether x should be added to the sequence in the first component or in the second component of the resulting pair. In the current version of the library, predicate must return an IntegralConstant holding a value convertible to bool. |
partition.by) partition can be called in an alternate way, which provides a nice syntax in some cases where the predicate is short:
where partition(-, predicate) denotes the partial application of partition to predicate.
| constexpr auto boost::hana::permutations | +
#include <boost/hana/fwd/permutations.hpp>
Return a sequence of all the permutations of the given sequence.Specifically, permutations(xs) is a sequence whose elements are permutations of the original sequence xs. The permutations are not guaranteed to be in any specific order. Also note that the number of permutations grows very rapidly as the length of the original sequence increases. The growth rate is O(length(xs)!); with a sequence xs of length only 8, permutations(xs) contains over 40 000 elements!
| constexpr auto boost::hana::remove_at | +
#include <boost/hana/fwd/remove_at.hpp>
Remove the element at a given index from a sequence.remove_at returns a new sequence identical to the original, except that the element at the given index is removed. Specifically, remove_at([x0, ..., xn-1, xn, xn+1, ..., xm], n) is a new sequence equivalent to [x0, ..., xn-1, xn+1, ..., xm].
| xs | A sequence from which an element is to be removed. |
| n | An non-negative IntegralConstant representing the index of the element to be removed from the sequence. The behavior is undefined if that index is not in the bounds of the sequence. |
| constexpr auto boost::hana::remove_at_c | +
#include <boost/hana/fwd/remove_at.hpp>
Equivalent to remove_at; provided for convenience.
| constexpr auto boost::hana::remove_range | +
#include <boost/hana/fwd/remove_range.hpp>
Remove the elements inside a given range of indices from a sequence.remove_range returns a new sequence identical to the original, except that elements at indices in the provided range are removed. Specifically, remove_range([x0, ..., xn], from, to) is a new sequence equivalent to [x0, ..., x_from-1, x_to, ..., xn].
| xs | A sequence from which elements are removed. |
| [from,to) | An half-open interval of IntegralConstants representing the indices of the elements to be removed from the sequence. The IntegralConstants in the half-open interval must be non-negative and in the bounds of the sequence. The half-open interval must also be valid, meaning that from <= to. |
| constexpr auto boost::hana::remove_range_c | +
#include <boost/hana/fwd/remove_range.hpp>
Equivalent to remove_range; provided for convenience.
| constexpr auto boost::hana::reverse | +
#include <boost/hana/fwd/reverse.hpp>
Reverse a sequence.Specifically, reverse(xs) is a new sequence containing the same elements as xs, except in reverse order.
| xs | The sequence to reverse. |
| constexpr auto boost::hana::scan_left | +
#include <boost/hana/fwd/scan_left.hpp>
Fold a Sequence to the left and return a list containing the successive reduction states.Like fold_left, scan_left reduces a sequence to a single value using a binary operation. However, unlike fold_left, it builds up a sequence of the intermediary results computed along the way and returns that instead of only the final reduction state. Like fold_left, scan_left can be used with or without an initial reduction state.
When the sequence is empty, two things may arise. If an initial state was provided, a singleton list containing that state is returned. Otherwise, if no initial state was provided, an empty list is returned. In particular, unlike for fold_left, using scan_left on an empty sequence without an initial state is not an error.
More specifically, scan_left([x1, ..., xn], state, f) is a sequence whose ith element is equivalent to fold_left([x1, ..., xi], state, f). The no-state variant is handled in an analogous way. For illustration, consider this left fold on a short sequence:
The analogous sequence generated with scan_left will be
Similarly, consider this left fold (without an initial state) on a short sequence:
The analogous sequence generated with scan_left will be
| xs | The sequence to scan from the left. |
| state | The (optional) initial reduction state. |
| f | A binary function called as f(state, x), where state is the result accumulated so far and x is an element in the sequence. If no initial state is provided, f is called as f(x1, x2), where x1 and x2 are both elements of the sequence. |
| constexpr auto boost::hana::scan_right | +
#include <boost/hana/fwd/scan_right.hpp>
Fold a Sequence to the right and return a list containing the successive reduction states.Like fold_right, scan_right reduces a sequence to a single value using a binary operation. However, unlike fold_right, it builds up a sequence of the intermediary results computed along the way and returns that instead of only the final reduction state. Like fold_right, scan_right can be used with or without an initial reduction state.
When the sequence is empty, two things may arise. If an initial state was provided, a singleton list containing that state is returned. Otherwise, if no initial state was provided, an empty list is returned. In particular, unlike for fold_right, using scan_right on an empty sequence without an initial state is not an error.
More specifically, scan_right([x1, ..., xn], state, f) is a sequence whose ith element is equivalent to fold_right([x1, ..., xi], state, f). The no-state variant is handled in an analogous way. For illustration, consider this right fold on a short sequence:
The analogous sequence generated with scan_right will be
Similarly, consider this right fold (without an initial state) on a short sequence:
The analogous sequence generated with scan_right will be
| xs | The sequence to scan from the right. |
| state | The (optional) initial reduction state. |
| f | A binary function called as f(x, state), where state is the result accumulated so far and x is an element in the sequence. When no initial state is provided, f is called as f(x1, x2), where x1 and x2 are elements of the sequence. |
| constexpr auto boost::hana::slice | +
#include <boost/hana/fwd/slice.hpp>
Extract the elements of a Sequence at the given indices.Given an arbitrary sequence of indices, slice returns a new sequence of the elements of the original sequence that appear at those indices. In other words,.
The indices do not have to be ordered or contiguous in any particular way, but they must not be out of the bounds of the sequence. It is also possible to specify the same index multiple times, in which case the element at this index will be repeatedly included in the resulting sequence.
+| xs | The sequence from which a subsequence is extracted. |
| indices | A compile-time Foldable containing non-negative IntegralConstants representing the indices. The indices are 0-based, and they must all be in bounds of the xs sequence. Note that any Foldable will really do (no need for an Iterable, for example); the linearization of the indices is used to determine the order of the elements included in the slice. |
| constexpr auto boost::hana::slice_c | +
#include <boost/hana/fwd/slice.hpp>
Shorthand to slice a contiguous range of elements.slice_c is simply a shorthand to slice a contiguous range of elements. In particular, slice_c<from, to>(xs) is equivalent to slice(xs, range_c<std::size_t, from, to>), which simply slices all the elements of xs contained in the half-open interval delimited by [from, to). Like for slice, the indices used with slice_c are 0-based and they must be in the bounds of the sequence being sliced.
| from | The index of the first element in the slice. |
| to | One-past the index of the last element in the slice. It must hold that from <= to. |
| constexpr auto boost::hana::sort | +
#include <boost/hana/fwd/sort.hpp>
Sort a sequence, optionally based on a custom predicate.Given a Sequence and an optional predicate (by default less), sort returns a new sequence containing the same elements as the original, except they are ordered in such a way that if x comes before y in the sequence, then either predicate(x, y) is true, or both predicate(x, y) and predicate(y, x) are false.
Also note that the sort is guaranteed to be stable. Hence, if x comes before y in the original sequence and both predicate(x, y) and predicate(y, x) are false, then x will come before y in the resulting sequence.
If no predicate is provided, the elements in the sequence must all be compile-time Orderable.
Given a Sequence S(T), a boolean IntegralConstant Bool and a binary predicate \( T \times T \to Bool \), sort has the following signatures. For the variant with a provided predicate,
+\[ \mathtt{sort} : S(T) \times (T \times T \to Bool) \to S(T) \] +
+for the variant without a custom predicate, T is required to be Orderable. The signature is then
+\[ \mathtt{sort} : S(T) \to S(T) \] +
+| xs | The sequence to sort. |
| predicate | A function called as predicate(x, y) for two elements x and y of the sequence, and returning a boolean IntegralConstant representing whether x is to be considered less than y, i.e. whether x should appear before y in the resulting sequence. More specifically, predicate must define a strict weak ordering on the elements of the sequence. When the predicate is not specified, this defaults to less. In the current version of the library, the predicate has to return an IntegralConstant holding a value convertible to a bool. |
sort.by) sort can be called in a third way, which provides a nice syntax especially when working with the ordering combinator:
where sort(-, predicate) denotes the partial application of sort to predicate.
| constexpr auto boost::hana::span | +
#include <boost/hana/fwd/span.hpp>
Returns a Product containing the longest prefix of a sequence satisfying a predicate, and the rest of the sequence.The first component of the returned Product is a sequence for which all elements satisfy the given predicate. The second component of the returned Product is a sequence containing the remainder of the argument. Both or either sequences may be empty, depending on the input argument. More specifically,.
except that make_pair may be an arbitrary Product.
Given a Sequence S(T), a Logical Bool and a predicate \( T \to Bool \), span has the following signature:
+\[ \mathtt{span} : S(T) \times (T \to Bool) \to S(T) \times S(T) \] +
+| xs | The sequence to break into two parts. |
| predicate | A function called as predicate(x), where x is an element of the sequence, and returning a Logical. In the current implementation of the library,predicatehas to return a compile-timeLogical`. |
span.by) span can be called in an alternate way, which provides a nice syntax in some cases where the predicate is short:
where span(-, predicate) denotes the partial application of span to predicate.
| constexpr auto boost::hana::take_back | +
#include <boost/hana/fwd/take_back.hpp>
Returns the last n elements of a sequence, or the whole sequence if the sequence has less than n elements.Given a Sequence xs and an IntegralConstant n, take_back(xs, n) is a new sequence containing the last n elements of xs, in the same order. If length(xs) <= n, the whole sequence is returned and no error is triggered.
| xs | The sequence to take the elements from. |
| n | A non-negative IntegralConstant representing the number of elements to keep in the resulting sequence. |
| constexpr auto boost::hana::take_front | +
#include <boost/hana/fwd/take_front.hpp>
Returns the first n elements of a sequence, or the whole sequence if the sequence has less than n elements.Given a Sequence xs and an IntegralConstant n, take_front(xs, n) is a new sequence containing the first n elements of xs, in the same order. If length(xs) <= n, the whole sequence is returned and no error is triggered.
| xs | The sequence to take the elements from. |
| n | A non-negative IntegralConstant representing the number of elements to keep in the resulting sequence. |
| constexpr auto boost::hana::take_front_c | +
#include <boost/hana/fwd/take_front.hpp>
Equivalent to take_front; provided for convenience.
| constexpr auto boost::hana::take_while | +
#include <boost/hana/fwd/take_while.hpp>
Take elements from a sequence while the predicate is satisfied.Specifically, take_while returns a new sequence containing the longest prefix of xs in which all the elements satisfy the given predicate.
| xs | The sequence to take elements from. |
| predicate | A function called as predicate(x), where x is an element of the sequence, and returning a Logical representing whether x should be included in the resulting sequence. In the current version of the library, predicate has to return a Constant Logical. |
| constexpr auto boost::hana::unfold_left | +
#include <boost/hana/fwd/unfold_left.hpp>
Dual operation to fold_left for sequences.While fold_left reduces a structure to a summary value from the left, unfold_left builds a sequence from a seed value and a function, starting from the left.
Given a Sequence S, an initial value state of tag I, an arbitrary Product P and a function \( f : I \to P(I, T) \), unfold_left<S> has the following signature:
+\[ \mathtt{unfold\_left}_S : I \times (I \to P(I, T)) \to S(T) \] +
+| S | The tag of the sequence to build up. |
| state | An initial value to build the sequence from. |
| f | A function called as f(state), where state is an initial value, and returning
|
In some cases, unfold_left can undo a fold_left operation:
if the following holds
| constexpr auto boost::hana::unfold_right | +
#include <boost/hana/fwd/unfold_right.hpp>
Dual operation to fold_right for sequences.While fold_right reduces a structure to a summary value from the right, unfold_right builds a sequence from a seed value and a function, starting from the right.
Given a Sequence S, an initial value state of tag I, an arbitrary Product P and a function \( f : I \to P(T, I) \), unfold_right<S> has the following signature:
+\[ \mathtt{unfold\_right}_S : I \times (I \to P(T, I)) \to S(T) \] +
+| S | The tag of the sequence to build up. |
| state | An initial value to build the sequence from. |
| f | A function called as f(state), where state is an initial value, and returning
|
In some cases, unfold_right can undo a fold_right operation:
if the following holds
| constexpr auto boost::hana::unique | +
#include <boost/hana/fwd/unique.hpp>
Removes all consecutive duplicate elements from a Sequence.Given a Sequence and an optional binary predicate, unique returns a new sequence containing only the first element of every subrange of the original sequence whose elements are all equal. In other words, it turns a sequence of the form [a, a, b, c, c, c, d, d, d, a] into a sequence [a, b, c, d, a]. The equality of two elements is determined by the provided predicate, or by equal if no predicate is provided.
Given a Sequence S(T), a Logical Bool and a binary predicate \( T \times T \to Bool \), unique has the following signature:
+\[ \mathtt{unique} : S(T) \times (T \times T \to Bool) \to S(T) \] +
+| xs | The sequence from which to remove consecutive duplicates. |
| predicate | A function called as predicate(x, y), where x and y are adjacent elements of the sequence, and returning a Logical representing whether x and y should be considered equal. predicate should define an equivalence relation over the elements of the sequence. In the current implementation of the library, predicate has to return a compile-time Logical. This parameter is optional; it defaults to equal if it is not provided, which then requires the elements of the sequence to be compile-time Comparable. |
unique.by) unique can be called in an alternate way, which provides a nice syntax, especially in conjunction with the comparing combinator:
where unique(-, predicate) denotes the partial application of unique to predicate.
| constexpr auto boost::hana::zip | +
#include <boost/hana/fwd/zip.hpp>
Zip one sequence or more.Given n sequences s1, ..., sn, zip produces a sequence whose i-th element is a tuple of (s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip produces a sequence of the form.
where M is the length of the sequences, which are all assumed to have the same length. Assuming the sequences to all have the same size allows the library to perform some optimizations. To zip sequences that may have different lengths, zip_shortest should be used instead. Also note that it is an error to provide no sequence at all, i.e. zip expects at least one sequence.
| constexpr auto boost::hana::zip_shortest | +
#include <boost/hana/fwd/zip_shortest.hpp>
Zip one sequence or more.Given n sequences s1, ..., sn, zip_shortest produces a sequence whose i-th element is a tuple of (s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip_shortest produces a sequence of the form.
where M is the length of the shortest sequence. Hence, the returned sequence stops when the shortest input sequence is exhausted. If you know that all the sequences you are about to zip have the same length, you should use zip instead, since it can be more optimized. Also note that it is an error to provide no sequence at all, i.e. zip_shortest expects at least one sequence.
| constexpr auto boost::hana::zip_shortest_with | +
#include <boost/hana/fwd/zip_shortest_with.hpp>
Zip one sequence or more with a given function.Given a n-ary function f and n sequences s1, ..., sn, zip_shortest_with produces a sequence whose i-th element is f(s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip_shortest_with produces a sequence of the form.
where M is the length of the shortest sequence. Hence, the returned sequence stops when the shortest input sequence is exhausted. If you know that all the sequences you are about to zip have the same length, you should use zip_with instead, since it can be more optimized. Also note that it is an error to provide no sequence at all, i.e. zip_shortest_with expects at least one sequence.
| constexpr auto boost::hana::zip_with | +
#include <boost/hana/fwd/zip_with.hpp>
Zip one sequence or more with a given function.Given a n-ary function f and n sequences s1, ..., sn, zip_with produces a sequence whose i-th element is f(s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip_with produces a sequence of the form.
where M is the length of the sequences, which are all assumed to have the same length. Assuming the sequences to all have the same size allows the library to perform some optimizations. To zip sequences that may have different lengths, zip_shortest_with should be used instead. Also note that it is an error to provide no sequence at all, i.e. zip_with expects at least one sequence.
The Struct concept represents struct-like user-defined types.
The Struct concept allows restricted compile-time reflection over user-defined types. In particular, it allows accessing the names of the members of a user-defined type, and also the value of those members. Structs can also be folded, searched and converted to some types of containers, where more advanced transformations can be performed.
While all types can in theory be made Structs, only a subset of them are actually interesting to see as such. More precisely, it is only interesting to make a type a Struct when it is conceptually a C++ struct, i.e. a mostly dumb aggregate of named data. The way this data is accessed is mostly unimportant to the Struct concept; it could be through getters and setters, through public members, through non-member functions or it could even be generated on-the-fly. The important part, which is made precise below, is that those accessor methods should be move-independent.
Another way to see a Struct is as a map where the keys are the names of the members and the values are the values of those members. However, there are subtle differences like the fact that one can't add a member to a Struct, and also that the order of the members inside a Struct plays a role in determining the equality of Structs, which is not the case for maps.
accessors
A model of Struct is created by specifying a sequence of key/value pairs with the accessors function. The first element of a pair in this sequence represents the "name" of a member of the Struct, while the second element is a function which retrieves this member from an object. The "names" do not have to be in any special form; they just have to be compile-time Comparable. For example, it is common to provide "names" that are hana::strings representing the actual names of the members, but one could provide hana::integral_constants just as well. The values must be functions which, when given an object, retrieve the appropriate member from it.
There are several ways of providing the accessors method, some of which are more flexible and others which are more convenient. First, one can define it through tag-dispatching, as usual.
Secondly, it is possible to provide a nested hana_accessors_impl type, which should be equivalent to a specialization of accessors_impl for tag-dispatching. However, for a type S, this technique only works when the data type of S is S itself, which is the case unless you explicitly asked for something else.
Finally, the most convenient (but least flexible) option is to use the BOOST_HANA_DEFINE_STRUCT, the BOOST_HANA_ADAPT_STRUCT or the BOOST_HANA_ADAPT_ADT macro, which provide a minimal syntactic overhead. See the documentation of these macros for details on how to use them.
Also note that it is not important that the accessor functions retrieve an actual member of the struct (e.g. x.member). Indeed, an accessor function could call a custom getter or even compute the value of the member on the fly:
The only important thing is that the accessor functions are move-independent, a notion which is defined below.
+The notion of move-independence presented here defines rigorously when it is legitimate to "double-move" from an object.
+A collection of functions f1, ..., fn sharing the same domain is said to be move-independent if for every fresh (not moved-from) object x in the domain, any permutation of the following statements is valid and leaves the zk objects in a fresh (not moved-from) state:
auto zk = (like void or a non-movable, non-copyable type), just pretend the return value is ignored.Intuitively, this ensures that we can treat f1, ..., fn as "accessors" that decompose x into independent subobjects, and that do so without moving from x more than that subobject. This is important because it allows us to optimally decompose Structs into their subparts inside the library.
For any Struct S, the accessors in the accessors<S>() sequence must be move-independent, as defined above.
Comparable (free model)Structs are required to be Comparable. Specifically, two Structs of the same data type S must be equal if and only if all of their members are equal. By default, a model of Comparable doing just that is provided for models of Struct. In particular, note that the comparison of the members is made in the same order as they appear in the hana::members sequence. Foldable (free model)Struct can be folded by considering it as a list of pairs each containing the name of a member and the value associated to that member, in the same order as they appear in the hana::members sequence. By default, a model of Foldable doing just that is provided for models of the Struct concept. Foldable makes it possible to turn a Struct into basically any Sequence, but also into a hana::map by simply using the to<...> function! Searchable (free model)Struct can be searched by considering it as a map where the keys are the names of the members of the Struct, and the values are the members associated to those names. By default, a model of Searchable is provided for any model of the Struct concept. +Functions | |
| auto | boost::hana::BOOST_HANA_ADAPT_ADT (...) |
Defines a model of Struct with the given accessors.Using this macro at global scope will define a model of the Struct concept for the given type. This can be used to easily adapt existing user-defined types in a ad-hoc manner. Unlike BOOST_HANA_ADAPT_STRUCT, this macro requires specifying the way to retrieve each member by providing a function that does the extraction. More... | |
| auto | boost::hana::BOOST_HANA_ADAPT_STRUCT (...) |
Defines a model of Struct with the given members.Using this macro at global scope will define a model of the Struct concept for the given type. This can be used to easily adapt existing user-defined types in a ad-hoc manner. Unlike the BOOST_HANA_DEFINE_STRUCT macro, this macro does not require the types of the members to be specified. More... | |
| auto | boost::hana::BOOST_HANA_DEFINE_STRUCT (...) |
Defines members of a structure, while at the same time modeling Struct.Using this macro in the body of a user-defined type will define the given members inside that type, and will also provide a model of the Struct concept for that user-defined type. This macro is often the easiest way to define a model of the Struct concept. More... | |
+Variables | |
| template<typename S > | |
| constexpr auto | boost::hana::accessors |
Returns a Sequence of pairs representing the accessors of the data structure.Given a Struct S, accessors<S>() is a Sequence of Products where the first element of each pair is the "name" of a member of the Struct, and the second element of each pair is a function that can be used to access that member when given an object of the proper data type. As described in the global documentation for Struct, the accessor functions in this sequence must be move-independent. More... | |
| constexpr keys_t | boost::hana::keys {} |
Returns a Sequence containing the name of the members of the data structure.Given a Struct object, keys returns a Sequence containing the name of all the members of the Struct, in the same order as they appear in the accessors sequence. More... | |
| constexpr auto | boost::hana::members |
Returns a Sequence containing the members of a Struct.Given a Struct object, members returns a Sequence containing all the members of the Struct, in the same order as their respective accessor appears in the accessors sequence. More... | |
| auto boost::hana::BOOST_HANA_ADAPT_ADT | +( | ++ | ... | ) | ++ |
#include <boost/hana/fwd/adapt_adt.hpp>
Defines a model of Struct with the given accessors.Using this macro at global scope will define a model of the Struct concept for the given type. This can be used to easily adapt existing user-defined types in a ad-hoc manner. Unlike BOOST_HANA_ADAPT_STRUCT, this macro requires specifying the way to retrieve each member by providing a function that does the extraction.
T is T itself. This is the case unless you specifically asked for something different; see tag_of's documentation.| auto boost::hana::BOOST_HANA_ADAPT_STRUCT | +( | ++ | ... | ) | ++ |
#include <boost/hana/fwd/adapt_struct.hpp>
Defines a model of Struct with the given members.Using this macro at global scope will define a model of the Struct concept for the given type. This can be used to easily adapt existing user-defined types in a ad-hoc manner. Unlike the BOOST_HANA_DEFINE_STRUCT macro, this macro does not require the types of the members to be specified.
T is T itself. This is the case unless you specifically asked for something different; see tag_of's documentation.| auto boost::hana::BOOST_HANA_DEFINE_STRUCT | +( | ++ | ... | ) | ++ |
#include <boost/hana/fwd/define_struct.hpp>
Defines members of a structure, while at the same time modeling Struct.Using this macro in the body of a user-defined type will define the given members inside that type, and will also provide a model of the Struct concept for that user-defined type. This macro is often the easiest way to define a model of the Struct concept.
T is T itself. This is the case unless you specifically asked for something different; see tag_of's documentation.| constexpr auto boost::hana::accessors | +
#include <boost/hana/fwd/accessors.hpp>
Returns a Sequence of pairs representing the accessors of the data structure.Given a Struct S, accessors<S>() is a Sequence of Products where the first element of each pair is the "name" of a member of the Struct, and the second element of each pair is a function that can be used to access that member when given an object of the proper data type. As described in the global documentation for Struct, the accessor functions in this sequence must be move-independent.
+
|
+ +related | +
#include <boost/hana/fwd/keys.hpp>
Returns a Sequence containing the name of the members of the data structure.Given a Struct object, keys returns a Sequence containing the name of all the members of the Struct, in the same order as they appear in the accessors sequence.
| constexpr auto boost::hana::members | +
#include <boost/hana/fwd/members.hpp>
Returns a Sequence containing the members of a Struct.Given a Struct object, members returns a Sequence containing all the members of the Struct, in the same order as their respective accessor appears in the accessors sequence.
Macros to perform different kinds of assertions.
++Macros | |
| #define | BOOST_HANA_RUNTIME_ASSERT(condition) unspecified |
| Expands to a runtime assertion. More... | |
| #define | BOOST_HANA_RUNTIME_ASSERT_MSG(condition, message) unspecified |
Equivalent to BOOST_HANA_RUNTIME_ASSERT, but allows providing a custom failure message. More... | |
| #define | BOOST_HANA_CONSTANT_ASSERT(condition) unspecified |
Compile-time assertion for Constants. More... | |
| #define | BOOST_HANA_CONSTANT_ASSERT_MSG(condition, message) unspecified |
Equivalent to BOOST_HANA_CONSTANT_ASSERT, but allows providing a custom failure message. More... | |
| #define | BOOST_HANA_ASSERT(condition) unspecified |
| Expands to the strongest form of assertion possible for the given condition. More... | |
| #define | BOOST_HANA_ASSERT_MSG(condition, message) unspecified |
Equivalent to BOOST_HANA_ASSERT, but allows providing a custom failure message. More... | |
| #define | BOOST_HANA_CONSTEXPR_ASSERT(condition) unspecified |
Expands to a static assertion or a runtime assertion, depending on whether constexpr lambdas are supported. More... | |
| +#define | BOOST_HANA_CONSTEXPR_ASSERT_MSG(condition, message) unspecified |
Equivalent to BOOST_HANA_CONSTEXPR_ASSERT, but allows providing a custom failure message. | |
| +#define | BOOST_HANA_RUNTIME_CHECK_MSG(condition, message) |
Equivalent to BOOST_HANA_RUNTIME_ASSERT_MSG, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
| +#define | BOOST_HANA_RUNTIME_CHECK(...) |
Equivalent to BOOST_HANA_RUNTIME_ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
| +#define | BOOST_HANA_CONSTANT_CHECK_MSG(condition, message) |
Equivalent to BOOST_HANA_CONSTANT_ASSERT_MSG, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
| +#define | BOOST_HANA_CONSTANT_CHECK(...) |
Equivalent to BOOST_HANA_CONSTANT_ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
| +#define | BOOST_HANA_CHECK_MSG(condition, message) |
Equivalent to BOOST_HANA_ASSERT_MSG, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
| +#define | BOOST_HANA_CHECK(...) |
Equivalent to BOOST_HANA__ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
| +#define | BOOST_HANA_CONSTEXPR_CHECK_MSG(condition, message) BOOST_HANA_RUNTIME_CHECK_MSG(condition, message) \ |
Equivalent to BOOST_HANA_CONSTEXPR_ASSERT_MSG, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
| +#define | BOOST_HANA_CONSTEXPR_CHECK(...) |
Equivalent to BOOST_HANA_CONSTEXPR_ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIONS config macro. For internal use only. | |
| #define BOOST_HANA_RUNTIME_ASSERT | +( | ++ | condition | ) | +unspecified | +
#include <boost/hana/assert.hpp>
Expands to a runtime assertion.
+Given a condition known at runtime, this macro expands to a runtime assertion similar to the assert macro. The provided condition must be explicitly convertible to a bool, and it must not be a model of the Constant concept. If the condition is a Constant, a static assertion will be triggered, asking you to use the BOOST_HANA_CONSTANT_ASSERT macro instead.
| #define BOOST_HANA_RUNTIME_ASSERT_MSG | +( | ++ | condition, | +
| + | + | + | message | +
| + | ) | +unspecified | +
#include <boost/hana/assert.hpp>
Equivalent to BOOST_HANA_RUNTIME_ASSERT, but allows providing a custom failure message.
| #define BOOST_HANA_CONSTANT_ASSERT | +( | ++ | condition | ) | +unspecified | +
#include <boost/hana/assert.hpp>
Compile-time assertion for Constants.
Given a condition known at compile-time in the form of a Constant, this macro expands to a compile-time assertion similar to a static_assert. The provided condition must be a model of the Constant concept, in which case its value is retrieved using hana::value and then converted to a bool. If the condition is not a Constant, a static assertion will be triggered, asking you to use the BOOST_HANA_RUNTIME_ASSERT macro instead.
This macro may be used at global/namespace scope and function scope only; it may not be used at class scope. Note that the condition may never be evaluated at runtime. Hence, any side effect may not take place (but you shouldn't rely on side effects inside assertions anyway).
+ +| #define BOOST_HANA_CONSTANT_ASSERT_MSG | +( | ++ | condition, | +
| + | + | + | message | +
| + | ) | +unspecified | +
#include <boost/hana/assert.hpp>
Equivalent to BOOST_HANA_CONSTANT_ASSERT, but allows providing a custom failure message.
| #define BOOST_HANA_ASSERT | +( | ++ | condition | ) | +unspecified | +
#include <boost/hana/assert.hpp>
Expands to the strongest form of assertion possible for the given condition.
+Given a condition, BOOST_HANA_ASSERT expands either to a compile-time or to a runtime assertion, depending on whether the value of the condition is known at compile-time or at runtime. Compile-time assertions are always preferred over runtime assertions. If the condition is a model of the Constant concept, its value (retrievable with hana::value) is assumed to be explicitly convertible to bool, and a compile-time assertion is performed on it. Otherwise, the condition itself is assumed to be explicitly convertible to bool, and a runtime assertion is performed on it.
If the assertion can be carried out at compile-time, the condition is not guaranteed to be evaluated at runtime at all (but it may). Hence, in general, you shouldn't rely on side effects that take place inside an assertion.
+| #define BOOST_HANA_ASSERT_MSG | +( | ++ | condition, | +
| + | + | + | message | +
| + | ) | +unspecified | +
#include <boost/hana/assert.hpp>
Equivalent to BOOST_HANA_ASSERT, but allows providing a custom failure message.
| #define BOOST_HANA_CONSTEXPR_ASSERT | +( | ++ | condition | ) | +unspecified | +
#include <boost/hana/assert.hpp>
Expands to a static assertion or a runtime assertion, depending on whether constexpr lambdas are supported.
This macro is used to assert on a condition that would be a constant expression if constexpr lambdas were supported. Right now, constexpr lambdas are not supported, and this is always a runtime assertion. Specifically, this is equivalent to BOOST_HANA_RUNTIME_ASSERT.
Concepts provided by the library.
++Modules | |
| Applicative | |
The Applicative concept represents Functors with the ability to lift values and combine computations. | |
| Comonad | |
The Comonad concept represents context-sensitive computations and data. | |
| Comparable | |
The Comparable concept defines equality and inequality. | |
| Constant | |
The Constant concept represents data that can be manipulated at compile-time. | |
| Euclidean Ring | |
The EuclideanRing concept represents a commutative Ring that can also be endowed with a division algorithm. | |
| Foldable | |
The Foldable concept represents data structures that can be reduced to a single value. | |
| Functor | |
The Functor concept represents types that can be mapped over. | |
| Group | |
The Group concept represents Monoids where all objects have an inverse w.r.t. the Monoid's binary operation. | |
| Hashable | |
The Hashable concept represents objects that can be normalized to a type-level hash. | |
| Iterable | |
The Iterable concept represents data structures supporting external iteration. | |
| Logical | |
The Logical concept represents types with a truth value. | |
| Metafunction | |
A Metafunction is a function that takes hana::types as inputs and returns a hana::type as output. | |
| Monad | |
The Monad concept represents Applicatives with the ability to flatten nested levels of structure. | |
| MonadPlus | |
The MonadPlus concept represents Monads with a monoidal structure. | |
| Monoid | |
The Monoid concept represents data types with an associative binary operation that has an identity. | |
| Orderable | |
The Orderable concept represents totally ordered data types. | |
| Product | |
| Represents types that are generic containers of two elements. | |
| Ring | |
The Ring concept represents Groups that also form a Monoid under a second binary operation that distributes over the first. | |
| Searchable | |
The Searchable concept represents structures that can be searched. | |
| Sequence | |
The Sequence concept represents generic index-based sequences. | |
| Struct | |
The Struct concept represents struct-like user-defined types. | |
+Classes | |
| struct | boost::hana::IntegralConstant< C > |
The IntegralConstant concept represents compile-time integral values. More... | |
Configurable options to tweak the global behavior of the library.
++Macros | |
| #define | BOOST_HANA_CONFIG_DISABLE_ASSERTIONS |
Disables the BOOST_HANA_*_ASSERT macro & friends. More... | |
| #define | BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS |
| Disables concept checks in interface methods. More... | |
| #define | BOOST_HANA_CONFIG_ENABLE_STRING_UDL |
| Enables usage of the "string literal operator template" GNU extension. More... | |
| #define | BOOST_HANA_CONFIG_ENABLE_DEBUG_MODE |
| Enables additional assertions and sanity checks to be done by Hana. More... | |
| +#define | BOOST_HANA_MAJOR_VERSION 1 |
Macro expanding to the major version of the library, i.e. the x in x.y.z. | |
| +#define | BOOST_HANA_MINOR_VERSION 0 |
Macro expanding to the minor version of the library, i.e. the y in x.y.z. | |
| +#define | BOOST_HANA_PATCH_VERSION 2 |
Macro expanding to the patch level of the library, i.e. the z in x.y.z. | |
| #define | BOOST_HANA_VERSION |
| Macro expanding to the full version of the library, in hexadecimal representation. More... | |
| #define BOOST_HANA_CONFIG_DISABLE_ASSERTIONS | +
#include <boost/hana/config.hpp>
Disables the BOOST_HANA_*_ASSERT macro & friends.
When this macro is defined, the BOOST_HANA_*_ASSERT macro & friends are disabled, i.e. they expand to nothing.
This macro is defined automatically when NDEBUG is defined. It can also be defined by users before including this header or defined on the command line.
| #define BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS | +
#include <boost/hana/config.hpp>
Disables concept checks in interface methods.
+When this macro is not defined (the default), tag-dispatched methods will make sure the arguments they are passed are models of the proper concept(s). This can be very helpful in catching programming errors, but it is also slightly less compile-time efficient. You should probably always leave the checks enabled (and hence never define this macro), except perhaps in translation units that are compiled very often but whose code using Hana is modified very rarely.
+ +| #define BOOST_HANA_CONFIG_ENABLE_STRING_UDL | +
#include <boost/hana/config.hpp>
Enables usage of the "string literal operator template" GNU extension.
+That operator is not part of the language yet, but it is supported by both Clang and GCC. This operator allows Hana to provide the nice _s user-defined literal for creating compile-time strings.
When this macro is not defined, the GNU extension will be not used by Hana. Because this is a non-standard extension, the macro is not defined by default.
+ +| #define BOOST_HANA_CONFIG_ENABLE_DEBUG_MODE | +
#include <boost/hana/config.hpp>
Enables additional assertions and sanity checks to be done by Hana.
+When this macro is defined (it is not defined by default), additional sanity checks may be done by Hana. These checks may be costly to perform, either in terms of compilation time or in terms of execution time. These checks may help debugging an application during its initial development, but they should not be enabled as part of the normal configuration.
+ +| #define BOOST_HANA_VERSION | +
#include <boost/hana/version.hpp>
Macro expanding to the full version of the library, in hexadecimal representation.
+Specifically, BOOST_HANA_VERSION expands to an hexadecimal number of the form 0xVVRRPPPP, where VV is the major version of the library, RR is the minor version and PPPP is the patch level. This allows the version of the library to be compared:
BOOST_HANA_{MAJOR,MINOR,PATCH}_VERSION macros. Core utilities of the library.
++Classes | |
| struct | boost::hana::common< T, U, enabler > |
| Metafunction returning the common data type between two data types. More... | |
| struct | boost::hana::has_common< T, U, typename > |
| Metafunction returning whether two data types share a common data type. More... | |
| struct | boost::hana::default_ |
| Mark a tag-dispatched method implementation as a default implementation. More... | |
| struct | boost::hana::is_default< Method, typename > |
| Returns whether a tag-dispatched method implementation is a default implementation. More... | |
| struct | boost::hana::tag_of< T, enabler > |
Metafunction returning the tag associated to T. More... | |
| struct | boost::hana::is_convertible< From, To, typename > |
| Returns whether there is a Hana-conversion from a data type to another. More... | |
| struct | boost::hana::embedding< bool > |
| Marks a conversion between data types as being an embedding. More... | |
| struct | boost::hana::is_embedded< From, To, typename > |
| Returns whether a data type can be embedded into another data type. More... | |
| struct | boost::hana::when< condition > |
| Enable a partial specialization only if a boolean condition is true. More... | |
+Typedefs | |
| template<typename T , typename U > | |
| using | boost::hana::common_t = typename common< T, U >::type |
Alias to common<T, U>::type, provided for convenience. More... | |
| template<typename T > | |
| using | boost::hana::tag_of_t = typename hana::tag_of< T >::type |
Alias to tag_of<T>::type, provided for convenience. More... | |
| template<typename... > | |
| using | boost::hana::when_valid = when< true > |
Variant of when allowing specializations to be enabled only if an expression is well-formed. More... | |
+Variables | |
| template<typename Tag , typename optional_T > | |
| constexpr auto | boost::hana::is_a = see-documentation |
| Returns whether the tag of an object matches a given tag. More... | |
| +template<typename Tag , typename... T> | |
| constexpr auto | boost::hana::is_an = is_a<Tag, T...> |
Equivalent to is_a; provided for consistency with the rules of the English language. | |
| template<typename Tag > | |
| constexpr auto | boost::hana::make |
| Create an object of the given tag with the given arguments. More... | |
| template<typename To > | |
| constexpr auto | boost::hana::to |
| Converts an object from one data type to another. More... | |
| using boost::hana::common_t = typedef typename common<T, U>::type | +
#include <boost/hana/fwd/core/common.hpp>
Alias to common<T, U>::type, provided for convenience.
| using boost::hana::tag_of_t = typedef typename hana::tag_of<T>::type | +
#include <boost/hana/fwd/core/tag_of.hpp>
Alias to tag_of<T>::type, provided for convenience.
| using boost::hana::when_valid = typedef when<true> | +
#include <boost/hana/fwd/core/when.hpp>
Variant of when allowing specializations to be enabled only if an expression is well-formed.
when_valid<...> is always equivalent to when<true>. However, when used inside a partial specialization, SFINAE will cause the partial specialization to be ignored when the expression is ill-formed.
when_valid seems to trigger ambiguous partial specializations on GCC. | constexpr auto boost::hana::is_a = see-documentation | +
#include <boost/hana/fwd/core/is_a.hpp>
Returns whether the tag of an object matches a given tag.
+Given a tag Tag and a C++ type T, is_a<Tag, T> is a compile-time Logical representing whether the tag of T is exactly Tag. In other words, it is equivalent to
For convenience, an alternate syntax is provided for using is_a. Specifically, is_a<Tag> is a function object returning whether the argument it is passed has the given tag. In other words,
| constexpr auto boost::hana::make | +
#include <boost/hana/fwd/core/make.hpp>
Create an object of the given tag with the given arguments.
+This function serves the same purpose as constructors in usual C++. However, instead of creating an object of a specific C++ type, it creates an object of a specific tag, regardless of the C++ type of that object.
+This function is actually a variable template, so make<T> can be passed around as a function object creating an object of tag T. Also, it uses tag-dispatching so this is how it should be customized for user-defined tags.
Finally, the default implementation of make is equivalent to calling the constructor of the given tag with the corresponding arguments. In other words, by default,
Note that the arguments are perfectly forwarded and the form of construction which is used is exactly as documented, i.e. T(args...). However, if T(args...) is not a valid expression, a compilation error is triggered. This default behavior is useful because it makes foreign C++ types that have no notion of tag constructible with make out-of-the-box, since their tag is exactly themselves.
| constexpr auto boost::hana::to | +
#include <boost/hana/fwd/core/to.hpp>
Converts an object from one data type to another.
+to is a natural extension of the static_cast language construct to data types. Given a destination data type To and an object x, to creates a new object of data type To from x. Note, however, that to is not required to actually create a new object, and may return a reference to the original object (for example when trying to convert an object to its own data type).
As a natural extension to static_cast, to provides a default behavior. For the purpose of what follows, let To be the destination data type and From be the data type of x, i.e. the source data type. Then, to has the following default behavior:
To and From data types are the same, then the object is forwarded as-is.From is convertible to To using static_cast, x is converted to From using static_cast.to<From>(x) triggers a static assertion.However, to is a tag-dispatched function, which means that to_impl may be specialized in the boost::hana namespace to customize its behavior for arbitrary data types. Also note that to is tag-dispatched using both the To and the From data types, which means that to_impl is called as to_impl<To, From>::apply(x). Also note that some concepts provide conversions to or from their models. For example, any Foldable may be converted into a Sequence. This is achieved by specializing to_impl<To, From> whenever To is a Sequence and From is a Foldable. When such conversions are provided, they are documented in the source concept, in this case Foldable.
When an object x of data type From can be converted to a data type To using to, we say that x is Hana-convertible to the data type To. We also say that there is a Hana-conversion from From to To. This bit of terminology is useful to avoid mistaking the various kinds of conversions C++ offers.
As you might have seen by now, Hana uses algebraic and category- theoretical structures all around the place to help specify concepts in a rigorous way. These structures always have operations associated to them, which is why they are useful. The notion of embedding captures the idea of injecting a smaller structure into a larger one while preserving the operations of the structure. In other words, an embedding is an injective mapping that is also structure-preserving. Exactly what it means for a structure's operations to be preserved is left to explain by the documentation of each structure. For example, when we talk of a Monoid-embedding from a Monoid A to a Monoid B, we simply mean an injective transformation that preserves the identity and the associative operation, as documented in Monoid.
But what does this have to do with the to function? Quite simply, the to function is a mapping between two data types, which will sometimes be some kind of structure, and it is sometimes useful to know whether such a mapping is well-behaved, i.e. lossless and structure preserving. The criterion for this conversion to be well- behaved is exactly that of being an embedding. To specify that a conversion is an embedding, simply use the embedding type as a base class of the corresponding to_impl specialization. Obviously, you should make sure the conversion is really an embedding, unless you want to shoot yourself in the foot.
| To | The data type to which x should be converted. |
| x | The object to convert to the given data type. |
General purpose data types provided by the library.
++Classes | |
| struct | boost::hana::integral_constant< T, v > |
| Compile-time value of an integral type. More... | |
| struct | boost::hana::basic_tuple< Xs > |
Stripped down version of hana::tuple. More... | |
| struct | boost::hana::lazy< implementation_defined > |
hana::lazy implements superficial laziness via a monadic interface. More... | |
| struct | boost::hana::map< Pairs > |
Basic associative container requiring unique, Comparable and Hashable keys. More... | |
| struct | boost::hana::optional< T > |
| Optional value whose optional-ness is known at compile-time. More... | |
| struct | boost::hana::pair< First, Second > |
| Generic container for two elements. More... | |
| struct | boost::hana::range< T, from, to > |
Compile-time half-open interval of hana::integral_constants. More... | |
| struct | boost::hana::set< implementation_defined > |
Basic unordered container requiring unique, Comparable and Hashable keys. More... | |
| struct | boost::hana::string< implementation_defined > |
| Compile-time string. More... | |
| struct | boost::hana::tuple< Xn > |
| General purpose index-based heterogeneous sequence with a fixed length. More... | |
| struct | boost::hana::type< T > |
| C++ type in value-level representation. More... | |
Implementation details. Do not rely on anything here, even if it is documented.
++Classes | |
| struct | boost::hana::detail::any_of< Predicate, T > |
Returns whether the Predicate is satisfied by any of the T.... More... | |
| struct | boost::hana::detail::array< T, Size > |
A minimal std::array with better constexpr support. More... | |
| struct | boost::hana::detail::CanonicalConstant< T > |
Tag representing a canonical Constant. More... | |
| struct | boost::hana::detail::create< T > |
Implementation of the generic std::make_xxx pattern for arbitrary xxxs. More... | |
| struct | boost::hana::detail::decay< T, U > |
Equivalent to std::decay, except faster. More... | |
| struct | boost::hana::detail::first_unsatisfied_index< Pred > |
Returns the index of the first element which does not satisfy Pred, or sizeof...(Xs) if no such element exists. More... | |
| struct | boost::hana::detail::has_duplicates< T > |
Returns whether any of the Ts are duplicate w.r.t. hana::equal. More... | |
| struct | boost::hana::detail::index_if< Pred, Ts, typename > |
Returns the index of the first element of the pack<> that satisfies the predicate, or the size of the pack if there is no such element. More... | |
| struct | boost::hana::detail::nested_by< Algorithm > |
Provides a .by static constexpr function object. More... | |
| struct | boost::hana::detail::nested_than< Algorithm > |
Provides a .than static constexpr function object. More... | |
| struct | boost::hana::detail::nested_to< Algorithm > |
Provides a .to static constexpr function object. More... | |
| struct | boost::hana::detail::operators::adl<... > |
Enables ADL in the hana::detail::operators namespace. More... | |
| struct | boost::hana::detail::std_common_type< T, U, typename > |
Equivalent to std::common_type, except it is SFINAE-friendly and does not support custom specializations. More... | |
| struct | boost::hana::detail::type_at< n, T > |
| Classic MPL-style metafunction returning the nth element of a type parameter pack. More... | |
+Macros | |
| #define | BOOST_HANA_DISPATCH_IF(IMPL, ...) IMPL |
| Dispatch to the given implementation method only when a condition is satisfied. More... | |
| #define | BOOST_HANA_PP_NARG(...) BOOST_HANA_PP_NARG_IMPL(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,) |
| Macro expanding to the number of arguments it is passed. More... | |
| +#define | BOOST_HANA_PP_CONCAT(x, y) BOOST_HANA_PP_CONCAT_PRIMITIVE(x, y) |
| Expands to the concatenation of its two arguments. | |
| +#define | BOOST_HANA_PP_STRINGIZE(...) BOOST_HANA_PP_STRINGIZE_PRIMITIVE(__VA_ARGS__) |
| Expands to the stringized version of its argument. | |
| #define | BOOST_HANA_PP_BACK(...) BOOST_HANA_PP_BACK_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__) |
| Expands to its last argument. More... | |
| #define | BOOST_HANA_PP_DROP_BACK(...) BOOST_HANA_PP_DROP_BACK_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__) |
| Expands to all of its arguments, except for the last one. More... | |
| +#define | BOOST_HANA_PP_FRONT(...) BOOST_HANA_PP_FRONT_IMPL(__VA_ARGS__, ) |
| Expands to its first argument. | |
| #define | BOOST_HANA_PP_DROP_FRONT(e0, ...) __VA_ARGS__ |
| Expands to all of its arguments, except for the first one. More... | |
+Typedefs | |
| template<template< typename... > class Concept, typename T , typename U > | |
| using | boost::hana::detail::has_common_embedding = typename has_common_embedding_impl< Concept, T, U >::type |
Returns whether T and U both have an embedding into a common type. More... | |
| template<template< typename... > class Concept, typename T , typename U > | |
| using | boost::hana::detail::has_nontrivial_common_embedding = typename has_nontrivial_common_embedding_impl< Concept, T, U >::type |
Returns whether T and U are distinct and both have an embedding into a common type. More... | |
| #define BOOST_HANA_DISPATCH_IF | +( | ++ | IMPL, | +
| + | + | + | ... | +
| + | ) | +IMPL | +
#include <boost/hana/detail/dispatch_if.hpp>
Dispatch to the given implementation method only when a condition is satisfied.
+If the condition is satisfied, this macro is equivalent to the type IMPL. Otherwise, it is equivalent to a type with a deleted static function named apply. When a tag-dispatching error happens, the condition should be false and the deleted static function apply will prevent the compiler from generating too much garbage.
BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS is defined, the condition is always ignored and this macro expands to the implementation only.BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS is defined. | #define BOOST_HANA_PP_NARG | +( | ++ | ... | ) | +BOOST_HANA_PP_NARG_IMPL(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,) | +
#include <boost/hana/detail/preprocessor.hpp>
Macro expanding to the number of arguments it is passed.
+Specifically, BOOST_HANA_PP_NARG(x1, ..., xn) expands to n. It is undefined behavior if n > 64 or if n == 0.
| #define BOOST_HANA_PP_BACK | +( | ++ | ... | ) | +BOOST_HANA_PP_BACK_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__) | +
#include <boost/hana/detail/preprocessor.hpp>
Expands to its last argument.
+This macro can be passed up to 20 arguments.
+ +| #define BOOST_HANA_PP_DROP_BACK | +( | ++ | ... | ) | +BOOST_HANA_PP_DROP_BACK_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__) | +
#include <boost/hana/detail/preprocessor.hpp>
Expands to all of its arguments, except for the last one.
+This macro can be given up to 20 arguments.
+ +| #define BOOST_HANA_PP_DROP_FRONT | +( | ++ | e0, | +
| + | + | + | ... | +
| + | ) | +__VA_ARGS__ | +
#include <boost/hana/detail/preprocessor.hpp>
Expands to all of its arguments, except for the first one.
+This macro may not be called with less than 2 arguments.
+ +| using boost::hana::detail::has_common_embedding = typedef typename has_common_embedding_impl<Concept, T, U>::type | +
#include <boost/hana/detail/has_common_embedding.hpp>
Returns whether T and U both have an embedding into a common type.
If T and U do not have a common-type, this metafunction returns false.
| using boost::hana::detail::has_nontrivial_common_embedding = typedef typename has_nontrivial_common_embedding_impl<Concept, T, U>::type | +
#include <boost/hana/detail/has_common_embedding.hpp>
Returns whether T and U are distinct and both have an embedding into a common type.
If T and U do not have a common-type, this metafunction returns false.
Experimental features that may or may not make it into the library. These features should not expected to be stable.
++Classes | |
| struct | boost::hana::experimental::types< T > |
| Container optimized for holding types. More... | |
+Functions | |
| template<typename T > | |
| auto | boost::hana::experimental::type_name () |
Returns a hana::string representing the name of the given type, at compile-time. More... | |
+Variables | |
| auto | boost::hana::experimental::print |
| Returns a string representation of the given object. More... | |
| auto boost::hana::experimental::type_name | +( | +) | ++ |
#include <boost/hana/experimental/type_name.hpp>
Returns a hana::string representing the name of the given type, at compile-time.
This only works on Clang (and apparently MSVC, but Hana does not work there as of writing this). Original idea taken from https://github.com/Manu343726/ctti.
+ +| auto boost::hana::experimental::print | +
#include <boost/hana/experimental/printable.hpp>
Returns a string representation of the given object.
+This function is defined for most containers provided by Hana, and also for objects that define an operator<< that can be used with a std::basic_ostream. It can recursively print containers within containers, but do not expect any kind of proper indentation.
This function requires (the rest of) Boost to be available on the system. It also requires RTTI to be enabled.
+ +Adapters for miscellaneous heterogeneous containers in Boost.
++Classes | |
| struct | boost::tuple< T > |
Adapter for boost::tuples. More... | |
Adapters for Boost.Fusion containers.
++Classes | |
| struct | boost::fusion::deque< T > |
| Adapter for Boost.Fusion deques. More... | |
| struct | boost::fusion::list< T > |
| Adapter for Boost.Fusion lists. More... | |
| struct | boost::fusion::tuple< T > |
| Adapter for Boost.Fusion tuples. More... | |
| struct | boost::fusion::vector< T > |
| Adapter for Boost.Fusion vectors. More... | |
Adapters for Boost.MPL containers.
++Classes | |
| struct | boost::mpl::integral_c< T, v > |
| Adapter for IntegralConstants from the Boost.MPL. More... | |
| struct | boost::mpl::list< T > |
| Adapter for Boost.MPL lists. More... | |
| struct | boost::mpl::vector< T > |
| Adapter for Boost.MPL vectors. More... | |
Adapters for components in the standard library.
++Classes | |
| struct | std::array< T, N > |
Adaptation of std::array for Hana. More... | |
| struct | std::integer_sequence< T, v > |
Adaptation of std::integer_sequence for Hana. More... | |
| struct | std::integral_constant< T, v > |
Adapter for std::integral_constants. More... | |
| struct | std::pair< First, Second > |
Adaptation of std::pair for Hana. More... | |
| class | std::ratio< Num, Denom > |
Adaptation of std::ratio for Hana. More... | |
| struct | std::tuple< T > |
Adapter for std::tuples. More... | |
Adapters for external libraries.
++Modules | |
| Boost.Fusion adapters | |
| Adapters for Boost.Fusion containers. | |
| Boost.MPL adapters | |
| Adapters for Boost.MPL containers. | |
| Other Boost adapters | |
| Adapters for miscellaneous heterogeneous containers in Boost. | |
| Standard library adapters | |
| Adapters for components in the standard library. | |
General purpose function objects.
++Variables | |
| constexpr auto | boost::hana::always |
Return a constant function returning x regardless of the argument(s) it is invoked with. More... | |
| constexpr auto | boost::hana::apply |
| Invokes a Callable with the given arguments. More... | |
| template<std::size_t n> | |
| constexpr auto | boost::hana::arg |
Return the nth passed argument. More... | |
| constexpr auto | boost::hana::capture |
| Create a function capturing the given variables. More... | |
| constexpr auto | boost::hana::compose |
| Return the composition of two functions or more. More... | |
| template<std::size_t n> | |
| constexpr auto | boost::hana::curry |
| Curry a function up to the given number of arguments. More... | |
| constexpr auto | boost::hana::demux |
| Invoke a function with the results of invoking other functions on its arguments. More... | |
| constexpr auto | boost::hana::fix |
| Return a function computing the fixed point of a function. More... | |
| constexpr auto | boost::hana::flip |
| Invoke a function with its two first arguments reversed. More... | |
| constexpr auto | boost::hana::id |
| The identity function – returns its argument unchanged. More... | |
| constexpr auto | boost::hana::infix |
| Return an equivalent function that can also be applied in infix notation. More... | |
| template<std::size_t n> | |
| constexpr auto | boost::hana::iterate |
Applies another function n times to its argument. More... | |
| constexpr auto | boost::hana::lockstep |
| Invoke a function with the result of invoking other functions on its arguments, in lockstep. More... | |
| constexpr auto | boost::hana::on |
| Invoke a function with the result of invoking another function on each argument. More... | |
| constexpr auto | boost::hana::overload |
| Pick one of several functions to call based on overload resolution. More... | |
| constexpr auto | boost::hana::overload_linearly |
| Call the first function that produces a valid call expression. More... | |
| constexpr auto | boost::hana::partial |
| Partially apply a function to some arguments. More... | |
| constexpr unspecified | boost::hana::_ {} |
| Create simple functions representing C++ operators inline. More... | |
| constexpr auto | boost::hana::reverse_partial |
| Partially apply a function to some arguments. More... | |
| constexpr auto boost::hana::always | +
#include <boost/hana/functional/always.hpp>
Return a constant function returning x regardless of the argument(s) it is invoked with.
Specifically, always(x) is a function such that
for any y.... A copy of x is made and it is owned by the always(x) function. When always(x) is called, it will return a reference to the x it owns. This reference is valid as long as always(x) is in scope.
| constexpr auto boost::hana::apply | +
#include <boost/hana/functional/apply.hpp>
Invokes a Callable with the given arguments.
+This is equivalent to std::invoke that will be added in C++17. However, apply is a function object instead of a function, which makes it possible to pass it to higher-order algorithms.
| f | A Callable to be invoked with the given arguments. |
| x... | The arguments to call f with. The number of x... must match the arity of f. |
Referenced by boost::hana::literals::operator""_c(), and boost::hana::literals::operator""_s().
+ +| constexpr auto boost::hana::arg | +
#include <boost/hana/functional/arg.hpp>
Return the nth passed argument.
Specifically, arg<n>(x1, ..., xn, ..., xm) is equivalent to xn. Note that indexing starts at 1, so arg<1> returns the 1st argument, arg<2> the 2nd and so on. Using arg<0> is an error. Passing less than n arguments to arg<n> is also an error.
| n | An unsigned integer representing the argument to return. n must be positive (meaning nonzero). |
| x1,...,xm | A variadic pack of arguments from which the nth one is returned. |
n be dynamic?We could have chosen arg to be used like arg(n)(x...) instead of arg<n>(x...). Provided all the arguments were of the same type, it would then be possible for n to only be known at runtime. However, we would then lose the ability to assert the in-boundedness of n statically.
n being a non-type template parameterI claim that the only interesting use case is with a compile-time n, which means that the usage would become arg(int_<n>)(x...), which is more cumbersome to write than arg<n>(x...). This is open for discussion.
| constexpr auto boost::hana::capture | +
#include <boost/hana/functional/capture.hpp>
Create a function capturing the given variables.
+Given 0 or more variables, capture creates a closure that can be used to partially apply a function. This is very similar to partial, except that capture allows the partially applied function to be specified later. Specifically, capture(vars...) is a function object taking a function f and returning f partially applied to vars.... In other words,
f must match the total number of arguments passed to it, i.e. sizeof...(vars) + sizeof...(args).| constexpr auto boost::hana::compose | +
#include <boost/hana/functional/compose.hpp>
Return the composition of two functions or more.
+compose is defined inductively. When given more than two functions, compose(f, g, h...) is equivalent to compose(f, compose(g, h...)). When given two functions, compose(f, g) is a function such that
If you need composition of the form f(g(x, y...)), use demux instead.
compose is an associative operation; compose(f, compose(g, h)) is equivalent to compose(compose(f, g), h).| constexpr auto boost::hana::curry | +
#include <boost/hana/functional/curry.hpp>
Curry a function up to the given number of arguments.
+Currying is a technique in which we consider a function taking multiple arguments (or, equivalently, a tuple of arguments), and turn it into a function which takes a single argument and returns a function to handle the remaining arguments. To help visualize, let's denote the type of a function f which takes arguments of types X1, ..., Xn and returns a R as
Then, currying is the process of taking f and turning it into an equivalent function (call it g) of type
This gives us the following equivalence, where x1, ..., xn are objects of type X1, ..., Xn respectively:
Currying can be useful in several situations, especially when working with higher-order functions.
+This curry utility is an implementation of currying in C++. Specifically, curry<n>(f) is a function such that
Note that the n has to be specified explicitly because the existence of functions with variadic arguments in C++ make it impossible to know when currying should stop.
Unlike usual currying, this implementation also allows a curried function to be called with several arguments at a time. Hence, the following always holds
Of course, this requires k to be less than or equal to n; failure to satisfy this will trigger a static assertion. This syntax is supported because it makes curried functions usable where normal functions are expected.
Another "extension" is that curry<0>(f) is supported: curry<0>(f) is a nullary function; whereas the classical definition for currying seems to leave this case undefined, as nullary functions don't make much sense in purely functional languages.
| constexpr auto boost::hana::demux | +
#include <boost/hana/functional/demux.hpp>
Invoke a function with the results of invoking other functions on its arguments.
+Specifically, demux(f)(g...) is a function such that
Each g is called with all the arguments, and then f is called with the result of each g. Hence, the arity of f must match the number of gs.
This is called demux because of a vague similarity between this device and a demultiplexer in signal processing. demux takes what can be seen as a continuation (f), a bunch of functions to split a signal (g...) and zero or more arguments representing the signal (x...). Then, it calls the continuation with the result of splitting the signal with whatever functions where given.
demux is associative. In other words (and noting demux(f, g) = demux(f)(g) to ease the notation), it is true that demux(demux(f, g), h) == demux(f, demux(g, h)).The signature of demux is
+\[ \mathtt{demux} : (B_1 \times \dotsb \times B_n \to C) \to ((A_1 \times \dotsb \times A_n \to B_1) \times \dotsb \times (A_1 \times \dotsb \times A_n \to B_n)) \to (A_1 \times \dotsb \times A_n \to C) \] +
+This can be rewritten more tersely as
+\[ \mathtt{demux} : \left(\prod_{i=1}^n B_i \to C \right) \to \prod_{j=1}^n \left(\prod_{i=1}^n A_i \to B_j \right) \to \left(\prod_{i=1}^n A_i \to C \right) \] +
+The signature of compose is
+\[ \mathtt{compose} : (B \to C) \times (A \to B) \to (A \to C) \] +
+A valid observation is that this coincides exactly with the type of demux when used with a single unary function. Actually, both functions are equivalent:
However, let's now consider the curried version of compose, curry<2>(compose):
+\[ \mathtt{curry_2(compose)} : (B \to C) \to ((A \to B) \to (A \to C)) \] +
+For the rest of this explanation, we'll just consider the curried version of compose and so we'll use compose instead of curry<2>(compose) to lighten the notation. With currying, we can now consider compose applied to itself:
+\[ \mathtt{compose(compose, compose)} : (B \to C) \to (A_1 \to A_2 \to B) \to (A_1 \to A_2 \to C) \] +
+If we uncurry deeply the above expression, we obtain
+\[ \mathtt{compose(compose, compose)} : (B \to C) \times (A_1 \times A_2 \to B) \to (A_1 \times A_2 \to C) \] +
+This signature is exactly the same as that of demux when given a single binary function, and indeed they are equivalent definitions. We can also generalize this further by considering compose(compose(compose, compose), compose):
+\[ \mathtt{compose(compose(compose, compose), compose)} : (B \to C) \to (A_1 \to A_2 \to A_3 \to B) \to (A_1 \to A_2 \to A_3 \to C) \] +
+which uncurries to
+\[ \mathtt{compose(compose(compose, compose), compose)} : (B \to C) \times (A_1 \times A_2 \times A_3 \to B) \to (A_1 \times A_2 \times A_3 \to C) \] +
+This signature is exactly the same as that of demux when given a single ternary function. Hence, for a single n-ary function g, demux(f)(g) is equivalent to the n-times composition of compose with itself, applied to g and f:
More information on this insight can be seen here. Also, I'm not sure how this insight could be generalized to more than one function g, or if that is even possible.
As explained above, demux is associative when it is used with two functions only. Indeed, given functions f, g and h with suitable signatures, we have
On the other hand, we have
and hence demux is associative in the binary case.
| constexpr auto boost::hana::fix | +
#include <boost/hana/functional/fix.hpp>
Return a function computing the fixed point of a function.
+fix is an implementation of the Y-combinator, also called the fixed-point combinator. It encodes the idea of recursion, and in fact any recursive function can be written in terms of it.
Specifically, fix(f) is a function such that
This definition allows f to use its first argument as a continuation to call itself recursively. Indeed, if f calls its first argument with y..., it is equivalent to calling f(fix(f), y...) per the above equation.
Most of the time, it is more convenient and efficient to define recursive functions without using a fixed-point combinator. However, there are some cases where fix provides either more flexibility (e.g. the ability to change the callback inside f) or makes it possible to write functions that couldn't be defined recursively otherwise.
| f | A function called as f(self, x...), where x... are the arguments in the fix(f)(x...) expression and self is fix(f). |
| constexpr auto boost::hana::flip | +
#include <boost/hana/functional/flip.hpp>
Invoke a function with its two first arguments reversed.
+Specifically, flip(f) is a function such that
| constexpr auto boost::hana::id | +
#include <boost/hana/functional/id.hpp>
The identity function – returns its argument unchanged.
+| constexpr auto boost::hana::infix | +
#include <boost/hana/functional/infix.hpp>
Return an equivalent function that can also be applied in infix notation.
+Specifically, infix(f) is an object such that:
Hence, the returned function can still be applied using the usual function call syntax, but it also gains the ability to be applied in infix notation. The infix syntax allows a great deal of expressiveness, especially when used in combination with some higher order algorithms. Since operator^ is left-associative, x ^infix(f)^ y is actually parsed as (x ^infix(f))^ y. However, for flexibility, the order in which both arguments are applied in infix notation does not matter. Hence, it is always the case that
However, note that applying more than one argument in infix notation to the same side of the operator will result in a compile-time assertion:
Additionally, a function created with infix may be partially applied in infix notation. Specifically,
^ operator was chosen because it is left-associative and has a low enough priority so that most expressions will render the expected behavior.| f | The function which gains the ability to be applied in infix notation. The function must be at least binary; a compile-time error will be triggered otherwise. |
| constexpr auto boost::hana::iterate | +
#include <boost/hana/functional/iterate.hpp>
Applies another function n times to its argument.
Given a function f and an argument x, iterate<n>(f, x) returns the result of applying f n times to its argument. In other words,
If n == 0, iterate<n>(f, x) returns the x argument unchanged and f is never applied. It is important to note that the function passed to iterate<n> must be a unary function. Indeed, since f will be called with the result of the previous f application, it may only take a single argument.
In addition to what's documented above, iterate can also be partially applied to the function argument out-of-the-box. In other words, iterate<n>(f) is a function object applying f n times to the argument it is called with, which means that
This is provided for convenience, and it turns out to be especially useful in conjunction with higher-order algorithms.
+Given a function \( f : T \to T \) and x and argument of data type T, the signature is \( \mathtt{iterate_n} : (T \to T) \times T \to T \)
| n | An unsigned integer representing the number of times that f should be applied to its argument. |
| f | A function to apply n times to its argument. |
| x | The initial value to call f with. |
| constexpr auto boost::hana::lockstep | +
#include <boost/hana/functional/lockstep.hpp>
Invoke a function with the result of invoking other functions on its arguments, in lockstep.
+Specifically, lockstep(f)(g1, ..., gN) is a function such that
Since each g is invoked on its corresponding argument in lockstep, the number of arguments must match the number of gs.
| constexpr auto boost::hana::on | +
#include <boost/hana/functional/on.hpp>
Invoke a function with the result of invoking another function on each argument.
+Specifically, on(f, g) is a function such that
For convenience, on also supports infix application as provided by infix.
on is associative, i.e. on(f, on(g, h)) is equivalent to on(on(f, g), h).| constexpr auto boost::hana::overload | +
#include <boost/hana/functional/overload.hpp>
Pick one of several functions to call based on overload resolution.
+Specifically, overload(f1, f2, ..., fn) is a function object such that
where fk is the function of f1, ..., fn that would be called if overload resolution was performed amongst that set of functions only. If more than one function fk would be picked by overload resolution, then the call is ambiguous.
| constexpr auto boost::hana::overload_linearly | +
#include <boost/hana/functional/overload_linearly.hpp>
Call the first function that produces a valid call expression.
+Given functions f1, ..., fn, overload_linearly(f1, ..., fn) is a new function that calls the first fk producing a valid call expression with the given arguments. Specifically,
where fk is the first function such that fk(args...) is a valid expression.
| constexpr auto boost::hana::partial | +
#include <boost/hana/functional/partial.hpp>
Partially apply a function to some arguments.
+Given a function f and some arguments, partial returns a new function corresponding to the partially applied function f. This allows providing some arguments to a function and letting the rest of the arguments be provided later. Specifically, partial(f, x...) is a function such that
f must match the total number of arguments passed to it, i.e. sizeof...(x) + sizeof...(y).| constexpr unspecified boost::hana::_ {} | +
#include <boost/hana/functional/placeholder.hpp>
Create simple functions representing C++ operators inline.
+Specifically, _ is an object used as a placeholder to build function objects representing calls to C++ operators. It works by overloading the operators between _ and any object so that they return a function object which actually calls the corresponding operator on its argument(s). Hence, for any supported operator @:
Operators may also be partially applied to one argument inline:
When invoked with more arguments than required, functions created with _ will discard the superfluous instead of triggering an error:
This makes functions created with _ easier to use in higher-order algorithms, which sometime provide more information than necessary to their callbacks.
+, binary -, /, *, %, unary +, unary -~, &, |, ^, <<, >>==, !=, <, <=, >, >=||, &&, !* (dereference), [] (array subscript)() (function call)More complex functionality like the ability to compose placeholders into larger function objects inline are not supported. This is on purpose; you should either use C++14 generic lambdas or a library like Boost.Phoenix if you need bigger guns. The goal here is to save you a couple of characters in simple situations.
+| constexpr auto boost::hana::reverse_partial | +
#include <boost/hana/functional/reverse_partial.hpp>
Partially apply a function to some arguments.
+Given a function f and some arguments, reverse_partial returns a new function corresponding to f whose last arguments are partially applied. Specifically, reverse_partial(f, x...) is a function such that
f must match the total number of arguments passed to it, i.e. sizeof...(x) + sizeof...(y).Includes all the library components except the adapters for external libraries. +More...
++Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
| boost::hana::literals | |
| Namespace containing C++14 user-defined literals provided by Hana. | |
Includes all the library components except the adapters for external libraries.
+Defines boost::hana::detail::has_[nontrivial_]common_embedding.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Typedefs | |
| template<template< typename... > class Concept, typename T , typename U > | |
| using | boost::hana::detail::has_common_embedding = typename has_common_embedding_impl< Concept, T, U >::type |
Returns whether T and U both have an embedding into a common type. More... | |
| template<template< typename... > class Concept, typename T , typename U > | |
| using | boost::hana::detail::has_nontrivial_common_embedding = typename has_nontrivial_common_embedding_impl< Concept, T, U >::type |
Returns whether T and U are distinct and both have an embedding into a common type. More... | |
Defines boost::hana::detail::has_[nontrivial_]common_embedding.
Defines boost::hana::detail::has_duplicates.
+More...
+Classes | |
| struct | boost::hana::detail::has_duplicates< T > |
Returns whether any of the Ts are duplicate w.r.t. hana::equal. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::has_duplicates.
Defines boost::hana::hash.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::hash.
Defines boost::hana::detail::hash_table.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::hash_table.
=-90&&a<=90)k=l(P(i.h/aa(ga*
+a))),b=k+P(a/360),b
Defines boost::hana::id.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::id |
| The identity function – returns its argument unchanged. More... | |
Defines boost::hana::id.
Defines boost::hana::if_.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::if_.
Hana is a header-only library for C++ metaprogramming suited for computations on both types and values. The functionality it provides is a superset of what is provided by the well established Boost.MPL and Boost.Fusion libraries. By leveraging C++11/14 implementation techniques and idioms, Hana boasts faster compilation times and runtime performance on par or better than previous metaprogramming libraries, while noticeably increasing the level of expressiveness in the process. Hana is easy to extend in a ad-hoc manner and it provides out-of-the-box inter-operation with Boost.Fusion, Boost.MPL and the standard library.
+ Hana is a header-only library without external dependencies (not even the rest of Boost). Hence, using Hana in your own project is very easy. Basically, just add the include/ directory to your compiler's header search path and you are done. However, if you want to cleanly install Hana on your system, you have a couple of options. First, you can install Boost 1.61.0 or later, since Hana is included in Boost starting with that release. If you do not want to install all of Boost, it is also possible to install Hana only. To do so, you can download the code from the official GitHub repository and install the library manually by issuing the following commands from the root of the project (requires CMake):
This will install Hana to the default install-directory for your platform (/usr/local for Unix, C:/Program Files for Windows). If you want to install Hana in a custom location, you can use
hana.pc file for use with pkg-config.If you use CMake in a project, you can use the provided FindHana.cmake module to setup Hana as an external CMake project. The module also allows installing Hana locally to that project, without needing to install Hana on the system per the above instructions. Finally, if you want to contribute to Hana, you can see how to best setup your environment for development in the README.
+The library relies on a C++14 compiler and standard library, but nothing else is required. Here is a table of the current C++14 compilers/toolchains with comments regarding support for Hana:
+| Compiler/Toolchain | Status |
|---|---|
| Clang >= 3.5.0 | Fully working; tested on each push to GitHub |
| Xcode >= 6.3 | Fully working; tested on each push to GitHub |
| GCC >= 6.0.0 | Fully working; tested on each push to GitHub |
More specifically, Hana requires a compiler/standard library supporting the following C++14 features (non-exhaustively):
constexpr<type_traits> headerMore information for specific platforms is available on the wiki.
+If you have a problem, please review the FAQ and the wiki. Searching the issues for your problem is also a good idea. If that doesn't help, feel free to chat with us in Gitter, or open a new issue. StackOverflow with the boost-hana tag is the preferred place to ask questions on usage. If you are encountering what you think is a bug, please open an issue.
+When Boost.MPL first appeared, it provided C++ programmers with a huge relief by abstracting tons of template hackery behind a workable interface. This breakthrough greatly contributed to making C++ template metaprogramming more mainstream, and today the discipline is deeply rooted in many serious projects. Recently, C++11 and C++14 brought many major changes to the language, some of which make metaprogramming much easier, while others drastically widen the design space for libraries. A natural question then arises: is it still desirable to have abstractions for metaprogramming, and if so, which ones? After investigating different options like the MPL11, the answer eventually came by itself in the form of a library; Hana. The key insight to Hana is that the manipulation of types and values are nothing but two sides of the same coin. By unifying both concepts, metaprogramming becomes easier and new exciting possibilities open before us.
+But to really understand what is Hana all about, it is essential to understand the different types of computations in C++. We will focus our attention on four different kinds of computations, even though a finer grained separation would be possible. First, we have runtime computations, which are the usual computations we use in C++. In that world, we have runtime containers, runtime functions and runtime algorithms:
+ The usual toolbox for programming within this quadrant is the C++ standard library, which provides reusable algorithms and containers operating at runtime. Since C++11, a second kind of computation is possible: constexpr computations. There, we have constexpr containers, constexpr functions and constexpr algorithms:
std::array's operator== would have to be marked constexpr, which is not the case (even in C++14).Basically, a constexpr computation is different from a runtime computation in that it is simple enough to be evaluated (interpreted, really) by the compiler. In general, any function that does not perform anything too unfriendly to the compiler's evaluator (like throwing or allocating memory) can be marked constexpr without any further change. This makes constexpr computations very similar to runtime computations, except constexpr computations are more restricted and they gain the ability to be evaluated at compile-time. Unfortunately, there is no commonly used toolbox for constexpr-programming, i.e. there is no widely adopted "standard library" for constexpr programming. However, the Sprout library may be worth checking out for those with some interest in constexpr computations.
The third kind of computations are heterogeneous computations. Heterogeneous computations differ from normal computations in that instead of having containers holding homogeneous objects (all objects having the same type), the containers may hold objects with different types. Furthermore, functions in this quadrant of computation are heterogeneous functions, which is a complicated way of talking about template functions. Similarly, we have heterogeneous algorithms that manipulate heterogeneous containers and functions:
+ If manipulating heterogeneous containers seems overly weird to you, just think of it as glorified std::tuple manipulation. In a C++03 world, the go-to library for doing this kind of computation is Boost.Fusion, which provides several data structures and algorithms to manipulate heterogeneous collections of data. The fourth and last quadrant of computation that we'll be considering here is the quadrant of type-level computations. In this quadrant, we have type-level containers, type-level functions (usually called metafunctions) and type-level algorithms. Here, everything operates on types: containers hold types and metafunctions take types as arguments and return types as results.
The realm of type-level computations has been explored quite extensively, and the de-facto solution for type-level computations in C++03 is a library named Boost.MPL, which provides type-level containers and algorithms. For low-level type transformations, the metafunctions provided by the <type_traits> standard header can also be used since C++11.
So all is good, but what is this library actually about? Now that we have set the table by clarifying the kinds of computations available to us in C++, the answer might strike you as very simple. The purpose of Hana is to merge the 3rd and the 4th quadrants of computation. More specifically, Hana is a (long-winded) constructive proof that heterogeneous computations are strictly more powerful than type-level computations, and that we can therefore express any type-level computation by an equivalent heterogeneous computation. This construction is done in two steps. First, Hana is a fully featured library of heterogeneous algorithms and containers, a bit like a modernized Boost.Fusion. Secondly, Hana provides a way of translating any type-level computation into its equivalent heterogeneous computation and back, which allows the full machinery of heterogeneous computations to be reused for type-level computations without any code duplication. Of course, the biggest advantage of this unification is seen by the user, as you will witness by yourself.
+The goal of this section is to introduce the main concepts of the library from a very high level and at a fairly rapid pace; don't worry if you don't understand everything that's about to be thrown at you. However, this tutorial assumes the reader is already at least familiar with basic metaprogramming and the C++14 standard. First, let's include the library:
+Unless specified otherwise, the documentation assumes the above lines to be present before examples and code snippets. Also note that finer grained headers are provided and will be explained in the Header organization section. For the purpose of the quickstart, let's now include some additional headers and define some lovely animal types that we'll need below:
+ If you are reading this documentation, chances are you already know std::tuple and std::make_tuple. Hana provides its own tuple and make_tuple:
This creates a tuple, which is like an array, except that it can hold elements with different types. Containers that can hold elements with different types such as this are called heterogeneous containers. While the standard library provides very few operations to manipulate std::tuples, Hana provides several operations and algorithms to manipulate its own tuples:
1_c is a C++14 user-defined literal creating a compile-time number. These user-defined literals are contained in the boost::hana::literals namespace, hence the using directive.Notice how we pass a C++14 generic lambda to transform; this is required because the lambda will first be called with a Fish, then a Cat, and finally a Dog, which all have different types. Hana provides most of the algorithms provided by the C++ standard library, except they work on tuples and related heterogeneous containers instead of std::vector & friends. In addition to working with heterogeneous values, Hana makes it possible to perform type-level computations with a natural syntax, all at compile-time and with no overhead whatsoever. This compiles and does just what you would expect:
type_c<...> is not a type! It is a C++14 variable template yielding an object representing a type for Hana. This is explained in the section on type computations.In addition to heterogeneous and compile-time sequences, Hana provides several features to make your metaprogramming nightmares a thing of the past. For example, one can check for the existence of a struct member with one easy line instead of relying on clunky SFINAE hacks:
+Writing a serialization library? Stop crying, we've got you covered. Reflection can be added to user-defined types very easily. This allows iterating over the members of a user-defined type, querying members with a programmatic interface and much more, without any runtime overhead:
+That's cool, but I can already hear you complaining about incomprehensible error messages. However, it turns out Hana was built for humans, not professional template metaprogrammers, and this shows. Let's intentionally screw up and see what kind of mess is thrown at us. First, the mistake:
+Now, the punishment:
+Not that bad, right? However, since small examples are very good to show off without actually doing something useful, let's examine a real world example.
+In this section our goal will be to implement a kind of switch statement able to process boost::anys. Given a boost::any, the goal is to dispatch to the function associated to the dynamic type of the any:
s suffix on string literals to create std::strings without syntactic overhead. This is a standard-defined C++14 user-defined literal.Since the any holds a char, the second function is called with the char inside it. If the any had held an int instead, the first function would have been called with the int inside it. When the dynamic type of the any does not match any of the covered cases, the default_ function is called instead. Finally, the result of the switch is the result of calling the function associated to the any's dynamic type. The type of that result is inferred to be the common type of the result of all the provided functions:
We'll now look at how this utility can be implemented using Hana. The first step is to associate each type to a function. To do so, we represent each case_ as a hana::pair whose first element is a type and whose second element is a function. Furthermore, we (arbitrarily) decide to represent the default_ case as a hana::pair mapping a dummy type to a function:
To provide the interface we showed above, switch_ will have to return a function taking the cases. In other words, switch_(a) must be a function taking any number of cases (which are hana::pairs), and performing the logic to dispatch a to the right function. This can easily be achieved by having switch_ return a C++14 generic lambda:
However, since parameter packs are not very flexible, we'll put the cases into a tuple so we can manipulate them:
+Notice how the auto keyword is used when defining cases; it is often easier to let the compiler deduce the type of the tuple and use make_tuple instead of working out the types manually. The next step is to separate the default case from the rest of the cases. This is where things start to get interesting. To do so, we use Hana's find_if algorithm, which works a bit like std::find_if:
find_if takes a tuple and a predicate, and returns the first element of the tuple which satisfies the predicate. The result is returned as a hana::optional, which is very similar to a std::optional, except whether that optional value is empty or not is known at compile-time. If the predicate is not satisfied for any element of the tuple, find_if returns nothing (an empty value). Otherwise, it returns just(x) (a non-empty value), where x is the first element satisfying the predicate. Unlike predicates used in STL algorithms, the predicate used here must be generic because the tuple's elements are heterogeneous. Furthermore, that predicate must return what Hana calls an IntegralConstant, which means that the predicate's result must be known at compile-time. These details are explained in the section on cross-phase algorithms. Inside the predicate, we simply compare the type of the case's first element to type_c<default_t>. If you recall that we were using hana::pairs to encode cases, this simply means that we're finding the default case among all of the provided cases. But what if no default case was provided? We should fail at compile-time, of course!
Notice how we can use static_assert on the result of the comparison with nothing, even though default_ is a non-constexpr object? Boldly, Hana makes sure that no information that's known at compile-time is lost to the runtime, which is clearly the case of the presence of a default_ case. The next step is to gather the set of non-default cases. To achieve this, we use the filter algorithm, which keeps only the elements of the sequence satisfying the predicate:
The next step is to find the first case matching the dynamic type of the any, and then call the function associated to that case. The simplest way to do this is to use classic recursion with variadic parameter packs. Of course, we could probably intertwine Hana algorithms in a convoluted way to achieve this, but sometimes the best way to do something is to write it from scratch using basic techniques. To do so, we'll call an implementation function with the contents of the rest tuple by using the unpack function:
unpack takes a tuple and a function, and calls the function with the content of the tuple as arguments. The result of unpack is the result of calling that function. In our case, the function is a generic lambda which in turn calls the process function. Our reason for using unpack here was to turn the rest tuple into a parameter pack of arguments, which are easier to process recursively than tuples. Before we move on to the process function, it is worthwhile to explain what second(*default_) is all about. As we explained earlier, default_ is an optional value. Like std::optional, this optional value overloads the dereference operator (and the arrow operator) to allow accessing the value inside the optional. If the optional is empty (nothing), a compile-time error is triggered. Since we know default_ is not empty (we checked that just above), what we're doing is simply pass the function associated to the default case to the process function. We're now ready for the final step, which is the implementation of the process function:
There are two overloads of this function: an overload for when there is at least one case to process, and the base case overload for when there's only the default case. As we would expect, the base case simply calls the default function and returns that result. The other overload is slightly more interesting. First, we retrieve the type associated to that case and store it in T. This decltype(...)::type dance might seem convoluted, but it is actually quite simple. Roughly speaking, this takes a type represented as an object (a type<T>) and pulls it back down to the type level (a T). The details are explained in the section on type-level computations. Then, we compare whether the dynamic type of the any matches this case, and if so we call the function associated to this case with the any casted to the proper type. Otherwise, we simply call process recursively with the rest of the cases. Pretty simple, wasn't it? Here's the final solution:
That's it for the quick start! This example only introduced a couple of useful algorithms (find_if, filter, unpack) and heterogeneous containers (tuple, optional), but rest assured that there is much more. The next sections of the tutorial gradually introduce general concepts pertaining to Hana in a friendly way, but you may use the following cheatsheet for quick reference if you want to start coding right away. This cheatsheet contains the most frequently used algorithms and containers, along with a short description of what each of them does.
constexpr function objects| container | description |
|---|---|
tuple | General purpose index-based heterogeneous sequence with a fixed length. Use this as a std::vector for heterogeneous objects. |
optional | Represents an optional value, i.e. a value that can be empty. This is a bit like std::optional, except that the emptiness is known at compile-time. |
map | Unordered associative array mapping (unique) compile-time entities to arbitrary objects. This is like std::unordered_map for heterogeneous objects. |
set | Unordered container holding unique keys that must be compile-time entities. This is like std::unordered_set for heterogeneous objects. |
range | Represents an interval of compile-time numbers. This is like std::integer_sequence, but better. |
pair | Container holding two heterogeneous objects. Like std::pair, but compresses the storage of empty types. |
string | Compile-time string. |
type | Container representing a C++ type. This is the root of the unification between types and values, and is of interest for MPL-style computations (type-level computations). |
integral_constant | Represents a compile-time number. This is very similar to std::integral_constant, except that hana::integral_constant also defines operators and more syntactic sugar. |
lazy | Encapsulates a lazy value or computation. |
basic_tuple | Stripped-down version of hana::tuple. Not standards conforming, but more compile-time efficient. |
| function | description |
|---|---|
adjust(sequence, value, f) | Apply a function to each element of a sequence that compares equal to some value and return the result. |
adjust_if(sequence, predicate, f) | Apply a function to each element of a sequence satisfying some predicate and return the result. |
{all,any,none}(sequence) | Returns whether all/any/none of the elements of a sequence are true-valued. |
{all,any,none}_of(sequence, predicate) | Returns whether all/any/none of the elements of the sequence satisfy some predicate. |
append(sequence, value) | Append an element to a sequence. |
at(sequence, index) | Returns the n-th element of a sequence. The index must be an IntegralConstant. |
back(sequence) | Returns the last element of a non-empty sequence. |
concat(sequence1, sequence2) | Concatenate two sequences. |
contains(sequence, value) | Returns whether a sequence contains the given object. |
count(sequence, value) | Returns the number of elements that compare equal to the given value. |
count_if(sequence, predicate) | Returns the number of elements that satisfy the predicate. |
drop_front(sequence[, n]) | Drop the first n elements from a sequence, or the whole sequence if length(sequence) <= n. n must be an IntegralConstant. When not provided, n defaults to 1. |
drop_front_exactly(sequence[, n]) | Drop the first n elements from a sequence. n must be an IntegralConstant and the sequence must have at least n elements. When not provided, n defaults to 1. |
drop_back(sequence[, n]) | Drop the last n elements from a sequence, or the whole sequence if length(sequence) <= n. n must be an IntegralConstant. When not provided, n defaults to 1. |
drop_while(sequence, predicate) | Drops elements from a sequence while a predicate is satisfied. The predicate must return an IntegralConstant. |
fill(sequence, value) | Replace all the elements of a sequence with some value. |
filter(sequence, predicate) | Remove all the elements that do not satisfy a predicate. The predicate must return an IntegralConstant. |
find(sequence, value) | Find the first element of a sequence which compares equal to some value and return just it, or return nothing. See hana::optional. |
find_if(sequence, predicate) | Find the first element of a sequence satisfying the predicate and return just it, or return nothing. See hana::optional. |
flatten(sequence) | Flatten a sequence of sequences, a bit like std::tuple_cat. |
fold_left(sequence[, state], f) | Accumulates the elements of a sequence from the left, optionally with a provided initial state. |
fold_right(sequence[, state], f) | Accumulates the elements of a sequence from the right, optionally with a provided initial state. |
fold(sequence[, state], f) | Equivalent to fold_left; provided for consistency with Boost.MPL and Boost.Fusion. |
for_each(sequence, f) | Call a function on each element of a sequence. Returns void. |
front(sequence) | Returns the first element of a non-empty sequence. |
group(sequence[, predicate]) | Group adjacent elements of a sequence which all satisfy (or all do not satisfy) some predicate. The predicate defaults to equality, in which case the elements must be Comparable. |
insert(sequence, index, element) | Insert an element at a given index. The index must be an IntegralConstant. |
insert_range(sequence, index, elements) | Insert a sequence of elements at a given index. The index must be an IntegralConstant. |
is_empty(sequence) | Returns whether a sequence is empty as an IntegralConstant. |
length(sequence) | Returns the length of a sequence as an IntegralConstant. |
lexicographical_compare(sequence1, sequence2[, predicate]) | Performs a lexicographical comparison of two sequences, optionally with a custom predicate, by default with hana::less. |
maximum(sequence[, predicate]) | Returns the greatest element of a sequence, optionally according to a predicate. The elements must be Orderable if no predicate is provided. |
minimum(sequence[, predicate]) | Returns the smallest element of a sequence, optionally according to a predicate. The elements must be Orderable if no predicate is provided. |
partition(sequence, predicate) | Partition a sequence into a pair of elements that satisfy some predicate, and elements that do not satisfy it. |
prepend(sequence, value) | Prepend an element to a sequence. |
remove(sequence, value) | Remove all the elements that are equal to a given value. |
remove_at(sequence, index) | Remove the element at the given index. The index must be an IntegralConstant. |
remove_if(sequence, predicate) | Remove all the elements that satisfy a predicate. The predicate must return an IntegralConstant. |
remove_range(sequence, from, to) | Remove the elements at indices in the given [from, to) half-open interval. The indices must be IntegralConstants. |
replace(sequence, oldval, newval) | Replace the elements of a sequence that compare equal to some value by some other value. |
replace_if(sequence, predicate, newval) | Replace the elements of a sequence that satisfy some predicate by some value. |
reverse(sequence) | Reverse the order of the elements in a sequence. |
reverse_fold(sequence[, state], f) | Equivalent to fold_right; provided for consistency with Boost.MPL and Boost.Fusion. |
size(sequence) | Equivalent to length; provided for consistency with the C++ standard library. |
slice(sequence, indices) | Returns a new sequence containing the elements at the given indices of the original sequence. |
slice_c<from, to>(sequence) | Returns a new sequence containing the elements at indices contained in [from, to) of the original sequence. |
sort(sequence[, predicate]) | Sort (stably) the elements of a sequence, optionally according to a predicate. The elements must be Orderable if no predicate is provided. |
take_back(sequence, number) | Take the last n elements of a sequence, or the whole sequence if length(sequence) <= n. n must be an IntegralConstant. |
take_front(sequence, number) | Take the first n elements of a sequence, or the whole sequence if length(sequence) <= n. n must be an IntegralConstant. |
take_while(sequence, predicate) | Take elements of a sequence while some predicate is satisfied, and return that. |
transform(sequence, f) | Apply a function to each element of a sequence and return the result. |
unique(sequence[, predicate]) | Removes all consecutive duplicates from a sequence. The predicate defaults to equality, in which case the elements must be Comparable. |
unpack(sequence, f) | Calls a function with the contents of a sequence. Equivalent to f(x1, ..., xN). |
zip(s1, ..., sN) | Zip N sequences into a sequence of tuples. All the sequences must have the same length. |
zip_shortest(s1, ..., sN) | Zip N sequences into a sequence of tuples. The resulting sequence has the length of the shortest input sequence. |
zip_with(f, s1, ..., sN) | Zip N sequences with a N-ary function. All the sequences must have the same length. |
zip_shortest_with(f, s1, ..., sN) | Zip N sequences with a N-ary function. The resulting sequence has the length of the shortest input sequence. |
In the rest of this tutorial, you will come across code snippets where different kinds of assertions like BOOST_HANA_RUNTIME_CHECK and BOOST_HANA_CONSTANT_CHECK are used. Like any sensible assert macro, they basically check that the condition they are given is satisfied. However, in the context of heterogeneous programming, some informations are known at compile-time, while others are known only at runtime. The exact type of assertion that's used in a context tells you whether the condition that's asserted upon can be known at compile-time or if it must be computed at runtime, which is a very precious piece of information. Here are the different kinds of assertions used in the tutorial, with a small description of their particularities. For more details, you should check the reference on assertions.
| assertion | description |
|---|---|
BOOST_HANA_RUNTIME_CHECK | Assertion on a condition that is not known until runtime. This assertion provides the weakest form of guarantee. |
BOOST_HANA_CONSTEXPR_CHECK | Assertion on a condition that would be constexpr if lambdas were allowed inside constant expressions. In other words, the only reason for it not being a static_assert is the language limitation that lambdas can't appear in constant expressions, which might be lifted in C++17. |
static_assert | Assertion on a constexpr condition. This is stronger than BOOST_HANA_CONSTEXPR_CHECK in that it requires the condition to be a constant expression, and it hence assures that the algorithms used in the expression are constexpr-friendly. |
BOOST_HANA_CONSTANT_CHECK | Assertion on a boolean IntegralConstant. This assertion provides the strongest form of guarantee, because an IntegralConstant can be converted to a constexpr value even if it is not constexpr itself. |
This section introduces the important notion of IntegralConstant and the philosophy behind Hana's metaprogramming paradigm. Let's start with a rather odd question. What is an integral_constant?
std::integral_constant.One valid answer is that integral_constant represents a type-level encoding of a number, or more generally any object of an integral type. For illustration, we could define a successor function on numbers in that representation very easily by using a template alias:
This is the way integral_constants are usually thought of; as type-level entities that can be used for template metaprogramming. Another way to see an integral_constant is as a runtime object representing a constexpr value of an integral type:
Here, while one is not marked as constexpr, the abstract value it holds (a constexpr 1) is still available at compile-time, because that value is encoded in the type of one. Indeed, even if one is not constexpr, we can use decltype to retrieve the compile-time value it represents:
But why on earth would we want to consider integral_constants as objects instead of type-level entities? To see why, consider how we could now implement the same successor function as before:
Did you notice anything new? The difference is that instead of implementing succ at the type-level with a template alias, we're now implementing it at the value-level with a template function. Furthermore, we can now perform compile-time arithmetic using the same syntax as that of normal C++. This way of seeing compile-time entities as objects instead of types is the key to Hana's expressive power.
The MPL defines arithmetic operators that can be used to do compile-time computations with integral_constants. A typical example of such an operation is plus, which is implemented roughly as:
By viewing integral_constants as objects instead of types, the translation from a metafunction to a function is very straightforward:
It is very important to emphasize the fact that this operator does not return a normal integer. Instead, it returns a value-initialized object whose type contains the result of the addition. The only useful information contained in that object is actually in its type, and we're creating an object because it allows us to use this nice value-level syntax. It turns out that we can make this syntax even better by using a C++14 variable template to simplify the creation of an integral_constant:
Now we're talking about a visible gain in expressiveness over the initial type-level approach, aren't we? But there's more; we can also use C++14 user defined literals to make this process even simpler:
+Hana provides its own integral_constants, which define arithmetic operators just like we showed above. Hana also provides variable templates to easily create different kinds of integral_constants: int_c, long_c, bool_c, etc... This allows you to omit the trailing {} braces otherwise required to value-initialize these objects. Of course, the _c suffix is also provided; it is part of the hana::literals namespace, and you must import it into your namespace before using it:
This way, you may do compile-time arithmetic without having to struggle with awkward type-level idiosyncrasies, and your coworkers will now be able to understand what's going on.
+To illustrate how good it gets, let's implement a function computing a 2-D euclidean distance at compile-time. As a reminder, the euclidean distance of two points in the 2-D plane is given by
++\[ \mathrm{distance}\left((x_1, y_1), (x_2, y_2)\right) := \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2} \] +
+First, here's how it looks like with a type-level approach (using the MPL):
+Yeah... Now, let's implement it with the value-level approach presented above:
+ This version looks arguably cleaner. However, this is not all. Notice how the distance function looks exactly as the one you would have written for computing the euclidean distance on dynamic values? Indeed, because we're using the same syntax for dynamic and compile-time arithmetic, generic functions written for one will work for both!
Without changing any code, we can use our distance function on runtime values and everything just works. Now that's DRY.
Once we have compile-time arithmetic, the next thing that might come to mind is compile-time branching. When metaprogramming, it is often useful to have one piece of code be compiled if some condition is true, and a different one otherwise. If you have heard of static_if, this should sound very familiar, and indeed it is exactly what we are talking about. Otherwise, if you don't know why we might want to branch at compile-time, consider the following code (adapted from N4461):
+This code creates a std::unique_ptr using the correct form of syntax for the constructor. To achieve this, it uses SFINAE and requires two different overloads. Now, anyone sane seeing this for the first time would ask why it is not possible to simply write:
The reason is that the compiler is required to compile both branches of the if statement, regardless of the condition (even though it is known at compile-time). But when T is not constructible from Args..., the second branch will fail to compile, which will cause a hard compilation error. What we need really is a way to tell the compiler not to compile the second branch when the condition is true, and the first branch when the condition is false.
To emulate this, Hana provides an if_ function that works a bit like a normal if statement, except except it takes a condition that can be an IntegralConstant and returns the one of two values (which may have different types) chosen by the condition. If the condition is true, the first value is returned, and otherwise the second value is returned. A somewhat vain example is the following:
hana::true_c and hana::false_c are just boolean IntegralConstants representing a compile-time true value and a compile-time false value, respectively.Here, one_two_three is equal to 123, and hello is equal to "hello". In other words, if_ is a little bit like the ternary conditional operator ? :, except that both sides of the : can have different types:
Ok, so this is neat, but how can it actually help us write complete branches that are lazily instantiated by the compiler? The answer is to represent both branches of the if statement we'd like to write as generic lambdas, and to use hana::if_ to return the branch that we'd like to execute. Here's how we could rewrite make_unique:
Here, the first value given to hana::if_ is a generic lambda representing the branch we want to execute if the condition is true, and the second value is the branch we want to execute otherwise. hana::if_ simply returns the branch chosen by the condition, and we call that branch (which is a generic lambda) immediately with std::forward<Args>(args).... Hence, the proper generic lambda ends up being called, with x... being args..., and we return the result of that call.
The reason why this approach works is because the body of each branch can only be instantiated when the types of all x... are known. Indeed, since the branch is a generic lambda, the type of the argument is not known until the lambda is called, and the compiler must wait for the types of x... to be known before type-checking the lambda's body. Since the erroneous lambda is never called when the condition is not satisfied (hana::if_ takes care of that), the body of the lambda that would fail is never type-checked and no compilation error happens.
if_ are lambdas. As such, they really are different functions from the make_unique function. The variables appearing inside those branches have to be either captured by the lambdas or passed to them as arguments, and so they are affected by the way they are captured or passed (by value, by reference, etc..).Since this pattern of expressing branches as lambdas and then calling them is very common, Hana provides a eval_if function whose purpose is to make compile-time branching easier. eval_if comes from the fact that in a lambda, one can either receive input data as arguments or capture it from the context. However, for the purpose of emulating a language level if statement, implicitly capturing variables from the enclosing scope is usually more natural. Hence, what we would prefer writing is
Here, we're capturing the args... variables from the enclosing scope, which prevents us from having to introduce the new x... variables and passing them as arguments to the branches. However, this has two problems. First, this will not achieve the right result, since hana::if_ will end up returning a lambda instead of returning the result of calling that lambda. To fix this, we can use hana::eval_if instead of hana::if_:
Here, we capture the enclosing args... by reference using [&], and we do not need to receive any arguments. Also, hana::eval_if assumes that its arguments are branches that can be called, and it will take care of calling the branch that is selected by the condition. However, this will still cause a compilation failure, because the bodies of the lambdas are not dependent anymore, and semantic analysis will be done for both branches even though only one would end up being used. The solution to this problem is to make the bodies of the lambdas artificially dependent on something, to prevent the compiler from being able to perform semantic analysis before the lambda is actually used. To make this possible, hana::eval_if will call the selected branch with an identity function (a function that returns its argument unchanged), if the branch accepts such an argument:
Here, the bodies of the branches take an additional argument called _ by convention. This argument will be provided by hana::eval_if to the branch that was selected. Then, we use _ as a function on the variables that we want to make dependent within the body of each branch. What happens is that _ will always be a function that returns its argument unchanged. However, the compiler can't possibly know it before the lambda has actually been called, so it can't know the type of _(args). This prevents the compiler from being able to perform semantic analysis, and no compilation error happens. Plus, since _(x) is guaranteed to be equivalent to x, we know that we're not actually changing the semantics of the branches by using this trick.
While using this trick may seem cumbersome, it can be very useful when dealing with many variables inside a branch. Furthermore, it is not required to wrap all variables with _; only variables that are involved in an expression whose type-checking has to be delayed must be wrapped, but the other ones are not required. There are still a few things to know about compile-time branching in Hana, but you can dig deeper by looking at the reference for hana::eval_if, hana::if_ and hana::lazy.
Why should we limit ourselves to arithmetic operations and branching? When you start considering IntegralConstants as objects, it becomes sensible to augment their interface with more functions that are generally useful. For example, Hana's IntegralConstants define a times member function that can be used to invoke a function a certain number of times, which is especially useful for loop unrolling:
In the above code, the 10 calls to f are expanded at compile-time. In other words, this is equivalent to writing
Another nice use of IntegralConstants is to define good-looking operators for indexing heterogeneous sequences. Whereas std::tuple must be accessed with std::get, hana::tuple can be accessed using the familiar operator[] used for standard library containers:
How this works is very simple. Basically, hana::tuple defines an operator[] taking an IntegralConstant instead of a normal integer, in a way similar to
This is the end of the section on IntegralConstants. This section introduced the feel behind Hana's new way of metaprogramming; if you liked what you've seen so far, the rest of this tutorial should feel just like home.
At this point, if you are interested in doing type-level computations as with the MPL, you might be wondering how is Hana going to help you. Do not despair. Hana provides a way to perform type-level computations with a great deal of expressiveness by representing types as values, just like we represented compile-time numbers as values. This is a completely new way of approaching metaprogramming, and you should try to set your old MPL habits aside for a bit if you want to become proficient with Hana.
+However, please be aware that modern C++ features like auto-deduced return type remove the need for type computations in many cases. Hence, before even considering to do a type computation, you should ask yourself whether there's a simpler way to achieve what you're trying to achieve. In most cases, the answer will be yes. However, when the answer is no, Hana will provide you with nuclear-strength facilities to do what needs to be done.
+The key behind Hana's approach to type-level computations is essentially the same as the approach to compile-time arithmetic. Basically, the idea is to represent compile-time entities as objects by wrapping them into some kind of container. For IntegralConstants, the compile-time entities were constant expressions of an integral type and the wrapper we used was integral_constant. In this section, the compile-time entities will be types and the wrapper we'll be using is called type. Just like we did for IntegralConstants, let's start by defining a dummy template that could be used to represent a type:
basic_type here because we're only building a naive version of the actual functionality provided by Hana.While this may seem completely useless, it is actually enough to start writing metafunctions that look like functions. Indeed, consider the following alternate implementations of std::add_pointer and std::is_pointer:
We've just written metafunctions that look like functions, just like we wrote compile-time arithmetic metafunctions as heterogeneous C++ operators in the previous section. Here's how we can use them:
+Notice how we can now use a normal function call syntax to perform type-level computations? This is analogous to how using values for compile-time numbers allowed us to use normal C++ operators to perform compile-time computations. Like we did for integral_constant, we can also go one step further and use C++14 variable templates to provide syntactic sugar for creating types:
hana::type_c variable template is implemented because of some subtleties; things were dumbed down here for the sake of the explanation. Please check the reference for hana::type to know exactly what you can expect from a hana::type_c<...>.But what does that buy us? Well, since a type_c<...> is just an object, we can store it in a heterogeneous sequence like a tuple, we can move it around and pass it to (or return it from) functions, and we can do basically anything else that requires an object:
make_tuple(type_c<T>...) can be annoying when there are several types. For this reason, Hana provides the tuple_t<T...> variable template, which is syntactic sugar for make_tuple(type_c<T>...).Also, notice that since the above tuple is really just a normal heterogeneous sequence, we can apply heterogeneous algorithms on that sequence just like we could on a tuple of ints, for example. Furthermore, since we're just manipulating objects, we can now use the full language instead of just the small subset available at the type-level. For example, consider the task of removing all the types that are not a reference or a pointer from a sequence of types. With the MPL, we would have to use a placeholder expression to express the predicate, which is clunky:
Now, since we're manipulating objects, we can use the full language and use a generic lambda instead, which leads to much more readable code:
+Since Hana handles all heterogeneous containers uniformly, this approach of representing types as values also has the benefit that a single library is now needed for both heterogeneous computations and type level computations. Indeed, whereas we would normally need two different libraries to perform almost identical tasks, we now need a single library. Again, consider the task of filtering a sequence with a predicate. With MPL and Fusion, this is what we must do:
+ With Hana, a single library is required. Notice how we use the same filter algorithm and the same container, and only tweak the predicate so it can operate on values:
But that is not all. Indeed, having a unified syntax for type-level and value-level computations allows us to achieve greater consistency in the interface of heterogeneous containers. For example, consider the simple task of creating a heterogeneous map associating types to values, and then accessing an element of it. With Fusion, what's happening is far from obvious to the untrained eye:
+However, with a unified syntax for types and values, the same thing becomes much clearer:
+While Hana's way takes more lines of codes, it is also arguably more readable and closer to how someone would expect to initialize a map.
+So far, we can represent types as values and perform type-level computations on those objects using the usual C++ syntax. This is nice, but it is not very useful because we have no way to get back a normal C++ type from an object representation. For example, how could we declare a variable whose type is the result of a type computation?
+Right now, there is no easy way to do it. To make this easier to achieve, we enrich the interface of the basic_type container that we defined above. Instead of being an empty struct, we now define it as
basic_type a metafunction in the MPL sense.This way, we can use decltype to easily access the actual C++ type represented by a type_c<...> object:
In general, doing type-level metaprogramming with Hana is a three step process:
+hana::type_c<...>decltype(...)::typeNow, you must be thinking that this is incredibly cumbersome. In reality, it is very manageable for several reasons. First, this wrapping and unwrapping only needs to happen at some very thin boundaries.
+Furthermore, since you get the advantage of working with objects (without having to wrap/unwrap) inside the computation, the cost of wrapping and unwrapping is amortized on the whole computation. Hence, for complex type computations, the syntactic noise of this three step process quickly becomes negligible in light of the expressiveness gain of working with values inside that computation. Also, using values instead of types means that we can avoid typing typename and template all around the place, which accounted for a lot of syntactic noise in classic metaprogramming.
Another point is that the three full steps are not always required. Indeed, sometimes one just needs to do a type-level computation and query something about the result, without necessarily fetching the result as a normal C++ type:
+In this case, we were able to skip the third step because we did not need to access the actual type represented by result. In other cases, the first step can be avoided, like when using tuple_t, which has no more syntactic noise than any other pure type-level approach:
For skeptical readers, let's consider the task of finding the smallest type in a sequence of types. This is a very good example of a short type-only computation, which is where we would expect the new paradigm to suffer the most. As you will see, things stay manageable even for small computations. First, let's implement it with the MPL:
+The result is quite readable (for anyone familiar with the MPL). Let's now implement the same thing using Hana:
+As you can witness, the syntactic noise of the 3-step process is almost completely hidden by the rest of the computation.
+The first type-level computation that we introduced in the form of a function looked like:
+While it looks more complicated, we could also write it as:
+However, this implementation emphasizes the fact that we're really emulating an existing metafunction and simply representing it as a function. In other words, we're lifting a metafunction (std::add_pointer) to the world of values by creating our own add_pointer function. It turns out that this lifting process is a generic one. Indeed, given any metafunction, we could write almost the same thing:
This mechanical transformation is easy to abstract into a generic lifter that can handle any MPL Metafunction as follows:
+More generally, we'll want to allow metafunctions with any number of arguments, which brings us to the following less naive implementation:
+ Hana provides a similar generic metafunction lifter called hana::metafunction. One small improvement is that hana::metafunction<F> is a function object instead of an overloaded function, so one can pass it to higher-order algorithms. It is also a model of the slightly more powerful concept of Metafunction, but this can safely be ignored for now. The process we explored in this section does not only apply to metafunctions; it also applies to templates. Indeed, we could define:
Hana provides a generic lifter for templates named hana::template_, and it also provides a generic lifter for MPL MetafunctionClasses named hana::metafunction_class. This gives us a way to uniformly represent "legacy" type-level computations as functions, so that any code written using a classic type-level metaprogramming library can almost trivially be used with Hana. For example, say you have a large chunk of MPL-based code and you'd like to interface with Hana. The process of doing so is no harder than wrapping your metafunctions with the lifter provided by Hana:
However, note that not all type-level computations can be lifted as-is with the tools provided by Hana. For example, std::extent can't be lifted because it requires non-type template parameters. Since there is no way to deal with non-type template parameters uniformly in C++, one must resort to using a hand-written function object specific to that type-level computation:
std::integral_constants (<boost/hana/ext/std/integral_constant.hpp>) when using type traits from <type_traits> directly.In practice, however, this should not be a problem since the vast majority of type-level computations can be lifted easily. Finally, since metafunctions provided by the <type_traits> header are used so frequently, Hana provides a lifted version for every one of them. Those lifted traits are in the hana::traits namespace, and they live in the <boost/hana/traits.hpp> header:
This is the end of the section on type computations. While this new paradigm for type level programming might be difficult to grok at first, it will make more sense as you use it more and more. You will also come to appreciate how it blurs the line between types and values, opening new exciting possibilities and simplifying many tasks.
+ Static introspection, as we will discuss it here, is the ability of a program to examine the type of an object at compile-time. In other words, it is a programmatic interface to interact with types at compile-time. For example, have you ever wanted to check whether some unknown type has a member named foo? Or perhaps at some point you have needed to iterate on the members of a struct?
If you have written a bit of templates in your life, chances are very high that you came across the first problem of checking for a member. Also, anyone having tried to implement object serialization or even just pretty printing has come across the second problem. In most dynamic languages like Python, Ruby or JavaScript, these problems are completely solved and introspection is used every day by programmers to make a lot of tasks simpler. However, as a C++ programmer, we do not have language support for those things, which makes several tasks much harder than they should be. While language support would likely be needed to properly tackle this problem, Hana makes some common introspection patterns much more accessible.
+Given an object of an unknown type, it is sometimes desirable to check whether this object has a member (or member function) with some name. This can be used to perform sophisticated flavors of overloading. For example, consider the problem of calling a toString method on objects that support it, but providing another default implementation for objects that do not support it:
How could we implement a check for the validity of obj.toString() as above in a generic fashion (so it can be reused in other functions, for example)? Normally, we would be stuck writing some kind of SFINAE-based detection:
This works, but the intent is not very clear and most people without a deep knowledge of template metaprogramming would think this is black magic. Then, we could implement optionalToString as
if statement will be compiled. If obj does not have a toString method, the compilation of the if branch will fail. We will address this issue in a moment.Instead of the above SFINAE trick, Hana provides a is_valid function that can be combined with C++14 generic lambdas to obtain a much cleaner implementation of the same thing:
This leaves us with a function object has_toString which returns whether the given expression is valid on the argument we pass to it. The result is returned as an IntegralConstant, so constexpr-ness is not an issue here because the result of the function is represented as a type anyway. Now, in addition to being less verbose (that's a one liner!), the intent is much clearer. Other benefits are the fact that has_toString can be passed to higher order algorithms and it can also be defined at function scope, so there is no need to pollute the namespace scope with implementation details. Here is how we would now write optionalToString:
Much cleaner, right? However, as we said earlier, this implementation won't actually work because both branches of the if always have to be compiled, regardless of whether obj has a toString method. There are several possible options, but the most classical one is to use std::enable_if:
has_toString returns an IntegralConstant to write decltype(...)::value, which is a constant expression. For some reason, has_toString(obj) is not considered a constant expression, even though I think it should be one because we never read from obj (see the section on advanced constexpr).While this implementation is perfectly valid, it is still pretty cumbersome because it requires writing two different functions and going through the hoops of SFINAE explicitly by using std::enable_if. However, as you might remember from the section on compile-time branching, Hana provides an if_ function that can be used to emulate the functionality of static_if. Here is how we could write optionalToString with hana::if_:
Now, the previous example covered only the specific case of checking for the presence of a non-static member function. However, is_valid can be used to detect the validity of almost any kind of expression. For completeness, we now present a list of common use cases for validity checking along with how to use is_valid to implement them.
The first idiom we'll look at is checking for the presence of a non-static member. We can do it in a similar way as we did for the previous example:
+ Notice how we cast the result of x.member to void? This is to make sure that our detection also works for types that can't be returned from functions, like array types. Also, it is important to use a reference as the parameter to our generic lambda, because that would otherwise require x to be CopyConstructible, which is not what we're trying to check. This approach is simple and the most convenient when an object is available. However, when the checker is intended to be used with no object around, the following alternate implementation can be better suited:
This validity checker is different from what we saw earlier because the generic lambda is not expecting an usual object anymore; it is now expecting a type (which is an object, but still represents a type). We then use the hana::traits::declval lifted metafunction from the <boost/hana/traits.hpp> header to create an rvalue of the type represented by t, which we can then use to check for a non-static member. Finally, instead of passing an actual object to has_member (like Foo{} or Bar{}), we now pass a type_c<...>. This implementation is ideal for when no object is lying around.
Checking for a static member is easy, and it is provided for completeness:
+ Again, we expect a type to be passed to the checker. Inside the generic lambda, we use decltype(t)::type to fetch the actual C++ type represented by the t object, as explained in the section on type computations. Then, we fetch the static member inside that type and cast it to void, for the same reason as we did for non-static members.
Checking for a nested type name is not hard, but it is slightly more convoluted than the previous cases:
+ One might wonder why we use -> hana::type<typename-expression> instead of simply -> typename-expression. Again, the reason is that we want to support types that can't be returned from functions, like array types or incomplete types.
Checking for a nested template name is similar to checking for a nested type name, except we use the template_<...> variable template instead of type<...> in the generic lambda:
Doing something only if an expression is well-formed is a very common pattern in C++. Indeed, the optionalToString function is just one instance of the following pattern, which is very general:
To encapsulate this pattern, Hana provides the sfinae function, which allows executing an expression, but only if it is well-formed:
Here, we create a maybe_add function, which is simply a generic lambda wrapped with Hana's sfinae function. maybe_add is a function which takes two inputs and returns just the result of the generic lambda if that call is well-formed, and nothing otherwise. just(...) and nothing both belong to a type of container called hana::optional, which is essentially a compile-time std::optional. All in all, maybe_add is morally equivalent to the following function returning a std::optional, except that the check is done at compile-time:
It turns out that we can take advantage of sfinae and optional to implement the optionalToString function as follows:
First, we wrap toString with the sfinae function. Hence, maybe_toString is a function which either returns just(x.toString()) if that is well-formed, or nothing otherwise. Secondly, we use the .value_or() function to extract the optional value from the container. If the optional value is nothing, .value_or() returns the default value given to it; otherwise, it returns the value inside the just (here x.toString()). This way of seeing SFINAE as a special case of computations that might fail is very clean and powerful, especially since sfinae'd functions can be combined through the hana::optional Monad, which is left to the reference documentation.
Have you ever wanted to iterate over the members of a user-defined type? The goal of this section is to show you how Hana can be used to do it quite easily. To allow working with user-defined types, Hana defines the Struct concept. Once a user-defined type is a model of that concept, one can iterate over the members of an object of that type and query other useful information. To turn a user-defined type into a Struct, a couple of options are available. First, you may define the members of your user-defined type with the BOOST_HANA_DEFINE_STRUCT macro:
This macro defines two members (name and age) with the given types. Then, it defines some boilerplate inside a Person::hana nested struct, which is required to make Person a model of the Struct concept. No constructors are defined (so POD-ness is retained), the members are defined in the same order as they appear here and the macro can be used with template structs just as well, and at any scope. Also note that you are free to add more members to the Person type after or before you use the macro. However, only members defined with the macro will be picked up when introspecting the Person type. Easy enough? Now, a Person can be accessed programmatically:
Iteration over a Struct is done as if the Struct was a sequence of pairs, where the first element of a pair is the key associated to a member, and the second element is the member itself. When a Struct is defined through the BOOST_HANA_DEFINE_STRUCT macro, the key associated to any member is a compile-time hana::string representing the name of that member. This is why the function used with for_each takes a single argument pair, and then uses first and second to access the subparts of the pair. Also, notice how the to<char const*> function is used on the name of the member? This converts the compile-time string to a constexpr char const* so it can couted. Since it can be annoying to always use first and second to fetch the subparts of the pair, we can also use the fuse function to wrap our lambda and make it a binary lambda instead:
Now, it looks much cleaner. As we just mentioned, Structs are seen as a kind of sequence of pairs for the purpose of iteration. In fact, a Struct can even be searched like an associative data structure whose keys are the names of the members, and whose values are the members themselves:
_s user-defined literal creates a compile-time hana::string. It is located in the boost::hana::literals namespace. Note that it is not part of the standard yet, but it is supported by Clang and GCC. If you want to stay 100% standard, you can use the BOOST_HANA_STRING macro instead.The main difference between a Struct and a hana::map is that a map can be modified (keys can be added and removed), while a Struct is immutable. However, you can easily convert a Struct into a hana::map with to<map_tag>, and then you can manipulate it in a more flexible way.
Using the BOOST_HANA_DEFINE_STRUCT macro to adapt a struct is convenient, but sometimes one can't modify the type that needs to be adapted. In these cases, the BOOST_HANA_ADAPT_STRUCT macro can be used to adapt a struct in a ad-hoc manner:
BOOST_HANA_ADAPT_STRUCT macro must be used at global scope.The effect is exactly the same as with the BOOST_HANA_DEFINE_STRUCT macro, except you do not need to modify the type you want to adapt, which is sometimes useful. Finally, it is also possible to define custom accessors by using the BOOST_HANA_ADAPT_ADT macro:
This way, the names used to access the members of the Struct will be those specified, and the associated function will be called on the Struct when retrieving that member. Before we move on to a concrete example of using these introspection features, it should also be mentioned that structs can be adapted without using macros. This advanced interface for defining Structs can be used for example to specify keys that are not compile-time strings. The advanced interface is described in the documentation of the Struct concept.
Let's now move on with a concrete example of using the introspection capabilities we just presented for printing custom objects as JSON. Our end goal is to have something like this:
+And the output, after passing it through a JSON pretty-printer, should look like
+First, let's define a couple of utility functions to make string manipulation easier:
+ The quote and the to_json overloads are pretty self-explanatory. The join function, however, might need a bit of explanation. Basically, the intersperse function takes a sequence and a separator, and returns a new sequence with the separator in between each pair of elements of the original sequence. In other words, we take a sequence of the form [x1, ..., xn] and turn it into a sequence of the form [x1, sep, x2, sep, ..., sep, xn]. Finally, we fold the resulting sequence with the _ + _ function object, which is equivalent to std::plus<>{}. Since our sequence contains std::strings (we assume it does), this has the effect of concatenating all the strings of the sequence into one big string. Now, let's define how to print a Sequence:
First, we use the transform algorithm to turn our sequence of objects into a sequence of std::strings in JSON format. Then, we join that sequence with commas and we enclose it with [] to denote a sequence in JSON notation. Simple enough? Let's now take a look at how to print user-defined types:
Here, we use the keys method to retrieve a tuple containing the names of the members of the user-defined type. Then, we transform that sequence into a sequence of "name" : member strings, which we then join and enclose with {}, which is used to denote objects in JSON notation. And that's it!
This section explains several important notions about Hana's containers: how to create them, the lifetime of their elements and other concerns.
+While the usual way of creating an object in C++ is to use its constructor, heterogeneous programming makes things a bit more complicated. Indeed, in most cases, one is not interested in (or even aware of) the actual type of the heterogeneous container to be created. At other times, one could write out that type explicitly, but it would be redundant or cumbersome to do so. For this reason, Hana uses a different approach borrowed from std::make_tuple to create new containers. Much like one can create a std::tuple with std::make_tuple, a hana::tuple can be created with hana::make_tuple. However, more generally, containers in Hana may be created with the make function:
In fact, make_tuple is just a shortcut for make<tuple_tag> so you don't have to type boost::hana::make<boost::hana::tuple_tag> when you are out of Hana's namespace. Simply put, make<...> is is used all around the library to create different types of objects, thus generalizing the std::make_xxx family of functions. For example, one can create a hana::range of compile-time integers with make<range_tag>:
++These types with a trailing
+_tagare dummy types representing a family of heterogeneous containers (hana::tuple,hana::map, etc..). Tags are documented in the section on Hana's core.
For convenience, whenever a component of Hana provides a make<xxx_tag> function, it also provides the make_xxx shortcut to reduce typing. Also, an interesting point that can be raised in this example is the fact that r is constexpr. In general, whenever a container is initialized with constant expressions only (which is the case for r), that container may be marked as constexpr.
So far, we have only created containers with the make_xxx family of functions. However, some containers do provide constructors as part of their interface. For example, one can create a hana::tuple just like one would create a std::tuple:
When constructors (or any member function really) are part of the public interface, they will be documented on a per-container basis. However, in the general case, one should not take for granted that a container can be constructed as the tuple was constructed above. For example, trying to create a hana::range that way will not work:
In fact, we can't even specify the type of the object we'd like to create in that case, because the exact type of a hana::range is implementation-defined, which brings us to the next section.
The goal of this section is to clarify what can be expected from the types of Hana's containers. Indeed, so far, we always let the compiler deduce the actual type of containers by using the make_xxx family of functions along with auto. But in general, what can we say about the type of a container?
The answer is that it depends. Some containers have well defined types, while others do not specify their representation. In this example, the type of the object returned by make_tuple is well-defined, while the type returned by make_range is implementation-defined:
This is documented on a per-container basis; when a container has an implementation-defined representation, a note explaining exactly what can be expected from that representation is included in the container's description. There are several reasons for leaving the representation of a container unspecified; they are explained in the rationales. When the representation of a container is implementation-defined, one must be careful not to make any assumptions about it, unless those assumption are explicitly allowed in the documentation of the container.
+While necessary, leaving the type of some containers unspecified makes some things very difficult to achieve, like overloading functions on heterogeneous containers:
+The is_a utility is provided for this reason (and others). is_a allows checking whether a type is a precise kind of container using its tag, regardless of the actual type of the container. For example, the above example could be rewritten as
This way, the second overload of f will only match when R is a type whose tag is range_tag, regardless of the exact representation of that range. Of course, is_a can be used with any kind of container: tuple, map, set and so on.
In Hana, containers own their elements. When a container is created, it makes a copy of the elements used to initialize it and stores them inside the container. Of course, unnecessary copies are avoided by using move semantics. Because of those owning semantics, the lifetime of the objects inside the container is the same as that of the container.
+ Much like containers in the standard library, containers in Hana expect their elements to be objects. For this reason, references may not be stored in them. When references must be stored inside a container, one should use a std::reference_wrapper instead:
Much like the previous section introduced general but important notions about heterogeneous containers, this section introduces general notions about heterogeneous algorithms.
+Algorithms in Hana always return a new container holding the result. This allows one to easily chain algorithms by simply using the result of the first as the input of the second. For example, to apply a function to every element of a tuple and then reverse the result, one simply has to connect the reverse and transform algorithms:
This is different from the algorithms of the standard library, where one has to provide iterators to the underlying sequence. For reasons documented in the rationales, an iterator-based design was considered but was quickly dismissed in favor of composable and efficient abstractions better suited to the very particular context of heterogeneous programming.
+One might also think that returning full sequences that own their elements from an algorithm would lead to tons of undesirable copies. For example, when using reverse and transform, one could think that an intermediate copy is made after the call to transform:
To make sure this does not happen, Hana uses perfect forwarding and move semantics heavily so it can provide an almost optimal runtime performance. So instead of doing a copy, a move occurs between reverse and transform:
Ultimately, the goal is that code written using Hana should be equivalent to clever hand-written code, except it should be enjoyable to write. Performance considerations are explained in depth in their own section.
+Algorithms in Hana are not lazy. When an algorithm is called, it does its job and returns a new sequence containing the result, end of the story. For example, calling the permutations algorithm on a large sequence is a stupid idea, because Hana will actually compute all the permutations:
To contrast, algorithms in Boost.Fusion return views which hold the original sequence by reference and apply the algorithm on demand, as the elements of the sequence are accessed. This leads to subtle lifetime issues, like having a view that refers to a sequence that was destroyed. Hana's design assumes that most of the time, we want to access all or almost all the elements in a sequence anyway, and hence performance is not a big argument in favor of laziness.
+Algorithms in Hana are a bit special with respect to the runtime code they are expanded into. The goal of this subsection is not to explain exactly what code is generated, which depends on the compiler anyway, but to give a feel for things. Basically, a Hana algorithm is like an unrolled version of an equivalent classical algorithm. Indeed, since the bounds of the processed sequence are known at compile-time, it makes sense that we can unroll the loop over the sequence. For example, let's consider the for_each algorithm:
If xs was a runtime sequence instead of a tuple, its length would only be known at runtime and the above code would have to be implemented as a loop:
However, in our case, the length of the sequence is known at compile-time and so we don't have to check the index at each iteration. Hence, we can just write:
+The main difference here is that no bound checking and index increment is done at each step, because there is no index anymore; the loop was effectively unrolled. In some cases, this can be desirable for performance reasons. In other cases, this can be detrimental to performance because it causes the code size to grow. As always, performance is a tricky subject and whether you actually want loop unrolling to happen should be tackled on a case-by-case basis. As a rule of thumb, algorithms processing all (or a subset) of the elements of a container are unrolled. In fact, if you think about it, this unrolling is the only way to go for heterogeneous sequences, because different elements of the sequence may have different types. As you might have noticed, we're not using normal indices into the tuple, but compile-time indices, which can't be generated by a normal for loop. In other words, the following does not make sense:
By default, Hana assumes functions to be pure. A pure function is a function that has no side-effects at all. In other words, it is a function whose effect on the program is solely determined by its return value. In particular, such a function may not access any state that outlives a single invocation of the function. These functions have very nice properties, like the ability to reason mathematically about them, to reorder or even eliminate calls, and so on. Except where specified otherwise, all functions used with Hana (i.e. used in higher order algorithms) should be pure. In particular, functions passed to higher order algorithms are not guaranteed to be called any specific number of times. Furthermore, the order of execution is generally not specified and should therefore not be taken for granted. If this lack of guarantees about function invocations seems crazy, consider the following use of the any_of algorithm:
std::integral_constant contained in <boost/hana/ext/std/integral_constant.hpp> must be included.According to the previous section on unrolling, this algorithm should be expanded into something like:
+Of course, the above code can't work as-is, because we're calling pred inside something that would have to be a constant expression, but pred is a lambda (and lambdas can't be called in constant expressions). However, whether any of these objects has an integral type is clearly known at compile-time, and hence we would expect that computing the answer only involves compile-time computations. In fact, this is exactly what Hana does, and the above algorithm is expanded into something like:
any_of must actually be more general than this. However, this lie-to-children is perfect for educational purposes.As you can see, the predicate is never even executed; only its result type on a particular object is used. Regarding the order of evaluation, consider the transform algorithm, which is specified (for tuples) as:
Since make_tuple is a function, and since the evaluation order for the arguments of a function is unspecified, the order in which f is called on each element of the tuple is unspecified too. If one sticks to pure functions, everything works fine and the resulting code is often easier to understand. However, some exceptional algorithms like for_each do expect impure functions, and they guarantee an order of evaluation. Indeed, a for_each algorithm that would only take pure functions would be pretty much useless. When an algorithm can accept an impure function or guarantees some order of evaluation, the documentation for that algorithm will mention it explicitly. However, by default, no guarantees may be taken for granted.
This section introduces the notion of cross-phase computations and algorithms. In fact, we have already used cross-phase algorithms in the quick start, for example with filter, but we did not explain exactly what was happening at that time. But before we introduce cross-phase algorithms, let's define what we mean by cross-phase. The phases we're referring to here are the compilation and the execution of a program. In C++ as in most statically typed languages, there is a clear distinction between compile-time and runtime; this is called phase distinction. When we speak of a cross-phase computation, we mean a computation that is somehow performed across those phases; i.e. that is partly executed at compile-time and partly executed at runtime.
Like we saw in earlier examples, some functions are able to return something that can be used at compile-time even when they are called on a runtime value. For example, let's consider the length function applied to a non-constexpr container:
Obviously, the tuple can't be made constexpr, since it contains runtime std::strings. Still, even though it is not called on a constant expression, length returns something that can be used at compile-time. If you think of it, the size of the tuple is known at compile-time regardless of its content, and hence it would only make sense for this information to be available to us at compile-time. If that seems surprising, think about std::tuple and std::tuple_size:
Since the size of the tuple is encoded in its type, it is always available at compile-time regardless of whether the tuple is constexpr or not. In Hana, this is implemented by having length return an IntegralConstant. Since an IntegralConstant's value is encoded in its type, the result of length is contained in the type of the object it returns, and the length is therefore known at compile-time. Because length goes from a runtime value (the container) to a compile-time value (the IntegralConstant), length is a trivial example of a cross-phase algorithm (trivial because it does not really manipulate the tuple). Another algorithm that is very similar to length is the is_empty algorithm, which returns whether a container is empty:
More generally, any algorithm that takes a container whose value is known at runtime but queries something that can be known at compile-time should be able to return an IntegralConstant or another similar compile-time value. Let's make things slightly more complicated by considering the any_of algorithm, which we already encountered in the previous section:
In this example, the result can't be known at compile-time, because the predicate returns a bool that is the result of comparing two std::strings. Since std::strings can't be compared at compile-time, the predicate must operate at runtime, and the overall result of the algorithm can then only be known at runtime too. However, let's say we used any_of with the following predicate instead:
std::integral_constant contained in <boost/hana/ext/std/integral_constant.hpp> must be included.First, since the predicate is only querying information about the type of each element of the tuple, it is clear that its result can be known at compile-time. Since the number of elements in the tuple is also known at compile-time, the overall result of the algorithm can, in theory, be known at compile-time. More precisely, what happens is that the predicate returns a value initialized std::is_same<...>, which inherits from std::integral_constant. Hana recognizes these objects, and the algorithm is written in such a way that it preserves the compile-timeness of the predicate's result. In the end, any_of hence returns an IntegralConstant holding the result of the algorithm, and we use the compiler's type deduction in a clever way to make it look easy. Hence, it would be equivalent to write (but then you would need to already know the result of the algorithm!):
Ok, so some algorithms are able to return compile-time values when their input satisfies some constraints with respect to compile-timeness. However, other algorithms are more restrictive and they require their inputs to satisfy some constraints regarding compile-timeness, without which they are not able to operate at all. An example of this is filter, which takes a sequence and a predicate, and returns a new sequence containing only those elements for which the predicate is satisfied. filter requires the predicate to return an IntegralConstant. While this requirement may seem stringent, it really makes sense if you think about it. Indeed, since we're removing some elements from the heterogeneous sequence, the type of the resulting sequence depends on the result of the predicate. Hence, the result of the predicate has to be known at compile-time for the compiler to be able to assign a type to the returned sequence. For example, consider what happens when we try to filter a heterogeneous sequence as follows:
Clearly, we know that the predicate will only return false on the second element, and hence the result should be a [Fish, Dog] tuple. However, the compiler has no way of knowing this since the predicate's result is the result of a runtime computation, which happens way after the compiler has finished its job. Hence, the compiler does not have enough information to determine the return type of the algorithm. However, we could filter the same sequence with any predicate whose result is available at compile-time:
Since the predicate returns an IntegralConstant, we know which elements of the heterogeneous sequence we'll be keeping at compile-time. Hence, the compiler is able to figure out the return type of the algorithm. Other algorithms like partition and sort work similarly; special algorithm requirements are always documented, just read the reference documentation of an algorithm before using it to avoid surprises.
This is the end of the section on algorithms. While this constitutes a fairly complete explanation of phase interaction inside algorithms, a deeper understanding can be gained by reading the advanced section on constexpr and the reference for Constant and IntegralConstant.
constexpr function objects instead of being template functions. This allows passing them to higher-order algorithms, which is very useful. However, since those function objects are defined at namespace scope in the header files, this causes each translation unit to see a different algorithm object. Hence, the address of an algorithm function object is not guaranteed to be unique across translation units, which can cause an ODR violation if one relies on such an address. So, in short, do not rely on the uniqueness of the address of any global object provided by Hana, which does not make sense in the general case anyway because such objects are constexpr. See issue #76 for more information.C++ programmers love performance, so here's a whole section dedicated to it. Since Hana lives on the frontier between runtime and compile-time computations, we are not only interested in runtime performance, but also compile-time performance. Since both topics are pretty much disjoint, we treat them separately below.
+hana::map and hana::set) have a pretty bad compile-time behavior because of their naive implementation, and their runtime behavior also seems to be problematic in some cases. Improving this situation is in the TODO list.C++ metaprogramming brings its share of awful things. One of the most annoying and well-known problem associated to it is interminable compilation times. Hana claims to be more compile-time efficient than its predecessors; this is a bold claim and we will now try to back it. Of course, Hana can't do miracles; metaprogramming is a byproduct of the C++ template system and the compiler is not meant to be used as an interpreter for some meta language. However, by using cutting edge and intensely benchmarked techniques, Hana is able to minimize the strain on the compiler.
+Before we dive, let me make a quick note on the methodology used to measure compile-time performance in Hana. Previous metaprogramming libraries measured the compile-time complexity of their meta-algorithms and meta-sequences by looking at the number of instantiations the compiler had to perform. While easy to understand, this way of measuring the compile-time complexity actually does not give us a lot of information regarding the compilation time, which is what we're interested in minimizing at the end of the day. Basically, the reason for this is that template metaprogramming is such a twisted model of computation that it's very hard to find a standard way of measuring the performance of algorithms. Hence, instead of presenting meaningless complexity analyses, we prefer to benchmark everything on every supported compiler and to pick the best implementation on that compiler. Also note that the benchmarks we present here are quite precise. Indeed, even though we do not take multiple measurements and take their mean or something similar to reduce incertitude, the benchmarks are very stable when they are regenerated, which suggests a reasonably good precision. Now, let's dive.
+First, Hana minimizes its dependency on the preprocessor. In addition to yielding cleaner error messages in many cases, this reduces the overall parsing and preprocessing time for header files. Also, because Hana only supports cutting edge compilers, there are very few workarounds in the library, which results in a cleaner and smaller library. Finally, Hana minimizes reliance on any kind of external dependencies. In particular, it only uses other Boost libraries in a few specific cases, and it does not rely on the standard library for the largest part. There are several reasons (other than include times) for doing so; they are documented in the rationales.
+Below is a chart showing the time required to include different libraries. The chart shows the time for including everything in the (non-external) public API of each library. For example, for Hana this means the <boost/hana.hpp> header, which excludes the external adapters. For other libraries like Boost.Fusion, this means including all the public headers in the boost/fusion/ directory, but not the adapters for external libraries like the MPL.
In addition to reduced preprocessing times, Hana uses modern techniques to implement heterogeneous sequences and algorithms in the most compile-time efficient way possible. Before jumping to the compile-time performance of the algorithms, we will have a look at the compile-time cost of creating heterogeneous sequences. Indeed, since we will be presenting algorithms that work on sequences, we must be aware of the cost of creating the sequences themselves, since that will influence the benchmarks for the algorithms. The following chart presents the compile-time cost of creating a sequence of n heterogeneous elements.
The benchmark methodology is to always create the sequences in the most efficient way possible. For Hana and std::tuple, this simply means using the appropriate make_tuple function. However, for the MPL, this means creating a mpl::vectorN of size up to 20, and then using mpl::push_back to create larger vectors. We use a similar technique for Fusion sequences. The reason for doing so is that Fusion and MPL sequences have fixed size limits, and the techniques used here have been found to be the fastest way to create longer sequences.
For completeness, we also present the compile-time cost of creating a std::array with n elements. However, note that std::array can only hold elements with a single type, so we're comparing apples and oranges here. As you can see, the cost of creating a std::array is constant and essentially inexistent (the non-zero overhead is that of simply including the <array> header). Hence, while Hana provides improved compile-times over other heterogeneous containers, please stick with normal homogeneous containers if that's all you need for your application; your compile-times will be much faster that way.
You can also see that creating sequences has a non-negligible cost. Actually, this is really the most expensive part of doing heterogeneous computations, as you will see in the following charts. Hence, when you look at the charts below, keep in mind the cost of merely creating the sequences. Also note that only the most important algorithms will be presented here, but the Metabench project provides micro benchmarks for compile-time performance for almost all of Hana's algorithms. Also, the benchmarks we present compare several different libraries. However, since Hana and Fusion can work with values and not only types, comparing their algorithms with type-only libraries like MPL is not really fair. Indeed, Hana and Fusion algorithms are more powerful since they also allow runtime effects to be performed. However, the comparison between Fusion and Hana is fair, because both libraries are just as powerful (strictly speaking). Finally, we can't show benchmarks of the algorithms for std::tuple, because the standard does not provide equivalent algorithms. Of course, we could use Hana's external adapters, but that would not be a faithful comparison.
The first algorithm which is ubiquitous in metaprogramming is transform. It takes a sequence and a function, and returns a new sequence containing the result of applying the function to each element. The following chart presents the compile-time performance of applying transform to a sequence of n elements. The x axis represents the number of elements in the sequence, and the y axis represents the compilation time in seconds. Also note that we're using the transform equivalent in each library; we're not using Hana's transform through the Boost.Fusion adapters, for example, because we really want to benchmark their implementation against ours.
Here, we can see that Hana's tuple performs better than all the other alternatives. This is mainly due to the fact that we use C++11 variadic parameter pack expansion to implement this algorithm under the hood, which is quite efficient.
+Before we move on, it is important to mention something regarding the benchmark methodology for Fusion algorithms. Some algorithms in Fusion are lazy, which means that they don't actually perform anything, but simply return a modified view to the original data. This is the case of fusion::transform, which simply returns a transformed view that applies the function to each element of the original sequence as those elements are accessed. If we want to benchmark anything at all, we need to force the evaluation of that view, as would eventually happen when accessing the elements of the sequence in real code. However, for complex computations with multiple layers, a lazy approach may yield a substantially different compile-time profile. Of course, this difference is poorly represented in micro benchmarks, so keep in mind that these benchmarks only give a part of the big picture. For completeness in the rest of the section, we will mention when a Fusion algorithm is lazy, so that you know when we're artificially forcing the evaluation of the algorithm for the purpose of benchmarking.
The second important class of algorithms are folds. Folds can be used to implement many other algorithms like count_if, minimum and so on. Hence, a good compile-time performance for fold algorithms ensures a good compile-time performance for those derived algorithms, which is why we're only presenting folds here. Also note that all the non-monadic fold variants are somewhat equivalent in terms of compile-time, so we only present the left folds. The following chart presents the compile-time performance of applying fold_left to a sequence of n elements. The x axis represents the number of elements in the sequence, and the y axis represents the compilation time in seconds. The function used for folding is a dummy function that does nothing. In real code, you would likely fold with a nontrivial operation, so the curves would be worse than that. However, these are micro benchmarks and hence they only show the performance of the algorithm itself.
The third and last algorithm that we present here is the find_if algorithm. This algorithm is difficult to implement efficiently, because it requires stopping at the first element which satisfies the given predicate. For the same reason, modern techniques don't really help us here, so this algorithm constitutes a good test of the implementation quality of Hana, without taking into account the free lunch given to use by C++14.
As you can see, Hana performs better than Fusion, and as well as MPL, yet Hana's find_if can be used with values too, unlike MPL's. This concludes the section on compile-time performance. In case you want to see the performance of an algorithm that we have not presented here, the Metabench project provides compile-time benchmarks for most of Hana's algorithms.
Hana was designed to be very efficient at runtime. But before we dive into the details, let's clarify one thing. Hana being a metaprogramming library which allows manipulating both types and values, it does not always make sense to even talk about runtime performance. Indeed, for type-level computations and computations on IntegralConstants, runtime performance is simply not a concern, because the result of the computation is contained in a type, which is a purely compile-time entity. In other words, these computations involve only compile-time work, and no code is even generated to perform these computations at runtime. The only case where it makes sense to discuss runtime performance is when manipulating runtime values in heterogeneous containers and algorithms, because this is the only case where the compiler has to generate some runtime code. It is therefore only computations of this sort that we will be studying in the remainder of this section.
Like we did for compile-time benchmarks, the methodology used to measure runtime performance in Hana is data driven rather than analytical. In other words, instead of trying to determine the complexity of an algorithm by counting the number of basic operations it does as a function of the input size, we simply take measurements for the most interesting cases and see how it behaves. There are a couple of reasons for doing so. First, we do not expect Hana's algorithms to be called on large inputs since those algorithms work on heterogeneous sequences whose length must be known at compile-time. For example, if you tried to call the find_if algorithm on a sequence of 100k elements, your compiler would simply die while trying to generate the code for this algorithm. Hence, algorithms can't be called on very large inputs and the analytical approach then loses a lot of its attractiveness. Secondly, processors have evolved into pretty complex beasts, and the actual performance you'll be able to squeeze out is actually controlled by much more than the mere number of steps your algorithm is doing. For example, bad cache behavior or branch misprediction could turn a theoretically efficient algorithm into a slowpoke, especially for small inputs. Since Hana causes a lot of unrolling to happen, these factors must be considered even more carefully and any analytical approach would probably only comfort us into thinking we're efficient. Instead, we want hard data, and pretty charts to display it!
There are a couple of different aspects we will want to benchmark. First, we will obviously want to benchmark the execution time of the algorithms. Secondly, because of the by-value semantics used throughout the library, we will also want to make sure that the minimum amount of data is copied around. Finally, we will want to make sure that using Hana does not cause too much code bloat because of unrolling, as explained in the section on algorithms.
+Just like we studied only a couple of key algorithms for compile-time performance, we will focus on the runtime performance of a few algorithms. For each benchmarked aspect, we will compare the algorithm as implemented by different libraries. Our goal is to always be at least as efficient as Boost.Fusion, which is near from optimality in terms of runtime performance. For comparison, we also show the same algorithm as executed on a runtime sequence, and on a sequence whose length is known at compile-time but whose transform algorithm does not use explicit loop unrolling. All the benchmarks presented here are done in a Release CMake configuration, which takes care of passing the proper optimization flags (usually -O3). Let's start with the following chart, which shows the execution time required to transform different kinds of sequences:
fusion::transform is usually lazy, and we're forcing its evaluation for the purpose of benchmarking.As you can see, Hana and Fusion are pretty much on the same line. std::array is slightly slower for larger collections data sets, and std::vector is noticeably slower for larger collections. Since we also want to look out for code bloat, let's take a look at the size of the executable generated for the exact same scenario:
As you can see, code bloat does not seem to be an issue, at least not one that can be detected in micro benchmarks such as this one. Let's now take a look at the fold algorithm, which is used very frequently:
Here, you can see that everybody is performing pretty much the same, which is a good sign that Hana is at least not screwing things up. Again, let's look at the executable size:
+Here again, the code size did not explode. So at least for moderate usages of Hana (and Fusion for that matter, since they have the same problem), code bloat should not be a major concern. The containers in the charts we just presented contain randomly generated ints, which is cheap to copy around and lends itself well to micro benchmarks. However, what happens when we chain multiple algorithms on a container whose elements are expensive to copy? More generally, the question is: when an algorithm is passed a temporary object, does it seize the opportunity to avoid unnecessary copies? Consider:
To answer this question, we'll look at the chart generated when benchmarking the above code for strings of about 1k characters. However, note that it does not really make sense to benchmark this for standard library algorithms, because they do not return containers.
+fusion::reverse is usually lazy, and we're forcing its evaluation for the purpose of benchmarking.As you can see, Hana is faster than Fusion, probably because of a more consistent use of move semantics in the implementation. If we had not provided a temporary container to reverse, no move could have been performed by Hana and both libraries would have performed similarly:
This concludes the section on runtime performance. Hopefully you are now convinced that Hana was built for speed. Performance is important to us: if you ever encounter a scenario where Hana causes bad code to be generated (and the fault is not on the compiler), please open an issue so the problem can be addressed.
+Hana provides out-of-the-box integration with some existing libraries. Specifically, this means that you can use some containers from these libraries in Hana's algorithms by simply including the appropriate header making the bridge between Hana and the external component. This can be very useful for porting existing code from e.g. Fusion/MPL to Hana:
+However, using external adapters has a couple of pitfalls. For example, after a while using Hana, you might become used to comparing Hana tuples using the normal comparison operators, or doing arithmetic with Hana integral_constants. Of course, nothing guarantees that these operators are defined for external adapters too (and in general they won't be). Hence, you'll have to stick to the functions provided by Hana that implement these operators. For example:
Instead, you should use the following:
+ But sometimes, it's much worse. Some external components define operators, but they don't necessarily have the same semantics as those from Hana. For example, comparing two std::tuples of different lengths will give an error when using operator==:
On the other hand, comparing Hana tuples of different lengths will just return a false IntegralConstant:
This is because std::tuple defines its own operators, and their semantics are different from that of Hana's operators. The solution is to stick with Hana's named functions instead of using operators when you know you'll have to work with other libraries:
When using external adapters, one should also be careful not to forget including the proper bridge headers. For example, suppose I want to use a Boost.MPL vector with Hana. I include the appropriate bridge header:
+Now, however, suppose that I use mpl::size to query the size of the vector and then compare it to some value. I could also use hana::length and everything would be fine, but bear with me for the sake of the example:
The reason why this breaks is that mpl::size returns a MPL IntegralConstant, and Hana has no way of knowing about these unless you include the proper bridge header. Hence, you should do the following instead:
The morale is that when working with external libraries, you have to be a bit careful about what objects you are manipulating. The final pitfall is about implementation limits in external libraries. Many older libraries have limits regarding the maximum size of the heterogeneous containers that can be created with them. For example, one may not create a Fusion list of more than FUSION_MAX_LIST_SIZE elements in it. Obviously, these limits are inherited by Hana and for example, trying to compute the permutations of a fusion::list containing 5 elements (the resulting list would contain 120 elements) will fail in a gruesome way:
Apart from the pitfalls explained in this section, using external adapters should be just as straightforward as using normal Hana containers. Of course, whenever possible, you should try to stick with Hana's containers because they are usually more friendly to work with and are often more optimized.
+The goal of this section is to give a high-level overview of Hana's core. This core is based on the notion of tag, which is borrowed from the Boost.Fusion and Boost.MPL libraries but taken much further by Hana. These tags are then used for several purposes, like algorithm customization, documentation grouping, improving error messages and converting containers into other containers. Because of its modular design, Hana can be extended in a ad-hoc manner very easily. In fact, all the functionality of the library is provided through an ad-hoc customization mechanism, which is explained here.
+Heterogeneous programming is basically programming with objects having different types. However, it is clear that some families of objects, while having different representations (C++ types), are strongly related. For example, the std::integral_constant<int, n> types are different for each different n, but conceptually they all represent the same thing; a compile-time number. The fact that std::integral_constant<int, 1>{} and std::integral_constant<int, 2>{} have different types is just a side effect of the fact that we're using their type to encode the value of these objects. Indeed, when manipulating a sequence of std::integral_constant<int, ...>s, chances are that you actually think of it as a homogeneous sequence of an imaginary integral_constant type, disregarding the actual types of the objects and pretending they are all just integral_constants with different values.
To reflect this reality, Hana provides tags representing its heterogeneous containers and other compile-time entities. For example, all of Hana's integral_constant<int, ...>s have different types, but they all share the same tag, integral_constant_tag<int>. This allows the programmer to think in terms of that single type instead of trying to think in terms of the actual types of the objects. Concretely, tags are implemented as empty structs. To make them stand out, Hana adopts the convention of naming these tags by adding the _tag suffix.
T can be obtained by using tag_of<T>::type, or equivalently tag_of_t<T>.Tags are an extension to normal C++ types. Indeed, by default, the tag of a type T is T itself, and the core of the library is designed to work in those cases. For example, hana::make expects either a tag or an actual type; if you send it a type T, it will do the logical thing and construct an object of type T with the arguments you pass it. If you pass a tag to it, however, you should specialize make for that tag and provide your own implementation, as explained below. Because tags are an extension to usual types, we end up mostly reasoning in terms of tags instead of usual types, and the documentation sometimes uses the words type, data type and tag interchangeably.
Tag dispatching is a generic programming technique for picking the right implementation of a function depending on the type of the arguments passed to the function. The usual mechanism for overriding a function's behavior is overloading. Unfortunately, this mechanism is not always convenient when dealing with families of related types having different base templates, or when the kind of template parameters is not known (is it a type or a non-type template parameter?). For example, consider trying to overload a function for all Boost.Fusion vectors:
+If you know Boost.Fusion, then you probably know that it won't work. This is because Boost.Fusion vectors are not necessarily specializations of the boost::fusion::vector template. Fusion vectors also exist in numbered forms, which are all of different types:
This is an implementation detail required by the lack of variadic templates in C++03 that leaks into the interface. This is unfortunate, but we need a way to work around it. To do so, we use an infrastructure with three distinct components:
+tag_of metafunction. Specifically, for any type T, tag_of<T>::type is the tag used to dispatch it.transform or unpack.xxx_impl (for an interface function xxx) with a nested apply static function, as will be shown below.When the public interface function xxx is called, it will get the tag of the argument(s) it wishes to dispatch the call on, and then forward the call to the xxx_impl implementation associated to those tags. For example, let's implement a basic setup for tag dispatching of a function that prints its argument to a stream. First, we define the public interface function and the implementation that can be specialized:
Now, let's define a type that needs tag dispatching to customize the behavior of print. While some C++14 examples exist, they are too complicated to show in this tutorial and we will therefore use a C++03 tuple implemented as several different types to illustrate the technique:
The nested using hana_tag = vector_tag; part is a terse way of controling the result of the tag_of metafunction, and hence the tag of the vectorN type. This is explained in the reference for tag_of. Finally, if you wanted to customize the behavior of the print function for all the vectorN types, you would normally have to write something along the lines of
Now, with tag dispatching, you can rely on the vectorNs all sharing the same tag and specialize only the print_impl struct instead:
One upside is that all vectorNs can now be treated uniformly by the print function, at the cost of some boilerplate when creating the data structure (to specify the tag of each vectorN) and when creating the initial print function (to setup the tag dispatching system with print_impl). There are also other advantages to this technique, like the ability to check for preconditions in the interface function without having to do it in each custom implementation, which would be tedious:
print function, but consider for example a function to get the nth element of a sequence; you might want to make sure that the index is not out-of-bounds.This technique also makes it easier to provide interface functions as function objects instead of normal overloaded functions, because only the interface function itself must go through the trouble of defining a function object. Function objects have several advantages over overloaded functions, like the ability to be used in higher order algorithms or as variables:
+As you are probably aware of, being able to implement an algorithm for many types at the same time is tremendously useful (that's precisely the goal of C++ templates!). However, even more useful is the ability to implement an algorithm for many types that satisfy some condition. C++ templates are currently missing this ability to constrain their template parameters, but a language feature called concepts is being rolled out with the goal of addressing this issue.
+With something similar in mind, Hana's algorithms support an additional layer of tag-dispatching to what was explained above. This layer allows us to "specialize" an algorithm for all types that satisfy some predicate. For example, let's say we wanted to implement the print function above for all types that represent some kind of sequence. Right now, we wouldn't have an easy way to do this. However, the tag dispatching for Hana's algorithms is set up slightly differently than what was shown above, and we could hence write the following:
where Tag represents some kind of sequence would only need to be a boolean expression representing whether Tag is a sequence. We'll see how such predicates can be created in the next section, but for now let's assume that it just works. Without going into the details of how this tag-dispatching is set up, the above specialization will only be picked up when the predicate is satisfied, and if no better match can be found. Hence, for example, if our vector_tag was to satisfy the predicate, our initial implementation for vector_tag would still be preferred over the hana::when-based specialization, because it represents a better match. In general, any specialization (whether explicit or partial) not using hana::when will be preferred over a specialization using hana::when, which was designed to be as unsurprising as possible from a user point of view. This covers pretty much all there's to say about tag-dispatching in Hana. The next section will explain how we can create C++ concepts for metaprogramming, which could then be used in conjunction with hana::when to achieve a great deal of expressiveness.
The implementation of concepts in Hana is very simple. At its heart, a concept is just a template struct that inherits from a boolean integral_constant representing whether the given type is a model of the concept:
Then, one can test whether a type T is a model of Concept by looking at Concept<T>::value. Simple enough, right? Now, while the way one might implement the check does not have to be anything specific as far as Hana is concerned, the rest of this section will explain how it is usually done in Hana, and how it interacts with tag dispatching. You should then be able to define your own concepts if you so desire, or at least to understand better how Hana works internally.
Usually, a concept defined by Hana will require that any model implements some tag-dispatched functions. For example, the Foldable concept requires that any model defines at least one of hana::unpack and hana::fold_left. Of course, concepts usually also define semantic requirements (called laws) that must be satisfied by their models, but these laws are not (and couldn't be) checked by the concept. But how do we check that some functions are properly implemented? For this, we'll have to slightly modify the way we defined tag-dispatched methods as shown in the previous section. Let's go back to our print example and try to define a Printable concept for those objects that can be printed. Our end goal is to have a template struct such as
To know whether print_impl<...> has been defined, we'll modify print_impl so that it inherits from a special base class when it is not overridden, and we'll simply check whether print_impl<T> inherits from that base class:
Of course, when we specialize print_impl with a custom type, we don't inherit from that special_base_class type:
As you can see, Printable<T> really only checks whether the print_impl<T> struct was specialized by a custom type. In particular, it does not even check whether the nested ::apply function is defined or if it is syntactically valid. It is assumed that if one specializes print_impl for a custom type, the nested ::apply function exists and is correct. If it is not, a compilation error will be triggered when one tries to call print on an object of that type. Concepts in Hana make the same assumptions.
Since this pattern of inheriting from a special base class is quite abundant in Hana, the library provides a dummy type called hana::default_ that can be used in place of special_base_class. Then, instead of using std::is_base_of, one can use hana::is_default, which looks nicer. With this syntactic sugar, the code now becomes:
This is all that there's to know about the interaction between tag-dispatched functions and concepts. However, some concepts in Hana do not rely solely on the definition of specific tag-dispatched functions to determine if a type is a model of the concept. This can happen when a concept merely introduces semantic guarantees through laws and refined concepts, but no additional syntactic requirements. Defining such a concept can be useful for several reasons. First, it sometimes happen that an algorithm can be implemented more efficiently if we can assume some semantic guarantees X or Y, so we might create a concept to enforce those guarantees. Secondly, it is sometimes possible to automatically define the models for several concepts when we have additional semantic guarantees, which saves the user the trouble of defining those models manually. For example, this is the case of the Sequence concept, which basically adds semantic guarantees to Iterable and Foldable, and in turn allows us to define the models for a myriad of concepts ranging from Comparable to Monad.
For these concepts, it is usually necessary to specialize the corresponding template struct in the boost::hana namespace to provide a model for a custom type. Doing so is like providing a seal saying that the semantic guarantees required by the concept are respected by the custom type. The concepts that require being explicitly specialized will document that fact. So that's it! This is all that there's to know about concepts in Hana, which ends this section about the core of Hana.
The library is designed to be modular while keeping the number of headers that must be included to get basic functionality reasonably low. The structure of the library was also intentionally kept simple, because we all love simplicity. What follows is a general overview of the header organization. A list of all the headers provided by the library is also available in the panel on the left (under the Headers label) in case you need more details.
+boost/hana.hppboost/hana/XXX, the corresponding header is boost/hana/XXX.hpp.boost/hana/concept/boost/hana/core/make and to.boost/hana/fwd/boost/hana/ directory, except all the headers contain only forward declarations and documentation. For example, to include the hana::tuple container, one can use the boost/hana/tuple.hpp header. However, if one only wants the forward declaration of that container, the boost/hana/fwd/tuple.hpp header can be used instead. Note that forward declarations for headers in boost/hana/ext/ and boost/hana/functional/ are not provided.boost/hana/functional/boost/hana/ext/
+ This directory contains adapters for external libraries. For a component named xxx in a namespace ns, the external adapter lives in the boost/hana/ext/ns/xxx.hpp header. For example, the external adapter for std::tuple lives in the boost/hana/ext/std/tuple.hpp header, while the external adapter for boost::mpl::vector is in boost/hana/ext/boost/mpl/vector.hpp.
Note that only the strict minimum required to adapt the external components is included in these headers (e.g. a forward declaration). This means that the definition of the external component should still be included when one wants to use it. For example:
boost/hana/experimental/
+ This directory contains experimental features that may or may not make it into the library at some point, but that were deemed useful enough to be made available to the public. Features in this subdirectory reside in the hana::experimental namespace. Also, do not expect these features to be stable; they may be moved, renamed, changed or removed between releases of the library. These features may also require additional external dependencies; each feature documents the additional dependencies it requires, if any.
Because of the potential additional dependencies, these headers are also not included by the master header of the library.
+boost/hana/detail/detail/ is guaranteed to be stable, so you should not use it.You now have everything you need to start using the library. From this point forward, mastering the library is only a matter of understanding how to use the general purpose concepts and containers provided with it, which is best done by looking at the reference documentation. At some point, you will probably also want to create your own concepts and data types that fit your needs better; go ahead, the library was designed to be used that way.
+Programming with heterogeneous objects is inherently functional – since it is impossible to modify the type of an object, a new object must be introduced instead, which rules out mutation. Unlike previous metaprogramming libraries whose design was modeled on the STL, Hana uses a functional style of programming which is the source for a good portion of its expressiveness. However, as a result, many concepts presented in the reference will be unfamiliar to C++ programmers without a knowledge of functional programming. The reference attempts to make these concepts approachable by using intuition whenever possible, but bear in mind that the highest rewards are usually the fruit of some effort.
+This finishes the tutorial part of the documentation. I hope you enjoy using the library, and please consider contributing to make it even better!
+– Louis
+ As for most generic libraries, algorithms in Hana are documented by the concept to which they belong (Foldable, Iterable, Searchable, Sequence, etc...). The different containers are then documented on their own page, and the concepts that they model are documented there. The concepts modeled by some container defines what algorithms can be used with such a container.
More specifically, the structure of the reference (available in the menu to the left) goes as follow:
+maybe for optional.After you get to know Hana a bit better, it will probably happen that you just want to find the reference for a precise function, concept or container. If you know the name of what you're looking for, you can use the search box located in the upper right corner of any page of the documentation. My personal experience is that this is by far the quickest way of finding what you want when you already know its name.
+As you will see in the reference, several functions provide signatures documented in a semi-formal mathematical language. We are in the process of documenting all functions in this way, but this may take a while. The notation used is the usual mathematical notation for defining functions. Specifically, a function Return f(Arg1, ..., ArgN); can be defined equivalently using mathematical notation as
+\[ \mathtt{f} : \mathtt{Arg}_1 \times \dots \times \mathtt{Arg}_n \to \mathtt{Return} \] +
+However, instead of documenting the actual argument and return types of functions, those signatures are written in terms of argument and return tags. This is done because of the heterogeneous setting, where the actual type of an object is usually pretty meaningless and does not help to reason about what's being returned or taken by a function. For example, instead of documenting the equal function for integral_constants as
+\[ \mathtt{equal} : \mathtt{integral\_constant<T, n>} \times \mathtt{integral\_constant<T, m>} \to \mathtt{integral\_constant<bool, n == m>} \] +
+which is not really helpful (as it really presents nothing but the implementation), it is instead documented using integral_constant_tag, which acts as the "type" of all integral_constants. Note that since equal is part of the Comparable concept, it is not actually documented for hana::integral_constant specifically, but the idea is there:
+\[ \mathtt{equal} : \mathtt{integral\_constant\_tag<T>} \times \mathtt{integral\_constant\_tag<T>} \to \mathtt{integral\_constant\_tag<bool>} \] +
+This clearly conveys the intention that comparing two integral_constants gives back another integral_constant holding a bool. In general, this abstraction of the actual representation of objects makes it possible for us to reason in a high level manner about functions, even though their actual return and argument types are heterogeneous and not helpful. Finally, most functions expect container elements to have some properties. For example, this is the case of the sort algorithm, which obviously requires the container elements to be Orderable. Normally, we would write the signature for the non-predicated version of sort as
+\[ \mathtt{sort} : \mathtt{S} \to \mathtt{S} \\ \text{where S is a Sequence} \] +
+However, this fails to express the requirement that the contents of S are Orderable. To express this, we use the following notation:
+\[ \mathtt{sort} : \mathtt{S(T)} \to \mathtt{S(T)} \\ \text{where S is a Sequence and T is Orderable} \] +
+One way to see this is to pretend that S, the sequence tag, is actually parameterized by the tag of the sequence's elements, T. We're also pretending that the elements all have the same tag T, which is not the case in general. Now, by stating that T must be Orderable, we're expressing the fact that the sequence's elements must be Orderable. This notation is used in different flavors to express different kinds of requirements. For example, the cartesian_product algorithm takes a sequence of sequences and returns the cartesian product of those sequences as a sequence of sequences. Using our notation, this can be conveyed very easily:
+\[ \mathtt{cartesian\_product} : \mathtt{S(S(T))} \to \mathtt{S(S(T))} \\ \text{where S is a Sequence} \] +
+I'd like to thank the following persons and organizations for contributing to Hana in one way or another:
+The reference documentation uses a couple of terms that are specific to this library. Also, a simplified implementation of functions is sometimes provided in pseudo-code, the actual implementation sometimes being slightly hard to understand. This section defines terms used in the reference and in the pseudo-code used to describe some functions.
+forwarded(x)Means that the object is forwarded optimally. This means that if x is a parameter, it is std::forwarded, and if it is a captured variable, it is moved from whenever the enclosing lambda is an rvalue.
Also note that when x can be moved from, the statement return forwarded(x); in a function with decltype(auto) does not mean that an rvalue reference to x will be returned, which would create a dangling reference. Rather, it means that x is returned by value, the value being constructed with the std::forwarded x.
perfect-captureThis is used in lambdas to signify that the captured variables are initialized using perfect forwarding, as if [x(forwarded(x))...]() { } had been used.
tag-dispatchedThis means that the documented function uses tag dispatching, and hence the exact implementation depends on the model of the concept associated to the function.
+implementation-definedThis expresses the fact that the exact implementation of an entity (usually a type) should not be relied upon by users. In particular, this means that one can not assume anything beyond what is written explicitly in the documentation. Usually, the concepts satisfied by an implementation-defined entity will be documented, because one could otherwise do nothing with it. Concretely, assuming too much about an implementation-defined entity will probably not kill you, but it will very probably break your code when you update to a newer version of Hana.
+This section documents the rationale for some design choices. It also serves as a FAQ for some (not so) frequently asked questions. If you think something should be added to this list, open a GitHub issue and we'll consider either improving the documentation or adding the question here.
+There are several reasons for doing so. First, Hana is a very fundamental library; we are basically reimplementing the core language and the standard library with support for heterogeneous types. When going through the code, one quickly realizes that other libraries are rarely needed, and that almost everything has to be implemented from scratch. Also, since Hana is very fundamental, there is even more incentive for keeping the dependencies minimal, because those dependencies will be handed down to the users. Regarding the minimal reliance on Boost in particular, one big argument for using it is portability. However, as a cutting edge library, Hana only targets very recent compilers. Hence, we can afford to depend on modern constructs and the portability given to us by using Boost would mostly represent dead weight.
+Iterator based designs have their own merits, but they are also known to reduce the composability of algorithms. Furthermore, the context of heterogeneous programming brings a lot of points that make iterators much less interesting. For example, incrementing an iterator would have to return a new iterator with a different type, because the type of the new object it is pointing to in the sequence might be different. It also turns out that implementing most algorithms in terms of iterators leads to a worse compile-time performance, simply because the execution model of metaprogramming (using the compiler as an interpreter) is so different from the runtime execution model of C++ (a processor accessing contiguous memory).
+First, it gives much more wiggle room for the implementation to perform compile-time and runtime optimizations by using clever representations for specific containers. For example, a tuple containing homogeneous objects of type T could be implemented as an array of type T instead, which is more efficient at compile-time. Secondly, and most importantly, it turns out that knowing the type of a heterogeneous container is not as useful as you would think. Indeed, in the context of heterogeneous programming, the type of the object returned by a computation is usually part of the computation too. In other words, there is no way to know the type of the object returned by an algorithm without actually performing the algorithm. For example, consider the find_if algorithm:
If the predicate is satisfied for some element of the tuple, result will be equal to just(x). Otherwise, result will be equal to nothing. However, the nothingness of the result is known at compile-time, which requires just(x) and nothing to have different types. Now, say you wanted to explicitly write the type of the result:
In order to possess the knowledge of what some_type is, you would need to actually perform the algorithm, because some_type depends on whether the predicate is satisfied or not for some element in the container. In other words, if you were able to write the above, then you would already know what the result of the algorithm is and you would not need to perform the algorithm in the first place. In Boost.Fusion, this problem is addressed by having a separate result_of namespace, which contains a metafunction computing the result type of any algorithm given the types of the arguments passed to it. For example, the above example could be rewritten with Fusion as:
Notice that we're basically doing the computation twice; once in the result_of namespace and once in the normal fusion namespace, which is highly redundant. Before the days of auto and decltype, such techniques were necessary to perform heterogeneous computations. However, since the advent of modern C++, the need for explicit return types in the context of heterogeneous programming is largely obsolete, and knowing the actual type of containers is usually not that useful.
No, it isn't the name of my girlfriend! I just needed a short and good looking name that people would easily remember, and Hana came up. It also came to my attention that Hana means flower in Japanese, and one in Korean. Since Hana is pretty and it unifies type-level and heterogeneous programming under a single paradigm, the name appears to be quite well chosen in retrospect :-).
+Since Hana defines a lot of algorithms on tuples, a possible way to go would have been to simply use std::tuple and provide the algorithms only, instead of also providing our own tuple. The reason for providing our own tuple is principally performance. Indeed, all the std::tuple implementations tested so far have a very bad compile-time performance. Also, to get truly amazing compile-time performance, we need to take advantage of the tuple's internal representation in some algorithms, which requires defining our own. Finally, some sugar like operator[] could not be provided if we were using a std::tuple, since that operator must be defined as a member function.
When deciding upon a name X, I try to balance the following things (in no specific order):
X in C++?X in the rest of the programming world?X actually is, regardless of historical reasonsXXX, like name clashes or names reserved by the standardOf course, good naming is and will always be hard. Names are and will always be tainted by the author's own bias. Still, I try to choose names in a reasonable manner.
+Unlike naming, which is fairly subjective, the order of the parameters of a function is usually pretty straightforward to determine. Basically, the rule of thumb is "the container goes first". It has always been this way in Fusion and MPL, and this is intuitive for most C++ programmers. Also, in higher-order algorithms, I try to put the function parameter last, so that multi-line lambdas look nice:
+There are several different techniques we could have used to provide customization points in the library, and tag-dispatching was chosen. Why? First, I wanted a two-layer dispatching system because this allows functions from the first layer (the ones that are called by users) to actually be function objects, which allows passing them to higher-order algorithms. Using a dispatching system with two layers also allows adding some compile-time sanity checks to the first layer, which improves error messages.
+Now, tag-dispatching was chosen over other techniques with two layers for a couple of reasons. First, having to explicitly state how some tag is a model of a concept gives the responsibility of making sure that the semantic requirements of the concept are respected to the user. Secondly, when checking whether a type is a model of some concept, we basically check that some key functions are implemented. In particular, we check that the functions from the minimal complete definition of that concept are implemented. For example, Iterable<T> checks whether the is_empty, at and drop_front functions implemented for T. However, the only way to detect this without tag-dispatching is to basically check whether the following expressions are valid in a SFINAE-able context:
Unfortunately, this requires actually doing the algorithms, which might either trigger a hard compile-time error or hurt compile-time performance. Also, this requires picking an arbitrary index N to call at with: what if the Iterable is empty? With tag dispatching, we can just ask whether at_impl<T>, is_empty_impl<T> and drop_front_impl<T> are defined, and nothing happens until we actually call their nested ::apply function.
It would require either (1) padding the shortest sequences with an arbitrary object, or (2) padding the shortest sequences with an object provided by the user when calling zip_longest. Since there is no requirement that all the zipped sequences have elements of similar types, there is no way to provide a single consistent padding object in all cases. A tuple of padding objects should be provided, but I find it perhaps too complicated to be worth it for now. If you need this functionality, open a GitHub issue.
Since the C++ concept proposal maps concepts to boolean constexpr functions, it would make sense that Hana defines its concepts as such too, instead of as structs with a nested ::value. Indeed, this was the first choice, but it had to be revised because template functions have one limitation that makes them less flexible. Specifically, a template function can't be passed to a higher-order metafunction. In other words, it is not possible to write the following
This sort of code is very useful in some contexts, such as checking whether two types have a common embedding modeling a concept:
+With concepts as boolean constexpr functions, this can't be written generically. When concepts are just template structs, however, we can use template template parameters:
In C++, the border between compile-time and runtime is hazy, a fact that is even more true with the introduction of generalized constant expressions in C++14. However, being able to manipulate heterogeneous objects is all about understanding that border and then crossing it at one's will. The goal of this section is to set things straight with constexpr; to understand which problems it can solve and which ones it can't. This section covers advanced concepts about to constant expressions; only readers with a good understanding of constexpr should attempt to read this.
Let's start with a challenging question. Should the following code compile?
+The answer is no, and the error given by Clang goes like
+The explanation is that inside of f's body, t is not a constant expression, and hence it can't be used as the operand to a static_assert. The reason is that such a function simply can't be generated by the compiler. To understand the issue, consider what should happen when we instantiate the f template with a concrete type:
Clearly, the compiler can't generate f<int>'s code, which should trigger a static_assert if t != 1, because we haven't specified t yet. Even worse, the generated function should work on both constant and non-constant expressions:
Clearly, fptr's code can't be generated, because it would require being able to static_assert on a runtime value, which does not make sense. Furthermore, note that it does not matter whether you make the function constexpr or not; making f constexpr would only state that the result of f is a constant expression whenever its argument is a constant expression, but it still does not give you the ability to know whether you were called with a constant expression from f's body. In other words, what we would want is something like:
In this hypothetical scenario, the compiler would know that t is a constant expression from the body of f, and the static_assert could be made to work. However, constexpr parameters do not exist in the current language, and adding them would bring up very challenging design and implementation issues. The conclusion of this little experiment is that argument passing strips away constexpr-ness. What might be unclear by now are the consequences of this stripping, which are explained next.
The fact that an argument is not a constant expression means that we can't use it as a non-type template parameter, as an array bound, inside a static_assert or anything else that requires a constant expression. In addition, this means that the return type of a function can't depend on the value of an argument which is nothing new if you think about it:
In fact, the return type of a function may only depend on the types of its arguments, and constexpr can't change this fact. This is of utmost importance to us, because we're interested in manipulating heterogeneous objects, which eventually means returning objects with different types depending on the argument of the function. For example, a function might want to return an object of type T in one case and an object of type U in the other; from our analysis, we now know that these "cases" will have to depend on information encoded in the types of the arguments, not in their values.
To preserve constexpr-ness through argument passing, we have to encode the constexpr value into a type, and then pass a not-necessarily-constexpr object of that type to the function. The function, which must be a template, may then access the constexpr value encoded inside that type.
Let me ask a tricky question. Is the following code valid?
+The answer is yes, but the reason might not be obvious at first. What happens here is that we have a non-constexpr int n, and a constexpr function f taking a reference to its argument. The reason why most people think it shouldn't work is that n is not constexpr. However, we're not doing anything with n inside of f, so there is no actual reason why this shouldn't work! This is a bit like throwing inside of a constexpr function:
As long as the code path where throw appears is not executed, the result of the invocation can be a constant expression. Similarly, we can do whatever we want inside of f, as long as we don't execute a code path that requires accessing its argument n, which is not a constant expression:
The error given by Clang for the second invocation is
+Let's now step the game up a bit and consider a more subtle example. Is the following code valid?
+The only difference with our initial scenario is that f now takes its argument by value instead of by reference. However, this makes a world of difference. Indeed, we're now asking the compiler to make a copy of n and to pass this copy to f. However, n is not constexpr, so its value is only known at runtime. How could the compiler make a copy (at compile-time) of a variable whose value is only known at runtime? Of course, it can't. Indeed, the error message given by Clang is pretty explicit about what's happening:
This section presents a mini reimplementation of the MPL library. The goal is to be as backward compatible as possible with the MPL, while still using Hana under the hood. Only the "Algorithms" part of the MPL is implemented as a case study, but it should be possible to implement many (but not all) metafunctions of the MPL.
+Scroll down to the main function to see the tests. The tests are exactly the examples in the MPL documentation that were copy/pasted and then modified as little as possible to work with this reimplementation.
Defines boost::hana::detail::index_if.
+More...
+Classes | |
| struct | boost::hana::detail::index_if< Pred, Ts, typename > |
Returns the index of the first element of the pack<> that satisfies the predicate, or the size of the pack if there is no such element. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::detail::index_if.
Defines boost::hana::infix.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| constexpr auto | boost::hana::infix |
| Return an equivalent function that can also be applied in infix notation. More... | |
Defines boost::hana::infix.
Defines boost::hana::insert.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::insert.
Defines boost::hana::insert_range.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::insert_range.
Adapts std::integer_sequence for use with Hana.
+More...
+Classes | |
| struct | std::integer_sequence< T, v > |
Adaptation of std::integer_sequence for Hana. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Adapts std::integer_sequence for use with Hana.
Adapts Boost.MPL IntegralConstants for use with Hana. +More...
++Classes | |
| struct | boost::mpl::integral_c< T, v > |
| Adapter for IntegralConstants from the Boost.MPL. More... | |
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Adapts Boost.MPL IntegralConstants for use with Hana.
+Defines boost::hana::integral_constant.
+More...
Defines boost::hana::integral_constant.
Defines boost::hana::intersection.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::intersection.
Defines boost::hana::intersperse.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::intersperse.
Defines macros for commonly used type traits. +More...
+Defines macros for commonly used type traits.
+Defines boost::hana::is_disjoint.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::is_disjoint.
Defines boost::hana::is_empty.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::is_empty.
Defines boost::hana::is_subset.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
Defines boost::hana::is_subset.
Defines boost::hana::iterate.
+More...
+Namespaces | |
| boost | |
| boost::hana | |
| Namespace containing everything in the library. | |
+Variables | |
| template<std::size_t n> | |
| constexpr auto | boost::hana::iterate |
Applies another function n times to its argument. More... | |
Defines boost::hana::iterate.
| t |