Template metaprogramming library originally spun off from CppOrderBook project.
- non_repeating_combinations: provides functionality that generates all non-repeating combinations of a specified size for all integers from 1 through n. All combinations are encapsulated consecutively in a single std::integer_sequence which can than be split and consumed.
- param_pack: provides class templates that can wrap type and non-type parameter packs which can then be accessed and manipulated much like an array-like data structure. Provide interfaces for monoidal, functorial, applicative-functorial and monadic access
- function_signature: can deduce the return type and the argument type from an instance of a function-like type
- monoidal_class_template: provides static checks to enforce monoidal behavior in a class template.
- type_pack_check: provides functionality to enforce certain properties across multiple types at compile time using either a single monoidal class template or two different templates.
- helpers: short collection that provides functionality to other components
- found in namespace
helpers
in filehelpers.hpp
template <typename T>
concept constexpr_bool_value
- C++20 concept to determine whether a type has as static constexpr member of type bool named value
template<template <typename...> class Class_Template, typename type>
constexpr inline bool specializes_Class_Template_v
- variable template to determine wheter a specific class template accepting only type parameters is specialized by a specific type
template<template <auto...> class Class_Template, typename type>
constexpr inline bool specializes_Class_Template_nt_v
- variable template to determine wheter a specific class template accepting only non-type parameters is specialized by a specific type
template<template <typename T, T...> class Class_Template, typename type>
constexpr inline bool specializes_Class_Template_tnt_v
- variable template to determine wheter a specific class template accepting a single type parameter
T
and a pack of non-type parameters of typeT
is specialized by a specific type
- found in namespace
non_rep_combinations
in filenon_rep_combinations.hpp
template <size_t n, size_t r>
using non_rep_combinations_t
- computes all non-repeating combinations of length
r
integers 1 throughn
- generates a specialization of
std::integer_sequence
with typesize_t
containing all combinations in one conseqcutive sequence which can then be broken down into the individual combinations
template <size_t n, size_t r>
using non_rep_combinations_t
- computes all non-repeating combinations of length
r
integers 0 throughn
- 1 - generates a specialization of
std::integer_sequence
with typesize_t
containing all combinations in one conseqcutive sequence which can then be broken down into the individual combinations - can be used to compute combinations of indices for data structures with
n
entries, e.g. during compile time checks
- found in namespace
param_pack
in fileparam_pack.hpp
template <size_t i, typename... Ts>
using pack_index_t
- type alias template to extract the i-th type in type parameter pack
Ts
template <size_t i, auto... vs>
constexpr inline auto pack_index_v
- variable template to extract the i-th in non-type parameter pack
vs
template<auto... is>
constexpr inline bool single_type_nt_pack_v
- variable template to determine whether all values in non-type parameter pack
is
are of the same type
template <auto... is>
using pack_type_t
- type alias template to extract the type of of a non-type paramter pack
is
- requires that all values of
is
are of the same type (i.e.single_type_nt_pack_v<is...> == true
)
template<auto... vals>
using non_type_pack_t
- alias template that generates a
non_type_pack
from valuesvals
template<typename T>
using generate_non_type_pack_t
- generates a
non_type_pack
from a different typeT
T
needs to implement a template with either just a non-type argument pack or a single type as first argument denoting the the type of the non-type argument pack that follows
template<typename T>
constexpr inline bool non_type_pack_convertible_v
- variable template to determine whether type
T
can be used to generate anon_type_pack
type via thegenerate_non_type_pack_t
template
template<typename T>
using generate_type_pack_t
- generates a
type_pack_t
from a different typeT
T
needs to implement a template with either just type arguments
template<typename T>
constexpr inline bool type_pack_convertible_v
- variable template to determine whether type
T
can be used to generate atype_pack_t
type via thegenerate_type_pack_t
template
template<typename T, T... vals>
struct non_type_pack
- class template that encapsulates non-type paramter pack consisting of values of type
T
- type alias for
T
(i.e. type ofvals
)
static constexpr size_t size
- number of values in
vals
(i.e.sizeof...(vals)
)
template<typename append_pack>
using append_t
- type alias that appends different
non_type_pack
of values of typeT
to this one - associative operation with 'empty' non-type-pack of same type
non_type_pack<T>
as neutral element non_type_pack
is thus a monoid on a type level withappend_t
as its monoid operation
template<size_t n>
using truncate_front_t
- type alias that removes the first
n
values from thisnon_type_pack
template<size_t n>
using truncate_front_t
- type alias that removes the last
n
values from thisnon_type_pack
template<size_t n>
using head_t
- type alias that yields a new
non_type_pack
containing the firstn
values of this one
template<size_t n>
using tail_t
- type alias that yields a new
non_type_pack
containing the lastn
values of this one
template<size_t i>
static constexpr T index_v
- variable template that extracts the i-th value from this
non_type_pack
template<template <auto...> class Class_Template>
using specialize_template_t
- class template that uses
vals
as non-type template arguments toClass_Template
to generate a type
template<template <typename U, U...> class Class_Template>
using specialize_type_param_template_t
- class template that uses
type
as type argument andvals
as non-type template arguments toClass_Template
to generate a type
- member type,
non_type_pack
containingvals
in reverse order
template<auto callable>
using functor_map_t
- alias template taking a non-type argument
- argument needs to be constexpr callable, taking an argument of type
type
as argument functor_map_t
appliescallable
to all values contained invals
and yields a newnon_type_pack
containing the resultsnon_type_pack
is thus a functor on a type level
template<template<type...> class Class_Template, typename... Other_NTP_Packs>
using applicative_pure_t
- alias template taking a class template (which in turn takes non-type paramenter of type
type
) and an arbitrary number of othernon_type_pack
-types of same type and size as the one being used Class_Template
is then specialized with the n-th values in thisnon_type_pack
and all those containedOther_NTP_Packs
for n = 0 tosize - 1
- all the specializations then need to contain a
constexpr
member variablevalue
of the same type - the resulting type is a new
non_type_pack
of typedecltype(value)
and sizesize
, containing all thevalue
s non_type_pack
is thus an applicative functor on a type level
template<template<T...> class Class_Template>
using monadic_bind_t
- takes a class template as an argument which takes a values of type
type
and generates anon_type_pack
type - the generated types are then all concatenated to one
non_type_pack
type non_type_pack
is thus a monad on a type level
template<auto fold_by, T init>
static constexpr T fold_v
- takes a value
fold_by
as non-type arguments which in turn is callable with two values of typetype
- takes an inital value
init
and recursively "folds" all values contained invals
into a single value
template<typename... Ts>
struct type_pack_t
- class template that encapsulates type paramter pack
static constexpr size_t size
- number of values in
Ts
(i.e.sizeof...(Ts)
)
template<size_t i>
using index_t
- alias template that extracts the i-th type from this
type_pack_t
template<typename append_pack>
using append_t
- type alias that appends different
type_pack_t
to this one - associative operation with 'empty' type-pack
type_pack_t<>
as neutral element type_pack_t
is thus a monoid on a type level withappend_t
as its monoid operation
template<size_t n>
using truncate_front_t
- type alias that removes the first
n
values from thistype_pack_t
template<size_t n>
using head_t
- type alias that yields a new
type_pack_t
containing the firstn
values of this one
template<size_t n>
using tail_t
- type alias that yields a new
type_pack_t
containing the lastn
values of this one
template<template <auto...> class Class_Template>
using specialize_template_t
- class template that uses
Ts
as type template arguments toClass_Template
to generate a type
- member type,
type_pack_t
containingTs
in reverse order
template<template <typename...> class Class_Template><br>
using functor_map_t`
- alias template taking a class template with a type parameter (or possibly more)
functor_map_t
appliesClass_Templ
to all types contained inTs
and yields a newtype_pack_t
containing the resultstype_pack_t
is thus a functor on a type level
template<template<typename...> class Class_Template, typename... Other_Type_Packs>
using applicative_pure_t
- alias template taking a class template (type paramenters) and an arbitrary number of other
type_pack_t
-types of same size as the one being used Class_Template
is then specialized with the n-th type in thistype_pack_t
and all those contained inOther_Type_Packs
for n = 0 tosize - 1
- the resulting type is a new
type_pack_t
of sizesize
, containing all the specializations type_pack_t
is thus an applicative functor on a type level
template<template <typename...> class Class_Template>
using monadic_bind_t
- takes a class template as an argument which has a type parameter generates a
type_pack_t
type - the generated types are then all concatenated to one
type_pack_t
type type_pack_t
is thus a monad on a type level
template<typename NT_Pack, size_t len>
using split_t
- alias template with
NT_Pack
as a type paremeter, which is anon_type_pack
with values of type size_t, andsize_t
len
as a non-type parameter - generates nested
type_pack_t
whose elements aretype_pack_t
s of sizelen
containing types fromTs
at indices specified innt_pack
(and split into groups of sizelen
)
template<template<typename...> class F, typename Init>
using fold_t
- takes a class template
F
with two type parameters - takes an inital value
Init
and recursively "folds" all types contained inTs
into a single type
template<template <typename...> class Templ, size_t order>
using apply_templ_to_nr_combs_t
- computes all non-repeating combinations of size
order
fromTs
, uses each combiation to specializeTempl
and generates atype_pack_t
-type containing all specializations
- found in namespace
function_signature
in file function_signature.hpp - deduces the return type and argument types of a function-like from an instance of that type
- piggybacks on
std::function
, which can be specilized/constructed from any number of callable types - some credit goes to this article
template<auto f>
requires helpers::specializes_class_template_v<std::function, decltype(std::function(f))>
using ret_type_t
- deduces the return type of
f
, providedstd::function
can be constructed fromf
template<auto f>
requires helpers::specializes_class_template_v<std::function, decltype(std::function(f))>
using arg_types_t
- generates a specialization of
param_pack::type_pack_t
containing all the argument types off
, providedstd::function
can be constructed fromf
- found in namespace
monoidal_class_template
in file monoidal_class_template.hpp
- offers a mechanism to enforce a class template behave as monoid w.r.t. to its specializations by a set of different types, using specialization as the monoid operation
- consider three types
T1
,T2
andT3
as well as a class templatemonoid_template
of the form
template <typename...>
struct monoid_template{/*...*/}
- now let's consider the specializations of
monoid_template
byT1
,T2
andT3
(i.e.monoid_template<T1>
,monoid_template<T2>
andmonoid_template<T3>
) and name themMT1
,MT2
andMT3
for brevity monoid_template
will be considered monoidal w.r.t.T1
,T2
andT3
if the following three conditions are fullfilled:- closure: specializing
monoid_template
with any combination of two out ofMT1
,MT2
andMT3
(e.g.monoid_template<MT3, MT1>
ormonoid_template<MT2, MT3>
) generates a valid type - identity: choosing omission of a second argument as identity element, specializing
monoid_template
with just one out ofMT1
,MT2
orMT3
has to yield a type that's equivalent to the one used as type argument - associativity: the specializations
monoid_template<MT1, monoid_template<MT2, MT3>>
andmonoid_template<monoid_template<MT1, MT2>, MT3>
yield equivalent types
- closure: specializing
- a note on equivalence: as we cannot rely on the compiler to recognize types generated by different orders of specialzing a template as equal, we additionally need to define under what conditions we consider two types to be equivalent (e.g. by equal value of a static member) when checking for identity and and associativity properties
- pratical applications: the idea of defining a monoidal class template arose from the desire to come up perform certain checks on a set of types at compile time. To this end, one could specialize a monoidal template with each of the subtypes respectively (or any subset of those types). The resulting specializations can then be aggregated in a fold-like fashion, again using the same monoidal template
- two of the following property checks require a user provided template template paramter
Comparator
that can be specialized by two type arguments to determine the those two types are to be considered equivalent within the context of this check - to this end, specializations of the comparator template are required to a
static constexpr bool
member namedvalue
, which is checked viarequires
clause in the relevant metafunctions
template <template <typename... Ts> class Class_Templ, size_t order, typename... Ts>
constexpr inline bool check_closure_property_v
- variable template to determine whether
Class_Templ
fullfills the closure property w.r.t.Ts
, i.e. whetherClass_Templ
can be spcialized with any two distinct types out of all the specializations ofClass_Templ
from all the possible non-repeating combinations of sizeorder
out of typesTs
Ts
can be passed as a raw type pack or as a single type specializingparam_pack::type_pack_t
template <template <typename... > class Class_Templ, template <typename, typename> class Comparator, size_t order, typename... Ts>
constexpr inline bool check_associativity_property_v
- variable template to determine whether
Class_Templ
fulfills the associativity property w.r.t.Ts
- as verifying associativity includes checking for equality, a class template
Comparator
needs to be provived to determine whether specializations ofClass_Templ
are to be considered equivalent within the context of the of the check Ts
can be passed as a raw type pack or as a single type specializingparam_pack::type_pack_t
template <template <typename... Ts> class Class_Templ, template <typename M1, typename M2> class Comparator, size_t order, typename... Ts>
constexpr inline bool check_identity_element_property_v
- variable template to determine whether
Class_Templ
fulfills the identity-element property w.r.t.Ts
- as verifying identity includes checking for equality, a class template
Comparator
needs to be provived to determine whether specializations ofClass_Templ
are to be considered equivalent within the context of the of the check Ts
can be passed as a raw type pack or as a single type specializingparam_pack::type_pack_t
template <template <typename... > class Class_Templ, template <typename MA, typename MB> class Comparator, size_t order, typename... Ts>
constexpr inline bool monoidal_class_template_v`
- combines checks for closure, associativity and identity for
Class_Templ
w.r.t.Ts
- comparator needs to be provided for associativity and identity checks
Ts
can be passed as a raw type pack or as a single type specializingparam_pack::type_pack_t
- found in namespace
type_pack_t
in filetype_pack_check.hpp
- provides functionality to perform compile time checks over set of types
template<template<typename...> class Type_Handler, template<typename, typename> class Aggregator, size_t order, typename... Ts>
using checker_aggregator_check_t
- uses every non-repeating compination of length
order
fromTs
to specialize templateType_Handler
and aggregates all specializations in a fold-like fashion using class templateAggregator
Ts
can be passed as a regualar type-parameter-pack or as a specialization ofparam_pack::type_pack_t
template<template<typename...> class Monoid_Templ, size_t order, typename... Ts>
using monoid_check_t = monoid_check<Monoid_Templ,order,Ts...>
- uses every non-repeating compination of length
order
fromTs
to specialize templateMonoid_Templ
and then usesMonoid_Templ
to aggregate all specializations in a fold-like fashion - for
Monoid_Templ
to be able to be used in that way,param_pack::check_closure_property_v<Monoid_Templ, order, Ts...> == true
is required Ts
can be passed as a regualar type-parameter-pack or as a specialization ofparam_pack::type_pack_t