XTE_ARROW()

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(noexcept(__VA_ARGS__)) \
	-> decltype(auto) \
	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
#define XTE_ARROW_CAST(_attr_spec, _arg, ...) \
	_attr_spec operator decltype(/* ... */)(this _arg) \
	noexcept(noexcept(__VA_ARGS__)) \
	requires(requires { __VA_ARGS__; }) \
	{ return __VA_ARGS__; }
Defines a cast operator. _attr_spec and _arg may optionally be wrapped in parentheses.

#arrow-ctor
#define XTE_ARROW_CTOR(_body, ...) \
	noexcept(/* ... */) \
	requires(/* ... */) \
	: /* ... */ \
	{ _body; }
Accepts a constructor body consisting of an 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].



Examples

#arrow
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())));
[View in Compiler Explorer]

#arrow-ctor
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) {}
[View in Compiler Explorer]