Table of contents

CI

Jln.mp is a single header C++17 metaprogramming library designed for fast compilation speed.

Licence: MIT

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

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 foo = jln:mp::remove<void>;

We can then apply it to our data:

using result = jln::mp::call<foo, 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 foo via a continuation (C parameter).

using foo = jln:mp::remove<void, /*C=*/jln::mp::cfe<std::tuple>>; using result = jln::mp::call<foo, 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.

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.
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.
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.
_v suffix
C::f takes values. Usually C::f<jln::mp::int_...> (C++17) or C::f<auto...> (C++20).
_c suffix
number type parameters are jln::mp::int_. Usually foo_c<int_ i> = foo<number<i>>.

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/functional/each.hpp" #include "jln/mp/functional/lift.hpp" #include "jln/mp/list/as_list.hpp" #include "jln/mp/list/join.hpp" #include "jln/mp/list/at.hpp" #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::lift<std::tuple>>, // convert a tuple like to mp::list emp::make_int_sequence< std::tuple_size<std::remove_reference_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<mp::int_... ituples, mp::int_... ivalues, class... Tuples> constexpr auto my_tuple_cat_impl( emp::numbers<ituples...>, emp::numbers<ivalues...>, std::tuple<Tuples...> t) { // get is looked up by argument-dependent lookup using std::get; return my_tuple_cat_result_type<Tuples...>{ get<ivalues>(get<ituples>(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 = emp::make_int_sequence_c< sizeof...(Tuples), // repeat each index by number of element mp::each<mp::repeat<std::tuple_size<std::remove_reference_t<Tuples>>>..., mp::join<> > >; // 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::remove_reference_t<Tuples>>>... >; return my_tuple_cat_impl(index_by_tuple{}, index_by_value{}, std::tuple<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_ENABLE_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

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.
adjacent_difference<C = listify>::f<xs...>Computes the differences between adjacent_difference pair of elements.
adjacent_remove_if<BinaryPred, C = listify>::f<xs...>Removes each element in a sequence which respect a predicate with privious element.
adjacent_remove<C = listify>Removes each element in a sequence which is the same type as the privious element.
all_of<Pred, C = identity>Checks whether a predicate holds for all elements of a sequence.
any_of<Pred, C = identity>Checks whether a predicate holds for at least some element of a sequence.
cartesian<C = listify>::f<seqs...>Computes the cartesian product of lists.
combine<C = listify>::f<xs...>Computes all possible combinations (with repetition) from the elements in a sequence.
compare_with<F, Cmp = less<>>comparison on the result of a function.
contains<x, C = identity>Checks whether a value is contained in a list.
copy_if<Pred, C = listify>Copies all elements that satisfy a predicate.
copy<x, C = listify>Copies all occurence of a value.
count_if<Pred, C = identity>Counts all elements that satisfy a predicate.
count<x, C = identity>Counts all elements identical to a value.
flatten<S = lift<list>, C = listify>Converts a tree or list of lists into one list containing the contents of all children.
flatten<lift<S, identity>, C>::f<seqs...>
wrapper<L>converts a typelist to a lift<S>
fold_left<F, C = identity>::f<state, xs...>Folds left over a list using a binary predicate.
fold_right<F, C = identity>::f<state, xs...>Folds right over a list using a binary predicate.
intersperse<x, C = listify>::f<xs...>Inserts a value between each element of a sequence.
is_sorted<Cmp = less<>, C = identity>::f<xs...>Checks wheteher a sequence is sorted.
is_unique<C = identity>Checks whether no values are identical.
is_unique_if<Cmp = lift<std::is_same>, C = identity>
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>= C::f<mismatch<CmpEq, lift</* implementation defined */>>::f<seq1, seq2>::f<CmpLess, seq1, seq2>>
matrix_shortest_with<F = listify, C = listify>::f<seqs...>Truncates a sequence of typelist on the smallest size.
matrix_shortest<C = listify>= matrix_shortest_with<listify, C>
merge<Cmp = less<>, C = listify>::f<seq1, seq2>Merges two list into one sorted sequence.
mismatch<Cmp = equal<>, C = listify, NC = C>::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>Checks whether a predicate does not hold for any element of a sequence.
permutations<C = listify>::f<xs...>Generates all permutations of sequence.
powerset<C = listify>::f<xs...>Computes the powerset of a sequence.
remove_if<Pred, C = listify>Removes all elements that satisfy a predicate.
remove<T, C = listify>Removes all occurence of a value.
repeat<N, C = listify>::f<xs...>Returns a sequence that contains a number of copies of the same sequence.
repeat_c<int_ n, C = listify>= repeat<number<n>, C>
replace_if<Pred, T, C = listify>Replaces every occurrence that satisfy a predicate by some value.
replace<T, U, C = listify>Replaces every occurrence of a value by another value.
reverse<C = listify>::f<xs...>Reverses the order of the elements of a sequence.
rotate<N, C = listify>::f<xs...>Rotates the elements of a sequence around a pivot.
rotate_c<int_ n, C = listify>= rotate<number<n>, C>
same<C = identity>::f<xs...>Checks whether all values are identical.
same<identity>::f<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>
take_while<Pred, C = listify, NC = C>Takes elements from a sequence while the predicate is satisfied.
transform<F, C = listify>::f<xs...>Executes F on every element of a sequence.
unique<C = listify>Returns a list of the same form as L with the duplicate elements removed.
unique_if<Cmp = lift<std::is_same>, C = listify>

Group: functional

bind<F, xs...>::f<ys...>Partially apply a function to some arguments.
reverse_bind<F, xs...>::f<ys...>Partially apply a function to some arguments.
bind1st<F, C>= partial<F, C>
bind2nd<F, C>= partial<identity, F, C>
capture<xs...>::f<C, ys...>= C::f<xs..., ys...>
capture_v<xs...>::f<C, ys...>= C::f<xs::value..., ys::value...>
capture_c<auto... xs>= capture<val<xs>...>
capture_v_c<auto... xs>::f<C, ys...>= C::f<xs..., ys::value...>
reverse_capture<xs...>::f<C, ys...>= C::f<ys..., xs...>
reverse_capture_v<xs...>::f<C, ys...>= C::f<ys::value..., xs::value...>
reverse_capture_c<auto... xs>= reverse_capture<val<xs>...>
reverse_capture_v_c<auto... xs>::f<C, ys...>= C::f<ys::value..., xs...>
cascade<F, Fs...>Recursively invokes functions to nested typelist of typelists.
compose_f<template<class...> F, template<class...> Fs...>Composition of two meta-functions or more.
compose<F, Fs...>Composition of two 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.
lift_t<template<class...> F, C = identity>::f<xs...>Makes a function from a lazy meta-function.
lift<template<class...> F, C = identity>::f<xs...>Makes a function from a meta-function.
lift_c<template<auto...> F>::f<auto... xs>= JLN_MP_DCALLF_C_XS(xs, F, xs...)
lift_v<template<auto...> F>::f<xs...>= JLN_MP_DCALLF_C_XS(xs, F, xs::value...)
memoize_call<C, xs...>Memoization version of call.
call<C, xs...>= C::f<xs...>
call_c<C, auto... xs>= C::f<xs...>
dispatch<C, F, xs...>= call<C, call<F, xs>...>
indirect_call<FC, F, xs...>= call<call<FC, xs...>, F, xs...>
unary_compose_call<C, F, xs...>= call<C, call<F, xs...>>
binary_compose_call<C, F0, F1, xs...>= call<C, call<F0, xs...>, call<F1, xs...>>
ternary_compose_call<C, F0, F1, F2, xs...>= call<C, call<F0, xs...>, call<F1, xs...>, call<F2, xs...>>
call_c
indirect_call<FC, F, xs...>
dispatch<C, F, xs...>
unary_compose_call<C, F, xs...>
binary_compose_call<C, F0, F1, xs...>
ternary_compose_call<C, F0, F1, F2, xs...>
call_t<C, xs...>= call<C, xs...>::type
indirect_call_t<FC, F, xs...>= indirect_call<FC, F, xs...>::type
dispatch_t<C, F, xs...>= dispatch<C, F, xs...>::type
unary_compose_call_t<C, F, xs...>= unary_compose_call<C, F, xs...>::type
binary_compose_call_t<C, F0, F1, xs...>= binary_compose_call<C, F0, F1, xs...>::type
ternary_compose_call_t<C, F0, F1, F2, xs...>= ternary_compose_call<C, F0, F1, F2, xs...>::type
monadic<C, FC = violation>Invokes FC whether na, otherwise C.
monadic0<C, FC = violation>Invokes FC whether any value is na, otherwise C.
monadic_xs<C, FC = violation>Invokes FC whether first value is na, otherwise C.
monadic_if_na<x, template<class...> M, C, FC = violation>Monadify only if x is na.
na
is_na= same_as<na>
violation= always<na>
try_<F, TC = identity, FC = violation>Invokes TC::f<result> whetehr F::f<xs...> is a valid expression other than na, otherwhise invokes FC::f<xs...>.
try_or<F, FC>= try_<F, identity, FC>
try_<F, TC, FC>::f<xs...>
on<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<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.
stop_iteration<_>
recurse<F, C = identity>::f<xs...>Recursively invokes F until stop_iteration.
recurse_fix<F, C = identity>::f<xs...>Version of fix that stops if there is stop_iteration The first invocation uses F::f<F, xs...>, the following invocations F::f<F, result>
infinite_recurse<F, C = identity>::f<x>Recursively invokes F until the result no longer changes
infinite_recurse_fix<F, C = identity>::f<xs...>Mix of fix and infinite_recurse.
tee<Fs..., C>::f<xs...>Invokes multiple functions passing all parameters to each.

Group: group

