hyperion::mpl::Pair#
- group Metaprogramming Pair Type
 Hyperion provides
mpl::Pairas a metaprogramming type for storing, communicating, working with, and operating on pairs of types or values.Example#
#include <hyperion/mpl/pair.h> using namespace hyperion::mpl; constexpr auto add_const = [](MetaPair auto pair) noexcept { return make_pair(pair.make_first().as_const(), pair.make_second().as_const()); }; constexpr auto pair = Pair<int, double>{}; constexpr auto constified = pair.apply(add_const); static_assert(constified == Pair<const int, const double>{});
Functions
- 
template<typename TLHSFirst, typename TLHSSecond, typename TRHSFirst, typename TRHSSecond>
bool operator==(const Pair<TLHSFirst, TLHSSecond> &lhs, const Pair<TRHSFirst, TRHSSecond> &rhs) noexcept# Equality comparison operator between two
Pairspecializations.Checks that
lhsandrhsboth represent the same metaprogramming types and values.Example#
constexpr auto first = Pair<int, Value<1, std::uint32_t>>{}; constexpr auto second = Pair<int, Value<1, std::uint64_t>>{}; static_assert(first == second);
- Template Parameters:
 - Parameters:
 - Returns:
 whether
lhsrepresents the same metaprogramming types and values asrhs
- 
template<typename TFirst, typename TSecond>
Pair<detail::convert_to_raw_t<TFirst>, detail::convert_to_raw_t<TSecond>> make_pair(TFirst &&first, TSecond &&second) noexcept# Constructs an
mpl::Pairrepresenting the types of the given arguments.If
TFirstorTSecondare metaprogramming types, first converts them to their raw type before storing in thePair. (e.g. if either arempl::Type<some_type>, the returned pair would bePair<some_type1, some_type2>, notPair<Type<some_type1>, Type<some_type2>>).This overload does not accept reference qualified parameters.
Requirements#
TFirstis not reference qualifiedTSecondis not reference qualified
Example#
constexpr auto pair = make_pair(decltype_<int>(), decltype_<double>()); static_assert(pair == Pair<int, double>{});
- 
template<typename TFirst, typename TSecond>
struct Pair# - #include <hyperion/mpl/pair.h>
Pairis Hyperion’s metaprogramming type for operating on pairs of types or values.Example#
#include <hyperion/mpl/pair.h> using namespace hyperion::mpl; constexpr auto add_const = [](MetaPair auto pair) noexcept { return make_pair(pair.make_first().as_const(), pair.make_second().as_const()); }; constexpr auto pair = Pair<int, double>{}; constexpr auto constified = pair.apply(add_const); static_assert(constified == Pair<const int, const double>{});
- Template Parameters:
 TFirst – The first type to store in the pair
TSecond – The second type to store in the pair
Public Types
Public Functions
- 
template<typename TDelay = first>
inline TDelay make_first() const noexcept# Returns an instance of
firstExample#
constexpr auto first = Pair<int, double>{}.make_first(); static_assert(first == decltype_<int>());
- Returns:
 an instance of
first
- 
template<typename TDelay = second>
inline TDelay make_second() const noexcept# Returns an instance of
secondExample#
constexpr auto second = Pair<int, double>{}.make_second(); static_assert(second == decltype_<double>());
- Returns:
 an instance of
second
- 
template<template<typename> typename TMetaFunction>
inline detail::convert_to_meta_t<TMetaFunction<Pair>> apply() const noexcept# Applies the template metafunction
TMetaFunctionto thisPair.Applies
TMetaFunctionto thisPair, and returns the result as a metaprogramming type (a specialization ofmpl::Type,mpl::Value, ormpl::Pair).Requirements#
Example#
template<typename TType> requires (!MetaPair<TType>) struct add_one_or_const { using type = std::conditional_t<MetaValue<TType>, decltype(TType{} + 1_value), decltype(decltype_<TType>().as_const())>; }; template<typename TPair> struct add_one_or_const_to_pair { using first = typename add_one_or_const<typename TPair::first>::type; using second = typename add_one_or_const<typename TPair::second>::type; }; static_assert(Pair<int, Value<1>>{}.apply<add_one_or_const_to_pair>() == Pair<const int, Value<2>>{});
- Template Parameters:
 TMetaFunction – The template metafunction to apply
- Returns:
 The result of applying
