Tools¶
Functional¶
#include<hysj/tools/functional.hpp>
-
unspecified apply¶
-
unspecified assign¶
-
unspecified holds_alternative¶
- Lifts of std::apply, assignment and std::holds_alternative.
-
unspecified unwrap¶
-
unspecified overload¶
- Functional overload-set.
-
unspecified visitor¶
- g = visitor(f...) creates a visitor of the overload set f…, which exposes:
-
operator()(auto&&... v)¶
- Calls std::visit with variants v...
-
operator()(auto&&... v)¶
-
unspecified always¶
-
template<int... i>
unspecified bind¶ - \(g(y...) = f(z...)\)\(z_j = \begin{cases} j = j^x_k \in J^X \rightarrow x_{k} \\ j = j^y_k \in J^Y \rightarrow y_k \end{cases}\)\(J^x = \{ h(k) \mid \forall k \in |X| \}\)\(h(k) = \begin{cases} i_k \geq 0 \rightarrow i_k \\ i_k < 0 \rightarrow |X| + |Y| - i_k \end{cases}\)\(J^y = |X| \cup |Y| \setminus J^x\).
Example
\(f(x) = 1 - x\), \(g(x) = x - 1\), and \(h() = 1 - 1\):
auto f = bind<0>(std::minus<>{},1) auto g = bind<-1>(std::minus<>{},1) auto h = bind<0,-1>(std::minus<>{},1,1);
-
template<integer... i>
unspecified combine¶ - \(h(x...) = f(y...)\)\(y_j = \begin{cases} j \in J^g \rightarrow g(x_j) \\ j \notin J^g \rightarrow x_j \end{cases}\)\(J^x = \{ h(k) \mid \forall k \in |X| \}\)\(h(k) = \begin{cases} i_k \geq 0 \rightarrow i_k \\ i_k < 0 \rightarrow |X| - i_k \end{cases}\)
Example
\(f_0(x,y) = h(x) + y\), \(f_1(x,y) = x + h(y)\), \(h(x) = 1\):
auto h = always(1); auto f_0 = combine<0>(std::plus<>{},h); auto f_1 = combine<-1>(std::plus<>{},h);
-
template<integer N>
unspecified compose¶ - \(h(x\ldots) = f(y\ldots, (g_0 \circ \ldots \circ g_n)(z\ldots),w\ldots)\)\(Z = \begin{cases} N = 0 \rightarrow |X| \\ N < 0 \rightarrow |X| \setminus ||X| - N| \\ N > 0 \rightarrow |N| \end{cases}\)\(Y = \begin{cases} N \geq 0 \rightarrow \emptyset \\ N < 0 \rightarrow |X| \setminus Z \end{cases}\)\(W = \begin{cases} N \leq 0 \rightarrow \emptyset \\ N > 0 \rightarrow |X| \setminus Z \end{cases}\)
Example
\(f_0(x,y,z) = (g \circ h)(x,y,z)\), \(f_1(x,y,z) = g(h(x),y,z)\), and \(f_2(x,y,z) = g(x,(h \circ h)(y,z))\):
auto g = [](auto...){}; auto h = [](auto...){}; auto f_0 = compose<0>(g,h) auto f_1 = compose<1>(g,h); auto f_2 = compose<-2>(g,h,h);
-
template<integer... i>
unspecified interpose¶ - \(h(x\ldots) = h(y\ldots)\)\(y_j = \begin{cases} j = j^g_k\in J^g \rightarrow g_k(x_j) \\ j \notin J^g \rightarrow x_j \end{cases}\)\(J^g = \{ h(k) \mid \forall k \in |X| \}\)\(h(k) = \begin{cases} i_k \geq 0 \rightarrow i_k \\ i_k < 0 \rightarrow |X| - i_k \end{cases}\)
Example
\(f_0(x,y,z) = g(h_0(x),y,z)\), \(f_1(x,y,z) = g(h_0(x),y,h_1(z))\):
auto g = [](auto...){}; auto h_0= [](auto...){}; auto h_1 = [](auto...){}; auto f_0 = interpose<0>(g,h_0) auto f_1 = interpose<0,-1>(g,h_0,h_1);
Preprocessor¶
#include<hysj/tools/preprocessor.hpp>
The preprocessor module defines helper-macros for working with sequences up to 24 elements long.
-
HYSJ_PRODUCT(sequences)¶
- Compute the cartesian product of a sequence of sequences.
Example
Defining the sequence S = ((0, 2)(1, 2)):
#define U0 (0)(1) #define U1 (2) #define S HYSJ_PRODUCT((U0)(U1))
-
HYSJ_MAP_LAMBDA(sequence)¶
- Maps sequence with
HYSJ_LAMBDA
, which the user defines before invokation (and preferably undefines after invocation).Example
Declaring two ints, i0 = 0 and i1 = 1:
#define S (0)(1) #define HYSJ_LAMBDA(v) int i##v = v; HYSJ_MAP_LAMBDA(S) #undef MYSJ_LAMBDA static_assert(i0 == 0 && i1 == 1);
-
HYSJ_SPLAT(i, sequence)¶
- Splats the ith element of each value in sequence into a list.
Example
Splating the last value of each element in the sequence (0, 1)(0, 1) into an array.
#define S (0,1)(0,1) std::array s{ HYSJ_SPLAT(1,S) }; static_assert(s == std::array{1,1});
-
HYSJ_PROJECT(i, sequence)¶
- Creates a new sequence consisting of the ith element of each value in sequence into a list.
Example
Projecting the sequence (0, 1)(0, 1) into a new sequence (0)(0):
#define S (0,1)(0,1) #define U HYSJ_PROJECT(0,S)
-
HYSJ_QUALIFIERS¶
- List of member-ref-qualifiers and associated forwarding function.
Example
Spitting out member-ref qualified overloads of a function call operator:
struct int_holder{ int x; static auto impl(auto&& h,auto &&f) arrow((fwd(f)(fwd(h).x))) #define HYSJ_LAMBDA(qualifier,function)\ auto operator()(auto && f) qualifier\ arrow((impl(function(*this), fwd(f)))) HYSJ_MAP_LAMBDA(HYSJ_QUALIFIERS) #undef HYSJ_LAMBDA };
Priority Tag¶
#include<hysj/tools/priority_tag.hpp>
-
template<std::size_t N>
struct priority_tag¶ - Helper type for defining a prioritized list of default implementations for a hook.
Example
Setting up a hook that by default first tries to invoke a member-function, and if that fails tries to invoke a free function.
inline constexpr struct hook_fn{ friend auto ordered_tag_invoke(hook_fn,priority_tag<1>,auto f) arrow((f.hook())) friend auto ordered_tag_invoke(hook_fn,priority_tag<0>,auto f) arrow((hook(f))) friend auto tag_invoke(hook_fn fn,auto f) arrow((ordered_tag_invoke(fn,priority_tag<1>{},f))) auto operator()(auto f)const arrow((tag_invoke(*this,f))) } hook{};
Reflection¶
#include<hysj/tools/reflection.hpp>
Facilities for rudimentary compile-time reflection of enums and structs. Was orignally adapted from describe. Provides two convenience macros to set up mirrors which encapsulate information about the type, as well as a list of mirrors for its members or enumerators.
-
struct reflection::enum_mirror¶
-
unspecified name¶
-
auto enumerators(enum_mirror)¶
- Returns a tuple of the reflected members.
-
unspecified name¶
-
HYSJ_MIRROR_ENUM(E, ...)¶
Sets up a mirror for an enumerator.
Example
enum myenum{a,b}; HYSJ_MIRROR_ENUM(myenum,a,b); auto [a_mirror,b_mirror] = enumerators(reflect<myenum>()); static_assert(a_mirror.value == a); static_assert(b_mirror.value == b);
-
struct reflection::struct_mirror¶
-
unspecified name¶
-
auto members(struct_mirror)¶
- Returns a tuple of the reflected members.
-
unspecified name¶
-
HYSJ_MIRROR_STRUCT(E, ...)¶
Sets up a mirror for a struct.
Example
struct mystruct{ int a,b; friend HYSJ_MIRROR_STRUCT(mystruct,a,b); }; auto [a_mirror,b_mirror] = members(reflect<mystruct>()); static_assert(a_mirror.pointer == &mystruct::a); static_assert(b_mirror.pointer == &mystruct::b);
Tag Invoke¶
#include<hysj/tools/tag_invoke.hpp>
Machinery for setting up hooks (or CPOs). Stolen from Niebler’s gist.
Tuple¶
#include<hysj/tools/tuple.hpp>
Helper functions for working with tuples, arrays, and spans.
Types¶
#include<hysj/tools/types.hpp>
-
struct nothing¶
- Regular void.
-
using real = double¶
-
using natural = uint64_t¶
-
using integer = int64_t¶
-
using ptrdiff = std::ptrdiff_t¶
Type Traits¶
#include<hysj/tools/type_traits.hpp>
-
template<class T, class U>
concept not_same_as¶ - Inverts std::same_as.
-
template<class T>
using unref_t¶ -
template<class T>
using uncvref_t¶ - Removes references (and const) and unpacks std::reference_wrapper.
-
template<class T, bool C>
using add_const_if¶ - \(\textit{add_const_if}(T,C) = \begin{cases} C = \top \rightarrow \textit{const}\;T \\ C = \bot \rightarrow T \end{cases}\)
-
template<class T>
using type_t¶
-
template<class T>
unspecified type_c¶ - Shorthands for std::identity_type.
-
template<auto i>
using constant_t¶
-
template<auto i>
unspecified constant_c¶ - Shorthands for std::integral_constant.
-
template<class X, class Y>
consteval auto is_same_constant(X, Y)¶ - Machinery for comparing integral-constants.
-
template<class T>
bool is_std_vector¶ -
template<class T>
bool is_std_reference_wrapper¶ -
template<class T>
bool is_std_array¶ -
template<class T>
bool is_std_span¶ - Checks if
T
is a std-type.
-
template<auto pointer>
using member_type = unspecified¶ - \(\textit{member_type}(T \textit{X::*} \textit{pointer}) = T\)