group_by<Cmp, C = listify>::f<xs...>Groups adjacent elements that respect a predicate.
group<C = listify>= group_by<same<>, C>
group_n<n, C = listify>::f<xs...>Splits a sequence by arbitrary size group.
group_n_c<int_ n, C = listify>= group_n<number<n>, C>
partition_with<Pred, F = listify, C = listify>Splits a list in two according to a predicate.
partition<Pred, C = listify>Splits a list in two according to a predicate.
split_after_if<Pred, C = listify>::f<xs...>Splits a sequence into multiple lists at every point that satisfy a predicate.
split_after<x, C = listify>= split_after_if<same_as<x>, C>
split_at_with<i, F = listify, C = listify>Splits a sequence at an arbitrary position.
split_at_with_c<int_ i, F = listify, C = listify>= split_at_with<number<i>, F, C>
split_at<i, C = listify>Splits a sequence at an arbitrary position.
split_at_c<int_ i, C = listify>= split_at<number<i>, C>
split_before_if<Pred, C = listify>::f<xs...>Splits a sequence into multiple lists at every point that satisfy a predicate.
split_before<x, C = listify>= split_before_if<same_as<x>, C>
split_if<Pred = identity, C = listify>::f<xs...>Splits a sequence into multiple lists at every point that satisfy a predicate.
split<x, C = listify>= split_if<same_as<x>, C>
zip<C = listify>n-ary version of transform.
zip_with<F = listify, C = listify>= zip<transform<unpack<F>, C>>

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.
at_c<int_ n, C = identity>= drop<number<n>, front<C>>
at0<C = identity>= front<C>
at1<C = identity>= drop<number<1>, front<C>>
at2<C = identity>= drop<number<2>, front<C>>
at3<C = identity>= drop<number<3>, front<C>>
at4<C = identity>= drop<number<4>, front<C>>
at5<C = identity>= drop<number<5>, front<C>>
at6<C = identity>= drop<number<6>, front<C>>
at7<C = identity>= drop<number<7>, front<C>>
at8<C = identity>= drop<number<8>, front<C>>
at9<C = identity>= drop<number<9>, front<C>>
back<C = identity>Retrieves the last element of a sequence.
drop<N, C = listify>::f<xs...>Removes N elements from the beginning of a sequence.
drop_c<int_ n, C = listify>= drop<number<n>, C>
erase<start, size = number<1>, C = listify>::f<xs...>Removes all elements between two arbitrary indices of a sequence.
erase_c<int_ start, int_ size = 1, C = listify>= erase<number<start>, number<size>, C>
front<C = identity>::f<x, xs...>Retrieves the first element of a sequence.
insert<i, x, C = listify>Inserts an elements at an arbitrary position.
insert_c<int_ i, x, C = listify>= insert_range_c<i, list<x>, C>
insert_range<i, seq, C = listify>Inserts all elements of seq at an arbitrary position.
insert_range_c<int_ i, seq, C = listify>= insert_range<number<i>, seq, C>
is_empty<C = identity>Checks whether a sequence has no elements.
is_list<C = identity>::f<x>Checks whether x is a list.
is_size_of<N, C = identity>= size<same_as<N, C>>
is_size_of_c<int_ n, C = identity>= size<same_as<number<n>, C>>
join<C = listify>::f<seqs...>Concatenates lists.
list<xs...>
listify= lift<list>
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>::f<xs...>Returns a contiguous subsequence of a sequence.
range_c<int_ beg, int_ end, C = listify>= range<number<beg>, number<end>, C>
size<C = identity>::f<xs...>Returns the number of elements in a xs.
slice<start, size, stride = number<1>, C = listify>::f<xs...>Returns a subset of elements in a xs picked at regular intervals in range.
slice_c<unsigned start, unsigned size, unsigned stride = 1, C = listify>= slice<number<start>, number<size>, number<stride>, C>
sliding_with_stride<size, stride, C = listify>Returns sliding windows of width size.
sliding<size, C = listify>= sliding_with_stride<size, number<1>, C>
sliding_with_stride_c<int_ size, int_ stride = 1, C = listify>
sliding_c<int_ size, C = listify>= sliding_with_stride_c<size, 1, C>
swap_index<I, J, C = listify>Swap elements at indexes I and J of a sequence.
swap_index_c<unsigned i, unsigned j, C = listify>
take<N, C = listify>::f<xs...>Extracts N elements of sequence.
take_c<int_ n, C = listify>= take<number<n>, C>
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.
wrap_in_list_c<bool b>
wrap_in_list_c<true>::f<xs...>= list<xs...>
wrap_in_list_c<false>::f<_>= list<>
wrap_in_list<b>= wrap_in_list_c<b::value>

Group: number

as_bool<C = identity>::f<x>Narrowing convertion from value to number.
as_number<C = identity>::f<x>Narrowing convertion from value to number.
indices<C = listify>Replaces each element of a sequence by its corresponding index.
int_= std::intmax_t
number<int_ v>= value
true_= number<1>
false_= number<0>
iota_v<C = numbers<>>::f<start, count, stride = number<1>>Generates a sequence of int_.
iota<C = listify>Generates a sequence of number.
is_number<C = identity>::f<x>Checks whether a value is a number.
make_int_sequence_v<C = numbers<>>::f<n>Generates an incremental sequence of n int_.
make_int_sequence<C = mp::listify>= make_int_sequence_v<mp::numbers<C>>
min<Cmp = less<>, C = identity>= fold_left<if_<flip<Cmp>, at1<>, at0<>>, C>
min0<Cmp = less<>, C = identity>= if_<size<>, min<Cmp, C>, always<number<0>, C>>
max<Cmp = less<>, C = identity>= fold_left<if_<Cmp, at1<>, at0<>>, C>
max0<Cmp = less<>, C = identity>= if_<size<>, max<Cmp, C>, always<number<0>, C>>
clamp<Min, Max, Cmp = less<>, C = identity>= if_<push_back<Min, Cmp>, always<Min>, if_<push_front<Max, Cmp>, always<Max>, identity>>
clamp_c<int_ min, int_ max, Cmp = less<>, C = identity>= clamp<number<min>, number<max>, Cmp, C>
abs<Cmp = less<>, C = identity>= tee<identity, neg<>, max<Cmp, C>>
pow<C = identity>= fold_left</* implementation defined */, C>
pow0<C = identity>= if_<size<>, pow<C>, always<number<0>, C>>
pow1<C = identity>= if_<size<>, pow<C>, always<number<1>, C>>
numbers<C = listify>::f<int_... ns>= call<C, number<ns>...>
or_<C = identity>::f<xs...>= C::f<number<(false || ... || xs::value)>>
and_<C = identity>::f<xs...>= C::f<number<(true && ... && xs::value)>>
add<C = identity>::f<xs...>= C::f<number<(... + xs::value)>>
add0<C = identity>= if_<size<>, add<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>>
lshift<C = identity>::f<xs...>= C::f<number<(... << xs::value)>>
lshift0<C = identity>= if_<size<>, lshift<C>, always<number<0>, C>>
rshift<C = identity>::f<xs...>= C::f<number<(... >> xs::value)>>
rshift0<C = identity>= if_<size<>, rshift<C>, always<number<0>, 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>>
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>>
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>>
xor_<C = identity>::f<xs...>= C::f<number<(... ^ xs::value)>>
xor0<C = identity>= if_<size<>, xor_<C>, always<number<0>, C>>
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_or<C = identity>::f<xs...>= C::f<number<(... | xs::value)>>
bit_or0<C = identity>= if_<size<>, bit_or<C>, always<number<0>, C>>
neg<C = identity>::f<x>= C::f<number<(-x::value)>>
unary_plus<C = identity>::f<x>= C::f<number<(+x::value)>>
not_<C = identity>::f<x>= C::f<number<(!x::value)>>
bit_not<C = identity>::f<x>= C::f<number<(~x::value)>>
inc<C = identity>::f<x>= C::f<number<(x::value+1)>>
dec<C = identity>::f<x>= C::f<number<(x::value-1)>>
equal<C = identity>::f<x, y>= C::f<number<(x::value == y::value)>>
not_equal<C = identity>::f<x, y>= C::f<number<(x::value != y::value)>>
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)>>
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)>>
equal_to<N, C = identity>= push_back<N, equal<C>>
not_equal_to<N, C = identity>= push_back<N, not_equal<C>>
less_than<N, C = identity>= push_back<N, less<C>>
less_equal_than<N, C = identity>= push_back<N, less_equal<C>>
greater_than<N, C = identity>= push_back<N, greater<C>>
greater_equal_than<N, C = identity>= push_back<N, greater_equal<C>>
equal_to_c<int_ n, C = identity>= equal_to<number<n>, C>
not_equal_to_c<int_ n, C = identity>= not_equal_to<number<n>, C>
less_than_c<int_ n, C = identity>= less_than<number<n>, C>
less_equal_than_c<int_ n, C = identity>= less_equal_than<number<n>, C>
greater_than_c<int_ n, C = identity>= greater_than<number<n>, C>
greater_equal_than_c<int_ n, C = identity>= greater_equal_than<number<n>, C>
to_bool<C = identity>::f<x>Converts a value to a number.

Group: trait

alignof_<C = identity>::f<x>Wrapper for alignof keyword
traits::extent<C = identity>::f<x, i...>= call<C, std::extent<x, i::value...>::type>
traits::emp::extent<x, i = number<0>>= std::extent<x, i::value>::type
traits::aligned_storage<C = identity>::f<Len, Alignment...>= call<C, std::aligned_storage<Len::value, Alignment::value...>::type>
traits::emp::aligned_storage<Len, Alignment...>= std::aligned_storage<Len::value, Alignment::value...>::type
traits::aligned_union<C = identity>::f<len, xs...>= call<C, std::aligned_union<len::value, xs...>::type>
traits::emp::aligned_union<len, xs...>= std::aligned_union<len::value, xs...>::type
is_specialization_of<template<class...> Tpl, C = identity>::f<x>Checks whether x is Tpl<xs...>
sizeof_<C = identity>::f<x>Wrapper for sizeof keyword

Group: utility

always<x, C = identity>::f<xs...>Always evaluate at an arbitrary value.
conditional_c<bool>
conditional_c<true>::f<x, y>= x
conditional_c<false>::f<x, y>= y
conditional<v>= conditional_c<bool(v::value)>
same_as<T, C = identity>::f<x>= C::f<number<std::is_same<T, x>::value>>
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.

