Jln.Mp: A C++17 metaprogramming library

Table of contents

Summary

CI

Jln.mp is a C++17 metaprogramming library designed for fast compilation speed (strongly inspired by Kvasir::mpl, but generally faster, with more algorithm and a debug mode to have errors with more context).

Licence: MIT

Online documentation: https://jonathanpoelen.github.io/jln.mp/

Online documentation for v1: https://jonathanpoelen.github.io/jln.mp/v1/

Single file version in standalone branch.

Concepts

Functions of jln.mp are used in 2 stages:

For example, suppose we want to remove void from a sequence. The function to use is jln::mp::remove:

using remove_void = jln::mp::remove<void>;

We can then apply it to our data:

using result = jln::mp::call<remove_void, int, void, double, char>;
// result == jln::mp::list<int, double, char>

Now suppose that result must be a std::tuple. Rather than linking with another function, it is possible to combine them in remove_void via a continuation (C parameter).

using remove_void = jln:mp::remove<void, /*C=*/jln::mp::cfe<std::tuple>>;

using result = jln::mp::call<remove_void, int, void, double, char>;
// result == std::tuple<int, double, char>

The default continuations are jln::mp::listify which transforms a sequence into a jln::mp::list and jln::mp::identity which returns the input value.

Jln.mp also has 2 additional namespaces:

Create a function

A function is a type with a f template member.

struct to_tuple
{
  template<class... xs>
  using f = std::tuple<xs...>;
};

jln::mp::call<to_tuple, int, double> == std::tuple<int, double>

In the mind of the library, functions should at least take a continuation.

// equivalent to jln::mp::cfe<std::tuple, C>
template<class C = jln::mp::identity>
struct to_tuple
{
  template<class... xs>
  using f = jln::mp::call<C, std::tuple<xs...>>;
};

jln::mp::call<to_tuple<>, int, double> == std::tuple<int, double>

Glossary

Sequence
a value sequence or a type sequence.
Set
a sequence of unique elements.
Map
a sequence of lists having at least one element (the key). The keys of the map must be unique.
Value
a type with a value member.
Typelist
an instance compatible with template<class...> class T, such as list<>.
Function
a type with a f template member. The number and the nature of the parameters depend on the context of use.
Predicate
a function which takes n argument (usually 1) and returns a boolean.
Meta-function
a template class template<class...> class M.
Lazy meta-function
a meta-function with a type member.
C
Continuation function. Represents the function used to chain calls, typically listify or identity.
TC parameter
True Continuation function. Represents a continuation used when something is found or true.
FC parameter
False Continuation function. Represents a continuation used when something is not found or false.
_v suffix
C::f takes values. Usually C::f<jln::mp::int_t...> (C++17) or C::f<auto...> (C++20). In the emp namespace, with a few exceptions, this corresponds to a variable template (as for the stl).

Example of real life

Implementation of std::tuple_cat that works with tuple like.

#include "jln/mp/algorithm/make_int_sequence.hpp"
#include "jln/mp/algorithm/transform.hpp"
#include "jln/mp/algorithm/repeat.hpp"
#include "jln/mp/algorithm/repeat_index.hpp"
#include "jln/mp/functional/each.hpp"
#include "jln/mp/functional/continuation.hpp"
#include "jln/mp/list/join.hpp"

#include <array>
#include <tuple>

namespace mp = jln::mp;
namespace emp = jln::mp::emp;

template<class Tuple>
struct my_tuple_element
{
    template<class I>
    using f = std::tuple_element_t<I::value, Tuple>;
};

template<class... Tuples>
using my_tuple_cat_result_type = mp::call<
    // Convert a sequence of mp::list to std::tuple
    mp::join<mp::cfe<std::tuple>>,
    // Convert a tuple like to mp::list of tuple element.
    // To support tuple-likes, it is necessary to use std::tuple_size and std::tuple_element.
    // Otherwise, emp::unpack<Tuples> is sufficient.
    emp::make_int_sequence<
        std::tuple_size<std::decay_t<Tuples>>,
        // Convert a sequence of tuple index to a mp::list of tuple element.
        mp::transform<my_tuple_element<std::decay_t<Tuples>>>
    >...
>;

template<class R, mp::int_t... ituples, mp::int_t... ivalues, class Tuple>
constexpr R my_tuple_cat_impl(
    emp::numbers<ituples...>, emp::numbers<ivalues...>, Tuple t)
{
    // get is looked up by argument-dependent lookup
    using std::get;
    return R{ get<ivalues>(get<ituples>(std::move(t)))... };
}

template<class... Tuples, class R = my_tuple_cat_result_type<Tuples...>>
constexpr R my_tuple_cat(Tuples&&... args)
{
    // ex:    tuple_size=3     tuple_size=2     tuple_size=4
    // list<    0, 0, 0,           1, 1,         2, 2, 2, 2   >
    using index_by_tuple = mp::repeat_index_v_c<mp::join<>>
        ::f<std::tuple_size_v<std::decay_t<Tuples>>...>;

    // ex:    tuple_size=3     tuple_size=2     tuple_size=4
    // list<    0, 1, 2,           0, 1,         0, 1, 2, 3   >
    using index_by_value = emp::join<
        emp::make_int_sequence<std::tuple_size<std::decay_t<Tuples>>>...
    >;

    return my_tuple_cat_impl<R>(index_by_tuple{}, index_by_value{},
        std::tuple<Tuples&&...>(std::forward<Tuples>(args)...));
}

// defines a tuple like
//@{
namespace toy
{
    // tuple like
    struct Vector2D
    {
        int x, y;
    };

    template<std::size_t i>
    constexpr int get(Vector2D const& t)
    {
        return i == 0 ? t.x : t.y;
    }
}

template<>
struct std::tuple_size<::toy::Vector2D>
: std::integral_constant<std::size_t, 2>
{};

template<size_t i>
struct std::tuple_element<i, ::toy::Vector2D>
{
    using type = int;
};
//@}

// test
// @{
constexpr std::tuple<int, float, double> t0{1, 2, 3};
constexpr std::tuple<char, unsigned> t1{4, 5};
constexpr std::tuple<long> t2{6};
constexpr std::array<short, 4> a{7, 8, 9, 10};
constexpr toy::Vector2D v {11, 12};

constexpr auto my_tuple = my_tuple_cat(t0, t1, t2, a, v);

using my_tuple_type = std::remove_const_t<decltype(my_tuple)>;
using std_tuple = std::tuple<
    int, float, double,
    char, unsigned,
    long,
    short, short, short, short,
    int, int>;

static_assert(std::is_same_v<my_tuple_type, std_tuple>);
static_assert(my_tuple == std::tuple{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
// @}

FAQ

> Functions are missing in the stacktrace when the compiler displays an error message, how to display them?

Compile with the define JLN_MP_DEBUG at 1 to have errors with more context.

> Error: sorry, unimplemented: mangling record_type or sorry, unimplemented: mangling typename_type with Gcc.

This is a Gcc bug when an algorithm is used in the prototype of a function.

template<class... Ts>
mp::call<func, Ts...> foo();

// Must be replaced by

template<class... Ts, class R = mp::call<func, Ts...>>
R foo();

Files by group

Files in alphabetical order

Functions by group

Functions in alphabetical order

Short descriptions

Group: algorithm

None= stop_recursion
Some<value, next = value>= list<value, next>
unfold<F, C = listify>Unfold F until returning None.
all_of<Pred, C = identity>::f<xs...>Checks whether a predicate holds for all elements of a sequence.
anticirculant_matrix<C = listify>= anticirculant_matrix_with<listify, C>
anticirculant_matrix_with<F = listify, C = listify>::f<xs...>square matrix in which all row vectors are composed of the same elements and each row vector is rotated one element to the left relative to the preceding row vector.
any_of<Pred, C = identity>Checks whether a predicate holds for at least some element of a sequence.
arrange<Ints, C = listify>Uses a list of indices to reorder a sequence.
arrange_c<int... ints>= arrange_c_with<listify, ints...>
arrange_c_with<C, int... ints>::f<xs...>
circulant_matrix<C = listify>= circulant_matrix_with<listify, C>
circulant_matrix_with<F = listify, C = listify>::f<xs...>square matrix in which all row vectors are composed of the same elements and each row vector is rotated one element to the right relative to the preceding row vector.
contains<x, C = identity>Checks whether a value is contained in a sequence.
count<x, C = identity>Counts all elements identical to a value.
count_if<Pred, C = identity>Counts all elements that satisfy a predicate.
counter<C = listify>Counts all distinct elements and returns a list of pairs containing the type and the repeat count.
counter_wrapped_with<F, C = listify>::f<xs...>Counts all distinct elements and returns a list of pairs containing the type and the repeat count.
ends_with<Seq, C = identity>Checks if the sequence ends with the given prefix.
ends_with<list<Ts...>, C>::f<xs...>
flatten<cfe<S, identity>, C>::f<xs...>
flatten<S = cfe<list>, C = listify>Recursive version of flatten_once.
flatten_f<template<class...> S, C = listify>= flatten<cfe<S>, C>
flatten_for_f<template<class...> S, C = identity>= flatten<cfe<S>, cfe<S, C>>
flatten_once<S = cfe<list>, C = listify>Remove 1 dimension level from a sequence.
flatten_once<cfe<S, identity>, C>::f<xs...>
flatten_once_f<template<class...> S, C = listify>= flatten_once<cfe<S>, C>
flatten_once_for_f<template<class...> S, C = identity>= flatten_once<cfe<S>, cfe<S, C>>
intersperse<x, C = listify>::f<xs...>Inserts a value between each element of a sequence.
is_disjoint<C = identity>Checks whether value in seqs[0] are disjoint from the value in seqs[1:].
is_disjoint_with<Cmp = same<>, C = identity>::f<seqs...>Checks whether value in seqs[0] are disjoint from the value in seqs[1:].
is_sorted<Cmp = less<>, C = identity>::f<xs...>Checks whether a sequence is sorted.
is_subset<C = identity>Checks whether value in seqs[0] are subset from the value in seqs[1:].
is_subset_with<Cmp = same<>, C = identity>::f<seqs...>Checks whether value in seqs[0] are subset from the value in seqs[1:].
is_unique<C = identity>Checks whether all values are unique.
is_unique_if<Cmp = same<>, C = identity>::f<xs...>Checks whether all values are unique.
lexicographical_compare<Cmp = less<>, C = identity>::f<seq1, seq2>Checks if seq1 is lexicographically less than seq2.
lexicographical_compare2<CmpLess = less<>, CmpEq = equal<>, C = identity>::f<seq1, seq2>
merge<Cmp = less<>, C = listify>::f<seq1, seq2>Merges two list into one sorted sequence.
mismatch<Cmp = equal<>, TC = listify, FC = TC>::f<seq1, seq2>Returns mismatching info of elements from two sequences.
mismatch_index<Cmp = equal<>, C = identity>Returns the first mismatching index of elements from two sequences, otherwise the size of the sequences.
none_of<Pred, C = identity>::f<xs...>Checks whether a predicate does not hold for any element of a sequence.
pairwise_fold<F, C = listify>Computes the differences between adjacent pair of elements.
pairwise_fold_and_transform_front<F, Front = identity, C = listify>::f<xs...>Computes the differences between adjacent pair of elements.
prefix<x, C = listify>::f<xs...>Inserts a value before each element of a sequence.
repeat<N, C = listify>= repeat_c<N::value, C>
repeat_c<unsigned N, C = listify>::f<xs...>Returns a sequence that contains a number of copies of the same sequence.
repeat_index<C = listify>= repeat_index_with<listify, C>
repeat_index_v_c<C = listify>= repeat_index_with_v_c<listify, C>
repeat_index_with<F = listify, C = listify>::f<ns...>= repeat_index_with_v_c<F, C>::f<ns::value...>
repeat_index_with_v_c<F = listify, C = listify>::f<unsigned... ns>Creates a sequence of index sequence, taking the size of each as a parameter.
replace<T, U, C = listify>Replaces every occurrence of a value by another value.
replace_if<Pred, T, C = listify>Replaces every occurrence that satisfy a predicate by some value.
reverse<C = listify>::f<xs...>Reverses the order of the elements of a sequence.
rotate<N, C = listify>= rotate_c<N::value, C>
rotate_c<int_t N, C = listify>::f<xs...>Rotates the elements of a sequence around a pivot.
same<C = identity>::f<xs...>Checks whether all values are identical.
same_v<C = identity>::f<xs...>= C::f<emp::same_xs_v<xs...>>
JLN_MP_IS_SAME(...)Fast implementation of std::is_same_v.
scan<F, C = listify>::f<xs...>Fold a sequence to the left and return a list containing the successive reduction states.
scan_right<F, C = listify>Fold a sequence to the right and return a list containing the successive reduction states.
similar<C = identity>::f<xs...>Checks whether all types are the same or instantiations of the same class template.
similar_v<C = identity>::f<xs...>= C::f<emp::similar_xs_v<xs...>>
sort<Cmp = less<>, C = listify>::f<xs...>Sorts the elements of a sequence according to an ordering relation.
stable_sort<Cmp = less<>, C = listify>= sort<Cmp, C>
starts_with<Seq, C = identity>Checks if the sequence begins with the given prefix.
starts_with<list<Ts...>, C>::f<xs...>
suffix<x, C = listify>::f<xs...>Inserts a value after each element of a sequence.
transform<F, C = listify>::f<xs...>Executes F on every element of a sequence.
transform_at<I, F, C = listify>= transform_at_c<I::value, F, C>
transform_at_c<unsigned i, F, C = listify>::f<xs...>Replace the element at position i of the sequence.
transform_first<F, C = listify>Replace the first element of the sequence.
transform_second<F, C = listify>Replace the second element of the sequence.
transform_third<F, C = listify>Replace the third element of the sequence.
uncompress<FillT, Selectors, C = listify>
uncompress_c<FillT, bool... selectors>= uncompress_c_with<listify, FillT, selectors...>
uncompress_c_with<C, FillT, bool... selectors>::f<xs...>Create sequence by replacing false in selectors with FillT and true with a element in xs value, starting from the left.
uncompress_for<FillT, Selectors...>= uncompress_c_with<listify, FillT, Selectors::value...>

Group: config

JLN_MP_APPLE_CLANGIs clang on MacOS.
JLN_MP_CLANGThe compiler is clang.
JLN_MP_CLANG_CLThe compiler is clang-cl.
JLN_MP_CLANG_LIKEThe compiler presents itself as a clang without necessarily being so.
JLN_MP_CUDAThe compiler is nvcc.
JLN_MP_ENABLE_FRIEND_INJECTIONWhen 1, algorithms using friend injection its accessible
JLN_MP_ENABLE_TYPE_PACK_ELEMENTWhen 1, the builtin __type_pack_element can be used.
JLN_MP_FAST_ALIAS_ON_VARIABLE_TEMPLATEWhen 1, number<f_v<xs...>> is faster than f<xs...>::type.
JLN_MP_FAST_TYPE_PACK_ELEMENTWhen 1, the builtin __type_pack_element can be used and is very fast.
JLN_MP_GCCThe compiler is gcc.
JLN_MP_HAS_BUILTIN(name)Check that a builtin exists.
JLN_MP_HOST_COMPILER_CLANGThe host compiler is clang (in the case of nvcc).
JLN_MP_HOST_COMPILER_GCCThe host compiler is gcc (in the case of nvcc).
JLN_MP_LAZY_ALIASWhen 0, aliases are not context dependent and are resolved as soon as possible which generate errors in contexts that should be lazy.
JLN_MP_MEMOIZED_ALIASWhen 1, aliases are memoized. This means that calling a "slow" alias a second time and with the same parameters will be fast.
JLN_MP_MSVCThe compiler is cl.
JLN_MP_MSVC_LIKEThe compiler presents itself as a msvc without necessarily being so.
JLN_MP_OPTIMIZED_ALIASWhen 1, the compiler considers an alias that makes alias<xs...> = F<xs...> is identical to F.
JLN_MP_REQUIRES_AS_FAST_SFINAEWhen 1, requires keyword is faster than traditional use of SFINAE.
JLN_MP_UNPACK(...)Displays parameters. Useful in a macro to remove parentheses from a value.
JLN_MP_WORKAROUND(symbol, test)Checks that a value respects a condition and is different from 0.
JLN_MP_DEBUGWhen 1, uses a memoization version of call to keep better track of calls in the case of compilation error. This is especially useful with clang, which doesn't display aliases.
JLN_MP_FORCE_LAZY_ALIASWhen 1, ignore the value of JLN_MP_LAZY_ALIAS in the implementations.
JLN_MP_MAX_CALL_ELEMENTMaximum pack size that can be passed to the call function.

Group: filter

compress<Selectors, C = listify>
compress_c<bool... selectors>= compress_c_with<listify, selectors...>
compress_c_with<C, bool... selectors>::f<xs...>Removes elements that have a corresponding element in selectors to 0.
compress_for<Selectors...>= compress_c_with<listify, Selectors::value...>
copy<x, C = listify>Copies all occurence of a value.
copy_if<Pred, C = listify>Copies all elements that satisfy a predicate.
remove_adjacent<C = listify>Removes each element in a sequence which is the same type as the privious element.
remove_adjacent_if<BinaryPred, C = listify>Removes each element in a sequence which respect a predicate with privious element.
remove<T, C = listify>Removes all occurence of a value.
remove_if<Pred, C = listify>Removes all elements that satisfy a predicate.
remove_prefix<Seq, TC = listify, FC = TC>Remove the first elements corresponding to a prefix.
remove_prefix<list<Ts...>, TC, FC>::f<xs...>
remove_suffix<Seq, TC = listify, FC = TC>Remove the last elements corresponding to a suffix.
remove_suffix<list<Ts...>, TC, FC>::f<xs...>
copy_unique<C = listify>::f<xs...>Copy unique elements from a sequence.
copy_unique_if<Cmp = same<>, C = listify>Copy unique elements from a sequence.
remove_unique<C = listify>::f<xs...>Remove unique elements from a sequence.
remove_unique_if<Cmp = same<>, C = listify>Remove unique elements from a sequence.
unique<C = listify>Returns a list with duplicate elements removed.
unique_if<Cmp = same<>, C = listify>::f<xs...>Returns a list with duplicate elements removed.

Group: functional

apply_or_identity<Pred, TC>Returns TC::f<x> if Pred::f<x>, otherwise returns x.
bind_back<F, BoundArgs...>::f<xs...>Invoking F with its last parameters bound to bound to args.
bind_back_c<F, int_t... BoundArgs>= bind_back<F, number<BoundArgs>...>
bind_back_v<F, auto... BoundArgs>::f<xs...>= F::f<xs..., BoundArgs...>
bind_front<F, BoundArgs...>::f<xs...>Invoking F with its first parameters bound to bound to args.
bind_front_c<F, int_t... BoundArgs>= bind_front<F, number<BoundArgs>...>
bind_front_v<F, auto... BoundArgs>::f<xs...>= F::f<BoundArgs..., xs...>
call<C, xs...>= C::f<xs...>
call_c<C, auto /*or int_t*/... xs>
call_t<C, xs...>= call<C, xs...>::type
capture_back<BoundArgs...>::f<F, xs...>Invoking F with its last parameters bound to args.
capture_back_c<int_t... BoundArgs>= capture_back<number<BoundArgs>...>
capture_back_v<auto... BoundArgs>::f<F, xs...>= F::f<xs..., BoundArgs...>
capture_front<BoundArgs...>::f<F, xs...>Invoking F with its first parameters bound to args.
capture_front_c<int_t... BoundArgs>= capture_front<number<BoundArgs>...>
capture_front_v<auto... BoundArgs>::f<F, xs...>= F::f<BoundArgs..., xs...>
cascade<F, Fs...>Recursively invokes functions to nested typelist of typelists.
cfe<template<class...> F, C = identity>::f<xs...>Makes a continuation from a meta-function.
cfe_v<template<auto /*or int_t*/...> F, C = identity>::f<xs...>Makes a function from a meta-function.
cfe_v_c<template<auto /*or int_t*/...> F, C = identity>::f<auto /*or int_t*/... xs>Makes a function from a meta-function.
cfl<template<class...> F, C = identity>::f<xs...>Makes a continuation from a lazy meta-function.
cfl_v<template<auto /*or int_t*/...> F, C = identity>::f<xs...>Makes a function from a lazy meta-function.
cfl_v_c<template<auto /*or int_t*/...> F, C = identity>::f<auto /*or int_t*/... xs>Makes a function from a lazy meta-function.
compare_with<F, Cmp = less<>>comparison on the result of a function.
compose<F, Fs...>Composition of two functions or more.
compose_f<template<class...> F, template<class...> Fs...>Composition of two meta-functions or more.
each<Fs..., C>::f<xs...>Invokes multiple functions each taking the parameter corresponding to its position.
eval<auto F, C = identity>::f<xs...>Invokes a lambda function.
fix<C>::f<xs...>Invokes a function computing the fixed point of a function.
flip<C = listify>::f<x0, x1, xs...>Invokes a function with its two first arguments reversed.
identity::f<x>= x
if_<Pred, TC, FC = always<false_>>::f<xs...>A conditional expression.
invoke_twice<F>::f<xs...>Invokes twice.
is_invocable<F, C = identity>Checks whether F::f<xs...> is invocable.
is_na= is<na>
is_not_invocable<F, C = identity>Checks whether F::f<xs...> is not invocable.
try_<F, TC = identity, FC = violation>::f<xs...>Invokes TC::f<result> whether FC::f<xs...> is a valid expression other than na, otherwhise invokes FC::f<xs...>.
try_or<F, FT = na>= try_<F, identity, always<FT>>
try_or_else<F, FC = violation>= try_<F, identity, FC>
violation= always<na>
monadic<TC, FC = violation>Invokes FC whether na, otherwise TC.
monadic0<TC, FC = violation>Invokes FC whether first value is na, otherwise TC.
monadic_if_na<x, template<class...> M, TC, FC = violation>Monadify only if x is na.
monadic_xs<TC, FC = violation>Invokes FC whether any value is na, otherwise TC.
memoize<C>::f<xs...>Memoize a call to C::f<xs...>.
memoize_call<C, xs...>Memoization version of call.
naValue that is not available.
not_fn<F, C = identity>Returns the negation of F.
partial_tee<Fs..., C>::f<xs...>Invokes multiple functions passing all parameters to each then calls C with the results and parameters without the first sizeof...(Fs).
partial_tee0<Fs..., C>::f<xs...>Invokes multiple functions passing all parameters to each (or without parameter whether it does not exist), then calls C with the results and parameters without the first sizeof...(Fs).
partial_tee0_xs<Fs..., C>::f<xs...>Invokes multiple functions each taking the parameter corresponding to its position (or without parameter whether it does not exist), except the last one taking zero to all remaining parameters.
partial_tee_xs<Fs..., C>::f<xs...>Invokes multiple functions each taking the parameter corresponding to its position, except the last one taking zero to all remaining parameters.
partial_transform<Fs..., C>::f<xs...>Invokes multiple functions each taking the parameter corresponding to its position, then calls C with the results and the rest of the parameters.
partial_transform0<Fs..., C>::f<xs...>Invokes multiple functions each taking the parameter corresponding to its position (or without parameter whether it does not exist), then calls C with the results and the rest of the parameters.
partial_transform0_xs<Fs..., C>::f<xs...>Invokes multiple functions each taking the parameter corresponding to its position (or without parameter whether it does not exist), except the last one taking zero to all remaining parameters.
partial_transform_xs<Fs..., C>::f<xs...>Invokes multiple functions each taking the parameter corresponding to its position, except the last one taking zero to all remaining parameters.
reverse_select<Pred, TC = identity, FC = TC>::f<x, y, xs...>A conditional selection expression.
reverse_select_flip<Pred, TC = identity, FC = TC>::f<x, y, xs...>A conditional selection expression with its two first arguments reversed.
select<Pred, TC = identity, FC = TC>::f<x, y, xs...>A conditional selection expression.
select_flip<Pred, TC = identity, FC = TC>::f<x, y, xs...>A conditional selection expression with its two first arguments reversed.
next_recursion::f<xs...>Specify values for the next iteration.
recursion_result::f<xs...>Specify result values and stop recursion.
recursively<F, C = identity>::f<xs...>Recursively invokes F until stop_recursion or recursion_result.
recursively_as_much_as_possible<F, C = identity>::f<xs...>Recursively invokes F until the result is stop_recursion, recursion_result or no longer changes.
recursively_as_much_as_possible_xs<F, C = listify>Same than recursively_as_much_as_possible, but with listify as default continuation.
recursively_xs<F, C = listify>Same than recursively, but with listify as default continuation.
stop_recursion::f<_...>Stop the recursion, the input values will be used as result.
tee<Fs..., C>::f<xs...>Invokes multiple functions passing all parameters to each.
until<Pred, F, C = identity>Apply a function until some predicate is satisfied.
until_xs<Pred, F, C = listify>Apply a function until some predicate is satisfied.
partial_until_last_t<template<class...> Tpl, OffsetEnd, Pred, TC = listify, FC = clear<TC>>= Tpl<OffsetEnd, Pred, recursively< pop_front<Tpl<OffsetEnd, Pred, next_recursion, stop_recursion>>, TC>, FC>
partial_until_last_t_c<template<int_t, class...> Tpl, int_t OffsetEnd, Pred, TC = listify, FC = clear<TC>>= Tpl<OffsetEnd, Pred, recursively< pop_front<Tpl<OffsetEnd, Pred, next_recursion, stop_recursion>>, TC>, FC>
until_last<Searcher>Uses a Searcher in a loop until the last result.
until_last_t<template<class...> Tpl, Pred, TC = listify, FC = clear<TC>>= Tpl<Pred, recursively< pop_front<Tpl<Pred, next_recursion, stop_recursion>>, TC>, FC>
while_<Pred, F, C = identity>Apply a function while some predicate is satisfied.
while_xs<Pred, F, C = listify>Apply a function while some predicate is satisfied.

Group: group

batched<size, C = listify>= strided_sliding_with_c<size::value, size::value, listify, C>
batched_c<int_t size, C = listify>= strided_sliding_with_c<size, size, listify, C>
batched_with<size, F = listify, C = listify>= strided_sliding_with_c<size::value, size::value, F, C>
batched_with_c<int_t size, F = listify, C = listify>Splits a sequence by arbitrary size group.
collapse<keys, C = listify>= emp::unpack<keys, cfe<collapse2_with>, C, listify>
collapse2<C, keys...>= collapse2_with<C, listify, keys...>
collapse2_c<C, int_t... keys>= collapse2_with<C, listify, number<keys>...>
collapse2_with<C, F, keys...>::f<xs...>Groups adjacent elements by adjacent keys.
collapse2_with_c<C, F, int_t... keys>= collapse2_with<C, F, number<keys>...>
collapse_for<keys...>= collapse2_with<listify, listify, keys...>
collapse_for_c<int_t... keys>= collapse2_with<listify, listify, number<keys>...>
collapse_with<keys, F = listify, C = listify>= emp::unpack<keys, cfe<collapse2_with>, C, F>
combine<C = listify>::f<xs...>Computes all possible combinations (with repetition) from the elements in a sequence.
group<C = listify>= group_by_with<same<>, listify, C>
group_by<Cmp, C = listify>= group_by_with<Cmp, listify, C>
group_by_with<Cmp, F = listify, C = listify>::f<xs...>Groups adjacent elements that respect a predicate.
group_with<F = listify, C = listify>= group_by_with<same<>, F, C>
left_matrix_longest<FillValue, C = listify>= left_matrix_longest_with<FillValue, listify, C>
left_matrix_longest_with<FillValue, F = listify, C = listify>::f<seqs...>Fills a sequence of typelist to the longest size.
right_matrix_longest<FillValue, C = listify>= right_matrix_longest_with<FillValue, listify, C>
right_matrix_longest_with<FillValue, F = listify, C = listify>::f<seqs...>Fills a sequence of typelist to the longest size.
left_matrix_shortest<C = listify>= left_matrix_shortest_with<listify, C>
left_matrix_shortest_with<F = listify, C = listify>::f<seqs...>Truncates a sequence of typelist to the smallest size.
right_matrix_shortest<C = listify>= right_matrix_shortest_with<listify, C>
right_matrix_shortest_with<F = listify, C = listify>::f<seqs...>Truncates a sequence of typelist to the smallest size.
pairwise<C = listify>= pairwise_with<listify, C>
pairwise_with<F = listify, C = listify>::f<xs...>Returns successive overlapping pairs.
partition<Pred, C = listify>Splits a list in two according to a predicate.
partition_with<Pred, F = listify, C = listify>::f<xs...>Splits a list in two according to a predicate.
permutations<C = listify>::f<xs...>Generates all permutations of sequence.
powerset<C = listify>::f<xs...>Computes the powerset of a sequence.
product<C = listify>::f<seq = list<>, seqs...>Computes the cartesian product of lists.
regroup<C = listify>= regroup_with<listify, C>
regroup_by<Cmp = same<>, C = listify>= regroup_by_with<Cmp, listify, C>
regroup_by_with<Cmp = same<>, F = listify, C = listify>::f<xs...>
regroup_with<F, C = listify>Group identical type together.
split_after<x, C = listify>= split_after_if_with<is<x>, listify, C>
split_after_if<Pred = identity, C = listify>= split_after_if_with<Pred, listify, C>
split_after_if_with<Pred, F = listify, C = listify>::f<xs...>Splits a sequence into multiple lists at every point that satisfy a predicate.
split_after_with<x, F = listify, C = listify>= split_after_if_with<is<x>, F, C>
split_at<i, C = listify>= split_at2_with_c<i::value, listify, listify, C>
split_at2_with<i, SubC1 = listify, SubC2 = SubC1, C = listify>= split_at2_with_c<i::value, SubC1, SubC2, C>
split_at2_with_c<unsigned i, SubC1 = listify, SubC2 = SubC1, C = listify>::f<xs...>Splits a sequence at an arbitrary position.
split_at_c<unsigned i, C = listify>Splits a sequence at an arbitrary position.
split_at_with<i, F = listify, C = listify>= split_at2_with_c<i::value, F, F, C>
split_at_with_c<unsigned i, F = listify, C = listify>= split_at2_with_c<i, F, F, C>
split_before<x, C = listify>= split_before_if_with<is<x>, listify, C>
split_before_if<Pred = identity, C = listify>= split_before_if_with<Pred, listify, C>
split_before_if_with<Pred, F = listify, C = listify>::f<xs...>Splits a sequence into multiple lists at every point that satisfy a predicate.
split_before_with<x, F = listify, C = listify>= split_before_if_with<is<x>, F, C>
split_from<GetIndex, C = listify>= split_from2<GetIndex, listify, listify, C>
split_from2<GetIndex, SubC1 = listify, SubC2 = SubC1, C = listify>::f<xs...>Splits a sequence at an arbitrary position returns by GetIndex.
split<x, C = listify>= split_if_with<is<x>, listify, C>
split_if<Pred = identity, C = listify>= split_if_with<Pred, listify, C>
split_if_with<Pred = identity, F = listify, C = listify>::f<xs...>Splits a sequence into multiple lists at every point that satisfy a predicate.
split_with<x, F = listify, C = listify>= split_if_with<is<x>, F, C>
split_keep_separator<x, C = listify>= split_keep_separator_if_with<is<x>, listify, C>
split_keep_separator_if<Pred = identity, C = listify>= split_keep_separator_if_with<Pred, listify, C>
split_keep_separator_if_with<Pred = identity, F = listify, C = listify>::f<xs...>Splits a sequence into multiple lists at every point that satisfy a predicate.
split_keep_separator_with<x, F = listify, C = listify>= split_keep_separator_if_with<is<x>, F, C>
split_once<x, TC = listify, FC = clear<>>= split_once_if<is<x>, TC, FC>
split_once_if<Pred, TC = listify, FC = clear<>>::f<xs...>Splits a sequence at the first position that satisfy a predicate.
zip_longest<FillValue, C = listify>Turns rows into columns, and columns into rows.
zip_longest_with<FillValue, F = listify, C = listify>= right_matrix_longest<FillValue, zip_with<F, C>>
zip<C = listify>= zip_with<listify, C>
zip_with<F = listify, C = listify>::f<seqs...>Turns rows into columns, and columns into rows.

Group: list

append<L, C = listify>Inserts elements at the end of L list.
as_list<C = identity>::f<seq>Extracts type paramaters of a template class or union, then constructs a list.
at<N, C = identity>Retrieves an element of a sequence at an arbitrary position.
at0<C = identity>= front<C>
at1<C = identity>= drop_front_c<1, front<C>>
at2<C = identity>= drop_front_c<2, front<C>>
at3<C = identity>= drop_front_c<3, front<C>>
at4<C = identity>= drop_front_c<4, front<C>>
at5<C = identity>= drop_front_c<5, front<C>>
at6<C = identity>= drop_front_c<6, front<C>>
at7<C = identity>= drop_front_c<7, front<C>>
at8<C = identity>= drop_front_c<8, front<C>>
at9<C = identity>= drop_front_c<9, front<C>>
at_c<unsigned n, C = identity>= drop_front_c<n, front<C>>
back<C = identity>Retrieves the last element of a sequence.
build_indexed<xs...>::f<i>Constructs an indexable sequence in O(1).
build_indexed_v<xs...>::f<int i>Constructs an indexable sequence in O(1).
clear<C = listify>::f<xs...>Removes all elements from the sequence.
drop_back<N, C = listify>= drop_back_c<N::value, C>
drop_back_c<unsigned N, C = listify>::f<xs...>Removes N elements from the end of a sequence.
drop_back_max<N, C = listify>= drop_back_max_c<N::value, C>
drop_back_max_c<unsigned N, C = listify>::f<xs...>Removes at most N elements from the end of a sequence.
drop_front<N, C = listify>= drop_front_c<N::value, C>
drop_front_c<unsigned N, C = listify>::f<xs...>Removes N elements from the beginning of a sequence.
drop_front_max<N, C = listify>= drop_front_max_c<N::value, C>
drop_front_max_c<unsigned N, C = listify>::f<xs...>Removes at most N elements from the beginning of a sequence.
enumerate<C = listify>= enumerate_with<listify, C>
enumerate_v_with<F, C = listify>::f<xs...>Returns pairs containing a numeric index of type int_t and a value.
enumerate_with<F = listify, C = listify>::f<xs...>Returns pairs containing an index and a value.
erase<start, size = number<1>, C = listify>= erase_c<start::value, size::value, C>
erase_c<int_t start, unsigned size = 1, C = listify>::f<xs...>Removes at most size elements from index start.
front<C = identity>::f<xs...>Retrieves the first element of a sequence.
insert<index, x, C = listify>= insert_sequence_c<index::value, list<x>, C>
insert_c<int_t index, x, C = listify>Inserts an elements at an arbitrary position.
insert_sequence<index, seq, C = listify>= insert_sequence_c<index::value, seq, C>
insert_sequence_c<int_t index, seq, C = listify>Inserts all elements of seq at an arbitrary position.
insert_sequence_c<index, List<xs...>, C>::f<ys...>
is_empty<C = identity>Checks whether a sequence has no elements.
is_list<C = identity>::f<x>Checks whether x is a list.
is_not_empty<C = identity>Checks whether a sequence has elements.
is_size_of<N, C = identity>= size<is<N, C>>
is_size_of_c<int_t n, C = identity>= size<is<number<n>, C>>
join<C = listify>::f<seqs...>Concatenates lists.
list<xs...>
listify= cfe<list>
offset<I, C = identity>= offset_c<I::value, C>
offset_c<int_t I, C = identity>::f<xs...>Difference between the number of parameter xs and I::value.
pop_back<C = listify>Removes the last element of sequence.
pop_front<C = listify>Remove the first element of sequence
prepend<L, C = listify>Inserts elements at the start of L list.
push_back<x, C = listify>::f<xs...>Appends x to the end of the sequence.
push_front<x, C = listify>::f<xs...>Appends x to the beginning of the sequence.
range<beg, end, C = listify>= range_c<beg::value, end::value, C>
range_c<int_t beg, int_t end, C = listify>::f<xs...>Returns a contiguous subsequence of a sequence.
size<C = identity>::f<xs...>Returns the number of elements in a xs.
slice<start, count, C = listify>= strided_slice_c<start::value, count::value, 1, C>
slice_c<int_t start, unsigned count, C = listify>= strided_slice_c<start, count, 1, C>
strided_slice<start, count, step = number<1>, C = listify>= strided_slice_c<start::value, count::value, step::value, C>
strided_slice_c<int_t start, unsigned count, unsigned step = 1, C = listify>::f<xs...>Returns a subset of elements in a xs picked at regular intervals in range.
sliding<size, C = listify>= strided_sliding_with_c<size::value, 1, listify, C>
sliding_c<int_t size, C = listify>= strided_sliding_with_c<size, 1, listify, C>
sliding_with<size, F = listify, C = listify>= strided_sliding_with_c<size::value, 1, F, C>
sliding_with_c<int_t size, F = listify, C = listify>= strided_sliding_with_c<size, 1, F, C>
strided_sliding<size, stride = number<1>, C = listify>= strided_sliding_with_c<size::value, stride::value, listify, C>
strided_sliding_c<int_t size, int_t stride = 1, C = listify>= strided_sliding_with_c<size, stride, listify, C>
strided_sliding_with<size, stride = number<1>, F = listify, C = listify>= strided_sliding_with_c<size::value, stride::value, F, C>
strided_sliding_with_c<int_t size, int_t stride = 1, F = listify, C = listify>Returns sliding windows of width size.
swap_index<I, J, C = listify>= swap_index_c<I::value, J::value, C>
swap_index_c<unsigned i, unsigned j, C = listify>Swap elements at indices i and j of a sequence.
take_back<N, C = listify>= take_back_c<N::value, C>
take_back_c<unsigned N, C = listify>::f<xs...>Extracts N elements from the end of a sequence.
take_back_max<N, C = listify>= take_back_max_c<N::value, C>
take_back_max_c<unsigned N, C = listify>::f<xs...>Extracts at most N elements from the end of a sequence.
take_front<N, C = listify>= take_front_c<N::value, C>
take_front_c<unsigned N, C = listify>::f<xs...>Extracts N elements from the beginning of a sequence.
take_front_max<N, C = listify>= take_front_max_c<N::value, C>
take_front_max_c<unsigned N, C = listify>::f<xs...>Extracts at most N elements from the beginning of a sequence.
wrap_in_list<b>= wrap_in_list_c<b::value>
wrap_in_list_c<true>::f<xs...>= list<xs...>
wrap_in_list_c<false>::f<xs...>= list<>
wrap_in_list_c<bool b>
wrap_in_list_if<Pred>Returns a list with the first element if the predicate is checked, otherwise returns a empty list.
wrap_in_list_if_not<Pred>Returns a list with the first element if the predicate is not checked, otherwise returns a empty list.

Group: map

is_map<C = identity>Checks whether xs is a map.
map_contains<key, C = identity>Checks if a key exists in a map.
map_not_contains<key, C = identity>Checks if a key does not exists in a map.
map_erase<Key, C = listify>If the map contains an element with a key Key, removes it.
map_find<key, TC = identity, FC = always<na>>::f<kvs...>Finds the element of the map with a key key.
map_find_or<key, FT>= map_find<key, identity, always<FT>>
map_find_or_else<key, FC>= map_find<key, identity, FC>
map_find_value<key, TC = identity, FC = always<na>>Finds the first value of the map with a key key.
map_find_value_or<key, FT>= map_find<key, unpack<at1<>>, always<FT>>
map_find_value_or_else<key, FC>= map_find<key, unpack<at1<>>, FC>
map_find_values<key, TC = listify, FC = always<na>>Finds the values of the map with a key key.
map_find_values_or<key, FT>= map_find<key, unpack<pop_front<listify>>, always<FT>>
map_find_values_or_else<key, FC>= map_find<key, unpack<pop_front<listify>>, FC>
map_insert<kv, C = listify>Inserts the element kv into the map, if the key emp::front<kv> does not exist.
map_insert_s<k, v, C = listify>Inserts the element list<k,v> into the map, if the key k does not exist.
map_keys<C = listify>Returns a list of the keys of map.
map_keys_with<F = mp::identity, C = listify>Returns a list of the keys of map transformed with F.
map_replace<KV, C = listify>If the map contain the key emp::front<KV>, replaces the existing element with KV.
map_replace_or_insert<KV, C = listify>If the map contain the key emp::front<KV>, replaces the existing element with KV; otherwise, inserts it using push_back<KV>.
map_element_key_update<F>::f<kv>Update an element L<k, v...> with L<F<k, v...>, v...>.
map_element_value_update<F>::f<kv>Update an element L<k, v...> with L<k, F<k, v...>>.
map_key_update<key, F, C = listify>If the map contain the key key, replaces the existing element L<key, v...> with L<F<key, v...>, v...>.
map_update<key, F, C = listify>If the map contain the key key, replaces the existing element L<key, v...> with F<L<key, v...>>.
map_update_or_insert<kv, F, C = listify>If the map contain a key emp::front<kv>, replaces the existing element L<k, v...> with F<L<k, v...>>; otherwise, inserts it using push_back<kv>.
map_update_s_or_insert<k, v, F, C = listify>If the map contain a key k, replaces the existing element L<k, v...> with F<list<k, v...>>; otherwise, inserts it using push_back<list<k,v>>.
map_value_update<key, F, C = listify>If the map contain the key key, replaces the existing element L<key, v...> with L<key, F<key, v...>>.
map_value_update_or_insert<kv, F, C = listify>If the map contain a key emp::front<kv>, replaces the existing element L<k, v...> with L<k, F<k, v...>>; otherwise, inserts it using push_back<kv>.
map_value_update_s_or_insert<k, v, F, C = listify>If the map contain a key k, replaces the existing element L<k, v...> with L<k, F<k, v...>>; otherwise, inserts it using push_back<list<k,v>>.

Group: number

as_bool<C = identity>::f<x>Convertion without narrowing from value to true_ / false_.
as_number<C = identity>::f<x>Convertion without narrowing from value to number.
indices<C = listify>Replaces each element of a sequence by its corresponding index.
false_= number<0>
int_t= std::intmax_t
number<int_t v>::value= v
true_= number<1>
uint_t= std::uintmax_t
iota<C = listify>Generates a sequence of number.
iota_v<C = numbers<>>::f<start, count, stride = number<1>>Generates a sequence of int_t.
is_number<C = identity>::f<x>Checks whether a value is a number.
int_seq_c<int_t... i>single list of int_t.
make_int_sequence<C = mp::listify>= make_int_sequence_v<mp::numbers<C>>
make_int_sequence_v<C = numbers<>>::f<n>Generates an incremental sequence of n int_t.
JLN_MP_D_MAKE_INDEX_SEQUENCE(n, /*tpl_class*/...)Template-dependent version of JLN_MP_MAKE_INDEX_SEQUENCE ; add typename when needed.
JLN_MP_D_MAKE_INTEGER_SEQUENCE(n, /*tpl_class*/...)Template-dependent version of JLN_MP_MAKE_INTEGER_SEQUENCE ; add typename when needed.
JLN_MP_D_MAKE_INTEGER_SEQUENCE_T(T, n, /*tpl_class*/...)Template-dependent version of JLN_MP_MAKE_INTEGER_SEQUENCE_T ; add typename when needed.
JLN_MP_D_MAKE_UNSIGNED_SEQUENCE(n, /*tpl_class*/...)Template-dependent version of JLN_MP_MAKE_UNSIGNED_SEQUENCE ; add typename when needed.
JLN_MP_MAKE_INDEX_SEQUENCE(n, /*tpl_class*/...)Fast initialization of template of the shape tpl_class<class T, std::size_t... ints>.
JLN_MP_MAKE_INTEGER_SEQUENCE(n, /*tpl_class*/...)Fast initialization of template of the shape tpl_class<class T, int_t... ints>.
JLN_MP_MAKE_INTEGER_SEQUENCE_T(T, n, /*tpl_class*/...)Fast initialization of template of the shape tpl_class<class T, T... ints>.
JLN_MP_MAKE_UNSIGNED_SEQUENCE(n, /*tpl_class*/...)Fast initialization of template of the shape tpl_class<class T, unsigned... ints>.
abs<C = identity>::f<x>
clamp<Min, Max, C = identity>= clamp_with<Min, Max, less<>, C>
clamp_c<int_t min, int_t max, C = identity>= clamp_with<number<min>, number<max>, less<>, C>
clamp_with<Min, Max, Cmp = less<>, C = identity>::f<x>= C::f<mp::conditional_c<Cmp::f<x, Min>::value>::f<Min, mp::conditional_c<Cmp::f<Max, x>::value>::f<Max, x>>>
clamp_with_c<int_t min, int_t max, Cmp = less<>, C = identity>= clamp_with<number<min>, number<max>, Cmp, C>
max<C = identity>= reverse_select<less<>, C>
min<C = identity>= reverse_select_flip<less<>, C>
pow<C = identity>::f<base, exponent>
not_<C = identity>::f<x>= C::f<number<!x::value>>
not_<not_<C>>::f<x>= C::f<number<bool(x::value)>>
numbers<C = listify>::f<int_t... ns>= C::f<number<ns>...>
add<C = identity>::f<xs...>= C::f<number<(xs::value + ...)>>
add0<C = identity>= if_<size<>, add<C>, always<number<0>, C>>
and_<C = identity>::f<xs...>= C::f<number<(xs::value && ... && true)>>
bit_and<C = identity>::f<xs...>= C::f<number<(xs::value & ...)>>
bit_and0<C = identity>= if_<size<>, bit_and<C>, always<number<0>, C>>
bit_not<C = identity>::f<x>= C::f<number<(~x::value)>>
bit_or<C = identity>::f<xs...>= C::f<number<(xs::value | ...)>>
bit_or0<C = identity>= if_<size<>, bit_or<C>, always<number<0>, C>>
dec<C = identity>::f<x>= C::f<number<(x::value-1)>>
div<C = identity>::f<xs...>= C::f<number<(... / xs::value)>>
div0<C = identity>= if_<size<>, div<C>, always<number<0>, C>>
div1<C = identity>= if_<size<>, div<C>, always<number<1>, C>>
equal<C = identity>::f<x, y>= C::f<number<(x::value == y::value)>>
equal_to<N, C = identity>= push_front<N, equal<C>>
equal_to_c<int_t n, C = identity>= equal_to<number<n>, C>
greater<C = identity>::f<x, y>= C::f<number<(x::value> y::value)>>
greater_equal<C = identity>::f<x, y>= C::f<number<(x::value>= y::value)>>
greater_equal_than<N, C = identity>= push_back<N, greater_equal<C>>
greater_equal_than_c<int_t n, C = identity>= greater_equal_than<number<n>, C>
greater_than<N, C = identity>= push_back<N, greater<C>>
greater_than_c<int_t n, C = identity>= greater_than<number<n>, C>
inc<C = identity>::f<x>= C::f<number<(x::value+1)>>
left_add<C = identity>::f<xs...>= C::f<number<(... + xs::value)>>
left_add0<C = identity>= if_<size<>, left_add<C>, always<number<0>, C>>
left_and<C = identity>::f<xs...>= C::f<number<(true && ... && xs::value)>>
left_bit_and<C = identity>::f<xs...>= C::f<number<(... & xs::value)>>
left_bit_and0<C = identity>= if_<size<>, left_bit_and<C>, always<number<0>, C>>
left_bit_or<C = identity>::f<xs...>= C::f<number<(... | xs::value)>>
left_bit_or0<C = identity>= if_<size<>, left_bit_or<C>, always<number<0>, C>>
left_mul<C = identity>::f<xs...>= C::f<number<(... * xs::value)>>
left_mul0<C = identity>= if_<size<>, left_mul<C>, always<number<0>, C>>
left_mul1<C = identity>= if_<size<>, left_mul<C>, always<number<1>, C>>
left_or<C = identity>::f<xs...>= C::f<number<(false || ... || xs::value)>>
left_xor<C = identity>::f<xs...>= C::f<number<(... ^ xs::value)>>
left_xor0<C = identity>= if_<size<>, left_xor<C>, always<number<0>, C>>
less<C = identity>::f<x, y>= C::f<number<(x::value < y::value)>>
less_equal<C = identity>::f<x, y>= C::f<number<(x::value <= y::value)>>
less_equal_than<N, C = identity>= push_back<N, less_equal<C>>
less_equal_than_c<int_t n, C = identity>= less_equal_than<number<n>, C>
less_than<N, C = identity>= push_back<N, less<C>>
less_than_c<int_t n, C = identity>= less_than<number<n>, C>
lshift<C = identity>::f<xs...>= C::f<number<(... << xs::value)>>
lshift0<C = identity>= if_<size<>, lshift<C>, always<number<0>, C>>
mod<C = identity>::f<xs...>= C::f<number<(... % xs::value)>>
mod0<C = identity>= if_<size<>, mod<C>, always<number<0>, C>>
mod1<C = identity>= if_<size<>, mod<C>, always<number<1>, C>>
mul<C = identity>::f<xs...>= C::f<number<(xs::value * ...)>>
mul0<C = identity>= if_<size<>, mul<C>, always<number<0>, C>>
mul1<C = identity>= if_<size<>, mul<C>, always<number<1>, C>>
neg<C = identity>::f<x>= C::f<number<(-x::value)>>
not_equal<C = identity>::f<x, y>= C::f<number<(x::value != y::value)>>
not_equal_to<N, C = identity>= push_front<N, not_equal<C>>
not_equal_to_c<int_t n, C = identity>= not_equal_to<number<n>, C>
or_<C = identity>::f<xs...>= C::f<number<(xs::value || ... || false)>>
rshift<C = identity>::f<xs...>= C::f<number<(...>> xs::value)>>
rshift0<C = identity>= if_<size<>, rshift<C>, always<number<0>, C>>
sub<C = identity>::f<xs...>= C::f<number<(... - xs::value)>>
sub0<C = identity>= if_<size<>, sub<C>, always<number<0>, C>>
unary_plus<C = identity>::f<x>= C::f<number<(+x::value)>>
xor0<C = identity>= if_<size<>, xor_<C>, always<number<0>, C>>
xor_<C = identity>::f<xs...>= C::f<number<(xs::value ^ ...)>>
to_bool<C = identity>::f<x>Converts a value to a true_ / false_.

Group: reduce

accumulate<F, C = identity>::f<state, seqs...>Computes the recursive invocation of F with the result of the previous invocation and each element of one or more lists traversed in parallel from the beginning to the end.
fold<F, C = identity>::f<xs...>Folds left over a list using a binary predicate.
fold_or<F, FallbackValue, C = identity>= if_<size<>, fold<F, C>, always<FallbackValue>>
fold_or_else<F, EmptyC, C = identity>Folds left over a list using a binary predicate.
fold_right<F, C = identity>::f<xs...>Folds right over a list using a binary predicate.
fold_right_or<F, FallbackValue, C = identity>= fold_right_or_else<F, always<FallbackValue>, C>
fold_right_or_else<F, EmptyC, C = identity>Folds right over a list using a binary predicate.
fold_balanced_tree<F, C = identity>::f<xs...>Folds tree over a list using a binary predicate.
fold_balanced_tree_or<F, FallbackValue, C = identity>= if_<size<>, fold_balanced_tree<F, C>, always<FallbackValue>>
fold_balanced_tree_or_else<F, EmptyC, C = identity>Folds tree over a list using a binary predicate.
fold_tree<F, C = identity>::f<xs...>Folds tree over a list using a binary predicate.
fold_tree_or<F, FallbackValue, C = identity>= if_<size<>, fold_tree<F, C>, always<FallbackValue>>
fold_tree_or_else<F, EmptyC, C = identity>Folds tree over a list using a binary predicate.
fold_xs<F, C = identity>Folds left over a list using a mulary predicate.
fold_xs_or<F, FallbackValue, C = identity>= partial_fold_xs_or_else_c<-1, F, always<FallbackValue>, C>
fold_xs_or_else<F, NoStateF = F, C = identity>Folds left over a list using a mulary predicate.
partial_fold_xs<OffsetEnd, F, C = identity>= partial_fold_xs_c<OffsetEnd::value, F, C>
partial_fold_xs_c<int_t OffsetEnd, F, C = identity>::f<xs...>As fold_xs, but stop at position OffsetEnd.
partial_fold_xs_or<OffsetEnd, F, FallbackValue, C = identity>= partial_fold_xs_or_else_c<OffsetEnd::value, F, always<FallbackValue>, C>
partial_fold_xs_or_c<int_t OffsetEnd, F, FallbackValue, C = identity>= partial_fold_xs_or_else_c<OffsetEnd, F, always<FallbackValue>, C>
partial_fold_xs_or_else<OffsetEnd, F, NoStateF = F, C = identity>= partial_fold_xs_or_else_c<OffsetEnd::value, F, NoStateF, C>
partial_fold_xs_or_else_c<int_t OffsetEnd, F, EmptyC, C = identity>As fold_xs_or_else, but stop at position OffsetEnd.
reverse_fold<F, C = identity>::f<xs...>Folds right over a list using a binary predicate.
reverse_fold_or<F, FallbackValue, C = identity>= reverse_fold_or_else<F, always<FallbackValue>, C>
reverse_fold_or_else<F, EmptyC, C = identity>Folds right over a list using a binary predicate.
reverse_fold_right<F, C = identity>::f<xs...>Folds right over a list using a binary predicate.
reverse_fold_right_or<F, FallbackValue, C = identity>= if_<size<>, reverse_fold_right<F, C>, always<FallbackValue>>
reverse_fold_right_or_else<F, EmptyC, C = identity>Folds right over a list using a binary predicate.
after<Seq, TC = listify, FC = clear<TC>>Find the sequence after a sub-sequence.
after<list<Ts...>, TC, FC>
before<Seq, TC = listify, FC = clear<TC>>Find the sequence before a sub-sequence.
before<list<Ts...>, TC, FC>::f<xs...>
before_after<Seq, TC = listify, FC = clear<TC>>= before_after_with<Seq, listify, listify, TC, FC>
before_after_with<Seq, SubC1 = listify, SubC2 = SubC1, TC = listify, FC = clear<TC>>Find the sequences before and after a sub-sequence.
before_after_with<list<Ts...>, SubC1, SubC2, TC, FC>::f<xs...>
conjunction<C = identity>Perform a logical AND on the sequence of value and returns the first value converted to false.
conjunction_with<Pred, C = identity>::f<xs...>Perform a logical AND on the sequence of value and returns the first value converted to false.
disjunction<C = identity>Perform a logical OR on the sequence of value and returns the first value converted to true.
disjunction_with<Pred, C = identity>::f<xs...>Perform a logical OR on the sequence of value and returns the first value converted to true.
drop_inclusive_until<Pred, TC = listify, FC = clear<TC>>= drop_until_extended_by_n_c<1, Pred, TC, FC>
drop_until<Pred, TC = listify, FC = clear<TC>>::f<xs...>Remove the first elements of a sequence that does not satisfy a predicate.
drop_until_extended_by_n<ExtendedByN, Pred, TC = listify, FC = clear<TC>>= drop_until_extended_by_n_c<ExtendedByN::value, Pred, TC, FC>
drop_until_extended_by_n_c<std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>::f<xs...>Remove the first minus at most ExtendedByN elements of a sequence that does not satisfy a predicate.
drop_inclusive_until_xs<Pred, TC = listify, FC = clear<TC>>= drop_until_extended_by_n_xs_c<1, Pred, TC, FC>
drop_until_extended_by_n_xs<ExtendedByN, Pred, TC = listify, FC = clear<TC>>= drop_until_extended_by_n_xs_c<ExtendedByN::value, Pred, TC, FC>
drop_until_extended_by_n_xs_c<std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>::f<xs...>Same as drop_until_extended_by_n_c, but for drop_until_xs.
drop_until_xs<Pred, TC = listify, FC = clear<TC>>::f<xs...>Remove the first elements of a sequence that does not satisfy a predicate.
partial_drop_inclusive_until_xs<OffsetEnd, Pred, TC = listify, FC = clear<TC>>= partial_drop_until_extended_by_n_xs_c<OffsetEnd::value, 1, Pred, TC, FC>
partial_drop_inclusive_until_xs_c<std::size_t OffsetEnd, Pred, TC = listify, FC = clear<TC>>= partial_drop_until_extended_by_n_xs_c<OffsetEnd, 1, Pred, TC, FC>
partial_drop_until_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC = listify, FC = clear<TC>>= partial_drop_until_extended_by_n_xs_c<OffsetEnd::value, ExtendedByN::value, Pred, TC, FC>
partial_drop_until_extended_by_n_xs_c<int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>::f<xs...>Same as drop_until_extended_by_n_xs_c, but stop searching at position OffsetEnd.
partial_drop_until_xs<OffsetEnd, Pred, TC = listify, FC = clear<TC>>= partial_drop_until_extended_by_n_xs_c<OffsetEnd::value, 0, Pred, TC, FC>
partial_drop_until_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = clear<TC>>= partial_drop_until_extended_by_n_xs_c<OffsetEnd, 0, Pred, TC, FC>
drop_inclusive_while<Pred, TC = listify, FC = clear<TC>>= drop_while_extended_by_n_c<1, Pred, TC, FC>
drop_while<Pred, TC = listify, FC = clear<TC>>::f<xs...>Remove the first elements of a sequence that satisfy a predicate.
drop_while_extended_by_n<ExtendedByN, Pred, TC = listify, FC = clear<TC>>= drop_while_extended_by_n_c<ExtendedByN::value, Pred, TC, FC>
drop_while_extended_by_n_c<std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>::f<xs...>Remove the first minus at most ExtendedByN elements of a sequence that satisfy a predicate.
drop_inclusive_while_xs<Pred, TC = listify, FC = clear<TC>>= drop_while_extended_by_n_xs_c<1, Pred, TC, FC>
drop_while_extended_by_n_xs<ExtendedByN, Pred, TC = listify, FC = clear<TC>>= drop_while_extended_by_n_xs_c<ExtendedByN::value, Pred, TC, FC>
drop_while_extended_by_n_xs_c<std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>::f<xs...>Same as drop_while_extended_by_n_c, but for drop_while_xs.
drop_while_xs<Pred, TC = listify, FC = clear<TC>>::f<xs...>Remove the first elements of a sequence that satisfy a predicate.
partial_drop_inclusive_while_xs<OffsetEnd, Pred, TC = listify, FC = clear<TC>>= partial_drop_while_extended_by_n_xs_c<OffsetEnd::value, 1, Pred, TC, FC>
partial_drop_inclusive_while_xs_c<std::size_t OffsetEnd, Pred, TC = listify, FC = clear<TC>>= partial_drop_while_extended_by_n_xs_c<OffsetEnd, 1, Pred, TC, FC>
partial_drop_while_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC = listify, FC = clear<TC>>= partial_drop_while_extended_by_n_xs_c<OffsetEnd::value, ExtendedByN::value, Pred, TC, FC>
partial_drop_while_extended_by_n_xs_c<int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>::f<xs...>Same as drop_while_extended_by_n_xs_c, but stop searching at position OffsetEnd.
partial_drop_while_xs<OffsetEnd, Pred, TC = listify, FC = clear<TC>>= partial_drop_while_extended_by_n_xs_c<OffsetEnd::value, 0, Pred, TC, FC>
partial_drop_while_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = clear<TC>>= partial_drop_while_extended_by_n_xs_c<OffsetEnd, 0, Pred, TC, FC>
find<T, TC = listify, FC = clear<TC>>= drop_until<is<T>, TC, FC>
find_if<Pred, TC = listify, FC = clear<TC>>Finds the first element that satisfy a predicate.
find_if_not<Pred, TC = listify, FC = clear<TC>>= drop_while<Pred, TC, FC>
find_last<T, TC = listify, FC = clear<TC>>= find_last_if<is<T>, TC, FC>
find_last_if<Pred, TC = listify, FC = clear<TC>>Finds the last element that satisfy a predicate.
find_last_if_not<Pred, TC = listify, FC = clear<TC>>= until_last_t<drop_while, Pred, TC, FC>
index_if<Pred, TC = identity, FC = size<>>::f<xs...>Finds the index of the first element of sequence that satisfies the predicate Pred.
index_if_xs<Pred, TC = identity, FC = size<>>::f<xs...>Search the index of first sub-sequence that satisfy a predicate.
index_of<T, TC = identity, FC = size<>>Finds the index of the first element of sequence that is a type T.
partial_index_if_xs<OffsetEnd, Pred, TC = identity, FC = size<>>= partial_index_if_xs_c<OffsetEnd::value, Pred, TC, FC>
partial_index_if_xs_c<int_t OffsetEnd, Pred, TC = identity, FC = size<>>::f<xs...>Same as index_if_xs, but stop searching at position OffsetEnd.
lower_bound<x, Cmp = less<>, TC = listify, FC = TC>::f<xs...>Finds first element that is not less than (i.e. greater or equal to) x.
lower_bound_c<int_t x, Cmp = less<>, TC = listify, FC = TC>= lower_bound<number<x>, Cmp, TC, FC>
lower_bound_than<x, TC = listify, FC = TC>= lower_bound<x, less<>, TC, FC>
lower_bound_than_c<int_t x, TC = listify, FC = TC>= lower_bound<number<x>, less<>, TC, FC>
last_max_element<C = identity>= last_max_element_with<less<>, C>
last_max_element_with<Cmp = less<>, C = identity>::f<xs...>Returns the greatest element.
max_element<C = identity>= max_element_with<less<>, C>
max_element_with<Cmp = less<>, C = identity>::f<xs...>Returns the greatest element.
last_min_element<C = identity>= last_min_element_with<less<>, C>
last_min_element_with<Cmp = less<>, C = identity>::f<xs...>Returns the smallest element.
min_element<C = identity>= min_element_with<less<>, C>
min_element_with<Cmp = less<>, C = identity>::f<xs...>Returns the smallest element.
partial_search<StopWhenAtLeast, Pred, TC = listify, FC = clear<TC>>Same search, but it stops when there is StopWhenAtLeast::value element or less.
partial_search_before<StopWhenAtLeast, Pred, TC = listify, FC = clear<TC>>Same search_before, but it stops when there is StopWhenAtLeast::value element or less.
partial_search_before_c<std::size_t StopWhenAtLeast, Pred, TC = listify, FC = clear<TC>>= partial_take_until_xs_c< -int_t{StopWhenAtLeast}-1, Pred, TC, FC>
partial_search_before_extended_by_n<StopWhenAtLeast, ExtendedByN, Pred, TC = listify, FC = clear<TC>>= partial_take_until_extended_by_n_xs_c< -int_t{StopWhenAtLeast::value}-1, ExtendedByN::value, Pred, TC, FC>
partial_search_before_extended_by_n_c<std::size_t StopWhenAtLeast, std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>Same search_before, but it stops when there is StopWhenAtLeast::value element or less.
partial_search_c<std::size_t StopWhenAtLeast, Pred, TC = listify, FC = clear<TC>>= partial_drop_until_xs_c< -int_t{StopWhenAtLeast}-1, Pred, TC, FC>
search<Pred, TC = listify, FC = clear<TC>>Search the first sub-sequence that satisfy a predicate.
search_before<Pred, TC = listify, FC = clear<TC>>Search elements before sub-sequence that satisfy a predicate.
search_before_extended_by_n<ExtendedByN, Pred, TC = listify, FC = clear<TC>>Search elements before sub-sequence that satisfy a predicate.
search_before_extended_by_n_c<std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>= take_until_extended_by_n_xs_c<ExtendedByN, Pred, TC, FC>
skip_inclusive_until<Pred, TC = listify, FC = TC>= drop_inclusive_until<Pred, TC, clear<FC>>
skip_until<Pred, TC = listify, FC = TC>Remove the first elements of a sequence that does not satisfy a predicate.
skip_until_extended_by_n<ExtendedByN, Pred, TC = listify, FC = TC>= drop_until_extended_by_n_c< ExtendedByN::value, Pred, TC, clear<FC>>
skip_until_extended_by_n_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>= drop_until_extended_by_n_c< ExtendedByN, Pred, TC, clear<FC>>
partial_skip_inclusive_until_xs<OffsetEnd, Pred, TC = listify, FC = TC>= partial_drop_inclusive_until_xs<OffsetEnd, Pred, TC, clear<FC>>
partial_skip_inclusive_until_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = TC>= partial_drop_inclusive_until_xs_c<OffsetEnd, Pred, TC, clear<FC>>
partial_skip_until_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC = listify, FC = TC>= partial_drop_until_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC, clear<FC>>
partial_skip_until_extended_by_n_xs_c<int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = TC>= partial_drop_until_extended_by_n_xs_c<OffsetEnd, ExtendedByN, Pred, TC, clear<FC>>
partial_skip_until_xs<OffsetEnd, Pred, TC = listify, FC = TC>= partial_drop_until_xs<OffsetEnd, Pred, TC, clear<FC>>
partial_skip_until_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = TC>Same as drop_until_xs, but stop searching at position OffsetEnd.
skip_inclusive_until_xs<Pred, TC = listify, FC = TC>= drop_inclusive_until_xs<Pred, TC, clear<FC>>
skip_until_extended_by_n_xs<ExtendedByN, Pred, TC = listify, FC = TC>= drop_until_extended_by_n_xs<ExtendedByN, Pred, TC, clear<FC>>
skip_until_extended_by_n_xs_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>= drop_until_extended_by_n_xs_c<ExtendedByN, Pred, TC, clear<FC>>
skip_until_xs<Pred, TC = listify, FC = TC>Remove the first elements of a sequence that does not satisfy a predicate.
skip_inclusive_while<Pred, TC = listify, FC = TC>= drop_inclusive_while<Pred, TC, clear<FC>>
skip_while<Pred, TC = listify, FC = TC>Remove the first elements of a sequence that satisfy a predicate.
skip_while_extended_by_n<ExtendedByN, Pred, TC = listify, FC = TC>= drop_while_extended_by_n_c< ExtendedByN::value, Pred, TC, clear<FC>>
skip_while_extended_by_n_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>= drop_while_extended_by_n_c< ExtendedByN, Pred, TC, clear<FC>>
partial_skip_inclusive_while_xs<OffsetEnd, Pred, TC = listify, FC = TC>= partial_drop_inclusive_while_xs<OffsetEnd, Pred, TC, clear<FC>>
partial_skip_inclusive_while_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = TC>= partial_drop_inclusive_while_xs_c<OffsetEnd, Pred, TC, clear<FC>>
partial_skip_while_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC = listify, FC = TC>= partial_drop_while_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC, clear<FC>>
partial_skip_while_extended_by_n_xs_c<int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = TC>= partial_drop_while_extended_by_n_xs_c<OffsetEnd, ExtendedByN, Pred, TC, clear<FC>>
partial_skip_while_xs<OffsetEnd, Pred, TC = listify, FC = TC>= partial_drop_while_xs<OffsetEnd, Pred, TC, clear<FC>>
partial_skip_while_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = TC>Same as skip_while_xs, but stop searching at position OffsetEnd.
skip_inclusive_while_xs<Pred, TC = listify, FC = TC>= drop_inclusive_while_xs<Pred, TC, clear<FC>>
skip_while_extended_by_n_xs<ExtendedByN, Pred, TC = listify, FC = TC>= drop_while_extended_by_n_xs<ExtendedByN, Pred, TC, clear<FC>>
skip_while_extended_by_n_xs_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>= drop_while_extended_by_n_xs_c<ExtendedByN, Pred, TC, clear<FC>>
skip_while_xs<Pred, TC = listify, FC = TC>Remove the first elements of a sequence that satisfy a predicate.
take_inclusive_until<Pred, TC = listify, FC = TC>= take_until_extended_by_n_c<1, Pred, TC, FC>
take_until<Pred, TC = listify, FC = TC>::f<xs...>Extract the first elements of a sequence that does not satisfy a predicate.
take_until_extended_by_n<ExtendedByN, Pred, TC = listify, FC = TC>= take_until_extended_by_n_c<ExtendedByN::value, Pred, TC, FC>
take_until_extended_by_n_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>::f<xs...>Extract the first plus at most ExtendedByN elements of a sequence that does not satisfy a predicate.
partial_take_inclusive_until_xs<OffsetEnd, Pred, TC = listify, FC = TC>= partial_take_until_extended_by_n_xs_c<OffsetEnd::value, 1, Pred, TC, FC>
partial_take_inclusive_until_xs_c<std::size_t OffsetEnd, Pred, TC = listify, FC = TC>= partial_take_until_extended_by_n_xs_c<OffsetEnd, 1, Pred, TC, FC>
partial_take_until_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC = listify, FC = TC>= partial_take_until_extended_by_n_xs_c<OffsetEnd::value, ExtendedByN::value, Pred, TC, FC>
partial_take_until_extended_by_n_xs_c<int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = TC>::f<xs...>Same as take_until_extended_by_n_xs_c, but stop searching at position OffsetEnd.
partial_take_until_xs<OffsetEnd, Pred, TC = listify, FC = TC>= partial_take_until_extended_by_n_xs_c<OffsetEnd::value, 0, Pred, TC, FC>
partial_take_until_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = TC>= partial_take_until_extended_by_n_xs_c<OffsetEnd, 0, Pred, TC, FC>
take_inclusive_until_xs<Pred, TC = listify, FC = TC>= take_until_extended_by_n_xs_c<1, Pred, TC, FC>
take_until_extended_by_n_xs<ExtendedByN, Pred, TC = listify, FC = TC>= take_until_extended_by_n_xs_c<ExtendedByN::value, Pred, TC, FC>
take_until_extended_by_n_xs_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>::f<xs...>Same as take_until_extended_by_n_c, but for take_until_xs.
take_until_xs<Pred, TC = listify, FC = TC>::f<xs...>Extracts the first elements of a sequence that does not satisfy a predicate.
take_inclusive_while<Pred, TC = listify, FC = TC>= take_while_extended_by_n_c<1, Pred, TC, FC>
take_while<Pred, TC = listify, FC = TC>::f<xs...>Extract the first elements of a sequence that satisfy a predicate.
take_while_extended_by_n<ExtendedByN, Pred, TC = listify, FC = TC>= take_while_extended_by_n_c<ExtendedByN::value, Pred, TC, FC>
take_while_extended_by_n_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>::f<xs...>Extract the first plus at most ExtendedByN elements of a sequence that satisfy a predicate.
partial_take_inclusive_while_xs<OffsetEnd, Pred, TC = listify, FC = TC>= partial_take_while_extended_by_n_xs_c<OffsetEnd::value, 1, Pred, TC, FC>
partial_take_inclusive_while_xs_c<std::size_t OffsetEnd, Pred, TC = listify, FC = TC>= partial_take_while_extended_by_n_xs_c<OffsetEnd, 1, Pred, TC, FC>
partial_take_while_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC = listify, FC = TC>= partial_take_while_extended_by_n_xs_c<OffsetEnd::value, ExtendedByN::value, Pred, TC, FC>
partial_take_while_extended_by_n_xs_c<int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = TC>::f<xs...>Same as take_while_extended_by_n_xs_c, but stop searching at position OffsetEnd.
partial_take_while_xs<OffsetEnd, Pred, TC = listify, FC = TC>= partial_take_while_extended_by_n_xs_c<OffsetEnd::value, 0, Pred, TC, FC>
partial_take_while_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = TC>= partial_take_while_extended_by_n_xs_c<OffsetEnd, 0, Pred, TC, FC>
take_inclusive_while_xs<Pred, TC = listify, FC = TC>= take_while_extended_by_n_xs_c<1, Pred, TC, FC>
take_while_extended_by_n_xs<ExtendedByN, Pred, TC = listify, FC = TC>= take_while_extended_by_n_xs_c<ExtendedByN::value, Pred, TC, FC>
take_while_extended_by_n_xs_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>::f<xs...>Same as take_while_extended_by_n_c, but for take_while_xs.
take_while_xs<Pred, TC = listify, FC = TC>::f<xs...>Extracts the first elements of a sequence that satisfy a predicate.
upper_bound<x, Cmp = less<>, TC = listify, FC = TC>Finds first element that is greater that x.
upper_bound_c<int_t x, Cmp = less<>, TC = listify, FC = TC>= upper_bound<number<x>, Cmp, TC, FC>
upper_bound_than<x, TC = listify, FC = TC>= upper_bound<x, less<>, TC, FC>
upper_bound_than_c<int_t x, TC = listify, FC = TC>= upper_bound<number<x>, less<>, TC, FC>

Group: set

set_all_contains<x, C = identity>::f<Sets...>Checks if x is an element of all set Sets.
set_any_contains<x, C = identity>::f<Sets...>Checks if x is an element of any set Sets.
set_contains<x, C = identity>::f<xs...>Checks if x is an element of the set whose elements are xs.
set_none_contains<x, C = identity>::f<Sets...>Checks if x is an element of none set Sets.
set_not_contains<x, C = identity>Checks if x is not an element of the set whose elements are xs.
set_difference<C = listify>::f<L, Sets...>Removes the elements of the list L that appear in any of the sets Sets.
set_find<x, TC = identity, FC = always<na>>::f<xs...>Finds the element x in the set.
set_find_or<x, FT>= set_find<x, identity, always<FT>>
set_find_or_else<x, FC>= set_find<x, identity, FC>
set_intersection<C = listify>::f<L, Sets...>Returns a set that contains the elements that occur in all of the sets Sets.
set_push_back<x, C = listify>::f<xs...>Appends x to the end of the set whose elements are xs if not already in xs.
set_push_back_elements<C = listify>::f<Set, xs...>Appends to the end of the set Set the elements of xs which are not already in Set.
set_push_front<x, C = listify>::f<xs...>Appends x to the beginning of the set whose elements are xs if not already in xs.
set_push_front_elements<C = listify>::f<Set, xs...>Appends to the beginning of the set Set the elements of xs which are not already in Set.
set_union<C = listify>::f<Set, Ls...>Appends to the end of the set Set the elements of Ls which are not already in Set.

Group: trait

alignof_<C = identity>::f<x>Wrapper for alignof keyword
traits::emp::aligned_storage<Len, Alignment...>= std::aligned_storage< Len::value, Alignment::value...>::type
traits::aligned_storage<C = identity>::f<Len, Alignment...>= C::f<std::aligned_storage<Len::value, Alignment::value...>::type>
traits::emp::aligned_union<len, xs...>= std::aligned_union<len::value, xs...>::type
traits::aligned_union<C = identity>::f<len, xs...>= C::f<std::aligned_union<len::value, xs...>::type>
traits::extent<C = identity>::f<x, i>= C::f<std::extent<x, i::value>::type>
traits::emp::extent<x, i = number<0>>= std::extent<x, i::value>::type
traits::emp::is_nothrow_convertible<xs...>= std::bool_constant<std::is_nothrow_convertible_v<xs...>>
traits::is_nothrow_convertible<C = identity>::f<xs...>= C::f<std::bool_constant<std::is_nothrow_convertible_v<xs...>>>
traits::is_nothrow_convertible<identity>::f<xs...>= std::bool_constant<std::is_nothrow_convertible_v<xs...>>
has_type<C = identity>::f<x>Checks whether x has a type member.
has_value_type<C = identity>::f<x>Checks whether x has a type member.
is_specialization_of<template<class...> Tpl, C = identity>::f<x>Checks whether x is Tpl<xs...>
lazy_voidEquivalent to std::void_t, but always resolved in a lazy way.
JLN_MP_LAZY_VOID(...)Equivalent to emp::lazy_void<xs...> while minimizing template instantiation.
sizeof_<C = identity>::f<x>Wrapper for sizeof keyword
type_<C = identity>::f<x>Function for x::type.
value_type<C = identity>::f<x>Function for x::value_type.
value_type<identity>::f<x>= x::value_type

Group: utility

always<x, C = identity>::f<xs...>Always evaluate at an arbitrary value.
conditional<bool_>= conditional_c<bool(bool_::value)>
conditional_c<bool>
conditional_c<false>::f<true_value, false_value>= false_value
conditional_c<true>::f<true_value, false_value>= true_value
default_make_index_tag
make_index<C = identity>Generates a unique index per type.
make_index_for<Tag = default_make_index_tag, C = identity>::f<T>Generates a unique index per type for a specified tag.
default_make_id_tag
id_info<int const* id>
id_t= int const*
make_id<C = identity>Generates a unique type id per type.
make_id_for<Tag = default_make_id_tag, C = identity>::f<T>Generates a unique type id per type for a specified tag.
inherit<Bases...>Class that inherits all Bases types.
inherit_safely<Bases...>Class that inherits all Bases types wrapped in a list<> type.
is<T, C = identity>::f<x>= C::f<number<std::is_same_v<T, x>>>
is_base_of<Derived, C = identity>::f<x>Wrapper for JLN_MP_IS_BASE_OF() / std::is_base_of
JLN_MP_IS_BASE_OF(Base, Derived)Uses a compiler builtin or std::is_base_if_v.
is_not<T, C = identity>= is<T, not_<C>>
iterate<n, F, C = identity>Apply a function n times to its argument.
iterate_c<uint_t n, F, C = identity>::f<x>Apply a function n times to its argument.
random<C = identity, auto v = []{}>= random_for<default_make_index_tag, C, v>
random_for<Tag = default_make_index_tag, C = identity, auto = []{}>::f<xs...>Generate a random number for a specified tag on each call with different xs.
JLN_MP_RANDOM_SEED_TIMELess than 0 to not rely on the __TIME__ macro (default) ; 0 for use __TIME__ macro as seed ; greater than 0 for used this value as a replacement of __TIME__ macro.
JLN_MP_RANDOM_SEED_WW value for the seed of random.
JLN_MP_RANDOM_SEED_ZZ value for the seed of random.
rewrap_unpack<C>::f<L, xs...>Rewrap result of unpack<C> in the same type as L.
rewrap_unpack_append<C>::f<L, xs...>Rewrap result of unpack_append<C> in the same type as L.
unpack<C>::f<seq, xs...>Turns a typelist into a sequence of those types.
unpack_append<C>::f<seq, xs...>Turns a typelist into a sequence of those types.
unpack_append_v<C>::f<seq, xs...>Turns a typelist into a sequence of those types.
unpack_v<C>::f<seq, xs...>Turns a typelist into a sequence of those types.

Group: value

as_val<C = identity>::f<x>Converts x to val.
has_value<C = identity>::f<x>Checks whether x has a value member.
is_val<C = identity>::f<x>Checks whether x is a val.
typed_value<T, T v>= val<v>
val<auto v>::value= v
value_from<T>= val<T::value>
val_add<C = identity>::f<xs...>= C::f<val<(xs::value + ...)>>
val_add0<C = identity>= if_<size<>, val_add<C>, always<val<0>, C>>
val_and<C = identity>::f<xs...>= C::f<val<(xs::value && ... && true)>>
val_bit_and<C = identity>::f<xs...>= C::f<val<(xs::value & ...)>>
val_bit_and0<C = identity>= if_<size<>, val_bit_and<C>, always<val<0>, C>>
val_bit_not<C = identity>::f<x>= C::f<val<(~x::value)>>
val_bit_or<C = identity>::f<xs...>= C::f<val<(xs::value | ...)>>
val_bit_or0<C = identity>= if_<size<>, val_bit_or<C>, always<val<0>, C>>
val_dec<C = identity>::f<x>= C::f<val<(x::value-1)>>
val_div<C = identity>::f<xs...>= C::f<val<(... / xs::value)>>
val_div0<C = identity>= if_<size<>, val_div<C>, always<val<0>, C>>
val_div1<C = identity>= if_<size<>, val_div<C>, always<val<1>, C>>
val_equal<C = identity>::f<x, y>= C::f<val<(x::value == y::value)>>
val_equal_to<N, C = identity>= push_back<N, val_equal<C>>
val_equal_to_c<auto x, C = identity>= val_equal_to<val<x>, C>
val_greater<C = identity>::f<x, y>= C::f<val<(x::value> y::value)>>
val_greater_equal<C = identity>::f<x, y>= C::f<val<(x::value>= y::value)>>
val_greater_equal_than<N, C = identity>= push_back<N, val_greater_equal<C>>
val_greater_equal_than_c<auto x, C = identity>= val_greater_equal_than<val<x>, C>
val_greater_than<N, C = identity>= push_back<N, val_greater<C>>
val_greater_than_c<auto x, C = identity>= val_greater_than<val<x>, C>
val_inc<C = identity>::f<x>= C::f<val<(x::value+1)>>
val_left_add<C = identity>::f<xs...>= C::f<val<(... + xs::value)>>
val_left_add0<C = identity>= if_<size<>, val_left_add<C>, always<val<0>, C>>
val_left_and<C = identity>::f<xs...>= C::f<val<(true && ... && xs::value)>>
val_left_bit_and<C = identity>::f<xs...>= C::f<val<(... & xs::value)>>
val_left_bit_and0<C = identity>= if_<size<>, val_bit_and<C>, always<val<0>, C>>
val_left_bit_or<C = identity>::f<xs...>= C::f<val<(... | xs::value)>>
val_left_bit_or0<C = identity>= if_<size<>, val_left_bit_or<C>, always<val<0>, C>>
val_left_mul<C = identity>::f<xs...>= C::f<val<(... * xs::value)>>
val_left_mul0<C = identity>= if_<size<>, val_left_mul<C>, always<val<0>, C>>
val_left_mul1<C = identity>= if_<size<>, val_left_mul<C>, always<val<1>, C>>
val_left_or<C = identity>::f<xs...>= C::f<val<(false || ... || xs::value)>>
val_left_xor<C = identity>::f<xs...>= C::f<val<(... ^ xs::value)>>
val_left_xor0<C = identity>= if_<size<>, val_left_xor<C>, always<val<0>, C>>
val_less<C = identity>::f<x, y>= C::f<val<(x::value < y::value)>>
val_less_equal<C = identity>::f<x, y>= C::f<val<(x::value <= y::value)>>
val_less_equal_than<N, C = identity>= push_back<N, val_less_equal<C>>
val_less_equal_than_c<auto x, C = identity>= val_less_equal_than<val<x>, C>
val_less_than<N, C = identity>= push_back<N, val_less<C>>
val_less_than_c<auto x, C = identity>= val_less_than<val<x>, C>
val_lshift<C = identity>::f<xs...>= C::f<val<(... << xs::value)>>
val_lshift0<C = identity>= if_<size<>, val_lshift<C>, always<val<0>, C>>
val_mod<C = identity>::f<xs...>= C::f<val<(... % xs::value)>>
val_mod0<C = identity>= if_<size<>, val_mod<C>, always<val<0>, C>>
val_mod1<C = identity>= if_<size<>, val_mod<C>, always<val<1>, C>>
val_mul<C = identity>::f<xs...>= C::f<val<(xs::value * ...)>>
val_mul0<C = identity>= if_<size<>, val_mul<C>, always<val<0>, C>>
val_mul1<C = identity>= if_<size<>, val_mul<C>, always<val<1>, C>>
val_neg<C = identity>::f<x>= C::f<val<(-x::value)>>
val_not<C = identity>::f<x>= C::f<val<(!x::value)>>
val_not_equal<C = identity>::f<x, y>= C::f<val<(x::value != y::value)>>
val_not_equal_to<N, C = identity>= push_back<N, val_not_equal<C>>
val_not_equal_to_c<auto x, C = identity>= val_not_equal_to<val<x>, C>
val_or<C = identity>::f<xs...>= C::f<val<(xs::value || ... || false)>>
val_rshift<C = identity>::f<xs...>= C::f<val<(...>> xs::value)>>
val_rshift0<C = identity>= if_<size<>, val_rshift<C>, always<val<0>, C>>
val_sub<C = identity>::f<xs...>= C::f<val<(... - xs::value)>>
val_sub0<C = identity>= if_<size<>, val_sub<C>, always<val<0>, C>>
val_unary_plus<C = identity>::f<x>= C::f<val<(+x::value)>>
val_xor<C = identity>::f<xs...>= C::f<val<(xs::value ^ ...)>>
val_xor0<C = identity>= if_<size<>, val_xor<C>, always<val<0>, C>>
typed_values<C = listify>::f<T, xs...>= C::f<val<T(xs::value)>...>
values<C = listify>::f<xs...>= C::f<val<xs::value>...>

Detailed descriptions

Group: algorithm

<jln/mp/algorithm/unfold.hpp>

Test file: test/src/algorithm/unfold.cpp

None

Implementation
stop_recursion

Some<value, next = value>

Implementation
list<value, next>

unfold<F, C = listify>

Return: list

Unfold F until returning None.

When F returns Some<value,next>, value is added to the results list and next is used for the next iteration.

Semantics
unfold<
  if_<
    less_than_c<5>,
    inc<cfe<Some>>,
    None
  >
>::f<number<0>>
==
list<number<1>, number<2>, number<3>, number<4>, number<5>>

emp::unfold<state, F, C = mp::listify> = mp::unfold<F, C>::f<state>

<jln/mp/algorithm/all_of.hpp>

Test file: test/src/algorithm/all_of.cpp

all_of<Pred, C = identity>::f<xs...>

Return: true_ / false_

Checks whether a predicate holds for all elements of a sequence.

emp::all_of<L, Pred, C = mp::identity> = emp::unpack<L, mp::all_of<Pred, C>>

bool emp::all_of_v<L, Pred, C = mp::identity> = emp::unpack<L, mp::all_of<Pred, C>>::value

emp::all_of_xs<Pred, xs...> = mp::all_of<Pred>::f<xs...>

bool emp::all_of_xs_v<Pred, xs...> = mp::all_of<Pred>::f<xs...>::value

<jln/mp/algorithm/anticirculant_matrix.hpp>

Test file: test/src/algorithm/anticirculant_matrix.cpp

anticirculant_matrix<C = listify>

anticirculant_matrix_with<F = listify, C = listify>::f<xs...>

Return: value

square matrix in which all row vectors are composed of the same elements and each row vector is rotated one element to the left relative to the preceding row vector.

Semantics
anticirculant_matrix_with<>::f<a, b, c, d>
== list<
  list<a, b, c, d>,
  list<b, c, d, a>,
  list<c, d, a, b>,
  list<d, a, b, c>
>

emp::anticirculant_matrix<L, C = mp::listify> = emp::unpack<L, mp::anticirculant_matrix<C>>

emp::anticirculant_matrix_with<L, F, C = mp::listify> = emp::unpack<L, mp::anticirculant_matrix_with<F, C>>

<jln/mp/algorithm/any_of.hpp>

Test file: test/src/algorithm/any_of.cpp

any_of<Pred, C = identity>

Return: true_ / false_

Checks whether a predicate holds for at least some element of a sequence.

Implementation
none_of<Pred, not_<C>>

emp::any_of<L, Pred, C = mp::identity> = emp::unpack<L, mp::any_of<Pred, C>>

bool emp::any_of_v<L, Pred, C = mp::identity> = emp::unpack<L, mp::any_of<Pred, C>>::value

emp::any_of_xs<Pred, xs...> = mp::any_of<Pred>::f<xs...>

bool emp::any_of_xs_v<Pred, xs...> = mp::any_of<Pred>::f<xs...>::value

<jln/mp/algorithm/arrange.hpp>

Test file: test/src/algorithm/arrange.cpp

arrange<Ints, C = listify>

Return: list

Uses a list of indices to reorder a sequence.

Semantics

Equivalent to

arrange<numbers<0, 2, 0>>::f<a, b, c, d> == list<a, c, a>

arrange_c<int... ints>

Implementation
arrange_c_with<listify, ints...>

arrange_c_with<C, int... ints>::f<xs...>

emp::arrange<L, Ints, C = listify> = emp::unpack<L, mp::arrange<Ints, C>>

emp::arrange_c<L, int... ints> = emp::unpack<L, arrange_c_with<listify, ints...>>

emp::arrange_with_c<L, C, int... ints> = emp::unpack<L, arrange_c_with<C, ints...>>

<jln/mp/algorithm/circulant_matrix.hpp>

Test file: test/src/algorithm/circulant_matrix.cpp

circulant_matrix<C = listify>

Implementation
circulant_matrix_with<listify, C>

circulant_matrix_with<F = listify, C = listify>::f<xs...>

Return: value

square matrix in which all row vectors are composed of the same elements and each row vector is rotated one element to the right relative to the preceding row vector.

Semantics
circulant_matrix_with<>::f<a, b, c, d>
== list<
  list<a, b, c, d>,
  list<d, a, b, c>,
  list<c, d, a, b>,
  list<b, c, d, a>
>

emp::circulant_matrix<L, C = mp::listify> = emp::unpack<L, mp::circulant_matrix<C>>

emp::circulant_matrix_with<L, F, C = mp::listify> = emp::unpack<L, mp::circulant_matrix_with<F, C>>

<jln/mp/algorithm/contains.hpp>

Test file: test/src/algorithm/contains.cpp

contains<x, C = identity>

Return: true_ / false_

Checks whether a value is contained in a sequence.

Implementation
any_of<is<x>, C>

emp::contains<L, x, C = mp::identity> = emp::unpack<L, mp::contains<x, C>>

bool emp::contains_v<L, x, C = mp::identity> = emp::unpack<L, mp::contains<x, C>>::value

<jln/mp/algorithm/count.hpp>

Test file: test/src/algorithm/count.cpp

count<x, C = identity>

Counts all elements identical to a value.

Implementation
transform<is<x>, add0<C>>

count_if<Pred, C = identity>

Counts all elements that satisfy a predicate.

Implementation
transform<Pred, add0<C>>

emp::count<L, x, C = mp::identity> = emp::unpack<L, mp::count<x, C>>

emp::count_if<L, Pred, C = mp::identity> = emp::unpack<L, mp::count_if<Pred, C>>

int_t emp::count_if_v<L, Pred, C = mp::identity> = emp::unpack<L, mp::count_if<Pred, C>>::value

int_t emp::count_v<L, x, C = mp::identity> = emp::unpack<L, mp::count<x, C>>::value

int_t emp::count_xs_v<x, xs...> = (std::is_same_v<x, xs> + ... + 0)

<jln/mp/algorithm/counter.hpp>

Test file: test/src/algorithm/counter.cpp

counter<C = listify>

Return: sequence of list of type and number

Counts all distinct elements and returns a list of pairs containing the type and the repeat count.

Elements are sorted in order of first appearance.

Implementation
counter_wrapped_with<listify, C>
Semantics
counter<F>::f<int, int, char, double, int, double>
== list<
  list<int, number<3>>,
  list<char, number<1>>,
  list<double, number<2>>
>

counter_wrapped_with<F, C = listify>::f<xs...>

Return: sequence of list of type and number

Counts all distinct elements and returns a list of pairs containing the type and the repeat count.

Elements are sorted in order of first appearance.

Semantics
counter<F>::f<int, int, char, double, int, double>
== list<
  F::f<int, number<3>>,
  F::f<char, number<1>>,
  F::f<double, number<2>>
>

emp::counter<L, C = mp::listify> = emp::unpack<L, mp::counter<C>>

emp::counter_wrapped_with<L, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::counter_wrapped_with<F, C>>

<jln/mp/algorithm/ends_with.hpp>

Test file: test/src/algorithm/ends_with.cpp

ends_with<Seq, C = identity>

Return: true_ / false_

Checks if the sequence ends with the given prefix.

ends_with<list<Ts...>, C>::f<xs...>

emp::ends_with<L, Seq, C = mp::identity> = emp::unpack<L, ends_with<Seq, C>>

bool emp::ends_with_v<L, Seq, C = mp::identity> = emp::unpack<L, ends_with<Seq, C>>::value

<jln/mp/algorithm/flatten.hpp>

Test file: test/src/algorithm/flatten.cpp

flatten<cfe<S, identity>, C>::f<xs...>

flatten<S = cfe<list>, C = listify>

Return: sequence

Recursive version of flatten_once.

Semantics
call<flatten<>, list<a, b>, c, list<list<d, e>, f>
==
list<a, b, c, d, e, f>

flatten_f<template<class...> S, C = listify>

Implementation
flatten<cfe<S>, C>

flatten_for_f<template<class...> S, C = identity>

Implementation
flatten<cfe<S>, cfe<S, C>>

flatten_once<S = cfe<list>, C = listify>

Return: sequence

Remove 1 dimension level from a sequence.

Semantics
call<flatten_once<>, list<a, b>, c, list<list<d, e>, f>
==
list<a, b, c, list<d, e>, f>

flatten_once<cfe<S, identity>, C>::f<xs...>

flatten_once_f<template<class...> S, C = listify>

Implementation
flatten_once<cfe<S>, C>

flatten_once_for_f<template<class...> S, C = identity>

Implementation
flatten_once<cfe<S>, cfe<S, C>>

emp::flatten<L, S = wrapper<L>, C = mp::listify> = emp::unpack<L, mp::flatten<S, C>>

emp::flatten_f<L, template<class...> S, C = mp::listify> = emp::unpack<L, mp::flatten_f<S, C>>

emp::flatten_for_f<L, template<class...> S, C = mp::identity> = emp::unpack<L, mp::flatten_for_f<S, C>>

emp::flatten_once<L, S = wrapper<L>, C = mp::listify> = emp::unpack<L, mp::flatten_once<S, C>>

emp::flatten_once_f<L, template<class...> S, C = mp::listify> = emp::unpack<L, mp::flatten_once_f<S, C>>

emp::flatten_once_for_f<L, template<class...> S, C = mp::identity> = emp::unpack<L, mp::flatten_once_for_f<S, C>>

<jln/mp/algorithm/intersperse.hpp>

Test file: test/src/algorithm/intersperse.cpp

intersperse<x, C = listify>::f<xs...>

Return: list

Inserts a value between each element of a sequence.

emp::intersperse<L, x, C = mp::listify> = emp::unpack<L, mp::intersperse<x, C>>

<jln/mp/algorithm/is_disjoint.hpp>

Test file: test/src/algorithm/is_disjoint.cpp

is_disjoint<C = identity>

Return: true_ / false_

Checks whether value in seqs[0] are disjoint from the value in seqs[1:].

Returns mp::true_ when sizeof...(seqs) < 2

Implementation
is_disjoint_with<same<>, C>

is_disjoint_with<Cmp = same<>, C = identity>::f<seqs...>

Return: true_ / false_

Checks whether value in seqs[0] are disjoint from the value in seqs[1:].

Returns mp::true_ when sizeof...(seqs) < 2

emp::is_disjoint<L1, L2, C = mp::identity> = is_disjoint<C>::f<L1, L2>

bool emp::is_disjoint_v<L1, L2> = is_disjoint<>::f<L1, L2>::value

emp::is_disjoint_with<L1, L2, Cmp = same<>, C = mp::identity> = is_disjoint_with<Cmp, C>::f<L1, L2>

bool emp::is_disjoint_with_v<L1, L2, Cmp = same<>> = is_disjoint_with<Cmp>::f<L1, L2>::value

<jln/mp/algorithm/is_sorted.hpp>

Test file: test/src/algorithm/is_sorted.cpp

is_sorted<Cmp = less<>, C = identity>::f<xs...>

Return: true_ / false_

Checks whether a sequence is sorted.

emp::is_sorted<L, Cmp = mp::less<>, C = mp::identity> = emp::unpack<L, mp::is_sorted<Cmp, C>>

bool emp::is_sorted_v<L, Cmp = mp::less<>, C = mp::identity> = emp::unpack<L, mp::is_sorted<Cmp, C>>::value

<jln/mp/algorithm/is_subset.hpp>

Test file: test/src/algorithm/is_subset.cpp

is_subset<C = identity>

Return: true_ / false_

Checks whether value in seqs[0] are subset from the value in seqs[1:].

Returns mp::true_ when sizeof...(seqs) < 2

Implementation
is_subset_with<same<>, C>

is_subset_with<Cmp = same<>, C = identity>::f<seqs...>

Return: true_ / false_

Checks whether value in seqs[0] are subset from the value in seqs[1:].

Returns mp::true_ when sizeof...(seqs) < 2

emp::is_subset<L1, L2, C = mp::identity> = is_subset<C>::f<L1, L2>

bool emp::is_subset<L1, L2> = is_subset<>::f<L1, L2>::value

emp::is_subset_with<L1, L2, Cmp = mp::same<>, C = mp::identity> = is_subset_with<Cmp, C>::f<L1, L2>

bool emp::is_subset_with<L1, L2, Cmp = mp::same<>> = is_subset_with<Cmp>::f<L1, L2>::value

<jln/mp/algorithm/is_unique.hpp>

Test file: test/src/algorithm/is_unique.cpp

is_unique<C = identity>

Return: true_ / false_

Checks whether all values are unique.

Implementation
is_unique_if<same<>, C>

is_unique_if<Cmp = same<>, C = identity>::f<xs...>

Return: true_ / false_

Checks whether all values are unique.

emp::is_unique<L, C = mp::identity> = emp::unpack<L, mp::is_unique_if<mp::same<>, C>>

emp::is_unique_if<L, Cmp = mp::same<>, C = mp::identity> = emp::unpack<L, mp::is_unique_if<Cmp, C>>

<jln/mp/algorithm/lexicographical_compare.hpp>

Test file: test/src/algorithm/lexicographical_compare.cpp

lexicographical_compare<Cmp = less<>, C = identity>::f<seq1, seq2>

Return: true_ / false_

Checks if seq1 is lexicographically less than seq2.

lexicographical_compare2<CmpLess = less<>, CmpEq = equal<>, C = identity>::f<seq1, seq2>

emp::lexicographical_compare<seq1, seq2, Cmp = mp::less<>, C = mp::identity> = lexicographical_compare<Cmp, C> ::f<seq1, seq2>

emp::lexicographical_compare2<seq1, seq2, CmpLess = mp::less<>, CmpEq = mp::equal<>, C = mp::identity> = lexicographical_compare2<CmpLess, CmpEq, C> ::f<seq1, seq2>

bool emp::lexicographical_compare_v<seq1, seq2, Cmp = mp::less<>, C = mp::identity> = lexicographical_compare<Cmp, C> ::f<seq1, seq2>::value

<jln/mp/algorithm/merge.hpp>

Test file: test/src/algorithm/merge.cpp

merge<Cmp = less<>, C = listify>::f<seq1, seq2>

Return: sequence

Merges two list into one sorted sequence.

Pre-condition
Post-condition

emp::merge<L, Cmp = mp::less<>, C = listify> = emp::unpack<L, mp::merge<Cmp, C>>

<jln/mp/algorithm/mismatch.hpp>

Test file: test/src/algorithm/mismatch.cpp

mismatch<Cmp = equal<>, TC = listify, FC = TC>::f<seq1, seq2>

Return: pair or number

Returns mismatching info of elements from two sequences.

Uses TC when a element mismatch and FC when one of the sequences equals the start of the other.

Semantics

FC::f<number<-1>, number<emp::size<seq1>>> if seq1 == seq2. FC::f<number<i>, number<-1>> if seq2 starts with seq1. FC::f<number<i>, number<1>> if seq1 starts with seq2. otherwise TC::f<number<i>, number<0>>.

emp::mismatch<seq1, seq2, Cmp = mp::equal<>, TC = mp::listify, FC = TC> = mismatch<Cmp, TC, FC>::f<seq1, seq2>

<jln/mp/algorithm/mismatch_index.hpp>

Test file: test/src/algorithm/mismatch_index.cpp

mismatch_index<Cmp = equal<>, C = identity>

Return: number

Returns the first mismatching index of elements from two sequences, otherwise the size of the sequences.

Implementation
mismatch<Cmp, front<C>, reverse_select<front<is<number<-1>>>, C>>

emp::mismatch_index<seq1, seq2, Cmp = mp::equal<>, C = mp::identity> = mismatch_index<Cmp, C>::f<seq1, seq2>

bool emp::mismatch_index_v<seq1, seq2, Cmp = mp::equal<>, C = mp::identity> = mismatch_index<Cmp, C>::f<seq1, seq2>::value

<jln/mp/algorithm/none_of.hpp>

Test file: test/src/algorithm/none_of.cpp

none_of<Pred, C = identity>::f<xs...>

Return: true_ / false_

Checks whether a predicate does not hold for any element of a sequence.

emp::none_of<L, Pred, C = mp::identity> = emp::unpack<L, mp::none_of<Pred, C>>

bool emp::none_of_v<L, Pred, C = mp::identity> = emp::unpack<mp::none_of<Pred, C>, L, L>::value

emp::none_of_xs<Pred, xs...> = mp::none_of<Pred>::f<xs...>

bool emp::none_of_xs_v<Pred, xs...> = mp::none_of<Pred>::f<xs...>::value

<jln/mp/algorithm/pairwise_fold.hpp>

Test file: test/src/algorithm/pairwise_fold.cpp

pairwise_fold<F, C = listify>

Return: sequence

Computes the differences between adjacent pair of elements.

Semantics
pairwise_fold<F, C>::f<a, b, c> = C::f<a, F::f<a, b>, F::f<b, c>>
pairwise_fold<F, C>::f<a> = C::f<a>
pairwise_fold<F, C>::f<> = C::f<>

pairwise_fold_and_transform_front<F, Front = identity, C = listify>::f<xs...>

Return: sequence

Computes the differences between adjacent pair of elements.

Semantics
pairwise_fold_and_transform_front<F, G, C>::f<a, b, c> = C::f<G::f<a>, F::f<a, b>, F::f<b, c>>
pairwise_fold_and_transform_front<F, G, C>::f<a> = C::f<G::f<a>>
pairwise_fold_and_transform_front<F, G, C>::f<> = C::f<>

emp::pairwise_fold<L, F, C = mp::listify> = emp::unpack<L, mp::pairwise_fold_and_transform_front<F, mp::identity, C>>

emp::pairwise_fold_and_transform_front<L, F, Front = mp::identity, C = mp::listify> = emp::unpack<L, mp::pairwise_fold_and_transform_front<F, Front, C>>

<jln/mp/algorithm/prefix.hpp>

Test file: test/src/algorithm/prefix.cpp

prefix<x, C = listify>::f<xs...>

Return: list

Inserts a value before each element of a sequence.

emp::prefix<L, x, C = mp::listify> = emp::unpack<L, mp::prefix<x, C>>

<jln/mp/algorithm/repeat.hpp>

Test file: test/src/algorithm/repeat.cpp

repeat<N, C = listify>

Implementation
repeat_c<N::value, C>

repeat_c<unsigned N, C = listify>::f<xs...>

Return: sequence

Returns a sequence that contains a number of copies of the same sequence.

Pre-condition
  • N >= 0

emp::repeat<L, n, C = mp::listify> = emp::unpack<L, mp::repeat<n, C>>

emp::repeat_c<L, int_t n, C = mp::listify> = emp::unpack<L, mp::repeat_c<n, C>>

emp::repeat_value_c<unsigned n, x, F = listify> = /*...*/

<jln/mp/algorithm/repeat_index.hpp>

Test file: test/src/algorithm/repeat_index.cpp

repeat_index<C = listify>

Implementation
repeat_index_with<listify, C>

repeat_index_v_c<C = listify>

Implementation
repeat_index_with_v_c<listify, C>

repeat_index_with<F = listify, C = listify>::f<ns...>

Implementation
repeat_index_with_v_c<F, C>::f<ns::value...>

repeat_index_with_v_c<F = listify, C = listify>::f<unsigned... ns>

Return: sequence

Creates a sequence of index sequence, taking the size of each as a parameter.

Semantics

Equivalent to

repeat_index_with_v_c<>::f<3, 0, 2, 1>
==
list<
  list<number<0>, number<0>, number<0>>,
  list<>,
  list<number<2>, number<2>>,
  list<number<3>>
>

emp::repeat_index<L, C = listify> = emp::unpack<L, mp::repeat_index_with<listify, C>>

emp::repeat_index_with<L, F = listify, C = listify> = emp::unpack<L, mp::repeat_index_with<F, C>>

<jln/mp/algorithm/replace.hpp>

Test file: test/src/algorithm/replace.cpp

replace<T, U, C = listify>

Return: sequence

Replaces every occurrence of a value by another value.

Implementation
replace_if<is<T>, U, C>

replace_if<Pred, T, C = listify>

Return: sequence

Replaces every occurrence that satisfy a predicate by some value.

emp::replace<L, T, U, C = mp::listify> = emp::unpack<L, mp::replace<T, U, C>>

emp::replace_if<L, Pred, T, C = mp::listify> = emp::unpack<L, mp::replace_if<Pred, T, C>>

<jln/mp/algorithm/reverse.hpp>

Test file: test/src/algorithm/reverse.cpp

reverse<C = listify>::f<xs...>

Return: sequence

Reverses the order of the elements of a sequence.

emp::reverse<L, C = mp::listify> = emp::unpack<L, mp::reverse<C>>

<jln/mp/algorithm/rotate.hpp>

Test file: test/src/algorithm/rotate.cpp

rotate<N, C = listify>

Implementation
rotate_c<N::value, C>

rotate_c<int_t N, C = listify>::f<xs...>

Return: sequence

Rotates the elements of a sequence around a pivot.

N
a negative value start to end of sequence. The final offset is a modulo of sizeof...(xs).
Semantics

Equivalent to

len = sizeof...(xs)
n = len ? (N < 0 ? len + N % len : N) % size : 0

C::f<...xs[n:], ...xs[:n]>

emp::rotate<L, n, C = mp::listify> = emp::unpack<L, mp::rotate<n, C>>

emp::rotate_c<L, int_t n, C = mp::listify> = emp::unpack<L, mp::rotate_c<n, C>>

<jln/mp/algorithm/same.hpp>

Test file: test/src/algorithm/same.cpp

same<C = identity>::f<xs...>

Return: true_ / false_

Checks whether all values are identical.

Implementation
C::f<number<emp::same_xs_v<xs...>>>

same_v<C = identity>::f<xs...>

Implementation
C::f<emp::same_xs_v<xs...>>

#define JLN_MP_IS_SAME(...)

Fast implementation of std::is_same_v.

emp::same<L, C = mp::identity> = emp::unpack<L, mp::same<C>>

bool emp::same_v<L, C = mp::identity> = emp::unpack<L, mp::same<C>>::value

bool emp::same_xs_v<xs...> = true

<jln/mp/algorithm/scan.hpp>

Test file: test/src/algorithm/scan.cpp

scan<F, C = listify>::f<xs...>

Return: sequence

Fold a sequence to the left and return a list containing the successive reduction states.

Semantics

Equivalent to

C::f<
  xs[0],
  F::f<xs[0], xs[1]>,
  F::f<F::f<xs[0], xs[1]>, xs[2]>,
  ...
>

emp::scan<L, F, C = mp::listify> = emp::unpack<L, mp::scan<F, C>>

<jln/mp/algorithm/scan_right.hpp>

Test file: test/src/algorithm/scan_right.cpp

scan_right<F, C = listify>

Return: sequence

Fold a sequence to the right and return a list containing the successive reduction states.

Semantics

Equivalent to

C::f<
  ...
  F::f<xs[n-3], F::f<xs[n-2], xs[n-1]>>,
  F::f<xs[n-2], xs[n-1]>,
  xs[n-1],
>

emp::scan_right<L, F, C = mp::listify> = emp::unpack<L, mp::scan_right<F, C>>

<jln/mp/algorithm/similar.hpp>

Test file: test/src/algorithm/similar.cpp

similar<C = identity>::f<xs...>

Return: true_ / false_

Checks whether all types are the same or instantiations of the same class template.

The list of supported class templates are: - template<class...> - template<class T, T...> - template<class, std::size_t> - template<std::size_t, class...> - template<class, auto...> (when supported) - template<auto, class...> (when supported) - template<auto...> (when supported)

Implementation
C::f<number<emp::similar_xs_v<xs...>>>

similar_v<C = identity>::f<xs...>

Implementation
C::f<emp::similar_xs_v<xs...>>

emp::similar<L, C = mp::identity> = emp::unpack<L, mp::similar<C>>

bool emp::similar_v<L, C = mp::identity> = emp::unpack<L, mp::similar<C>>::value

bool emp::similar_xs_v<xs...> = /*...*/

<jln/mp/algorithm/sort.hpp>

Test file: test/src/algorithm/sort.cpp

sort<Cmp = less<>, C = listify>::f<xs...>

Return: sequence

Sorts the elements of a sequence according to an ordering relation.

Sorting is stable.

Post-condition

stable_sort<Cmp = less<>, C = listify>

Implementation
sort<Cmp, C>

emp::sort<L, Cmp = mp::less<>, C = listify> = emp::unpack<L, mp::sort<Cmp, C>>

emp::stable_sort<L, Cmp = mp::less<>, C = listify> = emp::unpack<L, mp::sort<Cmp, C>>

<jln/mp/algorithm/starts_with.hpp>

Test file: test/src/algorithm/starts_with.cpp

starts_with<Seq, C = identity>

Return: true_ / false_

Checks if the sequence begins with the given prefix.

starts_with<list<Ts...>, C>::f<xs...>

emp::starts_with<L, Seq, C = mp::identity> = emp::unpack<L, starts_with<Seq, C>>

bool emp::starts_with_v<L, Seq, C = mp::identity> = emp::unpack<L, starts_with<Seq, C>>::value

<jln/mp/algorithm/suffix.hpp>

Test file: test/src/algorithm/suffix.cpp

suffix<x, C = listify>::f<xs...>

Return: list

Inserts a value after each element of a sequence.

emp::suffix<L, x, C = mp::listify> = emp::unpack<L, mp::suffix<x, C>>

<jln/mp/algorithm/transform.hpp>

Test file: test/src/algorithm/transform.cpp

transform<F, C = listify>::f<xs...>

Return: sequence

Executes F on every element of a sequence.

Implementation
C::f<F::f<xs>...>

emp::transform<L, F, C = mp::listify> = emp::unpack<L, mp::transform<F, C>>

<jln/mp/algorithm/transform_at.hpp>

Test file: test/src/algorithm/transform_at.cpp

transform_at<I, F, C = listify>

Implementation
transform_at_c<I::value, F, C>

transform_at_c<unsigned i, F, C = listify>::f<xs...>

Return: list

Replace the element at position i of the sequence.

emp::transform_at<L, I, F, C = listify> = emp::unpack<L, mp::transform_at_c<I::value, F, C>>

emp::transform_at_c<L, unsigned i, F, C = listify> = emp::unpack<L, mp::transform_at_c<i, F, C>>

<jln/mp/algorithm/transform_first.hpp>

Test file: test/src/algorithm/transform_first.cpp

transform_first<F, C = listify>

Return: list

Replace the first element of the sequence.

Implementation
partial_transform<F, C>

emp::transform_first<L, F, C = listify> = emp::unpack<L, mp::partial_transform<F, C>>

<jln/mp/algorithm/transform_second.hpp>

Test file: test/src/algorithm/transform_second.cpp

transform_second<F, C = listify>

Return: list

Replace the second element of the sequence.

Implementation
partial_transform<identity, F, C>

emp::transform_second<L, F, C = listify> = emp::unpack<L, mp::partial_transform<mp::identity, F, C>>

<jln/mp/algorithm/transform_third.hpp>

Test file: test/src/algorithm/transform_third.cpp

transform_third<F, C = listify>

Return: list

Replace the third element of the sequence.

Implementation
partial_transform<identity, identity, F, C>

emp::transform_third<L, F, C = listify> = emp::unpack<L, mp::partial_transform<mp::identity, mp::identity, F, C>>

<jln/mp/algorithm/uncompress.hpp>

Test file: test/src/algorithm/uncompress.cpp

uncompress<FillT, Selectors, C = listify>

uncompress_c<FillT, bool... selectors>

Implementation
uncompress_c_with<listify, FillT, selectors...>

uncompress_c_with<C, FillT, bool... selectors>::f<xs...>

Return: sequence

Create sequence by replacing false in selectors with FillT and true with a element in xs value, starting from the left.

Semantics
uncompress_c<T, 1,0,1,0,1,1>
         ::f<   a,  c,  e,f>
     == list<   a,T,c,T,e,f>

uncompress_for<FillT, Selectors...>

Implementation
uncompress_c_with<listify, FillT, Selectors::value...>

emp::uncompress<L, FillT, Selectors, C = mp::listify> = /*...*/

emp::uncompress_c<L, FillT, bool... selectors> = emp::unpack<L, mp::uncompress_c_with<listify, FillT, selectors...>>

emp::uncompress_c_with<L, FillT, C, bool... selectors> = emp::unpack<L, mp::uncompress_c_with<C, FillT, selectors...>>

emp::uncompress_for<L, FillT, Selectors...> = emp::unpack<L, mp::uncompress_c_with<listify, FillT, Selectors::value...>>

Group: config

<jln/mp/detail/compiler.hpp>

Test file: test/src/detail/compiler.cpp

#define JLN_MP_APPLE_CLANG

Is clang on MacOS.

#define JLN_MP_CLANG

The compiler is clang.

#define JLN_MP_CLANG_CL

The compiler is clang-cl.

#define JLN_MP_CLANG_LIKE

The compiler presents itself as a clang without necessarily being so.

#define JLN_MP_CUDA

The compiler is nvcc.

#define JLN_MP_ENABLE_FRIEND_INJECTION

When 1, algorithms using friend injection its accessible

#define JLN_MP_ENABLE_TYPE_PACK_ELEMENT

When 1, the builtin __type_pack_element can be used.

#define JLN_MP_FAST_ALIAS_ON_VARIABLE_TEMPLATE

When 1, number<f_v<xs...>> is faster than f<xs...>::type.

#define JLN_MP_FAST_TYPE_PACK_ELEMENT

When 1, the builtin __type_pack_element can be used and is very fast.

#define JLN_MP_GCC

The compiler is gcc.

#define JLN_MP_HAS_BUILTIN(name)

Check that a builtin exists.

#define JLN_MP_HOST_COMPILER_CLANG

The host compiler is clang (in the case of nvcc).

#define JLN_MP_HOST_COMPILER_GCC

The host compiler is gcc (in the case of nvcc).

#define JLN_MP_LAZY_ALIAS

When 0, aliases are not context dependent and are resolved as soon as possible which generate errors in contexts that should be lazy.

#define JLN_MP_MEMOIZED_ALIAS

When 1, aliases are memoized. This means that calling a "slow" alias a second time and with the same parameters will be fast.

#define JLN_MP_MSVC

The compiler is cl.

#define JLN_MP_MSVC_LIKE

The compiler presents itself as a msvc without necessarily being so.

#define JLN_MP_OPTIMIZED_ALIAS

When 1, the compiler considers an alias that makes alias<xs...> = F<xs...> is identical to F.

Therefore, cfe<alias> and cfe<F> will be the same.

#define JLN_MP_REQUIRES_AS_FAST_SFINAE

When 1, requires keyword is faster than traditional use of SFINAE.

#define JLN_MP_UNPACK(...)

Displays parameters. Useful in a macro to remove parentheses from a value.

#define JLN_MP_WORKAROUND(symbol, test)

Checks that a value respects a condition and is different from 0.

ex: JLN_MP_WORKAROUND(JLN_MP_GCC, < 1200).

<jln/mp/detail/config.hpp>

Test file: test/src/detail/config.cpp

#define JLN_MP_DEBUG

When 1, uses a memoization version of call to keep better track of calls in the case of compilation error. This is especially useful with clang, which doesn't display aliases.

#define JLN_MP_FORCE_LAZY_ALIAS

When 1, ignore the value of JLN_MP_LAZY_ALIAS in the implementations.

This allows the code to compile in an emptier way, but will fail when the compiler can resolve an alias leading to a compilation error (which is actually quite rare).

#define JLN_MP_MAX_CALL_ELEMENT

Maximum pack size that can be passed to the call function.

If the pack is larger, there will be a compilation error.

Group: filter

<jln/mp/algorithm/compress.hpp>

Test file: test/src/algorithm/compress.cpp

compress<Selectors, C = listify>

compress_c<bool... selectors>

Implementation
compress_c_with<listify, selectors...>

compress_c_with<C, bool... selectors>::f<xs...>

Return: sequence

Removes elements that have a corresponding element in selectors to 0.

Pre-condition
Semantics
compress_c<1,0,1,0,1,1>
       ::f<a,b,c,d,e,f>
   == list<a,  c,  e,f>

compress_for<Selectors...>

Implementation
compress_c_with<listify, Selectors::value...>

emp::compress<L, Selectors, C = mp::listify> = /*...*/

emp::compress_c<L, bool... selectors> = emp::unpack<L, mp::compress_c_with<listify, selectors...>>

emp::compress_c_with<L, C, bool... selectors> = emp::unpack<L, mp::compress_c_with<C, selectors...>>

emp::compress_for<L, Selectors...> = emp::unpack<L, mp::compress_c_with<listify, Selectors::value...>>

<jln/mp/algorithm/copy.hpp>

Test file: test/src/algorithm/copy.cpp

copy<x, C = listify>

Return: sequence

Copies all occurence of a value.

Implementation
copy_if<is<x>, C>

copy_if<Pred, C = listify>

Return: sequence

Copies all elements that satisfy a predicate.

Implementation
transform<wrap_in_list_if<Pred>, join<C>>

emp::copy<L, x, C = mp::listify> = emp::unpack<L, mp::copy<x, C>>

emp::copy_if<L, Pred, C = mp::listify> = emp::unpack<L, mp::copy_if<Pred, C>>

<jln/mp/algorithm/remove_adjacent.hpp>

Test file: test/src/algorithm/remove_adjacent.cpp

remove_adjacent<C = listify>

Return: sequence

Removes each element in a sequence which is the same type as the privious element.

Implementation
remove_adjacent_if<same<>, C>

remove_adjacent_if<BinaryPred, C = listify>

Return: sequence

Removes each element in a sequence which respect a predicate with privious element.

Implementation
pairwise_fold_and_transform_front< select<BinaryPred, always<list<>>, listify>, listify, join<C>>

emp::remove_adjacent<L, C = mp::listify> = emp::unpack<L, mp::remove_adjacent<C>>

emp::remove_adjacent_if<L, BinaryPred, C = mp::listify> = emp::unpack<L, mp::remove_adjacent_if<BinaryPred, C>>

<jln/mp/algorithm/remove.hpp>

Test file: test/src/algorithm/remove.cpp

remove<T, C = listify>

Return: sequence

Removes all occurence of a value.

Implementation
remove_if<is<T>, C>

remove_if<Pred, C = listify>

Return: sequence

Removes all elements that satisfy a predicate.

Implementation
transform<wrap_in_list_if_not<Pred>, join<C>>

emp::remove<L, T, C = mp::listify> = emp::unpack<L, mp::remove<T, C>>

emp::remove_if<L, Pred, C = mp::listify> = emp::unpack<L, mp::remove_if<Pred, C>>

<jln/mp/algorithm/remove_prefix.hpp>

Test file: test/src/algorithm/remove_prefix.cpp

remove_prefix<Seq, TC = listify, FC = TC>

Return: sequence

Remove the first elements corresponding to a prefix.

Calls TC with the rest of sequence when the prefix is found, otherwise calls FC with the whole sequence.

remove_prefix<list<Ts...>, TC, FC>::f<xs...>

emp::remove_prefix<L, Seq, TC = mp::listify, FC = TC> = emp::unpack<L, remove_prefix<Seq, TC, FC>>

<jln/mp/algorithm/remove_suffix.hpp>

Test file: test/src/algorithm/remove_suffix.cpp

remove_suffix<Seq, TC = listify, FC = TC>

Return: sequence

Remove the last elements corresponding to a suffix.

Calls TC with the rest of sequence when the suffix is found, otherwise calls FC with the whole sequence.

remove_suffix<list<Ts...>, TC, FC>::f<xs...>

emp::remove_suffix<L, Seq, TC = mp::listify, FC = TC> = emp::unpack<L, remove_suffix<Seq, TC, FC>>

<jln/mp/algorithm/remove_unique.hpp>

Test file: test/src/algorithm/remove_unique.cpp

copy_unique<C = listify>::f<xs...>

Return: sequence

Copy unique elements from a sequence.

copy_unique_if<Cmp = same<>, C = listify>

Return: sequence

Copy unique elements from a sequence.

remove_unique<C = listify>::f<xs...>

Return: sequence

Remove unique elements from a sequence.

remove_unique_if<Cmp = same<>, C = listify>

Return: sequence

Remove unique elements from a sequence.

emp::copy_unique<L, C = mp::listify> = emp::unpack<L, copy_unique<C>>

emp::copy_unique_if<L, Cmp = mp::same<>, C = mp::listify> = emp::unpack<L, copy_unique_if<Cmp, C>>

emp::remove_unique<L, C = mp::listify> = emp::unpack<L, remove_unique<C>>

emp::remove_unique_if<L, Cmp = mp::same<>, C = mp::listify> = emp::unpack<L, remove_unique_if<Cmp, C>>

<jln/mp/algorithm/unique.hpp>

Test file: test/src/algorithm/unique.cpp

unique<C = listify>

Return: set

Returns a list with duplicate elements removed.

Implementation
unique_if<same<>, C>

unique_if<Cmp = same<>, C = listify>::f<xs...>

Return: sequence

Returns a list with duplicate elements removed.

Only the first element found is kept.

emp::unique<L, C = mp::listify> = emp::unpack<L, unique<C>>

emp::unique_if<L, Cmp = mp::same<>, C = mp::listify> = emp::unpack<L, unique_if<Cmp, C>>

Group: functional

<jln/mp/functional/apply_or_identity.hpp>

Test file: test/src/functional/apply_or_identity.cpp

apply_or_identity<Pred, TC>

Return: value

Returns TC::f<x> if Pred::f<x>, otherwise returns x.

Implementation
if_<Pred, TC, identity>

emp::apply_or_identity<Pred, TC, x> = mp::if_<Pred, TC, mp::identity>::f<x>

<jln/mp/functional/bind_back.hpp>

Test file: test/src/functional/bind_back.cpp

bind_back<F, BoundArgs...>::f<xs...>

Return: sequence

Invoking F with its last parameters bound to bound to args.

Implementation
F::f<xs..., BoundArgs...>
Semantics
bind_back<F, c, d>::f<a, b> == F<a, b, c, d>

bind_back_c<F, int_t... BoundArgs>

Implementation
bind_back<F, number<BoundArgs>...>

bind_back_v<F, auto... BoundArgs>::f<xs...>

Implementation
F::f<xs..., BoundArgs...>

emp::bind_back<L, F, BoundArgs...> = /*...*/

emp::bind_back_c<L, F, int_t... BoundArgs> = /*...*/

emp::bind_back_v<L, F, auto... BoundArgs> = emp::unpack<L, mp::bind_back_v<F, BoundArgs...>>

<jln/mp/functional/bind_front.hpp>

Test file: test/src/functional/bind_front.cpp

bind_front<F, BoundArgs...>::f<xs...>

Return: sequence

Invoking F with its first parameters bound to bound to args.

Implementation
F::f<BoundArgs..., xs...>
Semantics
bind_front<F, a, b>::f<c, d> == F<a, b, c, d>

bind_front_c<F, int_t... BoundArgs>

Implementation
bind_front<F, number<BoundArgs>...>

bind_front_v<F, auto... BoundArgs>::f<xs...>

Implementation
F::f<BoundArgs..., xs...>

emp::bind_front<L, F, BoundArgs...> = emp::unpack<L, F, BoundArgs...>

emp::bind_front_c<L, F, int_t... BoundArgs> = emp::unpack<L, F, number<BoundArgs>...>

emp::bind_front_v<L, F, auto... BoundArgs> = emp::unpack<L, mp::bind_front_v<F, BoundArgs...>>

<jln/mp/functional/call.hpp>

Test file: test/src/functional/call.cpp

call<C, xs...>

Implementation
C::f<xs...>

call_c<C, auto /*or int_t*/... xs>

call_t<C, xs...>

Implementation
call<C, xs...>::type

<jln/mp/functional/capture_back.hpp>

Test file: test/src/functional/capture_back.cpp

capture_back<BoundArgs...>::f<F, xs...>

Return: sequence

Invoking F with its last parameters bound to args.

Implementation
F::f<xs..., BoundArgs...>
Semantics
capture_back<c, d>::f<F, a, b> == F<a, b, c, d>

capture_back_c<int_t... BoundArgs>

Implementation
capture_back<number<BoundArgs>...>

capture_back_v<auto... BoundArgs>::f<F, xs...>

Implementation
F::f<xs..., BoundArgs...>

emp::capture_back<L, BoundArgs...> = emp::unpack<L, mp::capture_back<BoundArgs...>>

emp::capture_back_c<L, int_t... BoundArgs> = emp::unpack<L, mp::capture_back_c<BoundArgs...>>

emp::capture_back_v<L, auto... BoundArgs> = emp::unpack<L, mp::capture_back_v<BoundArgs...>>

<jln/mp/functional/capture_front.hpp>

Test file: test/src/functional/capture_front.cpp

capture_front<BoundArgs...>::f<F, xs...>

Return: sequence

Invoking F with its first parameters bound to args.

Implementation
F::f<BoundArgs..., xs...>
Semantics
capture_front<a, b>::f<F, c, d> == F<a, b, c, d>

capture_front_c<int_t... BoundArgs>

Implementation
capture_front<number<BoundArgs>...>

capture_front_v<auto... BoundArgs>::f<F, xs...>

Implementation
F::f<BoundArgs..., xs...>

emp::capture_front<L, BoundArgs...> = emp::unpack<L, mp::capture_front<BoundArgs...>>

emp::capture_front_c<L, int_t... BoundArgs> = emp::unpack<L, mp::capture_front_c<BoundArgs...>>

emp::capture_front_v<L, auto... BoundArgs> = emp::unpack<L, mp::capture_front_v<BoundArgs...>>

<jln/mp/functional/cascade.hpp>

Test file: test/src/functional/cascade.cpp

cascade<F, Fs...>

Recursively invokes functions to nested typelist of typelists.

Semantics
cascade<F0> = transform<F0>
cascade<F0,F1,F2> = transform<unpack<transform<unpack<F0>, F1>>, F2>

<jln/mp/functional/continuation.hpp>

Test file: test/src/functional/continuation.cpp

cfe<template<class...> F, C = identity>::f<xs...>

Return: value

Makes a continuation from a meta-function.

cfl means continuation from lazy.

Implementation
C::f<F::f<xs...>>

cfe_v<template<auto /*or int_t*/...> F, C = identity>::f<xs...>

Return: value

Makes a function from a meta-function.

Implementation
C::f<F::f<xs::value...>>

cfe_v_c<template<auto /*or int_t*/...> F, C = identity>::f<auto /*or int_t*/... xs>

Return: value

Makes a function from a meta-function.

Implementation
C::f<F::f<xs...>>

cfl<template<class...> F, C = identity>::f<xs...>

Return: value

Makes a continuation from a lazy meta-function.

cfe means continuation from eager.

Implementation
C::f<F::f<xs...>::type>

cfl_v<template<auto /*or int_t*/...> F, C = identity>::f<xs...>

Return: value

Makes a function from a lazy meta-function.

Implementation
C::f<F::f<xs::value...>::type>

cfl_v_c<template<auto /*or int_t*/...> F, C = identity>::f<auto /*or int_t*/... xs>

Return: value

Makes a function from a lazy meta-function.

Implementation
C::f<F::f<xs...>::type>

<jln/mp/functional/compare_with.hpp>

Test file: test/src/functional/compare_with.cpp

compare_with<F, Cmp = less<>>

Return: true_ / false_

comparison on the result of a function.

Implementation
each<F, F, Cmp>

emp::compare_with<F, x, y, Cmp = mp::less<>> = Cmp::f< F::f<x>, F::f<y>>

bool emp::compare_with_v<F, x, y, Cmp = mp::less<>> = Cmp::f< F::f<x>, F::f<y>>::value

<jln/mp/functional/compose.hpp>

Test file: test/src/functional/compose.cpp

compose<F, Fs...>

Return: function

Composition of two functions or more.

Semantics
compose<foo, bar>::f<a, b> == bar::f<foo::f<a, b>>

compose_f<template<class...> F, template<class...> Fs...>

Return: function

Composition of two meta-functions or more.

Semantics
compose_f<foo, bar>::f<a, b> == bar<foo<a, b>>

<jln/mp/functional/each.hpp>

Test file: test/src/functional/each.cpp

each<Fs..., C>::f<xs...>

Return: value

Invokes multiple functions each taking the parameter corresponding to its position.

Implementation
C::f<Fs::f<xs>...>

<jln/mp/functional/eval.hpp>

Test file: test/src/functional/eval.cpp

eval<auto F, C = identity>::f<xs...>

Return: value

Invokes a lambda function.

Implementation
C::f<decltype(F.operator()<xs...>())>

emp::eval<auto F, xs...> = decltype(F.operator()<xs...>())

<jln/mp/functional/fix.hpp>

Test file: test/src/functional/fix.cpp

fix<C>::f<xs...>

Return: value

Invokes a function computing the fixed point of a function.

Implementation
C::f<fix<C>, xs...>
Semantics
fix<C>::f<xs...> = C::f<fix<C>, xs...>

emp::fix<F, xs...> = fix<F>::f<xs...>

<jln/mp/functional/flip.hpp>

Test file: test/src/functional/flip.cpp

flip<C = listify>::f<x0, x1, xs...>

Return: sequence

Invokes a function with its two first arguments reversed.

Implementation
C::f<x1, x0, xs...>
Semantics
C::f<xs[1], xs[0], ...xs[2:]>

emp::flip<L, C = mp::listify> = emp::unpack<L, mp::flip<C>>

<jln/mp/functional/identity.hpp>

Test file: test/src/functional/identity.cpp

identity::f<x>

Return: value

Implementation
x

emp::identity<x> = x

<jln/mp/functional/if.hpp>

Test file: test/src/functional/if.cpp

if_<Pred, TC, FC = always<false_>>::f<xs...>

Return: value

A conditional expression.

Implementation
conditional_c< !Pred::f<xs...>::value> ::f<FC, TC> ::f<xs...>

emp::if_<Pred, TC, FC, xs...> = mp::if_<Pred, TC, FC>::f<xs...>

<jln/mp/functional/invoke_twice.hpp>

Test file: test/src/functional/invoke_twice.cpp

invoke_twice<F>::f<xs...>

Return: value

Invokes twice.

Implementation
F::f<xs...> ::f<xs...>

<jln/mp/functional/try.hpp>

Test file: test/src/functional/try.cpp

is_invocable<F, C = identity>

Return: true_ / false_

Checks whether F::f<xs...> is invocable.

Implementation
try_<F, always<true_, C>, always<false_, C>>
Pre-condition
  • F::f<xs...> must be a SFINAE compatible expression

is_na

Implementation
is<na>

is_not_invocable<F, C = identity>

Return: true_ / false_

Checks whether F::f<xs...> is not invocable.

Implementation
try_<F, always<false_, C>, always<true_, C>>
Pre-condition
  • F::f<xs...> must be a SFINAE compatible expression

try_<F, TC = identity, FC = violation>::f<xs...>

Return: value

Invokes TC::f<result> whether FC::f<xs...> is a valid expression other than na, otherwhise invokes FC::f<xs...>.

Pre-condition
  • F::f<xs...> must be a SFINAE compatible expression

try_or<F, FT = na>

Implementation
try_<F, identity, always<FT>>

try_or_else<F, FC = violation>

Implementation
try_<F, identity, FC>

violation

Implementation
always<na>

emp::is_invocable<F, xs...> = number<is_invocable_v<F, xs...>>

bool emp::is_invocable_v<F, xs...> = ! std::is_same_v<na, try_<F>::f<xs...>>

emp::is_not_invocable<F, xs...> = number<!is_invocable_v<F, xs...>>

bool emp::is_not_invocable_v<F, xs...> = !is_invocable_v<F, xs...>

emp::try_<F, TC, FC, xs...> = mp::try_<F, TC, FC>::f<xs...>

emp::try_or<F, FT, xs...> = mp::try_<F, mp::identity, always<FT>>::f<xs...>

emp::try_or_else<F, FC, xs...> = mp::try_<F, mp::identity, FC>::f<xs...>

<jln/mp/functional/monadic.hpp>

Test file: test/src/functional/monadic.cpp

monadic<TC, FC = violation>

Return: value

Invokes FC whether na, otherwise TC.

Implementation
if_<is<na>, FC, TC>

monadic0<TC, FC = violation>

Return: value

Invokes FC whether first value is na, otherwise TC.

Implementation
if_<front<is<na>>, FC, TC>

monadic_if_na<x, template<class...> M, TC, FC = violation>

Return: value

Monadify only if x is na.

Implementation
mp::conditional_c<std::is_same_v<na, x>>::f<M<TC, FC>, TC>

monadic_xs<TC, FC = violation>

Return: value

Invokes FC whether any value is na, otherwise TC.

Implementation
if_<none_of<is<na>>, TC, FC>

<jln/mp/functional/memoize.hpp>

Test file: test/src/functional/memoize.cpp

memoize<C>::f<xs...>

Memoize a call to C::f<xs...>.

memoize_call<C, xs...>

Memoization version of call.

na

Value that is not available.

This type is used in smp for a contract that is not respected.

<jln/mp/functional/not_fn.hpp>

Test file: test/src/functional/not_fn.cpp

not_fn<F, C = identity>

Return: true_ / false_

Returns the negation of F.

emp::not_fn<L, F, C = mp::identity> = emp::unpack<L, mp::not_fn<F, C>>

emp::not_of<F, xs...> = mp::number<! F::f<xs...>::value>

<jln/mp/functional/partial_tee.hpp>

Test file: test/src/functional/partial_tee.cpp

partial_tee<Fs..., C>::f<xs...>

Return: value

Invokes multiple functions passing all parameters to each then calls C with the results and parameters without the first sizeof...(Fs).

Semantics
partial_tee<F,G,C>::f<a> == /* error */
partial_tee<F,G,C>::f<a,b,c,d> == C::f<F::f<a,b,c,d>, G::f<a,b,c,d>, c, d>

partial_tee0<Fs..., C>::f<xs...>

Return: value

Invokes multiple functions passing all parameters to each (or without parameter whether it does not exist), then calls C with the results and parameters without the first sizeof...(Fs).

Semantics
partial_tee0<F,G,C>::f<a> == C::f<F::f<a>, G::f<>>
partial_tee0<F,G,C>::f<a,b> == C::f<F::f<a,b>, G::f<a,b>>
partial_tee0<F,G,C>::f<a,b,c,d> == C::f<F::f<a,b,c,d>, G::f<a,b,c,d>, c, d>

<jln/mp/functional/partial_tee_xs.hpp>

Test file: test/src/functional/partial_tee_xs.cpp

partial_tee0_xs<Fs..., C>::f<xs...>

Return: value

Invokes multiple functions each taking the parameter corresponding to its position (or without parameter whether it does not exist), except the last one taking zero to all remaining parameters.

Semantics
partial_tee0_xs<F,G,H,C>::f<a> == C::f<F::f<a>, G::f<>, H::f<>>
partial_tee0_xs<F,G,H,C>::f<a,b> == C::f<F::f<a,b>, G::f<a,b>, H::f<>>
partial_tee0_xs<F,G,H,C>::f<a,b,c,d> == C::f<F::f<a,b,c,d>, G::f<a,b,c,d>, H::f<c,d>>
partial_tee0_xs<C>::f<> == C::f<>
partial_tee0_xs<C>::f<a> == /* error */

partial_tee_xs<Fs..., C>::f<xs...>

Return: value

Invokes multiple functions each taking the parameter corresponding to its position, except the last one taking zero to all remaining parameters.

Semantics
partial_tee_xs<F,G,H,C>::f<a> == /* error */
partial_tee_xs<F,G,H,C>::f<a,b> == C::f<F::f<a,b>, G::f<a,b>, H::f<>>
partial_tee_xs<F,G,H,C>::f<a,b,c,d> == C::f<F::f<a,b,c,d>, G::f<a,b,c,d>, H::f<c,d>>
partial_tee_xs<C>::f<> == C::f<>
partial_tee_xs<C>::f<a> == /* error */

<jln/mp/functional/partial_transform.hpp>

Test file: test/src/functional/partial_transform.cpp

partial_transform<Fs..., C>::f<xs...>

Return: value

Invokes multiple functions each taking the parameter corresponding to its position, then calls C with the results and the rest of the parameters.

Semantics
partial_transform<F,G,C>::f<a> == /* error */
partial_transform<F,G,C>::f<a,b,c,d> == C::f<F::f<a>, G::f<b>, c, d>

partial_transform0<Fs..., C>::f<xs...>

Return: value

Invokes multiple functions each taking the parameter corresponding to its position (or without parameter whether it does not exist), then calls C with the results and the rest of the parameters.

Semantics
partial_transform0<F,G,C>::f<a> == C::f<F::f<a>, G::f<>>
partial_transform0<F,G,C>::f<a,b,c,d> == C::f<F::f<a>, G::f<b>, c, d>

<jln/mp/functional/partial_transform_xs.hpp>

Test file: test/src/functional/partial_transform_xs.cpp

partial_transform0_xs<Fs..., C>::f<xs...>

Return: sequence

Invokes multiple functions each taking the parameter corresponding to its position (or without parameter whether it does not exist), except the last one taking zero to all remaining parameters.

Semantics
partial_transform0_xs<F,G,H,C>::f<a> == C::f<F::f<a>, G::f<>, H::f<>>
partial_transform0_xs<F,G,H,C>::f<a,b> == C::f<F::f<a>, G::f<b>, H::f<>>
partial_transform0_xs<F,G,H,C>::f<a,b,c,d> == C::f<F::f<a>, G::f<b>, H::f<c,d>>
partial_transform0_xs<C>::f<> == C::f<>
partial_transform0_xs<C>::f<a> == /* error */

partial_transform_xs<Fs..., C>::f<xs...>

Return: sequence

Invokes multiple functions each taking the parameter corresponding to its position, except the last one taking zero to all remaining parameters.

Semantics
partial_transform_xs<F,G,H,C>::f<a> == /* error */
partial_transform_xs<F,G,H,C>::f<a,b> == C::f<F::f<a>, G::f<b>, H::f<>>
partial_transform_xs<F,G,H,C>::f<a,b,c,d> == C::f<F::f<a>, G::f<b>, H::f<c,d>>
partial_transform_xs<C>::f<> == C::f<>
partial_transform_xs<C>::f<a> == /* error */

<jln/mp/functional/select.hpp>

Test file: test/src/functional/select.cpp

reverse_select<Pred, TC = identity, FC = TC>::f<x, y, xs...>

Return: value

A conditional selection expression.

This is the equivalent of the ternary Pred::f<a, b>::value ? b : a.

Implementation
conditional_c< !Pred::f<x, y, xs...>::value> ::f<front<FC>, at1<TC>> ::f<x, y>
Pre-condition
  • sizeof...(xs) >= 2

reverse_select_flip<Pred, TC = identity, FC = TC>::f<x, y, xs...>

Return: value

A conditional selection expression with its two first arguments reversed.

This is the equivalent of the ternary Pred::f<b, a>::value ? b : a.

Implementation
conditional_c< !Pred::f<y, x, xs...>::value> ::f<front<FC>, at1<TC>> ::f<x, y>
Pre-condition
  • sizeof...(xs) >= 2

select<Pred, TC = identity, FC = TC>::f<x, y, xs...>

Return: value

A conditional selection expression.

This is the equivalent of the ternary Pred::f<a, b>::value ? a : b.

Implementation
conditional_c< !Pred::f<x, y, xs...>::value> ::f<at1<FC>, front<TC>> ::f<x, y>
Pre-condition
  • sizeof...(xs) >= 2

select_flip<Pred, TC = identity, FC = TC>::f<x, y, xs...>

Return: value

A conditional selection expression with its two first arguments reversed.

This is the equivalent of the ternary Pred::f<b, a>::value ? a : b.

Implementation
conditional_c< !Pred::f<y, x, xs...>::value> ::f<at1<FC>, front<TC>> ::f<x, y>
Pre-condition
  • sizeof...(xs) >= 2

emp::reverse_select<Pred, x, y> = mp::conditional_c<!Pred::f<x, y>::value>::f<x, y>

emp::reverse_select_flip<Pred, x, y> = mp::conditional_c<!Pred::f<y, x>::value>::f<x, y>

auto emp::reverse_select_flip_v<Pred, x, y> = reverse_select_flip<Pred, x, y>::value

auto emp::reverse_select_v<Pred, x, y> = reverse_select<Pred, x, y>::value

emp::select<Pred, x, y> = mp::conditional_c<!Pred::f<x, y>::value>::f<y, x>

emp::select_flip<Pred, x, y> = mp::conditional_c<!Pred::f<y, x>::value>::f<y, x>

auto emp::select_flip_v<Pred, x, y> = select_flip<Pred, x, y>::value

auto emp::select_v<Pred, x, y> = select<Pred, x, y>::value

<jln/mp/functional/recursively.hpp>

Test file: test/src/functional/recursively.cpp

next_recursion::f<xs...>

Specify values for the next iteration.

recursion_result::f<xs...>

Specify result values and stop recursion.

recursively<F, C = identity>::f<xs...>

Return: value

Recursively invokes F until stop_recursion or recursion_result.

recursively_as_much_as_possible<F, C = identity>::f<xs...>

Return: value

Recursively invokes F until the result is stop_recursion, recursion_result or no longer changes.

recursively_as_much_as_possible_xs<F, C = listify>

Return: value

Same than recursively_as_much_as_possible, but with listify as default continuation.

Implementation
recursively_as_much_as_possible<F, C>

recursively_xs<F, C = listify>

Return: sequence

Same than recursively, but with listify as default continuation.

Implementation
recursively<F, C>

stop_recursion::f<_...>

Stop the recursion, the input values will be used as result.

Implementation
stop_recursion

emp::recursively<L, F, C = mp::identity> = emp::unpack<L, mp::recursively<F, C>>

emp::recursively_as_much_as_possible<L, F, C = mp::identity> = emp::unpack<L, mp::recursively_as_much_as_possible<F, C>>

emp::recursively_as_much_as_possible_xs<L, F, C = mp::listify> = emp::unpack<L, mp::recursively_as_much_as_possible<F, C>>

emp::recursively_xs<L, F, C = mp::listify> = emp::unpack<L, mp::recursively<F, C>>

<jln/mp/functional/tee.hpp>

Test file: test/src/functional/tee.cpp

tee<Fs..., C>::f<xs...>

Return: value

Invokes multiple functions passing all parameters to each.

Implementation
C::f<Fs::f<xs...>...>

<jln/mp/functional/until.hpp>

Test file: test/src/functional/until.cpp

until<Pred, F, C = identity>

Return: value

Apply a function until some predicate is satisfied.

Implementation
recursively<if_<Pred, stop_recursion, F>, C>

until_xs<Pred, F, C = listify>

Return: value

Apply a function until some predicate is satisfied.

Implementation
recursively<if_<Pred, stop_recursion, F>, C>

emp::until<L, Pred, F, C = mp::identity> = emp::unpack<L, mp::until<Pred, F, C>>

emp::until_xs<L, Pred, F, C = mp::listify> = emp::unpack<L, mp::until<Pred, F, C>>

<jln/mp/functional/until_last.hpp>

Test file: test/src/functional/until_last.cpp

partial_until_last_t<template<class...> Tpl, OffsetEnd, Pred, TC = listify, FC = clear<TC>>

Implementation
Tpl<OffsetEnd, Pred, recursively< pop_front<Tpl<OffsetEnd, Pred, next_recursion, stop_recursion>>, TC>, FC>

partial_until_last_t_c<template<int_t, class...> Tpl, int_t OffsetEnd, Pred, TC = listify, FC = clear<TC>>

Implementation
Tpl<OffsetEnd, Pred, recursively< pop_front<Tpl<OffsetEnd, Pred, next_recursion, stop_recursion>>, TC>, FC>

until_last<Searcher>

Return: sequence

Uses a Searcher in a loop until the last result.

Searcher must end with the continuations TC and FC. until_last_t<find, is<x>, TC, FC> is equivalent to find_last

until_last_t<template<class...> Tpl, Pred, TC = listify, FC = clear<TC>>

Implementation
Tpl<Pred, recursively< pop_front<Tpl<Pred, next_recursion, stop_recursion>>, TC>, FC>

emp::partial_until_last_t<L, template<class...> Tpl, OffsetEnd, Pred, TC = listify, FC = clear<TC>> = emp::unpack<L, mp::partial_until_last_t<Tpl, OffsetEnd, Pred, TC, FC>>

emp::partial_until_last_t_c<L, template<int_t, class...> Tpl, int_t OffsetEnd, Pred, TC = listify, FC = clear<TC>> = emp::unpack<L, mp::partial_until_last_t_c<Tpl, OffsetEnd, Pred, TC, FC>>

emp::until_last<L, Searcher> = emp::unpack<L, mp::until_last<Searcher>>

emp::until_last_t<L, template<class...> Tpl, Pred, TC = listify, FC = clear<TC>> = emp::unpack<L, mp::until_last_t<Tpl, Pred, TC, FC>>

<jln/mp/functional/while.hpp>

Test file: test/src/functional/while.cpp

while_<Pred, F, C = identity>

Return: value

Apply a function while some predicate is satisfied.

Implementation
recursively<if_<Pred, F, stop_recursion>, C>

while_xs<Pred, F, C = listify>

Return: value

Apply a function while some predicate is satisfied.

Implementation
recursively<if_<Pred, F, stop_recursion>, C>

emp::while_<L, Pred, F, C = mp::identity> = emp::unpack<L, mp::while_<Pred, F, C>>

emp::while_xs<L, Pred, F, C = mp::listify> = emp::unpack<L, mp::while_<Pred, F, C>>

Group: group

<jln/mp/algorithm/batched.hpp>

Test file: test/src/algorithm/batched.cpp

batched<size, C = listify>

Implementation
strided_sliding_with_c<size::value, size::value, listify, C>

batched_c<int_t size, C = listify>

batched_with<size, F = listify, C = listify>

Implementation
strided_sliding_with_c<size::value, size::value, F, C>

batched_with_c<int_t size, F = listify, C = listify>

Return: sequence

Splits a sequence by arbitrary size group.

Implementation
strided_sliding_with_c<size, size, F, C>
Post-condition
  • If size <= 0, then the result sequence is empty
Semantics
batched_c<2>::f<
  void, void, int, void, void
> = list<
  list<void, void>,
  list<int, void>,
  list<void>
>

emp::batched<L, size, C = mp::listify> = emp::unpack<L, mp::strided_sliding_with_c<size::value, size::value, mp::listify, C>>

emp::batched_c<L, int_t size, C = mp::listify> = emp::unpack<L, mp::strided_sliding_with_c<size, size, mp::listify, C>>

emp::batched_with<L, size, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::strided_sliding_with_c<size::value, size::value, F, C>>

emp::batched_with_c<L, int_t size, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::strided_sliding_with_c<size, size, F, C>>

<jln/mp/algorithm/collapse.hpp>

Test file: test/src/algorithm/collapse.cpp

collapse<keys, C = listify>

Implementation
emp::unpack<keys, cfe<collapse2_with>, C, listify>

collapse2<C, keys...>

Implementation
collapse2_with<C, listify, keys...>

collapse2_c<C, int_t... keys>

Implementation
collapse2_with<C, listify, number<keys>...>

collapse2_with<C, F, keys...>::f<xs...>

Return: sequence

Groups adjacent elements by adjacent keys.

Pre-condition
  • sizeof...(keys) == sizeof...(xs)
Semantics
collapse_for< 1,  1,  0,  0,  0,  1,  2,  2>
         ::f<_0, _1, _2, _3, _4, _5, _6, _7>
==
list<
  list<_0, _1>,
  list<_2, _3, _4>,
  list<_5>,
  list<_6, _7>
>
Note

collapse<list<xs...>>::f<xs...> == group<>::f<xs...>

collapse2_with_c<C, F, int_t... keys>

Implementation
collapse2_with<C, F, number<keys>...>

collapse_for<keys...>

Implementation
collapse2_with<listify, listify, keys...>

collapse_for_c<int_t... keys>

Implementation
collapse2_with<listify, listify, number<keys>...>

collapse_with<keys, F = listify, C = listify>

Implementation
emp::unpack<keys, cfe<collapse2_with>, C, F>

emp::collapse<L, keys, C = listify> = emp::unpack<L, mp::collapse_with<keys, listify, C>>

emp::collapse_for<L, keys...> = emp::unpack<L, mp::collapse2_with<listify, listify, keys...>>

emp::collapse_for_c<L, int_t... keys> = emp::unpack<L, mp::collapse2_with<listify, listify, number<keys>...>>

emp::collapse_with<L, keys, F = listify, C = listify> = emp::unpack<L, mp::collapse_with<keys, F, C>>

<jln/mp/algorithm/combine.hpp>

Test file: test/src/algorithm/combine.cpp

combine<C = listify>::f<xs...>

Return: sequence of list

Computes all possible combinations (with repetition) from the elements in a sequence.

emp::combine<L, C = mp::listify> = emp::unpack<L, mp::combine<C>>

<jln/mp/algorithm/group.hpp>

Test file: test/src/algorithm/group.cpp

group<C = listify>

Implementation
group_by_with<same<>, listify, C>

group_by<Cmp, C = listify>

Implementation
group_by_with<Cmp, listify, C>

group_by_with<Cmp, F = listify, C = listify>::f<xs...>

Return: sequence of list

Groups adjacent elements that respect a predicate.

Semantics
group_by<same<>>::f<void, void, int, void>
== list<
  list<void, void>,
  list<int>,
  list<void>
>

group_with<F = listify, C = listify>

Implementation
group_by_with<same<>, F, C>

emp::group<L, C = listify> = emp::unpack<L, mp::group_by_with<mp::same<>, listify, C>>

emp::group_by<L, Cmp, C = listify> = emp::unpack<L, mp::group_by_with<Cmp, listify, C>>

emp::group_by_with<L, Cmp, F = listify, C = listify> = emp::unpack<L, mp::group_by_with<Cmp, F, C>>

emp::group_with<L, F = listify, C = listify> = emp::unpack<L, mp::group_by_with<mp::same<>, F, C>>

<jln/mp/algorithm/matrix_longest.hpp>

Test file: test/src/algorithm/matrix_longest.cpp

left_matrix_longest<FillValue, C = listify>

Implementation
left_matrix_longest_with<FillValue, listify, C>

left_matrix_longest_with<FillValue, F = listify, C = listify>::f<seqs...>

Return: sequence

Fills a sequence of typelist to the longest size.

Post-condition
Semantics
left_matrix_longest_with<XX, listify>::f<
  list<_1, _2>,
  list<_1, _2, _3>,
  list<_1, _2>,
  list<_1, _2, _3, _4>
> = list<
  list<XX, XX, _1, _2>,
  list<XX, _1, _2, _3>,
  list<XX, XX, _1, _2>,
  list<_1, _2, _3, _4>
>

right_matrix_longest<FillValue, C = listify>

Implementation
right_matrix_longest_with<FillValue, listify, C>

right_matrix_longest_with<FillValue, F = listify, C = listify>::f<seqs...>

Return: sequence

Fills a sequence of typelist to the longest size.

Post-condition
Semantics
right_matrix_longest_with_matrix_longest_with<XX, listify>::f<
  list<_1, _2>,
  list<_1, _2, _3>,
  list<_1, _2>,
  list<_1, _2, _3, _4>
> = list<
  list<_1, _2, XX, XX>,
  list<_1, _2, _3, XX>,
  list<_1, _2, XX, XX>,
  list<_1, _2, _3, _4>
>

emp::left_matrix_longest<L, FillValue, C = mp::listify> = emp::unpack<L, mp::left_matrix_longest<FillValue, C>>

emp::left_matrix_longest_with<L, FillValue, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::left_matrix_longest_with<FillValue, F, C>>

emp::right_matrix_longest<L, FillValue, C = mp::listify> = emp::unpack<L, mp::right_matrix_longest<FillValue, C>>

emp::right_matrix_longest_with<L, FillValue, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::right_matrix_longest_with<FillValue, F, C>>

<jln/mp/algorithm/matrix_shortest.hpp>

Test file: test/src/algorithm/matrix_shortest.cpp

left_matrix_shortest<C = listify>

left_matrix_shortest_with<F = listify, C = listify>::f<seqs...>

Return: sequence

Truncates a sequence of typelist to the smallest size.

Post-condition
Semantics
left_matrix_shortest_with<listify>::f<
  list<_1, _2>,
  list<_1, _2, _3>,
  list<_1, _2>,
  list<_1, _2, _3, _4>
> = list<
  list<_1, _2>,
  list<_1, _2>,
  list<_1, _2>,
  list<_1, _2>
>

right_matrix_shortest<C = listify>

right_matrix_shortest_with<F = listify, C = listify>::f<seqs...>

Return: sequence

Truncates a sequence of typelist to the smallest size.

Post-condition
Semantics
right_matrix_shortest_with<listify>::f<
  list<_1, _2>,
  list<_1, _2, _3>,
  list<_1, _2>,
  list<_1, _2, _3, _4>
> = list<
  list<_1, _2>,
  list<_2, _3>,
  list<_1, _2>,
  list<_3, _4>
>

emp::left_matrix_shortest<L, C = mp::listify> = emp::unpack<L, mp::left_matrix_shortest<C>>

emp::left_matrix_shortest_with<L, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::left_matrix_shortest_with<F, C>>

emp::right_matrix_shortest<L, C = mp::listify> = emp::unpack<L, mp::right_matrix_shortest<C>>

emp::right_matrix_shortest_with<L, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::right_matrix_shortest_with<F, C>>

<jln/mp/algorithm/pairwise.hpp>

Test file: test/src/algorithm/pairwise.cpp

pairwise<C = listify>

Implementation
pairwise_with<listify, C>

pairwise_with<F = listify, C = listify>::f<xs...>

Return: sequence of list

Returns successive overlapping pairs.

Post-condition
  • If sizeof...(xs) <= 1, then the result sequence is empty
  • If sizeof...(xs) > 1, then the number of 2-tuples is sizeof...(xs) - 1
Semantics
pairwise<>::f<a, b, c, d>
== list<
  list<a, b>,
  list<b, c>,
  list<c, d>
>

emp::pairwise<L, C = mp::listify> = emp::unpack<L, mp::pairwise<C>>

emp::pairwise_with<L, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::pairwise_with<F, C>>

<jln/mp/algorithm/partition.hpp>

Test file: test/src/algorithm/partition.cpp

partition<Pred, C = listify>

Return: sequence of two lists

Splits a list in two according to a predicate.

The first value contains all elements for which the predicate returns true, the second value contains all elements for which predicate returns false

Implementation
partition_with<Pred, listify, C>

partition_with<Pred, F = listify, C = listify>::f<xs...>

Return: sequence of two values

Splits a list in two according to a predicate.

The first value contains all elements for which the predicate returns true, the second value contains all elements for which predicate returns false

emp::partition<L, Pred, C = mp::listify> = emp::unpack<L, mp::partition<Pred, C>>

emp::partition_with<L, Pred, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::partition_with<Pred, F, C>>

<jln/mp/algorithm/permutations.hpp>

Test file: test/src/algorithm/permutations.cpp

permutations<C = listify>::f<xs...>

Return: sequence of list

Generates all permutations of sequence.

Post-condition
  • sizeof...(result) == sizeof...(xs)!

emp::permutations<L, C = listify> = emp::unpack<L, mp::permutations<C>>

<jln/mp/algorithm/powerset.hpp>

Test file: test/src/algorithm/powerset.cpp

powerset<C = listify>::f<xs...>

Return: sequence of list

Computes the powerset of a sequence.

Semantics
powerset<>::f<a, b, c> == list<
  list<>,
  list<a>, list<b>, list<a, b>, list<c>,
  list<a, c>, list<b, c>,
  list<a, b, c>
>

emp::powerset<L, C = mp::listify> = emp::unpack<L, mp::powerset<C>>

<jln/mp/algorithm/product.hpp>

Test file: test/src/algorithm/product.cpp

product<C = listify>::f<seq = list<>, seqs...>

Return: sequence

Computes the cartesian product of lists.

Pre-condition
Post-condition
  • sizeof...(result) == (emp::size<seqs> * ...) if sizeof...(xs) != 0 else 0
Semantics
call<product<listify>,
  list<_0, _1, _2>,
  list<_3, _4>,
  list<_5>
> = list<
  list<_0, _3, _5>, list<_0, _4, _5>,
  list<_1, _3, _5>, list<_1, _4, _5>,
  list<_2, _3, _5>, list<_2, _4, _5>
>

emp::product<L, C = mp::listify> = emp::unpack<L, product<C>>

<jln/mp/algorithm/regroup.hpp>

Test file: test/src/algorithm/regroup.cpp

regroup<C = listify>

Implementation
regroup_with<listify, C>

regroup_by<Cmp = same<>, C = listify>

Implementation
regroup_by_with<Cmp, listify, C>

regroup_by_with<Cmp = same<>, F = listify, C = listify>::f<xs...>

regroup_with<F, C = listify>

Return: sequence of list of type and number

Group identical type together.

Elements are sorted in order of first appearance.

Semantics
regroup_with<listify>::f<int, int, char, double, int, double>
== list<
  list<int, int, int>,
  list<char>,
  list<double, double>
>

emp::regroup<L, C = mp::listify> = emp::unpack<L, mp::regroup<C>>

emp::regroup_by<L, Cmp = mp::same<>, C = mp::listify> = emp::unpack<L, mp::regroup_by<Cmp, C>>

emp::regroup_by_with<L, Cmp = mp::same<>, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::regroup_by_with<Cmp, F, C>>

emp::regroup_with<L, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::regroup_with<F, C>>

<jln/mp/algorithm/split_after.hpp>

Test file: test/src/algorithm/split_after.cpp

split_after<x, C = listify>

Implementation
split_after_if_with<is<x>, listify, C>

split_after_if<Pred = identity, C = listify>

Implementation
split_after_if_with<Pred, listify, C>

split_after_if_with<Pred, F = listify, C = listify>::f<xs...>

Return: sequence

Splits a sequence into multiple lists at every point that satisfy a predicate.

The separator value is inserted at the end of the previous list.

Semantics
split_after_if<is<_0>>::f<_0, _1, _2, _0, _3>
== list<
  list<_0>,
  list<_1, _2, _0>,
  list<_3>
>

split_after_with<x, F = listify, C = listify>

Implementation
split_after_if_with<is<x>, F, C>

emp::split_after<L, x, C = listify> = emp::unpack<L, mp::split_after_if_with<is<x>, listify, C>>

emp::split_after_if<L, Pred = mp::identity, C = listify> = emp::unpack<L, mp::split_after_if_with<Pred, listify, C>>

emp::split_after_if_with<L, Pred = mp::identity, F = listify, C = listify> = emp::unpack<L, mp::split_after_if_with<Pred, F, C>>

emp::split_after_with<L, x, F = listify, C = listify> = emp::unpack<L, mp::split_after_if_with<is<x>, F, C>>

<jln/mp/algorithm/split_at.hpp>

Test file: test/src/algorithm/split_at.cpp

split_at<i, C = listify>

Implementation
split_at2_with_c<i::value, listify, listify, C>

split_at2_with<i, SubC1 = listify, SubC2 = SubC1, C = listify>

Implementation
split_at2_with_c<i::value, SubC1, SubC2, C>

split_at2_with_c<unsigned i, SubC1 = listify, SubC2 = SubC1, C = listify>::f<xs...>

Return: sequence of two values

Splits a sequence at an arbitrary position.

Pre-condition
  • i >= 0 && i <= sizeof...(xs)

split_at_c<unsigned i, C = listify>

Return: sequence of two lists

Splits a sequence at an arbitrary position.

Implementation
split_at2_with_c<i, listify, listify, C>
Pre-condition
  • i >= 0 && i <= sizeof...(xs)

split_at_with<i, F = listify, C = listify>

Implementation
split_at2_with_c<i::value, F, F, C>

split_at_with_c<unsigned i, F = listify, C = listify>

Implementation
split_at2_with_c<i, F, F, C>

emp::split_at<L, i, C = mp::listify> = emp::unpack<L, mp::split_at2_with_c<i::value, listify, listify, C>>

emp::split_at2_with<L, i, SubC1 = mp::listify, SubC2 = mp::listify, C = mp::listify> = emp::unpack<L, mp::split_at2_with_c<i::value, SubC1, SubC2, C>>

emp::split_at2_with_c<L, unsigned i, SubC1 = mp::listify, SubC2 = mp::listify, C = mp::listify> = emp::unpack<L, mp::split_at2_with_c<i, SubC1, SubC2, C>>

emp::split_at_c<L, unsigned i, C = mp::listify> = emp::unpack<L, mp::split_at2_with_c<i, listify, listify, C>>

emp::split_at_with<L, i, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::split_at2_with_c<i::value, F, F, C>>

emp::split_at_with_c<L, unsigned i, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::split_at2_with_c<i, F, F, C>>

<jln/mp/algorithm/split_before.hpp>

Test file: test/src/algorithm/split_before.cpp

split_before<x, C = listify>

Implementation
split_before_if_with<is<x>, listify, C>

split_before_if<Pred = identity, C = listify>

Implementation
split_before_if_with<Pred, listify, C>

split_before_if_with<Pred, F = listify, C = listify>::f<xs...>

Return: sequence

Splits a sequence into multiple lists at every point that satisfy a predicate.

The separator value is inserted at the beginning of the following list.

Semantics
split_before_if<is<_0>>::f<_0, _1, _2, _0, _3>
== list<
  list<>,
  list<_0, _1, _2>,
  list<_0, _3>
>

split_before_with<x, F = listify, C = listify>

Implementation
split_before_if_with<is<x>, F, C>

emp::split_before<L, x, C = listify> = emp::unpack<L, mp::split_before_if_with<is<x>, listify, C>>

emp::split_before_if<L, Pred = mp::identity, C = listify> = emp::unpack<L, mp::split_before_if_with<Pred, listify, C>>

emp::split_before_if_with<L, Pred = mp::identity, F = listify, C = listify> = emp::unpack<L, mp::split_before_if_with<Pred, F, C>>

emp::split_before_with<L, x, F = listify, C = listify> = emp::unpack<L, mp::split_before_if_with<is<x>, F, C>>

<jln/mp/algorithm/split_from.hpp>

Test file: test/src/algorithm/split_from.cpp

split_from<GetIndex, C = listify>

Implementation
split_from2<GetIndex, listify, listify, C>

split_from2<GetIndex, SubC1 = listify, SubC2 = SubC1, C = listify>::f<xs...>

Return: sequence of two values

Splits a sequence at an arbitrary position returns by GetIndex.

Implementation
split_at2_with_c< GetIndex::f<xs...>::value, SubC1, SubC2, C>::f<xs...>
Pre-condition
  • GetIndex::f<xs...>::value >= 0 && GetIndex::f<xs...>::value <= sizeof...(xs)

emp::split_from<L, GetIndex, C = mp::listify> = emp::unpack<L, mp::split_from2<GetIndex, mp::listify, mp::listify, C>>

emp::split_from2<L, GetIndex, SubC1 = mp::listify, SubC2 = SubC1, C = mp::listify> = emp::unpack<L, mp::split_from2<GetIndex, SubC1, SubC2, C>>

<jln/mp/algorithm/split.hpp>

Test file: test/src/algorithm/split.cpp

split<x, C = listify>

Implementation
split_if_with<is<x>, listify, C>

split_if<Pred = identity, C = listify>

Implementation
split_if_with<Pred, listify, C>

split_if_with<Pred = identity, F = listify, C = listify>::f<xs...>

Return: sequence

Splits a sequence into multiple lists at every point that satisfy a predicate.

The separator value is removed.

Semantics
split_if<is<_0>>::f<_0, _1, _2, _0, _3>
== list<
  list<>,
  list<_1, _2>,
  list<_3>
>

split_with<x, F = listify, C = listify>

Implementation
split_if_with<is<x>, F, C>

emp::split<L, x, C = listify> = emp::unpack<L, mp::split_if_with<is<x>, listify, C>>

emp::split_if<L, Pred = mp::identity, C = listify> = emp::unpack<L, mp::split_if_with<Pred, listify, C>>

emp::split_if_with<L, Pred = mp::identity, F = listify, C = listify> = emp::unpack<L, mp::split_if_with<Pred, F, C>>

emp::split_with<L, x, F = listify, C = listify> = emp::unpack<L, mp::split_if_with<is<x>, F, C>>

<jln/mp/algorithm/split_keep_separator.hpp>

Test file: test/src/algorithm/split_keep_separator.cpp

split_keep_separator<x, C = listify>

Implementation
split_keep_separator_if_with<is<x>, listify, C>

split_keep_separator_if<Pred = identity, C = listify>

Implementation
split_keep_separator_if_with<Pred, listify, C>

split_keep_separator_if_with<Pred = identity, F = listify, C = listify>::f<xs...>

Return: sequence of list

Splits a sequence into multiple lists at every point that satisfy a predicate.

The separator value is inserted in a new list.

Semantics
split_keep_separator_if<is<_0>>::f<_0, _1, _2, _0, _3>
== list<
  list<>,
  list<_0>,
  list<_1, _2>,
  list<_0>,
  list<_3>
>

split_keep_separator_with<x, F = listify, C = listify>

Implementation
split_keep_separator_if_with<is<x>, F, C>

emp::split_keep_separator<L, x, C = listify> = emp::unpack<L, mp::split_keep_separator_if_with<is<x>, listify, C>>

emp::split_keep_separator_if<L, Pred = mp::identity, C = listify> = emp::unpack<L, mp::split_keep_separator_if_with<Pred, listify, C>>

emp::split_keep_separator_if_with<L, Pred = mp::identity, F = listify, C = listify> = emp::unpack<L, mp::split_keep_separator_if_with<Pred, F, C>>

emp::split_keep_separator_with<L, x, F = listify, C = listify> = emp::unpack<L, mp::split_keep_separator_if_with<is<x>, F, C>>

<jln/mp/algorithm/split_once.hpp>

Test file: test/src/algorithm/split_once.cpp

split_once<x, TC = listify, FC = clear<>>

Implementation
split_once_if<is<x>, TC, FC>

split_once_if<Pred, TC = listify, FC = clear<>>::f<xs...>

Return: sequence of two or zero sequence

Splits a sequence at the first position that satisfy a predicate.

emp::split_once<L, x, TC = listify, FC = clear<>> = emp::unpack<L, mp::split_once_if<is<x>, TC, FC>>

emp::split_once_if<L, Pred, TC = listify, FC = clear<>> = emp::unpack<L, mp::split_once_if<Pred, TC, FC>>

<jln/mp/algorithm/zip_longest.hpp>

Test file: test/src/algorithm/zip_longest.cpp

zip_longest<FillValue, C = listify>

Return: sequence of list

Turns rows into columns, and columns into rows.

Missing values are filled-in with fillvalue. This is similar to transposing a matrix.

Implementation
right_matrix_longest<FillValue, zip<C>>
Semantics
zip_longest<_0>::f<
  list<_1, _2, _3>,
  list<_a, _b, _c, _d>
> = list<
  list<_1, _a>,
  list<_2, _b>,
  list<_3, _c>
  list<_0, _d>
>

zip_longest_with<FillValue, F = listify, C = listify>

Implementation
right_matrix_longest<FillValue, zip_with<F, C>>

emp::zip_longest<L, FillValue, C = mp::listify> = emp::unpack<L, mp::zip_longest<FillValue, C>>

emp::zip_longest_with<L, FillValue, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::zip_longest_with<FillValue, F, C>>

<jln/mp/algorithm/zip.hpp>

Test file: test/src/algorithm/zip.cpp

zip<C = listify>

Implementation
zip_with<listify, C>

zip_with<F = listify, C = listify>::f<seqs...>

Return: sequence of list

Turns rows into columns, and columns into rows.

This is similar to transposing a matrix.

Pre-condition
  • all parameters must be lists
  • all lists must be the same size
Semantics
zip<>::f<
  list<_1, _2, _3>,
  list<_a, _b, _c>
> = list<
  list<_1, _a>,
  list<_2, _b>,
  list<_3, _c>
>

emp::zip<L, C = mp::listify> = emp::unpack<L, mp::zip<C>>

emp::zip_with<L, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::zip_with<F, C>>

Group: list

<jln/mp/list/append.hpp>

Test file: test/src/list/append.cpp

append<L, C = listify>

Return: sequence

Inserts elements at the end of L list.

Implementation
push_front<L, unpack_append<C>>

emp::append<L, xs...> = /*...*/

<jln/mp/list/as_list.hpp>

Test file: test/src/list/as_list.cpp

as_list<C = identity>::f<seq>

Return: list

Extracts type paramaters of a template class or union, then constructs a list.

Pre-condition
  • seq must be compatible with typelist or detail::_as_list<seq>::type.

emp::as_list<seq, C = mp::identity> = as_list<C>::f<seq>

<jln/mp/list/at.hpp>

Test file: test/src/list/at.cpp

at<N, C = identity>

Return: value

Retrieves an element of a sequence at an arbitrary position.

Implementation
drop_front<N, front<C>>
Pre-condition
  • 0 <= N < sizeof...(xs)

at0<C = identity>

Implementation
front<C>

at1<C = identity>

Implementation
drop_front_c<1, front<C>>

at2<C = identity>

Implementation
drop_front_c<2, front<C>>

at3<C = identity>

Implementation
drop_front_c<3, front<C>>

at4<C = identity>

Implementation
drop_front_c<4, front<C>>

at5<C = identity>

Implementation
drop_front_c<5, front<C>>

at6<C = identity>

Implementation
drop_front_c<6, front<C>>

at7<C = identity>

Implementation
drop_front_c<7, front<C>>

at8<C = identity>

Implementation
drop_front_c<8, front<C>>

at9<C = identity>

Implementation
drop_front_c<9, front<C>>

at_c<unsigned n, C = identity>

Implementation
drop_front_c<n, front<C>>

emp::at<L, i, C = mp::identity> = emp::unpack<L, mp::drop_front_c<i::value, mp::front<C>>>

emp::at0<L, C = mp::identity> = emp::unpack<L, mp::front<C>>

emp::at1<L, C = mp::identity> = emp::unpack<L, mp::drop_front_c<1, mp::front<C>>>

emp::at2<L, C = mp::identity> = emp::unpack<L, mp::drop_front_c<2, mp::front<C>>>

emp::at3<L, C = mp::identity> = emp::unpack<L, mp::drop_front_c<3, mp::front<C>>>

emp::at4<L, C = mp::identity> = emp::unpack<L, mp::drop_front_c<4, mp::front<C>>>

emp::at5<L, C = mp::identity> = emp::unpack<L, mp::drop_front_c<5, mp::front<C>>>

emp::at6<L, C = mp::identity> = emp::unpack<L, mp::drop_front_c<6, mp::front<C>>>

emp::at7<L, C = mp::identity> = emp::unpack<L, mp::drop_front_c<7, mp::front<C>>>

emp::at8<L, C = mp::identity> = emp::unpack<L, mp::drop_front_c<8, mp::front<C>>>

emp::at9<L, C = mp::identity> = emp::unpack<L, mp::drop_front_c<9, mp::front<C>>>

emp::at_c<L, unsigned i, C = mp::identity> = emp::unpack<L, mp::drop_front_c<i, mp::front<C>>>

<jln/mp/list/back.hpp>

Test file: test/src/list/back.cpp

back<C = identity>

Return: value

Retrieves the last element of a sequence.

Implementation
rotate_c<-1, front<C>>

emp::back<L, C = mp::identity> = emp::unpack<L, mp::back<C>>

<jln/mp/list/lookup.hpp>

Test file: test/src/list/lookup.cpp

build_indexed<xs...>::f<i>

Constructs an indexable sequence in O(1).

If possible prefer the use of build_indexed_v

Pre-condition
  • 0 <= i::value < sizeof...(xs)

build_indexed_v<xs...>::f<int i>

Constructs an indexable sequence in O(1).

Pre-condition
  • 0 <= i < sizeof...(xs)

emp::build_indexed<L> = emp::unpack<L, cfe<mp::build_indexed>>

emp::build_indexed_v<L> = emp::unpack<L, cfe<mp::build_indexed_v>>

emp::indexed_lookup<IndexedV, I> = IndexedV::f<I::value>

emp::indexed_lookup_c<IndexedV, int i> = IndexedV::f<i>

emp::lookup<L, I> = emp::unpack<L, mp::cfe<mp::build_indexed_v>>::f<I::value>

emp::lookup_c<L, int i> = emp::unpack<L, mp::cfe<mp::build_indexed_v>>::f<i>

<jln/mp/list/clear.hpp>

Test file: test/src/list/clear.cpp

clear<C = listify>::f<xs...>

Return: value

Removes all elements from the sequence.

Implementation
C::f<>

<jln/mp/list/drop_back.hpp>

Test file: test/src/list/drop_back.cpp

drop_back<N, C = listify>

Implementation
drop_back_c<N::value, C>

drop_back_c<unsigned N, C = listify>::f<xs...>

Return: sequence

Removes N elements from the end of a sequence.

Pre-condition
  • 0 <= N <= sizeof...(xs)

drop_back_max<N, C = listify>

Implementation
drop_back_max_c<N::value, C>

drop_back_max_c<unsigned N, C = listify>::f<xs...>

Return: sequence

Removes at most N elements from the end of a sequence.

Pre-condition
  • 0 <= N

emp::drop_back<L, N, C = mp::listify> = emp::unpack<L, mp::drop_back<N, C>>

emp::drop_back_c<L, int_t n, C = mp::listify> = emp::unpack<L, mp::drop_back_c<n, C>>

emp::drop_back_max<L, N, C = mp::listify> = emp::unpack<L, mp::drop_back_max<N, C>>

emp::drop_back_max_c<L, int_t n, C = mp::listify> = emp::unpack<L, mp::drop_back_max_c<n, C>>

<jln/mp/list/drop_front.hpp>

Test file: test/src/list/drop_front.cpp

drop_front<N, C = listify>

Implementation
drop_front_c<N::value, C>

drop_front_c<unsigned N, C = listify>::f<xs...>

Return: sequence

Removes N elements from the beginning of a sequence.

Pre-condition
  • 0 <= N <= sizeof...(xs)

drop_front_max<N, C = listify>

Implementation
drop_front_max_c<N::value, C>

drop_front_max_c<unsigned N, C = listify>::f<xs...>

Return: sequence

Removes at most N elements from the beginning of a sequence.

Pre-condition
  • 0 <= N

emp::drop_front<L, N, C = mp::listify> = emp::unpack<L, mp::drop_front<N, C>>

emp::drop_front_c<L, unsigned n, C = mp::listify> = emp::unpack<L, mp::drop_front_c<n, C>>

emp::drop_front_max<L, N, C = mp::listify> = emp::unpack<L, mp::drop_front_max<N, C>>

emp::drop_front_max_c<L, unsigned n, C = mp::listify> = emp::unpack<L, mp::drop_front_max_c<n, C>>

<jln/mp/list/enumerate.hpp>

Test file: test/src/list/enumerate.cpp

enumerate<C = listify>

Implementation
enumerate_with<listify, C>

enumerate_v_with<F, C = listify>::f<xs...>

Return: sequence

Returns pairs containing a numeric index of type int_t and a value.

Semantics
C::f<F::f<0, xs[0]>, ..., F::f<n, xs[n]>>

enumerate_with<F = listify, C = listify>::f<xs...>

Return: sequence

Returns pairs containing an index and a value.

Semantics
C::f<F::f<number<0>, xs[0]>, ..., F::f<number<n>, xs[n]>>

emp::enumerate<L, C = mp::listify> = emp::unpack<L, mp::enumerate_with<mp::listify, C>>

emp::enumerate_v_with<L, F, C = mp::listify> = emp::unpack<L, mp::enumerate_v_with<F, C>>

emp::enumerate_with<L, F = mp::listify, C = mp::listify> = emp::unpack<L, mp::enumerate_with<F, C>>

<jln/mp/list/erase.hpp>

Test file: test/src/list/erase.cpp

erase<start, size = number<1>, C = listify>

Implementation
erase_c<start::value, size::value, C>

erase_c<int_t start, unsigned size = 1, C = listify>::f<xs...>

Return: sequence

Removes at most size elements from index start.

A negative value represents an index starting from the end.

emp::erase<L, start, size = mp::number<1>, C = mp::listify> = emp::unpack<L, mp::erase<start, size, C>>

emp::erase_c<L, int_t start, unsigned size = 1, C = mp::listify> = emp::unpack<L, mp::erase_c<start, size, C>>

<jln/mp/list/front.hpp>

Test file: test/src/list/front.cpp

front<C = identity>::f<xs...>

Return: value

Retrieves the first element of a sequence.

emp::front<L, C = mp::identity> = emp::unpack<L, front<C>>

<jln/mp/list/insert.hpp>

Test file: test/src/list/insert.cpp

insert<index, x, C = listify>

Implementation
insert_sequence_c<index::value, list<x>, C>

insert_c<int_t index, x, C = listify>

Return: sequence

Inserts an elements at an arbitrary position.

Implementation
insert_sequence_c<index, list<x>, C>

emp::insert<L, index, x, C = mp::listify> = emp::unpack<L, mp::insert<index, x, C>>

emp::insert_c<L, int_t index, x, C = mp::listify> = emp::unpack<L, mp::insert_c<index, x, C>>

<jln/mp/list/insert_sequence.hpp>

Test file: test/src/list/insert_sequence.cpp

insert_sequence<index, seq, C = listify>

Implementation
insert_sequence_c<index::value, seq, C>

insert_sequence_c<int_t index, seq, C = listify>

Return: sequence

Inserts all elements of seq at an arbitrary position.

A negative value represents an index starting from the end.

insert_sequence_c<index, List<xs...>, C>::f<ys...>

emp::insert_sequence<L, index, seq, C = mp::listify> = emp::unpack<L, mp::insert_sequence<index, seq, C>>

emp::insert_sequence_c<L, int_t index, seq, C = mp::listify> = emp::unpack<L, mp::insert_sequence_c<index, seq, C>>

<jln/mp/list/is_empty.hpp>

Test file: test/src/list/is_empty.cpp

is_empty<C = identity>

Return: true_ / false_

Checks whether a sequence has no elements.

Implementation
size<not_<C>>

emp::is_empty<L, C = mp::identity> = emp::unpack<L, mp::is_empty<C>>

bool emp::is_empty_v<L, C = mp::identity> = emp::unpack<L, mp::is_empty<C>>::value

<jln/mp/list/is_list.hpp>

Test file: test/src/list/is_list.cpp

is_list<C = identity>::f<x>

Return: true_ / false_

Checks whether x is a list.

Implementation
C::f<number<emp::is_list_v<x>>>

emp::is_list<x, C = mp::identity> = C::f<number<emp::is_list_v<x>>>

bool emp::is_list_v<x> = false

<jln/mp/list/is_not_empty.hpp>

Test file: test/src/list/is_not_empty.cpp

is_not_empty<C = identity>

Return: true_ / false_

Checks whether a sequence has elements.

Implementation
size<is<number<0>, not_<C>>>

emp::is_not_empty<L, C = mp::identity> = emp::unpack<L, mp::is_not_empty<C>>

bool emp::is_not_empty_v<L, C = mp::identity> = emp::unpack<L, mp::is_not_empty<C>>::value

<jln/mp/list/is_size_of.hpp>

Test file: test/src/list/is_size_of.cpp

is_size_of<N, C = identity>

Implementation
size<is<N, C>>

is_size_of_c<int_t n, C = identity>

Implementation
size<is<number<n>, C>>

emp::is_size_of<L, N, C = mp::identity> = emp::unpack<L, mp::is_size_of<N, C>>

emp::is_size_of_c<L, int_t n, C = mp::identity> = emp::unpack<L, mp::is_size_of_c<n, C>>

bool emp::is_size_of_c_v<L, int_t n, C = mp::identity> = emp::unpack<L, mp::is_size_of_c<n, C>>::value

bool emp::is_size_of_v<L, N, C = mp::identity> = emp::unpack<L, mp::is_size_of<N, C>>::value

<jln/mp/list/join.hpp>

Test file: test/src/list/join.cpp

join<C = listify>::f<seqs...>

Return: sequence

Concatenates lists.

Pre-condition

emp::join<seqs...> = mp::join<>::f<seqs...>

<jln/mp/list/list.hpp>

Test file: test/src/list/list.cpp

list<xs...>

<jln/mp/list/listify.hpp>

Test file: test/src/list/listify.cpp

listify

Return: list

Implementation
cfe<list>

<jln/mp/list/offset.hpp>

Test file: test/src/list/offset.cpp

offset<I, C = identity>

Implementation
offset_c<I::value, C>

offset_c<int_t I, C = identity>::f<xs...>

Return: number

Difference between the number of parameter xs and I::value.

Implementation
C::f<number<I - int_t(sizeof...(xs))>>
Semantics

Equivalent to

size<push_front<I, sub<C>>>

emp::offset<L, I, C = mp::identity> = emp::unpack<L, mp::offset<I, C>>

emp::offset_c<L, int_t i, C = mp::identity> = emp::unpack<L, mp::offset_c<i, C>>

int_t emp::offset_c_v<L, int_t i, C = mp::identity> = emp::unpack<L, mp::offset_c<i, C>>::value

int_t emp::offset_v<L, I, C = mp::identity> = emp::unpack<L, mp::offset<I, C>>::value

<jln/mp/list/pop_back.hpp>

Test file: test/src/list/pop_back.cpp

pop_back<C = listify>

Return: sequence

Removes the last element of sequence.

Implementation
rotate_c<-1, pop_front<C>>
Pre-condition
  • sizeof...(xs) > 0

emp::pop_back<L, C = mp::listify> = emp::unpack<L, mp::pop_back<C>>

<jln/mp/list/pop_front.hpp>

Test file: test/src/list/pop_front.cpp

pop_front<C = listify>

Return: sequence

Remove the first element of sequence

Implementation
drop_front_c<1, C>
Pre-condition
  • sizeof...(xs) > 0

emp::pop_front<L, C = mp::listify> = drop_front_c<L, 1, C>

<jln/mp/list/prepend.hpp>

Test file: test/src/list/prepend.cpp

prepend<L, C = listify>

Return: sequence

Inserts elements at the start of L list.

Implementation
push_front<L, unpack<C>>

emp::prepend<L, xs...> = emp::unpack<L, listify, xs...>

<jln/mp/list/push_back.hpp>

Test file: test/src/list/push_back.cpp

push_back<x, C = listify>::f<xs...>

Return: sequence

Appends x to the end of the sequence.

Implementation
C::f<xs..., x>

emp::push_back<L, T, C = mp::listify> = emp::unpack<L, mp::push_back<T, C>>

<jln/mp/list/push_front.hpp>

Test file: test/src/list/push_front.cpp

push_front<x, C = listify>::f<xs...>

Return: sequence

Appends x to the beginning of the sequence.

Implementation
C::f<x, xs...>

emp::push_front<L, T, C = mp::listify> = emp::unpack<L, mp::push_front<T, C>>

<jln/mp/list/range.hpp>

Test file: test/src/list/range.cpp

range<beg, end, C = listify>

Implementation
range_c<beg::value, end::value, C>

range_c<int_t beg, int_t end, C = listify>::f<xs...>

Return: sequence

Returns a contiguous subsequence of a sequence.

A negative value represents an index starting from the end. All indices available in the range are returned, indices outside the bounds are ignored.

emp::range<L, beg, end, C = mp::listify> = emp::unpack<L, mp::range<beg, end, C>>

emp::range_c<L, int_t beg, int_t end, C = mp::listify> = emp::unpack<L, mp::range_c<beg, end, C>>

<jln/mp/list/size.hpp>

Test file: test/src/list/size.cpp

size<C = identity>::f<xs...>

Return: number

Returns the number of elements in a xs.

Implementation
C::f<number<sizeof...(xs)>>

emp::size<L, C = mp::identity> = emp::unpack<L, mp::size<C>>

std::size_t emp::size_v<L, C = mp::identity> = emp::unpack<L, mp::size<C>>::value

<jln/mp/list/slice.hpp>

Test file: test/src/list/slice.cpp

slice<start, count, C = listify>

Implementation
strided_slice_c<start::value, count::value, 1, C>

slice_c<int_t start, unsigned count, C = listify>

Implementation
strided_slice_c<start, count, 1, C>

strided_slice<start, count, step = number<1>, C = listify>

Implementation
strided_slice_c<start::value, count::value, step::value, C>

strided_slice_c<int_t start, unsigned count, unsigned step = 1, C = listify>::f<xs...>

Return: sequence

Returns a subset of elements in a xs picked at regular intervals in range.

A negative start represents an index starting from the end.

Pre-condition

emp::slice<L, start, count, C = mp::listify> = emp::unpack<L, mp::strided_slice_c<start::value, count::value, 1, C>>

emp::slice_c<L, int_t start, unsigned count, C = mp::listify> = emp::unpack<L, mp::strided_slice_c<start, count, 1, C>>

emp::strided_slice<L, start, count, step = number<1>, C = mp::listify> = emp::unpack<L, strided_slice<start, count, step, C>>

emp::strided_slice_c<L, int_t start, unsigned count, unsigned step = 1, C = mp::listify> = emp::unpack<L, mp::strided_slice_c<start, count, step, C>>

<jln/mp/list/sliding.hpp>

Test file: test/src/list/sliding.cpp

sliding<size, C = listify>

Implementation
strided_sliding_with_c<size::value, 1, listify, C>

sliding_c<int_t size, C = listify>

Implementation
strided_sliding_with_c<size, 1, listify, C>

sliding_with<size, F = listify, C = listify>

Implementation
strided_sliding_with_c<size::value, 1, F, C>

sliding_with_c<int_t size, F = listify, C = listify>

Implementation
strided_sliding_with_c<size, 1, F, C>

strided_sliding<size, stride = number<1>, C = listify>

Implementation
strided_sliding_with_c<size::value, stride::value, listify, C>

strided_sliding_c<int_t size, int_t stride = 1, C = listify>

Implementation
strided_sliding_with_c<size, stride, listify, C>

strided_sliding_with<size, stride = number<1>, F = listify, C = listify>

Implementation
strided_sliding_with_c<size::value, stride::value, F, C>

strided_sliding_with_c<int_t size, int_t stride = 1, F = listify, C = listify>

Return: sequence of list Given a sequence and a count n, place a window over the first n elements of the underlying range. Return the contents of that window as the first element of the adapted range, then slide the window forward one element at a time until hitting the end of the underlying range.

Returns sliding windows of width size.

Pre-condition
  • stride != 0
  • size >= 0
Semantics

If stride < 0, then stride = stride + size If sizeof...(xs) < size, then f = C::f<xs...> If stride > 1, the last window may be smaller than size If stride == 0 || size <= 0, then the result sequence is empty

strided_sliding_with_c<3, 1, F, C>::f<_0, _1, _2, _3, _4>
==
C::f<F::f<_0, _1, _2>, F::f<_1, _2, _3>, F::f<_2, _3, _4>>

strided_sliding_with_c<3, 2, F, C>::f<_0, _1, _2, _3, _4>
==
C::f<F::f<_0, _1, _2>, F::f<_2, _3, _4>>

emp::sliding<L, size, C = mp::listify> = emp::unpack<L, mp::strided_sliding_with_c<size::value, 1, listify, C>>

emp::sliding_c<L, int_t size, C = mp::listify> = emp::unpack<L, mp::strided_sliding_with_c<size, 1, listify, C>>

emp::sliding_with<L, size, F = listify, C = mp::listify> = emp::unpack<L, mp::strided_sliding_with_c<size::value, 1, F, C>>

emp::sliding_with_c<L, int_t size, F = listify, C = mp::listify> = emp::unpack<L, mp::strided_sliding_with_c<size, 1, F, C>>

emp::strided_sliding<L, size, stride = number<1>, C = mp::listify> = emp::unpack<L, mp::strided_sliding_with_c<size::value, stride::value, listify, C>>

emp::strided_sliding_c<L, int_t size, int_t stride = 1, C = mp::listify> = emp::unpack<L, mp::strided_sliding_with_c<size, stride, listify, C>>

emp::strided_sliding_with<L, size, stride = number<1>, F = listify, C = mp::listify> = emp::unpack<L, mp::strided_sliding_with_c<size::value, stride::value, F, C>>

emp::strided_sliding_with_c<L, int_t size, int_t stride = 1, F = listify, C = mp::listify> = emp::unpack<L, mp::strided_sliding_with_c<size, stride, F, C>>

<jln/mp/list/swap_index.hpp>

Test file: test/src/list/swap_index.cpp

swap_index<I, J, C = listify>

Implementation
swap_index_c<I::value, J::value, C>

swap_index_c<unsigned i, unsigned j, C = listify>

Return: sequence

Swap elements at indices i and j of a sequence.

Pre-condition
  • 0 < i < sizeof...(xs)
  • 0 < j < sizeof...(xs)
Note

swap_index<I, J> == swap_index<J, I>

emp::swap_index<L, I, J, C = mp::listify> = emp::unpack<L, swap_index<I, J, C>>

emp::swap_index_c<L, unsigned i, unsigned j, C = mp::listify> = emp::unpack<L, swap_index_c<i, j, C>>

<jln/mp/list/take_back.hpp>

Test file: test/src/list/take_back.cpp

take_back<N, C = listify>

Implementation
take_back_c<N::value, C>

take_back_c<unsigned N, C = listify>::f<xs...>

Return: sequence

Extracts N elements from the end of a sequence.

Pre-condition
  • 0 <= N <= sizeof...(xs)

take_back_max<N, C = listify>

Implementation
take_back_max_c<N::value, C>

take_back_max_c<unsigned N, C = listify>::f<xs...>

Return: sequence

Extracts at most N elements from the end of a sequence.

Pre-condition
  • 0 <= N

emp::take_back<L, N, C = mp::listify> = emp::unpack<L, mp::take_back<N, C>>

emp::take_back_c<L, int_t n, C = mp::listify> = emp::unpack<L, mp::take_back_c<n, C>>

emp::take_back_max<L, N, C = mp::listify> = emp::unpack<L, mp::take_back_max<N, C>>

emp::take_back_max_c<L, int_t n, C = mp::listify> = emp::unpack<L, mp::take_back_max_c<n, C>>

<jln/mp/list/take_front.hpp>

Test file: test/src/list/take_front.cpp

take_front<N, C = listify>

Implementation
take_front_c<N::value, C>

take_front_c<unsigned N, C = listify>::f<xs...>

Return: sequence

Extracts N elements from the beginning of a sequence.

Pre-condition
  • 0 <= N <= sizeof...(xs)

take_front_max<N, C = listify>

Implementation
take_front_max_c<N::value, C>

take_front_max_c<unsigned N, C = listify>::f<xs...>

Return: sequence

Extracts at most N elements from the beginning of a sequence.

Implementation
conditional_c<sizeof...(xs) <= N> ::f<C, take_front_c<N, C>> ::f<xs...>
Pre-condition
  • 0 <= N

emp::take_front<L, N, C = mp::listify> = emp::unpack<L, mp::take_front<N, C>>

emp::take_front_c<L, int_t n, C = mp::listify> = emp::unpack<L, mp::take_front_c<n, C>>

emp::take_front_max<L, N, C = mp::listify> = emp::unpack<L, mp::take_front_max<N, C>>

emp::take_front_max_c<L, int_t n, C = mp::listify> = emp::unpack<L, mp::take_front_max_c<n, C>>

<jln/mp/list/wrap_in_list.hpp>

Test file: test/src/list/wrap_in_list.cpp

wrap_in_list<b>

Implementation
wrap_in_list_c<b::value>

wrap_in_list_c<true>::f<xs...>

Implementation
list<xs...>

wrap_in_list_c<false>::f<xs...>

Implementation
list<>

wrap_in_list_c<bool b>

wrap_in_list_if<Pred>

Return: list

Returns a list with the first element if the predicate is checked, otherwise returns a empty list.

Pre-condition
  • Pred<xs...>::value must be narrowing convertible to bool

wrap_in_list_if_not<Pred>

Return: list

Returns a list with the first element if the predicate is not checked, otherwise returns a empty list.

Pre-condition
  • Pred<xs...>::value must be narrowing convertible to bool

emp::wrap_in_list<b, xs...> = mp::wrap_in_list_c<b::value>::f<xs...>

emp::wrap_in_list_c<bool b, xs...> = mp::wrap_in_list_c<b>::f<xs...>

emp::wrap_in_list_if<Pred, xs...> = mp::wrap_in_list_if<Pred>::f<xs...>

emp::wrap_in_list_if_not<Pred, xs...> = mp::wrap_in_list_if_not<Pred>::f<xs...>

Group: map

<jln/mp/map/is_map.hpp>

Test file: test/src/map/is_map.cpp

is_map<C = identity>

Return: true_ / false_

Checks whether xs is a map.

A map is a sequence of lists having at least one element (the key). The keys of the map must be unique.

emp::is_map<L, C = mp::identity> = emp::unpack<L, mp::is_map<C>>

bool emp::is_map_v<L, C = mp::identity> = emp::unpack<L, mp::is_map<C>>::value

emp::is_map_xs<kvs...> = mp::is_map<>::f<kvs...>

bool emp::is_map_xs_v<kvs...> = mp::is_map<>::f<kvs...>::value

<jln/mp/map/map_contains.hpp>

Test file: test/src/map/map_contains.cpp

map_contains<key, C = identity>

Return: true_ / false_

Checks if a key exists in a map.

Implementation
map_find<key, always<true_, C>, always<false_, C>>
Pre-condition

map_not_contains<key, C = identity>

Return: true_ / false_

Checks if a key does not exists in a map.

Implementation
map_find<key, always<false_, C>, always<true_, C>>
Pre-condition

emp::map_contains<L, key, C = mp::identity> = emp::unpack<L, mp::map_contains<key, C>>

bool emp::map_contains_v<L, key, C = mp::identity> = emp::unpack<L, mp::map_contains<key, C>>::value

emp::map_contains_xs<key, kvs...> = mp::map_contains<key>::f<kvs...>

bool emp::map_contains_xs_v<key, kvs...> = mp::map_contains<key>::f<kvs...>::value

emp::map_not_contains<L, key, C = mp::identity> = emp::unpack<L, mp::map_not_contains<key, C>>

bool emp::map_not_contains_v<L, key, C = mp::identity> = emp::unpack<L, mp::map_not_contains<key, C>>::value

emp::map_not_contains_xs<key, kvs...> = mp::map_not_contains<key>::f<kvs...>

bool emp::map_not_contains_xs_v<key, kvs...> = !mp::map_contains<key>::f<kvs...>::value

<jln/mp/map/map_erase.hpp>

Test file: test/src/map/map_erase.cpp

map_erase<Key, C = listify>

Return: map

If the map contains an element with a key Key, removes it.

Implementation
transform<map_find<Key, always<list<>>, listify>, join<C>>
Pre-condition

emp::map_erase<L, Key, C = mp::listify> = emp::unpack<L, mp::map_erase<Key, C>>

<jln/mp/map/map_find.hpp>

Test file: test/src/map/map_find.cpp

map_find<key, TC = identity, FC = always<na>>::f<kvs...>

Return: sequence

Finds the element of the map with a key key.

Calls TC with element found. If no element is found, FC is used with the whole map.

Pre-condition

map_find_or<key, FT>

Implementation
map_find<key, identity, always<FT>>

map_find_or_else<key, FC>

Implementation
map_find<key, identity, FC>

map_find_value<key, TC = identity, FC = always<na>>

Finds the first value of the map with a key key.

Implementation
map_find<key, unpack<at1<TC>>, FC>

map_find_value_or<key, FT>

Implementation
map_find<key, unpack<at1<>>, always<FT>>

map_find_value_or_else<key, FC>

Implementation
map_find<key, unpack<at1<>>, FC>

map_find_values<key, TC = listify, FC = always<na>>

Finds the values of the map with a key key.

Implementation
map_find<key, unpack<pop_front<TC>>, FC>

map_find_values_or<key, FT>

Implementation
map_find<key, unpack<pop_front<listify>>, always<FT>>

map_find_values_or_else<key, FC>

Implementation
map_find<key, unpack<pop_front<listify>>, FC>

emp::map_find<L, key, TC = mp::identity, FC = mp::always<na>> = emp::unpack<L, mp::map_find<key, TC, FC>>

emp::map_find_or<L, key, FT> = emp::unpack<L, mp::map_find< key, mp::identity, mp::always<FT>>>

emp::map_find_or_else<L, key, FC> = emp::unpack<L, mp::map_find< key, mp::identity, FC>>

emp::map_find_value<L, key, TC = mp::identity, FC = mp::always<na>> = emp::unpack<L, mp::map_find< key, mp::unpack<mp::at1<TC>>, FC>>

emp::map_find_value_or<L, key, FT> = emp::unpack<L, mp::map_find< key, mp::unpack<mp::at1<>>, mp::always<FT>>>

emp::map_find_value_or_else<L, key, FC> = emp::unpack<L, mp::map_find< key, mp::unpack<mp::at1<>>, FC>>

emp::map_find_values<L, key, TC = mp::listify, FC = mp::always<na>> = emp::unpack<L, mp::map_find< key, mp::unpack<mp::pop_front<TC>>, FC>>

emp::map_find_values_or<L, key, FT> = emp::unpack<L, mp::map_find< key, mp::unpack<mp::pop_front<>>, mp::always<FT>>>

emp::map_find_values_or_else<L, key, FC> = emp::unpack<L, mp::map_find< key, mp::unpack<mp::pop_front<>>, FC>>

<jln/mp/map/map_insert.hpp>

Test file: test/src/map/map_insert.cpp

map_insert<kv, C = listify>

Return: map

Inserts the element kv into the map, if the key emp::front<kv> does not exist.

Implementation
if_<map_contains<unpack<front<>>::f<kv>>, C, push_back<kv, C>>
Pre-condition

map_insert_s<k, v, C = listify>

Return: map

Inserts the element list<k,v> into the map, if the key k does not exist.

Implementation
if_<map_contains<k>, C, push_back<list<k, v>, C>>
Pre-condition

emp::map_insert<L, kv, C = mp::listify> = emp::unpack<L, mp::map_insert<kv, C>>

emp::map_insert_s<L, k, v, C = mp::listify> = emp::unpack<L, mp::map_insert_s<k, v, C>>

<jln/mp/map/map_keys.hpp>

Test file: test/src/map/map_keys.cpp

map_keys<C = listify>

Return: sequence

Returns a list of the keys of map.

When is a valid map, the keys are unique, so the result is a set.

Implementation
transform<unpack<front<>>, C>

map_keys_with<F = mp::identity, C = listify>

Return: sequence

Returns a list of the keys of map transformed with F.

When is a valid map, the keys are unique.

Implementation
transform<unpack<front<F>>, C>

emp::map_keys<L, C = mp::listify> = emp::unpack<L, mp::map_keys<C>>

emp::map_keys_with<L, F = mp::identity, C = mp::listify> = emp::unpack<L, mp::map_keys_with<F, C>>

<jln/mp/map/map_replace.hpp>

Test file: test/src/map/map_replace.cpp

map_replace<KV, C = listify>

Return: map

If the map contain the key emp::front<KV>, replaces the existing element with KV.

Implementation
map_update<unpack<front<>>::f<KV>, always<KV>, C>
Pre-condition

map_replace_or_insert<KV, C = listify>

Return: map

If the map contain the key emp::front<KV>, replaces the existing element with KV; otherwise, inserts it using push_back<KV>.

Implementation
map_update_or_insert<KV, always<KV>, C>
Pre-condition

emp::map_replace<L, KV, C = mp::listify> = emp::unpack<L, mp::map_replace<KV, C>>

emp::map_replace_or_insert<L, KV, C = mp::listify> = emp::unpack<L, mp::map_replace_or_insert<KV, C>>

<jln/mp/map/map_update.hpp>

Test file: test/src/map/map_update.cpp

map_element_key_update<F>::f<kv>

Update an element L<k, v...> with L<F<k, v...>, v...>.

Pre-condition

map_element_value_update<F>::f<kv>

Update an element L<k, v...> with L<k, F<k, v...>>.

Pre-condition

map_key_update<key, F, C = listify>

Return: sequence

If the map contain the key key, replaces the existing element L<key, v...> with L<F<key, v...>, v...>.

Implementation
map_update<key, map_element_key_update<F>, C>
Pre-condition

map_update<key, F, C = listify>

Return: sequence

If the map contain the key key, replaces the existing element L<key, v...> with F<L<key, v...>>.

Implementation
transform<map_find<key, F, front<>>, C>
Pre-condition

map_update_or_insert<kv, F, C = listify>

Return: sequence

If the map contain a key emp::front<kv>, replaces the existing element L<k, v...> with F<L<k, v...>>; otherwise, inserts it using push_back<kv>.

Implementation
if_< map_contains<unpack<front<>>::f<kv>>, map_update<unpack<front<>>::f<kv>, F, C>, push_back<kv, C>>
Pre-condition

map_update_s_or_insert<k, v, F, C = listify>

Return: sequence

If the map contain a key k, replaces the existing element L<k, v...> with F<list<k, v...>>; otherwise, inserts it using push_back<list<k,v>>.

Implementation
if_< map_contains<k>, map_update<k, F, C>, push_back<list<k, v>, C>>
Pre-condition

map_value_update<key, F, C = listify>

Return: map

If the map contain the key key, replaces the existing element L<key, v...> with L<key, F<key, v...>>.

Implementation
map_update<key, map_element_value_update<F>, C>
Pre-condition

map_value_update_or_insert<kv, F, C = listify>

Return: map

If the map contain a key emp::front<kv>, replaces the existing element L<k, v...> with L<k, F<k, v...>>; otherwise, inserts it using push_back<kv>.

Pre-condition

map_value_update_s_or_insert<k, v, F, C = listify>

Return: map

If the map contain a key k, replaces the existing element L<k, v...> with L<k, F<k, v...>>; otherwise, inserts it using push_back<list<k,v>>.

Pre-condition

emp::map_element_key_update<kv, F> = /*...*/

emp::map_element_value_update<kv, F> = /*...*/

emp::map_key_update<L, key, F, C = listify> = emp::unpack<L, mp::map_key_update<key, F, C>>

emp::map_update<L, key, F, C = listify> = emp::unpack<L, mp::map_update<key, F, C>>

emp::map_update_or_insert<L, kv, F, C = listify> = emp::unpack<L, mp::map_update_or_insert<kv, F, C>>

emp::map_update_s_or_insert<L, k, v, F, C = listify> = emp::unpack<L, mp::map_update_s_or_insert<k, v, F, C>>

emp::map_value_update<L, key, F, C = listify> = emp::unpack<L, mp::map_value_update<key, F, C>>

emp::map_value_update_or_insert<L, kv, F, C = listify> = emp::unpack<L, mp::map_value_update_or_insert<kv, F, C>>

emp::map_value_update_s_or_insert<L, k, v, F, C = listify> = emp::unpack<L, mp::map_value_update_s_or_insert<k, v, F, C>>

Group: number

<jln/mp/number/as_bool.hpp>

Test file: test/src/number/as_bool.cpp

as_bool<C = identity>::f<x>

Return: true_ / false_

Convertion without narrowing from value to true_ / false_.

Implementation
C::f<number<bool{x::value}>>

emp::as_bool<x> = number<bool{x::value}>

<jln/mp/number/as_number.hpp>

Test file: test/src/number/as_number.cpp

as_number<C = identity>::f<x>

Return: number

Convertion without narrowing from value to number.

Implementation
C::f<number<int_t{x::value}>>

emp::as_number<x> = number<int_t{x::value}>

<jln/mp/list/indices.hpp>

Test file: test/src/list/indices.cpp

indices<C = listify>

Return: sequence

Replaces each element of a sequence by its corresponding index.

Implementation
size<make_int_sequence<C>>

emp::indices<L, C = mp::listify> = emp::unpack<L, mp::indices<C>>

<jln/mp/number/number.hpp>

Test file: test/src/number/number.cpp

false_

Implementation
number<0>

int_t

Implementation
std::intmax_t

number<int_t v>::value

Implementation
v

true_

Implementation
number<1>

uint_t

Implementation
std::uintmax_t

<jln/mp/algorithm/iota.hpp>

Test file: test/src/algorithm/iota.cpp

iota<C = listify>

Return: sequence of number

Generates a sequence of number.

Implementation
iota_v<numbers<C>>

iota_v<C = numbers<>>::f<start, count, stride = number<1>>

Return: sequence of int_t

Generates a sequence of int_t.

emp::iota<start, count, stride = number<1>, C = mp::listify> = /*...*/

emp::iota_c<int_t start, int_t count, int_t stride = 1, C = mp::listify> = /*...*/

emp::iota_v<start, count, stride = number<1>, C = mp::numbers<>> = /*...*/

emp::iota_v_c<int_t start, int_t count, int_t stride = 1, C = mp::numbers<>> = /*...*/

<jln/mp/number/is_number.hpp>

Test file: test/src/number/is_number.cpp

is_number<C = identity>::f<x>

Return: true_ / false_

Checks whether a value is a number.

Implementation
C::f<number<emp::is_number_v<x>>>

emp::is_number<x> = number<emp::is_number_v<x>>

bool emp::is_number_v<x> = false

<jln/mp/algorithm/make_int_sequence.hpp>

Test file: test/src/algorithm/make_int_sequence.cpp

int_seq_c<int_t... i>

single list of int_t.

make_int_sequence<C = mp::listify>

Implementation
make_int_sequence_v<mp::numbers<C>>

make_int_sequence_v<C = numbers<>>::f<n>

Return: sequence

Generates an incremental sequence of n int_t.

#define JLN_MP_D_MAKE_INDEX_SEQUENCE(n, /*tpl_class*/...)

Template-dependent version of JLN_MP_MAKE_INDEX_SEQUENCE ; add typename when needed.

// typename impl<...>::template f<T, 0, 1, 2> ->
JLN_MP_MAKE_INDEX_SEQUENCE(n, impl<...>::template f)

#define JLN_MP_D_MAKE_INTEGER_SEQUENCE(n, /*tpl_class*/...)

Template-dependent version of JLN_MP_MAKE_INTEGER_SEQUENCE ; add typename when needed.

// typename impl<...>::template f<T, 0, 1, 2> ->
JLN_MP_D_MAKE_INTEGER_SEQUENCE(n, impl<...>::template f)

#define JLN_MP_D_MAKE_INTEGER_SEQUENCE_T(T, n, /*tpl_class*/...)

Template-dependent version of JLN_MP_MAKE_INTEGER_SEQUENCE_T ; add typename when needed.

// typename impl<...>::template f<T, 0, 1, 2> ->
JLN_MP_D_MAKE_INTEGER_SEQUENCE_T(T, n, impl<...>::template f)

#define JLN_MP_D_MAKE_UNSIGNED_SEQUENCE(n, /*tpl_class*/...)

Template-dependent version of JLN_MP_MAKE_UNSIGNED_SEQUENCE ; add typename when needed.

// typename impl<...>::template f<T, 0, 1, 2> ->
JLN_MP_D_MAKE_UNSIGNED_SEQUENCE(n, impl<...>::template f)

#define JLN_MP_MAKE_INDEX_SEQUENCE(n, /*tpl_class*/...)

Fast initialization of template of the shape tpl_class<class T, std::size_t... ints>.

Pre-condition
  • n should be a template parameter.

#define JLN_MP_MAKE_INTEGER_SEQUENCE(n, /*tpl_class*/...)

Fast initialization of template of the shape tpl_class<class T, int_t... ints>.

Pre-condition
  • n should be a template parameter.

#define JLN_MP_MAKE_INTEGER_SEQUENCE_T(T, n, /*tpl_class*/...)

Fast initialization of template of the shape tpl_class<class T, T... ints>.

template<class, int...>
struct ints { ... };

template<class n>
using make_ints = JLN_MP_MAKE_INTEGER_SEQUENCE_T(int, n::value, ints);
Pre-condition
  • n should be a template parameter.

#define JLN_MP_MAKE_UNSIGNED_SEQUENCE(n, /*tpl_class*/...)

Fast initialization of template of the shape tpl_class<class T, unsigned... ints>.

Pre-condition
  • n should be a template parameter.

emp::make_int_sequence<n, C = mp::listify> = /*...*/

emp::make_int_sequence_c<unsigned n, C = mp::listify> = /*...*/

emp::make_int_sequence_v<n, C = mp::numbers<>> = /*...*/

emp::make_int_sequence_v_c<unsigned n, C = mp::numbers<>> = /*...*/

<jln/mp/number/math.hpp>

Test file: test/src/number/math.cpp

abs<C = identity>::f<x>

clamp<Min, Max, C = identity>

Implementation
clamp_with<Min, Max, less<>, C>

clamp_c<int_t min, int_t max, C = identity>

Implementation
clamp_with<number<min>, number<max>, less<>, C>

clamp_with<Min, Max, Cmp = less<>, C = identity>::f<x>

Implementation
C::f<mp::conditional_c<Cmp::f<x, Min>::value>::f<Min, mp::conditional_c<Cmp::f<Max, x>::value>::f<Max, x>>>

clamp_with_c<int_t min, int_t max, Cmp = less<>, C = identity>

Implementation
clamp_with<number<min>, number<max>, Cmp, C>

max<C = identity>

Implementation
reverse_select<less<>, C>

min<C = identity>

Implementation
reverse_select_flip<less<>, C>

pow<C = identity>::f<base, exponent>

emp::abs<I, C = mp::identity> = mp::abs<C>::f<I>

emp::abs_c<int_t i, C = mp::identity> = C::f<number<abs_c_v<i>>>

auto emp::abs_c_v<int_t i, C = mp::identity> = C ::f<number<abs_c_v<i>>>::value

auto emp::abs_v<I, C = mp::identity> = mp::abs<C>::f<I>::value

emp::clamp<I, Min, Max, C = mp::identity> = mp::clamp_with<Min, Max, mp::less<>, C>::f<I>

emp::clamp_c<int_t i, int_t min, int_t max, C = mp::identity> = C::f<number<(i < min ? min : max < i ? max : i)>>

auto emp::clamp_c_v<int_t i, int_t min, int_t max, C = mp::identity> = C ::f<number<i < min ? min : max < i ? max : i>>::value

auto emp::clamp_v<I, Min, Max, C = mp::identity> = mp::clamp_with<Min, Max, mp::less<>, C> ::f<I>::value

emp::clamp_with<I, Min, Max, Cmp = mp::less<>, C = mp::identity> = mp::clamp_with<Min, Max, Cmp, C>::f<I>

emp::clamp_with_c<int_t i, int_t min, int_t max, Cmp = mp::less<>, C = mp::identity> = mp::clamp_with_c<min, max, Cmp, C>::f<number<i>>

auto emp::clamp_with_c_v<int_t i, int_t min, int_t max, Cmp = mp::less<>, C = mp::identity> = C ::f<number<clamp_with_c_v<i, min, max, Cmp>>>::value

auto emp::clamp_with_v<I, Min, Max, Cmp = mp::less<>, C = mp::identity> = mp::clamp_with<Min, Max, Cmp, C> ::f<I>::value

emp::max<x, y, C = mp::identity> = mp::reverse_select<mp::less<>, C>::f<x, y>

emp::max_c<int_t x, int_t y, C = mp::identity> = C::f<number<x < y ? y : x>>

auto emp::max_c_v<int_t x, int_t y, C = mp::identity> = C ::f<number<x < y ? y : x>>::value

auto emp::max_v<x, y, C = mp::identity> = C::f< mp::conditional_c<x::value < y::value>::f<y, x>>::value

emp::min<x, y, C = mp::identity> = mp::select<mp::less<>, C>::f<x, y>

emp::min_c<int_t x, int_t y, C = mp::identity> = C::f<number<y < x ? y : x>>

auto emp::min_c_v<int_t x, int_t y, C = mp::identity> = C ::f<number<y < x ? y : x>>::value

auto emp::min_v<x, y, C = mp::identity> = C::f< mp::conditional_c<y::value < x::value>::f<y, x>>::value

emp::pow<Base, Exponent, C = mp::identity> = mp::pow<C>::f<Base, Exponent>

emp::pow_c<int_t base, int_t exponent, C = mp::identity> = /*...*/

int_t emp::pow_c_v<int_t base, int_t exponent, C = mp::identity> = /*...*/

int_t emp::pow_v<Base, Exponent, C = mp::identity> = /*...*/

<jln/mp/number/not.hpp>

Test file: test/src/number/not.cpp

not_<C = identity>::f<x>

Implementation
C::f<number<!x::value>>

not_<not_<C>>::f<x>

Implementation
C::f<number<bool(x::value)>>

emp::not_<x, C = mp::identity> = mp::not_<C>::f<x>

bool emp::not_v<x, C = mp::identity> = mp::not_<C>::f<x>::value

<jln/mp/number/numbers.hpp>

Test file: test/src/number/numbers.cpp

numbers<C = listify>::f<int_t... ns>

Implementation
C::f<number<ns>...>

emp::numbers<int_t... vs> = list<number<vs>...>

<jln/mp/number/operators.hpp>

Test file: test/src/number/operators.cpp

add<C = identity>::f<xs...>

Implementation
C::f<number<(xs::value + ...)>>

add0<C = identity>

Implementation
if_<size<>, add<C>, always<number<0>, C>>

and_<C = identity>::f<xs...>

Implementation
C::f<number<(xs::value && ... && true)>>

bit_and<C = identity>::f<xs...>

Implementation
C::f<number<(xs::value & ...)>>

bit_and0<C = identity>

Implementation
if_<size<>, bit_and<C>, always<number<0>, C>>

bit_not<C = identity>::f<x>

Implementation
C::f<number<(~x::value)>>

bit_or<C = identity>::f<xs...>

Implementation
C::f<number<(xs::value | ...)>>

bit_or0<C = identity>

Implementation
if_<size<>, bit_or<C>, always<number<0>, C>>

dec<C = identity>::f<x>

Implementation
C::f<number<(x::value-1)>>

div<C = identity>::f<xs...>

Implementation
C::f<number<(... / xs::value)>>

div0<C = identity>

Implementation
if_<size<>, div<C>, always<number<0>, C>>

div1<C = identity>

Implementation
if_<size<>, div<C>, always<number<1>, C>>

equal<C = identity>::f<x, y>

Implementation
C::f<number<(x::value == y::value)>>

equal_to<N, C = identity>

Implementation
push_front<N, equal<C>>

equal_to_c<int_t n, C = identity>

Implementation
equal_to<number<n>, C>

greater<C = identity>::f<x, y>

Implementation
C::f<number<(x::value> y::value)>>

greater_equal<C = identity>::f<x, y>

Implementation
C::f<number<(x::value>= y::value)>>

greater_equal_than<N, C = identity>

Implementation
push_back<N, greater_equal<C>>

greater_equal_than_c<int_t n, C = identity>

Implementation
greater_equal_than<number<n>, C>

greater_than<N, C = identity>

Implementation
push_back<N, greater<C>>

greater_than_c<int_t n, C = identity>

Implementation
greater_than<number<n>, C>

inc<C = identity>::f<x>

Implementation
C::f<number<(x::value+1)>>

left_add<C = identity>::f<xs...>

Implementation
C::f<number<(... + xs::value)>>

left_add0<C = identity>

Implementation
if_<size<>, left_add<C>, always<number<0>, C>>

left_and<C = identity>::f<xs...>

Implementation
C::f<number<(true && ... && xs::value)>>

left_bit_and<C = identity>::f<xs...>

Implementation
C::f<number<(... & xs::value)>>

left_bit_and0<C = identity>

Implementation
if_<size<>, left_bit_and<C>, always<number<0>, C>>

left_bit_or<C = identity>::f<xs...>

Implementation
C::f<number<(... | xs::value)>>

left_bit_or0<C = identity>

Implementation
if_<size<>, left_bit_or<C>, always<number<0>, C>>

left_mul<C = identity>::f<xs...>

Implementation
C::f<number<(... * xs::value)>>

left_mul0<C = identity>

Implementation
if_<size<>, left_mul<C>, always<number<0>, C>>

left_mul1<C = identity>

Implementation
if_<size<>, left_mul<C>, always<number<1>, C>>

left_or<C = identity>::f<xs...>

Implementation
C::f<number<(false || ... || xs::value)>>

left_xor<C = identity>::f<xs...>

Implementation
C::f<number<(... ^ xs::value)>>

left_xor0<C = identity>

Implementation
if_<size<>, left_xor<C>, always<number<0>, C>>

less<C = identity>::f<x, y>

Implementation
C::f<number<(x::value < y::value)>>

less_equal<C = identity>::f<x, y>

Implementation
C::f<number<(x::value <= y::value)>>

less_equal_than<N, C = identity>

Implementation
push_back<N, less_equal<C>>

less_equal_than_c<int_t n, C = identity>

Implementation
less_equal_than<number<n>, C>

less_than<N, C = identity>

Implementation
push_back<N, less<C>>

less_than_c<int_t n, C = identity>

Implementation
less_than<number<n>, C>

lshift<C = identity>::f<xs...>

Implementation
C::f<number<(... << xs::value)>>

lshift0<C = identity>

Implementation
if_<size<>, lshift<C>, always<number<0>, C>>

mod<C = identity>::f<xs...>

Implementation
C::f<number<(... % xs::value)>>

mod0<C = identity>

Implementation
if_<size<>, mod<C>, always<number<0>, C>>

mod1<C = identity>

Implementation
if_<size<>, mod<C>, always<number<1>, C>>

mul<C = identity>::f<xs...>

Implementation
C::f<number<(xs::value * ...)>>

mul0<C = identity>

Implementation
if_<size<>, mul<C>, always<number<0>, C>>

mul1<C = identity>

Implementation
if_<size<>, mul<C>, always<number<1>, C>>

neg<C = identity>::f<x>

Implementation
C::f<number<(-x::value)>>

not_equal<C = identity>::f<x, y>

Implementation
C::f<number<(x::value != y::value)>>

not_equal_to<N, C = identity>

Implementation
push_front<N, not_equal<C>>

not_equal_to_c<int_t n, C = identity>

Implementation
not_equal_to<number<n>, C>

or_<C = identity>::f<xs...>

Implementation
C::f<number<(xs::value || ... || false)>>

rshift<C = identity>::f<xs...>

Implementation
C::f<number<(...>> xs::value)>>

rshift0<C = identity>

Implementation
if_<size<>, rshift<C>, always<number<0>, C>>

sub<C = identity>::f<xs...>

Implementation
C::f<number<(... - xs::value)>>

sub0<C = identity>

Implementation
if_<size<>, sub<C>, always<number<0>, C>>

unary_plus<C = identity>::f<x>

Implementation
C::f<number<(+x::value)>>

xor0<C = identity>

Implementation
if_<size<>, xor_<C>, always<number<0>, C>>

xor_<C = identity>::f<xs...>

Implementation
C::f<number<(xs::value ^ ...)>>

emp::add<xs...> = number<(xs::value + ...)>

emp::add0<xs...> = mp::add0<>::f<xs...>

emp::add0_c<int_t... xs> = add_c<xs..., 0>

int_t emp::add0_c_v<int_t... xs> = add_c_v<xs..., 0>

emp::add0_seq<L, C = mp::identity> = emp::unpack<L, mp::add0<C>>

int_t emp::add0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::add0<C>>::value

int_t emp::add0_v<xs...> = mp::add0<>::f<xs...>::value

emp::add_c<int_t... xs> = number<(xs + ...)>

int_t emp::add_c_v<int_t... xs> = (xs + ...)

emp::add_seq<L, C = mp::identity> = emp::unpack<L, mp::add<C>>

int_t emp::add_seq_v<L, C = mp::identity> = emp::unpack<L, mp::add<C>>::value

int_t emp::add_v<xs...> = (xs::value + ...)

emp::and_<xs...> = number<(xs::value && ... && true)>

emp::and_c<int_t... xs> = number<(xs && ... && true)>

int_t emp::and_c_v<int_t... xs> = (xs && ... && true)

emp::and_left_seq<L, C = mp::identity> = emp::unpack<L, mp::left_and<C>>

int_t emp::and_left_seq_v<L, C = mp::identity> = emp::unpack<L, mp::left_and<C>>::value

emp::and_seq<L, C = mp::identity> = emp::unpack<L, mp::and_<C>>

int_t emp::and_seq_v<L, C = mp::identity> = emp::unpack<L, mp::and_<C>>::value

int_t emp::and_v<xs...> = (xs::value && ... && true)

emp::bit_and<xs...> = number<(xs::value & ...)>

emp::bit_and0<xs...> = mp::bit_and0<>::f<xs...>

emp::bit_and0_c<int_t... xs> = bit_and_c<xs..., (sizeof...(xs) ? std::numeric_limits<int_t>::max() : 0)>

int_t emp::bit_and0_c_v<int_t... xs> = bit_and_c_v<xs..., sizeof...(xs) ? std::numeric_limits<int_t>::max() : 0>

emp::bit_and0_seq<L, C = mp::identity> = emp::unpack<L, mp::bit_and0<C>>

int_t emp::bit_and0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::bit_and0<C>>::value

int_t emp::bit_and0_v<xs...> = mp::bit_and0<>::f<xs...>::value

emp::bit_and_c<int_t... xs> = number<(xs & ...)>

int_t emp::bit_and_c_v<int_t... xs> = (xs & ...)

emp::bit_and_seq<L, C = mp::identity> = emp::unpack<L, mp::bit_and<C>>

int_t emp::bit_and_seq_v<L, C = mp::identity> = emp::unpack<L, mp::bit_and<C>>::value

int_t emp::bit_and_v<xs...> = (xs::value & ...)

emp::bit_not<x, C = mp::identity> = mp::bit_not<C>::f<x>

int_t emp::bit_not_v<x, C = mp::identity> = mp::bit_not<C>::f<x>

emp::bit_or<xs...> = number<(xs::value | ...)>

emp::bit_or0<xs...> = mp::bit_or0<>::f<xs...>

emp::bit_or0_c<int_t... xs> = bit_or_c<xs..., (sizeof...(xs) ? std::numeric_limits<int_t>::max() : 0)>

int_t emp::bit_or0_c_v<int_t... xs> = bit_or_c_v<xs..., sizeof...(xs) ? std::numeric_limits<int_t>::max() : 0>

emp::bit_or0_seq<L, C = mp::identity> = emp::unpack<L, mp::bit_or0<C>>

int_t emp::bit_or0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::bit_or0<C>>::value

int_t emp::bit_or0_v<xs...> = mp::bit_or0<>::f<xs...>::value

emp::bit_or_c<int_t... xs> = number<(xs | ...)>

int_t emp::bit_or_c_v<int_t... xs> = (xs | ...)

emp::bit_or_seq<L, C = mp::identity> = emp::unpack<L, mp::bit_or<C>>

int_t emp::bit_or_seq_v<L, C = mp::identity> = emp::unpack<L, mp::bit_or<C>>::value

int_t emp::bit_or_v<xs...> = (xs::value | ...)

emp::dec<x, C = mp::identity> = mp::dec<C>::f<x>

int_t emp::dec_v<x, C = mp::identity> = mp::dec<C>::f<x>

emp::div<xs...> = number<(... / xs::value)>

emp::div0<xs...> = mp::div0<>::f<xs...>

emp::div0_c<int_t... xs> = div_c<xs..., (sizeof...(xs) ? 1 : 0)>

int_t emp::div0_c_v<int_t... xs> = div_c_v<xs..., sizeof...(xs) ? 1 : 0>

emp::div0_seq<L, C = mp::identity> = emp::unpack<L, mp::div0<C>>

int_t emp::div0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::div0<C>>::value

int_t emp::div0_v<xs...> = mp::div0<>::f<xs...>::value

emp::div1<xs...> = mp::div1<>::f<xs...>

emp::div1_c<int_t... xs> = div_c<xs..., 1>

int_t emp::div1_c_v<int_t... xs> = div_c_v<xs..., 1>

emp::div1_seq<L, C = mp::identity> = emp::unpack<L, mp::div1<C>>

int_t emp::div1_seq_v<L, C = mp::identity> = emp::unpack<L, mp::div1<C>>::value

int_t emp::div1_v<xs...> = mp::div1<>::f<xs...>::value

emp::div_c<int_t... xs> = number<(... / xs)>

int_t emp::div_c_v<int_t... xs> = (... / xs)

emp::div_seq<L, C = mp::identity> = emp::unpack<L, mp::div<C>>

int_t emp::div_seq_v<L, C = mp::identity> = emp::unpack<L, mp::div<C>>::value

int_t emp::div_v<xs...> = (... / xs::value)

emp::equal<x, y, C = mp::identity> = mp::equal<C>::f<x, y>

int_t emp::equal_v<x, y, C = mp::identity> = mp::equal<C>::f<x, y>

emp::greater<x, y, C = mp::identity> = mp::greater<C>::f<x, y>

emp::greater_equal<x, y, C = mp::identity> = mp::greater_equal<C>::f<x, y>

int_t emp::greater_equal_v<x, y, C = mp::identity> = mp::greater_equal<C>::f<x, y>

int_t emp::greater_v<x, y, C = mp::identity> = mp::greater<C>::f<x, y::value>

emp::inc<x, C = mp::identity> = mp::inc<C>::f<x>

int_t emp::inc_v<x, C = mp::identity> = mp::inc<C>::f<x>

emp::left_add<xs...> = number<(... + xs::value)>

emp::left_add0<xs...> = mp::add0<>::f<xs...>

emp::left_add0_c<int_t... xs> = left_add_c<xs..., 0>

int_t emp::left_add0_c_v<int_t... xs> = left_add_c_v<xs..., 0>

emp::left_add0_seq<L, C = mp::identity> = emp::unpack<L, mp::left_add0<C>>

int_t emp::left_add0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::left_add0<C>>::value

int_t emp::left_add0_v<xs...> = mp::add0<>::f<xs...>::value

emp::left_add_c<int_t... xs> = number<(... + xs)>

int_t emp::left_add_c_v<int_t... xs> = (... + xs)

emp::left_add_seq<L, C = mp::identity> = emp::unpack<L, mp::left_add<C>>

int_t emp::left_add_seq_v<L, C = mp::identity> = emp::unpack<L, mp::left_add<C>>::value

int_t emp::left_add_v<xs...> = (... + xs::value)

emp::left_and<xs...> = number<(true && ... && xs::value)>

emp::left_and_c<int_t... xs> = number<(true && ... && xs)>

int_t emp::left_and_c_v<int_t... xs> = (true && ... && xs)

int_t emp::left_and_v<xs...> = (true && ... && xs::value)

emp::left_bit_and<xs...> = number<(... & xs::value)>

emp::left_bit_and0<xs...> = mp::left_bit_and0<>::f<xs...>

emp::left_bit_and0_c<int_t... xs> = left_bit_and_c<xs..., (sizeof...(xs) ? std::numeric_limits<int_t>::max() : 0)>

int_t emp::left_bit_and0_c_v<int_t... xs> = left_bit_and_c_v<xs..., sizeof...(xs) ? std::numeric_limits<int_t>::max() : 0>

emp::left_bit_and0_seq<L, C = mp::identity> = emp::unpack<L, mp::left_bit_and0<C>>

int_t emp::left_bit_and0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::left_bit_and0<C>>::value

int_t emp::left_bit_and0_v<xs...> = mp::left_bit_and0<>::f<xs...>::value

emp::left_bit_and_c<int_t... xs> = number<(... & xs)>

int_t emp::left_bit_and_c_v<int_t... xs> = (... & xs)

emp::left_bit_and_seq<L, C = mp::identity> = emp::unpack<L, mp::left_bit_and<C>>

int_t emp::left_bit_and_seq_v<L, C = mp::identity> = emp::unpack<L, mp::left_bit_and<C>>::value

int_t emp::left_bit_and_v<xs...> = (... & xs::value)

emp::left_bit_or<xs...> = number<(... | xs::value)>

emp::left_bit_or0<xs...> = mp::left_bit_or0<>::f<xs...>

emp::left_bit_or0_c<int_t... xs> = left_bit_or_c<xs..., (sizeof...(xs) ? std::numeric_limits<int_t>::max() : 0)>

int_t emp::left_bit_or0_c_v<int_t... xs> = left_bit_or_c_v<xs..., sizeof...(xs) ? std::numeric_limits<int_t>::max() : 0>

emp::left_bit_or0_seq<L, C = mp::identity> = emp::unpack<L, mp::left_bit_or0<C>>

int_t emp::left_bit_or0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::left_bit_or0<C>>::value

int_t emp::left_bit_or0_v<xs...> = mp::left_bit_or0<>::f<xs...>::value

emp::left_bit_or_c<int_t... xs> = number<(... | xs)>

int_t emp::left_bit_or_c_v<int_t... xs> = (... | xs)

emp::left_bit_or_seq<L, C = mp::identity> = emp::unpack<L, mp::left_bit_or<C>>

int_t emp::left_bit_or_seq_v<L, C = mp::identity> = emp::unpack<L, mp::left_bit_or<C>>::value

int_t emp::left_bit_or_v<xs...> = (... | xs::value)

emp::left_mul<xs...> = number<(... * xs::value)>

emp::left_mul0<xs...> = mp::left_mul0<>::f<xs...>

emp::left_mul0_c<int_t... xs> = left_mul_c<xs..., (sizeof...(xs) ? 1 : 0)>

int_t emp::left_mul0_c_v<int_t... xs> = left_mul_c_v<xs..., sizeof...(xs) ? 1 : 0>

emp::left_mul0_seq<L, C = mp::identity> = emp::unpack<L, mp::left_mul0<C>>

int_t emp::left_mul0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::left_mul0<C>>::value

int_t emp::left_mul0_v<xs...> = mp::left_mul0<>::f<xs...>::value

emp::left_mul1<xs...> = mp::left_mul1<>::f<xs...>

emp::left_mul1_c<int_t... xs> = left_mul_c<xs..., 1>

int_t emp::left_mul1_c_v<int_t... xs> = left_mul_c_v<xs..., 1>

emp::left_mul1_seq<L, C = mp::identity> = emp::unpack<L, mp::left_mul1<C>>

int_t emp::left_mul1_seq_v<L, C = mp::identity> = emp::unpack<L, mp::left_mul1<C>>::value

int_t emp::left_mul1_v<xs...> = mp::left_mul1<>::f<xs...>::value

emp::left_mul_c<int_t... xs> = number<(... * xs)>

int_t emp::left_mul_c_v<int_t... xs> = (... * xs)

emp::left_mul_seq<L, C = mp::identity> = emp::unpack<L, mp::left_mul<C>>

int_t emp::left_mul_seq_v<L, C = mp::identity> = emp::unpack<L, mp::left_mul<C>>::value

int_t emp::left_mul_v<xs...> = (... * xs::value)

emp::left_or<xs...> = number<(false || ... || xs::value)>

emp::left_or_c<int_t... xs> = number<(false || ... || xs)>

int_t emp::left_or_c_v<int_t... xs> = (false || ... || xs)

int_t emp::left_or_v<xs...> = (false || ... || xs::value)

emp::left_xor<xs...> = number<(... ^ xs::value)>

emp::left_xor0<xs...> = mp::left_xor0<>::f<xs...>

emp::left_xor0_c<int_t... xs> = left_xor_c<xs..., 0, 0>

int_t emp::left_xor0_c_v<int_t... xs> = left_xor_c_v<xs..., 0, 0>

emp::left_xor0_seq<L, C = mp::identity> = emp::unpack<L, mp::left_xor0<C>>

int_t emp::left_xor0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::left_xor0<C>>::value

int_t emp::left_xor0_v<xs...> = mp::left_xor0<>::f<xs...>::value

emp::left_xor_c<int_t... xs> = number<(... ^ xs)>

int_t emp::left_xor_c_v<int_t... xs> = (... ^ xs)

emp::left_xor_seq<L, C = mp::identity> = emp::unpack<L, mp::left_xor<C>>

int_t emp::left_xor_seq_v<L, C = mp::identity> = emp::unpack<L, mp::left_xor<C>>::value

int_t emp::left_xor_v<xs...> = (... ^ xs::value)

emp::less<x, y, C = mp::identity> = mp::less<C>::f<x, y>

emp::less_equal<x, y, C = mp::identity> = mp::less_equal<C>::f<x, y>

int_t emp::less_equal_v<x, y, C = mp::identity> = mp::less_equal<C>::f<x, y>

int_t emp::less_v<x, y, C = mp::identity> = mp::less<C>::f<x, y::value>

emp::lshift<xs...> = number<(... << xs::value)>

emp::lshift0<xs...> = mp::lshift0<>::f<xs...>

emp::lshift0_c<int_t... xs> = lshift_c<xs..., 0>

int_t emp::lshift0_c_v<int_t... xs> = lshift_c_v<xs..., 0>

emp::lshift0_seq<L, C = mp::identity> = emp::unpack<L, mp::lshift0<C>>

int_t emp::lshift0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::lshift0<C>>::value

int_t emp::lshift0_v<xs...> = mp::lshift0<>::f<xs...>::value

emp::lshift_c<int_t... xs> = number<(... << xs)>

int_t emp::lshift_c_v<int_t... xs> = (... << xs)

emp::lshift_seq<L, C = mp::identity> = emp::unpack<L, mp::lshift<C>>

int_t emp::lshift_seq_v<L, C = mp::identity> = emp::unpack<L, mp::lshift<C>>::value

int_t emp::lshift_v<xs...> = (... << xs::value)

emp::mod<xs...> = number<(... % xs::value)>

emp::mod0<xs...> = mp::mod0<>::f<xs...>

emp::mod0_c<int_t... xs> = mod_c<xs..., (sizeof...(xs) ? std::numeric_limits<int_t>::min() : 0)>

int_t emp::mod0_c_v<int_t... xs> = mod_c_v<xs..., sizeof...(xs) ? std::numeric_limits<int_t>::min() : 0>

emp::mod0_seq<L, C = mp::identity> = emp::unpack<L, mp::mod0<C>>

int_t emp::mod0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::mod0<C>>::value

int_t emp::mod0_v<xs...> = mp::mod0<>::f<xs...>::value

emp::mod1<xs...> = mp::mod1<>::f<xs...>

emp::mod1_c<int_t... xs> = mod_c<xs..., (sizeof...(xs) ? std::numeric_limits<int_t>::min() : 1)>

int_t emp::mod1_c_v<int_t... xs> = mod_c_v<xs..., sizeof...(xs) ? std::numeric_limits<int_t>::min() : 1>

emp::mod1_seq<L, C = mp::identity> = emp::unpack<L, mp::mod1<C>>

int_t emp::mod1_seq_v<L, C = mp::identity> = emp::unpack<L, mp::mod1<C>>::value

int_t emp::mod1_v<xs...> = mp::mod1<>::f<xs...>::value

emp::mod_c<int_t... xs> = number<(... % xs)>

int_t emp::mod_c_v<int_t... xs> = (... % xs)

emp::mod_seq<L, C = mp::identity> = emp::unpack<L, mp::mod<C>>

int_t emp::mod_seq_v<L, C = mp::identity> = emp::unpack<L, mp::mod<C>>::value

int_t emp::mod_v<xs...> = (... % xs::value)

emp::mul<xs...> = number<(xs::value * ...)>

emp::mul0<xs...> = mp::mul0<>::f<xs...>

emp::mul0_c<int_t... xs> = mul_c<xs..., (sizeof...(xs) ? 1 : 0)>

int_t emp::mul0_c_v<int_t... xs> = mul_c_v<xs..., sizeof...(xs) ? 1 : 0>

emp::mul0_seq<L, C = mp::identity> = emp::unpack<L, mp::mul0<C>>

int_t emp::mul0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::mul0<C>>::value

int_t emp::mul0_v<xs...> = mp::mul0<>::f<xs...>::value

emp::mul1<xs...> = mp::mul1<>::f<xs...>

emp::mul1_c<int_t... xs> = mul_c<xs..., 1>

int_t emp::mul1_c_v<int_t... xs> = mul_c_v<xs..., 1>

emp::mul1_seq<L, C = mp::identity> = emp::unpack<L, mp::mul1<C>>

int_t emp::mul1_seq_v<L, C = mp::identity> = emp::unpack<L, mp::mul1<C>>::value

int_t emp::mul1_v<xs...> = mp::mul1<>::f<xs...>::value

emp::mul_c<int_t... xs> = number<(xs * ...)>

int_t emp::mul_c_v<int_t... xs> = (xs * ...)

emp::mul_seq<L, C = mp::identity> = emp::unpack<L, mp::mul<C>>

int_t emp::mul_seq_v<L, C = mp::identity> = emp::unpack<L, mp::mul<C>>::value

int_t emp::mul_v<xs...> = (xs::value * ...)

emp::neg<x, C = mp::identity> = mp::neg<C>::f<x>

int_t emp::neg_v<x, C = mp::identity> = mp::neg<C>::f<x>

emp::not_equal<x, y, C = mp::identity> = mp::not_equal<C>::f<x, y>

int_t emp::not_equal_v<x, y, C = mp::identity> = mp::not_equal<C>::f<x, y>

emp::or_<xs...> = number<(xs::value || ... || false)>

emp::or_c<int_t... xs> = number<(xs || ... || false)>

int_t emp::or_c_v<int_t... xs> = (xs || ... || false)

emp::or_left_seq<L, C = mp::identity> = emp::unpack<L, mp::left_or<C>>

int_t emp::or_left_seq_v<L, C = mp::identity> = emp::unpack<L, mp::left_or<C>>::value

emp::or_seq<L, C = mp::identity> = emp::unpack<L, mp::or_<C>>

int_t emp::or_seq_v<L, C = mp::identity> = emp::unpack<L, mp::or_<C>>::value

int_t emp::or_v<xs...> = (xs::value || ... || false)

emp::rshift<xs...> = number<(...>> xs::value)>

emp::rshift0<xs...> = mp::rshift0<>::f<xs...>

emp::rshift0_c<int_t... xs> = rshift_c<xs..., 0>

int_t emp::rshift0_c_v<int_t... xs> = rshift_c_v<xs..., 0>

emp::rshift0_seq<L, C = mp::identity> = emp::unpack<L, mp::rshift0<C>>

int_t emp::rshift0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::rshift0<C>>::value

int_t emp::rshift0_v<xs...> = mp::rshift0<>::f<xs...>::value

emp::rshift_c<int_t... xs> = number<(...>> xs)>

int_t emp::rshift_c_v<int_t... xs> = (...>> xs)

emp::rshift_seq<L, C = mp::identity> = emp::unpack<L, mp::rshift<C>>

int_t emp::rshift_seq_v<L, C = mp::identity> = emp::unpack<L, mp::rshift<C>>::value

int_t emp::rshift_v<xs...> = (...>> xs::value)

emp::sub<xs...> = number<(... - xs::value)>

emp::sub0<xs...> = mp::sub0<>::f<xs...>

emp::sub0_c<int_t... xs> = sub_c<xs..., 0>

int_t emp::sub0_c_v<int_t... xs> = sub_c_v<xs..., 0>

emp::sub0_seq<L, C = mp::identity> = emp::unpack<L, mp::sub0<C>>

int_t emp::sub0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::sub0<C>>::value

int_t emp::sub0_v<xs...> = mp::sub0<>::f<xs...>::value

emp::sub_c<int_t... xs> = number<(... - xs)>

int_t emp::sub_c_v<int_t... xs> = (... - xs)

emp::sub_seq<L, C = mp::identity> = emp::unpack<L, mp::sub<C>>

int_t emp::sub_seq_v<L, C = mp::identity> = emp::unpack<L, mp::sub<C>>::value

int_t emp::sub_v<xs...> = (... - xs::value)

emp::unary_plus<x, C = mp::identity> = mp::unary_plus<C>::f<x>

int_t emp::unary_plus_v<x, C = mp::identity> = mp::unary_plus<C>::f<x>

emp::xor0<xs...> = mp::xor0<>::f<xs...>

emp::xor0_c<int_t... xs> = xor_c<xs..., 0, 0>

int_t emp::xor0_c_v<int_t... xs> = xor_c_v<xs..., 0, 0>

emp::xor0_seq<L, C = mp::identity> = emp::unpack<L, mp::xor0<C>>

int_t emp::xor0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::xor0<C>>::value

int_t emp::xor0_v<xs...> = mp::xor0<>::f<xs...>::value

emp::xor_<xs...> = number<(xs::value ^ ...)>

emp::xor_c<int_t... xs> = number<(xs ^ ...)>

int_t emp::xor_c_v<int_t... xs> = (xs ^ ...)

emp::xor_seq<L, C = mp::identity> = emp::unpack<L, mp::xor_<C>>

int_t emp::xor_seq_v<L, C = mp::identity> = emp::unpack<L, mp::xor_<C>>::value

int_t emp::xor_v<xs...> = (xs::value ^ ...)

<jln/mp/number/to_bool.hpp>

Test file: test/src/number/to_bool.cpp

to_bool<C = identity>::f<x>

Return: true_ / false_

Converts a value to a true_ / false_.

Implementation
C::f<number<bool(x::value)>>

emp::to_bool<x> = number<bool(x::value)>

Group: reduce

<jln/mp/algorithm/accumulate.hpp>

Test file: test/src/algorithm/accumulate.cpp

accumulate<F, C = identity>::f<state, seqs...>

Return: value

Computes the recursive invocation of F with the result of the previous invocation and each element of one or more lists traversed in parallel from the beginning to the end.

Implementation
zip<push_front<state, fold<flip<unpack<F>>, C>>> ::f<seqs...>
Pre-condition
  • all seqs must be the same size
Semantics

Equivalent to

C::f<fold<F>::f<
  ...
  fold<F>::f<fold<F>::f<state, ...seqs[:][0]>, ...seqs[:][1]>
  ...,
  ...seqs[:][n-1]>
>>

emp::accumulate<L, state, F, C = mp::identity> = emp::unpack<L, mp::zip<mp::push_front<state, mp::fold<mp::flip<mp::unpack<F>>, C>>>>

<jln/mp/algorithm/fold.hpp>

Test file: test/src/algorithm/fold.cpp

fold<F, C = identity>::f<xs...>

Return: value

Folds left over a list using a binary predicate.

The first element in the input pack as the state, use push_front<> to add state if needed.

Pre-condition
  • sizeof...(xs) >= 1
Semantics
F::f<F::f<F::f<F::f<xs[0], xs[1]>, xs[2]>, ...>, xs[n-1]>

fold_or<F, FallbackValue, C = identity>

Implementation
if_<size<>, fold<F, C>, always<FallbackValue>>

fold_or_else<F, EmptyC, C = identity>

Return: value

Folds left over a list using a binary predicate.

Like fold<>, but uses EmptyC when xs is empty.

Implementation
if_<size<>, fold<F, C>, EmptyC>

emp::fold<L, state, F, C = mp::identity> = emp::unpack<L, mp::push_front<state, mp::fold<F, C>>>

emp::fold_or<L, F, FallbackValue, C = mp::identity> = emp::unpack<L, mp::fold_or_else<F, always<FallbackValue>, C>>

emp::fold_or_else<L, F, EmptyC = F, C = mp::identity> = emp::unpack<L, mp::fold_or_else<F, EmptyC, C>>

emp::reduce<L, F, C = mp::identity> = emp::unpack<L, mp::fold<F, C>>

<jln/mp/algorithm/fold_right.hpp>

Test file: test/src/algorithm/fold_right.cpp

fold_right<F, C = identity>::f<xs...>

Return: value

Folds right over a list using a binary predicate.

The first element in the input pack as the state, use push_front<> to add state if needed.

Pre-condition
  • sizeof...(xs) >= 1
Semantics
F::f<xs[1], F::f<..., F::f<xs[n-2], F::f<xs[n-1], xs[0]>>>>

fold_right_or<F, FallbackValue, C = identity>

Implementation
fold_right_or_else<F, always<FallbackValue>, C>

fold_right_or_else<F, EmptyC, C = identity>

Return: value

Folds right over a list using a binary predicate.

Like fold_right<>, but uses NoStateF when xs is empty.

Implementation
if_<size<>, rotate_c<-1, fold_right<F, C>>, EmptyC>

emp::fold_right<L, state, F, C = mp::identity> = emp::unpack<L, mp::push_front<state, mp::fold_right<F, C>>>

emp::fold_right_or<L, F, FallbackValue, C = mp::identity> = emp::unpack<L, mp::fold_right_or_else<F, always<FallbackValue>, C>>

emp::fold_right_or_else<L, F, NoStateF = F, C = mp::identity> = emp::unpack<L, mp::fold_right_or_else<F, NoStateF, C>>

<jln/mp/algorithm/fold_tree.hpp>

Test file: test/src/algorithm/fold_tree.cpp

fold_balanced_tree<F, C = identity>::f<xs...>

Return: value

Folds tree over a list using a binary predicate.

recursively fold (n+1)/2 value to the left and the rest to the right.

Semantics

Equivalent to

F::f<fold_tree::f<...xs[0..(n+1)/2]>, fold_tree::f<...xs[n-(n+1)/2..n]>>

fold_balanced_tree_or<F, FallbackValue, C = identity>

Implementation
if_<size<>, fold_balanced_tree<F, C>, always<FallbackValue>>

fold_balanced_tree_or_else<F, EmptyC, C = identity>

Return: value

Folds tree over a list using a binary predicate.

Like fold_balanced_tree<>, but uses EmptyC when xs is empty.

Implementation
if_<size<>, fold_balanced_tree<F, C>, EmptyC>

fold_tree<F, C = identity>::f<xs...>

Return: value

Folds tree over a list using a binary predicate.

recursively fold n/2 value to the left and the rest to the right.

Semantics

Equivalent to

F::f<fold_tree::f<...xs[0..n/2]>, fold_tree::f<...xs[n/2..n]>>

fold_tree_or<F, FallbackValue, C = identity>

Implementation
if_<size<>, fold_tree<F, C>, always<FallbackValue>>

fold_tree_or_else<F, EmptyC, C = identity>

Return: value

Folds tree over a list using a binary predicate.

Like fold_tree<>, but uses EmptyC when xs is empty.

Implementation
if_<size<>, fold_tree<F, C>, EmptyC>

emp::fold_balanced_tree<L, F, C = mp::identity> = emp::unpack<L, mp::fold_balanced_tree<F, C>>

emp::fold_balanced_tree_or<L, F, FallbackValue, C = mp::identity> = emp::unpack<L, mp::fold_balanced_tree_or_else<F, always<FallbackValue>, C>>

emp::fold_balanced_tree_or_else<L, F, EmptyC = F, C = mp::identity> = emp::unpack<L, mp::fold_balanced_tree_or_else<F, EmptyC, C>>

emp::fold_tree<L, F, C = mp::identity> = emp::unpack<L, mp::fold_tree<F, C>>

emp::fold_tree_or<L, F, FallbackValue, C = mp::identity> = emp::unpack<L, mp::fold_tree_or_else<F, always<FallbackValue>, C>>

emp::fold_tree_or_else<L, F, EmptyC = F, C = mp::identity> = emp::unpack<L, mp::fold_tree_or_else<F, EmptyC, C>>

<jln/mp/algorithm/fold_xs.hpp>

Test file: test/src/algorithm/fold_xs.cpp

fold_xs<F, C = identity>

Return: value

Folds left over a list using a mulary predicate.

The first element in the input pack as the state, use push_front<> to add state if needed.

Implementation
partial_fold_xs_c<-1, F, C>
Semantics

Equivalent to

F::f<... F::f<xs[0], xs[1], ..., xs[n-1]>, xs[2], ..., xs[n-1]>, ..., xs[n-1]>, ...>

fold_xs_or<F, FallbackValue, C = identity>

Implementation
partial_fold_xs_or_else_c<-1, F, always<FallbackValue>, C>

fold_xs_or_else<F, NoStateF = F, C = identity>

Folds left over a list using a mulary predicate.

Like fold_xs<>, but uses NoStateF when xs is empty.

Implementation
partial_fold_xs_or_else_c<-1, F, NoStateF, C>

partial_fold_xs<OffsetEnd, F, C = identity>

Implementation
partial_fold_xs_c<OffsetEnd::value, F, C>

partial_fold_xs_c<int_t OffsetEnd, F, C = identity>::f<xs...>

As fold_xs, but stop at position OffsetEnd.

partial_fold_xs_or<OffsetEnd, F, FallbackValue, C = identity>

Implementation
partial_fold_xs_or_else_c<OffsetEnd::value, F, always<FallbackValue>, C>

partial_fold_xs_or_c<int_t OffsetEnd, F, FallbackValue, C = identity>

Implementation
partial_fold_xs_or_else_c<OffsetEnd, F, always<FallbackValue>, C>

partial_fold_xs_or_else<OffsetEnd, F, NoStateF = F, C = identity>

Implementation
partial_fold_xs_or_else_c<OffsetEnd::value, F, NoStateF, C>

partial_fold_xs_or_else_c<int_t OffsetEnd, F, EmptyC, C = identity>

As fold_xs_or_else, but stop at position OffsetEnd.

Implementation
if_<size<>, partial_fold_xs_c<OffsetEnd, F, C>, EmptyC>

emp::fold_xs<L, state, F, C = mp::identity> = emp::unpack<L, mp::push_front<state, mp::partial_fold_xs_c<-1, F, C>>>

emp::fold_xs_or<L, F, FallbackValue, C = mp::identity> = emp::unpack<L, mp::partial_fold_xs_or_else_c<-1, F, always<FallbackValue>, C>>

emp::fold_xs_or_else<L, F, NoStateF = F, C = mp::identity> = emp::unpack<L, mp::partial_fold_xs_or_else_c<-1, F, NoStateF, C>>

emp::partial_fold_xs<L, OffsetEnd, state, F, C = mp::identity> = emp::unpack<L, mp::push_front<state, mp::partial_fold_xs<OffsetEnd, F, C>>>

emp::partial_fold_xs_c<L, int_t OffsetEnd, state, F, C = mp::identity> = emp::unpack<L, mp::push_front<state, mp::partial_fold_xs_c<OffsetEnd, F, C>>>

emp::partial_fold_xs_or<L, OffsetEnd, F, FallbackValue, C = mp::identity> = emp::unpack<L, mp::partial_fold_xs_or_else<OffsetEnd, F, always<FallbackValue>, C>>

emp::partial_fold_xs_or_c<L, int_t OffsetEnd, F, FallbackValue, C = mp::identity> = emp::unpack<L, mp::partial_fold_xs_or_else_c<OffsetEnd, F, always<FallbackValue>, C>>

emp::partial_fold_xs_or_else<L, OffsetEnd, F, NoStateF = F, C = mp::identity> = emp::unpack<L, mp::partial_fold_xs_or_else<OffsetEnd, F, NoStateF, C>>

emp::partial_fold_xs_or_else_c<L, int_t OffsetEnd, F, NoStateF = F, C = mp::identity> = emp::unpack<L, mp::partial_fold_xs_or_else_c<OffsetEnd, F, NoStateF, C>>

<jln/mp/algorithm/reverse_fold.hpp>

Test file: test/src/algorithm/reverse_fold.cpp

reverse_fold<F, C = identity>::f<xs...>

Return: value

Folds right over a list using a binary predicate.

The first element in the input pack as the state, use push_front<> to add state if needed.

Pre-condition
  • sizeof...(xs) >= 1
Semantics
F::f<F::f<F::f<F::f<xs[0], xs[n-1]>, x[n-2]>, ...>, x[1]>

reverse_fold_or<F, FallbackValue, C = identity>

Implementation
reverse_fold_or_else<F, always<FallbackValue>, C>

reverse_fold_or_else<F, EmptyC, C = identity>

Return: value

Folds right over a list using a binary predicate.

Like reverse_fold<>, but uses NoStateF when xs is empty.

Implementation
if_<size<>, rotate_c<-1, reverse_fold<F, C>>, EmptyC>

emp::reverse_fold<L, state, F, C = mp::identity> = emp::unpack<L, mp::push_front<state, mp::reverse_fold<F, C>>>

emp::reverse_fold_or<L, F, FallbackValue, C = mp::identity> = emp::unpack<L, mp::reverse_fold_or_else<F, always<FallbackValue>, C>>

emp::reverse_fold_or_else<L, F, NoStateF = F, C = mp::identity> = emp::unpack<L, mp::reverse_fold_or_else<F, NoStateF, C>>

<jln/mp/algorithm/reverse_fold_right.hpp>

Test file: test/src/algorithm/reverse_fold_right.cpp

reverse_fold_right<F, C = identity>::f<xs...>

Return: value

Folds right over a list using a binary predicate.

This is equivalent to reverse<fold<flip<F>, C>>.

Pre-condition
  • sizeof...(xs) >= 1
Semantics
F::f<xs[n-1], F::f<..., F::f<xs[2], F::f<xs[1], xs[0]>>>>

reverse_fold_right_or<F, FallbackValue, C = identity>

Implementation
if_<size<>, reverse_fold_right<F, C>, always<FallbackValue>>

reverse_fold_right_or_else<F, EmptyC, C = identity>

Return: value

Folds right over a list using a binary predicate.

Like reverse_fold_right<>, but uses EmptyC when xs is empty.

Implementation
if_<size<>, reverse_fold_right<F, C>, EmptyC>

emp::reverse_fold_right<L, state, F, C = mp::identity> = emp::unpack<L, mp::push_front<state, mp::reverse_fold_right<F, C>>>

emp::reverse_fold_right_or<L, F, FallbackValue, C = mp::identity> = emp::unpack<L, mp::reverse_fold_right_or_else<F, always<FallbackValue>, C>>

emp::reverse_fold_right_or_else<L, F, EmptyC = F, C = mp::identity> = emp::unpack<L, mp::reverse_fold_right_or_else<F, EmptyC, C>>

emp::reverse_reduce<L, F, C = mp::identity> = emp::unpack<L, mp::reverse_fold_right<F, C>>

<jln/mp/algorithm/after.hpp>

Test file: test/src/algorithm/after.cpp

after<Seq, TC = listify, FC = clear<TC>>

Return: sequence

Find the sequence after a sub-sequence.

Calls TC with all the elements after the sub-sequence found. If no element is found, FC is used with the whole sequence.

after<list<Ts...>, TC, FC>

emp::after<L, Seq, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::after<Seq, TC, FC>>

<jln/mp/algorithm/before.hpp>

Test file: test/src/algorithm/before.cpp

before<Seq, TC = listify, FC = clear<TC>>

Return: sequence

Find the sequence before a sub-sequence.

Calls TC with all the elements before the sub-sequence found. If no element is found, FC is used with the whole sequence.

before<list<Ts...>, TC, FC>::f<xs...>

emp::before<L, Seq, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::before<Seq, TC, FC>>

<jln/mp/algorithm/before_after.hpp>

Test file: test/src/algorithm/before_after.cpp

before_after<Seq, TC = listify, FC = clear<TC>>

Implementation
before_after_with<Seq, listify, listify, TC, FC>

before_after_with<Seq, SubC1 = listify, SubC2 = SubC1, TC = listify, FC = clear<TC>>

Return: sequence

Find the sequences before and after a sub-sequence.

Calls TC with result of SubC1 and SubC2 called respectively with the sequences before and after the one found. If no element is found, FC is used with the whole sequence.

before_after_with<list<Ts...>, SubC1, SubC2, TC, FC>::f<xs...>

emp::before_after<L, Seq, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::before_after<Seq, TC, FC>>

emp::before_after_with<L, Seq, SubC1 = mp::listify, SubC2 = SubC1, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::before_after_with<Seq, SubC1, SubC2, TC, FC>>

<jln/mp/algorithm/conjunction.hpp>

Test file: test/src/algorithm/conjunction.cpp

conjunction<C = identity>

Return: value convertible to true_ / false_

Perform a logical AND on the sequence of value and returns the first value converted to false.

Conjunction is short-circuiting: if there is a template type argument xs[i] with bool(xs[i]::value) == false, then instantiating conjunction<C>::f<xs[0], ..., xs[n-1]> does not require the instantiation of xs[j]::value for j > i.

Implementation
conjunction_with<identity, C>
Post-condition
  • If sizeof...(xs) == 0, true_
  • If sizeof...(xs) != 0, the first value for which bool(xs[i]::value) == false, or last value if there is no such type.
Note

If you just need a boolean, all_of<identity,C> is more appropriate.

conjunction_with<Pred, C = identity>::f<xs...>

Return: value

Perform a logical AND on the sequence of value and returns the first value converted to false.

Conjunction is short-circuiting: if there is a template type argument xs[i] with bool(Pred::f<xs[i]>::value) == false, then instantiating conjunction<C>::f<xs[0], ..., xs[n-1]> does not require the instantiation of Pred::f<xs[j]>::value for j > i.

Post-condition
  • If sizeof...(xs) == 0, true_
  • If sizeof...(xs) != 0, the first type xs[i] for which bool(Pred::f<xs[i]>::value) == false, or last value if there is no such type.
Note

If you just need a boolean, all_of<Pred,C> is more appropriate.

emp::conjunction<L, C = mp::identity> = emp::unpack<L, mp::conjunction_with<mp::identity, C>>

bool emp::conjunction_v<L, C = mp::identity> = emp::unpack<L, mp::conjunction_with<mp::identity, C>>::value

emp::conjunction_with<L, Pred, C = mp::identity> = emp::unpack<L, mp::conjunction_with<Pred, C>>

bool emp::conjunction_with_v<L, Pred, C = mp::identity> = emp::unpack<L, mp::conjunction_with<Pred, C>>::value

<jln/mp/algorithm/disjunction.hpp>

Test file: test/src/algorithm/disjunction.cpp

disjunction<C = identity>

Return: value convertible to true_ / false_

Perform a logical OR on the sequence of value and returns the first value converted to true.

Disjunction is short-circuiting: if there is a template type argument xs[i] with bool(xs[i]::value) == true, then instantiating disjunction<C>::f<xs[0], ..., xs[n-1]> does not require the instantiation of xs[j]::value for j > i.

Implementation
disjunction_with<identity, C>
Post-condition
  • If sizeof...(xs) == 0, false_
  • If sizeof...(xs) != 0, the first value for which bool(xs[i]::value) == true, or last value if there is no such type.
Note

If you just need a boolean, any_of<identity,C> is more appropriate.

disjunction_with<Pred, C = identity>::f<xs...>

Return: value

Perform a logical OR on the sequence of value and returns the first value converted to true.

Disjunction is short-circuiting: if there is a template type argument xs[i] with bool(xs[i]::value) == true, then instantiating disjunction<C>::f<xs[0], ..., xs[n-1]> does not require the instantiation of Pred::f<xs[j]>::value for j > i

Post-condition
  • If sizeof...(xs) == 0, false_
  • If sizeof...(xs) != 0, the first type xs[i] for which bool(Pred::f<xs[i]>::value) == true, or last value if there is no such type.
Note

If you just need a boolean, any_of<Pred,C> is more appropriate.

emp::disjunction<L, C = mp::identity> = emp::unpack<L, mp::disjunction_with<mp::identity, C>>

bool emp::disjunction_v<L, C = mp::identity> = emp::unpack<L, mp::disjunction_with<mp::identity, C>>::value

emp::disjunction_with<L, Pred, C = mp::identity> = emp::unpack<L, mp::disjunction_with<Pred, C>>

bool emp::disjunction_with_v<L, Pred, C = mp::identity> = emp::unpack<L, mp::disjunction_with<Pred, C>>::value

<jln/mp/algorithm/drop_until.hpp>

Test file: test/src/algorithm/drop_until.cpp

drop_inclusive_until<Pred, TC = listify, FC = clear<TC>>

Implementation
drop_until_extended_by_n_c<1, Pred, TC, FC>

drop_until<Pred, TC = listify, FC = clear<TC>>::f<xs...>

Return: sequence

Remove the first elements of a sequence that does not satisfy a predicate.

When an element satisfy the predicate, call TC with it and those that follow it. Otherwise FC is called on the whole sequence.

drop_until_extended_by_n<ExtendedByN, Pred, TC = listify, FC = clear<TC>>

Implementation
drop_until_extended_by_n_c<ExtendedByN::value, Pred, TC, FC>

drop_until_extended_by_n_c<std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>::f<xs...>

Return: sequence

Remove the first minus at most ExtendedByN elements of a sequence that does not satisfy a predicate.

When an element satisfy the predicate, call TC with it and those that follow it plus at most ExtendedByN. Otherwise FC is called on the whole sequence.

Semantics
call<drop_while_extended_by_n_c<2, is<number<4>>>,
  number<0>, number<1>, number<2>, number<3>, number<4>, number<5>>
//                        ^ -2       ^ -1       ^ found elem
==
list<number<2>, number<3>, number<4>, number<5>>

call<drop_while_extended_by_n_c<2, is<number<1>>>,
  number<0>, number<1>, number<2>, number<3>, number<4>, number<5>>
//  ^ -1       ^ found elem
==
list<number<0>, number<1>>

emp::drop_inclusive_until<L, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::drop_inclusive_until<Pred, TC, FC>>

emp::drop_until<L, Pred, C = mp::listify> = emp::unpack<L, mp::drop_until<Pred, C>>

emp::drop_until_extended_by_n<L, ExtendedByN, Pred, TC = listify, FC = clear<TC>> = emp::unpack<L, mp::drop_until_extended_by_n<ExtendedByN, Pred, TC, FC>>

emp::drop_until_extended_by_n_c<L, std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>> = emp::unpack<L, mp::drop_until_extended_by_n_c<ExtendedByN, Pred, TC, FC>>

<jln/mp/algorithm/drop_until_xs.hpp>

Test file: test/src/algorithm/drop_until_xs.cpp

drop_inclusive_until_xs<Pred, TC = listify, FC = clear<TC>>

Implementation
drop_until_extended_by_n_xs_c<1, Pred, TC, FC>

drop_until_extended_by_n_xs<ExtendedByN, Pred, TC = listify, FC = clear<TC>>

Implementation
drop_until_extended_by_n_xs_c<ExtendedByN::value, Pred, TC, FC>

drop_until_extended_by_n_xs_c<std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>::f<xs...>

Return: sequence

Same as drop_until_extended_by_n_c, but for drop_until_xs.

drop_until_xs<Pred, TC = listify, FC = clear<TC>>::f<xs...>

Return: sequence

Remove the first elements of a sequence that does not satisfy a predicate.

Pre-condition
  • Pred::f<ys...> must return a boolean, 1 or 0 Same as drop_until, but the predicate takes all the elements of the current position until the end of the list.

partial_drop_inclusive_until_xs<OffsetEnd, Pred, TC = listify, FC = clear<TC>>

Implementation
partial_drop_until_extended_by_n_xs_c<OffsetEnd::value, 1, Pred, TC, FC>

partial_drop_inclusive_until_xs_c<std::size_t OffsetEnd, Pred, TC = listify, FC = clear<TC>>

Implementation
partial_drop_until_extended_by_n_xs_c<OffsetEnd, 1, Pred, TC, FC>

partial_drop_until_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC = listify, FC = clear<TC>>

Implementation
partial_drop_until_extended_by_n_xs_c<OffsetEnd::value, ExtendedByN::value, Pred, TC, FC>

partial_drop_until_extended_by_n_xs_c<int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>::f<xs...>

Return: sequence

Same as drop_until_extended_by_n_xs_c, but stop searching at position OffsetEnd.

OffsetEnd
a negative value start to end of sequence.

partial_drop_until_xs<OffsetEnd, Pred, TC = listify, FC = clear<TC>>

Implementation
partial_drop_until_extended_by_n_xs_c<OffsetEnd::value, 0, Pred, TC, FC>

partial_drop_until_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = clear<TC>>

Implementation
partial_drop_until_extended_by_n_xs_c<OffsetEnd, 0, Pred, TC, FC>

emp::drop_inclusive_until_xs<L, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::drop_inclusive_until_xs<Pred, TC, FC>>

emp::drop_until_extended_by_n_xs<L, ExtendedByN, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::drop_until_extended_by_n_xs<ExtendedByN, Pred, TC, FC>>

emp::drop_until_extended_by_n_xs_c<L, std::size_t ExtendedByN, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::drop_until_extended_by_n_xs_c<ExtendedByN, Pred, TC, FC>>

emp::drop_until_xs<L, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::drop_until_xs<Pred, TC, FC>>

emp::partial_drop_inclusive_until_xs<L, OffsetEnd, state, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_drop_inclusive_until_xs<OffsetEnd, Pred, TC, FC>>

emp::partial_drop_inclusive_until_xs_c<L, int_t OffsetEnd, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_drop_inclusive_until_xs_c<OffsetEnd, Pred, TC, FC>>

emp::partial_drop_until_extended_by_n_xs<L, OffsetEnd, ExtendedByN, Pred, TC = listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_drop_until_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC, FC>>

emp::partial_drop_until_extended_by_n_xs_c<L, int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_drop_until_extended_by_n_xs_c<OffsetEnd, ExtendedByN, Pred, TC, FC>>

emp::partial_drop_until_xs<L, OffsetEnd, state, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_drop_until_xs<OffsetEnd, Pred, TC, FC>>

emp::partial_drop_until_xs_c<L, int_t OffsetEnd, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_drop_until_xs_c<OffsetEnd, Pred, TC, FC>>

<jln/mp/algorithm/drop_while.hpp>

Test file: test/src/algorithm/drop_while.cpp

drop_inclusive_while<Pred, TC = listify, FC = clear<TC>>

Implementation
drop_while_extended_by_n_c<1, Pred, TC, FC>

drop_while<Pred, TC = listify, FC = clear<TC>>::f<xs...>

Return: sequence

Remove the first elements of a sequence that satisfy a predicate.

When an element does not satisfy the predicate, call TC with it and all those that follow it. Otherwise FC is called on the whole sequence.

drop_while_extended_by_n<ExtendedByN, Pred, TC = listify, FC = clear<TC>>

Implementation
drop_while_extended_by_n_c<ExtendedByN::value, Pred, TC, FC>

drop_while_extended_by_n_c<std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>::f<xs...>

Return: sequence

Remove the first minus at most ExtendedByN elements of a sequence that satisfy a predicate.

When an element does not satisfy the predicate, call TC with it and all those that follow it plus at most ExtendedByN. Otherwise FC is called on the whole sequence.

Semantics
call<drop_while_extended_by_n_c<2, is_not<number<4>>>,
  number<0>, number<1>, number<2>, number<3>, number<4>, number<5>>
//                         ^ 2        ^ 1       ^ found elem
==
list<number<2>, number<3>, number<4>, number<5>>

call<drop_while_extended_by_n_c<2, is_not<number<1>>>,
  number<0>, number<1>, number<2>, number<3>, number<4>, number<5>>
//   ^ 1       ^ found elem
==
list<number<0>, number<1>>

emp::drop_inclusive_while<L, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::drop_inclusive_while<Pred, TC, FC>>

emp::drop_while<L, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::drop_while<Pred, TC, FC>>

emp::drop_while_extended_by_n<L, ExtendedByN, Pred, TC = listify, FC = clear<TC>> = emp::unpack<L, mp::drop_while_extended_by_n<ExtendedByN, Pred, TC, FC>>

emp::drop_while_extended_by_n_c<L, std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>> = emp::unpack<L, mp::drop_while_extended_by_n_c<ExtendedByN, Pred, TC, FC>>

<jln/mp/algorithm/drop_while_xs.hpp>

Test file: test/src/algorithm/drop_while_xs.cpp

drop_inclusive_while_xs<Pred, TC = listify, FC = clear<TC>>

Implementation
drop_while_extended_by_n_xs_c<1, Pred, TC, FC>

drop_while_extended_by_n_xs<ExtendedByN, Pred, TC = listify, FC = clear<TC>>

Implementation
drop_while_extended_by_n_xs_c<ExtendedByN::value, Pred, TC, FC>

drop_while_extended_by_n_xs_c<std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>::f<xs...>

Return: sequence

Same as drop_while_extended_by_n_c, but for drop_while_xs.

drop_while_xs<Pred, TC = listify, FC = clear<TC>>::f<xs...>

Return: sequence

Remove the first elements of a sequence that satisfy a predicate.

Same as drop_while, but the predicate takes all the elements of the current position until the end of the list.

partial_drop_inclusive_while_xs<OffsetEnd, Pred, TC = listify, FC = clear<TC>>

Implementation
partial_drop_while_extended_by_n_xs_c<OffsetEnd::value, 1, Pred, TC, FC>

partial_drop_inclusive_while_xs_c<std::size_t OffsetEnd, Pred, TC = listify, FC = clear<TC>>

Implementation
partial_drop_while_extended_by_n_xs_c<OffsetEnd, 1, Pred, TC, FC>

partial_drop_while_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC = listify, FC = clear<TC>>

Implementation
partial_drop_while_extended_by_n_xs_c<OffsetEnd::value, ExtendedByN::value, Pred, TC, FC>

partial_drop_while_extended_by_n_xs_c<int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>::f<xs...>

Return: sequence

Same as drop_while_extended_by_n_xs_c, but stop searching at position OffsetEnd.

OffsetEnd
a negative value start to end of sequence.

partial_drop_while_xs<OffsetEnd, Pred, TC = listify, FC = clear<TC>>

Implementation
partial_drop_while_extended_by_n_xs_c<OffsetEnd::value, 0, Pred, TC, FC>

partial_drop_while_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = clear<TC>>

Implementation
partial_drop_while_extended_by_n_xs_c<OffsetEnd, 0, Pred, TC, FC>

emp::drop_inclusive_while_xs<L, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::drop_inclusive_while_xs<Pred, TC, FC>>

emp::drop_while_extended_by_n_xs<L, ExtendedByN, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::drop_while_extended_by_n_xs<ExtendedByN, Pred, TC, FC>>

emp::drop_while_extended_by_n_xs_c<L, std::size_t ExtendedByN, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::drop_while_extended_by_n_xs_c<ExtendedByN, Pred, TC, FC>>

emp::drop_while_xs<L, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::drop_while_xs<Pred, TC, FC>>

emp::partial_drop_inclusive_while_xs<L, OffsetEnd, state, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_drop_inclusive_while_xs<OffsetEnd, Pred, TC, FC>>

emp::partial_drop_inclusive_while_xs_c<L, int_t OffsetEnd, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_drop_inclusive_while_xs_c<OffsetEnd, Pred, TC, FC>>

emp::partial_drop_while_extended_by_n_xs<L, OffsetEnd, ExtendedByN, Pred, TC = listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_drop_while_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC, FC>>

emp::partial_drop_while_extended_by_n_xs_c<L, int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_drop_while_extended_by_n_xs_c<OffsetEnd, ExtendedByN, Pred, TC, FC>>

emp::partial_drop_while_xs<L, OffsetEnd, state, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_drop_while_xs<OffsetEnd, Pred, TC, FC>>

emp::partial_drop_while_xs_c<L, int_t OffsetEnd, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_drop_while_xs_c<OffsetEnd, Pred, TC, FC>>

<jln/mp/algorithm/find.hpp>

Test file: test/src/algorithm/find.cpp

find<T, TC = listify, FC = clear<TC>>

Implementation
drop_until<is<T>, TC, FC>

find_if<Pred, TC = listify, FC = clear<TC>>

Return: sequence

Finds the first element that satisfy a predicate.

Implementation
drop_until<Pred, TC, FC>
Pre-condition
  • Pred::f<x> must return a boolean, 1 or 0 Calls TC with all the elements since the one found at the end. If no element is found, FC is used with the whole sequence.

find_if_not<Pred, TC = listify, FC = clear<TC>>

Implementation
drop_while<Pred, TC, FC>

emp::find<L, T, TC = mp::listify, FC = clear<TC>> = emp::unpack<L, mp::find_if<mp::is<T>, TC, FC>>

emp::find_if<L, Pred, TC = mp::listify, FC = clear<TC>> = emp::unpack<L, mp::find_if<Pred, TC, FC>>

emp::find_if_not<L, Pred, TC = mp::listify, FC = clear<TC>> = emp::unpack<L, mp::find_if_not<Pred, TC, FC>>

<jln/mp/algorithm/find_last.hpp>

Test file: test/src/algorithm/find_last.cpp

find_last<T, TC = listify, FC = clear<TC>>

Implementation
find_last_if<is<T>, TC, FC>

find_last_if<Pred, TC = listify, FC = clear<TC>>

Return: sequence

Finds the last element that satisfy a predicate.

Calls TC with all the elements since the last found at the end. If no element is found, FC is used with the whole sequence.

Implementation
until_last_t<drop_until, Pred, TC, FC>

find_last_if_not<Pred, TC = listify, FC = clear<TC>>

Implementation
until_last_t<drop_while, Pred, TC, FC>

emp::find_last<L, T, TC = mp::listify, FC = clear<TC>> = emp::unpack<L, mp::find_last_if<mp::is<T>, TC, FC>>

emp::find_last_if<L, Pred, TC = mp::listify, FC = clear<TC>> = emp::unpack<L, mp::find_last_if<Pred, TC, FC>>

emp::find_last_if_not<L, Pred, TC = mp::listify, FC = clear<TC>> = emp::unpack<L, mp::find_last_if_not<Pred, TC, FC>>

<jln/mp/algorithm/index.hpp>

Test file: test/src/algorithm/index.cpp

index_if<Pred, TC = identity, FC = size<>>::f<xs...>

Return: number

Finds the index of the first element of sequence that satisfies the predicate Pred.

Calls TC with the index found or FC with the whole sequence.

index_if_xs<Pred, TC = identity, FC = size<>>::f<xs...>

Return: sequence

Search the index of first sub-sequence that satisfy a predicate.

index_of<T, TC = identity, FC = size<>>

Return: number

Finds the index of the first element of sequence that is a type T.

Calls TC with the index found or FC with the whole sequence.

Implementation
index_if<is<T>, TC, FC>

partial_index_if_xs<OffsetEnd, Pred, TC = identity, FC = size<>>

Implementation
partial_index_if_xs_c<OffsetEnd::value, Pred, TC, FC>

partial_index_if_xs_c<int_t OffsetEnd, Pred, TC = identity, FC = size<>>::f<xs...>

Same as index_if_xs, but stop searching at position OffsetEnd.

OffsetEnd
a negative value start to end of sequence.

emp::index_if<L, Pred, TC = mp::identity, FC = mp::size<>> = emp::unpack<L, mp::index_if<Pred, TC, FC>>

bool emp::index_if_v<L, Pred, TC = mp::identity, FC = mp::size<>> = emp::unpack<L, mp::index_if<Pred, TC, FC>>::value

emp::index_if_xs<L, Pred, TC = mp::identity, FC = mp::size<>> = emp::unpack<L, mp::index_if_xs<Pred, TC, FC>>

bool emp::index_if_xs_v<L, Pred, TC = mp::identity, FC = mp::size<>> = emp::unpack<L, mp::index_if_xs<Pred, TC, FC>>::value

emp::index_of<L, T, TC = mp::identity, FC = mp::size<>> = emp::unpack<L, mp::index_of<T, TC, FC>>

bool emp::index_of_v<L, T, TC = mp::identity, FC = mp::size<>> = emp::unpack<L, mp::index_of<T, TC, FC>>::value

emp::partial_index_if_xs<OffsetEnd, L, Pred, TC = mp::identity, FC = mp::size<>> = emp::unpack<L, mp::partial_index_if_xs<OffsetEnd, Pred, TC, FC>>

emp::partial_index_if_xs_c<int_t OffsetEnd, L, Pred, TC = mp::identity, FC = mp::size<>> = emp::unpack<L, mp::partial_index_if_xs_c<OffsetEnd, Pred, TC, FC>>

bool emp::partial_index_if_xs_c_v<int_t OffsetEnd, L, Pred, TC = mp::identity, FC = mp::size<>> = emp::unpack<L, mp::partial_index_if_xs_c<OffsetEnd, Pred, TC, FC>>::value

bool emp::partial_index_if_xs_v<OffsetEnd, L, Pred, TC = mp::identity, FC = mp::size<>> = emp::unpack<L, mp::partial_index_if_xs<OffsetEnd, Pred, TC, FC>>::value

<jln/mp/algorithm/lower_bound.hpp>

Test file: test/src/algorithm/lower_bound.cpp

lower_bound<x, Cmp = less<>, TC = listify, FC = TC>::f<xs...>

Return: sequence

Finds first element that is not less than (i.e. greater or equal to) x.

Calls TC with all the elements since the one found at the end. If no element is found, FC is used.

Pre-condition

lower_bound_c<int_t x, Cmp = less<>, TC = listify, FC = TC>

Implementation
lower_bound<number<x>, Cmp, TC, FC>

lower_bound_than<x, TC = listify, FC = TC>

Implementation
lower_bound<x, less<>, TC, FC>

lower_bound_than_c<int_t x, TC = listify, FC = TC>

Implementation
lower_bound<number<x>, less<>, TC, FC>

emp::lower_bound<L, x, Cmp = mp::less<>, TC = mp::listify, FC = TC> = emp::unpack<L, mp::lower_bound<x, Cmp, TC, FC>>

emp::lower_bound_c<L, int_t x, Cmp = mp::less<>, TC = mp::listify, FC = TC> = emp::unpack<L, mp::lower_bound<mp::number<x>, Cmp, TC, FC>>

emp::lower_bound_than<L, x, TC = mp::listify, FC = TC> = emp::unpack<L, mp::lower_bound<x, mp::less<>, TC, FC>>

emp::lower_bound_than_c<L, int_t x, TC = mp::listify, FC = TC> = emp::unpack<L, mp::lower_bound<mp::number<x>, mp::less<>, TC, FC>>

<jln/mp/algorithm/max_element.hpp>

Test file: test/src/algorithm/max_element.cpp

last_max_element<C = identity>

Implementation
last_max_element_with<less<>, C>

last_max_element_with<Cmp = less<>, C = identity>::f<xs...>

Return: value

Returns the greatest element.

If several elements in the sequence are equivalent to the greatest element, returns the element to the last such element.

Pre-condition
  • sizeof...(xs) > 0

max_element<C = identity>

Implementation
max_element_with<less<>, C>

max_element_with<Cmp = less<>, C = identity>::f<xs...>

Return: value

Returns the greatest element.

If several elements in the sequence are equivalent to the greatest element, returns the element to the first such element.

Pre-condition
  • sizeof...(xs) > 0

emp::last_max_element<L, C = mp::identity> = emp::unpack<L, mp::last_max_element<C>>

emp::last_max_element_c<int_t... xs> = mp::last_max_element_with<>::f<number<xs>...>

auto emp::last_max_element_c_v<int_t... xs> = mp::last_max_element_with<> ::f<number<xs>...>::value

auto emp::last_max_element_v<L, C = mp::identity> = emp::unpack<L, mp::last_max_element<C>>::value

emp::last_max_element_with<L, Cmp = mp::less<>, C = mp::identity> = emp::unpack<L, mp::last_max_element_with<Cmp, C>>

emp::last_max_element_with_c<Cmp, int_t... xs> = mp::last_max_element_with<Cmp> ::f<number<xs>...>

auto emp::last_max_element_with_c_v<Cmp, int_t... xs> = mp::last_max_element_with<Cmp> ::f<number<xs>...>::value

auto emp::last_max_element_with_v<L, Cmp = mp::less<>, C = mp::identity> = emp::unpack<L, mp::last_max_element_with<Cmp, C>>::value

emp::last_max_element_with_xs<Cmp, xs...> = mp::last_max_element_with<Cmp>::f<xs...>

auto emp::last_max_element_with_xs_v<Cmp, xs...> = mp::last_max_element_with<Cmp> ::f<xs...>::value

emp::last_max_element_xs<xs...> = mp::last_max_element_with<>::f<xs...>

auto emp::last_max_element_xs_v<xs...> = mp::last_max_element_with<> ::f<xs...>::value

emp::max_element<L, C = mp::identity> = emp::unpack<L, mp::max_element<C>>

emp::max_element_c<int_t... xs> = mp::max_element_with<>::f<number<xs>...>

auto emp::max_element_c_v<int_t... xs> = mp::max_element_with<> ::f<number<xs>...>::value

auto emp::max_element_v<L, C = mp::identity> = emp::unpack<L, mp::max_element<C>>::value

emp::max_element_with<L, Cmp = mp::less<>, C = mp::identity> = emp::unpack<L, mp::max_element_with<Cmp, C>>

emp::max_element_with_c<Cmp, int_t... xs> = mp::max_element_with<Cmp> ::f<number<xs>...>

auto emp::max_element_with_c_v<Cmp, int_t... xs> = mp::max_element_with<Cmp> ::f<number<xs>...>::value

auto emp::max_element_with_v<L, Cmp = mp::less<>, C = mp::identity> = emp::unpack<L, mp::max_element_with<Cmp, C>>::value

emp::max_element_with_xs<Cmp, xs...> = mp::max_element_with<Cmp>::f<xs...>

auto emp::max_element_with_xs_v<Cmp, xs...> = mp::max_element_with<Cmp> ::f<xs...>::value

emp::max_element_xs<xs...> = mp::max_element_with<>::f<xs...>

auto emp::max_element_xs_v<xs...> = mp::max_element_with<> ::f<xs...>::value

<jln/mp/algorithm/min_element.hpp>

Test file: test/src/algorithm/min_element.cpp

last_min_element<C = identity>

Implementation
last_min_element_with<less<>, C>

last_min_element_with<Cmp = less<>, C = identity>::f<xs...>

Return: value

Returns the smallest element.

If several elements in the sequence are equivalent to the smallest element, returns the element to the last such element.

Pre-condition
  • sizeof...(xs) > 0

min_element<C = identity>

Implementation
min_element_with<less<>, C>

min_element_with<Cmp = less<>, C = identity>::f<xs...>

Return: value

Returns the smallest element.

If several elements in the sequence are equivalent to the smallest element, returns the element to the first such element.

Pre-condition
  • sizeof...(xs) > 0

emp::last_min_element<L, C = mp::identity> = emp::unpack<L, mp::last_min_element<C>>

emp::last_min_element_c<int_t... xs> = mp::last_min_element_with<>::f<number<xs>...>

auto emp::last_min_element_c_v<int_t... xs> = mp::last_min_element_with<> ::f<number<xs>...>::value

auto emp::last_min_element_v<L, C = mp::identity> = emp::unpack<L, mp::last_min_element<C>>::value

emp::last_min_element_with<L, Cmp = mp::less<>, C = mp::identity> = emp::unpack<L, mp::last_min_element_with<Cmp, C>>

emp::last_min_element_with_c<Cmp, int_t... xs> = mp::last_min_element_with<Cmp> ::f<number<xs>...>

auto emp::last_min_element_with_c_v<Cmp, int_t... xs> = mp::last_min_element_with<Cmp> ::f<number<xs>...>::value

auto emp::last_min_element_with_v<L, Cmp = mp::less<>, C = mp::identity> = emp::unpack<L, mp::last_min_element_with<Cmp, C>>::value

emp::last_min_element_with_xs<Cmp, xs...> = mp::last_min_element_with<Cmp>::f<xs...>

auto emp::last_min_element_with_xs_v<Cmp, xs...> = mp::last_min_element_with<Cmp> ::f<xs...>::value

emp::last_min_element_xs<xs...> = mp::last_min_element_with<>::f<xs...>

auto emp::last_min_element_xs_v<xs...> = mp::last_min_element_with<> ::f<xs...>::value

emp::min_element<L, C = mp::identity> = emp::unpack<L, mp::min_element<C>>

emp::min_element_c<int_t... xs> = mp::min_element_with<>::f<number<xs>...>

auto emp::min_element_c_v<int_t... xs> = mp::min_element_with<> ::f<number<xs>...>::value

auto emp::min_element_v<L, C = mp::identity> = emp::unpack<L, mp::min_element<C>>::value

emp::min_element_with<L, Cmp = mp::less<>, C = mp::identity> = emp::unpack<L, mp::min_element_with<Cmp, C>>

emp::min_element_with_c<Cmp, int_t... xs> = mp::min_element_with<Cmp> ::f<number<xs>...>

auto emp::min_element_with_c_v<Cmp, int_t... xs> = mp::min_element_with<Cmp> ::f<number<xs>...>::value

auto emp::min_element_with_v<L, Cmp = mp::less<>, C = mp::identity> = emp::unpack<L, mp::min_element_with<Cmp, C>>::value

emp::min_element_with_xs<Cmp, xs...> = mp::min_element_with<Cmp>::f<xs...>

auto emp::min_element_with_xs_v<Cmp, xs...> = mp::min_element_with<Cmp> ::f<xs...>::value

emp::min_element_xs<xs...> = mp::min_element_with<>::f<xs...>

auto emp::min_element_xs_v<xs...> = mp::min_element_with<> ::f<xs...>::value

<jln/mp/algorithm/search.hpp>

Test file: test/src/algorithm/search.cpp

Return: sequence

Same search, but it stops when there is StopWhenAtLeast::value element or less.

Implementation
partial_drop_until_xs_c< -int_t{StopWhenAtLeast::value}-1, Pred, TC, FC>
Pre-condition
  • Pred::f<ys...> must return a boolean, 1 or 0

partial_search_before<StopWhenAtLeast, Pred, TC = listify, FC = clear<TC>>

Return: sequence

Same search_before, but it stops when there is StopWhenAtLeast::value element or less.

Implementation
partial_take_until_xs_c< -int_t{StopWhenAtLeast::value}-1, Pred, TC, FC>
Pre-condition
  • Pred::f<ys...> must return a boolean, 1 or 0

partial_search_before_c<std::size_t StopWhenAtLeast, Pred, TC = listify, FC = clear<TC>>

Implementation
partial_take_until_xs_c< -int_t{StopWhenAtLeast}-1, Pred, TC, FC>

partial_search_before_extended_by_n<StopWhenAtLeast, ExtendedByN, Pred, TC = listify, FC = clear<TC>>

Implementation
partial_take_until_extended_by_n_xs_c< -int_t{StopWhenAtLeast::value}-1, ExtendedByN::value, Pred, TC, FC>

partial_search_before_extended_by_n_c<std::size_t StopWhenAtLeast, std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>

Return: sequence

Same search_before, but it stops when there is StopWhenAtLeast::value element or less.

Implementation
partial_take_until_extended_by_n_xs_c< -int_t{StopWhenAtLeast}-1, ExtendedByN, Pred, TC, FC>
Pre-condition
  • Pred::f<ys...> must return a boolean, 1 or 0

partial_search_c<std::size_t StopWhenAtLeast, Pred, TC = listify, FC = clear<TC>>

Implementation
partial_drop_until_xs_c< -int_t{StopWhenAtLeast}-1, Pred, TC, FC>

search<Pred, TC = listify, FC = clear<TC>>

Return: sequence

Search the first sub-sequence that satisfy a predicate.

Implementation
drop_until_xs<Pred, TC, FC>
Pre-condition
  • Pred::f<ys...> must return a boolean, 1 or 0 Calls TC with all the elements from sub-sequence found at the end. If no element is found, FC is used with the whole sequence.

search_before<Pred, TC = listify, FC = clear<TC>>

Return: sequence

Search elements before sub-sequence that satisfy a predicate.

Implementation
take_until_xs<Pred, TC, FC>
Pre-condition
  • Pred::f<ys...> must return a boolean, 1 or 0 Calls TC with the elements from the beginning to sub-sequence found. If no element is found, FC is used with the whole sequence.

search_before_extended_by_n<ExtendedByN, Pred, TC = listify, FC = clear<TC>>

Return: sequence

Search elements before sub-sequence that satisfy a predicate.

Implementation
take_until_extended_by_n_xs<ExtendedByN, Pred, TC, FC>
Pre-condition
  • Pred::f<ys...> must return a boolean, 1 or 0 Calls TC with the elements from the beginning to sub-sequence found + ExtendedByN. If no element is found, FC is used with the whole sequence.

search_before_extended_by_n_c<std::size_t ExtendedByN, Pred, TC = listify, FC = clear<TC>>

Implementation
take_until_extended_by_n_xs_c<ExtendedByN, Pred, TC, FC>

emp::partial_search_before<L, StopWhenAtLeast, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_search_before<Pred, StopWhenAtLeast, TC, FC>>

emp::partial_search_before_c<L, std::size_t StopWhenAtLeast, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_search_before_c<StopWhenAtLeast, Pred, TC, FC>>

emp::partial_search_before_extended_by_n<L, StopWhenAtLeast, ExtendedByN, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_search_before_extended_by_n<StopWhenAtLeast, ExtendedByN, Pred, TC, FC>>

emp::partial_search_before_extended_by_n_c<L, std::size_t StopWhenAtLeast, std::size_t ExtendedByN, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_search_before_extended_by_n_c<StopWhenAtLeast, ExtendedByN, Pred, TC, FC>>

emp::partial_search_c<L, std::size_t StopWhenAtLeast, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::partial_search_c<StopWhenAtLeast, Pred, TC, FC>>

emp::search<L, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::search<Pred, TC, FC>>

emp::search_before<L, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::search_before<Pred, TC, FC>>

emp::search_before_extended_by_n<L, ExtendedByN, Pred, TC = mp::listify, FC = mp::clear<TC>> = emp::unpack<L, mp::search_before_extended_by_n<ExtendedByN, Pred, TC, FC>>

<jln/mp/algorithm/skip_until.hpp>

Test file: test/src/algorithm/skip_until.cpp

skip_inclusive_until<Pred, TC = listify, FC = TC>

Implementation
drop_inclusive_until<Pred, TC, clear<FC>>

skip_until<Pred, TC = listify, FC = TC>

Return: sequence

Remove the first elements of a sequence that does not satisfy a predicate.

Implementation
drop_until<Pred, TC, clear<FC>>
Pre-condition
  • Pred::f<x> must return a boolean, 1 or 0

skip_until_extended_by_n<ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
drop_until_extended_by_n_c< ExtendedByN::value, Pred, TC, clear<FC>>

skip_until_extended_by_n_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
drop_until_extended_by_n_c< ExtendedByN, Pred, TC, clear<FC>>

emp::skip_inclusive_until<L, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::skip_inclusive_until<Pred, TC, FC>>

emp::skip_until<L, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::skip_until<Pred, TC, FC>>

emp::skip_until_extended_by_n<L, ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::skip_until_extended_by_n<ExtendedByN, Pred, TC, FC>>

emp::skip_until_extended_by_n_c<L, std::size_t ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::skip_until_extended_by_n_c<ExtendedByN, Pred, TC, FC>>

<jln/mp/algorithm/skip_until_xs.hpp>

Test file: test/src/algorithm/skip_until_xs.cpp

partial_skip_inclusive_until_xs<OffsetEnd, Pred, TC = listify, FC = TC>

Implementation
partial_drop_inclusive_until_xs<OffsetEnd, Pred, TC, clear<FC>>

partial_skip_inclusive_until_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = TC>

Implementation
partial_drop_inclusive_until_xs_c<OffsetEnd, Pred, TC, clear<FC>>

partial_skip_until_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
partial_drop_until_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC, clear<FC>>

partial_skip_until_extended_by_n_xs_c<int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
partial_drop_until_extended_by_n_xs_c<OffsetEnd, ExtendedByN, Pred, TC, clear<FC>>

partial_skip_until_xs<OffsetEnd, Pred, TC = listify, FC = TC>

Implementation
partial_drop_until_xs<OffsetEnd, Pred, TC, clear<FC>>

partial_skip_until_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = TC>

Return: sequence

Same as drop_until_xs, but stop searching at position OffsetEnd.

OffsetEnd
a negative value start to end of sequence.
Implementation
partial_drop_until_xs_c<OffsetEnd, Pred, TC, clear<FC>>

skip_inclusive_until_xs<Pred, TC = listify, FC = TC>

Implementation
drop_inclusive_until_xs<Pred, TC, clear<FC>>

skip_until_extended_by_n_xs<ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
drop_until_extended_by_n_xs<ExtendedByN, Pred, TC, clear<FC>>

skip_until_extended_by_n_xs_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
drop_until_extended_by_n_xs_c<ExtendedByN, Pred, TC, clear<FC>>

skip_until_xs<Pred, TC = listify, FC = TC>

Return: sequence

Remove the first elements of a sequence that does not satisfy a predicate.

Implementation
drop_until_xs<Pred, TC, clear<FC>>
Pre-condition
  • Pred::f<ys...> must return a boolean, 1 or 0

emp::partial_skip_inclusive_until_xs<L, OffsetEnd, state, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_skip_inclusive_until_xs<OffsetEnd, Pred, TC, FC>>

emp::partial_skip_inclusive_until_xs_c<L, int_t OffsetEnd, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_skip_inclusive_until_xs_c<OffsetEnd, Pred, TC, FC>>

emp::partial_skip_until_extended_by_n_xs<L, OffsetEnd, ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::partial_drop_until_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC, clear<FC>>>

emp::partial_skip_until_extended_by_n_xs_c<L, int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::partial_drop_until_extended_by_n_xs_c<OffsetEnd, ExtendedByN, Pred, TC, clear<FC>>>

emp::partial_skip_until_xs<L, OffsetEnd, state, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_skip_until_xs<OffsetEnd, Pred, TC, FC>>

emp::partial_skip_until_xs_c<L, int_t OffsetEnd, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_skip_until_xs_c<OffsetEnd, Pred, TC, FC>>

emp::skip_inclusive_until_xs<L, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::skip_inclusive_until_xs<Pred, TC, FC>>

emp::skip_until_extended_by_n_xs<L, ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::drop_until_extended_by_n_xs<ExtendedByN, Pred, TC, clear<FC>>>

emp::skip_until_extended_by_n_xs_c<L, std::size_t ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::drop_until_extended_by_n_xs_c<ExtendedByN, Pred, TC, clear<FC>>>

emp::skip_until_xs<L, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::skip_until_xs<Pred, TC, FC>>

<jln/mp/algorithm/skip_while.hpp>

Test file: test/src/algorithm/skip_while.cpp

skip_inclusive_while<Pred, TC = listify, FC = TC>

Implementation
drop_inclusive_while<Pred, TC, clear<FC>>

skip_while<Pred, TC = listify, FC = TC>

Return: sequence

Remove the first elements of a sequence that satisfy a predicate.

Implementation
drop_while<Pred, TC, clear<FC>>
Pre-condition
  • Pred::f<x> must return a boolean, 1 or 0

skip_while_extended_by_n<ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
drop_while_extended_by_n_c< ExtendedByN::value, Pred, TC, clear<FC>>

skip_while_extended_by_n_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
drop_while_extended_by_n_c< ExtendedByN, Pred, TC, clear<FC>>

emp::skip_inclusive_while<L, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::skip_inclusive_while<Pred, TC, FC>>

emp::skip_while<L, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::skip_while<Pred, TC, FC>>

emp::skip_while_extended_by_n<L, ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::skip_while_extended_by_n<ExtendedByN, Pred, TC, FC>>

emp::skip_while_extended_by_n_c<L, std::size_t ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::skip_while_extended_by_n_c<ExtendedByN, Pred, TC, FC>>

<jln/mp/algorithm/skip_while_xs.hpp>

Test file: test/src/algorithm/skip_while_xs.cpp

partial_skip_inclusive_while_xs<OffsetEnd, Pred, TC = listify, FC = TC>

Implementation
partial_drop_inclusive_while_xs<OffsetEnd, Pred, TC, clear<FC>>

partial_skip_inclusive_while_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = TC>

Implementation
partial_drop_inclusive_while_xs_c<OffsetEnd, Pred, TC, clear<FC>>

partial_skip_while_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
partial_drop_while_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC, clear<FC>>

partial_skip_while_extended_by_n_xs_c<int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
partial_drop_while_extended_by_n_xs_c<OffsetEnd, ExtendedByN, Pred, TC, clear<FC>>

partial_skip_while_xs<OffsetEnd, Pred, TC = listify, FC = TC>

Implementation
partial_drop_while_xs<OffsetEnd, Pred, TC, clear<FC>>

partial_skip_while_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = TC>

Return: sequence

Same as skip_while_xs, but stop searching at position OffsetEnd.

OffsetEnd
a negative value start to end of sequence.
Implementation
partial_drop_while_xs_c<OffsetEnd, Pred, TC, clear<FC>>

skip_inclusive_while_xs<Pred, TC = listify, FC = TC>

Implementation
drop_inclusive_while_xs<Pred, TC, clear<FC>>

skip_while_extended_by_n_xs<ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
drop_while_extended_by_n_xs<ExtendedByN, Pred, TC, clear<FC>>

skip_while_extended_by_n_xs_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
drop_while_extended_by_n_xs_c<ExtendedByN, Pred, TC, clear<FC>>

skip_while_xs<Pred, TC = listify, FC = TC>

Return: sequence

Remove the first elements of a sequence that satisfy a predicate.

Implementation
drop_while_xs<Pred, TC, clear<FC>>
Pre-condition
  • Pred::f<ys...> must return a boolean, 1 or 0 Same as skip_while, but the predicate takes all the elements of the current position until the end of the list.

emp::partial_skip_inclusive_while_xs<L, OffsetEnd, state, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_skip_inclusive_while_xs<OffsetEnd, Pred, TC, FC>>

emp::partial_skip_inclusive_while_xs_c<L, int_t OffsetEnd, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_skip_inclusive_while_xs_c<OffsetEnd, Pred, TC, FC>>

emp::partial_skip_while_extended_by_n_xs<L, OffsetEnd, ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::partial_drop_while_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC, clear<FC>>>

emp::partial_skip_while_extended_by_n_xs_c<L, int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::partial_drop_while_extended_by_n_xs_c<OffsetEnd, ExtendedByN, Pred, TC, clear<FC>>>

emp::partial_skip_while_xs<L, OffsetEnd, state, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_skip_while_xs<OffsetEnd, Pred, TC, FC>>

emp::partial_skip_while_xs_c<L, int_t OffsetEnd, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_skip_while_xs_c<OffsetEnd, Pred, TC, FC>>

emp::skip_inclusive_while_xs<L, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::skip_inclusive_while_xs<Pred, TC, FC>>

emp::skip_while_extended_by_n_xs<L, ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::drop_while_extended_by_n_xs<ExtendedByN, Pred, TC, clear<FC>>>

emp::skip_while_extended_by_n_xs_c<L, std::size_t ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::drop_while_extended_by_n_xs_c<ExtendedByN, Pred, TC, clear<FC>>>

emp::skip_while_xs<L, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::skip_while_xs<Pred, TC, FC>>

<jln/mp/algorithm/take_until.hpp>

Test file: test/src/algorithm/take_until.cpp

take_inclusive_until<Pred, TC = listify, FC = TC>

Implementation
take_until_extended_by_n_c<1, Pred, TC, FC>

take_until<Pred, TC = listify, FC = TC>::f<xs...>

Return: sequence

Extract the first elements of a sequence that does not satisfy a predicate.

When an element satisfy the predicate, call TC with it and those before it. Otherwise FC is called on the whole sequence.

take_until_extended_by_n<ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
take_until_extended_by_n_c<ExtendedByN::value, Pred, TC, FC>

take_until_extended_by_n_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>::f<xs...>

Return: sequence

Extract the first plus at most ExtendedByN elements of a sequence that does not satisfy a predicate.

When an element satisfy the predicate, call TC with it and those before it plus at most ExtendedByN. Otherwise FC is called on the whole sequence.

Semantics
call<take_until_extended_by_n_c<2, is<number<2>>>,
  number<0>, number<1>, number<2>, number<3>, number<4>, number<5>>
//  predicate not satisfied ^ (+1)   ^ +2
==
list<number<0>, number<1>, number<2>, number<3>>

call<take_until_extended_by_n_c<2, is<number<5>>>,
  number<0>, number<1>, number<2>, number<3>, number<4>, number<5>>
//                                   predicate not satisfied ^ (+1)
==
list<number<0>, number<1>, number<2>, number<3>, number<4>, number<5>>

emp::take_inclusive_until<L, Pred, TC = mp::listify, FC = clear<TC>> = emp::unpack<L, mp::take_until_extended_by_n_c<1, Pred, TC, FC>>

emp::take_until<L, Pred, TC = mp::listify, FC = clear<TC>> = emp::unpack<L, mp::take_until<Pred, TC, FC>>

emp::take_until_extended_by_n<ExtendedByN, L, Pred, TC = mp::listify, FC = clear<TC>> = emp::unpack<L, mp::take_until_extended_by_n_c<ExtendedByN::value, Pred, TC, FC>>

emp::take_until_extended_by_n_c<std::size_t ExtendedByN, L, Pred, TC = mp::listify, FC = clear<TC>> = emp::unpack<L, mp::take_until_extended_by_n_c<ExtendedByN, Pred, TC, FC>>

<jln/mp/algorithm/take_until_xs.hpp>

Test file: test/src/algorithm/take_until_xs.cpp

partial_take_inclusive_until_xs<OffsetEnd, Pred, TC = listify, FC = TC>

Implementation
partial_take_until_extended_by_n_xs_c<OffsetEnd::value, 1, Pred, TC, FC>

partial_take_inclusive_until_xs_c<std::size_t OffsetEnd, Pred, TC = listify, FC = TC>

Implementation
partial_take_until_extended_by_n_xs_c<OffsetEnd, 1, Pred, TC, FC>

partial_take_until_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
partial_take_until_extended_by_n_xs_c<OffsetEnd::value, ExtendedByN::value, Pred, TC, FC>

partial_take_until_extended_by_n_xs_c<int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = TC>::f<xs...>

Return: sequence

Same as take_until_extended_by_n_xs_c, but stop searching at position OffsetEnd.

OffsetEnd
a negative value start to end of sequence.

partial_take_until_xs<OffsetEnd, Pred, TC = listify, FC = TC>

Implementation
partial_take_until_extended_by_n_xs_c<OffsetEnd::value, 0, Pred, TC, FC>

partial_take_until_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = TC>

Implementation
partial_take_until_extended_by_n_xs_c<OffsetEnd, 0, Pred, TC, FC>

take_inclusive_until_xs<Pred, TC = listify, FC = TC>

Implementation
take_until_extended_by_n_xs_c<1, Pred, TC, FC>

take_until_extended_by_n_xs<ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
take_until_extended_by_n_xs_c<ExtendedByN::value, Pred, TC, FC>

take_until_extended_by_n_xs_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>::f<xs...>

Return: sequence

Same as take_until_extended_by_n_c, but for take_until_xs.

take_until_xs<Pred, TC = listify, FC = TC>::f<xs...>

Return: sequence

Extracts the first elements of a sequence that does not satisfy a predicate.

emp::partial_take_inclusive_until_xs<L, OffsetEnd, state, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_take_inclusive_until_xs<OffsetEnd, Pred, TC, FC>>

emp::partial_take_inclusive_until_xs_c<L, int_t OffsetEnd, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_take_inclusive_until_xs_c<OffsetEnd, Pred, TC, FC>>

emp::partial_take_until_extended_by_n_xs<L, OffsetEnd, ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::partial_take_until_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC, FC>>

emp::partial_take_until_extended_by_n_xs_c<L, int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::partial_take_until_extended_by_n_xs_c<OffsetEnd, ExtendedByN, Pred, TC, FC>>

emp::partial_take_until_xs<L, OffsetEnd, state, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_take_until_xs<OffsetEnd, Pred, TC, FC>>

emp::partial_take_until_xs_c<L, int_t OffsetEnd, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_take_until_xs_c<OffsetEnd, Pred, TC, FC>>

emp::take_inclusive_until_xs<L, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::take_inclusive_until_xs<Pred, TC, FC>>

emp::take_until_extended_by_n_xs<L, ExtendedByN, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::take_until_extended_by_n_xs<ExtendedByN, Pred, TC, FC>>

emp::take_until_extended_by_n_xs_c<L, std::size_t ExtendedByN, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::take_until_extended_by_n_xs_c<ExtendedByN, Pred, TC, FC>>

emp::take_until_xs<L, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::take_until_xs<Pred, TC, FC>>

<jln/mp/algorithm/take_while.hpp>

Test file: test/src/algorithm/take_while.cpp

take_inclusive_while<Pred, TC = listify, FC = TC>

Implementation
take_while_extended_by_n_c<1, Pred, TC, FC>

take_while<Pred, TC = listify, FC = TC>::f<xs...>

Return: sequence

Extract the first elements of a sequence that satisfy a predicate.

When an element does not satisfy the predicate, call TC with it and those before it. Otherwise FC is called on the whole sequence.

take_while_extended_by_n<ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
take_while_extended_by_n_c<ExtendedByN::value, Pred, TC, FC>

take_while_extended_by_n_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>::f<xs...>

Return: sequence

Extract the first plus at most ExtendedByN elements of a sequence that satisfy a predicate.

When an element satisfy the predicate, call TC with it and those before it plus at most ExtendedByN. Otherwise FC is called on the whole sequence.

Semantics
call<take_while_extended_by_n_c<2, is_not<number<2>>>,
  number<0>, number<1>, number<2>, number<3>, number<4>, number<5>>
//  predicate not satisfied ^ (+1)   ^ +2
==
list<number<0>, number<1>, number<2>, number<3>>

call<take_while_extended_by_n_c<2, is_not<number<5>>>,
  number<0>, number<1>, number<2>, number<3>, number<4>, number<5>>
//                                   predicate not satisfied ^ (+1)
==
list<number<0>, number<1>, number<2>, number<3>, number<4>, number<5>>

emp::take_inclusive_while<L, Pred, TC = mp::listify, FC = clear<TC>> = emp::unpack<L, mp::take_while_extended_by_n_c<1, Pred, TC, FC>>

emp::take_while<L, Pred, TC = mp::listify, FC = clear<TC>> = emp::unpack<L, mp::take_while<Pred, TC, FC>>

emp::take_while_extended_by_n<ExtendedByN, L, Pred, TC = mp::listify, FC = clear<TC>> = emp::unpack<L, mp::take_while_extended_by_n_c<ExtendedByN::value, Pred, TC, FC>>

emp::take_while_extended_by_n_c<std::size_t ExtendedByN, L, Pred, TC = mp::listify, FC = clear<TC>> = emp::unpack<L, mp::take_while_extended_by_n_c<ExtendedByN, Pred, TC, FC>>

<jln/mp/algorithm/take_while_xs.hpp>

Test file: test/src/algorithm/take_while_xs.cpp

partial_take_inclusive_while_xs<OffsetEnd, Pred, TC = listify, FC = TC>

Implementation
partial_take_while_extended_by_n_xs_c<OffsetEnd::value, 1, Pred, TC, FC>

partial_take_inclusive_while_xs_c<std::size_t OffsetEnd, Pred, TC = listify, FC = TC>

Implementation
partial_take_while_extended_by_n_xs_c<OffsetEnd, 1, Pred, TC, FC>

partial_take_while_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
partial_take_while_extended_by_n_xs_c<OffsetEnd::value, ExtendedByN::value, Pred, TC, FC>

partial_take_while_extended_by_n_xs_c<int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = TC>::f<xs...>

Return: sequence

Same as take_while_extended_by_n_xs_c, but stop searching at position OffsetEnd.

OffsetEnd
a negative value start to end of sequence.

partial_take_while_xs<OffsetEnd, Pred, TC = listify, FC = TC>

Implementation
partial_take_while_extended_by_n_xs_c<OffsetEnd::value, 0, Pred, TC, FC>

partial_take_while_xs_c<int_t OffsetEnd, Pred, TC = listify, FC = TC>

Implementation
partial_take_while_extended_by_n_xs_c<OffsetEnd, 0, Pred, TC, FC>

take_inclusive_while_xs<Pred, TC = listify, FC = TC>

Implementation
take_while_extended_by_n_xs_c<1, Pred, TC, FC>

take_while_extended_by_n_xs<ExtendedByN, Pred, TC = listify, FC = TC>

Implementation
take_while_extended_by_n_xs_c<ExtendedByN::value, Pred, TC, FC>

take_while_extended_by_n_xs_c<std::size_t ExtendedByN, Pred, TC = listify, FC = TC>::f<xs...>

Return: sequence

Same as take_while_extended_by_n_c, but for take_while_xs.

take_while_xs<Pred, TC = listify, FC = TC>::f<xs...>

Return: sequence

Extracts the first elements of a sequence that satisfy a predicate.

emp::partial_take_inclusive_while_xs<L, OffsetEnd, state, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_take_inclusive_while_xs<OffsetEnd, Pred, TC, FC>>

emp::partial_take_inclusive_while_xs_c<L, int_t OffsetEnd, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_take_inclusive_while_xs_c<OffsetEnd, Pred, TC, FC>>

emp::partial_take_while_extended_by_n_xs<L, OffsetEnd, ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::partial_take_while_extended_by_n_xs<OffsetEnd, ExtendedByN, Pred, TC, FC>>

emp::partial_take_while_extended_by_n_xs_c<L, int_t OffsetEnd, std::size_t ExtendedByN, Pred, TC = listify, FC = TC> = emp::unpack<L, mp::partial_take_while_extended_by_n_xs_c<OffsetEnd, ExtendedByN, Pred, TC, FC>>

emp::partial_take_while_xs<L, OffsetEnd, state, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_take_while_xs<OffsetEnd, Pred, TC, FC>>

emp::partial_take_while_xs_c<L, int_t OffsetEnd, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::partial_take_while_xs_c<OffsetEnd, Pred, TC, FC>>

emp::take_inclusive_while_xs<L, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::take_inclusive_while_xs<Pred, TC, FC>>

emp::take_while_extended_by_n_xs<L, ExtendedByN, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::take_while_extended_by_n_xs<ExtendedByN, Pred, TC, FC>>

emp::take_while_extended_by_n_xs_c<L, std::size_t ExtendedByN, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::take_while_extended_by_n_xs_c<ExtendedByN, Pred, TC, FC>>

emp::take_while_xs<L, Pred, TC = mp::listify, FC = TC> = emp::unpack<L, mp::take_while_xs<Pred, TC, FC>>

<jln/mp/algorithm/upper_bound.hpp>

Test file: test/src/algorithm/upper_bound.cpp

upper_bound<x, Cmp = less<>, TC = listify, FC = TC>

Return: sequence

Finds first element that is greater that x.

Invokes TC with all the elements since the one found at the end. If no element is found, FC is used.

Implementation
lower_bound<x, flip<tee<Cmp, not_<>>>, TC, FC>
Pre-condition

upper_bound_c<int_t x, Cmp = less<>, TC = listify, FC = TC>

Implementation
upper_bound<number<x>, Cmp, TC, FC>

upper_bound_than<x, TC = listify, FC = TC>

Implementation
upper_bound<x, less<>, TC, FC>

upper_bound_than_c<int_t x, TC = listify, FC = TC>

Implementation
upper_bound<number<x>, less<>, TC, FC>

emp::upper_bound<L, x, Cmp = mp::less<>, TC = mp::listify, FC = TC> = emp::unpack<L, mp::upper_bound<x, Cmp, TC, FC>>

emp::upper_bound_c<L, int_t x, Cmp = mp::less<>, TC = mp::listify, FC = TC> = emp::unpack<L, mp::upper_bound<mp::number<x>, Cmp, TC, FC>>

emp::upper_bound_than<L, x, TC = mp::listify, FC = TC> = emp::unpack<L, mp::upper_bound<x, mp::less<>, TC, FC>>

emp::upper_bound_than_c<L, int_t x, TC = mp::listify, FC = TC> = emp::unpack<L, mp::upper_bound<mp::number<x>, mp::less<>, TC, FC>>

Group: set

<jln/mp/set/set_contains.hpp>

Test file: test/src/set/set_contains.cpp

set_all_contains<x, C = identity>::f<Sets...>

Return: true_ / false_

Checks if x is an element of all set Sets.

Implementation
C::f<number<emp::set_all_contains_v<x, Sets...>>>
Pre-condition

set_any_contains<x, C = identity>::f<Sets...>

Return: true_ / false_

Checks if x is an element of any set Sets.

Implementation
C::f<number<emp::set_any_contains_v<x, Sets...>>>
Pre-condition

set_contains<x, C = identity>::f<xs...>

Return: true_ / false_

Checks if x is an element of the set whose elements are xs.

Implementation
C::f<number<emp::set_contains_xs_v<x, xs...>>>
Pre-condition

set_none_contains<x, C = identity>::f<Sets...>

Return: true_ / false_

Checks if x is an element of none set Sets.

Implementation
C::f<number<!emp::set_any_contains_v<x, Sets...>>>
Pre-condition

set_not_contains<x, C = identity>

Return: true_ / false_

Checks if x is not an element of the set whose elements are xs.

Implementation
set_contains<x, not_<C>>
Pre-condition

emp::set_all_contains<x, Sets...> = number<set_all_contains_v<x, Sets...>>

bool emp::set_all_contains_v<x, Sets...> = /*...*/

emp::set_any_contains<x, Sets...> = number<set_any_contains_v<x, Sets...>>

bool emp::set_any_contains_v<x, Sets...> = /*...*/

emp::set_contains<Set, x> = number<set_contains_v<Set, x>>

bool emp::set_contains_v<Set, x> = /*...*/

bool emp::set_contains_xs_v<x, xs...> = /*...*/

emp::set_none_contains<x, Sets...> = number<!set_any_contains_v<x, Sets...>>

bool emp::set_none_contains_v<x, Sets...> = !set_any_contains_v<x, Sets...>

emp::set_not_contains<Set, x> = number<!set_contains_v<Set, x>>

<jln/mp/set/set_difference.hpp>

Test file: test/src/set/set_difference.cpp

set_difference<C = listify>::f<L, Sets...>

Return: set

Removes the elements of the list L that appear in any of the sets Sets.

Pre-condition
Post-condition

emp::set_difference<L, Sets...> = /*...*/

<jln/mp/set/set_find.hpp>

Test file: test/src/set/set_find.cpp

set_find<x, TC = identity, FC = always<na>>::f<xs...>

Return: value

Finds the element x in the set.

Calls TC with element found. If no element is found, FC is used with the whole set.

Pre-condition

set_find_or<x, FT>

Implementation
set_find<x, identity, always<FT>>

set_find_or_else<x, FC>

Implementation
set_find<x, identity, FC>

emp::set_find<L, x, TC = mp::identity, FC = mp::always<na>> = emp::unpack<L, mp::set_find<x, TC, FC>>

emp::set_find_or<L, x, FT> = emp::unpack<L, mp::set_find<x, mp::identity, mp::always<FT>>>

emp::set_find_or_else<L, x, FC> = emp::unpack<L, mp::set_find<x, mp::identity, FC>>

<jln/mp/set/set_intersection.hpp>

Test file: test/src/set/set_intersection.cpp

set_intersection<C = listify>::f<L, Sets...>

Return: set

Returns a set that contains the elements that occur in all of the sets Sets.

Pre-condition
Post-condition

emp::set_intersection<L, Sets...> = /*...*/

<jln/mp/set/set_push_back.hpp>

Test file: test/src/set/set_push_back.cpp

set_push_back<x, C = listify>::f<xs...>

Return: set

Appends x to the end of the set whose elements are xs if not already in xs.

Pre-condition
Post-condition

emp::set_push_back<Set, x> = /*...*/

<jln/mp/set/set_push_back_elements.hpp>

Test file: test/src/set/set_push_back_elements.cpp

set_push_back_elements<C = listify>::f<Set, xs...>

Return: set

Appends to the end of the set Set the elements of xs which are not already in Set.

Pre-condition
Post-condition
Semantics

Equivalent to

fold<cfe<emp::set_push_back>>::f<xs...>

emp::set_push_back_elements<Set, xs...> = mp::set_push_back_elements<>::f<Set, xs...>

<jln/mp/set/set_push_front.hpp>

Test file: test/src/set/set_push_front.cpp

set_push_front<x, C = listify>::f<xs...>

Return: set

Appends x to the beginning of the set whose elements are xs if not already in xs.

Pre-condition
Post-condition

emp::set_push_front<Set, x> = /*...*/

<jln/mp/set/set_push_front_elements.hpp>

Test file: test/src/set/set_push_front_elements.cpp

set_push_front_elements<C = listify>::f<Set, xs...>

Return: set

Appends to the beginning of the set Set the elements of xs which are not already in Set.

Pre-condition
Post-condition
Semantics

Equivalent to

fold<cfe<emp::set_push_front>>::f<xs...>

emp::set_push_front_elements<Set, xs...> = mp::set_push_front_elements<>::f<Set, xs...>

<jln/mp/set/set_union.hpp>

Test file: test/src/set/set_union.cpp

set_union<C = listify>::f<Set, Ls...>

Return: set

Appends to the end of the set Set the elements of Ls which are not already in Set.

Implementation
emp::unpack<join<>::f<Ls...>, set_push_back_elements<C>, Set>
Pre-condition
Post-condition

emp::set_union<Set, Ls...> = mp::set_union<>::f<Set, Ls...>

Group: trait

<jln/mp/utility/alignof.hpp>

Test file: test/src/utility/alignof.cpp

alignof_<C = identity>::f<x>

Return: number

Wrapper for alignof keyword

Implementation
C::f<number<alignof(x)>>

emp::alignof_<x> = number<alignof(x)>

<jln/mp/utility/stl_traits.hpp>

Test file: test/src/utility/stl_traits.cpp

traits::emp::aligned_storage<Len, Alignment...>

Implementation
std::aligned_storage< Len::value, Alignment::value...>::type

traits::aligned_storage<C = identity>::f<Len, Alignment...>

Implementation
C::f<std::aligned_storage<Len::value, Alignment::value...>::type>

traits::emp::aligned_union<len, xs...>

Implementation
std::aligned_union<len::value, xs...>::type

traits::aligned_union<C = identity>::f<len, xs...>

Implementation
C::f<std::aligned_union<len::value, xs...>::type>

traits::extent<C = identity>::f<x, i>

Implementation
C::f<std::extent<x, i::value>::type>

traits::emp::extent<x, i = number<0>>

Implementation
std::extent<x, i::value>::type

traits::emp::is_nothrow_convertible<xs...>

Implementation
std::bool_constant<std::is_nothrow_convertible_v<xs...>>

traits::is_nothrow_convertible<C = identity>::f<xs...>

Implementation
C::f<std::bool_constant<std::is_nothrow_convertible_v<xs...>>>

traits::is_nothrow_convertible<identity>::f<xs...>

Implementation
std::bool_constant<std::is_nothrow_convertible_v<xs...>>

<jln/mp/utility/has_type.hpp>

Test file: test/src/utility/has_type.cpp

has_type<C = identity>::f<x>

Return: true_ / false_

Checks whether x has a type member.

emp::has_type<x> = /*...*/

bool emp::has_type_v<x> = /*...*/

<jln/mp/utility/has_value_type.hpp>

Test file: test/src/utility/has_value_type.cpp

has_value_type<C = identity>::f<x>

Return: true_ / false_

Checks whether x has a type member.

emp::has_value_type<x> = /*...*/

bool emp::has_value_type_v<x> = /*...*/

<jln/mp/utility/is_specialization_of.hpp>

Test file: test/src/utility/is_specialization_of.cpp

is_specialization_of<template<class...> Tpl, C = identity>::f<x>

Return: true_ / false_

Checks whether x is Tpl<xs...>

Implementation
C::f<number<emp::is_specialization_of_v<Tpl, x>>>

emp::is_specialization_of<template<class...> Tpl, x> = number<emp::is_specialization_of_v<Tpl, x>>

bool emp::is_specialization_of_v<template<class...> Tpl, T> = false

<jln/mp/utility/lazy_void.hpp>

Test file: test/src/utility/lazy_void.cpp

lazy_void

Equivalent to std::void_t, but always resolved in a lazy way.

This fixes the ambiguity encountered with clang for the following code:

template<class T, class = void> struct Impl;
template<class T> struct Impl<T, std::void_t<typename T::foo>> {};
template<class T> struct Impl<T, std::void_t<typename T::bar>> {}; // redefinition of Impl<T, void>

lazy_void can be replaced with always<void>::f when the macro JLN_MP_FORCE_LAZY_ALIAS is set to 0.

#define JLN_MP_LAZY_VOID(...)

Equivalent to emp::lazy_void<xs...> while minimizing template instantiation.

emp::lazy_void<xs...> = void

<jln/mp/utility/sizeof.hpp>

Test file: test/src/utility/sizeof.cpp

sizeof_<C = identity>::f<x>

Return: number

Wrapper for sizeof keyword

Implementation
C::f<number<sizeof(x)>>

emp::sizeof_<x> = number<sizeof(x)>

<jln/mp/utility/type.hpp>

Test file: test/src/utility/type.cpp

type_<C = identity>::f<x>

Return: value

Function for x::type.

Implementation
C::f<x::type>

emp::type_<x> = x::type

<jln/mp/utility/value_type.hpp>

Test file: test/src/utility/value_type.cpp

value_type<C = identity>::f<x>

Return: value

Function for x::value_type.

Implementation
C::f<x::value_type>

value_type<identity>::f<x>

Implementation
x::value_type

emp::value_type<x> = x::value_type

Group: utility

<jln/mp/utility/always.hpp>

Test file: test/src/utility/always.cpp

always<x, C = identity>::f<xs...>

Return: value

Always evaluate at an arbitrary value.

Implementation
C::f<x>
Post-condition
  • result = x

<jln/mp/utility/conditional.hpp>

Test file: test/src/utility/conditional.cpp

conditional<bool_>

Implementation
conditional_c<bool(bool_::value)>

conditional_c<bool>

conditional_c<false>::f<true_value, false_value>

Implementation
false_value

conditional_c<true>::f<true_value, false_value>

Implementation
true_value

emp::conditional<bool_, true_value, false_value> = mp::conditional_c<bool(bool_::value)> ::f<true_value, false_value>

emp::conditional_c<bool bool_, true_value, false_value> = mp::conditional_c<bool_> ::f<true_value, false_value>

<jln/mp/utility/make_index.hpp>

Test file: test/src/utility/make_index.cpp

default_make_index_tag

make_index<C = identity>

Return: number

Generates a unique index per type.

make_index_for<Tag = default_make_index_tag, C = identity>::f<T>

Return: number

Generates a unique index per type for a specified tag.

Implementation
C::f<number<emp::make_index_of_v<T, Tag>>>

emp::make_index_of<T, Tag = default_make_index_tag> = number<make_index_of_v<T, Tag>>

int emp::make_index_of_v<T, Tag = default_make_index_tag> = /*...*/

int emp::next_index_v<Tag = default_make_index_tag, auto v = []{}> = /*...*/

emp::type_of_index<int idx, Tag = default_make_index_tag> = /*...*/

<jln/mp/utility/make_id.hpp>

Test file: test/src/utility/make_id.cpp

default_make_id_tag

id_info<int const* id>

id_t

Implementation
int const*

make_id<C = identity>

Return: id_info

Generates a unique type id per type.

Implementation
make_id_for<default_make_id_tag, C>

make_id_for<Tag = default_make_id_tag, C = identity>::f<T>

Return: id_info

Generates a unique type id per type for a specified tag.

Implementation
C::f<id_info<emp::id_of_v<T, Tag>>>

emp::id_of<T, Tag = default_make_id_tag> = id_info<id_of_v<T, Tag>>

int const* emp::id_of_info_v<id_info> = /*...*/

int const* emp::id_of_v<T, Tag = default_make_id_tag> = &meta::meta_t<T, Tag>::id

emp::type_of<int const* id> = decltype( meta_from_info(JLN_MP_MK_ID_INFO(id)))::type

emp::type_of_info<id_info> = decltype( meta_from_info(static_cast<id_info*>(nullptr)))::type

<jln/mp/utility/inherit.hpp>

Test file: test/src/utility/inherit.cpp

inherit<Bases...>

Class that inherits all Bases types.

This used with JLN_MP_IS_BASE_OF() makes a really fast version of set_contains.

class A {};
class B {};
class C {};
using set = inherit<A, B, C>;

using T = ...;
if constexpr (JLN_MP_IS_BASE_OF(T, set)) {
  ...
}

inherit_safely<Bases...>

Class that inherits all Bases types wrapped in a list<> type.

class A;
class B;
class C;
using set = inherit_safely<A, B, C>;

using T = ...;
if constexpr (JLN_MP_IS_BASE_OF(list<T>, set)) {
  ...
}

<jln/mp/utility/is.hpp>

Test file: test/src/utility/is.cpp

is<T, C = identity>::f<x>

Return: true_ / false_

Implementation
C::f<number<std::is_same_v<T, x>>>

<jln/mp/utility/is_base_of.hpp>

Test file: test/src/utility/is_base_of.cpp

is_base_of<Derived, C = identity>::f<x>

Return: true_ / false_

Wrapper for JLN_MP_IS_BASE_OF() / std::is_base_of

Implementation
C::f<number<JLN_MP_IS_BASE_OF(x, Derived)>>

#define JLN_MP_IS_BASE_OF(Base, Derived)

Uses a compiler builtin or std::is_base_if_v.

Note: the real signature takes a var args.

emp::is_base_of<Base, Derived> = number<JLN_MP_IS_BASE_OF(Base, Derived)>

bool emp::is_base_of_v<Base, Derived> = JLN_MP_IS_BASE_OF(Base, Derived)

<jln/mp/utility/is_not.hpp>

Test file: test/src/utility/is_not.cpp

is_not<T, C = identity>

Return: true_ / false_

Implementation
is<T, not_<C>>

<jln/mp/utility/iterate.hpp>

Test file: test/src/utility/iterate.cpp

iterate<n, F, C = identity>

Return: value

Apply a function n times to its argument.

Implementation
iterate_c<n::value, F, C>

iterate_c<uint_t n, F, C = identity>::f<x>

Return: value

Apply a function n times to its argument.

emp::iterate<L, n, F, C = mp::identity> = emp::unpack<L, mp::iterate<n, F, C>>

emp::iterate_c<L, uint_t n, F, C = mp::identity> = emp::unpack<L, mp::iterate_c<n, F, C>>

<jln/mp/utility/random.hpp>

Test file: test/src/utility/random.cpp

random<C = identity, auto v = []{}>

Implementation
random_for<default_make_index_tag, C, v>

random_for<Tag = default_make_index_tag, C = identity, auto = []{}>::f<xs...>

Return: number

Generate a random number for a specified tag on each call with different xs.

#define JLN_MP_RANDOM_SEED_TIME

Less than 0 to not rely on the __TIME__ macro (default) ; 0 for use __TIME__ macro as seed ; greater than 0 for used this value as a replacement of __TIME__ macro.

#define JLN_MP_RANDOM_SEED_W

W value for the seed of random.

#define JLN_MP_RANDOM_SEED_Z

Z value for the seed of random.

emp::random<Tag = default_make_index_tag, auto v = []{}> = /*...*/

emp::random_of<T, Tag = default_make_index_tag, auto v = []{}> = /*...*/

unsigned emp::random_of_v<T, Tag = default_make_index_tag> = /*...*/

unsigned emp::random_v<Tag = default_make_index_tag, auto v = []{}> = /*...*/

<jln/mp/utility/rewrap_unpack.hpp>

Test file: test/src/utility/rewrap_unpack.cpp

rewrap_unpack<C>::f<L, xs...>

Return: sequence

Rewrap result of unpack<C> in the same type as L.

Semantics
rewrap_unpack<C>::f<L, xs...>
==
unpack<emp::wraper<L>>::f<unpack<C>::f<L, xs...>>

rewrap_unpack<remove<b>>::f<std::tuple<a, b, c>, d, e>
==
std::tuple<d, e, a, c>

rewrap_unpack_append<C>::f<L, xs...>

Return: sequence

Rewrap result of unpack_append<C> in the same type as L.

Semantics
rewrap_unpack_append<C>::f<L, xs...>
==
unpack<emp::wraper<L>>::f<unpack_append<C>::f<L, xs...>>

rewrap_unpack<remove<b>>::f<std::tuple<a, b, c>, d, e>
==
std::tuple<a, c, d, e>

emp::rewrap_unpack<L, C, xs...> = /*...*/

emp::rewrap_unpack_append<L, C, xs...> = /*...*/

<jln/mp/utility/unpack.hpp>

Test file: test/src/utility/unpack.cpp

unpack<C>::f<seq, xs...>

Return: sequence

Turns a typelist into a sequence of those types.

Implementation
emp::unpack<seq, C, xs...>
Semantics
unpack<F>::f<typelist<xs...>, ys...> == F::f<ys..., xs...>

unpack_append<C>::f<seq, xs...>

Return: sequence

Turns a typelist into a sequence of those types.

Semantics
unpack_append<F>::f<typelist<xs...>, ys...> == F::f<xs..., ys...>

unpack_append_v<C>::f<seq, xs...>

Return: sequence

Turns a typelist into a sequence of those types.

Semantics
unpack_append<F>::f<valuelist<xs...>, ys...> == F::f<xs..., ys...>

unpack_v<C>::f<seq, xs...>

Return: sequence

Turns a typelist into a sequence of those types.

Semantics
unpack<F>::f<valuelist<xs...>, ys...> == F::f<ys..., xs...>

emp::unpack<L, C, xs...> = emp::unpack<L, C, xs...>

emp::unpack_append<L, C, xs...> = /*...*/

emp::unpack_append_c<L, C, int_t... xs> = /*...*/

emp::unpack_append_c_v<L, C, int_t... xs> = /*...*/

emp::unpack_append_v<L, C, xs...> = /*...*/

emp::unpack_c<L, C, int_t... xs> = emp::unpack<L, C, number<xs>...>

emp::unpack_c_v<L, C, int_t... xs> = /*...*/

emp::unpack_v<L, C, xs...> = /*...*/

<jln/mp/utility/wrapper.hpp>

Test file: test/src/utility/wrapper.cpp

emp::rewrap<L, xs...> = wrapper<L>::f<xs...>

emp::wrapper<L> = /*...*/

Group: value

<jln/mp/value/as_val.hpp>

Test file: test/src/value/as_val.cpp

as_val<C = identity>::f<x>

Return: true_ / false_

Converts x to val.

Implementation
C::f<val<x::value>>
Pre-condition

emp::as_val<x, C = mp::identity> = mp::as_val<C>::f<x>

<jln/mp/value/has_value.hpp>

Test file: test/src/value/has_value.cpp

has_value<C = identity>::f<x>

Return: true_ / false_

Checks whether x has a value member.

emp::has_value<x> = /*...*/

bool emp::has_value_v<x> = /*...*/

<jln/mp/value/is_val.hpp>

Test file: test/src/value/is_val.cpp

is_val<C = identity>::f<x>

Return: true_ / false_

Checks whether x is a val.

Implementation
C::f<number<emp::is_val_v<x>>>

emp::is_val<x> = number<emp::is_val_v<x>>

bool emp::is_val_v<x> = false

<jln/mp/value/val.hpp>

Test file: test/src/value/val.cpp

typed_value<T, T v>

Implementation
val<v>

val<auto v>::value

Implementation
v

value_from<T>

Implementation
val<T::value>

<jln/mp/value/operators.hpp>

Test file: test/src/value/operators.cpp

val_add<C = identity>::f<xs...>

Implementation
C::f<val<(xs::value + ...)>>

val_add0<C = identity>

Implementation
if_<size<>, val_add<C>, always<val<0>, C>>

val_and<C = identity>::f<xs...>

Implementation
C::f<val<(xs::value && ... && true)>>

val_bit_and<C = identity>::f<xs...>

Implementation
C::f<val<(xs::value & ...)>>

val_bit_and0<C = identity>

Implementation
if_<size<>, val_bit_and<C>, always<val<0>, C>>

val_bit_not<C = identity>::f<x>

Implementation
C::f<val<(~x::value)>>

val_bit_or<C = identity>::f<xs...>

Implementation
C::f<val<(xs::value | ...)>>

val_bit_or0<C = identity>

Implementation
if_<size<>, val_bit_or<C>, always<val<0>, C>>

val_dec<C = identity>::f<x>

Implementation
C::f<val<(x::value-1)>>

val_div<C = identity>::f<xs...>

Implementation
C::f<val<(... / xs::value)>>

val_div0<C = identity>

Implementation
if_<size<>, val_div<C>, always<val<0>, C>>

val_div1<C = identity>

Implementation
if_<size<>, val_div<C>, always<val<1>, C>>

val_equal<C = identity>::f<x, y>

Implementation
C::f<val<(x::value == y::value)>>

val_equal_to<N, C = identity>

Implementation
push_back<N, val_equal<C>>

val_equal_to_c<auto x, C = identity>

Implementation
val_equal_to<val<x>, C>

val_greater<C = identity>::f<x, y>

Implementation
C::f<val<(x::value> y::value)>>

val_greater_equal<C = identity>::f<x, y>

Implementation
C::f<val<(x::value>= y::value)>>

val_greater_equal_than<N, C = identity>

Implementation
push_back<N, val_greater_equal<C>>

val_greater_equal_than_c<auto x, C = identity>

Implementation
val_greater_equal_than<val<x>, C>

val_greater_than<N, C = identity>

Implementation
push_back<N, val_greater<C>>

val_greater_than_c<auto x, C = identity>

Implementation
val_greater_than<val<x>, C>

val_inc<C = identity>::f<x>

Implementation
C::f<val<(x::value+1)>>

val_left_add<C = identity>::f<xs...>

Implementation
C::f<val<(... + xs::value)>>

val_left_add0<C = identity>

Implementation
if_<size<>, val_left_add<C>, always<val<0>, C>>

val_left_and<C = identity>::f<xs...>

Implementation
C::f<val<(true && ... && xs::value)>>

val_left_bit_and<C = identity>::f<xs...>

Implementation
C::f<val<(... & xs::value)>>

val_left_bit_and0<C = identity>

Implementation
if_<size<>, val_bit_and<C>, always<val<0>, C>>

val_left_bit_or<C = identity>::f<xs...>

Implementation
C::f<val<(... | xs::value)>>

val_left_bit_or0<C = identity>

Implementation
if_<size<>, val_left_bit_or<C>, always<val<0>, C>>

val_left_mul<C = identity>::f<xs...>

Implementation
C::f<val<(... * xs::value)>>

val_left_mul0<C = identity>

Implementation
if_<size<>, val_left_mul<C>, always<val<0>, C>>

val_left_mul1<C = identity>

Implementation
if_<size<>, val_left_mul<C>, always<val<1>, C>>

val_left_or<C = identity>::f<xs...>

Implementation
C::f<val<(false || ... || xs::value)>>

val_left_xor<C = identity>::f<xs...>

Implementation
C::f<val<(... ^ xs::value)>>

val_left_xor0<C = identity>

Implementation
if_<size<>, val_left_xor<C>, always<val<0>, C>>

val_less<C = identity>::f<x, y>

Implementation
C::f<val<(x::value < y::value)>>

val_less_equal<C = identity>::f<x, y>

Implementation
C::f<val<(x::value <= y::value)>>

val_less_equal_than<N, C = identity>

Implementation
push_back<N, val_less_equal<C>>

val_less_equal_than_c<auto x, C = identity>

Implementation
val_less_equal_than<val<x>, C>

val_less_than<N, C = identity>

Implementation
push_back<N, val_less<C>>

val_less_than_c<auto x, C = identity>

Implementation
val_less_than<val<x>, C>

val_lshift<C = identity>::f<xs...>

Implementation
C::f<val<(... << xs::value)>>

val_lshift0<C = identity>

Implementation
if_<size<>, val_lshift<C>, always<val<0>, C>>

val_mod<C = identity>::f<xs...>

Implementation
C::f<val<(... % xs::value)>>

val_mod0<C = identity>

Implementation
if_<size<>, val_mod<C>, always<val<0>, C>>

val_mod1<C = identity>

Implementation
if_<size<>, val_mod<C>, always<val<1>, C>>

val_mul<C = identity>::f<xs...>

Implementation
C::f<val<(xs::value * ...)>>

val_mul0<C = identity>

Implementation
if_<size<>, val_mul<C>, always<val<0>, C>>

val_mul1<C = identity>

Implementation
if_<size<>, val_mul<C>, always<val<1>, C>>

val_neg<C = identity>::f<x>

Implementation
C::f<val<(-x::value)>>

val_not<C = identity>::f<x>

Implementation
C::f<val<(!x::value)>>

val_not_equal<C = identity>::f<x, y>

Implementation
C::f<val<(x::value != y::value)>>

val_not_equal_to<N, C = identity>

Implementation
push_back<N, val_not_equal<C>>

val_not_equal_to_c<auto x, C = identity>

Implementation
val_not_equal_to<val<x>, C>

val_or<C = identity>::f<xs...>

Implementation
C::f<val<(xs::value || ... || false)>>

val_rshift<C = identity>::f<xs...>

Implementation
C::f<val<(...>> xs::value)>>

val_rshift0<C = identity>

Implementation
if_<size<>, val_rshift<C>, always<val<0>, C>>

val_sub<C = identity>::f<xs...>

Implementation
C::f<val<(... - xs::value)>>

val_sub0<C = identity>

Implementation
if_<size<>, val_sub<C>, always<val<0>, C>>

val_unary_plus<C = identity>::f<x>

Implementation
C::f<val<(+x::value)>>

val_xor<C = identity>::f<xs...>

Implementation
C::f<val<(xs::value ^ ...)>>

val_xor0<C = identity>

Implementation
if_<size<>, val_xor<C>, always<val<0>, C>>

emp::val_add<xs...> = val<(xs::value + ...)>

emp::val_add0<xs...> = mp::val_add0<>::f<xs...>

emp::val_add0_c<auto... xs> = val_add_c<xs..., 0>

auto emp::val_add0_c_v<auto... xs> = val_add_c_v<xs..., 0>

emp::val_add0_seq<L, C = mp::identity> = emp::unpack<L, mp::val_add0<C>>

auto emp::val_add0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_add0<C>>::value

auto emp::val_add0_v<xs...> = mp::val_add0<>::f<xs...>::value

emp::val_add_c<auto... xs> = val<(xs + ...)>

auto emp::val_add_c_v<auto... xs> = (xs + ...)

emp::val_add_seq<L, C = mp::identity> = emp::unpack<L, mp::val_add<C>>

auto emp::val_add_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_add<C>>::value

auto emp::val_add_v<xs...> = (xs::value + ...)

emp::val_and<xs...> = val<(xs::value && ... && true)>

emp::val_and_c<auto... xs> = val<(xs && ... && true)>

auto emp::val_and_c_v<auto... xs> = (xs && ... && true)

emp::val_and_seq<L, C = mp::identity> = emp::unpack<L, mp::val_and<C>>

auto emp::val_and_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_and<C>>::value

auto emp::val_and_v<xs...> = (xs::value && ... && true)

emp::val_bit_and<xs...> = val<(xs::value & ...)>

emp::val_bit_and0<xs...> = mp::val_bit_and0<>::f<xs...>

emp::val_bit_and0_c<auto... xs> = /*...*/

auto emp::val_bit_and0_c_v<auto... xs> = /*...*/

emp::val_bit_and0_seq<L, C = mp::identity> = emp::unpack<L, mp::val_bit_and0<C>>

auto emp::val_bit_and0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_bit_and0<C>>::value

auto emp::val_bit_and0_v<xs...> = mp::val_bit_and0<>::f<xs...>::value

emp::val_bit_and_c<auto... xs> = val<(xs & ...)>

auto emp::val_bit_and_c_v<auto... xs> = val<(xs & ...)>()

emp::val_bit_and_seq<L, C = mp::identity> = emp::unpack<L, mp::val_bit_and<C>>

auto emp::val_bit_and_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_bit_and<C>>::value

auto emp::val_bit_and_v<xs...> = (xs::value & ...)

emp::val_bit_not<x, C = mp::identity> = mp::val_bit_not<C>::f<x>

auto emp::val_bit_not_v<x, C = mp::identity> = mp::val_bit_not<C>::f<x>::value

emp::val_bit_or<xs...> = val<(xs::value | ...)>

emp::val_bit_or0<xs...> = mp::val_bit_or0<>::f<xs...>

emp::val_bit_or0_c<auto... xs> = /*...*/

auto emp::val_bit_or0_c_v<auto... xs> = /*...*/

emp::val_bit_or0_seq<L, C = mp::identity> = emp::unpack<L, mp::val_bit_or0<C>>

auto emp::val_bit_or0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_bit_or0<C>>::value

auto emp::val_bit_or0_v<xs...> = mp::val_bit_or0<>::f<xs...>::value

emp::val_bit_or_c<auto... xs> = val<(xs | ...)>

auto emp::val_bit_or_c_v<auto... xs> = val<(xs | ...)>()

emp::val_bit_or_seq<L, C = mp::identity> = emp::unpack<L, mp::val_bit_or<C>>

auto emp::val_bit_or_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_bit_or<C>>::value

auto emp::val_bit_or_v<xs...> = (xs::value | ...)

emp::val_dec<x, C = mp::identity> = mp::val_dec<C>::f<x>

auto emp::val_dec_v<x, C = mp::identity> = mp::val_dec<C>::f<x>::value

emp::val_div<xs...> = val<(... / xs::value)>

emp::val_div0<xs...> = mp::val_div0<>::f<xs...>

emp::val_div0_c<auto... xs> = val_div_c<xs..., (sizeof...(xs) ? 1 : 0)>

auto emp::val_div0_c_v<auto... xs> = val_div_c_v<xs..., (sizeof...(xs) ? 1 : 0)>

emp::val_div0_seq<L, C = mp::identity> = emp::unpack<L, mp::val_div0<C>>

auto emp::val_div0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_div0<C>>::value

auto emp::val_div0_v<xs...> = mp::val_div0<>::f<xs...>::value

emp::val_div1<xs...> = mp::val_div1<>::f<xs...>

emp::val_div1_c<auto... xs> = val_div_c<xs..., 1>

auto emp::val_div1_c_v<auto... xs> = val_div_c_v<xs..., 1>

emp::val_div1_seq<L, C = mp::identity> = emp::unpack<L, mp::val_div1<C>>

auto emp::val_div1_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_div1<C>>::value

auto emp::val_div1_v<xs...> = mp::val_div1<>::f<xs...>::value

emp::val_div_c<auto... xs> = val<(... / xs)>

auto emp::val_div_c_v<auto... xs> = (... / xs)

emp::val_div_seq<L, C = mp::identity> = emp::unpack<L, mp::val_div<C>>

auto emp::val_div_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_div<C>>::value

auto emp::val_div_v<xs...> = (... / xs::value)

emp::val_equal<x, y, C = mp::identity> = mp::val_equal<C>::f<x, y>

auto emp::val_equal_v<x, y, C = mp::identity> = mp::val_equal<C>::f<x, y>::value

emp::val_greater<x, y, C = mp::identity> = mp::val_greater<C>::f<x, y>

emp::val_greater_equal<x, y, C = mp::identity> = mp::val_greater_equal<C>::f<x, y>

auto emp::val_greater_equal_v<x, y, C = mp::identity> = mp::val_greater_equal<C>::f<x, y>::value

auto emp::val_greater_v<x, y, C = mp::identity> = mp::val_greater<C>::f<x, y>::value

emp::val_inc<x, C = mp::identity> = mp::val_inc<C>::f<x>

auto emp::val_inc_v<x, C = mp::identity> = mp::val_inc<C>::f<x>::value

emp::val_left_add<xs...> = val<(... + xs::value)>

emp::val_left_add0<xs...> = mp::val_add0<>::f<xs...>

emp::val_left_add0_c<auto... xs> = val_left_add_c<xs..., 0>

auto emp::val_left_add0_c_v<auto... xs> = val_left_add_c_v<xs..., 0>

emp::val_left_add0_seq<L, C = mp::identity> = emp::unpack<L, mp::val_left_add0<C>>

auto emp::val_left_add0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_left_add0<C>>::value

auto emp::val_left_add0_v<xs...> = mp::val_add0<>::f<xs...>::value

emp::val_left_add_c<auto... xs> = val<(... + xs)>

auto emp::val_left_add_c_v<auto... xs> = (... + xs)

emp::val_left_add_seq<L, C = mp::identity> = emp::unpack<L, mp::val_left_add<C>>

auto emp::val_left_add_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_left_add<C>>::value

auto emp::val_left_add_v<xs...> = (... + xs::value)

emp::val_left_and<xs...> = val<(true && ... && xs::value)>

emp::val_left_and_c<auto... xs> = val<(true && ... && xs)>

auto emp::val_left_and_c_v<auto... xs> = (true && ... && xs)

emp::val_left_and_seq<L, C = mp::identity> = emp::unpack<L, mp::val_left_and<C>>

auto emp::val_left_and_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_left_and<C>>::value

auto emp::val_left_and_v<xs...> = (true && ... && xs::value)

emp::val_left_bit_and<xs...> = val<(... & xs::value)>

emp::val_left_bit_and0<xs...> = mp::val_left_bit_and0<>::f<xs...>

emp::val_left_bit_and0_c<auto... xs> = /*...*/

auto emp::val_left_bit_and0_c_v<auto... xs> = /*...*/

emp::val_left_bit_and0_seq<L, C = mp::identity> = emp::unpack<L, mp::val_left_bit_and0<C>>

auto emp::val_left_bit_and0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_left_bit_and0<C>>::value

auto emp::val_left_bit_and0_v<xs...> = mp::val_left_bit_and0<>::f<xs...>::value

emp::val_left_bit_and_c<auto... xs> = val<(... & xs)>

auto emp::val_left_bit_and_c_v<auto... xs> = val<(... & xs)>()

emp::val_left_bit_and_seq<L, C = mp::identity> = emp::unpack<L, mp::val_left_bit_and<C>>

auto emp::val_left_bit_and_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_left_bit_and<C>>::value

auto emp::val_left_bit_and_v<xs...> = (... & xs::value)

emp::val_left_bit_or<xs...> = val<(... | xs::value)>

emp::val_left_bit_or0<xs...> = mp::val_left_bit_or0<>::f<xs...>

emp::val_left_bit_or0_c<auto... xs> = /*...*/

auto emp::val_left_bit_or0_c_v<auto... xs> = /*...*/

emp::val_left_bit_or0_seq<L, C = mp::identity> = emp::unpack<L, mp::val_left_bit_or0<C>>

auto emp::val_left_bit_or0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_left_bit_or0<C>>::value

auto emp::val_left_bit_or0_v<xs...> = mp::val_left_bit_or0<>::f<xs...>::value

emp::val_left_bit_or_c<auto... xs> = val<(... | xs)>

auto emp::val_left_bit_or_c_v<auto... xs> = val<(... | xs)>()

emp::val_left_bit_or_seq<L, C = mp::identity> = emp::unpack<L, mp::val_left_bit_or<C>>

auto emp::val_left_bit_or_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_left_bit_or<C>>::value

auto emp::val_left_bit_or_v<xs...> = (... | xs::value)

emp::val_left_mul<xs...> = val<(... * xs::value)>

emp::val_left_mul0<xs...> = mp::val_left_mul0<>::f<xs...>

emp::val_left_mul0_c<auto... xs> = val_left_mul_c<xs..., (sizeof...(xs) ? 1 : 0)>

auto emp::val_left_mul0_c_v<auto... xs> = val_left_mul_c_v<xs..., (sizeof...(xs) ? 1 : 0)>

emp::val_left_mul0_seq<L, C = mp::identity> = emp::unpack<L, mp::val_left_mul0<C>>

auto emp::val_left_mul0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_left_mul0<C>>::value

auto emp::val_left_mul0_v<xs...> = mp::val_left_mul0<>::f<xs...>::value

emp::val_left_mul1<xs...> = mp::val_left_mul1<>::f<xs...>

emp::val_left_mul1_c<auto... xs> = val_left_mul_c<xs..., 1>

auto emp::val_left_mul1_c_v<auto... xs> = val_left_mul_c_v<xs..., 1>

emp::val_left_mul1_seq<L, C = mp::identity> = emp::unpack<L, mp::val_left_mul1<C>>

auto emp::val_left_mul1_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_left_mul1<C>>::value

auto emp::val_left_mul1_v<xs...> = mp::val_left_mul1<>::f<xs...>::value

emp::val_left_mul_c<auto... xs> = val<(... * xs)>

auto emp::val_left_mul_c_v<auto... xs> = (... * xs)

emp::val_left_mul_seq<L, C = mp::identity> = emp::unpack<L, mp::val_left_mul<C>>

auto emp::val_left_mul_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_left_mul<C>>::value

auto emp::val_left_mul_v<xs...> = (... * xs::value)

emp::val_left_or<xs...> = val<(false || ... || xs::value)>

emp::val_left_or_c<auto... xs> = val<(false || ... || xs)>

auto emp::val_left_or_c_v<auto... xs> = (false || ... || xs)

emp::val_left_or_seq<L, C = mp::identity> = emp::unpack<L, mp::val_left_or<C>>

auto emp::val_left_or_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_left_or<C>>::value

auto emp::val_left_or_v<xs...> = (false || ... || xs::value)

emp::val_left_xor<xs...> = val<(... ^ xs::value)>

emp::val_left_xor0<xs...> = mp::val_left_xor0<>::f<xs...>

emp::val_left_xor0_c<auto... xs> = val_left_xor_c<xs..., 0, 0>

auto emp::val_left_xor0_c_v<auto... xs> = val_left_xor_c_v<xs..., 0, 0>()

emp::val_left_xor0_seq<L, C = mp::identity> = emp::unpack<L, mp::val_left_xor0<C>>

auto emp::val_left_xor0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_left_xor0<C>>::value

auto emp::val_left_xor0_v<xs...> = mp::val_left_xor0<>::f<xs...>::value

emp::val_left_xor_c<auto... xs> = val<(... ^ xs)>

auto emp::val_left_xor_c_v<auto... xs> = val<(... ^ xs)>()

emp::val_left_xor_seq<L, C = mp::identity> = emp::unpack<L, mp::val_left_xor<C>>

auto emp::val_left_xor_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_left_xor<C>>::value

auto emp::val_left_xor_v<xs...> = (... ^ xs::value)

emp::val_less<x, y, C = mp::identity> = mp::val_less<C>::f<x, y>

emp::val_less_equal<x, y, C = mp::identity> = mp::val_less_equal<C>::f<x, y>

auto emp::val_less_equal_v<x, y, C = mp::identity> = mp::val_less_equal<C>::f<x, y>::value

auto emp::val_less_v<x, y, C = mp::identity> = mp::val_less<C>::f<x, y>::value

emp::val_lshift<xs...> = val<(... << xs::value)>

emp::val_lshift0<xs...> = mp::val_lshift0<>::f<xs...>

emp::val_lshift0_c<auto... xs> = val_lshift_c<xs..., 0>

auto emp::val_lshift0_c_v<auto... xs> = val_lshift_c_v<xs..., 0>

emp::val_lshift0_seq<L, C = mp::identity> = emp::unpack<L, mp::val_lshift0<C>>

auto emp::val_lshift0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_lshift0<C>>::value

auto emp::val_lshift0_v<xs...> = mp::val_lshift0<>::f<xs...>::value

emp::val_lshift_c<auto... xs> = val<(... << xs)>

auto emp::val_lshift_c_v<auto... xs> = (... << xs)

emp::val_lshift_seq<L, C = mp::identity> = emp::unpack<L, mp::val_lshift<C>>

auto emp::val_lshift_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_lshift<C>>::value

auto emp::val_lshift_v<xs...> = (... << xs::value)

emp::val_mod<xs...> = val<(... % xs::value)>

emp::val_mod0<xs...> = mp::val_mod0<>::f<xs...>

emp::val_mod0_c<auto... xs> = /*...*/

auto emp::val_mod0_c_v<auto... xs> = /*...*/

emp::val_mod0_seq<L, C = mp::identity> = emp::unpack<L, mp::val_mod0<C>>

auto emp::val_mod0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_mod0<C>>::value

auto emp::val_mod0_v<xs...> = mp::val_mod0<>::f<xs...>::value

emp::val_mod1<xs...> = mp::val_mod1<>::f<xs...>

emp::val_mod1_c<auto... xs> = /*...*/

auto emp::val_mod1_c_v<auto... xs> = /*...*/

emp::val_mod1_seq<L, C = mp::identity> = emp::unpack<L, mp::val_mod1<C>>

auto emp::val_mod1_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_mod1<C>>::value

auto emp::val_mod1_v<xs...> = mp::val_mod1<>::f<xs...>::value

emp::val_mod_c<auto... xs> = val<(... % xs)>

auto emp::val_mod_c_v<auto... xs> = (... % xs)

emp::val_mod_seq<L, C = mp::identity> = emp::unpack<L, mp::val_mod<C>>

auto emp::val_mod_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_mod<C>>::value

auto emp::val_mod_v<xs...> = (... % xs::value)

emp::val_mul<xs...> = val<(xs::value * ...)>

emp::val_mul0<xs...> = mp::val_mul0<>::f<xs...>

emp::val_mul0_c<auto... xs> = val_mul_c<xs..., (sizeof...(xs) ? 1 : 0)>

auto emp::val_mul0_c_v<auto... xs> = val_mul_c_v<xs..., (sizeof...(xs) ? 1 : 0)>

emp::val_mul0_seq<L, C = mp::identity> = emp::unpack<L, mp::val_mul0<C>>

auto emp::val_mul0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_mul0<C>>::value

auto emp::val_mul0_v<xs...> = mp::val_mul0<>::f<xs...>::value

emp::val_mul1<xs...> = mp::val_mul1<>::f<xs...>

emp::val_mul1_c<auto... xs> = val_mul_c<xs..., 1>

auto emp::val_mul1_c_v<auto... xs> = val_mul_c_v<xs..., 1>

emp::val_mul1_seq<L, C = mp::identity> = emp::unpack<L, mp::val_mul1<C>>

auto emp::val_mul1_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_mul1<C>>::value

auto emp::val_mul1_v<xs...> = mp::val_mul1<>::f<xs...>::value

emp::val_mul_c<auto... xs> = val<(xs * ...)>

auto emp::val_mul_c_v<auto... xs> = (xs * ...)

emp::val_mul_seq<L, C = mp::identity> = emp::unpack<L, mp::val_mul<C>>

auto emp::val_mul_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_mul<C>>::value

auto emp::val_mul_v<xs...> = (xs::value * ...)

emp::val_neg<x, C = mp::identity> = mp::val_neg<C>::f<x>

auto emp::val_neg_v<x, C = mp::identity> = mp::val_neg<C>::f<x>::value

emp::val_not<x, C = mp::identity> = mp::val_not<C>::f<x>

emp::val_not_equal<x, y, C = mp::identity> = mp::val_not_equal<C>::f<x, y>

auto emp::val_not_equal_v<x, y, C = mp::identity> = mp::val_not_equal<C>::f<x, y>::value

auto emp::val_not_v<x, C = mp::identity> = mp::val_not<C>::f<x>::value

emp::val_or<xs...> = val<(xs::value || ... || false)>

emp::val_or_c<auto... xs> = val<(xs || ... || false)>

auto emp::val_or_c_v<auto... xs> = (xs || ... || false)

emp::val_or_seq<L, C = mp::identity> = emp::unpack<L, mp::val_or<C>>

auto emp::val_or_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_or<C>>::value

auto emp::val_or_v<xs...> = (xs::value || ... || false)

emp::val_rshift<xs...> = val<(...>> xs::value)>

emp::val_rshift0<xs...> = mp::val_rshift0<>::f<xs...>

emp::val_rshift0_c<auto... xs> = val_rshift_c<xs..., 0>

auto emp::val_rshift0_c_v<auto... xs> = val_rshift_c_v<xs..., 0>

emp::val_rshift0_seq<L, C = mp::identity> = emp::unpack<L, mp::val_rshift0<C>>

auto emp::val_rshift0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_rshift0<C>>::value

auto emp::val_rshift0_v<xs...> = mp::val_rshift0<>::f<xs...>::value

emp::val_rshift_c<auto... xs> = val<(...>> xs)>

auto emp::val_rshift_c_v<auto... xs> = (...>> xs)

emp::val_rshift_seq<L, C = mp::identity> = emp::unpack<L, mp::val_rshift<C>>

auto emp::val_rshift_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_rshift<C>>::value

auto emp::val_rshift_v<xs...> = (...>> xs::value)

emp::val_sub<xs...> = val<(... - xs::value)>

emp::val_sub0<xs...> = mp::val_sub0<>::f<xs...>

emp::val_sub0_c<auto... xs> = val_sub_c<xs..., 0>

auto emp::val_sub0_c_v<auto... xs> = val_sub_c_v<xs..., 0>

emp::val_sub0_seq<L, C = mp::identity> = emp::unpack<L, mp::val_sub0<C>>

auto emp::val_sub0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_sub0<C>>::value

auto emp::val_sub0_v<xs...> = mp::val_sub0<>::f<xs...>::value

emp::val_sub_c<auto... xs> = val<(... - xs)>

auto emp::val_sub_c_v<auto... xs> = (... - xs)

emp::val_sub_seq<L, C = mp::identity> = emp::unpack<L, mp::val_sub<C>>

auto emp::val_sub_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_sub<C>>::value

auto emp::val_sub_v<xs...> = (... - xs::value)

emp::val_unary_plus<x, C = mp::identity> = mp::val_unary_plus<C>::f<x>

auto emp::val_unary_plus_v<x, C = mp::identity> = mp::val_unary_plus<C>::f<x>::value

emp::val_xor0<xs...> = mp::val_xor0<>::f<xs...>

emp::val_xor0_c<auto... xs> = val_xor_c<xs..., 0, 0>

auto emp::val_xor0_c_v<auto... xs> = val_xor_c_v<xs..., 0, 0>()

emp::val_xor0_seq<L, C = mp::identity> = emp::unpack<L, mp::val_xor0<C>>

auto emp::val_xor0_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_xor0<C>>::value

auto emp::val_xor0_v<xs...> = mp::val_xor0<>::f<xs...>::value

emp::val_xor_<xs...> = val<(xs::value ^ ...)>

emp::val_xor_c<auto... xs> = val<(xs ^ ...)>

auto emp::val_xor_c_v<auto... xs> = val<(xs ^ ...)>()

emp::val_xor_seq<L, C = mp::identity> = emp::unpack<L, mp::val_xor<C>>

auto emp::val_xor_seq_v<L, C = mp::identity> = emp::unpack<L, mp::val_xor<C>>::value

auto emp::val_xor_v<xs...> = (xs::value ^ ...)

<jln/mp/value/values.hpp>

Test file: test/src/value/values.cpp

typed_values<C = listify>::f<T, xs...>

Implementation
C::f<val<T(xs::value)>...>

values<C = listify>::f<xs...>

Implementation
C::f<val<xs::value>...>

emp::typed_values<T, T... xs> = list<val<T(xs)>...>

emp::values<auto... xs> = list<val<xs>...>