File indexing completed on 2025-01-18 09:53:56
0001
0002
0003
0004
0005
0006 #ifndef BOOST_YAP_USER_MACROS_HPP_INCLUDED
0007 #define BOOST_YAP_USER_MACROS_HPP_INCLUDED
0008
0009 #include <boost/preprocessor/cat.hpp>
0010 #include <boost/preprocessor/repetition/enum_params.hpp>
0011 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
0012 #include <boost/preprocessor/repetition/enum.hpp>
0013
0014
0015 #ifndef BOOST_YAP_DOXYGEN
0016
0017
0018 #define BOOST_YAP_OPERATOR_unary_plus(...) +(__VA_ARGS__)
0019 #define BOOST_YAP_OPERATOR_negate(...) -(__VA_ARGS__)
0020 #define BOOST_YAP_OPERATOR_dereference(...) *(__VA_ARGS__)
0021 #define BOOST_YAP_OPERATOR_complement(...) ~(__VA_ARGS__)
0022 #define BOOST_YAP_OPERATOR_address_of(...) &(__VA_ARGS__)
0023 #define BOOST_YAP_OPERATOR_logical_not(...) !(__VA_ARGS__)
0024 #define BOOST_YAP_OPERATOR_pre_inc(...) ++(__VA_ARGS__)
0025 #define BOOST_YAP_OPERATOR_pre_dec(...) --(__VA_ARGS__)
0026 #define BOOST_YAP_OPERATOR_post_inc(...) ++(__VA_ARGS__, int)
0027 #define BOOST_YAP_OPERATOR_post_dec(...) --(__VA_ARGS__, int)
0028
0029
0030 #define BOOST_YAP_OPERATOR_shift_left(...) <<(__VA_ARGS__)
0031 #define BOOST_YAP_OPERATOR_shift_right(...) >>(__VA_ARGS__)
0032 #define BOOST_YAP_OPERATOR_multiplies(...) *(__VA_ARGS__)
0033 #define BOOST_YAP_OPERATOR_divides(...) /(__VA_ARGS__)
0034 #define BOOST_YAP_OPERATOR_modulus(...) %(__VA_ARGS__)
0035 #define BOOST_YAP_OPERATOR_plus(...) +(__VA_ARGS__)
0036 #define BOOST_YAP_OPERATOR_minus(...) -(__VA_ARGS__)
0037 #define BOOST_YAP_OPERATOR_less(...) <(__VA_ARGS__)
0038 #define BOOST_YAP_OPERATOR_greater(...) >(__VA_ARGS__)
0039 #define BOOST_YAP_OPERATOR_less_equal(...) <=(__VA_ARGS__)
0040 #define BOOST_YAP_OPERATOR_greater_equal(...) >=(__VA_ARGS__)
0041 #define BOOST_YAP_OPERATOR_equal_to(...) ==(__VA_ARGS__)
0042 #define BOOST_YAP_OPERATOR_not_equal_to(...) !=(__VA_ARGS__)
0043 #define BOOST_YAP_OPERATOR_logical_or(...) ||(__VA_ARGS__)
0044 #define BOOST_YAP_OPERATOR_logical_and(...) &&(__VA_ARGS__)
0045 #define BOOST_YAP_OPERATOR_bitwise_and(...) &(__VA_ARGS__)
0046 #define BOOST_YAP_OPERATOR_bitwise_or(...) |(__VA_ARGS__)
0047 #define BOOST_YAP_OPERATOR_bitwise_xor(...) ^(__VA_ARGS__)
0048 #define BOOST_YAP_OPERATOR_comma(...) ,(__VA_ARGS__)
0049 #define BOOST_YAP_OPERATOR_mem_ptr(...) ->*(__VA_ARGS__)
0050 #define BOOST_YAP_OPERATOR_assign(...) =(__VA_ARGS__)
0051 #define BOOST_YAP_OPERATOR_shift_left_assign(...) <<=(__VA_ARGS__)
0052 #define BOOST_YAP_OPERATOR_shift_right_assign(...) >>=(__VA_ARGS__)
0053 #define BOOST_YAP_OPERATOR_multiplies_assign(...) *=(__VA_ARGS__)
0054 #define BOOST_YAP_OPERATOR_divides_assign(...) /=(__VA_ARGS__)
0055 #define BOOST_YAP_OPERATOR_modulus_assign(...) %=(__VA_ARGS__)
0056 #define BOOST_YAP_OPERATOR_plus_assign(...) +=(__VA_ARGS__)
0057 #define BOOST_YAP_OPERATOR_minus_assign(...) -=(__VA_ARGS__)
0058 #define BOOST_YAP_OPERATOR_bitwise_and_assign(...) &=(__VA_ARGS__)
0059 #define BOOST_YAP_OPERATOR_bitwise_or_assign(...) |=(__VA_ARGS__)
0060 #define BOOST_YAP_OPERATOR_bitwise_xor_assign(...) ^=(__VA_ARGS__)
0061 #define BOOST_YAP_OPERATOR_subscript(...) [](__VA_ARGS__)
0062
0063 #define BOOST_YAP_INDIRECT_CALL(macro) BOOST_PP_CAT(BOOST_YAP_OPERATOR_, macro)
0064
0065 #endif
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 #define BOOST_YAP_USER_UNARY_OPERATOR( \
0092 op_name, expr_template, result_expr_template) \
0093 template<::boost::yap::expr_kind Kind, typename Tuple> \
0094 constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
0095 expr_template<Kind, Tuple> const & x) \
0096 { \
0097 using lhs_type = ::boost::yap::detail::operand_type_t< \
0098 result_expr_template, \
0099 expr_template<Kind, Tuple> const &>; \
0100 using tuple_type = ::boost::hana::tuple<lhs_type>; \
0101 return result_expr_template< \
0102 ::boost::yap::expr_kind::op_name, \
0103 tuple_type>{ \
0104 tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(x)}}; \
0105 } \
0106 template<::boost::yap::expr_kind Kind, typename Tuple> \
0107 constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
0108 expr_template<Kind, Tuple> & x) \
0109 { \
0110 using lhs_type = ::boost::yap::detail::operand_type_t< \
0111 result_expr_template, \
0112 expr_template<Kind, Tuple> &>; \
0113 using tuple_type = ::boost::hana::tuple<lhs_type>; \
0114 return result_expr_template< \
0115 ::boost::yap::expr_kind::op_name, \
0116 tuple_type>{ \
0117 tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(x)}}; \
0118 } \
0119 template<::boost::yap::expr_kind Kind, typename Tuple> \
0120 constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
0121 expr_template<Kind, Tuple> && x) \
0122 { \
0123 using tuple_type = ::boost::hana::tuple<expr_template<Kind, Tuple>>; \
0124 return result_expr_template< \
0125 ::boost::yap::expr_kind::op_name, \
0126 tuple_type>{tuple_type{std::move(x)}}; \
0127 }
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 #define BOOST_YAP_USER_BINARY_OPERATOR( \
0158 op_name, expr_template, result_expr_template) \
0159 template<::boost::yap::expr_kind Kind, typename Tuple, typename Expr> \
0160 constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
0161 expr_template<Kind, Tuple> const & lhs, Expr && rhs) \
0162 { \
0163 using lhs_type = ::boost::yap::detail::operand_type_t< \
0164 result_expr_template, \
0165 expr_template<Kind, Tuple> const &>; \
0166 using rhs_type = \
0167 ::boost::yap::detail::operand_type_t<result_expr_template, Expr>; \
0168 using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
0169 return result_expr_template< \
0170 ::boost::yap::expr_kind::op_name, \
0171 tuple_type>{ \
0172 tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(lhs), \
0173 ::boost::yap::detail::make_operand<rhs_type>{}( \
0174 static_cast<Expr &&>(rhs))}}; \
0175 } \
0176 template<::boost::yap::expr_kind Kind, typename Tuple, typename Expr> \
0177 constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
0178 expr_template<Kind, Tuple> & lhs, Expr && rhs) \
0179 { \
0180 using lhs_type = ::boost::yap::detail::operand_type_t< \
0181 result_expr_template, \
0182 expr_template<Kind, Tuple> &>; \
0183 using rhs_type = \
0184 ::boost::yap::detail::operand_type_t<result_expr_template, Expr>; \
0185 using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
0186 return result_expr_template< \
0187 ::boost::yap::expr_kind::op_name, \
0188 tuple_type>{ \
0189 tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(lhs), \
0190 ::boost::yap::detail::make_operand<rhs_type>{}( \
0191 static_cast<Expr &&>(rhs))}}; \
0192 } \
0193 template<::boost::yap::expr_kind Kind, typename Tuple, typename Expr> \
0194 constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
0195 expr_template<Kind, Tuple> && lhs, Expr && rhs) \
0196 { \
0197 using lhs_type = ::boost::yap::detail::remove_cv_ref_t< \
0198 expr_template<Kind, Tuple> &&>; \
0199 using rhs_type = \
0200 ::boost::yap::detail::operand_type_t<result_expr_template, Expr>; \
0201 using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
0202 return result_expr_template< \
0203 ::boost::yap::expr_kind::op_name, \
0204 tuple_type>{ \
0205 tuple_type{std::move(lhs), \
0206 ::boost::yap::detail::make_operand<rhs_type>{}( \
0207 static_cast<Expr &&>(rhs))}}; \
0208 } \
0209 template<typename T, ::boost::yap::expr_kind Kind, typename Tuple> \
0210 constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
0211 T && lhs, expr_template<Kind, Tuple> && rhs) \
0212 ->::boost::yap::detail::free_binary_op_result_t< \
0213 result_expr_template, \
0214 ::boost::yap::expr_kind::op_name, \
0215 T, \
0216 expr_template<Kind, Tuple> &&> \
0217 { \
0218 using result_types = ::boost::yap::detail::free_binary_op_result< \
0219 result_expr_template, \
0220 ::boost::yap::expr_kind::op_name, \
0221 T, \
0222 expr_template<Kind, Tuple> &&>; \
0223 using lhs_type = typename result_types::lhs_type; \
0224 using rhs_type = typename result_types::rhs_type; \
0225 using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
0226 return {tuple_type{lhs_type{static_cast<T &&>(lhs)}, std::move(rhs)}}; \
0227 } \
0228 template<typename T, ::boost::yap::expr_kind Kind, typename Tuple> \
0229 constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
0230 T && lhs, expr_template<Kind, Tuple> const & rhs) \
0231 ->::boost::yap::detail::free_binary_op_result_t< \
0232 result_expr_template, \
0233 ::boost::yap::expr_kind::op_name, \
0234 T, \
0235 expr_template<Kind, Tuple> const &> \
0236 { \
0237 using result_types = ::boost::yap::detail::free_binary_op_result< \
0238 result_expr_template, \
0239 ::boost::yap::expr_kind::op_name, \
0240 T, \
0241 expr_template<Kind, Tuple> const &>; \
0242 using lhs_type = typename result_types::lhs_type; \
0243 using rhs_type = typename result_types::rhs_type; \
0244 using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
0245 using rhs_tuple_type = typename result_types::rhs_tuple_type; \
0246 return {tuple_type{lhs_type{static_cast<T &&>(lhs)}, \
0247 rhs_type{rhs_tuple_type{std::addressof(rhs)}}}}; \
0248 } \
0249 template<typename T, ::boost::yap::expr_kind Kind, typename Tuple> \
0250 constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
0251 T && lhs, expr_template<Kind, Tuple> & rhs) \
0252 ->::boost::yap::detail::free_binary_op_result_t< \
0253 result_expr_template, \
0254 ::boost::yap::expr_kind::op_name, \
0255 T, \
0256 expr_template<Kind, Tuple> &> \
0257 { \
0258 using result_types = ::boost::yap::detail::free_binary_op_result< \
0259 result_expr_template, \
0260 ::boost::yap::expr_kind::op_name, \
0261 T, \
0262 expr_template<Kind, Tuple> &>; \
0263 using lhs_type = typename result_types::lhs_type; \
0264 using rhs_type = typename result_types::rhs_type; \
0265 using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
0266 using rhs_tuple_type = typename result_types::rhs_tuple_type; \
0267 return {tuple_type{lhs_type{static_cast<T &&>(lhs)}, \
0268 rhs_type{rhs_tuple_type{std::addressof(rhs)}}}}; \
0269 }
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297 #define BOOST_YAP_USER_ASSIGN_OPERATOR(this_type, expr_template) \
0298 template< \
0299 typename Expr, \
0300 typename = std::enable_if_t< \
0301 !::boost::yap::detail::copy_or_move<this_type, Expr &&>::value>> \
0302 constexpr auto operator=(Expr && rhs) const & \
0303 { \
0304 using lhs_type = ::boost::yap::detail:: \
0305 operand_type_t<expr_template, this_type const &>; \
0306 using rhs_type = \
0307 ::boost::yap::detail::operand_type_t<expr_template, Expr>; \
0308 using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
0309 return expr_template<::boost::yap::expr_kind::assign, tuple_type>{ \
0310 tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(*this), \
0311 ::boost::yap::detail::make_operand<rhs_type>{}( \
0312 static_cast<Expr &&>(rhs))}}; \
0313 } \
0314 template< \
0315 typename Expr, \
0316 typename = std::enable_if_t< \
0317 !::boost::yap::detail::copy_or_move<this_type, Expr &&>::value>> \
0318 constexpr auto operator=(Expr && rhs) & \
0319 { \
0320 using lhs_type = ::boost::yap::detail:: \
0321 operand_type_t<expr_template, decltype(*this)>; \
0322 using rhs_type = \
0323 ::boost::yap::detail::operand_type_t<expr_template, Expr>; \
0324 using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
0325 return expr_template<::boost::yap::expr_kind::assign, tuple_type>{ \
0326 tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(*this), \
0327 ::boost::yap::detail::make_operand<rhs_type>{}( \
0328 static_cast<Expr &&>(rhs))}}; \
0329 } \
0330 template< \
0331 typename Expr, \
0332 typename = std::enable_if_t< \
0333 !::boost::yap::detail::copy_or_move<this_type, Expr &&>::value>> \
0334 constexpr auto operator=(Expr && rhs) && \
0335 { \
0336 using rhs_type = \
0337 ::boost::yap::detail::operand_type_t<expr_template, Expr>; \
0338 using tuple_type = ::boost::hana::tuple<this_type, rhs_type>; \
0339 return expr_template<::boost::yap::expr_kind::assign, tuple_type>{ \
0340 tuple_type{std::move(*this), \
0341 ::boost::yap::detail::make_operand<rhs_type>{}( \
0342 static_cast<Expr &&>(rhs))}}; \
0343 }
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367 #define BOOST_YAP_USER_SUBSCRIPT_OPERATOR(expr_template) \
0368 template<typename Expr> \
0369 constexpr auto operator[](Expr && rhs) const & \
0370 { \
0371 using lhs_type = ::boost::yap::detail:: \
0372 operand_type_t<expr_template, decltype(*this)>; \
0373 using rhs_type = \
0374 ::boost::yap::detail::operand_type_t<expr_template, Expr>; \
0375 using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
0376 return expr_template<::boost::yap::expr_kind::subscript, tuple_type>{ \
0377 tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(*this), \
0378 ::boost::yap::detail::make_operand<rhs_type>{}( \
0379 static_cast<Expr &&>(rhs))}}; \
0380 } \
0381 template<typename Expr> \
0382 constexpr auto operator[](Expr && rhs) & \
0383 { \
0384 using lhs_type = ::boost::yap::detail:: \
0385 operand_type_t<expr_template, decltype(*this)>; \
0386 using rhs_type = \
0387 ::boost::yap::detail::operand_type_t<expr_template, Expr>; \
0388 using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
0389 return expr_template<::boost::yap::expr_kind::subscript, tuple_type>{ \
0390 tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(*this), \
0391 ::boost::yap::detail::make_operand<rhs_type>{}( \
0392 static_cast<Expr &&>(rhs))}}; \
0393 } \
0394 template<typename Expr> \
0395 constexpr auto operator[](Expr && rhs) && \
0396 { \
0397 using lhs_type = \
0398 ::boost::yap::detail::remove_cv_ref_t<decltype(*this)>; \
0399 using rhs_type = \
0400 ::boost::yap::detail::operand_type_t<expr_template, Expr>; \
0401 using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
0402 return expr_template<::boost::yap::expr_kind::subscript, tuple_type>{ \
0403 tuple_type{std::move(*this), \
0404 ::boost::yap::detail::make_operand<rhs_type>{}( \
0405 static_cast<Expr &&>(rhs))}}; \
0406 }
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429 #define BOOST_YAP_USER_CALL_OPERATOR(expr_template) \
0430 template<typename... U> \
0431 constexpr auto operator()(U &&... u) const & \
0432 { \
0433 using lhs_type = ::boost::yap::detail:: \
0434 operand_type_t<expr_template, decltype(*this)>; \
0435 using tuple_type = ::boost::hana::tuple< \
0436 lhs_type, \
0437 ::boost::yap::detail::operand_type_t<expr_template, U>...>; \
0438 return expr_template<::boost::yap::expr_kind::call, tuple_type>{ \
0439 tuple_type{ \
0440 ::boost::yap::detail::make_operand<lhs_type>{}(*this), \
0441 ::boost::yap::detail::make_operand< \
0442 ::boost::yap::detail::operand_type_t<expr_template, U>>{}( \
0443 static_cast<U &&>(u))...}}; \
0444 } \
0445 template<typename... U> \
0446 constexpr auto operator()(U &&... u) & \
0447 { \
0448 using lhs_type = ::boost::yap::detail:: \
0449 operand_type_t<expr_template, decltype(*this)>; \
0450 using tuple_type = ::boost::hana::tuple< \
0451 lhs_type, \
0452 ::boost::yap::detail::operand_type_t<expr_template, U>...>; \
0453 return expr_template<::boost::yap::expr_kind::call, tuple_type>{ \
0454 tuple_type{ \
0455 ::boost::yap::detail::make_operand<lhs_type>{}(*this), \
0456 ::boost::yap::detail::make_operand< \
0457 ::boost::yap::detail::operand_type_t<expr_template, U>>{}( \
0458 static_cast<U &&>(u))...}}; \
0459 } \
0460 template<typename... U> \
0461 constexpr auto operator()(U &&... u) && \
0462 { \
0463 using this_type = \
0464 ::boost::yap::detail::remove_cv_ref_t<decltype(*this)>; \
0465 using tuple_type = ::boost::hana::tuple< \
0466 this_type, \
0467 ::boost::yap::detail::operand_type_t<expr_template, U>...>; \
0468 return expr_template<::boost::yap::expr_kind::call, tuple_type>{ \
0469 tuple_type{ \
0470 std::move(*this), \
0471 ::boost::yap::detail::make_operand< \
0472 ::boost::yap::detail::operand_type_t<expr_template, U>>{}( \
0473 static_cast<U &&>(u))...}}; \
0474 }
0475
0476
0477 #ifndef BOOST_YAP_DOXYGEN
0478
0479 #define BOOST_YAP_USER_CALL_OPERATOR_OPERAND_T(z, n, expr_template) \
0480 ::boost::yap::detail::operand_type_t<expr_template, BOOST_PP_CAT(U, n)>
0481 #define BOOST_YAP_USER_CALL_OPERATOR_MAKE_OPERAND(z, n, expr_template) \
0482 ::boost::yap::detail::make_operand<::boost::yap::detail::operand_type_t< \
0483 expr_template, \
0484 BOOST_PP_CAT(U, n)>>{}( \
0485 static_cast<BOOST_PP_CAT(U, n) &&>(BOOST_PP_CAT(u, n)))
0486
0487 #endif
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512 #define BOOST_YAP_USER_CALL_OPERATOR_N(expr_template, n) \
0513 template<BOOST_PP_ENUM_PARAMS(n, typename U)> \
0514 constexpr auto operator()(BOOST_PP_ENUM_BINARY_PARAMS(n, U, &&u)) const & \
0515 { \
0516 using lhs_type = ::boost::yap::detail:: \
0517 operand_type_t<expr_template, decltype(*this)>; \
0518 using tuple_type = ::boost::hana::tuple< \
0519 lhs_type, \
0520 BOOST_PP_ENUM( \
0521 n, BOOST_YAP_USER_CALL_OPERATOR_OPERAND_T, expr_template)>; \
0522 return expr_template<::boost::yap::expr_kind::call, tuple_type>{ \
0523 tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(*this), \
0524 BOOST_PP_ENUM( \
0525 n, \
0526 BOOST_YAP_USER_CALL_OPERATOR_MAKE_OPERAND, \
0527 expr_template)}}; \
0528 } \
0529 template<BOOST_PP_ENUM_PARAMS(n, typename U)> \
0530 constexpr auto operator()(BOOST_PP_ENUM_BINARY_PARAMS(n, U, &&u)) & \
0531 { \
0532 using lhs_type = ::boost::yap::detail:: \
0533 operand_type_t<expr_template, decltype(*this)>; \
0534 using tuple_type = ::boost::hana::tuple< \
0535 lhs_type, \
0536 BOOST_PP_ENUM( \
0537 n, BOOST_YAP_USER_CALL_OPERATOR_OPERAND_T, expr_template)>; \
0538 return expr_template<::boost::yap::expr_kind::call, tuple_type>{ \
0539 tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(*this), \
0540 BOOST_PP_ENUM( \
0541 n, \
0542 BOOST_YAP_USER_CALL_OPERATOR_MAKE_OPERAND, \
0543 expr_template)}}; \
0544 } \
0545 template<BOOST_PP_ENUM_PARAMS(n, typename U)> \
0546 constexpr auto operator()(BOOST_PP_ENUM_BINARY_PARAMS(n, U, &&u)) && \
0547 { \
0548 using this_type = \
0549 ::boost::yap::detail::remove_cv_ref_t<decltype(*this)>; \
0550 using tuple_type = ::boost::hana::tuple< \
0551 this_type, \
0552 BOOST_PP_ENUM( \
0553 n, BOOST_YAP_USER_CALL_OPERATOR_OPERAND_T, expr_template)>; \
0554 return expr_template<::boost::yap::expr_kind::call, tuple_type>{ \
0555 tuple_type{std::move(*this), \
0556 BOOST_PP_ENUM( \
0557 n, \
0558 BOOST_YAP_USER_CALL_OPERATOR_MAKE_OPERAND, \
0559 expr_template)}}; \
0560 }
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582 #define BOOST_YAP_USER_EXPR_IF_ELSE(expr_template) \
0583 template<typename Expr1, typename Expr2, typename Expr3> \
0584 constexpr auto if_else(Expr1 && expr1, Expr2 && expr2, Expr3 && expr3) \
0585 ->::boost::yap::detail:: \
0586 ternary_op_result_t<expr_template, Expr1, Expr2, Expr3> \
0587 { \
0588 using result_types = ::boost::yap::detail:: \
0589 ternary_op_result<expr_template, Expr1, Expr2, Expr3>; \
0590 using cond_type = typename result_types::cond_type; \
0591 using then_type = typename result_types::then_type; \
0592 using else_type = typename result_types::else_type; \
0593 using tuple_type = \
0594 ::boost::hana::tuple<cond_type, then_type, else_type>; \
0595 return {tuple_type{::boost::yap::detail::make_operand<cond_type>{}( \
0596 static_cast<Expr1 &&>(expr1)), \
0597 ::boost::yap::detail::make_operand<then_type>{}( \
0598 static_cast<Expr2 &&>(expr2)), \
0599 ::boost::yap::detail::make_operand<else_type>{}( \
0600 static_cast<Expr3 &&>(expr3))}}; \
0601 }
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624 #define BOOST_YAP_USER_UDT_ANY_IF_ELSE(expr_template, udt_trait) \
0625 template<typename Expr1, typename Expr2, typename Expr3> \
0626 constexpr auto if_else(Expr1 && expr1, Expr2 && expr2, Expr3 && expr3) \
0627 ->::boost::yap::detail::udt_any_ternary_op_result_t< \
0628 expr_template, \
0629 Expr1, \
0630 Expr2, \
0631 Expr3, \
0632 udt_trait> \
0633 { \
0634 using result_types = ::boost::yap::detail::udt_any_ternary_op_result< \
0635 expr_template, \
0636 Expr1, \
0637 Expr2, \
0638 Expr3, \
0639 udt_trait>; \
0640 using cond_type = typename result_types::cond_type; \
0641 using then_type = typename result_types::then_type; \
0642 using else_type = typename result_types::else_type; \
0643 using tuple_type = \
0644 ::boost::hana::tuple<cond_type, then_type, else_type>; \
0645 return {tuple_type{::boost::yap::detail::make_operand<cond_type>{}( \
0646 static_cast<Expr1 &&>(expr1)), \
0647 ::boost::yap::detail::make_operand<then_type>{}( \
0648 static_cast<Expr2 &&>(expr2)), \
0649 ::boost::yap::detail::make_operand<else_type>{}( \
0650 static_cast<Expr3 &&>(expr3))}}; \
0651 }
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677 #define BOOST_YAP_USER_UDT_UNARY_OPERATOR(op_name, expr_template, udt_trait) \
0678 template<typename T> \
0679 constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)(T && x) \
0680 ->::boost::yap::detail::udt_unary_op_result_t< \
0681 expr_template, \
0682 ::boost::yap::expr_kind::op_name, \
0683 T, \
0684 udt_trait> \
0685 { \
0686 using result_types = ::boost::yap::detail::udt_unary_op_result< \
0687 expr_template, \
0688 ::boost::yap::expr_kind::op_name, \
0689 T, \
0690 udt_trait>; \
0691 using x_type = typename result_types::x_type; \
0692 using tuple_type = ::boost::hana::tuple<x_type>; \
0693 return {tuple_type{x_type{static_cast<T &&>(x)}}}; \
0694 }
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725
0726
0727
0728 #define BOOST_YAP_USER_UDT_UDT_BINARY_OPERATOR( \
0729 op_name, expr_template, t_udt_trait, u_udt_trait) \
0730 template<typename T, typename U> \
0731 constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)(T && lhs, U && rhs) \
0732 ->::boost::yap::detail::udt_udt_binary_op_result_t< \
0733 expr_template, \
0734 ::boost::yap::expr_kind::op_name, \
0735 T, \
0736 U, \
0737 t_udt_trait, \
0738 u_udt_trait> \
0739 { \
0740 using result_types = ::boost::yap::detail::udt_udt_binary_op_result< \
0741 expr_template, \
0742 ::boost::yap::expr_kind::op_name, \
0743 T, \
0744 U, \
0745 t_udt_trait, \
0746 u_udt_trait>; \
0747 using lhs_type = typename result_types::lhs_type; \
0748 using rhs_type = typename result_types::rhs_type; \
0749 using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
0750 return {tuple_type{ \
0751 lhs_type{static_cast<T &&>(lhs)}, \
0752 rhs_type{static_cast<U &&>(rhs)}, \
0753 }}; \
0754 }
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783
0784 #define BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR( \
0785 op_name, expr_template, udt_trait) \
0786 template<typename T, typename U> \
0787 constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)(T && lhs, U && rhs) \
0788 ->::boost::yap::detail::udt_any_binary_op_result_t< \
0789 expr_template, \
0790 ::boost::yap::expr_kind::op_name, \
0791 T, \
0792 U, \
0793 udt_trait> \
0794 { \
0795 using result_types = ::boost::yap::detail::udt_any_binary_op_result< \
0796 expr_template, \
0797 ::boost::yap::expr_kind::op_name, \
0798 T, \
0799 U, \
0800 udt_trait>; \
0801 using lhs_type = typename result_types::lhs_type; \
0802 using rhs_type = typename result_types::rhs_type; \
0803 using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
0804 return {tuple_type{lhs_type{static_cast<T &&>(lhs)}, \
0805 rhs_type{static_cast<U &&>(rhs)}}}; \
0806 }
0807
0808
0809
0810
0811
0812
0813
0814
0815
0816
0817 #define BOOST_YAP_USER_LITERAL_PLACEHOLDER_OPERATOR(expr_template) \
0818 template<char... c> \
0819 constexpr auto operator"" _p() \
0820 { \
0821 using i = ::boost::hana::llong< \
0822 ::boost::hana::ic_detail::parse<sizeof...(c)>({c...})>; \
0823 static_assert(1 <= i::value, "Placeholders must be >= 1."); \
0824 return expr_template< \
0825 ::boost::yap::expr_kind::terminal, \
0826 ::boost::hana::tuple<::boost::yap::placeholder<i::value>>>{}; \
0827 }
0828
0829 #endif