Group: value

as_val<C = identity>::f<x>Converts x to val.
has_type<C = identity>::f<x>Checks whether a value to a type member.
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.
val<auto v>= value
typed_val<T, T v>= val<v>
val_or<C = identity>::f<xs...>= C::f<val<(false || ... || xs::value)>>
val_and<C = identity>::f<xs...>= C::f<val<(true && ... && xs::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_sub<C = identity>::f<xs...>= C::f<val<(... - xs::value)>>
val_sub0<C = identity>= if_<size<>, val_sub<C>, always<val<0>, 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_rshift<C = identity>::f<xs...>= C::f<val<(... >> xs::value)>>
val_rshift0<C = identity>= if_<size<>, val_rshift<C>, always<val<0>, 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_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_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_xor<C = identity>::f<xs...>= C::f<val<(... ^ xs::value)>>
val_xor0<C = identity>= if_<size<>, val_xor<C>, always<val<0>, C>>
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_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_neg<C = identity>::f<x>= C::f<val<(-x::value)>>
val_unary_plus<C = identity>::f<x>= C::f<val<(+x::value)>>
val_not<C = identity>::f<x>= C::f<val<(!x::value)>>
val_bit_not<C = identity>::f<x>= C::f<val<(~x::value)>>
val_inc<C = identity>::f<x>= C::f<val<(x::value+1)>>
val_dec<C = identity>::f<x>= C::f<val<(x::value-1)>>
val_equal<C = identity>::f<x, y>= C::f<val<(x::value == y::value)>>
val_not_equal<C = identity>::f<x, y>= C::f<val<(x::value != y::value)>>
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_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_equal_to<N, C = identity>= push_back<N, val_equal<C>>
val_not_equal_to<N, C = identity>= push_back<N, val_not_equal<C>>
val_less_than<N, C = identity>= push_back<N, val_less<C>>
val_less_equal_than<N, C = identity>= push_back<N, val_less_equal<C>>
val_greater_than<N, C = identity>= push_back<N, val_greater<C>>
val_greater_equal_than<N, C = identity>= push_back<N, val_greater_equal<C>>
val_equal_to_c<auto x, C = identity>= val_equal_to<val<x>, C>
val_not_equal_to_c<auto x, C = identity>= val_not_equal_to<val<x>, C>
val_less_than_c<auto x, C = identity>= val_less_than<val<x>, C>
val_less_equal_than_c<auto x, C = identity>= val_less_equal_than<val<x>, C>
val_greater_than_c<auto x, C = identity>= val_greater_than<val<x>, C>
val_greater_equal_than_c<auto x, C = identity>= val_greater_equal_than<val<x>, C>
values<C = listify>::f<xs...>= call<C, val<xs::value>...>
typed_values<C = listify>::f<T, xs...>= call<C, val<T(xs::value)>...>

Detailed descriptions

Group: algorithm

<jln/mp/algorithm/accumulate.hpp>

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.

Implementation

call<zip<push_front<state, fold_left<flip<unpack<F>>, C>>>, seqs...>

Pre-condition

  • all seqs must be the same size

Semantics

Equivalent to C::f<fold_left<F>::f< ... fold_left<F>::f<fold_left<F>::f<state, ...seqs[:][0]>, ...seqs[:][1]> ..., ...seqs[:][n-1]> >>

emp::accumulate<L, state, F, C = mp::identity> = unpack<L, mp::zip<mp::push_front<state, mp::fold_left<mp::flip<mp::unpack<F>>, C>>>>

<jln/mp/algorithm/adjacent_difference.hpp>

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

Computes the differences between adjacent_difference pair of elements.

Semantics

adjacent_difference_difference<C>::f<a, b, c> = C::f<a, sub::f<a, b>, sub::f<b, c>>

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

<jln/mp/algorithm/adjacent_remove.hpp>

adjacent_remove_if<BinaryPred, C = listify>::f<xs...>

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

adjacent_remove<C = listify>

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

Implementation

adjacent_remove_if<same<>, C>

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

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

<jln/mp/algorithm/all_of.hpp>

all_of<Pred, C = identity>

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

Implementation

transform<Pred, and_<C>>

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

<jln/mp/algorithm/any_of.hpp>

any_of<Pred, C = identity>

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

Implementation

transform<Pred, or_<C>>

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

<jln/mp/algorithm/cartesian.hpp>

cartesian<C = listify>::f<seqs...>

Computes the cartesian product of lists.

Pre-condition

Post-condition

  • sizeof...(result) == (emp::size<seqs> * ...) if sizeof...(xs) != 0 else 0

Semantics

call<cartesian<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::cartesian<L, C = mp::listify> = unpack<L, cartesian<C>>

<jln/mp/algorithm/combine.hpp>

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

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

Implementation

repeat_c<sizeof...(xs), cartesian<C>>::f<list<xs...>>

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

<jln/mp/algorithm/compare_with.hpp>

compare_with<F, Cmp = less<>>

comparison on the result of a function.

Implementation

each<F, F, Cmp>

emp::compare_with<F, x, y> = less<call<F, x>, call<F, y>>

<jln/mp/algorithm/contains.hpp>

contains<x, C = identity>

Checks whether a value is contained in a list.

Implementation

any_of<same_as<x>, C>

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

<jln/mp/algorithm/copy.hpp>

copy_if<Pred, C = listify>

Copies all elements that satisfy a predicate.

Implementation

remove_if<tee<Pred, not_<>>, C>

copy<x, C = listify>

Copies all occurence of a value.

Implementation

remove_if<same_as<x, not_<>>, C>

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

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

<jln/mp/algorithm/count.hpp>

count_if<Pred, C = identity>

Counts all elements that satisfy a predicate.

Implementation

transform<Pred, add0<C>>

count<x, C = identity>

Counts all elements identical to a value.

Implementation

transform<same_as<x>, add0<C>>

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

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

<jln/mp/algorithm/flatten.hpp>

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

Converts a tree or list of lists into one list containing the contents of all children.

flatten<lift<S, identity>, C>::f<seqs...>

wrapper<L>

converts a typelist to a lift<S>

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

emp::rewrap<L, xs...> = wrapper<L>::f<xs...>

<jln/mp/algorithm/fold_left.hpp>

fold_left<F, C = identity>::f<state, xs...>

Folds left over a list using a binary predicate.

fold left consideres the first element in the input pack the state, use push_front<> to add state if needed.

Implementation

C::f</* implementation defined */>

Semantics

Equivalent to F::f<... F::f<state, xs[0]>, x[1]>, ..., x[n-1]>, ...>

emp::fold_left<L, state, C = mp::identity> = unpack<L, mp::push_front<state, mp::fold_left<C>>>

<jln/mp/algorithm/fold_right.hpp>

fold_right<F, C = identity>::f<state, xs...>

Folds right over a list using a binary predicate.

fold right consideres the first element in the input pack the state, use push_front<> to add state if needed.

Implementation

C::f</* implementation defined */>

Semantics

Equivalent to F::f<x[0], ..., F::f<x[n-2], F::f<xs[n-1], state>>>

emp::fold_right<L, state, C = mp::identity> = unpack<L, mp::push_front<state, mp::fold_right<C>>>

<jln/mp/algorithm/intersperse.hpp>

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

Inserts a value between each element of a sequence.

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

<jln/mp/algorithm/is_sorted.hpp>

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

Checks wheteher a sequence is sorted.

Implementation

C</* implementation defined */>

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

<jln/mp/algorithm/is_unique.hpp>

is_unique<C = identity>

Checks whether no values are identical.

is_unique_if<Cmp = lift<std::is_same>, C = identity>

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

emp::is_unique_if<L, Cmp = lift<std::is_same>, C = mp::identity> = unpack<L, is_unique_if<Cmp, C>>

<jln/mp/algorithm/lexicographical_compare.hpp>

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

Checks if seq1 is lexicographically less than seq2.

Implementation

C::f<mismatch</* implementation defined */, lift</* implementation defined */>>::f<seq1, seq2>::f<Cmp, seq1, seq2>>

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

Implementation

C::f<mismatch<CmpEq, lift</* implementation defined */>>::f<seq1, seq2>::f<CmpLess, seq1, seq2>>

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

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

<jln/mp/algorithm/matrix_shortest.hpp>

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

Truncates a sequence of typelist on the smallest size.

Pre-condition

  • sizeof...(result) == sizeof...(xs)

Post-condition

Semantics

call<matrix_shortest<listify>, 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> >

Note

A truncated values becomes a list

matrix_shortest<C = listify>

Implementation

matrix_shortest_with<listify, C>

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

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

<jln/mp/algorithm/merge.hpp>

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

Merges two list into one sorted sequence.

Implementation

call<unpack<C>, /* implementation defined */>

Pre-condition

Post-condition

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

<jln/mp/algorithm/mismatch.hpp>

mismatch<Cmp = equal<>, C = listify, NC = C>::f<seq1, seq2>

Returns mismatching info of elements from two sequences.

Uses C when a element mismatch and NC when one of the sequences equals the start of the other.

Semantics

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

emp::mismatch<seq1, seq2, Cmp = mp::equal<>, C = mp::listify, NC = C> = call<mismatch<Cmp, C, NC>, seq1, seq2>

<jln/mp/algorithm/mismatch_index.hpp>

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

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

Implementation

mismatch<Cmp, at0<C>, if_<at0<same_as<number<-1>>>, at1<C>, at0<C>>>

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

<jln/mp/algorithm/none_of.hpp>

none_of<Pred, C = identity>

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

Implementation

any_of<Pred, not_<C>>

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

<jln/mp/algorithm/permutations.hpp>

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

Generates all permutations of sequence.

Post-condition

  • sizeof...(result) == sizeof...(xs)!

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

<jln/mp/algorithm/powerset.hpp>

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

Computes the powerset of a sequence.

Semantics

call<powerset<>, 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> = unpack<L, mp::powerset<C>>

<jln/mp/algorithm/remove.hpp>

remove_if<Pred, C = listify>

Removes all elements that satisfy a predicate.

Implementation

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

remove<T, C = listify>

Removes all occurence of a value.

Implementation

remove_if<same_as<T>, C>

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

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

<jln/mp/algorithm/repeat.hpp>

repeat<N, C = listify>::f<xs...>

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

Implementation

emp::make_int_sequence<N, /* implementation defined */>

repeat_c<int_ n, C = listify>

Implementation

repeat<number<n>, C>

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

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

<jln/mp/algorithm/replace.hpp>

replace_if<Pred, T, C = listify>

Replaces every occurrence that satisfy a predicate by some value.

Implementation

transform<if_<Pred, always<T>, identity>, C>

replace<T, U, C = listify>

Replaces every occurrence of a value by another value.

Implementation

replace_if<same_as<T>, U, C>

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

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

<jln/mp/algorithm/reverse.hpp>

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

Reverses the order of the elements of a sequence.

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

<jln/mp/algorithm/rotate.hpp>

rotate<N, C = listify>::f<xs...>

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 n = 0 len = sizeof...(xs) if (len) { n = N::value if (n < 0) n = len + (n % len) n = n % len } C::f<...xs[n:], ...xs[:n]>

rotate_c<int_ n, C = listify>

Implementation

rotate<number<n>, C>

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

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

<jln/mp/algorithm/same.hpp>

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

Checks whether all values are identical.

Implementation

C::f</* implementation defined */>

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

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

<jln/mp/algorithm/sort.hpp>

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

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

Implementation

call<unpack<C>, /* implementation defined */>

Post-condition

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

Implementation

sort<Cmp, C>

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

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

<jln/mp/algorithm/take_while.hpp>

take_while<Pred, C = listify, NC = C>

Takes elements from a sequence while the predicate is satisfied.

Implementation

invoke_twice<index_if<Pred, tee<identity, always<C>, lift<take>>, always<NC>>>

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

<jln/mp/algorithm/transform.hpp>

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

Executes F on every element of a sequence.

Implementation

dispatch<C, F, xs...>

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

<jln/mp/algorithm/unique.hpp>

unique<C = listify>

Returns a list of the same form as L with the duplicate elements removed.

unique_if<Cmp = lift<std::is_same>, C = listify>

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

emp::unique_if<L, Cmp = lift<std::is_same>, C = mp::listify> = unpack<L, unique_if<Cmp, C>>

Group: functional

<jln/mp/functional/bind.hpp>

bind<F, xs...>::f<ys...>

Partially apply a function to some arguments.

Implementation

call<F, xs..., ys...>

reverse_bind<F, xs...>::f<ys...>

Partially apply a function to some arguments.

Implementation

call<F, ys..., xs...>

bind1st<F, C>

Implementation

partial<F, C>

bind2nd<F, C>

Implementation

partial<identity, F, C>

<jln/mp/functional/capture.hpp>

capture<xs...>::f<C, ys...>

Implementation

C::f<xs..., ys...>

capture_v<xs...>::f<C, ys...>

Implementation

C::f<xs::value..., ys::value...>

capture_c<auto... xs>

Implementation

capture<val<xs>...>

capture_v_c<auto... xs>::f<C, ys...>

Implementation

C::f<xs..., ys::value...>

reverse_capture<xs...>::f<C, ys...>

Implementation

C::f<ys..., xs...>

reverse_capture_v<xs...>::f<C, ys...>

Implementation

C::f<ys::value..., xs::value...>

reverse_capture_c<auto... xs>

Implementation

reverse_capture<val<xs>...>

reverse_capture_v_c<auto... xs>::f<C, ys...>

Implementation

C::f<ys::value..., xs...>

<jln/mp/functional/cascade.hpp>

cascade<F, Fs...>

Recursively invokes functions to nested typelist of typelists.

Semantics

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

<jln/mp/functional/compose.hpp>

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

Composition of two meta-functions or more.

compose<F, Fs...>

Composition of two functions or more.

Implementation

conditional_c<sizeof...(Fs) == 0>::f<at1<F>, mp::fold_right<lift_t</* implementation defined */>>>::f<identity, F, Fs...>

<jln/mp/functional/each.hpp>

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

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

Implementation

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

<jln/mp/functional/eval.hpp>

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

Invokes a lambda function.

Implementation

C<decltype(F.operator()<xs...>())>

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

<jln/mp/functional/fix.hpp>

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

Invokes a function computing the fixed point of a function.

Implementation

call<C, fix<C>, xs...>

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

<jln/mp/functional/flip.hpp>

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

Invokes a function with its two first arguments reversed.

Implementation

call<C, x1, x0, xs...>

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

<jln/mp/functional/identity.hpp>

identity::f<x>

Implementation

x

emp::identity<x> = x

<jln/mp/functional/if.hpp>

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

A conditional expression.

Implementation

mp::conditional_c<bool(call<Pred, xs...>::value)>::f<TC, FC>::f<xs...>

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

<jln/mp/functional/invoke_twice.hpp>

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

Invokes twice.

Implementation

call<F, xs...>::f<xs...>

<jln/mp/functional/is_invocable.hpp>

is_invocable<F, C = identity>

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

emp::is_invocable<F, xs...> = mp::call<mp::is_invocable<F>, xs...>

<jln/mp/functional/lift.hpp>

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

Makes a function from a lazy meta-function.

Implementation

C::f<JLN_MP_DCALLF_XS(xs, F, xs...)::type>

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

Makes a function from a meta-function.

Implementation

C::f<JLN_MP_DCALLF_XS(xs, F, xs...)>

lift_c<template<auto...> F>::f<auto... xs>

Implementation

JLN_MP_DCALLF_C_XS(xs, F, xs...)

lift_v<template<auto...> F>::f<xs...>

Implementation

JLN_MP_DCALLF_C_XS(xs, F, xs::value...)

<jln/mp/functional/call.hpp>

memoize_call<C, xs...>

Memoization version of call.

call<C, xs...>

Implementation

C::f<xs...>

call_c<C, auto... xs>

Implementation

C::f<xs...>

dispatch<C, F, xs...>

Implementation

call<C, call<F, xs>...>

indirect_call<FC, F, xs...>

Implementation

call<call<FC, xs...>, F, xs...>

unary_compose_call<C, F, xs...>

Implementation

call<C, call<F, xs...>>

binary_compose_call<C, F0, F1, xs...>

Implementation

call<C, call<F0, xs...>, call<F1, xs...>>

ternary_compose_call<C, F0, F1, F2, xs...>

Implementation

call<C, call<F0, xs...>, call<F1, xs...>, call<F2, xs...>>

call_c

indirect_call<FC, F, xs...>

dispatch<C, F, xs...>

unary_compose_call<C, F, xs...>

binary_compose_call<C, F0, F1, xs...>

ternary_compose_call<C, F0, F1, F2, xs...>

call_t<C, xs...>

Implementation

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

indirect_call_t<FC, F, xs...>

Implementation

indirect_call<FC, F, xs...>::type

dispatch_t<C, F, xs...>

Implementation

dispatch<C, F, xs...>::type

unary_compose_call_t<C, F, xs...>

Implementation

unary_compose_call<C, F, xs...>::type

binary_compose_call_t<C, F0, F1, xs...>

Implementation

binary_compose_call<C, F0, F1, xs...>::type

ternary_compose_call_t<C, F0, F1, F2, xs...>

Implementation

ternary_compose_call<C, F0, F1, F2, xs...>::type

<jln/mp/functional/monadic.hpp>

monadic<C, FC = violation>

Invokes FC whether na, otherwise C.

Implementation

if_<same_as<na>, FC, C>

monadic0<C, FC = violation>

Invokes FC whether any value is na, otherwise C.

Implementation

if_<front<same_as<na>>, FC, C>

monadic_xs<C, FC = violation>

Invokes FC whether first value is na, otherwise C.

Implementation

if_<transform<same_as<na>, or_<>>, FC, C>

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

Monadify only if x is na.

Implementation

conditional_c<std::is_same<na, x>::value>::f<M<C, FC>, C>

<jln/mp/functional/try.hpp>

na

is_na

Implementation

same_as<na>

violation

Implementation

always<na>

try_<F, TC = identity, FC = violation>

Invokes TC::f<result> whetehr F::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, FC>

Implementation

try_<F, identity, FC>

try_<F, TC, FC>::f<xs...>

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

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

<jln/mp/functional/on.hpp>

on<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.

Implementation

/* unspecified */

Semantics

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

<jln/mp/functional/partial.hpp>

partial<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.

Implementation

/* unspecified */

Pre-condition

  • sizeof...(xs) >= sizeof...(Fs)

Semantics

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

<jln/mp/functional/recurse.hpp>

stop_iteration<_>

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

Recursively invokes F until stop_iteration.

The first invocation uses F::f<xs...>, the following invocations F::f<result>

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

Version of fix that stops if there is stop_iteration The first invocation uses F::f<F, xs...>, the following invocations F::f<F, result>

infinite_recurse<F, C = identity>::f<x>

Recursively invokes F until the result no longer changes

Semantics

call<infinite_recurse<lift_t<std::remove_pointer>>, int****> == int

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

Mix of fix and infinite_recurse.

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

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

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

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

<jln/mp/functional/tee.hpp>

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

Invokes multiple functions passing all parameters to each.

Implementation

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

Group: group

<jln/mp/algorithm/group.hpp>

group_by<Cmp, C = listify>::f<xs...>

Groups adjacent elements that respect a predicate.

Semantics

call<group<same<>>, void, void, int, void > = list< list<void, void>, list<int>, list<void> >

group<C = listify>

Implementation

group_by<same<>, C>

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

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

<jln/mp/algorithm/group_n.hpp>

group_n<n, C = listify>::f<xs...>

Splits a sequence by arbitrary size group.

Post-condition

  • If n <= 0, then the result sequence is empty

Semantics

call<group_n<number<2>>, void, void, int, void, void > = list< list<void, void>, list<int, void>, list<void> >

group_n_c<int_ n, C = listify>

Implementation

group_n<number<n>, C>

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

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

<jln/mp/algorithm/partition.hpp>

partition_with<Pred, F = listify, C = listify>

Splits a list in two according to a predicate.

Implementation

tee<remove_if<Pred, F>, copy_if<Pred, F>, C>

partition<Pred, C = listify>

Splits a list in two according to a predicate.

Implementation

tee<remove_if<Pred>, copy_if<Pred>, C>

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

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

<jln/mp/algorithm/split_after.hpp>

split_after_if<Pred, C = listify>::f<xs...>

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

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

Semantics

call<split_after_if<same_as<void>, _0, _1, _2, _0, _3> == list< list<_0>, list<_1, _2, _0>, list<_3> >

split_after<x, C = listify>

Implementation

split_after_if<same_as<x>, C>

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

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

<jln/mp/algorithm/split_at.hpp>

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

Splits a sequence at an arbitrary position.

Implementation

tee<take<i, F>, drop<i, F>, C>

Pre-condition

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

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

Implementation

split_at_with<number<i>, F, C>

split_at<i, C = listify>

Splits a sequence at an arbitrary position.

Implementation

tee<take<i>, drop<i>, C>

Pre-condition

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

split_at_c<int_ i, C = listify>

Implementation

split_at<number<i>, C>

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

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

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

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

<jln/mp/algorithm/split_before.hpp>

split_before_if<Pred, C = listify>::f<xs...>

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

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

Semantics

call<split_before_if<same_as<void>, _0, _1, _2, _0, _3> == list< list<>, list<_0, _1, _2>, list<_0, _3> >

split_before<x, C = listify>

Implementation

split_before_if<same_as<x>, C>

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

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

<jln/mp/algorithm/split.hpp>

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

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

Semantics

call<split_if<same_as<void>, _0, _1, _2, _0, _3> == list< list<>, list<_1, _2>, list<_3> >

split<x, C = listify>

Implementation

split_if<same_as<x>, C>

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

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

<jln/mp/algorithm/zip.hpp>

zip<C = listify>

n-ary version of transform.

Pre-condition

  • all parameters must be lists
  • all lists must be the same size

Semantics

call<zip<listify>, list<_1, _2, _3>, list<_a, _b, _c> > = list< list<_1, _a>, list<_2, _b>, list<_3, _c> >

zip_with<F = listify, C = listify>

Implementation

zip<transform<unpack<F>, C>>

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

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

Group: list

<jln/mp/list/append.hpp>

append<L, C = listify>

Inserts elements at the end of L list.

Implementation

push_front<L, unpack_append<C>>

emp::append<L, xs...> = unpack_append<L, listify, xs...>

<jln/mp/list/as_list.hpp>

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

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

Implementation

C::f</* implementation defined */>

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>

at<N, C = identity>

Retrieves an element of a sequence at an arbitrary position.

Implementation

drop<N, front<C>>

Pre-condition

  • 0 <= N < sizeof...(xs)

at_c<int_ n, C = identity>

Implementation

drop<number<n>, front<C>>

at0<C = identity>

Implementation

front<C>

at1<C = identity>

Implementation

drop<number<1>, front<C>>

at2<C = identity>

Implementation

drop<number<2>, front<C>>

at3<C = identity>

Implementation

drop<number<3>, front<C>>

at4<C = identity>

Implementation

drop<number<4>, front<C>>

at5<C = identity>

Implementation

drop<number<5>, front<C>>

at6<C = identity>

Implementation

drop<number<6>, front<C>>

at7<C = identity>

Implementation

drop<number<7>, front<C>>

at8<C = identity>

Implementation

drop<number<8>, front<C>>

at9<C = identity>

Implementation

drop<number<9>, front<C>>

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

emp::at_c<L, int_ i, C = mp::identity> = unpack<L, mp::drop<number<i>, mp::front<C>>>

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

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

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

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

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

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

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

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

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

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

<jln/mp/list/back.hpp>

back<C = identity>

Retrieves the last element of a sequence.

Implementation

rotate<number<-1>, front<C>>

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

<jln/mp/list/drop.hpp>

drop<N, C = listify>::f<xs...>

Removes N elements from the beginning of a sequence.

Pre-condition

  • 0 <= N <= sizeof...(xs)

drop_c<int_ n, C = listify>

Implementation

drop<number<n>, C>

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

emp::drop_c<L, int_ n, C = mp::listify> = unpack<L, mp::drop<number<n>, C>>

<jln/mp/list/erase.hpp>

erase<start, size = number<1>, C = listify>::f<xs...>

Removes all elements between two arbitrary indices of a sequence.

Implementation

call<join<C>, take<start>::f<xs...>, call<drop_c<std::min<std::size_t>(sizeof...(xs), /* implementation defined */+ std::size_t{size::value})>, xs...>>

Pre-condition

  • 0 <= start < sizeof...(xs)
  • 0 <= start + size < sizeof...(xs)

erase_c<int_ start, int_ size = 1, C = listify>

Implementation

erase<number<start>, number<size>, C>

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

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

<jln/mp/list/front.hpp>

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

Retrieves the first element of a sequence.

Implementation

C::f<x>

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

<jln/mp/list/insert.hpp>

insert<i, x, C = listify>

Inserts an elements at an arbitrary position.

Implementation

insert_range<i, list<x>, C>

Pre-condition

  • 0 <= i < sizeof...(xs)

insert_c<int_ i, x, C = listify>

Implementation

insert_range_c<i, list<x>, C>

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

emp::insert_c<L, int_ i, x, C = mp::listify> = insert<L, number<i>, x, C>

<jln/mp/list/insert_range.hpp>

insert_range<i, seq, C = listify>

Inserts all elements of seq at an arbitrary position.

Implementation

tee<take<i>, always<seq>, drop<i>, join<C>>

Pre-condition

  • 0 <= i < sizeof...(xs)
  • seq must be a list

insert_range_c<int_ i, seq, C = listify>

Implementation

insert_range<number<i>, seq, C>

emp::insert_range<L, i, seq, C = mp::listify> = unpack<L, mp::insert_range<i, seq, C>>

emp::insert_range_c<L, int_ i, seq, C = mp::listify> = unpack<L, mp::insert_range_c<i, seq, C>>

<jln/mp/list/is_empty.hpp>

is_empty<C = identity>

Checks whether a sequence has no elements.

Implementation

size<not_<C>>

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

<jln/mp/list/is_list.hpp>

is_list<C = identity>::f<x>

Checks whether x is a list.

Implementation

C::f</* implementation defined */>

emp::is_list<x, C = mp::identity> = C::f</* implementation defined */>

<jln/mp/list/is_size_of.hpp>

is_size_of<N, C = identity>

Implementation

size<same_as<N, C>>

is_size_of_c<int_ n, C = identity>

Implementation

size<same_as<number<n>, C>>

emp::is_size_of<L, N, C = mp::identity> = unpack<L, mp::is_size_of<N, C>>

emp::is_size_of_c<L, int_ n, C = mp::identity> = unpack<L, mp::is_size_of_c<n, C>>

<jln/mp/list/join.hpp>

join<C = listify>::f<seqs...>

Concatenates lists.

Pre-condition

emp::join<seqs...> = mp::call<mp::join<>, seqs...>

<jln/mp/list/list.hpp>

list<xs...>

<jln/mp/list/listify.hpp>

listify

Implementation

lift<list>

<jln/mp/list/pop_back.hpp>

pop_back<C = listify>

Removes the last element of sequence.

Implementation

rotate<number<-1>, pop_front<C>>

Pre-condition

  • sizeof...(xs) > 0

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

<jln/mp/list/pop_front.hpp>

pop_front<C = listify>

Remove the first element of sequence

Implementation

drop<number<1>, C>

Pre-condition

  • sizeof...(xs) > 0

emp::pop_front<L, C = mp::listify> = drop<L, mp::number<1>, C>

<jln/mp/list/prepend.hpp>

prepend<L, C = listify>

Inserts elements at the start of L list.

Implementation

push_front<L, unpack<C>>

emp::prepend<L, xs...> = unpack<L, listify, xs...>

<jln/mp/list/push_back.hpp>

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

Appends x to the end of the sequence.

Implementation

call<C, xs..., x>

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

<jln/mp/list/push_front.hpp>

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

Appends x to the beginning of the sequence.

Implementation

call<C, x, xs...>

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

<jln/mp/list/range.hpp>

range<beg, end, C = listify>::f<xs...>

Returns a contiguous subsequence of a sequence.

A negative value represents an index starting from the end. if finally, end <= beg, then an empty list is returned.

range_c<int_ beg, int_ end, C = listify>

Implementation

range<number<beg>, number<end>, C>

emp::range<L, beg, end, C = mp::listify> = unpack<L, mp::range<beg, end, C>>

emp::range_c<L, int_ beg, int_ end, C = mp::listify> = unpack<L, mp::range_c<beg, end, C>>

<jln/mp/list/size.hpp>

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

Returns the number of elements in a xs.

Implementation

C::f<number<sizeof...(xs)>>

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

<jln/mp/list/slice.hpp>

slice<start, size, stride = number<1>, C = listify>::f<xs...>

Returns a subset of elements in a xs picked at regular intervals in range.

Pre-condition

  • 0 <= start < sizeof...(xs)
  • stride > 0
  • 0 <= size * (stride - 1) + 1 < sizeof...(xs) - start

slice_c<unsigned start, unsigned size, unsigned stride = 1, C = listify>

Implementation

slice<number<start>, number<size>, number<stride>, C>

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

emp::slice_c<L, unsigned start, unsigned size, unsigned stride = 1, C = mp::listify> = slice<L, number<start>, number<size>, number<stride>, C>

<jln/mp/list/sliding.hpp>

sliding_with_stride<size, stride, C = listify>

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

sliding<size, C = listify>

Implementation

sliding_with_stride<size, number<1>, C>

sliding_with_stride_c<int_ size, int_ stride = 1, C = listify>

sliding_c<int_ size, C = listify>

Implementation

sliding_with_stride_c<size, 1, C>

emp::sliding_with_stride<L, size, stride, C = mp::listify> = unpack<L, mp::sliding_with_stride<size, stride, C>>

emp::sliding_with_stride_c<L, int_ size, int_ stride, C = mp::listify> = unpack<L, mp::sliding_with_stride_c<size, stride, C>>

emp::sliding<L, size, C = mp::listify> = unpack<L, mp::sliding<size, C>>

emp::sliding_c<L, int_ size, C = mp::listify> = unpack<L, mp::sliding_c<size, C>>

<jln/mp/list/swap_index.hpp>

swap_index<I, J, C = listify>

Swap elements at indexes 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>

swap_index_c<unsigned i, unsigned j, C = listify>

emp::swap_index<L, I, J, C = mp::listify> = unpack<L, swap_index<I, J, C>>

emp::swap_index_c<L, unsigned i, unsigned j, C = mp::listify> = unpack<L, swap_index_c<i, j, C>>

<jln/mp/list/take.hpp>

take<N, C = listify>::f<xs...>

Extracts N elements of sequence.

Implementation

call<rotate<N, drop<number<sizeof...(xs) - N::value>, C>>, xs...>

Pre-condition

  • 0 <= N <= sizeof...(xs)

take_c<int_ n, C = listify>

Implementation

take<number<n>, C>

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

emp::take_c<L, int_ n, C = mp::listify> = unpack<L, mp::take<number<n>, C>>

<jln/mp/list/wrap_in_list.hpp>

wrap_in_list_if<Pred>

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>

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

wrap_in_list_c<bool b>

wrap_in_list_c<true>::f<xs...>

Implementation

list<xs...>

wrap_in_list_c<false>::f<_>

Implementation

list<>

wrap_in_list<b>

Implementation

wrap_in_list_c<b::value>

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...>

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...>

Group: number

<jln/mp/number/as_bool.hpp>

as_bool<C = identity>::f<x>

Narrowing convertion from value to number.

Implementation

call<C, number<bool{x::value}>>

emp::as_bool<x> = number<bool{x::value}>

<jln/mp/number/as_number.hpp>

as_number<C = identity>::f<x>

Narrowing convertion from value to number.

Implementation

call<C, number<int_{x::value}>>

emp::as_number<x> = number<int_{x::value}>

<jln/mp/algorithm/indices.hpp>

indices<C = listify>

Replaces each element of a sequence by its corresponding index.

Implementation

size<make_int_sequence<C>>

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

<jln/mp/number/number.hpp>

int_

Implementation

std::intmax_t

number<int_ v>

Implementation

value

true_

Implementation

number<1>

false_

Implementation

number<0>

<jln/mp/algorithm/iota.hpp>

iota_v<C = numbers<>>::f<start, count, stride = number<1>>

Generates a sequence of int_.

iota<C = listify>

Generates a sequence of number.

Implementation

iota_v<numbers<C>>

emp::iota_v_c<int_ start, int_ count, int_ stride = 1, C = mp::numbers<>> = /* implementation defined */

emp::iota_v<start, count, stride = number<1>, C = mp::numbers<>> = iota_v_c<start::value, count::value, stride::value, C>

emp::iota_c<int_ start, int_ count, int_ stride = 1, C = mp::listify> = iota_v_c<start, count, stride, mp::numbers<C>>

emp::iota<start, count, stride = number<1>, C = mp::listify> = iota_v_c<start::value, count::value, stride::value, mp::numbers<C>>

<jln/mp/number/is_number.hpp>

is_number<C = identity>::f<x>

Checks whether a value is a number.

Implementation

call<C, /* implementation defined */>

emp::is_number<x> = /* implementation defined */

<jln/mp/algorithm/make_int_sequence.hpp>

make_int_sequence_v<C = numbers<>>::f<n>

Generates an incremental sequence of n int_.

make_int_sequence<C = mp::listify>

Implementation

make_int_sequence_v<mp::numbers<C>>

emp::make_int_sequence_v<n, C = mp::numbers<>> = mp::make_int_sequence_v<C>::f<n>

emp::make_int_sequence_v_c<int_ n, C = mp::numbers<>> = make_int_sequence_v<mp::number<n>, C>

emp::make_int_sequence<n, C = mp::listify> = mp::make_int_sequence<C>::f<n>

emp::make_int_sequence_c<int_ n, C = mp::listify> = make_int_sequence<mp::number<n>, C>

<jln/mp/number/math.hpp>

min<Cmp = less<>, C = identity>

Implementation

fold_left<if_<flip<Cmp>, at1<>, at0<>>, C>

min0<Cmp = less<>, C = identity>

Implementation

if_<size<>, min<Cmp, C>, always<number<0>, C>>

max<Cmp = less<>, C = identity>

Implementation

fold_left<if_<Cmp, at1<>, at0<>>, C>

max0<Cmp = less<>, C = identity>

Implementation

if_<size<>, max<Cmp, C>, always<number<0>, C>>

clamp<Min, Max, Cmp = less<>, C = identity>

Implementation

if_<push_back<Min, Cmp>, always<Min>, if_<push_front<Max, Cmp>, always<Max>, identity>>

clamp_c<int_ min, int_ max, Cmp = less<>, C = identity>

Implementation

clamp<number<min>, number<max>, Cmp, C>

abs<Cmp = less<>, C = identity>

Implementation

tee<identity, neg<>, max<Cmp, C>>

pow<C = identity>

Implementation

fold_left</* implementation defined */, C>

pow0<C = identity>

Implementation

if_<size<>, pow<C>, always<number<0>, C>>

pow1<C = identity>

Implementation

if_<size<>, pow<C>, always<number<1>, C>>

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

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

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

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

emp::clamp<L, Min, Max, Cmp = mp::less<>, C = mp::identity> = unpack<L, mp::clamp<Min, Max, Cmp, C>>

emp::clamp_c<L, int_ min, int_ max, Cmp = mp::less<>, C = mp::identity> = unpack<L, mp::clamp_c<min, max, Cmp, C>>

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

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

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

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

<jln/mp/number/numbers.hpp>

numbers<C = listify>::f<int_... ns>

Implementation

call<C, number<ns>...>

emp::numbers<int_... vs> = list<number<vs>...>

<jln/mp/number/operators.hpp>

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

Implementation

C::f<number<(false || ... || xs::value)>>

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

Implementation

C::f<number<(true && ... && xs::value)>>

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

Implementation

C::f<number<(... + xs::value)>>

add0<C = identity>

Implementation

if_<size<>, add<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>>

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

Implementation

C::f<number<(... << xs::value)>>

lshift0<C = identity>

Implementation

if_<size<>, lshift<C>, always<number<0>, C>>

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

Implementation

C::f<number<(... >> xs::value)>>

rshift0<C = identity>

Implementation

if_<size<>, rshift<C>, always<number<0>, 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>>

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>>

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>>

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

Implementation

C::f<number<(... ^ xs::value)>>

xor0<C = identity>

Implementation

if_<size<>, xor_<C>, always<number<0>, C>>

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_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>>

neg<C = identity>::f<x>

Implementation

C::f<number<(-x::value)>>

unary_plus<C = identity>::f<x>

Implementation

C::f<number<(+x::value)>>

not_<C = identity>::f<x>

Implementation

C::f<number<(!x::value)>>

bit_not<C = identity>::f<x>

Implementation

C::f<number<(~x::value)>>

inc<C = identity>::f<x>

Implementation

C::f<number<(x::value+1)>>

dec<C = identity>::f<x>

Implementation

C::f<number<(x::value-1)>>

equal<C = identity>::f<x, y>

Implementation

C::f<number<(x::value == y::value)>>

not_equal<C = identity>::f<x, y>

Implementation

C::f<number<(x::value != y::value)>>

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)>>

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)>>

