339 lines
14 KiB
C++
339 lines
14 KiB
C++
// 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_EXPRESSION_HPP_INCLUDED
|
|
#define BOOST_YAP_EXPRESSION_HPP_INCLUDED
|
|
|
|
#include <boost/yap/algorithm.hpp>
|
|
|
|
|
|
namespace boost { namespace yap {
|
|
|
|
/** Reference expression template that provides all operator overloads.
|
|
|
|
\note Due to a limitation of Doxygen, each of the
|
|
<code>value()</code>, <code>left()</code>, <code>right()</code>, and
|
|
operator overloads listed here is a stand-in for three member
|
|
functions. For each function <code>f</code>, the listing here is:
|
|
\code return_type f (); \endcode However, there are actually three
|
|
functions:
|
|
\code
|
|
return_type f () const &;
|
|
return_type f () &;
|
|
return_type f () &&;
|
|
\endcode
|
|
*/
|
|
template<expr_kind Kind, typename Tuple>
|
|
struct expression
|
|
{
|
|
using tuple_type = Tuple;
|
|
|
|
static const expr_kind kind = Kind;
|
|
|
|
/** Default constructor. Does nothing. */
|
|
constexpr expression() {}
|
|
|
|
/** Moves \a rhs into the only data mamber, \c elements. */
|
|
constexpr expression(tuple_type && rhs) :
|
|
elements(static_cast<tuple_type &&>(rhs))
|
|
{}
|
|
|
|
tuple_type elements;
|
|
|
|
/** A convenience member function that dispatches to the free function
|
|
<code>value()</code>. */
|
|
constexpr decltype(auto) value() &
|
|
{
|
|
return ::boost::yap::value(*this);
|
|
}
|
|
|
|
#ifndef BOOST_YAP_DOXYGEN
|
|
|
|
constexpr decltype(auto) value() const &
|
|
{
|
|
return ::boost::yap::value(*this);
|
|
}
|
|
|
|
constexpr decltype(auto) value() &&
|
|
{
|
|
return ::boost::yap::value(std::move(*this));
|
|
}
|
|
|
|
#endif
|
|
|
|
/** A convenience member function that dispatches to the free function
|
|
<code>left()</code>. */
|
|
constexpr decltype(auto) left() & { return ::boost::yap::left(*this); }
|
|
|
|
#ifndef BOOST_YAP_DOXYGEN
|
|
|
|
constexpr decltype(auto) left() const &
|
|
{
|
|
return ::boost::yap::left(*this);
|
|
}
|
|
|
|
constexpr decltype(auto) left() &&
|
|
{
|
|
return ::boost::yap::left(std::move(*this));
|
|
}
|
|
|
|
#endif
|
|
|
|
/** A convenience member function that dispatches to the free function
|
|
<code>right()</code>. */
|
|
constexpr decltype(auto) right() &
|
|
{
|
|
return ::boost::yap::right(*this);
|
|
}
|
|
|
|
#ifndef BOOST_YAP_DOXYGEN
|
|
|
|
constexpr decltype(auto) right() const &
|
|
{
|
|
return ::boost::yap::right(*this);
|
|
}
|
|
|
|
constexpr decltype(auto) right() &&
|
|
{
|
|
return ::boost::yap::right(std::move(*this));
|
|
}
|
|
|
|
#endif
|
|
|
|
BOOST_YAP_USER_ASSIGN_OPERATOR(
|
|
expression, ::boost::yap::expression) // =
|
|
BOOST_YAP_USER_SUBSCRIPT_OPERATOR(::boost::yap::expression) // []
|
|
BOOST_YAP_USER_CALL_OPERATOR(::boost::yap::expression) // ()
|
|
};
|
|
|
|
/** Terminal expression specialization of the reference expression
|
|
template.
|
|
|
|
\note Due to a limitation of Doxygen, the <code>value()</code> member
|
|
and each of the operator overloads listed here is a stand-in for three
|
|
member functions. For each function <code>f</code>, the listing here
|
|
is: \code return_type f (); \endcode However, there are actually three
|
|
functions:
|
|
\code
|
|
return_type f () const &;
|
|
return_type f () &;
|
|
return_type f () &&;
|
|
\endcode
|
|
*/
|
|
template<typename T>
|
|
struct expression<expr_kind::terminal, hana::tuple<T>>
|
|
{
|
|
using tuple_type = hana::tuple<T>;
|
|
|
|
static const expr_kind kind = expr_kind::terminal;
|
|
|
|
/** Default constructor. Does nothing. */
|
|
constexpr expression() {}
|
|
|
|
/** Forwards \a t into \c elements. */
|
|
constexpr expression(T && t) : elements(static_cast<T &&>(t)) {}
|
|
|
|
/** Copies \a rhs into the only data mamber, \c elements. */
|
|
constexpr expression(hana::tuple<T> const & rhs) : elements(rhs) {}
|
|
|
|
/** Moves \a rhs into the only data mamber, \c elements. */
|
|
constexpr expression(hana::tuple<T> && rhs) : elements(std::move(rhs))
|
|
{}
|
|
|
|
tuple_type elements;
|
|
|
|
/** A convenience member function that dispatches to the free function
|
|
<code>value()</code>. */
|
|
constexpr decltype(auto) value() &
|
|
{
|
|
return ::boost::yap::value(*this);
|
|
}
|
|
|
|
#ifndef BOOST_YAP_DOXYGEN
|
|
|
|
constexpr decltype(auto) value() const &
|
|
{
|
|
return ::boost::yap::value(*this);
|
|
}
|
|
|
|
constexpr decltype(auto) value() &&
|
|
{
|
|
return ::boost::yap::value(std::move(*this));
|
|
}
|
|
|
|
#endif
|
|
|
|
BOOST_YAP_USER_ASSIGN_OPERATOR(
|
|
expression, ::boost::yap::expression) // =
|
|
BOOST_YAP_USER_SUBSCRIPT_OPERATOR(::boost::yap::expression) // []
|
|
BOOST_YAP_USER_CALL_OPERATOR(::boost::yap::expression) // ()
|
|
};
|
|
|
|
#ifndef BOOST_YAP_DOXYGEN
|
|
|
|
BOOST_YAP_USER_UNARY_OPERATOR(unary_plus, expression, expression) // +
|
|
BOOST_YAP_USER_UNARY_OPERATOR(negate, expression, expression) // -
|
|
BOOST_YAP_USER_UNARY_OPERATOR(dereference, expression, expression) // *
|
|
BOOST_YAP_USER_UNARY_OPERATOR(complement, expression, expression) // ~
|
|
BOOST_YAP_USER_UNARY_OPERATOR(address_of, expression, expression) // &
|
|
BOOST_YAP_USER_UNARY_OPERATOR(logical_not, expression, expression) // !
|
|
BOOST_YAP_USER_UNARY_OPERATOR(pre_inc, expression, expression) // ++
|
|
BOOST_YAP_USER_UNARY_OPERATOR(pre_dec, expression, expression) // --
|
|
BOOST_YAP_USER_UNARY_OPERATOR(post_inc, expression, expression) // ++(int)
|
|
BOOST_YAP_USER_UNARY_OPERATOR(post_dec, expression, expression) // --(int)
|
|
|
|
BOOST_YAP_USER_BINARY_OPERATOR(shift_left, expression, expression) // <<
|
|
BOOST_YAP_USER_BINARY_OPERATOR(shift_right, expression, expression) // >>
|
|
BOOST_YAP_USER_BINARY_OPERATOR(multiplies, expression, expression) // *
|
|
BOOST_YAP_USER_BINARY_OPERATOR(divides, expression, expression) // /
|
|
BOOST_YAP_USER_BINARY_OPERATOR(modulus, expression, expression) // %
|
|
BOOST_YAP_USER_BINARY_OPERATOR(plus, expression, expression) // +
|
|
BOOST_YAP_USER_BINARY_OPERATOR(minus, expression, expression) // -
|
|
BOOST_YAP_USER_BINARY_OPERATOR(less, expression, expression) // <
|
|
BOOST_YAP_USER_BINARY_OPERATOR(greater, expression, expression) // >
|
|
BOOST_YAP_USER_BINARY_OPERATOR(less_equal, expression, expression) // <=
|
|
BOOST_YAP_USER_BINARY_OPERATOR(greater_equal, expression, expression) // >=
|
|
BOOST_YAP_USER_BINARY_OPERATOR(equal_to, expression, expression) // ==
|
|
BOOST_YAP_USER_BINARY_OPERATOR(not_equal_to, expression, expression) // !=
|
|
BOOST_YAP_USER_BINARY_OPERATOR(logical_or, expression, expression) // ||
|
|
BOOST_YAP_USER_BINARY_OPERATOR(logical_and, expression, expression) // &&
|
|
BOOST_YAP_USER_BINARY_OPERATOR(bitwise_and, expression, expression) // &
|
|
BOOST_YAP_USER_BINARY_OPERATOR(bitwise_or, expression, expression) // |
|
|
BOOST_YAP_USER_BINARY_OPERATOR(bitwise_xor, expression, expression) // ^
|
|
BOOST_YAP_USER_BINARY_OPERATOR(comma, expression, expression) // ,
|
|
BOOST_YAP_USER_BINARY_OPERATOR(mem_ptr, expression, expression) // ->*
|
|
BOOST_YAP_USER_BINARY_OPERATOR(shift_left_assign, expression, expression) // <<=
|
|
BOOST_YAP_USER_BINARY_OPERATOR(shift_right_assign, expression, expression) // >>=
|
|
BOOST_YAP_USER_BINARY_OPERATOR(multiplies_assign, expression, expression) // *=
|
|
BOOST_YAP_USER_BINARY_OPERATOR(divides_assign, expression, expression) // /=
|
|
BOOST_YAP_USER_BINARY_OPERATOR(modulus_assign, expression, expression) // %=
|
|
BOOST_YAP_USER_BINARY_OPERATOR(plus_assign, expression, expression) // +=
|
|
BOOST_YAP_USER_BINARY_OPERATOR(minus_assign, expression, expression) // -=
|
|
BOOST_YAP_USER_BINARY_OPERATOR(bitwise_and_assign, expression, expression) // &=
|
|
BOOST_YAP_USER_BINARY_OPERATOR(bitwise_or_assign, expression, expression) // |=
|
|
BOOST_YAP_USER_BINARY_OPERATOR(bitwise_xor_assign, expression, expression) // ^=
|
|
|
|
BOOST_YAP_USER_EXPR_IF_ELSE(expression)
|
|
|
|
#else
|
|
|
|
/** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
|
|
template<typename Expr>
|
|
constexpr auto operator+(Expr &&);
|
|
/** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
|
|
template<typename Expr>
|
|
constexpr auto operator-(Expr &&);
|
|
/** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
|
|
template<typename Expr>
|
|
constexpr auto operator*(Expr &&);
|
|
/** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
|
|
template<typename Expr>
|
|
constexpr auto operator~(Expr &&);
|
|
/** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
|
|
template<typename Expr>
|
|
constexpr auto operator&(Expr &&);
|
|
/** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
|
|
template<typename Expr>
|
|
constexpr auto operator!(Expr &&);
|
|
/** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
|
|
template<typename Expr>
|
|
constexpr auto operator++(Expr &&);
|
|
/** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
|
|
template<typename Expr>
|
|
constexpr auto operator--(Expr &&);
|
|
/** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
|
|
template<typename Expr>
|
|
constexpr auto operator++(Expr &&, int);
|
|
/** \see BOOST_YAP_USER_UNARY_OPERATOR for full semantics. */
|
|
template<typename Expr>
|
|
constexpr auto operator--(Expr &&, int);
|
|
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator<<(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator>>(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator*(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator/(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator%(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator+(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator-(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator<(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator>(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator<=(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator>=(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator==(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator!=(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator||(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator&&(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator&(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator|(LExpr && lhs, RExpr && rhs);
|
|
/** \see BOOST_YAP_USER_BINARY_OPERATOR for full semantics. */
|
|
template<typename LExpr, typename RExpr>
|
|
constexpr auto operator^(LExpr && lhs, RExpr && rhs);
|
|
|
|
/** \see BOOST_YAP_USER_EXPR_IF_ELSE for full semantics. */
|
|
template<typename Expr1, typename Expr2, typename Expr3>
|
|
constexpr auto if_else(Expr1 && expr1, Expr2 && expr2, Expr3 && expr3);
|
|
|
|
#endif
|
|
|
|
/** Returns <code>make_expression<boost::yap::expression, Kind>(...)</code>.
|
|
*/
|
|
template<expr_kind Kind, typename... T>
|
|
constexpr auto make_expression(T &&... t)
|
|
{
|
|
return make_expression<expression, Kind>(static_cast<T &&>(t)...);
|
|
}
|
|
|
|
/** Returns <code>make_terminal<boost::yap::expression>(t)</code>. */
|
|
template<typename T>
|
|
constexpr auto make_terminal(T && t)
|
|
{
|
|
return make_terminal<expression>(static_cast<T &&>(t));
|
|
}
|
|
|
|
/** Returns <code>as_expr<boost::yap::expression>(t)</code>. */
|
|
template<typename T>
|
|
constexpr decltype(auto) as_expr(T && t)
|
|
{
|
|
return as_expr<expression>(static_cast<T &&>(t));
|
|
}
|
|
|
|
}}
|
|
|
|
#endif
|