Prologue and Epilogue ===================== Every source in |hysj| starts by including the prologue, and ends by including the epilogue. These introduce and unintroduce some unhygenic, but ergonomic, macros. The macros are cleaned up in the epilogue. *Example* .. code-block:: cpp #include #include namespace hysj::inline _HYSJ_VERSION_NAMESPACE::something{ //yada yada. } #include Prologue -------- :cpp:include:`#include` .. c:macro:: fwd(expression) Simpler :cppref:`std::forward `. | .. c:macro:: arrow(sequence) Expects a sequence of :cpp:expr:`(expression)(constraint)`, where :cpp:expr:`constraint` is optional. Sets up noexcept-specification, trailing return type deduction, and a function body, repating :cpp:expr:`expression` 3 times. If :cpp:expr:`constraint` is supplied it will be pasted as a return-type-requirement on :cpp:expr:`expression`. *Example* Defines a function: .. code-block:: cpp constexpr add_one(auto x) arrow((x + 1)(-> std::integral)) equivalent to: .. code-block:: cpp constexpr add_one(auto x) noexcept(noexcept(x+1)) -> decltype(auto) requires requires { { x + 1 } -> std::integral; } { return x + 1; } | .. c:macro:: lift(identifier) Lifts :cpp:expr:`identifier` into a variadic lambda using :c:macro:`arrow`. *Example* Invokes a range of callables: .. code-block:: cpp std::ranges::for_each(callables,lift(std::invoke)); | .. c:macro:: reify(expression) Extracts the nested type-alias :cpp:expr:`type` from the uncvref'd type of the expression. *Example* Computes type from :cppref:`identity_type ` expression: .. code-block:: cpp static_assert(std::is_same_v{}),int>); | Epilogue -------- :cpp:include:`#include` Undefines the unhygenic, non-namespace-prefixed, macros introduced in the prologue_.