equal_to<N, C = identity>

Implementation

push_back<N, equal<C>>

not_equal_to<N, C = identity>

Implementation

push_back<N, not_equal<C>>

less_than<N, C = identity>

Implementation

push_back<N, less<C>>

less_equal_than<N, C = identity>

Implementation

push_back<N, less_equal<C>>

greater_than<N, C = identity>

Implementation

push_back<N, greater<C>>

greater_equal_than<N, C = identity>

Implementation

push_back<N, greater_equal<C>>

equal_to_c<int_ n, C = identity>

Implementation

equal_to<number<n>, C>

not_equal_to_c<int_ n, C = identity>

Implementation

not_equal_to<number<n>, C>

less_than_c<int_ n, C = identity>

Implementation

less_than<number<n>, C>

less_equal_than_c<int_ n, C = identity>

Implementation

less_equal_than<number<n>, C>

greater_than_c<int_ n, C = identity>

Implementation

greater_than<number<n>, C>

greater_equal_than_c<int_ n, C = identity>

Implementation

greater_equal_than<number<n>, C>

emp::or_seq<L, C = mp::identity> = unpack<L, mp::or_<C>>

emp::and_seq<L, C = mp::identity> = unpack<L, mp::and_<C>>

emp::add_seq<L, C = mp::identity> = unpack<L, mp::add<C>>

