Remove this_type parameter from all member function macros.

This commit is contained in:
Zach Laine 2017-05-09 11:14:55 -05:00
parent 1b2ca8744b
commit 55e9f33892
17 changed files with 48 additions and 100 deletions

View File

@ -23,7 +23,6 @@ namespace boost { namespace yap {
template <expr_kind Kind, typename Tuple>
struct expression
{
using this_type = expression<Kind, Tuple>;
using tuple_type = Tuple;
static const expr_kind kind = Kind;
@ -189,7 +188,7 @@ namespace boost { namespace yap {
#else
#define BOOST_YAP_UNARY_MEMBER_OPERATOR(op_name) \
BOOST_YAP_USER_UNARY_OPERATOR_MEMBER(op_name, this_type, ::boost::yap::expression)
BOOST_YAP_USER_UNARY_OPERATOR_MEMBER(op_name, ::boost::yap::expression)
BOOST_YAP_UNARY_MEMBER_OPERATOR(unary_plus) // +
BOOST_YAP_UNARY_MEMBER_OPERATOR(negate) // -
@ -208,7 +207,7 @@ namespace boost { namespace yap {
// types), for expression and terminal. Don't forget the free
// operators.
#define BOOST_YAP_BINARY_MEMBER_OPERATOR(op_name) \
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(op_name, this_type, ::boost::yap::expression)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(op_name, ::boost::yap::expression)
BOOST_YAP_BINARY_MEMBER_OPERATOR(shift_left) // <<
BOOST_YAP_BINARY_MEMBER_OPERATOR(shift_right) // >>
@ -245,7 +244,7 @@ namespace boost { namespace yap {
#undef BOOST_YAP_BINARY_MEMBER_OPERATOR
BOOST_YAP_USER_MEMBER_CALL_OPERATOR(this_type, ::boost::yap::expression)
BOOST_YAP_USER_MEMBER_CALL_OPERATOR(::boost::yap::expression)
#endif // BOOST_YAP_DOXYGEN
};
@ -267,7 +266,6 @@ namespace boost { namespace yap {
template <typename T>
struct expression<expr_kind::terminal, hana::tuple<T>>
{
using this_type = expression<expr_kind::terminal, hana::tuple<T>>;
using tuple_type = hana::tuple<T>;
static const expr_kind kind = expr_kind::terminal;
@ -408,7 +406,7 @@ namespace boost { namespace yap {
#else
#define BOOST_YAP_UNARY_MEMBER_OPERATOR(op_name) \
BOOST_YAP_USER_UNARY_OPERATOR_MEMBER(op_name, this_type, ::boost::yap::expression)
BOOST_YAP_USER_UNARY_OPERATOR_MEMBER(op_name, ::boost::yap::expression)
BOOST_YAP_UNARY_MEMBER_OPERATOR(unary_plus) // +
BOOST_YAP_UNARY_MEMBER_OPERATOR(negate) // -
@ -424,7 +422,7 @@ namespace boost { namespace yap {
#undef BOOST_YAP_UNARY_MEMBER_OPERATOR
#define BOOST_YAP_BINARY_MEMBER_OPERATOR(op_name) \
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(op_name, this_type, ::boost::yap::expression)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(op_name, ::boost::yap::expression)
BOOST_YAP_BINARY_MEMBER_OPERATOR(shift_left) // <<
BOOST_YAP_BINARY_MEMBER_OPERATOR(shift_right) // >>
@ -461,7 +459,7 @@ namespace boost { namespace yap {
#undef BOOST_YAP_BINARY_MEMBER_OPERATOR
BOOST_YAP_USER_MEMBER_CALL_OPERATOR(this_type, ::boost::yap::expression)
BOOST_YAP_USER_MEMBER_CALL_OPERATOR(::boost::yap::expression)
#endif // BOOST_YAP_DOXYGEN
};

View File

@ -79,16 +79,14 @@
unary enumerators in <code>expr_kind</code>, without the
<code>expr_kind::</code> qualification.
\param this_type The type in which the operator overloads are being
defined.
\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_UNARY_OPERATOR_MEMBER(op_name, this_type, expr_template) \
#define BOOST_YAP_USER_UNARY_OPERATOR_MEMBER(op_name, expr_template) \
auto operator BOOST_YAP_INDIRECT_CALL(op_name)(()) const & \
{ \
using this_type = ::boost::yap::detail::remove_cv_ref_t<decltype(*this)>; \
using lhs_type = ::boost::yap::detail::operand_type_t<expr_template, this_type const &>; \
using tuple_type = ::boost::hana::tuple<lhs_type>; \
return expr_template< ::boost::yap::expr_kind::op_name, tuple_type>{ \
@ -99,6 +97,7 @@
} \
auto operator BOOST_YAP_INDIRECT_CALL(op_name)(()) & \
{ \
using this_type = ::boost::yap::detail::remove_cv_ref_t<decltype(*this)>; \
using lhs_type = ::boost::yap::detail::operand_type_t<expr_template, this_type &>; \
using tuple_type = ::boost::hana::tuple<lhs_type>; \
return expr_template< ::boost::yap::expr_kind::op_name, tuple_type>{ \
@ -109,6 +108,7 @@
} \
auto operator BOOST_YAP_INDIRECT_CALL(op_name)(()) && \
{ \
using this_type = ::boost::yap::detail::remove_cv_ref_t<decltype(*this)>; \
using tuple_type = ::boost::hana::tuple<this_type>; \
return expr_template< ::boost::yap::expr_kind::op_name, tuple_type>{ \
tuple_type{std::move(*this)} \
@ -135,17 +135,15 @@
binary enumerators in <code>expr_kind</code>, without the
<code>expr_kind::</code> qualification.
\param this_type The type in which the operator overloads are being
defined.
\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_BINARY_OPERATOR_MEMBER(op_name, this_type, expr_template) \
#define BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(op_name, expr_template) \
template <typename Expr> \
auto operator BOOST_YAP_INDIRECT_CALL(op_name)() (Expr && rhs) const & \
{ \
using this_type = ::boost::yap::detail::remove_cv_ref_t<decltype(*this)>; \
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>; \
@ -159,6 +157,7 @@
template <typename Expr> \
auto operator BOOST_YAP_INDIRECT_CALL(op_name)() (Expr && rhs) & \
{ \
using this_type = ::boost::yap::detail::remove_cv_ref_t<decltype(*this)>; \
using lhs_type = ::boost::yap::detail::operand_type_t<expr_template, this_type &>; \
using rhs_type = ::boost::yap::detail::operand_type_t<expr_template, Expr>; \
using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
@ -172,6 +171,7 @@
template <typename Expr> \
auto operator BOOST_YAP_INDIRECT_CALL(op_name)() (Expr && rhs) && \
{ \
using this_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<this_type, rhs_type>; \
return expr_template< ::boost::yap::expr_kind::op_name, tuple_type>{ \
@ -198,17 +198,15 @@
Example:
\snippet user_macros_snippets.cpp USER_MEMBER_CALL_OPERATOR
\param this_type The type in which the operator overloads are being
defined.
\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_MEMBER_CALL_OPERATOR(this_type, expr_template) \
#define BOOST_YAP_USER_MEMBER_CALL_OPERATOR(expr_template) \
template <typename ...U> \
auto operator() (U && ... u) const & \
{ \
using this_type = ::boost::yap::detail::remove_cv_ref_t<decltype(*this)>; \
using lhs_type = ::boost::yap::detail::operand_type_t<expr_template, this_type const &>; \
using tuple_type = ::boost::hana::tuple< \
lhs_type, \
@ -226,6 +224,7 @@
template <typename ...U> \
auto operator() (U && ... u) & \
{ \
using this_type = ::boost::yap::detail::remove_cv_ref_t<decltype(*this)>; \
using lhs_type = ::boost::yap::detail::operand_type_t<expr_template, this_type &>; \
using tuple_type = ::boost::hana::tuple< \
lhs_type, \
@ -243,6 +242,7 @@
template <typename ...U> \
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>... \

View File

@ -10,14 +10,12 @@
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
using this_type = user_expr<Kind, Tuple>;
static const boost::yap::expr_kind kind = Kind;
Tuple elements;
// Member operator overloads for operator!().
BOOST_YAP_USER_UNARY_OPERATOR_MEMBER(logical_not, this_type, ::user_expr)
BOOST_YAP_USER_UNARY_OPERATOR_MEMBER(logical_not, ::user_expr)
};
/// [USER_UNARY_OPERATOR_MEMBER]
@ -36,8 +34,6 @@ struct lazy_vector_1 :
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
using this_type = user_expr<Kind, Tuple>;
static const boost::yap::expr_kind kind = Kind;
Tuple elements;
@ -46,7 +42,7 @@ struct user_expr
// on the right-hand side, even another expression. Left as-is, there is
// no matching overload for x && y, where x is not an expression and y is.
// BOOST_YAP_USER_FREE_BINARY_OPERATOR can help with that.
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(logical_and, this_type, ::user_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(logical_and, ::user_expr)
};
/// [USER_BINARY_OPERATOR_MEMBER]
@ -65,8 +61,6 @@ struct lazy_vector_2 :
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
using this_type = user_expr<Kind, Tuple>;
static const boost::yap::expr_kind kind = Kind;
Tuple elements;
@ -74,7 +68,7 @@ struct user_expr
// Member operator overloads for operator()(). These will match any
// number of parameters. Each one can be any type, even another
// expression.
BOOST_YAP_USER_MEMBER_CALL_OPERATOR(this_type, ::user_expr)
BOOST_YAP_USER_MEMBER_CALL_OPERATOR(::user_expr)
};
/// [USER_MEMBER_CALL_OPERATOR]
@ -93,15 +87,13 @@ struct lazy_vector_3 :
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
using this_type = user_expr<Kind, Tuple>;
static const boost::yap::expr_kind kind = Kind;
Tuple elements;
// Member operator overloads for operator&&(). These will match any value
// on the right-hand side, even another expression.
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(logical_and, this_type, ::user_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(logical_and, ::user_expr)
};
// Free operator overloads for operator&&(). These will match any value on
@ -125,8 +117,6 @@ struct lazy_vector_4 :
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
using this_type = user_expr<Kind, Tuple>;
static const boost::yap::expr_kind kind = Kind;
Tuple elements;
@ -153,8 +143,6 @@ struct lazy_vector_5 :
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
using this_type = user_expr<Kind, Tuple>;
static const boost::yap::expr_kind kind = Kind;
Tuple elements;
@ -188,8 +176,6 @@ struct lazy_vector_6 :
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
using this_type = user_expr<Kind, Tuple>;
static const boost::yap::expr_kind kind = Kind;
Tuple elements;
@ -223,8 +209,6 @@ struct lazy_vector_7 :
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
using this_type = user_expr<Kind, Tuple>;
static const boost::yap::expr_kind kind = Kind;
Tuple elements;
@ -268,8 +252,6 @@ struct lazy_vector_8 :
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
using this_type = user_expr<Kind, Tuple>;
static const boost::yap::expr_kind kind = Kind;
Tuple elements;
@ -302,8 +284,6 @@ struct lazy_vector_9 :
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
using this_type = user_expr<Kind, Tuple>;
static const boost::yap::expr_kind kind = Kind;
Tuple elements;

View File

@ -19,17 +19,15 @@ using namespace AutoDiff;
template <boost::yap::expr_kind Kind, typename Tuple>
struct autodiff_expr
{
using this_type = autodiff_expr<Kind, Tuple>;
static boost::yap::expr_kind const kind = Kind;
Tuple elements;
BOOST_YAP_USER_UNARY_OPERATOR_MEMBER(negate, this_type, ::autodiff_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, this_type, ::autodiff_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(minus, this_type, ::autodiff_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(multiplies, this_type, ::autodiff_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(divides, this_type, ::autodiff_expr)
BOOST_YAP_USER_UNARY_OPERATOR_MEMBER(negate, ::autodiff_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, ::autodiff_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(minus, ::autodiff_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(multiplies, ::autodiff_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(divides, ::autodiff_expr)
};
BOOST_YAP_USER_FREE_BINARY_OPERATOR(plus, ::autodiff_expr)
@ -53,13 +51,11 @@ template <OPCODE Opcode>
struct autodiff_fn_expr :
autodiff_expr<boost::yap::expr_kind::terminal, boost::hana::tuple<OPCODE>>
{
using this_type = autodiff_fn_expr<Opcode>;
autodiff_fn_expr () :
autodiff_expr {boost::hana::tuple<OPCODE>{Opcode}}
{}
BOOST_YAP_USER_MEMBER_CALL_OPERATOR(this_type, ::autodiff_expr);
BOOST_YAP_USER_MEMBER_CALL_OPERATOR(::autodiff_expr);
};
// Someone included <math.h>, so we have to add trailing underscores.

View File

@ -9,8 +9,6 @@
template <boost::yap::expr_kind Kind, typename Tuple>
struct future_expr
{
using this_type = future_expr<Kind, Tuple>;
static boost::yap::expr_kind const kind = Kind;
future_expr (Tuple && tuple) :
@ -22,8 +20,8 @@ struct future_expr
// Returns the transformed/flattenen expression.
auto get () const;
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(logical_or, this_type, ::future_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(logical_and, this_type, ::future_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(logical_or, ::future_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(logical_and, ::future_expr)
};
// A special-cased future terminal that matches the semantics from the

View File

@ -32,14 +32,12 @@ struct take_nth
template <boost::yap::expr_kind Kind, typename Tuple>
struct lazy_vector_expr
{
using this_type = lazy_vector_expr<Kind, Tuple>;
static const boost::yap::expr_kind kind = Kind;
Tuple elements;
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, this_type, ::lazy_vector_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(minus, this_type, ::lazy_vector_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, ::lazy_vector_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(minus, ::lazy_vector_expr)
// Note that this does not return an expression; it is greedily evaluated.
auto operator[] (std::size_t n) const;

View File

@ -39,8 +39,6 @@ struct map_list_of_transform
template <boost::yap::expr_kind Kind, typename Tuple>
struct map_list_of_expr
{
using this_type = map_list_of_expr<Kind, Tuple>;
static boost::yap::expr_kind const kind = Kind;
Tuple elements;
@ -53,7 +51,7 @@ struct map_list_of_expr
return transform.map;
}
BOOST_YAP_USER_MEMBER_CALL_OPERATOR(this_type, ::map_list_of_expr)
BOOST_YAP_USER_MEMBER_CALL_OPERATOR(::map_list_of_expr)
};
// A tag type for creating the map_list_of function terminal.

View File

@ -35,18 +35,16 @@ struct tarray_expr
"tarray_expr instantiated with an unsupported terminal type."
);
using this_type = tarray_expr<Kind, Tuple>;
static const boost::yap::expr_kind kind = Kind;
Tuple elements;
// Define operators +, -, *, and / for an expression on the left, and
// anythng on the right.
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, this_type, ::tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(minus, this_type, ::tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(multiplies, this_type, ::tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(divides, this_type, ::tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, ::tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(minus, ::tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(multiplies, ::tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(divides, ::tarray_expr)
int operator[] (std::size_t n) const
{ return boost::yap::evaluate(boost::yap::transform(*this, take_nth{n})); }

View File

@ -32,14 +32,12 @@ struct take_nth
template <boost::yap::expr_kind Kind, typename Tuple>
struct lazy_vector_expr
{
using this_type = lazy_vector_expr<Kind, Tuple>;
static const boost::yap::expr_kind kind = Kind;
Tuple elements;
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, this_type, ::lazy_vector_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(minus, this_type, ::lazy_vector_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, ::lazy_vector_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(minus, ::lazy_vector_expr)
// Note that this does not return an expression; it is greedily evaluated.
auto operator[] (std::size_t n) const;

View File

@ -27,8 +27,6 @@ struct map_list_of_transform
template <boost::yap::expr_kind Kind, typename Tuple>
struct map_list_of_expr
{
using this_type = map_list_of_expr<Kind, Tuple>;
static boost::yap::expr_kind const kind = Kind;
Tuple elements;
@ -41,7 +39,7 @@ struct map_list_of_expr
return transform.map;
}
BOOST_YAP_USER_MEMBER_CALL_OPERATOR(this_type, ::map_list_of_expr)
BOOST_YAP_USER_MEMBER_CALL_OPERATOR(::map_list_of_expr)
};
struct map_list_of_tag {};

View File

@ -29,8 +29,6 @@ struct map_list_of_transform
template <boost::yap::expr_kind Kind, typename Tuple>
struct map_list_of_expr
{
using this_type = map_list_of_expr<Kind, Tuple>;
static boost::yap::expr_kind const kind = Kind;
Tuple elements;
@ -43,7 +41,7 @@ struct map_list_of_expr
return transform.map;
}
BOOST_YAP_USER_MEMBER_CALL_OPERATOR(this_type, ::map_list_of_expr)
BOOST_YAP_USER_MEMBER_CALL_OPERATOR(::map_list_of_expr)
};
struct map_list_of_tag {};

View File

@ -16,13 +16,11 @@ namespace bh = boost::hana;
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
using this_type = user_expr<Kind, Tuple>;
static boost::yap::expr_kind const kind = Kind;
Tuple elements;
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, this_type, ::user_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, ::user_expr)
};
template <typename T>

View File

@ -36,14 +36,12 @@ struct take_nth
template <boost::yap::expr_kind Kind, typename Tuple>
struct lazy_vector_expr
{
using this_type = lazy_vector_expr<Kind, Tuple>;
static const boost::yap::expr_kind kind = Kind;
Tuple elements;
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, this_type, ::lazy_vector_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(minus, this_type, ::lazy_vector_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, ::lazy_vector_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(minus, ::lazy_vector_expr)
auto operator[] (std::size_t n) const
{ return boost::yap::evaluate(boost::yap::transform(*this, take_nth{n})); }

View File

@ -16,13 +16,11 @@ namespace bh = boost::hana;
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
using this_type = user_expr<Kind, Tuple>;
static boost::yap::expr_kind const kind = Kind;
Tuple elements;
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, this_type, ::user_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, ::user_expr)
};
template <typename T>

View File

@ -19,13 +19,11 @@ namespace bh = boost::hana;
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
using this_type = user_expr<Kind, Tuple>;
static boost::yap::expr_kind const kind = Kind;
Tuple elements;
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, this_type, ::user_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, ::user_expr)
};
template <typename T>

View File

@ -16,13 +16,11 @@ namespace bh = boost::hana;
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
using this_type = user_expr<Kind, Tuple>;
static boost::yap::expr_kind const kind = Kind;
Tuple elements;
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, this_type, ::user_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, ::user_expr)
};
template <typename T>

View File

@ -16,13 +16,11 @@ namespace bh = boost::hana;
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
using this_type = user_expr<Kind, Tuple>;
static boost::yap::expr_kind const kind = Kind;
Tuple elements;
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, this_type, ::user_expr)
BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, ::user_expr)
};
template <typename T>