hyperion::mpl::List#
- group Metaprogramming List Type
Hyperion provides
mpl::Listas a metaprogramming type for storing, communicating, working with, and operating on lists of types or values.Example#
#include <hyperion/mpl/list.h> #include <hyperion/mpl/metapredicates.h> using namespace hyperion::mpl; constexpr auto add_const = [](MetaType auto type) noexcept { return type.add_const(); }; constexpr auto list = List<int, double, float>{}; constexpr auto zipped = list.zip(List<u32, usize, i32>{}); constexpr auto constified = zipped.apply(add_const); static_assert(constified == List<Pair<const int, const u32>, Pair<const double, const usize>, Pair<const float, const i32>>{}); static_assert(constified.all_of(is_const));
Exposition-Only Types#
struct as_meta: Exposition-only template metafunction that converts a type,TType, to the corresponding metaprogramming type, exposed via the memberusingaliastype. MapsTTypein the following manner:If
TTypeis aMetaType, maps toType<typename as_meta<typename TType::type>::type>, elseIf
TTypeis aMetaValue, maps toValue<TType::value>, elseIf
TTypeis aMetaPair, maps to, elsePair<typename as_meta<typename TType::first>::type, typename as_meta<typename TType::second>::type>
Maps to
Type<TType>
struct as_raw: Exposition-only template metafunction that converts a type,TType, to the corresponding raw type, exposed via the memberusingaliastype. MapsTTypein the following manner:If
TTypeis aMetaType, maps totypename as_raw<typename TType::type>::type, elseIf
TTypeis aMetaValue, maps toValue<TType::value>, elseIf
TTypeis aMetaPair, maps to, elsePair<typename as_raw<typename TType::first>::type, typename as_raw<typename TType::second>::type>
Maps to
TType
Functions
-
template<typename ...TLHTypes, typename ...TRHTypes>
auto operator==(const List<TLHTypes...> &lhs, const List<TRHTypes...> &rhs) noexcept# Equality comparison operator for
ListChecks that each element of
lhsis equal to the corresponding (by index) element ofrhs, as if byequal_to(lhs.at(index))(rhs.at(index)).Example#
static_assert(List<int, double, float>{} == List<int, double, float>{}); static_assert(List<Value<1, i32>, double, float>{} == List<Value<1, u32>, double, float>{});
-
template<typename ...TLHTypes, typename ...TRHTypes>
auto operator!=(const List<TLHTypes...> &lhs, const List<TRHTypes...> &rhs) noexcept# Inequality comparison operator for
ListChecks that any element of
lhsis not equal to the corresponding (by index) element ofrhs, as if bynot_equal_to(lhs.at(index))(rhs.at(index)).Example#
static_assert(List<int, double, float>{} != List<float, double, float>{}); static_assert(List<Value<1, i32>, double, float>{} != List<Value<2, u32>, double, float>{});
-
template<typename ...TTypes>
auto make_list(TTypes&&... types) noexcept# Creates an
mpl::Listrepresenting the types of the given arguments,typesExample#
static_assert(make_list(1, 1.0, 1_usize, 1_value) == List<int, double, usize, Value<1_usize>>{});
-
template<typename ...TTypes>
auto make_list() noexcept# Creates an
mpl::Listrepresenting the specified types.Example#
static_assert(make_list<int, double, usize, Value<1>, Type<int>>() == List<int, double, usize, Value<1>, int>{});
-
template<typename ...TTypes>
auto operator|(List<TTypes...> list, auto range_object)# Pipeline operator for
mpl::Lists. Provides support for pipingmpl::Lists intostd::rangesalgorithms and views.Example#
constexpr auto list = List<int, const double, float>{}; constexpr auto ranged = list | std::ranges::views::filter([](auto type) { return not type.is_const(); }) | std::ranges::views::transform([](auto type) { return type.as_lvalue_reference().as_volatile(); }) | std::ranges::views::reverse | std::ranges::views::drop(1_value); static_assert(ranged == List<volatile int&>{});
- Template Parameters:
TTypes – the types represented in the
List- Parameters:
list – the list to pipe into a
std::rangesalgorithm or viewrange_object – the
std::rangesalgorithm or view to pipe into
- Returns:
the result of the pipeline, up to this point
-
struct not_found_tag#
- #include <hyperion/mpl/list.h>
Tag type indicating that a searching operation in an
mpl::Listcould not find a/the desired result.
-
template<typename ...TTypes>
struct List# - #include <hyperion/mpl/list.h>
Listis a metaprogramming type for storing, communicating, working with, and operating on lists of types or values.Example#
#include <hyperion/mpl/list.h> #include <hyperion/mpl/metapredicates.h> using namespace hyperion::mpl; constexpr auto add_const = [](MetaType auto type) noexcept { return type.add_const(); }; constexpr auto const_zipped = List<int, double, float>{} .zip(List<u32, usize, i32>{}) .apply(add_const); static_assert(const_zipped == List<Pair<const int, const u32>, Pair<const double, const usize>, Pair<const float, const i32>>{}); static_assert(const_zipped.all_of(is_const)); constexpr auto nums = List<Value<1>, Value<2>, Value<3>>{}; static_assert(nums.accumulate(0_value) == 6_value);
- Template Parameters:
TTypes – The types to represent in the list
Public Functions
-
template<template<typename> typename TPredicate>
inline std::enable_if_t<TypeMetaFunction<TPredicate> && MetaValue<TPredicate<List>> && std::same_as<std::remove_const_t<decltype(TPredicate<List>::value)>, bool>, Value<TPredicate<List>::value, bool>> satisfies() const noexcept# Checks to see if this
Listspecialization satisfies the given template metafunction predicate,TPredicateRequirements#
TPredicatemust be aListMetaFunctionIt must be a template taking a single value parameter,
It must have a
static constexprmember variable,value, or a using alias type,type
The type of the value of
TPredicate,TPredicate<List>::value, must be (possibly cv-ref qualified)bool)
Example#
template<typename TList> struct are_integral { static inline constexpr auto value = TList{}.all_of( [](MetaType auto type) { return type.template satisfies<std::is_integral>(); }); }; // `integral` is `Value<true, bool>` constexpr auto integral = List<i32, u16>{}.satisfies<are_integral>(); // `not_integral` is `Value<false, bool>` constexpr auto not_integral = List<float, double>{}.satisfies<are_integral>(); static_assert(was_const); static_assert(not not_const);
-
template<typename TPredicate>
inline auto satisfies(TPredicate &&predicate) const noexcept# Checks to see if this
Listspecialization satisfies the given metafunction predicate.Requirements#
If
predicateis invocable withList{}:The value returned by invoking
predicatewithList{}must either be aMetaValue, or aTypespecialization representing aMetaValue.Using
TValueto represent thatMetaValuetype, the type of the value ofTValue, that isdecltype(TValue::value), must be of type (possibly cv-ref qualified)bool
If the above conditions on the return value of
predicateare not met, the program is ill-formed
If
predicateis not invocable withList{}, returnsValue<false>
Example#
static constexpr auto are_integral = [](MetaList auto list) { return list.all_of( [](MetaType auto type) { return type.template satisfies<std::is_integral>(); }); }; constexpr auto integral = List<List<u16>, List<i32>>{}.satisfies(are_integral); constexpr auto not_integral = List<List<float>, List<double>>{}.satisfies(are_integral); static_assert(integral); static_assert(not not_integral);
- Template Parameters:
TPredicate – The type of the metafunction predicate to check with
- Parameters:
predicate – The metafunction predicate to check with, as a
Valuespecialization
-
template<typename TFunction>
inline auto apply(TFunction &&func) const noexcept# Applies the metafunction
functo the elements of thisList, returning the result as a newListspecialization.Using the exposition-only template metafunctions
as_metaandas_raw(see the corresponding section in the Metaprogramming List Type module-level documentation), appliesfuncto each element,TElement, of thisListas if bytypename as_raw<decltype(typename as_meta<TElement>::type{}.apply(func))>::type.Requirements#
funcmust be a metafunction invocable with the corresponding metaprogramming type of each element in thisList. That is,funcmust be aMetaFunctionOf<TFunction, typename as_meta<TElement>::type>for each element,TElement, of thisListOR,
funcmust be a metafunction appliable to the corresponding metaprogramming type of each element in thisList. That is,typename as_meta<TElement>::type{}.apply(func)must be well formed for each element,TElement, of thisList
Example#
constexpr auto add_const = [](MetaType auto type) noexcept { return type.add_const(); }; static_assert(List<int, double>{}.apply(add_const) == List<const int, const double>{});
-
template<typename TVisitor>
inline void for_each(TVisitor &&vis) const noexcept# Invokes the function
viswith each element of thisList.This is the canonical way to iterate through the elements of a
List.Using the exposition-only template metafunction
as_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), appliesvisto each element,TElement, of thisListas if byvis(typename as_meta<TElement>::type{}).Requirements#
Example#
constexpr auto example = List<Value<1>, int, float, double, int>{}; constexpr auto count_if = [](auto list, auto predicate) noexcept { auto num_satisfied = 0; list.for_each([&num_satisfied, predicate](auto element) { if(element.satisfies(predicate)) { num_satisfied++; } }); return num_satisfied; }; constexpr auto num_ints = count_if(example, equal_to(decltype_<int>())); static_assert(num_ints == 2);
-
template<typename TVisitor, MetaValue TCount>
inline void for_each_n(TVisitor &&vis, TCount count) const noexcept# Invokes the function
viswith the firstcountelements of thisList.This is the canonical way to iterate through a subset of the elements of a
List.Using the exposition-only template metafunction
as_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), appliesvisto each element,TElement, of thisListas if byvis(typename as_meta<TElement>::type{}).Requirements#
vismust be invocable with the corresponding metaprogramming type for each element of thisList. This is, for each element,TElement,std::invocable<TVisitor, typename as_meta<TElement>::type>must be true.The invoke result of
visfor each element of thisListmust bevoid.countmust be less than or equal to the number of elements of thisList
Example#
constexpr auto example = List<Value<1>, int, float, double, int>{}; constexpr auto count_if_in_first_half = [](auto list, auto predicate) noexcept { auto num_satisfied = 0; list.for_each_n([&num_satisfied, predicate](auto element) { if(element.satisfies(predicate)) { num_satisfied++; } }, list.size() / 2_value); return num_satisfied; }; constexpr auto num_ints = count_if_in_first_half(example, equal_to(decltype_<int>())); static_assert(num_ints == 1);
-
inline auto accumulate(MetaValue auto state) const noexcept#
Computes the arithmetic sum of
stateand the elements of thisList.Requirements#
Example#
static_assert(List<Value<1>, Value<2>, Value<3>>{}.accumulate(4_value) == 10);
-
template<typename TDelay = List<as_meta<TTypes>...>>
inline auto accumulate(auto state, auto &&accumulator) const noexcept# Computes the accumulation of
stateand the elements of thisList.Using the exposition-only template metafunction
as_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), andTElement_Nto represent the type of each element in thisList, uses the accumulation operationaccumulator, performs the accumulation of the elements of thisList, in order, by first invokingaccumulatorwithas_meta<decltype(state)>{}, as_meta<TElement_0>{}, then continues to callaccumulatorfor each successiveTElement, using the result of the previous invocation as thestateparameter for the next invocation in the sequence.Requirements#
Using
TElement_Nto represent the type of each element in thisListandTStateto represent bothdecltype(state)and the (possibly different) type(s) of the return value of each possible invocation ofaccumulator,accumulatormust be a callable taking two parameters, separately invocable with parameters of typesas_meta<TState_N>, as_meta<TElement_N>, for each of allTElements andTStates. That is, the recursive call chainmust be well-formed.accumulator( accumulator( ...( accumulator(as_meta<decltype(state)>{}, as_meta<TElement_0>{}), as_meta<TElement_1>{}), ...), as_meta<TElement_N-1>{})
Example#
static_assert(List<int, double, float, int>{} .accumulate(0_value, [](auto state, auto element) { // increment state if `element` is a `MetaType` representing `int` if constexpr(MetaType<decltype(element)>) { if constexpr(decltype(element){} == decltype_<int>()) { return state + 1_value; } else { return state; } } else { return state; } }) == 2);
- Parameters:
state – the initial state to begin the accumulation with
accumulator – the callable to perform the accumulation operation
- Returns:
the accumulation of
stateand the elements of thisList, according toaccumulator
-
template<typename TPredicate>
inline auto find_if(TPredicate &&predicate) const noexcept# Returns the first element of this
Listthat satisfies the metafunction predicatepredicate.Using the exposition-only template metafunction
as_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), checks each element,TElement, of thisListto see whether it satisfiespredicate, as if bytypename as_meta<TElement>::type{}.satisfies(predicate), and if satisfied, returns that element.If no element satisfying
predicateis found, returnsType<not_found_tag>Requirements#
predicatemust be a metapredicate invocable with the corresponding metaprogramming type of each element in thisList. That is,funcmust be aMetaPredicateOf<TFunction, typename as_meta<TElement>::type>for each element,TElement, of thisListOR,
predicatemust be a metapredicate satisfiable with the corresponding metaprogramming type of each element in thisList. That is,typename as_meta<TElement>::type{}.satisfy(predicate)must be well formed for each element,TElement, of thisList
Example#
static_assert(List<int, const double, float>{}.find_if(is_const) == decltype_<const double>()); static_assert(List<int, const double, float>{}.find_if(is_volatile) == decltype_<not_found_tag>()); static_assert(List<Value<1>, Value<2>, Value<3>>{}.find_if(is_const) == decltype_<not_found_tag>());
- Template Parameters:
TPredicate – The type of the metapredicate to use for searcch
- Parameters:
predicate – The metapredicate to use for search
- Returns:
the first element satisfying
predicate, orType<not_found_tag>if no element satisfiespredicate
-
inline auto find(auto value) const noexcept#
Returns the first element of this
Listthat is equal tovalue.If no element equal to
valueis found, returnsType<not_found_tag>Example#
static_assert(List<int, const double, float>{}.find(decltype_<const double>()) == decltype_<const double>()); static_assert(List<int, const double, float>{}.find(decltype_<usize>()) == decltype_<not_found_tag>()); static_assert(List<int, const double, float>{}.find(1_value) == decltype_<not_found_tag>()); static_assert(List<int, Value<1>, const double, float>{}.find(1_value) == 1); static_assert(List<Value<1>, Value<2>, Value<3>>{}.find(4_value) == decltype_<not_found_tag>());
- Parameters:
value – The metaprogramming value to search for
- Returns:
the first element equal to
value, orType<not_found_tag>if no element equalsvalue
-
template<typename TPredicate>
inline auto count_if(TPredicate &&predicate) const noexcept# Returns the number of elements of this
Listthat satisfy the metafunction predicatepredicate, as aValuespecialization.Using the exposition-only template metafunction
as_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), checks each element,TElement, of thisListto see whether it satisfiespredicate, as if bytypename as_meta<TElement>::type{}.satisfies(predicate), and if satisfied, increments the internal count.Requirements#
predicatemust be a metapredicate invocable with the corresponding metaprogramming type of each element in thisList. That is,funcmust be aMetaPredicateOf<TFunction, typename as_meta<TElement>::type>for each element,TElement, of thisListOR,
predicatemust be a metapredicate satisfiable with the corresponding metaprogramming type of each element in thisList. That is,typename as_meta<TElement>::type{}.satisfy(predicate)must be well formed for each element,TElement, of thisList
Example#
static_assert(List<int, const double, float>{}.count_if(is_const) == 1_value); static_assert(List<int, const double, float>{}.count_if(is_volatile) == 0_value); static_assert(List<Value<1>, Value<2>, Value<3>>{}.count_if(is_const) == 0_value);
- Template Parameters:
TPredicate – The type of the metapredicate to use
- Parameters:
predicate – The metapredicate to use
- Returns:
the number of elements satisfying
predicate
-
inline auto count(auto value) const noexcept#
Returns the number of elements of this
Listthat are equal tovalue, as aValuespecialization.Example#
static_assert(List<int, const double, float>{}.count(decltype_<const double>()) == 1); static_assert(List<int, const double, float>{}.count(decltype_<usize>()) == 0); static_assert(List<int, const double, float, int>{}.count(decltype_<int>()) == 2); static_assert(List<int, const double, float>{}.count(1_value) == 0); static_assert(List<int, Value<1>, const double, float>{}.count(1_value) == 1); static_assert(List<Value<1>, Value<2>, Value<3>>{}.count(4_value) == 0);
-
inline auto contains(auto value) const noexcept#
Returns whether this
Listcontains an element equal tovalue, as aValuespecialization.Example#
static_assert(List<int, const double, float>{}.contains(decltype_<const double>())); static_assert(not List<int, const double, float>{}.contains(decltype_<usize>())); static_assert(not List<int, const double, float>{}.contains(1_value)); static_assert(List<int, Value<1>, const double, float>{}.contains(1_value)); static_assert(not List<Value<1>, Value<2>, Value<3>>{}.contains(4_value));
-
template<typename TPredicate>
inline auto all_of(TPredicate &&predicate) const noexcept# Returns whether all elements of this
Listsatisfy the metafunction predicatepredicate, as aValuespecialization.Using the exposition-only template metafunction
as_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), checks each element,TElement, of thisListto see whether it satisfiespredicate, as if bytypename as_meta<TElement>::type{}.satisfies(predicate).Requirements#
predicatemust be a metapredicate invocable with the corresponding metaprogramming type of each element in thisList. That is,funcmust be aMetaPredicateOf<TFunction, typename as_meta<TElement>::type>for each element,TElement, of thisListOR,
predicatemust be a metapredicate satisfiable with the corresponding metaprogramming type of each element in thisList. That is,typename as_meta<TElement>::type{}.satisfy(predicate)must be well formed for each element,TElement, of thisList
Example#
static_assert(List<const int, const double, const float>{}.all_of(is_const)); static_assert(not List<int, const double, float>{}.all_of(is_const)); static_assert(not List<Value<1>, Value<2>, Value<3>>{}.all_of(is_const));
- Template Parameters:
TPredicate – The type of the metapredicate to use
- Parameters:
predicate – The metapredicate to use
- Returns:
whether all elements satisfy
predicate
-
template<typename TPredicate>
inline auto any_of(TPredicate &&predicate) const noexcept# Returns whether any elements of this
Listsatisfy the metafunction predicatepredicate, as aValuespecialization.Using the exposition-only template metafunction
as_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), checks each element,TElement, of thisListto see whether it satisfiespredicate, as if bytypename as_meta<TElement>::type{}.satisfies(predicate).Requirements#
predicatemust be a metapredicate invocable with the corresponding metaprogramming type of each element in thisList. That is,funcmust be aMetaPredicateOf<TFunction, typename as_meta<TElement>::type>for each element,TElement, of thisListOR,
predicatemust be a metapredicate satisfiable with the corresponding metaprogramming type of each element in thisList. That is,typename as_meta<TElement>::type{}.satisfy(predicate)must be well formed for each element,TElement, of thisList
Example#
static_assert(List<const int, const double, const float>{}.any_of(is_const)); static_assert(List<int, const double, float>{}.any_of(is_const)); static_assert(not List<int, double, float>{}.any_of(is_const)); static_assert(not List<Value<1>, Value<2>, Value<3>>{}.all_of(is_const));
- Template Parameters:
TPredicate – The type of the metapredicate to use
- Parameters:
predicate – The metapredicate to use
- Returns:
whether any elements satisfy
predicate
-
template<typename TPredicate>
inline auto none_of(TPredicate &&predicate) const noexcept# Returns whether zero elements of this
Listsatisfy the metafunction predicatepredicate, as aValuespecialization.Using the exposition-only template metafunction
as_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), checks each element,TElement, of thisListto see whether it satisfiespredicate, as if bytypename as_meta<TElement>::type{}.satisfies(predicate).Requirements#
predicatemust be a metapredicate invocable with the corresponding metaprogramming type of each element in thisList. That is,funcmust be aMetaPredicateOf<TFunction, typename as_meta<TElement>::type>for each element,TElement, of thisListOR,
predicatemust be a metapredicate satisfiable with the corresponding metaprogramming type of each element in thisList. That is,typename as_meta<TElement>::type{}.satisfy(predicate)must be well formed for each element,TElement, of thisList
Example#
static_assert(not List<const int, const double, const float>{}.none_of(is_const)); static_assert(not List<int, const double, float>{}.none_of(is_const)); static_assert(List<int, double, float>{}.none_of(is_const)); static_assert(List<Value<1>, Value<2>, Value<3>>{}.none_of(is_const));
- Template Parameters:
TPredicate – The type of the metapredicate to use
- Parameters:
predicate – The metapredicate to use
- Returns:
whether zero elements satisfy
predicate
-
template<typename TPredicate>
inline auto index_if(TPredicate &&predicate) const noexcept# Returns the index of the first element satisfying
predicate, as aValuespecialization orValue<sizeof...(TTypes)>if no element satisfiespredicate.Using the exposition-only template metafunction
as_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), checks each element,TElement, of thisListto see whether it satisfiespredicate, as if bytypename as_meta<TElement>::type{}.satisfies(predicate), and if satisfied, returns the index of that element.Requirements#
predicatemust be a metapredicate invocable with the corresponding metaprogramming type of each element in thisList. That is,funcmust be aMetaPredicateOf<TFunction, typename as_meta<TElement>::type>for each element,TElement, of thisListOR,
predicatemust be a metapredicate satisfiable with the corresponding metaprogramming type of each element in thisList. That is,typename as_meta<TElement>::type{}.satisfy(predicate)must be well formed for each element,TElement, of thisList
Example#
static_assert(List<int, const double, float>{}.index_if(is_const) == 1_value); static_assert(List<int, double, const float>{}.index_if(is_const) == 2_value); static_assert(List<int, double, float>{}.index_if(is_const) == 3_value); static_assert(List<Value<1>, Value<2>, Value<3>>{}.index_if(is_const) == 3_value);
- Template Parameters:
TPredicate – The type of the metapredicate to use
- Parameters:
predicate – The metapredicate to use
- Returns:
the index of the first element to satisfy
predicate, orsizeof...(TTypes)if no element satisfiespredicate
-
inline auto index_of(auto value) const noexcept#
Returns the index of the first element of this
Listthat is equal tovalue, as aValuespecialization.If no element equal to
valueis found, returnsValue<sizeof...(TTypes)>Example#
static_assert(List<int, const double, float>{}.index_of(decltype_<const double>()) == 1); static_assert(List<int, const double, float>{}.index_of(decltype_<usize>()) == 3); static_assert(List<int, const double, float>{}.index_of(1_value) == 3); static_assert(List<int, const double, float, int>{}.index_of(decltype_<int>()) == 0); static_assert(List<int, Value<1>, const double, float>{}.index_of(1_value) == 1); static_assert(List<Value<1>, Value<2>, Value<3>>{}.index_of(4_value) == 3);
- Parameters:
value – The metaprogramming value to search for
- Returns:
the index of the first element equal to
value, orValue<sizeof...(TTypes)>if no element equalsvalue
-
template<typename TPredicate>
inline auto filter(TPredicate &&predicate) const noexcept# Returns a
Listcontaining only the elements of thisListthat satisfypredicate.Using the exposition-only template metafunction
as_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), checks each element,TElement, of thisListto see whether it satisfiespredicate, as if bytypename as_meta<TElement>::type{}.satisfies(predicate), and if satisfied, that element is included in the returnedList.Relative ordering of elements is maintained in the returned
List.Requirements#
predicatemust be a metapredicate invocable with the corresponding metaprogramming type of each element in thisList. That is,funcmust be aMetaPredicateOf<TFunction, typename as_meta<TElement>::type>for each element,TElement, of thisListOR,
predicatemust be a metapredicate satisfiable with the corresponding metaprogramming type of each element in thisList. That is,typename as_meta<TElement>::type{}.satisfy(predicate)must be well formed for each element,TElement, of thisList
Example#
constexpr auto is_value = [](MetaValue auto val) noexcept { return Value<true>{}; }; static_assert(List<int, const double, float>{}.filter(is_const) == List<const double>{}); static_assert(List<int, double, float>{}.filter(is_const) == List<>{}); static_assert(List<int, double, const float>{}.filter(is_const) == List<const float>{}); static_assert(List<int, Value<1>, double, Value<2>, float>{}.filter(is_value) == List<Value<1>, Value<2>>{});
-
template<typename TPredicate>
inline auto remove_if(TPredicate &&predicate) const noexcept# Returns a copy of this
List, but with all elements that satisfypredicateremoved.Using the exposition-only template metafunction
as_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), checks each element,TElement, of thisListto see whether it satisfiespredicate, as if bytypename as_meta<TElement>::type{}.satisfies(predicate), and if satisfied, that element is not included in the returnedList.Relative ordering of elements is maintained in the returned
List.Requirements#
predicatemust be a metapredicate invocable with the corresponding metaprogramming type of each element in thisList. That is,funcmust be aMetaPredicateOf<TFunction, typename as_meta<TElement>::type>for each element,TElement, of thisListOR,
predicatemust be a metapredicate satisfiable with the corresponding metaprogramming type of each element in thisList. That is,typename as_meta<TElement>::type{}.satisfy(predicate)must be well formed for each element,TElement, of thisList
Example#
constexpr auto is_value = [](MetaValue auto val) noexcept { return Value<true>{}; }; static_assert(List<int, const double, float>{}.remove_if(is_const) == List<int, float>{}); static_assert(List<int, double, float>{}.remove_if(is_const) == List<int, double, float>{}); static_assert(List<int, double, const float>{}.remove_if(is_const) == List<int, double>{}); static_assert(List<int, Value<1>, double, Value<2>, float>{}.remove_if(is_value) == List<int, double, float>{});
- Template Parameters:
TPredicate – The type of the metapredicate to use
- Parameters:
predicate – The metapredicate to use
- Returns:
a copy of this
List, but with all elements that satisfypredicateremoved
-
inline auto remove(auto value) const noexcept#
Returns a copy of this
List, but with all elements that are equal tovalueremoved.Using the exposition-only template metafunction
as_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), checks each element,TElement, of thisListto see whether it is equal tovalue, as if bytypename as_meta<TElement>::type{}.satisfies(equal_to(value)), and if equal, that element is not included in the returnedList.Relative ordering of elements is maintained in the returned
List.Requirements#
predicatemust be a metapredicate invocable with the corresponding metaprogramming type of each element in thisList. That is,funcmust be aMetaPredicateOf<TFunction, typename as_meta<TElement>::type>for each element,TElement, of thisListOR,
predicatemust be a metapredicate satisfiable with the corresponding metaprogramming type of each element in thisList. That is,typename as_meta<TElement>::type{}.satisfy(predicate)must be well formed for each element,TElement, of thisList
Example#
static_assert(List<int, const double, float>{}.remove(decltype_<const double>()) == List<int, float>{}); static_assert(List<int, double, float>{}.remove(decltype_<u32>()) == List<int, double, float>{}); static_assert(List<int, double, const float>{}.remove(decltype_<const float>()) == List<int, double>{}); static_assert(List<int, Value<1>, double, Value<2>, float>{}.remove(1_value) == List<int, double, Value<2>, float>{});
- Template Parameters:
TPredicate – The type of the metapredicate to use
- Parameters:
predicate – The metapredicate to use
- Returns:
a copy of this
List, but with all elements that are equal tovalueremoved
-
template<template<typename...> typename TList, typename ...TValues>
inline auto sift(TList<TValues...> list) const noexcept# Returns a
Listcontaining the elements of thisListoccurring at the indices specified inlist.Ordering of elements in the returned list follows ordering of indices specified in
list.Requirements#
Example#
constexpr auto sifter = List<Value<1>, Value<2>>{}; static_assert(List<int, const double, float>{}.sift(sifter) == List<const double, float>{}); static_assert(List<int, double, float>{}.sift(sifter) == List<double, float>{}); static_assert(List<int, Value<1>, double, Value<2>, float>{}.sift(sifter) == List<Value<1>, double>{});
- Template Parameters:
TList – The metaprogramming list class template
TValues – The metaprogramming value types stored in
list
- Parameters:
list – The metaprogramming list containing the indices of the elements of this
Listto get- Returns:
a
Listcontaining the elements of thisListoccurring at the indices specified inlist
-
template<typename TFunction>
inline std::invoke_result_t<TFunction, as_meta<TTypes>...> unwrap(TFunction &&func) const noexcept# Converts the elements of this list into a parameter pack, and invokes
funcwith that pack, returning the result of the invocation.Requirements#
funcmust be invocable with the elements of thisListas a parameter pack. That is, using the exposition-only template metafunctionas_meta(see the corresponding section in the Metaprogramming List Type module-level documentation),std::invoke(std::forward<TFunction>(func), typename as_meta<TTypes>::type{}...)must be well-formed
Example#
constexpr auto sum = [](MetaValue auto... values) noexcept { return (values + ...); }; static_assert(List<Value<1>, Value<2>, Value<3>>{}.unwrap(sum) == 6);
-
template<usize TIndex>
inline auto at() const noexcept# Returns the element of this
Listat indexTIndex.Given type,
type, being the element at indexTIndexof thisList, and using the exposition-only template metafunctionas_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), returns the element at indexTIndex, converted to the correspondingmplmetaprogramming type, as if byreturn typename as_meta<type>::type{};Requirements#
TIndexmust be less than the size of thisList
Example#
static_assert(List<int, double, float>{}.at<0>() == decltype_<int>()); static_assert(List<int, double, float>{}.at<1>() == decltype_<double>()); static_assert(List<int, double, float>{}.at<2>() == decltype_<float>());
- Template Parameters:
TIndex – the index of the element to access
- Returns:
the element at index
TIndex
-
inline auto at(MetaValue auto index) const noexcept#
Returns the element of this
Listat index,index.Given type,
type, being the element at index,index, of thisList, and using the exposition-only template metafunctionas_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), returns the element atindex, converted to the correspondingmplmetaprogramming type, as if byreturn typename as_meta<type>::type{};Requirements#
indexmust be less than the size of thisList
Example#
static_assert(List<int, double, float>{}.at(0_value) == decltype_<int>()); static_assert(List<int, double, float>{}.at(1_value) == decltype_<double>()); static_assert(List<int, double, float>{}.at(2_value) == decltype_<float>());
- Parameters:
index – the index of the element to access
- Returns:
the element at index
TIndex
-
inline auto front() const noexcept#
Returns the first element of this
ListGiven type,
type, being the first element of thisList, and using the exposition-only template metafunctionas_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), returns the first element, converted to the correspondingmplmetaprogramming type, as if byreturn typename as_meta<type>::type{};Example#
static_assert(List<int, double, float>{}.front() == decltype_<int>()); static_assert(List<double, int, float>{}.front() == decltype_<double>()); static_assert(List<float, double, int>{}.front() == decltype_<float>());
- Returns:
the first element of this
List
-
inline auto back() const noexcept#
Returns the last element of this
ListGiven type,
type, being the last element of thisList, and using the exposition-only template metafunctionas_meta(see the corresponding section in the Metaprogramming List Type module-level documentation), returns the last element, converted to the correspondingmplmetaprogramming type, as if byreturn typename as_meta<type>::type{};Example#
static_assert(List<float, double, int>{}.back() == decltype_<int>()); static_assert(List<int, float, double>{}.back() == decltype_<double>()); static_assert(List<int, double, float>{}.back() == decltype_<float>());
- Returns:
the last element of this
List
-
inline auto push_front(MetaType auto type) const noexcept#
Returns a copy of this
List, withtypeprepended to the beginning of theList.Using the exposition-only template metafunction
as_raw(see the corresponding section in the Metaprogramming List Type module-level documentation), returns aListcontainingtypename as_raw<decltype(type)>::type, TTypes....Example#
static_assert(List<float, double, int>{}.push_front(decltype_<int>()) == List<int, float, double, int>{}); static_assert(List<float, double, int>{}.push_front(decltype_<float>()) == List<float, float, double, int>{}); static_assert(List<float, double, int>{}.push_front(decltype_usize>()) == List<usize, float, double, int>{});
-
inline auto push_front(MetaValue auto value) const noexcept#
Returns a copy of this
List, withvalueprepended to the beginning of theList.Using the exposition-only template metafunction
as_raw(see the corresponding section in the Metaprogramming List Type module-level documentation), returns aListcontainingtypename as_raw<decltype(value)>::type, TTypes....Example#
static_assert(List<float, double, int>{}.push_front(1_value) == List<Value<1>, float, double, int>{}); static_assert(List<float, double, int>{}.push_front(2_value) == List<Value<2>, float, double, int>{}); static_assert(List<float, double, int>{}.push_front(3_value) == List<Value<3>, float, double, int>{});
-
inline auto push_front(MetaPair auto pair) const noexcept#
Returns a copy of this
List, withpairprepended to the beginning of theList.Using the exposition-only template metafunction
as_raw(see the corresponding section in the Metaprogramming List Type module-level documentation), returns aListcontainingtypename as_raw<decltype(pair)>::type, TTypes....Example#
static_assert(List<float, double, int>{}.push_front(Pair<int, double>{}) == List<Pair<int, double>, float, double, int>{}); static_assert(List<float, double, int>{}.push_front(Pair<Value<1>, float>{}) == List<Pair<Value<1>, float>, float, double, int>{}); static_assert(List<float, double, int>{}.push_front(Pair<usize, void>{}) == List<Pair<usize, void>, float, double, int>{});
-
template<typename ...TOthers>
inline List<TOthers..., TTypes...> push_front(List<TOthers...> list) const noexcept# Returns a copy of this
List, with the elements oflistprepended to the beginning of theList.Using the exposition-only template metafunction
as_raw(see the corresponding section in the Metaprogramming List Type module-level documentation), returns aListcontainingTOthers..., TTypes....Example#
static_assert(List<float, double, int>{}.push_front(List<Value<1>, int, double>{}) == List<Value<1>, int, double, float, double, int>{}); static_assert(List<float, double, int>{}.push_front(List<usize, Pair<i32, f32>, i64>{}) == List<usize, Pair<i32, f32>, i64, float, double, int>{}); static_assert(List<float, double, int>{}.push_front(List<i64, f64, Value<2>>{}) == List<i64, f64, Value<2>, float, double, int>{});
-
inline auto push_back(MetaType auto type) const noexcept#
Returns a copy of this
List, withtypeappended to the end of theList.Using the exposition-only template metafunction
as_raw(see the corresponding section in the Metaprogramming List Type module-level documentation), returns aListcontainingTTypes..., typename as_raw<decltype(type)>::type.Example#
static_assert(List<float, double, int>{}.push_back(decltype_<int>()) == List<float, double, int, int>{}); static_assert(List<float, double, int>{}.push_back(decltype_<float>()) == List<float, double, int, float>{}); static_assert(List<float, double, int>{}.push_back(decltype_usize>()) == List<float, double, int, usize>{});
-
inline auto push_back(MetaValue auto value) const noexcept#
Returns a copy of this
List, withvalueappended to the end of theList.Using the exposition-only template metafunction
as_raw(see the corresponding section in the Metaprogramming List Type module-level documentation), returns aListcontainingTTypes..., typename as_raw<decltype(value)>::type.Example#
static_assert(List<float, double, int>{}.push_back(1_value) == List<float, double, int, Value<1>>{}); static_assert(List<float, double, int>{}.push_back(2_value) == List<float, double, int, Value<2>>{}); static_assert(List<float, double, int>{}.push_back(3_value) == List<float, double, int, Value<3>>{});
-
inline auto push_back(MetaPair auto pair) const noexcept#
Returns a copy of this
List, withpairappended to the end of theList.Using the exposition-only template metafunction
as_raw(see the corresponding section in the Metaprogramming List Type module-level documentation), returns aListcontainingTTypes..., typename as_raw<decltype(pair)>::type.Example#
static_assert(List<float, double, int>{}.push_back(Pair<int, double>{}) == List<float, double, int, Pair<int, double>>{}); static_assert(List<float, double, int>{}.push_back(Pair<Value<1>, float>{}) == List<float, double, int, Pair<Value<1>, float>>{}); static_assert(List<float, double, int>{}.push_back(Pair<usize, i32>{}) == List<float, double, int, Pair<usize, i32>>{});
-
template<typename ...TOthers>
inline List<TTypes..., TOthers...> push_back(List<TOthers...> list) const noexcept# Returns a copy of this
List, with the elements oflistappended to the end of theList.Using the exposition-only template metafunction
as_raw(see the corresponding section in the Metaprogramming List Type module-level documentation), returns aListcontainingTTypes..., TOthers....Example#
static_assert(List<float, double, int>{}.push_back(List<Value<1>, int, double>{}) == List<float, double, int, Value<1>, int, double>{}); static_assert(List<float, double, int>{}.push_back(List<usize, Pair<i32, f32>, i64>{}) == List<float, double, int, usize, Pair<i32, f32>, i64>{}); static_assert(List<float, double, int>{}.push_back(List<i64, f64, Value<2>>{}) == List<float, double, int, i64, f64, Value<2>>{});
-
inline auto pop_front() const noexcept#
Returns a copy of this
Listwith the first element removed.- Returns:
a copy of this
Listwith the first element removed
-
inline auto pop_back() const noexcept#
Returns a copy of this
Listwith the last element removed.- Returns:
a copy of this
Listwith the last element removed
-
template<typename ...TRHTypes>
inline auto zip(List<TRHTypes...> rhs) const noexcept# Converts the elements of this
Listandrhsinto a single list ofPairs of elements.Returns a
ListofPairs of elements, created as if byList<Pair<this->at(0), rhs.at(0)>, Pair<this->at(1), rhs.at(1)>, ..., Pair<this->at(this->size() - 1), rhs.at(rhs.size() - 1)>>{}
Requirements#
this
Listandrhsmust be the same size
Example#
static_assert(List<int, double>{}.zip(List<u32, u64>{}) == List<Pair<int, u32>, Pair<double, u64>>{});