TMetaFunctionto thisPair, as a metaprogramming type
- 
template<template<typename> typename TMetaFunction>
inline auto apply() const noexcept# Applies the template metafunction
TMetaFunctionto the types represented in thisPair.Applies
TMetaFunctiontofirstandsecondindividually, returning the results together as a specialization ofPair. AppliesTMetaFunctionto each offirstandsecondas if bymake().template apply<TMetaFunction>(), wheremakeismake_firstormake_second, respectively.Requirements#
TMetaFunctionmust not be instantiatable with this specialization ofPair. I.E.TMetaFunction<Pair>must not be well-formed (this is most easily achievable by adding a requirement clause ofrequires (!MetaPair<TType>)to yourTMetaFunction, whereTTypeis the type parameter of the template).TMetaFunctionmust be applicable to bothfirstandsecond. I.E.,make().template apply<TMetaFunction>(), wheremakeismake_firstormake_second, respectively, must be well formed.
Example#
template<typename TType> requires (!MetaPair<TType>) struct add_one_or_const { using type = std::conditional_t<MetaValue<TType>, decltype(TType{} + 1_value), decltype(decltype_<TType>().as_const())>; }; static_assert(Pair<int, Value<1>>{}.apply<add_one_or_const>() == Pair<const int, Value<2>>{});
- Template Parameters:
 TMetaFunction – The template metafunction to apply
- Returns:
 The result of applying
TMetaFunctionto thisPair, as a metaprogramming type
- 
template<typename TFunction>
inline meta_result_t<TFunction, Pair> apply(TFunction &&func) const noexcept# Applies the metafunction
TFunctionto thisPair.Applies
TFunctionto thisPair, as if bystd::forward<TFunction>(func)(Pair{}), and returns the resulting metaprogramming type.Requirements#
TFunctionmust be aMetaFunctionOf<Pair>.
Example#
constexpr auto add_one_or_const = [](MetaPair auto pair) noexcept { constexpr auto apply_to_inner = [](auto inner) noexcept { if constexpr(MetaType<decltype(inner)>) { return inner.as_const(); } else if constexpr(MetaValue<decltype(inner)>) { return inner + 1_value; } }; return make_pair(pair.make_first().apply(apply_to_inner), pair.make_second().apply(apply_to_inner)); }; static_assert(Pair<int, Value<1>>{}.apply(add_one_or_const) == Pair<const int, Value<2>>{});
- Template Parameters:
 TFunction – The type of the metafunction to apply
- Parameters:
 func – The metafunction to apply
- Returns:
 The result of applying
TFunctionto thisPair
- 
template<typename TFunction>
inline Pair<meta_result_t<TFunction, first>, meta_result_t<TFunction, second>> apply(TFunction &&func) const noexcept# Applies the metafunction
TFunctionto the types represented in thisPair.Applies
TFunctiontofirstandsecondindividually, returning the results together as a specialization ofPair. AppliesTFunctionto each offirstandsecondas if bymake().apply(std::forward<TFunction>(func)), wheremakeismake_firstormake_second, respectively.Requirements#
TFunctionmust be aMetaFunctionOf<first>.TFunctionmust be aMetaFunctionOf<second>.TFunctionmust not be aMetaFunctionOf<Pair>.
Example#
constexpr auto add_one_or_const = [](auto val) noexcept requires (!MetaPair<decltype(val)>) { if constexpr(MetaType<decltype(val)>) { return val.as_const(); } else if constexpr(MetaValue<decltype(val)>) { return val + 1_value; } }; static_assert(Pair<int, Value<1>>{}.apply(add_one_or_const) == Pair<const int, Value<2>>{});
- Template Parameters:
 TFunction – The type of the metafunction to apply
- Parameters:
 func – The metafunction to apply
- Returns:
 The result of applying
TFunctionto the types represented in thisPair
- 
template<template<typename> typename TPredicate>
inline detail::convert_to_meta_t<TPredicate<Pair>> satisfies() const noexcept# Checks that this
Pairsatisfies the template metafunction predicate,TPredicate.Checks that this
PairsatisfiesTPredicateand returns the result as anmpl:Value<result, bool>.Requirements#
TPredicatemust be instantiatable with this specialization ofPair(i.e.TPredicate<Pair>must be well-formed).The specialization of
TMetaFunctionforPair,TMetaFunction<Pair>, must be aMetaValueThe value of the specialization of
TMetaFunctionforPair,TMetaFunction<Pair>::value, must be of type (possibly cv-ref qualified)bool
Example#
template<typename TType> requires (!MetaPair<TType>) struct is_one_or_const { static inline constexpr auto value = false; }; template<typename TType> requires MetaValue<TType> struct is_one_or_const<TType> { static inline constexpr auto value = TType::value == 1; }; template<typename TType> requires MetaType<TType> struct is_one_or_const<TType> { static inline constexpr auto value = std::is_const_v<typename TType::type>; }; template<typename TPair> struct is_one_or_const_in_pair { static inline constexpr auto value = is_one_or_const<typename TPair::first>::value && is_one_or_const<typename TPair::second>::value; }; static_assert(Pair<int, Value<1>>{}.satisfies<is_one_or_const_in_pair>());
- Template Parameters:
 TPredicate – The template metafunction predicate to validate
- Returns:
 whether this
