123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829 |
- // Copyright (C) 2016-2018 T. Zachary Laine
- //
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_YAP_USER_MACROS_HPP_INCLUDED
- #define BOOST_YAP_USER_MACROS_HPP_INCLUDED
- #include <boost/preprocessor/cat.hpp>
- #include <boost/preprocessor/repetition/enum_params.hpp>
- #include <boost/preprocessor/repetition/enum_binary_params.hpp>
- #include <boost/preprocessor/repetition/enum.hpp>
- #ifndef BOOST_YAP_DOXYGEN
- // unary
- #define BOOST_YAP_OPERATOR_unary_plus(...) +(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_negate(...) -(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_dereference(...) *(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_complement(...) ~(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_address_of(...) &(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_logical_not(...) !(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_pre_inc(...) ++(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_pre_dec(...) --(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_post_inc(...) ++(__VA_ARGS__, int)
- #define BOOST_YAP_OPERATOR_post_dec(...) --(__VA_ARGS__, int)
- // binary
- #define BOOST_YAP_OPERATOR_shift_left(...) <<(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_shift_right(...) >>(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_multiplies(...) *(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_divides(...) /(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_modulus(...) %(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_plus(...) +(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_minus(...) -(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_less(...) <(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_greater(...) >(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_less_equal(...) <=(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_greater_equal(...) >=(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_equal_to(...) ==(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_not_equal_to(...) !=(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_logical_or(...) ||(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_logical_and(...) &&(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_bitwise_and(...) &(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_bitwise_or(...) |(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_bitwise_xor(...) ^(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_comma(...) ,(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_mem_ptr(...) ->*(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_assign(...) =(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_shift_left_assign(...) <<=(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_shift_right_assign(...) >>=(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_multiplies_assign(...) *=(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_divides_assign(...) /=(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_modulus_assign(...) %=(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_plus_assign(...) +=(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_minus_assign(...) -=(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_bitwise_and_assign(...) &=(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_bitwise_or_assign(...) |=(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_bitwise_xor_assign(...) ^=(__VA_ARGS__)
- #define BOOST_YAP_OPERATOR_subscript(...) [](__VA_ARGS__)
- #define BOOST_YAP_INDIRECT_CALL(macro) BOOST_PP_CAT(BOOST_YAP_OPERATOR_, macro)
- #endif // BOOST_YAP_DOXYGEN
- /** Defines operator overloads for unary operator \a op_name that each take an
- expression instantiated from \a expr_template and return an expression
- instantiated from the \a result_expr_template expression template. One
- overload is defined for each of the qualifiers <code>const &</code>,
- <code>&</code>, and <code>&&</code>. For the lvalue reference overloads,
- the argument is captured by reference into the resulting expression. For
- the rvalue reference overload, the argument is moved into the resulting
- expression.
- Example:
- \snippet user_macros_snippets.cpp USER_UNARY_OPERATOR
- \param op_name The operator to be overloaded; this must be one of the \b
- unary enumerators in <code>expr_kind</code>, without the
- <code>expr_kind::</code> qualification.
- \param expr_template The expression template to which the overloads apply.
- \a expr_template must be an \ref ExpressionTemplate.
- \param result_expr_template The expression template to use to instantiate
- the result expression. \a result_expr_template must be an \ref
- ExpressionTemplate.
- */
- #define BOOST_YAP_USER_UNARY_OPERATOR( \
- op_name, expr_template, result_expr_template) \
- template<::boost::yap::expr_kind Kind, typename Tuple> \
- constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
- expr_template<Kind, Tuple> const & x) \
- { \
- using lhs_type = ::boost::yap::detail::operand_type_t< \
- result_expr_template, \
- expr_template<Kind, Tuple> const &>; \
- using tuple_type = ::boost::hana::tuple<lhs_type>; \
- return result_expr_template< \
- ::boost::yap::expr_kind::op_name, \
- tuple_type>{ \
- tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(x)}}; \
- } \
- template<::boost::yap::expr_kind Kind, typename Tuple> \
- constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
- expr_template<Kind, Tuple> & x) \
- { \
- using lhs_type = ::boost::yap::detail::operand_type_t< \
- result_expr_template, \
- expr_template<Kind, Tuple> &>; \
- using tuple_type = ::boost::hana::tuple<lhs_type>; \
- return result_expr_template< \
- ::boost::yap::expr_kind::op_name, \
- tuple_type>{ \
- tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(x)}}; \
- } \
- template<::boost::yap::expr_kind Kind, typename Tuple> \
- constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
- expr_template<Kind, Tuple> && x) \
- { \
- using tuple_type = ::boost::hana::tuple<expr_template<Kind, Tuple>>; \
- return result_expr_template< \
- ::boost::yap::expr_kind::op_name, \
- tuple_type>{tuple_type{std::move(x)}}; \
- }
- /** Defines operator overloads for binary operator \a op_name that each
- produce an expression instantiated from the \a expr_template expression
- template. One overload is defined for each of the qualifiers <code>const
- &</code>, <code>&</code>, and <code>&&</code>. For the lvalue reference
- overloads, <code>*this</code> is captured by reference into the resulting
- expression. For the rvalue reference overload, <code>*this</code> is
- moved into the resulting expression.
- Note that this does not work for yap::expr_kinds assign, subscript, or
- call. Use BOOST_YAP_USER_ASSIGN_OPERATOR,
- BOOST_YAP_USER_SUBSCRIPT_OPERATOR, or BOOST_YAP_USER_CALL_OPERATOR for
- those, respectively.
- Example:
- \snippet user_macros_snippets.cpp USER_BINARY_OPERATOR
- \param op_name The operator to be overloaded; this must be one of the \b
- binary enumerators in <code>expr_kind</code>, except assign, subscript, or
- call, without the <code>expr_kind::</code> qualification.
- \param expr_template The expression template to which the overloads apply.
- \a expr_template must be an \ref ExpressionTemplate.
- \param result_expr_template The expression template to use to instantiate
- the result expression. \a result_expr_template must be an \ref
- ExpressionTemplate.
- */
- #define BOOST_YAP_USER_BINARY_OPERATOR( \
- op_name, expr_template, result_expr_template) \
- template<::boost::yap::expr_kind Kind, typename Tuple, typename Expr> \
- constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
- expr_template<Kind, Tuple> const & lhs, Expr && rhs) \
- { \
- using lhs_type = ::boost::yap::detail::operand_type_t< \
- result_expr_template, \
- expr_template<Kind, Tuple> const &>; \
- using rhs_type = \
- ::boost::yap::detail::operand_type_t<result_expr_template, Expr>; \
- using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
- return result_expr_template< \
- ::boost::yap::expr_kind::op_name, \
- tuple_type>{ \
- tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(lhs), \
- ::boost::yap::detail::make_operand<rhs_type>{}( \
- static_cast<Expr &&>(rhs))}}; \
- } \
- template<::boost::yap::expr_kind Kind, typename Tuple, typename Expr> \
- constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
- expr_template<Kind, Tuple> & lhs, Expr && rhs) \
- { \
- using lhs_type = ::boost::yap::detail::operand_type_t< \
- result_expr_template, \
- expr_template<Kind, Tuple> &>; \
- using rhs_type = \
- ::boost::yap::detail::operand_type_t<result_expr_template, Expr>; \
- using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
- return result_expr_template< \
- ::boost::yap::expr_kind::op_name, \
- tuple_type>{ \
- tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(lhs), \
- ::boost::yap::detail::make_operand<rhs_type>{}( \
- static_cast<Expr &&>(rhs))}}; \
- } \
- template<::boost::yap::expr_kind Kind, typename Tuple, typename Expr> \
- constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
- expr_template<Kind, Tuple> && lhs, Expr && rhs) \
- { \
- using lhs_type = ::boost::yap::detail::remove_cv_ref_t< \
- expr_template<Kind, Tuple> &&>; \
- using rhs_type = \
- ::boost::yap::detail::operand_type_t<result_expr_template, Expr>; \
- using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
- return result_expr_template< \
- ::boost::yap::expr_kind::op_name, \
- tuple_type>{ \
- tuple_type{std::move(lhs), \
- ::boost::yap::detail::make_operand<rhs_type>{}( \
- static_cast<Expr &&>(rhs))}}; \
- } \
- template<typename T, ::boost::yap::expr_kind Kind, typename Tuple> \
- constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
- T && lhs, expr_template<Kind, Tuple> && rhs) \
- ->::boost::yap::detail::free_binary_op_result_t< \
- result_expr_template, \
- ::boost::yap::expr_kind::op_name, \
- T, \
- expr_template<Kind, Tuple> &&> \
- { \
- using result_types = ::boost::yap::detail::free_binary_op_result< \
- result_expr_template, \
- ::boost::yap::expr_kind::op_name, \
- T, \
- expr_template<Kind, Tuple> &&>; \
- using lhs_type = typename result_types::lhs_type; \
- using rhs_type = typename result_types::rhs_type; \
- using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
- return {tuple_type{lhs_type{static_cast<T &&>(lhs)}, std::move(rhs)}}; \
- } \
- template<typename T, ::boost::yap::expr_kind Kind, typename Tuple> \
- constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
- T && lhs, expr_template<Kind, Tuple> const & rhs) \
- ->::boost::yap::detail::free_binary_op_result_t< \
- result_expr_template, \
- ::boost::yap::expr_kind::op_name, \
- T, \
- expr_template<Kind, Tuple> const &> \
- { \
- using result_types = ::boost::yap::detail::free_binary_op_result< \
- result_expr_template, \
- ::boost::yap::expr_kind::op_name, \
- T, \
- expr_template<Kind, Tuple> const &>; \
- using lhs_type = typename result_types::lhs_type; \
- using rhs_type = typename result_types::rhs_type; \
- using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
- using rhs_tuple_type = typename result_types::rhs_tuple_type; \
- return {tuple_type{lhs_type{static_cast<T &&>(lhs)}, \
- rhs_type{rhs_tuple_type{std::addressof(rhs)}}}}; \
- } \
- template<typename T, ::boost::yap::expr_kind Kind, typename Tuple> \
- constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)( \
- T && lhs, expr_template<Kind, Tuple> & rhs) \
- ->::boost::yap::detail::free_binary_op_result_t< \
- result_expr_template, \
- ::boost::yap::expr_kind::op_name, \
- T, \
- expr_template<Kind, Tuple> &> \
- { \
- using result_types = ::boost::yap::detail::free_binary_op_result< \
- result_expr_template, \
- ::boost::yap::expr_kind::op_name, \
- T, \
- expr_template<Kind, Tuple> &>; \
- using lhs_type = typename result_types::lhs_type; \
- using rhs_type = typename result_types::rhs_type; \
- using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
- using rhs_tuple_type = typename result_types::rhs_tuple_type; \
- return {tuple_type{lhs_type{static_cast<T &&>(lhs)}, \
- rhs_type{rhs_tuple_type{std::addressof(rhs)}}}}; \
- }
- /** Defines operator overloads for \a operator=() that each produce an
- expression instantiated from the \a expr_template expression template.
- One overload is defined for each of the qualifiers <code>const &</code>,
- <code>&</code>, and <code>&&</code>. For the lvalue reference overloads,
- <code>*this</code> is captured by reference into the resulting expression.
- For the rvalue reference overload, <code>*this</code> is moved into the
- resulting expression.
- The \a rhs parameter to each of the defined overloads may be any type,
- including an expression, except that the overloads are constrained by
- std::enable_if<> not to conflict with the assignment and move assignement
- operators. If \a rhs is a non-expression, it is wrapped in a terminal
- expression.
- Example:
- \snippet user_macros_snippets.cpp USER_ASSIGN_OPERATOR
- \param this_type The type of the class the operator is a member of; this
- is required to avoid clashing with the assignment and move assignement
- operators.
- \param expr_template The expression template to use to instantiate the
- result expression. \a expr_template must be an \ref
- ExpressionTemplate.
- */
- #define BOOST_YAP_USER_ASSIGN_OPERATOR(this_type, expr_template) \
- template< \
- typename Expr, \
- typename = std::enable_if_t< \
- !::boost::yap::detail::copy_or_move<this_type, Expr &&>::value>> \
- constexpr auto operator=(Expr && rhs) const & \
- { \
- using lhs_type = ::boost::yap::detail:: \
- operand_type_t<expr_template, this_type const &>; \
- using rhs_type = \
- ::boost::yap::detail::operand_type_t<expr_template, Expr>; \
- using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
- return expr_template<::boost::yap::expr_kind::assign, tuple_type>{ \
- tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(*this), \
- ::boost::yap::detail::make_operand<rhs_type>{}( \
- static_cast<Expr &&>(rhs))}}; \
- } \
- template< \
- typename Expr, \
- typename = std::enable_if_t< \
- !::boost::yap::detail::copy_or_move<this_type, Expr &&>::value>> \
- constexpr auto operator=(Expr && rhs) & \
- { \
- using lhs_type = ::boost::yap::detail:: \
- operand_type_t<expr_template, decltype(*this)>; \
- using rhs_type = \
- ::boost::yap::detail::operand_type_t<expr_template, Expr>; \
- using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
- return expr_template<::boost::yap::expr_kind::assign, tuple_type>{ \
- tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(*this), \
- ::boost::yap::detail::make_operand<rhs_type>{}( \
- static_cast<Expr &&>(rhs))}}; \
- } \
- template< \
- typename Expr, \
- typename = std::enable_if_t< \
- !::boost::yap::detail::copy_or_move<this_type, Expr &&>::value>> \
- constexpr auto operator=(Expr && rhs) && \
- { \
- using rhs_type = \
- ::boost::yap::detail::operand_type_t<expr_template, Expr>; \
- using tuple_type = ::boost::hana::tuple<this_type, rhs_type>; \
- return expr_template<::boost::yap::expr_kind::assign, tuple_type>{ \
- tuple_type{std::move(*this), \
- ::boost::yap::detail::make_operand<rhs_type>{}( \
- static_cast<Expr &&>(rhs))}}; \
- }
- /** Defines operator overloads for \a operator[]() that each produce an
- expression instantiated from the \a expr_template expression template.
- One overload is defined for each of the qualifiers <code>const &</code>,
- <code>&</code>, and <code>&&</code>. For the lvalue reference overloads,
- <code>*this</code> is captured by reference into the resulting expression.
- For the rvalue reference overload, <code>*this</code> is moved into the
- resulting expression.
- The \a rhs parameter to each of the defined overloads may be any type,
- including an expression, except that the overloads are constrained by
- std::enable_if<> not to conflict with the assignment and move assignement
- operators. If \a rhs is a non-expression, it is wrapped in a terminal
- expression.
- Example:
- \snippet user_macros_snippets.cpp USER_SUBSCRIPT_OPERATOR
- \param expr_template The expression template to use to instantiate the
- result expression. \a expr_template must be an \ref
- ExpressionTemplate.
- */
- #define BOOST_YAP_USER_SUBSCRIPT_OPERATOR(expr_template) \
- template<typename Expr> \
- constexpr auto operator[](Expr && rhs) const & \
- { \
- using lhs_type = ::boost::yap::detail:: \
- operand_type_t<expr_template, decltype(*this)>; \
- using rhs_type = \
- ::boost::yap::detail::operand_type_t<expr_template, Expr>; \
- using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
- return expr_template<::boost::yap::expr_kind::subscript, tuple_type>{ \
- tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(*this), \
- ::boost::yap::detail::make_operand<rhs_type>{}( \
- static_cast<Expr &&>(rhs))}}; \
- } \
- template<typename Expr> \
- constexpr auto operator[](Expr && rhs) & \
- { \
- using lhs_type = ::boost::yap::detail:: \
- operand_type_t<expr_template, decltype(*this)>; \
- using rhs_type = \
- ::boost::yap::detail::operand_type_t<expr_template, Expr>; \
- using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
- return expr_template<::boost::yap::expr_kind::subscript, tuple_type>{ \
- tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(*this), \
- ::boost::yap::detail::make_operand<rhs_type>{}( \
- static_cast<Expr &&>(rhs))}}; \
- } \
- template<typename Expr> \
- constexpr auto operator[](Expr && rhs) && \
- { \
- using lhs_type = \
- ::boost::yap::detail::remove_cv_ref_t<decltype(*this)>; \
- using rhs_type = \
- ::boost::yap::detail::operand_type_t<expr_template, Expr>; \
- using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
- return expr_template<::boost::yap::expr_kind::subscript, tuple_type>{ \
- tuple_type{std::move(*this), \
- ::boost::yap::detail::make_operand<rhs_type>{}( \
- static_cast<Expr &&>(rhs))}}; \
- }
- /** Defines operator overloads for the call operator taking any number of
- parameters ("operator()") that each produce an expression instantiated
- from the \a expr_template expression template. One overload is defined
- for each of the qualifiers <code>const &</code>, <code>&</code>, and
- <code>&&</code>. For the lvalue reference overloads, <code>*this</code>
- is captured by reference into the resulting expression. For the rvalue
- reference overload, <code>*this</code> is moved into the resulting
- expression.
- The \a u parameters to each of the defined overloads may be any type,
- including an expression. Each non-expression is wrapped in a terminal
- expression.
- Example:
- \snippet user_macros_snippets.cpp USER_CALL_OPERATOR
- \param expr_template The expression template to use to instantiate the
- result expression. \a expr_template must be an \ref
- ExpressionTemplate.
- */
- #define BOOST_YAP_USER_CALL_OPERATOR(expr_template) \
- template<typename... U> \
- constexpr auto operator()(U &&... u) const & \
- { \
- using lhs_type = ::boost::yap::detail:: \
- operand_type_t<expr_template, decltype(*this)>; \
- using tuple_type = ::boost::hana::tuple< \
- lhs_type, \
- ::boost::yap::detail::operand_type_t<expr_template, U>...>; \
- return expr_template<::boost::yap::expr_kind::call, tuple_type>{ \
- tuple_type{ \
- ::boost::yap::detail::make_operand<lhs_type>{}(*this), \
- ::boost::yap::detail::make_operand< \
- ::boost::yap::detail::operand_type_t<expr_template, U>>{}( \
- static_cast<U &&>(u))...}}; \
- } \
- template<typename... U> \
- constexpr auto operator()(U &&... u) & \
- { \
- using lhs_type = ::boost::yap::detail:: \
- operand_type_t<expr_template, decltype(*this)>; \
- using tuple_type = ::boost::hana::tuple< \
- lhs_type, \
- ::boost::yap::detail::operand_type_t<expr_template, U>...>; \
- return expr_template<::boost::yap::expr_kind::call, tuple_type>{ \
- tuple_type{ \
- ::boost::yap::detail::make_operand<lhs_type>{}(*this), \
- ::boost::yap::detail::make_operand< \
- ::boost::yap::detail::operand_type_t<expr_template, U>>{}( \
- static_cast<U &&>(u))...}}; \
- } \
- template<typename... U> \
- constexpr auto operator()(U &&... u) && \
- { \
- using this_type = \
- ::boost::yap::detail::remove_cv_ref_t<decltype(*this)>; \
- using tuple_type = ::boost::hana::tuple< \
- this_type, \
- ::boost::yap::detail::operand_type_t<expr_template, U>...>; \
- return expr_template<::boost::yap::expr_kind::call, tuple_type>{ \
- tuple_type{ \
- std::move(*this), \
- ::boost::yap::detail::make_operand< \
- ::boost::yap::detail::operand_type_t<expr_template, U>>{}( \
- static_cast<U &&>(u))...}}; \
- }
- #ifndef BOOST_YAP_DOXYGEN
- #define BOOST_YAP_USER_CALL_OPERATOR_OPERAND_T(z, n, expr_template) \
- ::boost::yap::detail::operand_type_t<expr_template, BOOST_PP_CAT(U, n)>
- #define BOOST_YAP_USER_CALL_OPERATOR_MAKE_OPERAND(z, n, expr_template) \
- ::boost::yap::detail::make_operand<::boost::yap::detail::operand_type_t< \
- expr_template, \
- BOOST_PP_CAT(U, n)>>{}( \
- static_cast<BOOST_PP_CAT(U, n) &&>(BOOST_PP_CAT(u, n)))
- #endif
- /** Defines operator overloads for the call operator taking N parameters
- ("operator()(t0, t1, ... tn-1)") that each produce an expression
- instantiated from the \a expr_template expression template. One overload
- is defined for each of the qualifiers <code>const &</code>,
- <code>&</code>, and <code>&&</code>. For the lvalue reference overloads,
- <code>*this</code> is captured by reference into the resulting expression.
- For the rvalue reference overload, <code>*this</code> is moved into the
- resulting expression.
- The \a u parameters to each of the defined overloads may be any type,
- including an expression. Each non-expression is wrapped in a terminal
- expression.
- Example:
- \snippet user_macros_snippets.cpp USER_CALL_OPERATOR
- \param expr_template The expression template to use to instantiate the
- result expression. \a expr_template must be an \ref
- ExpressionTemplate.
- \param n The number of parameters accepted by the operator() overloads. n
- must be <= BOOST_PP_LIMIT_REPEAT.
- */
- #define BOOST_YAP_USER_CALL_OPERATOR_N(expr_template, n) \
- template<BOOST_PP_ENUM_PARAMS(n, typename U)> \
- constexpr auto operator()(BOOST_PP_ENUM_BINARY_PARAMS(n, U, &&u)) const & \
- { \
- using lhs_type = ::boost::yap::detail:: \
- operand_type_t<expr_template, decltype(*this)>; \
- using tuple_type = ::boost::hana::tuple< \
- lhs_type, \
- BOOST_PP_ENUM( \
- n, BOOST_YAP_USER_CALL_OPERATOR_OPERAND_T, expr_template)>; \
- return expr_template<::boost::yap::expr_kind::call, tuple_type>{ \
- tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(*this), \
- BOOST_PP_ENUM( \
- n, \
- BOOST_YAP_USER_CALL_OPERATOR_MAKE_OPERAND, \
- expr_template)}}; \
- } \
- template<BOOST_PP_ENUM_PARAMS(n, typename U)> \
- constexpr auto operator()(BOOST_PP_ENUM_BINARY_PARAMS(n, U, &&u)) & \
- { \
- using lhs_type = ::boost::yap::detail:: \
- operand_type_t<expr_template, decltype(*this)>; \
- using tuple_type = ::boost::hana::tuple< \
- lhs_type, \
- BOOST_PP_ENUM( \
- n, BOOST_YAP_USER_CALL_OPERATOR_OPERAND_T, expr_template)>; \
- return expr_template<::boost::yap::expr_kind::call, tuple_type>{ \
- tuple_type{::boost::yap::detail::make_operand<lhs_type>{}(*this), \
- BOOST_PP_ENUM( \
- n, \
- BOOST_YAP_USER_CALL_OPERATOR_MAKE_OPERAND, \
- expr_template)}}; \
- } \
- template<BOOST_PP_ENUM_PARAMS(n, typename U)> \
- constexpr auto operator()(BOOST_PP_ENUM_BINARY_PARAMS(n, U, &&u)) && \
- { \
- using this_type = \
- ::boost::yap::detail::remove_cv_ref_t<decltype(*this)>; \
- using tuple_type = ::boost::hana::tuple< \
- this_type, \
- BOOST_PP_ENUM( \
- n, BOOST_YAP_USER_CALL_OPERATOR_OPERAND_T, expr_template)>; \
- return expr_template<::boost::yap::expr_kind::call, tuple_type>{ \
- tuple_type{std::move(*this), \
- BOOST_PP_ENUM( \
- n, \
- BOOST_YAP_USER_CALL_OPERATOR_MAKE_OPERAND, \
- expr_template)}}; \
- }
- /** Defines a 3-parameter function <code>if_else()</code> that acts as an
- analogue to the ternary operator (<code>?:</code>), since the ternary
- operator is not user-overloadable. The return type of
- <code>if_else()</code> is an expression instantiated from the \a
- expr_template expression template.
- At least one parameter to <code>if_else()</code> must be an expression.
- For each parameter E passed to <code>if_else()</code>, if E is an rvalue,
- E is moved into the result, and otherwise E is captured by reference into
- the result.
- Example:
- \snippet user_macros_snippets.cpp USER_EXPR_IF_ELSE
- \param expr_template The expression template to use to instantiate the
- result expression. \a expr_template must be an \ref
- ExpressionTemplate.
- */
- #define BOOST_YAP_USER_EXPR_IF_ELSE(expr_template) \
- template<typename Expr1, typename Expr2, typename Expr3> \
- constexpr auto if_else(Expr1 && expr1, Expr2 && expr2, Expr3 && expr3) \
- ->::boost::yap::detail:: \
- ternary_op_result_t<expr_template, Expr1, Expr2, Expr3> \
- { \
- using result_types = ::boost::yap::detail:: \
- ternary_op_result<expr_template, Expr1, Expr2, Expr3>; \
- using cond_type = typename result_types::cond_type; \
- using then_type = typename result_types::then_type; \
- using else_type = typename result_types::else_type; \
- using tuple_type = \
- ::boost::hana::tuple<cond_type, then_type, else_type>; \
- return {tuple_type{::boost::yap::detail::make_operand<cond_type>{}( \
- static_cast<Expr1 &&>(expr1)), \
- ::boost::yap::detail::make_operand<then_type>{}( \
- static_cast<Expr2 &&>(expr2)), \
- ::boost::yap::detail::make_operand<else_type>{}( \
- static_cast<Expr3 &&>(expr3))}}; \
- }
- /** Defines a function <code>if_else()</code> that acts as an analogue to the
- ternary operator (<code>?:</code>), since the ternary operator is not
- user-overloadable. The return type of <code>if_else()</code> is an
- expression instantiated from the \a expr_template expression template.
- Each parameter to <code>if_else()</code> may be any type that is \b not an
- expression. At least on parameter must be a type <code>T</code> for which
- \code udt_trait<std::remove_cv_t<std::remove_reference_t<T>>>::value
- \endcode is true. Each parameter is wrapped in a terminal expression.
- Example:
- \snippet user_macros_snippets.cpp USER_UDT_ANY_IF_ELSE
- \param expr_template The expression template to use to instantiate the
- result expression. \a expr_template must be an \ref
- ExpressionTemplate.
- \param udt_trait A trait template to use to constrain which types are
- accepted as template parameters to <code>if_else()</code>.
- */
- #define BOOST_YAP_USER_UDT_ANY_IF_ELSE(expr_template, udt_trait) \
- template<typename Expr1, typename Expr2, typename Expr3> \
- constexpr auto if_else(Expr1 && expr1, Expr2 && expr2, Expr3 && expr3) \
- ->::boost::yap::detail::udt_any_ternary_op_result_t< \
- expr_template, \
- Expr1, \
- Expr2, \
- Expr3, \
- udt_trait> \
- { \
- using result_types = ::boost::yap::detail::udt_any_ternary_op_result< \
- expr_template, \
- Expr1, \
- Expr2, \
- Expr3, \
- udt_trait>; \
- using cond_type = typename result_types::cond_type; \
- using then_type = typename result_types::then_type; \
- using else_type = typename result_types::else_type; \
- using tuple_type = \
- ::boost::hana::tuple<cond_type, then_type, else_type>; \
- return {tuple_type{::boost::yap::detail::make_operand<cond_type>{}( \
- static_cast<Expr1 &&>(expr1)), \
- ::boost::yap::detail::make_operand<then_type>{}( \
- static_cast<Expr2 &&>(expr2)), \
- ::boost::yap::detail::make_operand<else_type>{}( \
- static_cast<Expr3 &&>(expr3))}}; \
- }
- /** Defines a free/non-member operator overload for unary operator \a op_name
- that produces an expression instantiated from the \a expr_template
- expression template.
- The parameter to the defined operator overload may be any type that is \b
- not an expression and for which \code
- udt_trait<std::remove_cv_t<std::remove_reference_t<T>>>::value \endcode is
- true. The parameter is wrapped in a terminal expression.
- Example:
- \snippet user_macros_snippets.cpp USER_UDT_UNARY_OPERATOR
- \param op_name The operator to be overloaded; this must be one of the \b
- unary enumerators in <code>expr_kind</code>, without the
- <code>expr_kind::</code> qualification.
- \param expr_template The expression template to use to instantiate the
- result expression. \a expr_template must be an \ref
- ExpressionTemplate.
- \param udt_trait A trait template to use to constrain which types are
- accepted as template parameters to the defined operator overload.
- */
- #define BOOST_YAP_USER_UDT_UNARY_OPERATOR(op_name, expr_template, udt_trait) \
- template<typename T> \
- constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)(T && x) \
- ->::boost::yap::detail::udt_unary_op_result_t< \
- expr_template, \
- ::boost::yap::expr_kind::op_name, \
- T, \
- udt_trait> \
- { \
- using result_types = ::boost::yap::detail::udt_unary_op_result< \
- expr_template, \
- ::boost::yap::expr_kind::op_name, \
- T, \
- udt_trait>; \
- using x_type = typename result_types::x_type; \
- using tuple_type = ::boost::hana::tuple<x_type>; \
- return {tuple_type{x_type{static_cast<T &&>(x)}}}; \
- }
- /** Defines a free/non-member operator overload for binary operator \a op_name
- that produces an expression instantiated from the \a expr_template
- expression template.
- The \a lhs parameter to the defined operator overload may be any type that
- is \b not an expression and for which \code
- t_udt_trait<std::remove_cv_t<std::remove_reference_t<T>>>::value \endcode is
- true. The parameter is wrapped in a terminal expression.
- The \a rhs parameter to the defined operator overload may be any type that
- is \b not an expression and for which \code
- u_udt_trait<std::remove_cv_t<std::remove_reference_t<U>>>::value \endcode is
- true. The parameter is wrapped in a terminal expression.
- Example:
- \snippet user_macros_snippets.cpp USER_UDT_UDT_BINARY_OPERATOR
- \param op_name The operator to be overloaded; this must be one of the \b
- binary enumerators in <code>expr_kind</code>, without the
- <code>expr_kind::</code> qualification.
- \param expr_template The expression template to use to instantiate the
- result expression. \a expr_template must be an \ref
- ExpressionTemplate.
- \param t_udt_trait A trait template to use to constrain which types are
- accepted as \a T template parameters to the defined operator overload.
- \param u_udt_trait A trait template to use to constrain which types are
- accepted as \a U template parameters to the defined operator overload.
- */
- #define BOOST_YAP_USER_UDT_UDT_BINARY_OPERATOR( \
- op_name, expr_template, t_udt_trait, u_udt_trait) \
- template<typename T, typename U> \
- constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)(T && lhs, U && rhs) \
- ->::boost::yap::detail::udt_udt_binary_op_result_t< \
- expr_template, \
- ::boost::yap::expr_kind::op_name, \
- T, \
- U, \
- t_udt_trait, \
- u_udt_trait> \
- { \
- using result_types = ::boost::yap::detail::udt_udt_binary_op_result< \
- expr_template, \
- ::boost::yap::expr_kind::op_name, \
- T, \
- U, \
- t_udt_trait, \
- u_udt_trait>; \
- using lhs_type = typename result_types::lhs_type; \
- using rhs_type = typename result_types::rhs_type; \
- using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
- return {tuple_type{ \
- lhs_type{static_cast<T &&>(lhs)}, \
- rhs_type{static_cast<U &&>(rhs)}, \
- }}; \
- }
- /** Defines a free/non-member operator overload for binary operator \a op_name
- that produces an expression instantiated from the \a expr_template
- expression template.
- The \a lhs and \a rhs parameters to the defined operator overload may be any
- types that are \b not expressions. Each parameter is wrapped in a terminal
- expression.
- At least one of the parameters to the defined operator overload must be a
- type \c T for which \code
- udt_trait<std::remove_cv_t<std::remove_reference_t<T>>>::value \endcode is
- true.
- Example:
- \snippet user_macros_snippets.cpp USER_UDT_ANY_BINARY_OPERATOR
- \param op_name The operator to be overloaded; this must be one of the \b
- binary enumerators in <code>expr_kind</code>, without the
- <code>expr_kind::</code> qualification.
- \param expr_template The expression template to use to instantiate the
- result expression. \a expr_template must be an \ref
- ExpressionTemplate.
- \param udt_trait A trait template to use to constrain which types are
- accepted as template parameters to the defined operator overload.
- */
- #define BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR( \
- op_name, expr_template, udt_trait) \
- template<typename T, typename U> \
- constexpr auto operator BOOST_YAP_INDIRECT_CALL(op_name)(T && lhs, U && rhs) \
- ->::boost::yap::detail::udt_any_binary_op_result_t< \
- expr_template, \
- ::boost::yap::expr_kind::op_name, \
- T, \
- U, \
- udt_trait> \
- { \
- using result_types = ::boost::yap::detail::udt_any_binary_op_result< \
- expr_template, \
- ::boost::yap::expr_kind::op_name, \
- T, \
- U, \
- udt_trait>; \
- using lhs_type = typename result_types::lhs_type; \
- using rhs_type = typename result_types::rhs_type; \
- using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
- return {tuple_type{lhs_type{static_cast<T &&>(lhs)}, \
- rhs_type{static_cast<U &&>(rhs)}}}; \
- }
- /** Defines user defined literal template that creates literal placeholders
- instantiated from the \a expr_template expression template. It is
- recommended that you put this in its own namespace.
- \param expr_template The expression template to use to instantiate the
- result expression. \a expr_template must be an \ref
- ExpressionTemplate.
- */
- #define BOOST_YAP_USER_LITERAL_PLACEHOLDER_OPERATOR(expr_template) \
- template<char... c> \
- constexpr auto operator"" _p() \
- { \
- using i = ::boost::hana::llong< \
- ::boost::hana::ic_detail::parse<sizeof...(c)>({c...})>; \
- static_assert(1 <= i::value, "Placeholders must be >= 1."); \
- return expr_template< \
- ::boost::yap::expr_kind::terminal, \
- ::boost::hana::tuple<::boost::yap::placeholder<i::value>>>{}; \
- }
- #endif
|