123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- #ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
- #define BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
- #include <boost/config.hpp>
- #include <boost/variant/detail/apply_visitor_unary.hpp>
- #if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
- # include <boost/variant/detail/has_result_type.hpp>
- #endif
- #include <boost/core/enable_if.hpp>
- #include <boost/type_traits/is_lvalue_reference.hpp>
- #include <boost/type_traits/is_same.hpp>
- #include <utility>
- namespace boost {
- namespace detail { namespace variant {
- template <typename Visitor, typename Value1, bool MoveSemantics>
- class apply_visitor_binary_invoke
- {
- public:
- typedef typename Visitor::result_type
- result_type;
- private:
- Visitor& visitor_;
- Value1& value1_;
- public:
- apply_visitor_binary_invoke(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
- : visitor_(visitor)
- , value1_(value1)
- {
- }
- public:
- template <typename Value2>
- typename enable_if_c<MoveSemantics && is_same<Value2, Value2>::value, result_type>::type
- operator()(Value2&& value2)
- {
- return visitor_(std::move(value1_), std::forward<Value2>(value2));
- }
- template <typename Value2>
- typename disable_if_c<MoveSemantics && is_same<Value2, Value2>::value, result_type>::type
- operator()(Value2&& value2)
- {
- return visitor_(value1_, std::forward<Value2>(value2));
- }
- private:
- apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&);
- };
- template <typename Visitor, typename Visitable2, bool MoveSemantics>
- class apply_visitor_binary_unwrap
- {
- public:
- typedef typename Visitor::result_type
- result_type;
- private:
- Visitor& visitor_;
- Visitable2& visitable2_;
- public:
- apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
- : visitor_(visitor)
- , visitable2_(visitable2)
- {
- }
- public:
- template <typename Value1>
- typename enable_if_c<MoveSemantics && is_same<Value1, Value1>::value, result_type>::type
- operator()(Value1&& value1)
- {
- apply_visitor_binary_invoke<
- Visitor
- , Value1
- , ! ::boost::is_lvalue_reference<Value1>::value
- > invoker(visitor_, value1);
- return boost::apply_visitor(invoker, std::move(visitable2_));
- }
- template <typename Value1>
- typename disable_if_c<MoveSemantics && is_same<Value1, Value1>::value, result_type>::type
- operator()(Value1&& value1)
- {
- apply_visitor_binary_invoke<
- Visitor
- , Value1
- , ! ::boost::is_lvalue_reference<Value1>::value
- > invoker(visitor_, value1);
- return boost::apply_visitor(invoker, visitable2_);
- }
- private:
- apply_visitor_binary_unwrap& operator=(const apply_visitor_binary_unwrap&);
- };
- }}
- template <typename Visitor, typename Visitable1, typename Visitable2>
- inline typename Visitor::result_type
- apply_visitor( Visitor& visitor, Visitable1&& visitable1, Visitable2&& visitable2)
- {
- ::boost::detail::variant::apply_visitor_binary_unwrap<
- Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
- > unwrapper(visitor, visitable2);
- return boost::apply_visitor(unwrapper, std::forward<Visitable1>(visitable1));
- }
- template <typename Visitor, typename Visitable1, typename Visitable2>
- inline typename Visitor::result_type
- apply_visitor( const Visitor& visitor , Visitable1&& visitable1 , Visitable2&& visitable2)
- {
- ::boost::detail::variant::apply_visitor_binary_unwrap<
- const Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
- > unwrapper(visitor, visitable2);
- return boost::apply_visitor(unwrapper, std::forward<Visitable1>(visitable1));
- }
- #if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
- namespace detail { namespace variant {
- template <typename Visitor, typename Value1, bool MoveSemantics>
- class apply_visitor_binary_invoke_cpp14
- {
- Visitor& visitor_;
- Value1& value1_;
- public:
- apply_visitor_binary_invoke_cpp14(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
- : visitor_(visitor)
- , value1_(value1)
- {
- }
- public:
- template <typename Value2>
- decltype(auto) operator()(Value2&& value2, typename enable_if_c<MoveSemantics && is_same<Value2, Value2>::value, bool>::type = true)
- {
- return visitor_(std::move(value1_), std::forward<Value2>(value2));
- }
- template <typename Value2>
- decltype(auto) operator()(Value2&& value2, typename disable_if_c<MoveSemantics && is_same<Value2, Value2>::value, bool>::type = true)
- {
- return visitor_(value1_, std::forward<Value2>(value2));
- }
- private:
- apply_visitor_binary_invoke_cpp14& operator=(const apply_visitor_binary_invoke_cpp14&);
- };
- template <typename Visitor, typename Visitable2, bool MoveSemantics>
- class apply_visitor_binary_unwrap_cpp14
- {
- Visitor& visitor_;
- Visitable2& visitable2_;
- public:
- apply_visitor_binary_unwrap_cpp14(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
- : visitor_(visitor)
- , visitable2_(visitable2)
- {
- }
- public:
- template <typename Value1>
- decltype(auto) operator()(Value1&& value1, typename enable_if_c<MoveSemantics && is_same<Value1, Value1>::value, bool>::type = true)
- {
- apply_visitor_binary_invoke_cpp14<
- Visitor
- , Value1
- , ! ::boost::is_lvalue_reference<Value1>::value
- > invoker(visitor_, value1);
- return boost::apply_visitor(invoker, std::move(visitable2_));
- }
- template <typename Value1>
- decltype(auto) operator()(Value1&& value1, typename disable_if_c<MoveSemantics && is_same<Value1, Value1>::value, bool>::type = true)
- {
- apply_visitor_binary_invoke_cpp14<
- Visitor
- , Value1
- , ! ::boost::is_lvalue_reference<Value1>::value
- > invoker(visitor_, value1);
- return boost::apply_visitor(invoker, visitable2_);
- }
- private:
- apply_visitor_binary_unwrap_cpp14& operator=(const apply_visitor_binary_unwrap_cpp14&);
- };
- }}
- template <typename Visitor, typename Visitable1, typename Visitable2>
- inline decltype(auto) apply_visitor(Visitor& visitor, Visitable1&& visitable1, Visitable2&& visitable2,
- typename boost::disable_if<
- boost::detail::variant::has_result_type<Visitor>,
- bool
- >::type = true)
- {
- ::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
- Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
- > unwrapper(visitor, visitable2);
- return boost::apply_visitor(unwrapper, std::forward<Visitable1>(visitable1));
- }
- template <typename Visitor, typename Visitable1, typename Visitable2>
- inline decltype(auto) apply_visitor(const Visitor& visitor, Visitable1&& visitable1, Visitable2&& visitable2,
- typename boost::disable_if<
- boost::detail::variant::has_result_type<Visitor>,
- bool
- >::type = true)
- {
- ::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
- const Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
- > unwrapper(visitor, visitable2);
- return boost::apply_visitor(unwrapper, std::forward<Visitable1>(visitable1));
- }
- #endif
- }
- #endif
|