PairsatisfiesTPredicate, as anmpl::Value
- 
template<template<typename> typename TPredicate>
inline auto satisfies() const noexcept# Checks that the types represented by this
Pairsatisfy the template metafunction predicate,TPredicate.Checks that
firstandsecondboth satisfyTPredicate, and returns the result as anmpl:Value<result, bool>. Checks thatfirstandsecondboth satisfyTPredicateas if bymake().template satisfies<TPredicate>()wheremakeismake_firstormake_second, respectively.Requirements#
TPredicatemust not be instantiatable with this specialization ofPair. I.E.,TPredicate<Pair>must not be well-formed (this is most easily achievable by adding a requirement clause ofrequires (!MetaPair<TType>)to yourTPredicate, whereTTypeis the type parameter of the template).TPredicatemust be a template metafunction predicate capable of being satisfied by bothfirstandsecond. I.E.,TMetaFunction<first>andTMetaFunction<second>must be well-formed.
Example#
template<typename TType> requires (!MetaPair<TType>) struct is_one_or_const { static inline constexpr auto value = false; }; template<typename TType> requires MetaValue<TType> struct is_one_or_const<TType> { static inline constexpr auto value = TType::value == 1; }; template<typename TType> requires MetaType<TType> struct is_one_or_const<TType> { static inline constexpr auto value = std::is_const_v<typename TType::type>; }; static_assert(Pair<int, Value<1>>{}.satisfies<is_one_or_const>());
- Template Parameters:
 TPredicate – The template metafunction predicate to validate
- Returns:
 whether this
PairsatisfiesTPredicate, as anmpl::Value
- 
template<typename TPredicate>
inline auto satisfies(TPredicate &&predicate) const noexcept# Checks that this
Pairsatisfies the metafunction predicate,predicate.Checks that this
Pairsatisfiespredicateand returns the result as anmpl:Value<result, bool>.If
predicateis aMetaPredicateOf<Pair>, invokespredicatewith thisPairspecialization and returns the result. Otherwise, checks iffirstandsecondseparately satisfypredicate, and returns the boolean and of those results.Example#
constexpr auto is_one_or_const = [](auto value) noexcept { if constexpr(MetaType<decltype(value)>) { return value.is_const(); } else if constexpr(MetaValue<decltype(value)>) { return Value<decltype(value)::value == 1, bool>{}; } }; static_assert(Pair<int, Value<1>>{}.satisfies(is_one_or_const));
- Template Parameters:
 TPredicate – The metafunction predicate to validate
- Returns:
 whether this
Pairsatisfiespredicate, as anmpl::Value
- 
template<typename TFunction>
inline std::invoke_result_t<TFunction, first, second> unwrap(TFunction &&func) const noexcept# Unwraps this
Pairintofirstandsecond, and invokesfuncwith them.Decomposes
thisinto its constituentfirstandsecondmetaprogramming elements and invokesfunc, passingfirstandsecondas the invocation arguments, returning the result of the invocation.Requirements#
funcmust be invocable withfirst, second
Example#
constexpr auto sum = [](MetaValue auto lhs, MetaValue auto rhs) noexcept { return lhs + rhs; }; static_assert(Pair<Value<1>, Value<2>>{}.unpack(sum) == 3_value);
- Template Parameters:
 TFunction – the type of the function to invoke with
firstandsecondas arguments- Parameters:
 func – the function to invoke with
firstandsecondas arguments- Returns:
 The result of invoking
funcwithfirstandsecondas arguments
- 
template<std::size_t TIndex>
inline auto get() const noexcept# Returns the metaprogramming type at
TIndexof thisPairIf
TIndexis0, returnsfirst. IfTIndexis1, returnssecond.Requirements#
TIndexmust be0, or1
Example#
constexpr auto first = Pair<int, double>{}.template get<0>(); static_assert(first == decltype_<int>());
- Template Parameters:
 TIndex – The index of the type to get
- Returns:
 The metaprogramming type at
TIndexof thisPair
Note
This, combined with specializations of
std::tuple_elementandstd::tuple_sizeenable structured binding destructuring of this pair intofirstandsecondindividually, as in:// we can't use structured bindings outside of function-scope, so we wrap our example // in a `constexpr` function constexpr auto example() { auto [first, second] = Pair<int, double>{}; return first == decltype_<int>() && second == decltype_<double>(); } static_assert(example());
- 
template<std::size_t TIndex>
inline auto get() noexcept# Returns the metaprogramming type at
TIndexof thisPairIf
TIndexis0, returnsfirst. IfTIndexis1, returnssecond.Requirements#
TIndexmust be0, or1
Example#
constexpr auto first = Pair<int, double>{}.template get<0>(); static_assert(first == decltype_<int>());
- Template Parameters:
 TIndex – The index of the type to get
- Returns:
 The metaprogramming type at
TIndexof thisPair
Note
This, combined with specializations of
std::tuple_elementandstd::tuple_sizeenable structured binding destructuring of this pair intofirstandsecondindividually, as in:// we can't use structured bindings outside of function-scope, so we wrap our example // in a `constexpr` function constexpr auto example() { auto [first, second] = Pair<int, double>{}; return first == decltype_<int>() && second == decltype_<double>(); } static_assert(example());
 
- 
template<typename TLHSFirst, typename TLHSSecond, typename TRHSFirst, typename TRHSSecond>