emp::add0_seq<L, C = mp::identity> = unpack<L, mp::add0<C>>

emp::sub_seq<L, C = mp::identity> = unpack<L, mp::sub<C>>

emp::sub0_seq<L, C = mp::identity> = unpack<L, mp::sub0<C>>

emp::lshift_seq<L, C = mp::identity> = unpack<L, mp::lshift<C>>

emp::lshift0_seq<L, C = mp::identity> = unpack<L, mp::lshift0<C>>

emp::rshift_seq<L, C = mp::identity> = unpack<L, mp::rshift<C>>

emp::rshift0_seq<L, C = mp::identity> = unpack<L, mp::rshift0<C>>

emp::mul_seq<L, C = mp::identity> = unpack<L, mp::mul<C>>

emp::mul0_seq<L, C = mp::identity> = unpack<L, mp::mul0<C>>

emp::mul1_seq<L, C = mp::identity> = unpack<L, mp::mul1<C>>

emp::div_seq<L, C = mp::identity> = unpack<L, mp::div<C>>

emp::div0_seq<L, C = mp::identity> = unpack<L, mp::div0<C>>

emp::div1_seq<L, C = mp::identity> = unpack<L, mp::div1<C>>

emp::mod_seq<L, C = mp::identity> = unpack<L, mp::mod<C>>

