32 FORCEINLINE U &&fget(U &&x) {
33 return std::forward<U>(x);
38 FORCEINLINE
decltype(
auto) fget(std::reference_wrapper<U> x) {
52 template <
typename Tag>
67 return std::forward<L>(l);
83 template <
typename F,
typename... Args>
84 FORCEINLINE
decltype(
auto)
operator()(F &&f, Args &&...args)
const {
85 return detail::fget(std::forward<F>(f))(detail::fget(std::forward<Args>(args))...);
101 template <
typename F,
typename... Args>
102 FORCEINLINE
decltype(
auto)
operator()(F &&f, Args &&...args)
const {
104 return detail::fget(std::forward<F>(f)).operator[](detail::fget(std::forward<Args>(args))...);
109#define CLEF_OPERATION(TAG, OP) \
112 struct TAG : binary_op { \
114 static const char *name() { return AS_STRING(OP); } \
118 template <typename L, typename R> \
119 FORCEINLINE auto operator OP(L &&l, R &&r) \
120 requires(is_any_lazy<L, R>) \
122 return expr<tags::TAG, expr_storage_t<L>, expr_storage_t<R>>{tags::TAG(), std::forward<L>(l), std::forward<R>(r)}; \
126 struct operation<tags::TAG> { \
128 template <typename L, typename R> \
129 FORCEINLINE decltype(auto) operator()(L &&l, R &&r) const { \
130 return detail::fget(std::forward<L>(l)) OP detail::fget(std::forward<R>(r)); \
135 CLEF_OPERATION(plus, +);
136 CLEF_OPERATION(minus, -);
137 CLEF_OPERATION(multiplies, *);
138 CLEF_OPERATION(divides, /);
139 CLEF_OPERATION(greater, >);
140 CLEF_OPERATION(less, <);
141 CLEF_OPERATION(leq, <=);
142 CLEF_OPERATION(geq, >=);
143 CLEF_OPERATION(eq, ==);
148#define CLEF_OPERATION(TAG, OP) \
151 struct TAG : unary_op { \
153 static const char *name() { return AS_STRING(OP); } \
157 template <typename L> \
158 FORCEINLINE auto operator OP(L &&l) \
159 requires(is_any_lazy<L>) \
161 return expr<tags::TAG, expr_storage_t<L>>{tags::TAG(), std::forward<L>(l)}; \
165 struct operation<tags::TAG> { \
167 template <typename L> \
168 FORCEINLINE decltype(auto) operator()(L &&l) const { \
169 return OP detail::fget(std::forward<L>(l)); \
173 CLEF_OPERATION(unaryplus, +);
174 CLEF_OPERATION(negate, -);
175 CLEF_OPERATION(loginot, !);
192 template <
typename C,
typename A,
typename B>
193 FORCEINLINE A
operator()(C
const &c, A
const &a, B
const &b)
const {
194 return detail::fget(c) ? detail::fget(a) : detail::fget(b);
210 template <
typename C,
typename A,
typename B>
211 FORCEINLINE
auto if_else(C &&c, A &&a, B &&b) {
227 template <
typename Tag,
typename... Args>
243 template <
typename Tag,
typename... Args>
244 FORCEINLINE
decltype(
auto)
op_dispatch(std::false_type, Args &&...args) {
Provides some utility functions and type traits for the CLEF library.
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.