expression.hpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. // Copyright (C) 2016-2018 T. Zachary Laine
  2. //
  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
  8. #include <boost/yap/algorithm.hpp>
  9. namespace boost { namespace yap {
  10. /** Reference expression template that provides all operator overloads.
  11. \note Due to a limitation of Doxygen, each of the
  12. <code>value()</code>, <code>left()</code>, <code>right()</code>, and
  13. operator overloads listed here is a stand-in for three member
  14. functions. For each function <code>f</code>, the listing here is:
  15. \code return_type f (); \endcode However, there are actually three
  16. functions:
  17. \code
  18. return_type f () const &;
  19. return_type f () &;
  20. return_type f () &&;
  21. \endcode
  22. */
  23. template<expr_kind Kind, typename Tuple>
  24. struct expression
  25. {
  26. using tuple_type = Tuple;
  27. static const expr_kind kind = Kind;
  28. /** Default constructor. Does nothing. */
  29. constexpr expression() {}
  30. /** Moves \a rhs into the only data mamber, \c elements. */
  31. constexpr expression(tuple_type && rhs) :
  32. elements(static_cast<tuple_type &&>(rhs))
  33. {}
  34. tuple_type elements;
  35. /** A convenience member function that dispatches to the free function
  36. <code>value()</code>. */
  37. constexpr decltype(auto) value() &
  38. {
  39. return ::boost::yap::value(*this);
  40. }
  41. #ifndef BOOST_YAP_DOXYGEN
  42. constexpr decltype(auto) value() const &
  43. {
  44. return ::boost::yap::value(*this);
  45. }
  46. constexpr decltype(auto) value() &&
  47. {
  48. return ::boost::yap::value(std::move(*this));
  49. }
  50. #endif
  51. /** A convenience member function that dispatches to the free function
  52. <code>left()</code>. */
  53. constexpr decltype(auto) left() & { return ::boost::yap::left(*this); }
  54. #ifndef BOOST_YAP_DOXYGEN
  55. constexpr decltype(auto) left() const &
  56. {
  57. return ::boost::yap::left(*this);
  58. }
  59. constexpr decltype(auto) left() &&
  60. {
  61. return ::boost::yap::left(std::move(*this));
  62. }
  63. #endif
  64. /** A convenience member function that dispatches to the free function
  65. <code>right()</code>. */
  66. constexpr decltype(auto) right() &
  67. {
  68. return ::boost::yap::right(*this);
  69. }
  70. #ifndef BOOST_YAP_DOXYGEN
  71. constexpr decltype(auto) right() const &
  72. {
  73. return ::boost::yap::right(*this);
  74. }
  75. constexpr decltype(auto) right() &&
  76. {
  77. return ::boost::yap::right(std::move(*this));
  78. }
  79. #endif
  80. BOOST_YAP_USER_ASSIGN_OPERATOR(
  81. expression, ::boost::yap::expression) // =
  82. BOOST_YAP_USER_SUBSCRIPT_OPERATOR(::boost::yap::expression) // []
  83. BOOST_YAP_USER_CALL_OPERATOR(::boost::yap::expression) // ()
  84. };
  85. /** Terminal expression specialization of the reference expression
  86. template.
  87. \note Due to a limitation of Doxygen, the <code>value()</code> member
  88. and each of the operator overloads listed here is a stand-in for three
  89. member functions. For each function <code>f</code>, the listing here
  90. is: \code return_type f (); \endcode However, there are actually three
  91. functions:
  92. \code
  93. return_type f () const &;
  94. return_type f () &;
  95. return_type f () &&;
  96. \endcode
  97. */
  98. template<typename T>
  99. struct expression<expr_kind::terminal, hana::tuple<T>>
  100. {
  101. using tuple_type = hana::tuple<T>;
  102. static const expr_kind kind = expr_kind::terminal;
  103. /** Default constructor. Does nothing. */
  104. constexpr expression() {}
  105. /** Forwards \a t into \c elements. */
  106. constexpr expression(T && t) : elements(static_cast<T &&>(t)) {}
  107. /** Copies \a rhs into the only data mamber, \c elements. */
  108. constexpr expression(hana::tuple<T> const & rhs) : elements(rhs) {}
  109. /** Moves \a rhs into the only data mamber, \c elements. */
  110. constexpr expression(hana::tuple<T> && rhs) : elements(std::move(rhs))
  111. {}
  112. tuple_type elements;
  113. /** A convenience member function that dispatches to the free function
  114. <code>value()</code>. */
  115. constexpr decltype(auto) value() &
  116. {
  117. return ::boost::yap::value(*this);
  118. }
  119. #ifndef BOOST_YAP_DOXYGEN
  120. constexpr decltype(auto) value() const &
  121. {
  122. return ::boost::yap::value(*this);
  123. }
  124. constexpr decltype(auto) value() &&
  125. {
  126. return ::boost::yap::value(std::move(*this));
  127. }
  128. #endif
  129. BOOST_YAP_USER_ASSIGN_OPERATOR(
  130. expression, ::boost::yap::expression) // =
  131. BOOST_YAP_USER_SUBSCRIPT_OPERATOR(::boost::yap::expression) // []
  132. BOOST_YAP_USER_CALL_OPERATOR(::boost::yap::expression) // ()
  133. };
  134. #ifndef BOOST_YAP_DOXYGEN
  135. BOOST_YAP_USER_UNARY_OPERATOR(unary_plus, expression, expression) // +
  136. BOOST_YAP_USER_UNARY_OPERATOR(negate, expression, expression) // -
  137. BOOST_YAP_USER_UNARY_OPERATOR(dereference, expression, expression) // *
  138. BOOST_YAP_USER_UNARY_OPERATOR(complement, expression, expression) // ~
  139. BOOST_YAP_USER_UNARY_OPERATOR(address_of, expression, expression) // &
  140. BOOST_YAP_USER_UNARY_OPERATOR(logical_not, expression, expression) // !
  141. BOOST_YAP_USER_UNARY_OPERATOR(pre_inc, expression, expression) // ++
  142. BOOST_YAP_USER_UNARY_OPERATOR(pre_dec, expression, expression) // --
  143. BOOST_YAP_USER_UNARY_OPERATOR(post_inc, expression, expression) // ++(int)
  144. BOOST_YAP_USER_UNARY_OPERATOR(post_dec, expression, expression) // --(int)
  145. BOOST_YAP_USER_BINARY_OPERATOR(shift_left, expression, expression) // <<
  146. BOOST_YAP_USER_BINARY_OPERATOR(shift_right, expression, expression) // >>
  147. BOOST_YAP_USER_BINARY_OPERATOR(multiplies, expression, expression) // *
  148. BOOST_YAP_USER_BINARY_OPERATOR(divides, expression, expression) // /
  149. BOOST_YAP_USER_BINARY_OPERATOR(modulus, expression, expression) // %
  150. BOOST_YAP_USER_BINARY_OPERATOR(plus, expression, expression) // +
  151. BOOST_YAP_USER_BINARY_OPERATOR(minus, expression, expression) // -
  152. BOOST_YAP_USER_BINARY_OPERATOR(less, expression, expression) // <
  153. BOOST_YAP_USER_BINARY_OPERATOR(greater, expression, expression) // >
  154. BOOST_YAP_USER_BINARY_OPERATOR(less_equal, expression, expression) // <=
  155. BOOST_YAP_USER_BINARY_OPERATOR(greater_equal, expression, expression) // >=
  156. BOOST_YAP_USER_BINARY_OPERATOR(equal_to, expression, expression) // ==
  157. BOOST_YAP_USER_BINARY_OPERATOR(not_equal_to, expression, expression) // !=
  158. BOOST_YAP_USER_BINARY_OPERATOR(logical_or, expression, expression) // ||
  159. BOOST_YAP_USER_BINARY_OPERATOR(logical_and, expression, expression) // &&
  160. BOOST_YAP_USER_BINARY_OPERATOR(bitwise_and, expression, expression) // &
  161. BOOST_YAP_USER_BINARY_OPERATOR(bitwise_or, expression, expression) // |
  162. BOOST_YAP_USER_BINARY_OPERATOR(bitwise_xor, expression, expression) // ^
  163. BOOST_YAP_USER_BINARY_OPERATOR(comma, expression, expression) // ,
  164. BOOST_YAP_USER_BINARY_OPERATOR(mem_ptr, expression, expression) // ->*
  165. BOOST_YAP_USER_BINARY_OPERATOR(shift_left_assign, expression, expression) // <<=
  166. BOOST_YAP_USER_BINARY_OPERATOR(shift_right_assign, expression, expression) // >>=
  167. BOOST_YAP_USER_BINARY_OPERATOR(multiplies_assign, expression, expression) // *=
  168. BOOST_YAP_USER_BINARY_OPERATOR(divides_assign, expression, expression) // /=
  169. BOOST_YAP_USER_BINARY_OPERATOR(modulus_assign, expression, expression) // %=
  170. BOOST_YAP_USER_BINARY_OPERATOR(plus_assign, expression, expression) // +=
  171. BOOST_YAP_USER_BINARY_OPERATOR(minus_assign, expression, expression) // -=
  172. BOOST_YAP_USER_BINARY_OPERATOR(bitwise_and_assign, expression, expression) // &=
  173. BOOST_YAP_USER_BINARY_OPERATOR(bitwise_or_assign, expression, expression) // |=
  174. BOOST_YAP_USER_BINARY_OPERATOR(bitwise_xor_assign, expression, expression) // ^=
  175. BOOST_YAP_USER_EXPR_IF_ELSE(expression)
  176. #else
  177. /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
  178. template<typename Expr>
  179. constexpr auto operator+(Expr &&);
  180. /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
  181. template<typename Expr>
  182. constexpr auto operator-(Expr &&);
  183. /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
  184. template<typename Expr>
  185. constexpr auto operator*(Expr &&);
  186. /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
  187. template<typename Expr>
  188. constexpr auto operator~(Expr &&);
  189. /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
  190. template<typename Expr>
  191. constexpr auto operator&(Expr &&);
  192. /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
  193. template<typename Expr>
  194. constexpr auto operator!(Expr &&);
  195. /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
  196. template<typename Expr>
  197. constexpr auto operator++(Expr &&);
  198. /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
  199. template<typename Expr>
  200. constexpr auto operator--(Expr &&);
  201. /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
  202. template<typename Expr>
  203. constexpr auto operator++(Expr &&, int);
  204. /** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
  205. template<typename Expr>
  206. constexpr auto operator--(Expr &&, int);
  207. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  208. template<typename LExpr, typename RExpr>
  209. constexpr auto operator<<(LExpr && lhs, RExpr && rhs);
  210. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  211. template<typename LExpr, typename RExpr>
  212. constexpr auto operator>>(LExpr && lhs, RExpr && rhs);
  213. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  214. template<typename LExpr, typename RExpr>
  215. constexpr auto operator*(LExpr && lhs, RExpr && rhs);
  216. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  217. template<typename LExpr, typename RExpr>
  218. constexpr auto operator/(LExpr && lhs, RExpr && rhs);
  219. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  220. template<typename LExpr, typename RExpr>
  221. constexpr auto operator%(LExpr && lhs, RExpr && rhs);
  222. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  223. template<typename LExpr, typename RExpr>
  224. constexpr auto operator+(LExpr && lhs, RExpr && rhs);
  225. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  226. template<typename LExpr, typename RExpr>
  227. constexpr auto operator-(LExpr && lhs, RExpr && rhs);
  228. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  229. template<typename LExpr, typename RExpr>
  230. constexpr auto operator<(LExpr && lhs, RExpr && rhs);
  231. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  232. template<typename LExpr, typename RExpr>
  233. constexpr auto operator>(LExpr && lhs, RExpr && rhs);
  234. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  235. template<typename LExpr, typename RExpr>
  236. constexpr auto operator<=(LExpr && lhs, RExpr && rhs);
  237. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  238. template<typename LExpr, typename RExpr>
  239. constexpr auto operator>=(LExpr && lhs, RExpr && rhs);
  240. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  241. template<typename LExpr, typename RExpr>
  242. constexpr auto operator==(LExpr && lhs, RExpr && rhs);
  243. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  244. template<typename LExpr, typename RExpr>
  245. constexpr auto operator!=(LExpr && lhs, RExpr && rhs);
  246. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  247. template<typename LExpr, typename RExpr>
  248. constexpr auto operator||(LExpr && lhs, RExpr && rhs);
  249. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  250. template<typename LExpr, typename RExpr>
  251. constexpr auto operator&&(LExpr && lhs, RExpr && rhs);
  252. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  253. template<typename LExpr, typename RExpr>
  254. constexpr auto operator&(LExpr && lhs, RExpr && rhs);
  255. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  256. template<typename LExpr, typename RExpr>
  257. constexpr auto operator|(LExpr && lhs, RExpr && rhs);
  258. /** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
  259. template<typename LExpr, typename RExpr>
  260. constexpr auto operator^(LExpr && lhs, RExpr && rhs);
  261. /** \see BOOST_YAP_USER_EXPR_IF_ELSE for full semantics. */
  262. template<typename Expr1, typename Expr2, typename Expr3>
  263. constexpr auto if_else(Expr1 && expr1, Expr2 && expr2, Expr3 && expr3);
  264. #endif
  265. /** Returns <code>make_expression<boost::yap::expression, Kind>(...)</code>.
  266. */
  267. template<expr_kind Kind, typename... T>
  268. constexpr auto make_expression(T &&... t)
  269. {
  270. return make_expression<expression, Kind>(static_cast<T &&>(t)...);
  271. }
  272. /** Returns <code>make_terminal<boost::yap::expression>(t)</code>. */
  273. template<typename T>
  274. constexpr auto make_terminal(T && t)
  275. {
  276. return make_terminal<expression>(static_cast<T &&>(t));
  277. }
  278. /** Returns <code>as_expr<boost::yap::expression>(t)</code>. */
  279. template<typename T>
  280. constexpr decltype(auto) as_expr(T && t)
  281. {
  282. return as_expr<expression>(static_cast<T &&>(t));
  283. }
  284. }}
  285. #endif