emp::mod0_seq<L, C = mp::identity> = unpack<L, mp::mod0<C>>

emp::mod1_seq<L, C = mp::identity> = unpack<L, mp::mod1<C>>

emp::xor_seq<L, C = mp::identity> = unpack<L, mp::xor_<C>>

emp::xor0_seq<L, C = mp::identity> = unpack<L, mp::xor0<C>>

emp::bit_and_seq<L, C = mp::identity> = unpack<L, mp::bit_and<C>>

emp::bit_and0_seq<L, C = mp::identity> = unpack<L, mp::bit_and0<C>>

emp::bit_or_seq<L, C = mp::identity> = unpack<L, mp::bit_or<C>>

emp::bit_or0_seq<L, C = mp::identity> = unpack<L, mp::bit_or0<C>>

emp::or_c<int_... xs> = number<(false || ... || xs)>

emp::and_c<int_... xs> = number<(true && ... && xs)>

emp::add_c<int_... xs> = number<(... + xs)>

emp::add0_c<int_... xs> = add_c<xs..., 0>

emp::sub_c<int_... xs> = number<(... - xs)>

emp::sub0_c<int_... xs> = sub_c<xs..., 0>

emp::lshift_c<int_... xs> = number<(... << xs)>

emp::lshift0_c<int_... xs> = lshift_c<xs..., 0>

