1 // Copyright (C) 2016-2018 T. Zachary Laine
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 #ifndef BOOST_YAP_EXPRESSION_HPP_INCLUDED
7 #define BOOST_YAP_EXPRESSION_HPP_INCLUDED
9 #include <boost/yap/algorithm.hpp>
12 namespace boost { namespace yap {
14 /** Reference expression template that provides all operator overloads.
16 \note Due to a limitation of Doxygen, each of the
17 <code>value()</code>, <code>left()</code>, <code>right()</code>, and
18 operator overloads listed here is a stand-in for three member
19 functions. For each function <code>f</code>, the listing here is:
20 \code return_type f (); \endcode However, there are actually three
23 return_type f () const &;
28 template<expr_kind Kind, typename Tuple>
31 using tuple_type = Tuple;
33 static const expr_kind kind = Kind;
35 /** Default constructor. Does nothing. */
36 constexpr expression() {}
38 /** Moves \a rhs into the only data mamber, \c elements. */
39 constexpr expression(tuple_type && rhs) :
40 elements(static_cast<tuple_type &&>(rhs))
45 /** A convenience member function that dispatches to the free function
46 <code>value()</code>. */
47 constexpr decltype(auto) value() &
49 return ::boost::yap::value(*this);
52 #ifndef BOOST_YAP_DOXYGEN
54 constexpr decltype(auto) value() const &
56 return ::boost::yap::value(*this);
59 constexpr decltype(auto) value() &&
61 return ::boost::yap::value(std::move(*this));
66 /** A convenience member function that dispatches to the free function
67 <code>left()</code>. */
68 constexpr decltype(auto) left() & { return ::boost::yap::left(*this); }
70 #ifndef BOOST_YAP_DOXYGEN
72 constexpr decltype(auto) left() const &
74 return ::boost::yap::left(*this);
77 constexpr decltype(auto) left() &&
79 return ::boost::yap::left(std::move(*this));
84 /** A convenience member function that dispatches to the free function
85 <code>right()</code>. */
86 constexpr decltype(auto) right() &
88 return ::boost::yap::right(*this);
91 #ifndef BOOST_YAP_DOXYGEN
93 constexpr decltype(auto) right() const &
95 return ::boost::yap::right(*this);
98 constexpr decltype(auto) right() &&
100 return ::boost::yap::right(std::move(*this));
105 BOOST_YAP_USER_ASSIGN_OPERATOR(
106 expression, ::boost::yap::expression) // =
107 BOOST_YAP_USER_SUBSCRIPT_OPERATOR(::boost::yap::expression) // []
108 BOOST_YAP_USER_CALL_OPERATOR(::boost::yap::expression) // ()
111 /** Terminal expression specialization of the reference expression
114 \note Due to a limitation of Doxygen, the <code>value()</code> member
115 and each of the operator overloads listed here is a stand-in for three
116 member functions. For each function <code>f</code>, the listing here
117 is: \code return_type f (); \endcode However, there are actually three
120 return_type f () const &;
126 struct expression<expr_kind::terminal, hana::tuple<T>>
128 using tuple_type = hana::tuple<T>;
130 static const expr_kind kind = expr_kind::terminal;
132 /** Default constructor. Does nothing. */
133 constexpr expression() {}
135 /** Forwards \a t into \c elements. */
136 constexpr expression(T && t) : elements(static_cast<T &&>(t)) {}
138 /** Copies \a rhs into the only data mamber, \c elements. */
139 constexpr expression(hana::tuple<T> const & rhs) : elements(rhs) {}
141 /** Moves \a rhs into the only data mamber, \c elements. */
142 constexpr expression(hana::tuple<T> && rhs) : elements(std::move(rhs))
147 /** A convenience member function that dispatches to the free function
148 <code>value()</code>. */
149 constexpr decltype(auto) value() &
151 return ::boost::yap::value(*this);
154 #ifndef BOOST_YAP_DOXYGEN
156 constexpr decltype(auto) value() const &
158 return ::boost::yap::value(*this);
161 constexpr decltype(auto) value() &&
163 return ::boost::yap::value(std::move(*this));
168 BOOST_YAP_USER_ASSIGN_OPERATOR(
169 expression, ::boost::yap::expression) // =
170 BOOST_YAP_USER_SUBSCRIPT_OPERATOR(::boost::yap::expression) // []
171 BOOST_YAP_USER_CALL_OPERATOR(::boost::yap::expression) // ()
174 #ifndef BOOST_YAP_DOXYGEN
176 BOOST_YAP_USER_UNARY_OPERATOR(unary_plus, expression, expression) // +
177 BOOST_YAP_USER_UNARY_OPERATOR(negate, expression, expression) // -
178 BOOST_YAP_USER_UNARY_OPERATOR(dereference, expression, expression) // *
179 BOOST_YAP_USER_UNARY_OPERATOR(complement, expression, expression) // ~
180 BOOST_YAP_USER_UNARY_OPERATOR(address_of, expression, expression) // &
181 BOOST_YAP_USER_UNARY_OPERATOR(logical_not, expression, expression) // !
182 BOOST_YAP_USER_UNARY_OPERATOR(pre_inc, expression, expression) // ++
183 BOOST_YAP_USER_UNARY_OPERATOR(pre_dec, expression, expression) // --
184 BOOST_YAP_USER_UNARY_OPERATOR(post_inc, expression, expression) // ++(int)
185 BOOST_YAP_USER_UNARY_OPERATOR(post_dec, expression, expression) // --(int)
187 BOOST_YAP_USER_BINARY_OPERATOR(shift_left, expression, expression) // <<
188 BOOST_YAP_USER_BINARY_OPERATOR(shift_right, expression, expression) // >>
189 BOOST_YAP_USER_BINARY_OPERATOR(multiplies, expression, expression) // *
190 BOOST_YAP_USER_BINARY_OPERATOR(divides, expression, expression) // /
191 BOOST_YAP_USER_BINARY_OPERATOR(modulus, expression, expression) // %
192 BOOST_YAP_USER_BINARY_OPERATOR(plus, expression, expression) // +
193 BOOST_YAP_USER_BINARY_OPERATOR(minus, expression, expression) // -
194 BOOST_YAP_USER_BINARY_OPERATOR(less, expression, expression) // <
195 BOOST_YAP_USER_BINARY_OPERATOR(greater, expression, expression) // >
196 BOOST_YAP_USER_BINARY_OPERATOR(less_equal, expression, expression) // <=
197 BOOST_YAP_USER_BINARY_OPERATOR(greater_equal, expression, expression) // >=
198 BOOST_YAP_USER_BINARY_OPERATOR(equal_to, expression, expression) // ==
199 BOOST_YAP_USER_BINARY_OPERATOR(not_equal_to, expression, expression) // !=
200 BOOST_YAP_USER_BINARY_OPERATOR(logical_or, expression, expression) // ||
201 BOOST_YAP_USER_BINARY_OPERATOR(logical_and, expression, expression) // &&
202 BOOST_YAP_USER_BINARY_OPERATOR(bitwise_and, expression, expression) // &
203 BOOST_YAP_USER_BINARY_OPERATOR(bitwise_or, expression, expression) // |
204 BOOST_YAP_USER_BINARY_OPERATOR(bitwise_xor, expression, expression) // ^
205 BOOST_YAP_USER_BINARY_OPERATOR(comma, expression, expression) // ,
206 BOOST_YAP_USER_BINARY_OPERATOR(mem_ptr, expression, expression) // ->*
207 BOOST_YAP_USER_BINARY_OPERATOR(shift_left_assign, expression, expression) // <<=
208 BOOST_YAP_USER_BINARY_OPERATOR(shift_right_assign, expression, expression) // >>=
209 BOOST_YAP_USER_BINARY_OPERATOR(multiplies_assign, expression, expression) // *=
210 BOOST_YAP_USER_BINARY_OPERATOR(divides_assign, expression, expression) // /=
211 BOOST_YAP_USER_BINARY_OPERATOR(modulus_assign, expression, expression) // %=
212 BOOST_YAP_USER_BINARY_OPERATOR(plus_assign, expression, expression) // +=
213 BOOST_YAP_USER_BINARY_OPERATOR(minus_assign, expression, expression) // -=
214 BOOST_YAP_USER_BINARY_OPERATOR(bitwise_and_assign, expression, expression) // &=
215 BOOST_YAP_USER_BINARY_OPERATOR(bitwise_or_assign, expression, expression) // |=
216 BOOST_YAP_USER_BINARY_OPERATOR(bitwise_xor_assign, expression, expression) // ^=
218 BOOST_YAP_USER_EXPR_IF_ELSE(expression)
222 /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
223 template<typename Expr>
224 constexpr auto operator+(Expr &&);
225 /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
226 template<typename Expr>
227 constexpr auto operator-(Expr &&);
228 /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
229 template<typename Expr>
230 constexpr auto operator*(Expr &&);
231 /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
232 template<typename Expr>
233 constexpr auto operator~(Expr &&);
234 /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
235 template<typename Expr>
236 constexpr auto operator&(Expr &&);
237 /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
238 template<typename Expr>
239 constexpr auto operator!(Expr &&);
240 /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
241 template<typename Expr>
242 constexpr auto operator++(Expr &&);
243 /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
244 template<typename Expr>
245 constexpr auto operator--(Expr &&);
246 /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
247 template<typename Expr>
248 constexpr auto operator++(Expr &&, int);
249 /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
250 template<typename Expr>
251 constexpr auto operator--(Expr &&, int);
253 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
254 template<typename LExpr, typename RExpr>
255 constexpr auto operator<<(LExpr && lhs, RExpr && rhs);
256 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
257 template<typename LExpr, typename RExpr>
258 constexpr auto operator>>(LExpr && lhs, RExpr && rhs);
259 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
260 template<typename LExpr, typename RExpr>
261 constexpr auto operator*(LExpr && lhs, RExpr && rhs);
262 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
263 template<typename LExpr, typename RExpr>
264 constexpr auto operator/(LExpr && lhs, RExpr && rhs);
265 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
266 template<typename LExpr, typename RExpr>
267 constexpr auto operator%(LExpr && lhs, RExpr && rhs);
268 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
269 template<typename LExpr, typename RExpr>
270 constexpr auto operator+(LExpr && lhs, RExpr && rhs);
271 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
272 template<typename LExpr, typename RExpr>
273 constexpr auto operator-(LExpr && lhs, RExpr && rhs);
274 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
275 template<typename LExpr, typename RExpr>
276 constexpr auto operator<(LExpr && lhs, RExpr && rhs);
277 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
278 template<typename LExpr, typename RExpr>
279 constexpr auto operator>(LExpr && lhs, RExpr && rhs);
280 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
281 template<typename LExpr, typename RExpr>
282 constexpr auto operator<=(LExpr && lhs, RExpr && rhs);
283 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
284 template<typename LExpr, typename RExpr>
285 constexpr auto operator>=(LExpr && lhs, RExpr && rhs);
286 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
287 template<typename LExpr, typename RExpr>
288 constexpr auto operator==(LExpr && lhs, RExpr && rhs);
289 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
290 template<typename LExpr, typename RExpr>
291 constexpr auto operator!=(LExpr && lhs, RExpr && rhs);
292 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
293 template<typename LExpr, typename RExpr>
294 constexpr auto operator||(LExpr && lhs, RExpr && rhs);
295 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
296 template<typename LExpr, typename RExpr>
297 constexpr auto operator&&(LExpr && lhs, RExpr && rhs);
298 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
299 template<typename LExpr, typename RExpr>
300 constexpr auto operator&(LExpr && lhs, RExpr && rhs);
301 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
302 template<typename LExpr, typename RExpr>
303 constexpr auto operator|(LExpr && lhs, RExpr && rhs);
304 /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
305 template<typename LExpr, typename RExpr>
306 constexpr auto operator^(LExpr && lhs, RExpr && rhs);
308 /** \see BOOST_YAP_USER_EXPR_IF_ELSE for full semantics. */
309 template<typename Expr1, typename Expr2, typename Expr3>
310 constexpr auto if_else(Expr1 && expr1, Expr2 && expr2, Expr3 && expr3);
314 /** Returns <code>make_expression<boost::yap::expression, Kind>(...)</code>.
316 template<expr_kind Kind, typename... T>
317 constexpr auto make_expression(T &&... t)
319 return make_expression<expression, Kind>(static_cast<T &&>(t)...);
322 /** Returns <code>make_terminal<boost::yap::expression>(t)</code>. */
324 constexpr auto make_terminal(T && t)
326 return make_terminal<expression>(static_cast<T &&>(t));
329 /** Returns <code>as_expr<boost::yap::expression>(t)</code>. */
331 constexpr decltype(auto) as_expr(T && t)
333 return as_expr<expression>(static_cast<T &&>(t));