XTE_ARROW (), XTE_ARROW_RETURN (), XTE_ARROW_IF (), XTE_ARROW_CHOOSE (), XTE_ARROW_CAST (), XTE_ARROW_CTOR ()
Defined in header <xte/preproc/arrow.hpp> Deduplicates the repetition required for defining the body,
noexcept specifier, and requires clause of a template function consisting of a single expression.(i.e. eliminates annoying typing when defining forwarding function templates.)
Definitions
#arrow#define XTE_ARROW (... )\ noexcept __VA_OPT__ (\ (noexcept (__VA_ARGS__ ))\ ->decltype (auto )\ requires (requires {__VA_ARGS__ ; })\ ) {return __VA_ARGS__ ; }
#arrow-return
Same as #arrow but does not specify a trailing return type. Useful for cast operators.#define XTE_ARROW_RETURN (... )\ noexcept __VA_OPT__ (\ (noexcept (__VA_ARGS__ ))\ requires (requires {__VA_ARGS__ ; })\ ) {return __VA_ARGS__ ; }
#arrow-if
#define XTE_ARROW_IF (_cond ,_then ,... )\ noexcept (/* ??? */ )\ ->decltype (auto )\ requires (/* ??? */ )\ {if constexpr (_cond) { (_then); } return __VA_ARGS__; }
_cond is explicitly cast to bool .#arrow-choose
#define XTE_ARROW_CHOOSE (_cond ,_then ,... )\ noexcept (/* ??? */ )\ ->decltype (auto )\ requires (/* ??? */ )\ {if constexpr (_cond) { return _then; } else { return __VA_ARGS__; } }
_cond is explicitly cast to bool . _then may optionally be wrapped in parentheses.#arrow-cast
Defines a cast operator.#define XTE_ARROW_CAST (_attr_spec ,_arg ,... )/* ??? */
#arrow-ctor
Accepts a constructor body consisting of, at most, one expression (optionally wrapped in parentheses), followed by a list of things to initialize and what to initialize them with, respectively, in alternating order. Values must be wrapped in two sets of parentheses, unless the intention is to brace-initialize, in which case they must be wrapped in one outer set of parentheses and one inner set of brackets. Wrapping the thing to initialize in one set of parentheses designates it as a base class type, and wrapping it in two sets of parentheses designates it as a pack of base class types. See [Example #1].#define XTE_ARROW_CTOR (_body ,... )\ noexcept (/* ??? */ )\ requires (/* ??? */ )\ :/* ??? */ \ {/* ??? */ }
Examples
#0[View in Compiler Explorer]auto add (auto a ,auto b )XTE_ARROW (a +b )struct S {void operator +(S ) {}// not marked `noexcept` };static_assert (noexcept (add (1 ,2 )));static_assert (!noexcept (add (S (),S ())));
#1
[View in Compiler Explorer]template <typename T ,typename... Ts >struct X :T ,Ts ... {int x [2 ];X (int a ,int b ,auto arg ,auto... args )XTE_ARROW_CTOR (,// : x ,({a ,b }),// x { a, b } (T ),((arg )),// T(arg) ((Ts )),((args ...))// Ts(args...)... )// {} };struct A {int a ; };struct B {double b0 ,b1 ; };struct C {double c0 ,c1 ; };static_assert (noexcept (X <A ,B ,C >(1 ,2 ,418 ,3.14159 ,6.28318 )));// : x { 1, 2 }, A(418), B(3.14159, 6.28318), C(3.14159, 6.28318) {}