emp::rshift_c<int_... xs> = number<(... >> xs)>

emp::rshift0_c<int_... xs> = rshift_c<xs..., 0>

emp::mul_c<int_... xs> = number<(... * xs)>

emp::mul0_c<int_... xs> = mul_c<xs..., (sizeof...(xs) ? 1 : 0)>

emp::mul1_c<int_... xs> = mul_c<xs..., 1>

emp::div_c<int_... xs> = number<(... / xs)>

emp::div0_c<int_... xs> = div_c<xs..., (sizeof...(xs) ? 1 : 0)>

emp::div1_c<int_... xs> = div_c<xs..., 1>

emp::mod_c<int_... xs> = number<(... % xs)>

emp::mod0_c<int_... xs> = mod_c<xs..., (sizeof...(xs) ? std::numeric_limits<int_>::min() : 0)>

emp::mod1_c<int_... xs> = mod_c<xs..., (sizeof...(xs) ? std::numeric_limits<int_>::min() : 1)>

emp::xor_c<int_... xs> = number<(... ^ xs)>

emp::xor0_c<int_... xs> = xor_c<xs..., 0, 0>

emp::bit_and_c<int_... xs> = number<(... & xs)>

emp::bit_and0_c<int_... xs> = bit_and_c<xs..., (sizeof...(xs) ? std::numeric_limits<int_>::max() : 0)>

emp::bit_or_c<int_... xs> = number<(... | xs)>

emp::bit_or0_c<int_... xs> = bit_or_c<xs..., (sizeof...(xs) ? std::numeric_limits<int_>::max() : 0)>

emp::or_<xs...> = number<(false || ... || xs::value)>

emp::and_<xs...> = number<(true && ... && xs::value)>

emp::add<xs...> = number<(... + xs::value)>

emp::add0<xs...> = call<mp::add0<>, xs...>

emp::sub<xs...> = number<(... - xs::value)>

emp::sub0<xs...> = call<mp::sub0<>, xs...>

emp::lshift<xs...> = number<(... << xs::value)>

emp::lshift0<xs...> = call<mp::lshift0<>, xs...>

emp::rshift<xs...> = number<(... >> xs::value)>

emp::rshift0<xs...> = call<mp::rshift0<>, xs...>

emp::mul<xs...> = number<(... * xs::value)>

emp::mul0<xs...> = call<mp::mul0<>, xs...>

emp::mul1<xs...> = call<mp::mul1<>, xs...>

emp::div<xs...> = number<(... / xs::value)>

emp::div0<xs...> = call<mp::div0<>, xs...>

emp::div1<xs...> = call<mp::div1<>, xs...>

emp::mod<xs...> = number<(... % xs::value)>

emp::mod0<xs...> = call<mp::mod0<>, xs...>

emp::mod1<xs...> = call<mp::mod1<>, xs...>

emp::xor_<xs...> = number<(... ^ xs::value)>

emp::xor0<xs...> = call<mp::xor0<>, xs...>

emp::bit_and<xs...> = number<(... & xs::value)>

emp::bit_and0<xs...> = call<mp::bit_and0<>, xs...>

emp::bit_or<xs...> = number<(... | xs::value)>

emp::bit_or0<xs...> = call<mp::bit_or0<>, xs...>

emp::neg<x, C = mp::identity> = call<mp::neg<C>, x>

emp::unary_plus<x, C = mp::identity> = call<mp::unary_plus<C>, x>

emp::not_<x, C = mp::identity> = call<mp::not_<C>, x>

emp::bit_not<x, C = mp::identity> = call<mp::bit_not<C>, x>

emp::inc<x, C = mp::identity> = call<mp::inc<C>, x>

emp::dec<x, C = mp::identity> = call<mp::dec<C>, x>

emp::equal<x, y, C = mp::identity> = call<mp::equal<C>, x, y>

emp::not_equal<x, y, C = mp::identity> = call<mp::not_equal<C>, x, y>

emp::less<x, y, C = mp::identity> = call<mp::less<C>, x, y>

emp::less_equal<x, y, C = mp::identity> = call<mp::less_equal<C>, x, y>

emp::greater<x, y, C = mp::identity> = call<mp::greater<C>, x, y>

emp::greater_equal<x, y, C = mp::identity> = call<mp::greater_equal<C>, x, y>

<jln/mp/number/to_bool.hpp>

to_bool<C = identity>::f<x>

Converts a value to a number.

Implementation

call<C, number<bool(x::value)>>

emp::to_bool<x> = number<bool(x::value)>

Group: trait

<jln/mp/utility/alignof.hpp>

alignof_<C = identity>::f<x>

Wrapper for alignof keyword

Implementation

C::f<number<alignof(x)>>

emp::alignof_<x> = number<alignof(x)>

<jln/mp/utility/stl_traits.hpp>

traits::extent<C = identity>::f<x, i...>

Implementation

call<C, std::extent<x, i::value...>::type>

traits::emp::extent<x, i = number<0>>

Implementation

std::extent<x, i::value>::type

traits::aligned_storage<C = identity>::f<Len, Alignment...>

Implementation

call<C, std::aligned_storage<Len::value, Alignment::value...>::type>

traits::emp::aligned_storage<Len, Alignment...>

Implementation

std::aligned_storage<Len::value, Alignment::value...>::type

traits::aligned_union<C = identity>::f<len, xs...>

Implementation

call<C, std::aligned_union<len::value, xs...>::type>

traits::emp::aligned_union<len, xs...>

Implementation

std::aligned_union<len::value, xs...>::type

<jln/mp/utility/is_specialization_of.hpp>

is_specialization_of<template<class...> Tpl, C = identity>::f<x>

Checks whether x is Tpl<xs...>

Implementation

C::f</* implementation defined */>

emp::is_specialization_of<template<class...> Tpl, x> = /* implementation defined */

<jln/mp/utility/sizeof.hpp>

sizeof_<C = identity>::f<x>

Wrapper for sizeof keyword

Implementation

C::f<number<sizeof(x)>>

emp::sizeof_<x> = number<sizeof(x)>

Group: utility

<jln/mp/utility/always.hpp>

always<x, C = identity>::f<xs...>

Always evaluate at an arbitrary value.

Implementation

C::f<x>

Post-condition

  • result = x

<jln/mp/utility/conditional.hpp>

conditional_c<bool>

conditional_c<true>::f<x, y>

Implementation

x

conditional_c<false>::f<x, y>

Implementation

y

conditional<v>

Implementation

conditional_c<bool(v::value)>

emp::conditional<v, x, y> = mp::conditional_c<bool(v::value)>::f<x, y>

emp::conditional_c<bool cond, x, y> = mp::conditional_c<cond>::f<x, y>

<jln/mp/utility/same_as.hpp>

same_as<T, C = identity>::f<x>

Implementation

C::f<number<std::is_same<T, x>::value>>

<jln/mp/utility/unpack.hpp>

unpack<C>::f<seq, xs...>

Turns a typelist into a sequence of those types.

Semantics

unpack<F>::f<typelist<xs...>, ys...> == F::f<ys..., xs...>

unpack_append<C>::f<seq, xs...>

Turns a typelist into a sequence of those types.

Semantics

reverse_unpack<F>::f<typelist<xs...>, ys...> == F::f<xs..., ys...>

emp::unpack<L, C, xs...> = /* implementation defined */

emp::unpack_append<L, C, xs...> = /* implementation defined */

Group: value

<jln/mp/value/as_val.hpp>

as_val<C = identity>::f<x>

Converts x to val.

Implementation

mp::call<C, val<x::value>>

Pre-condition

emp::f<x> = val<x::value>

<jln/mp/utility/has_type.hpp>

has_type<C = identity>::f<x>

Checks whether a value to a type member.

Implementation

C::f</* implementation defined */>

emp::has_type<x> = /* implementation defined */

<jln/mp/value/has_value.hpp>

has_value<C = identity>::f<x>

Checks whether x has a value member.

Implementation

C::f</* implementation defined */>

emp::has_value<x> = /* implementation defined */

<jln/mp/value/is_val.hpp>

is_val<C = identity>::f<x>

Checks whether x is a val.

Implementation

call<C, /* implementation defined */>

emp::is_val<x> = /* implementation defined */

<jln/mp/value/val.hpp>

