From 514fd94b1eec4226001eab04fc82c7aa4e1f95f8 Mon Sep 17 00:00:00 2001 From: Zach Laine Date: Sat, 19 Nov 2016 13:29:47 -0600 Subject: [PATCH] Add reference qualified overloaded value(), left(), and right() expression members, and free versions of same. --- expression.hpp | 165 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 162 insertions(+), 3 deletions(-) diff --git a/expression.hpp b/expression.hpp index 8a3318d..2941bea 100644 --- a/expression.hpp +++ b/expression.hpp @@ -66,7 +66,7 @@ namespace boost::proto17 { { return eval_expression_as(*this, hana::basic_type{}); } #endif - decltype(auto) value () const + decltype(auto) value () const & { using namespace hana::literals; static_assert( @@ -76,7 +76,27 @@ namespace boost::proto17 { return elements[0_c]; } - decltype(auto) left () const + decltype(auto) value () & + { + using namespace hana::literals; + static_assert( + decltype(hana::size(elements))::value == 1UL, + "value() is only defined for unary expressions." + ); + return elements[0_c]; + } + + decltype(auto) value () && + { + using namespace hana::literals; + static_assert( + decltype(hana::size(elements))::value == 1UL, + "value() is only defined for unary expressions." + ); + return static_cast(elements)[0_c]; + } + + decltype(auto) left () const & { using namespace hana::literals; static_assert( @@ -86,7 +106,27 @@ namespace boost::proto17 { return elements[0_c]; } - decltype(auto) right () const + decltype(auto) left () & + { + using namespace hana::literals; + static_assert( + decltype(hana::size(elements))::value == 2UL, + "left() and right() are only defined for binary expressions." + ); + return elements[0_c]; + } + + decltype(auto) left () && + { + using namespace hana::literals; + static_assert( + decltype(hana::size(elements))::value == 2UL, + "left() and right() are only defined for binary expressions." + ); + return static_cast(elements)[0_c]; + } + + decltype(auto) right () const & { using namespace hana::literals; static_assert( @@ -96,6 +136,26 @@ namespace boost::proto17 { return elements[1_c]; } + decltype(auto) right () & + { + using namespace hana::literals; + static_assert( + decltype(hana::size(elements))::value == 2UL, + "left() and right() are only defined for binary expressions." + ); + return elements[1_c]; + } + + decltype(auto) right () && + { + using namespace hana::literals; + static_assert( + decltype(hana::size(elements))::value == 2UL, + "left() and right() are only defined for binary expressions." + ); + return static_cast(elements)[1_c]; + } + #define BOOST_PROTO17_UNARY_MEMBER_OPERATOR(op, op_name) \ auto operator op const & \ { \ @@ -213,6 +273,105 @@ namespace boost::proto17 { } }; + template + decltype(auto) value (Expr const & expr) + { + using namespace hana::literals; + static_assert( + decltype(hana::size(expr.elements))::value == 1UL, + "value() is only defined for unary expressions." + ); + return expr.elements[0_c]; + } + + template + decltype(auto) value (Expr & expr) + { + using namespace hana::literals; + static_assert( + decltype(hana::size(expr.elements))::value == 1UL, + "value() is only defined for unary expressions." + ); + return expr.elements[0_c]; + } + + template + decltype(auto) value (std::remove_reference_t && expr) + { + using namespace hana::literals; + static_assert( + decltype(hana::size(expr.elements))::value == 1UL, + "value() is only defined for unary expressions." + ); + return static_cast(expr.elements)[0_c]; + } + + template + decltype(auto) left (Expr const & expr) + { + using namespace hana::literals; + static_assert( + decltype(hana::size(expr.elements))::value == 2UL, + "left() and right() are only defined for binary expressions." + ); + return expr.elements[0_c]; + } + + template + decltype(auto) left (Expr & expr) + { + using namespace hana::literals; + static_assert( + decltype(hana::size(expr.elements))::value == 2UL, + "left() and right() are only defined for binary expressions." + ); + return expr.elements[0_c]; + } + + template + decltype(auto) left (std::remove_reference_t && expr) + { + using namespace hana::literals; + static_assert( + decltype(hana::size(expr.elements))::value == 2UL, + "left() and right() are only defined for binary expressions." + ); + return static_cast(expr.elements)[0_c]; + } + + template + decltype(auto) right (Expr const & expr) + { + using namespace hana::literals; + static_assert( + decltype(hana::size(expr.elements))::value == 2UL, + "left() and right() are only defined for binary expressions." + ); + return expr.elements[1_c]; + } + + template + decltype(auto) right (Expr & expr) + { + using namespace hana::literals; + static_assert( + decltype(hana::size(expr.elements))::value == 2UL, + "left() and right() are only defined for binary expressions." + ); + return expr.elements[1_c]; + } + + template + decltype(auto) right (std::remove_reference_t && expr) + { + using namespace hana::literals; + static_assert( + decltype(hana::size(expr.elements))::value == 2UL, + "left() and right() are only defined for binary expressions." + ); + return static_cast(expr.elements)[1_c]; + } + namespace detail { template