43 FORCEINLINE U &&fget(U &&x) {
44 return std::forward<U>(x);
49 FORCEINLINE
decltype(
auto) fget(std::reference_wrapper<U> x) {
63 template <
typename Tag>
78 return std::forward<L>(l);
94 template <
typename F,
typename... Args>
95 FORCEINLINE
decltype(
auto)
operator()(F &&f, Args &&...args)
const {
96 return detail::fget(std::forward<F>(f))(detail::fget(std::forward<Args>(args))...);
112 template <
typename F,
typename... Args>
113 FORCEINLINE
decltype(
auto)
operator()(F &&f, Args &&...args)
const {
115 return detail::fget(std::forward<F>(f)).operator[](detail::fget(std::forward<Args>(args))...);
120#define CLEF_OPERATION(TAG, OP) \
123 struct TAG : binary_op { \
125 static const char *name() { return AS_STRING(OP); } \
129 template <typename L, typename R> \
130 FORCEINLINE auto operator OP(L &&l, R &&r) \
131 requires(is_any_lazy<L, R>) \
133 return expr<tags::TAG, expr_storage_t<L>, expr_storage_t<R>>{tags::TAG(), std::forward<L>(l), std::forward<R>(r)}; \
137 struct operation<tags::TAG> { \
139 template <typename L, typename R> \
140 FORCEINLINE decltype(auto) operator()(L &&l, R &&r) const { \
141 return detail::fget(std::forward<L>(l)) OP detail::fget(std::forward<R>(r)); \
146 CLEF_OPERATION(plus, +);
147 CLEF_OPERATION(minus, -);
148 CLEF_OPERATION(multiplies, *);
149 CLEF_OPERATION(divides, /);
150 CLEF_OPERATION(greater, >);
151 CLEF_OPERATION(less, <);
152 CLEF_OPERATION(leq, <=);
153 CLEF_OPERATION(geq, >=);
154 CLEF_OPERATION(eq, ==);
159#define CLEF_OPERATION(TAG, OP) \
162 struct TAG : unary_op { \
164 static const char *name() { return AS_STRING(OP); } \
168 template <typename L> \
169 FORCEINLINE auto operator OP(L &&l) \
170 requires(is_any_lazy<L>) \
172 return expr<tags::TAG, expr_storage_t<L>>{tags::TAG(), std::forward<L>(l)}; \
176 struct operation<tags::TAG> { \
178 template <typename L> \
179 FORCEINLINE decltype(auto) operator()(L &&l) const { \
180 return OP detail::fget(std::forward<L>(l)); \
184 CLEF_OPERATION(unaryplus, +);
185 CLEF_OPERATION(negate, -);
186 CLEF_OPERATION(loginot, !);
203 template <
typename C,
typename A,
typename B>
204 FORCEINLINE A
operator()(C
const &c, A
const &a, B
const &b)
const {
205 return detail::fget(c) ? detail::fget(a) : detail::fget(b);
221 template <
typename C,
typename A,
typename B>
222 FORCEINLINE
auto if_else(C &&c, A &&a, B &&b) {
238 template <
typename Tag,
typename... Args>
254 template <
typename Tag,
typename... Args>
255 FORCEINLINE
decltype(
auto)
op_dispatch(std::false_type, Args &&...args) {
Provides a basic lazy expression type for the clef library.
__inline__ auto if_else(C &&c, A &&a, B &&b)
Create a lazy ternary (if-else) expression.
__inline__ auto op_dispatch(std::true_type, Args &&...args)
Dispatch operations containing at least one lazy operand.
typename detail::expr_storage_impl< T >::type expr_storage_t
Type trait to determine how a type should be stored in an expression tree, i.e. either by reference o...
Macros used in the nda library.
Single node of the expression tree.
Generic operation performed on expression nodes.
Provides some utility functions and type traits for the CLEF library.