val<auto v>

Implementation

value

typed_val<T, T v>

Implementation

val<v>

<jln/mp/value/operators.hpp>

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

Implementation

C::f<val<(false || ... || xs::value)>>

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

Implementation

C::f<val<(true && ... && xs::value)>>

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_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_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_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_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_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_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_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>>

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_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_neg<C = identity>::f<x>

Implementation

C::f<val<(-x::value)>>

val_unary_plus<C = identity>::f<x>

Implementation

C::f<val<(+x::value)>>

val_not<C = identity>::f<x>

Implementation

C::f<val<(!x::value)>>

val_bit_not<C = identity>::f<x>

Implementation

C::f<val<(~x::value)>>

val_inc<C = identity>::f<x>

Implementation

C::f<val<(x::value+1)>>

val_dec<C = identity>::f<x>

Implementation

C::f<val<(x::value-1)>>

val_equal<C = identity>::f<x, y>

Implementation

C::f<val<(x::value == y::value)>>

val_not_equal<C = identity>::f<x, y>

Implementation

C::f<val<(x::value != y::value)>>

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_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_equal_to<N, C = identity>

Implementation

push_back<N, val_equal<C>>

val_not_equal_to<N, C = identity>

Implementation

push_back<N, val_not_equal<C>>

val_less_than<N, C = identity>

Implementation

push_back<N, val_less<C>>

val_less_equal_than<N, C = identity>

Implementation

push_back<N, val_less_equal<C>>

val_greater_than<N, C = identity>

Implementation

push_back<N, val_greater<C>>

val_greater_equal_than<N, C = identity>

Implementation

push_back<N, val_greater_equal<C>>

val_equal_to_c<auto x, C = identity>

Implementation

val_equal_to<val<x>, C>

val_not_equal_to_c<auto x, C = identity>

Implementation

val_not_equal_to<val<x>, C>

val_less_than_c<auto x, C = identity>

Implementation

val_less_than<val<x>, C>

val_less_equal_than_c<auto x, C = identity>

Implementation

val_less_equal_than<val<x>, C>

val_greater_than_c<auto x, C = identity>

Implementation

val_greater_than<val<x>, C>

val_greater_equal_than_c<auto x, C = identity>

Implementation

val_greater_equal_than<val<x>, C>

emp::val_or_seq<L, C = mp::identity> = unpack<L, mp::val_or<C>>

emp::val_and_seq<L, C = mp::identity> = unpack<L, mp::val_and<C>>

emp::val_add_seq<L, C = mp::identity> = unpack<L, mp::val_add<C>>

emp::val_add0_seq<L, C = mp::identity> = unpack<L, mp::val_add0<C>>

emp::val_sub_seq<L, C = mp::identity> = unpack<L, mp::val_sub<C>>

emp::val_sub0_seq<L, C = mp::identity> = unpack<L, mp::val_sub0<C>>

emp::val_lshift_seq<L, C = mp::identity> = unpack<L, mp::val_lshift<C>>

emp::val_lshift0_seq<L, C = mp::identity> = unpack<L, mp::val_lshift0<C>>

emp::val_rshift_seq<L, C = mp::identity> = unpack<L, mp::val_rshift<C>>

emp::val_rshift0_seq<L, C = mp::identity> = unpack<L, mp::val_rshift0<C>>

emp::val_mul_seq<L, C = mp::identity> = unpack<L, mp::val_mul<C>>

emp::val_mul0_seq<L, C = mp::identity> = unpack<L, mp::val_mul0<C>>

emp::val_mul1_seq<L, C = mp::identity> = unpack<L, mp::val_mul1<C>>

emp::val_div_seq<L, C = mp::identity> = unpack<L, mp::val_div<C>>

emp::val_div0_seq<L, C = mp::identity> = unpack<L, mp::val_div0<C>>

emp::val_div1_seq<L, C = mp::identity> = unpack<L, mp::val_div1<C>>

emp::val_mod_seq<L, C = mp::identity> = unpack<L, mp::val_mod<C>>

emp::val_mod0_seq<L, C = mp::identity> = unpack<L, mp::val_mod0<C>>

emp::val_mod1_seq<L, C = mp::identity> = unpack<L, mp::val_mod1<C>>

emp::val_xor_seq<L, C = mp::identity> = unpack<L, mp::val_xor<C>>

emp::val_xor0_seq<L, C = mp::identity> = unpack<L, mp::val_xor0<C>>

emp::val_bit_and_seq<L, C = mp::identity> = unpack<L, mp::val_bit_and<C>>

emp::val_bit_and0_seq<L, C = mp::identity> = unpack<L, mp::val_bit_and0<C>>

emp::val_bit_or_seq<L, C = mp::identity> = unpack<L, mp::val_bit_or<C>>

emp::val_bit_or0_seq<L, C = mp::identity> = unpack<L, mp::val_bit_or0<C>>

emp::val_or_c<auto... xs> = val<(false || ... || xs)>

emp::val_and_c<auto... xs> = val<(true && ... && xs)>

emp::val_add_c<auto... xs> = val<(... + xs)>

emp::val_add0_c<auto... xs> = val_add_c<xs..., 0>

emp::val_sub_c<auto... xs> = val<(... - xs)>

emp::val_sub0_c<auto... xs> = val_sub_c<xs..., 0>

emp::val_lshift_c<auto... xs> = val<(... << xs)>

emp::val_lshift0_c<auto... xs> = val_lshift_c<xs..., 0>

emp::val_rshift_c<auto... xs> = val<(... >> xs)>

emp::val_rshift0_c<auto... xs> = val_rshift_c<xs..., 0>

emp::val_mul_c<auto... xs> = val<(... * xs)>

emp::val_mul0_c<auto... xs> = val_mul_c<xs..., (sizeof...(xs) ? 1 : 0)>

emp::val_mul1_c<auto... xs> = val_mul_c<xs..., 1>

emp::val_div_c<auto... xs> = val<(... / xs)>

emp::val_div0_c<auto... xs> = val_div_c<xs..., (sizeof...(xs) ? 1 : 0)>

emp::val_div1_c<auto... xs> = val_div_c<xs..., 1>

emp::val_mod_c<auto... xs> = val<(... % xs)>

emp::val_mod0_c<auto... xs> = /* implementation defined */

emp::val_mod1_c<auto... xs> = /* implementation defined */

emp::val_xor_c<auto... xs> = val<(... ^ xs)>

emp::val_xor0_c<auto... xs> = val_xor_c<xs..., 0, 0>

emp::val_bit_and_c<auto... xs> = val<(... & xs)>

emp::val_bit_and0_c<auto... xs> = /* implementation defined */

emp::val_bit_or_c<auto... xs> = val<(... | xs)>

emp::val_bit_or0_c<auto... xs> = /* implementation defined */

emp::val_or<xs...> = val<(false || ... || xs::value)>

emp::val_and<xs...> = val<(true && ... && xs::value)>

emp::val_add<xs...> = val<(... + xs::value)>

emp::val_add0<xs...> = call<mp::val_add0<>, xs...>

emp::val_sub<xs...> = val<(... - xs::value)>

emp::val_sub0<xs...> = call<mp::val_sub0<>, xs...>

emp::val_lshift<xs...> = val<(... << xs::value)>

emp::val_lshift0<xs...> = call<mp::val_lshift0<>, xs...>

emp::val_rshift<xs...> = val<(... >> xs::value)>

emp::val_rshift0<xs...> = call<mp::val_rshift0<>, xs...>

emp::val_mul<xs...> = val<(... * xs::value)>

emp::val_mul0<xs...> = call<mp::val_mul0<>, xs...>

emp::val_mul1<xs...> = call<mp::val_mul1<>, xs...>

emp::val_div<xs...> = val<(... / xs::value)>

emp::val_div0<xs...> = call<mp::val_div0<>, xs...>

emp::val_div1<xs...> = call<mp::val_div1<>, xs...>

emp::val_mod<xs...> = val<(... % xs::value)>

emp::val_mod0<xs...> = call<mp::val_mod0<>, xs...>

emp::val_mod1<xs...> = call<mp::val_mod1<>, xs...>

emp::val_xor<xs...> = val<(... ^ xs::value)>

emp::val_xor0<xs...> = call<mp::val_xor0<>, xs...>

emp::val_bit_and<xs...> = val<(... & xs::value)>

emp::val_bit_and0<xs...> = call<mp::val_bit_and0<>, xs...>

emp::val_bit_or<xs...> = val<(... | xs::value)>

emp::val_bit_or0<xs...> = call<mp::val_bit_or0<>, xs...>

emp::val_neg<x, C = mp::identity> = call<mp::val_neg<C>, x>

emp::val_unary_plus<x, C = mp::identity> = call<mp::val_unary_plus<C>, x>

emp::val_not<x, C = mp::identity> = call<mp::val_not<C>, x>

emp::val_bit_not<x, C = mp::identity> = call<mp::val_bit_not<C>, x>

emp::val_inc<x, C = mp::identity> = call<mp::val_inc<C>, x>

emp::val_dec<x, C = mp::identity> = call<mp::val_dec<C>, x>

emp::val_equal<x, y, C = mp::identity> = call<mp::val_equal<C>, x, y>

emp::val_not_equal<x, y, C = mp::identity> = call<mp::val_not_equal<C>, x, y>

emp::val_less<x, y, C = mp::identity> = call<mp::val_less<C>, x, y>

emp::val_less_equal<x, y, C = mp::identity> = call<mp::val_less_equal<C>, x, y>

emp::val_greater<x, y, C = mp::identity> = call<mp::val_greater<C>, x, y>

emp::val_greater_equal<x, y, C = mp::identity> = call<mp::val_greater_equal<C>, x, y>

<jln/mp/value/values.hpp>

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

Implementation

call<C, val<xs::value>...>

typed_values<C = listify>::f<T, xs...>

Implementation

call<C, val<T(xs::value)>...>

emp::values<auto... xs> = list<val<xs>...>

emp::typed_values<T, T... xs> = list<val<T(xs)>...>