123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- //-----------------------------------------------------------------------------
- // boost variant/detail/apply_visitor_binary.hpp header file
- // See http://www.boost.org for updates, documentation, and revision history.
- //-----------------------------------------------------------------------------
- //
- // Copyright (c) 2002-2003 Eric Friedman
- // Copyright (c) 2014-2024 Antony Polukhin
- //
- // 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_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 {
- //////////////////////////////////////////////////////////////////////////
- // function template apply_visitor(visitor, visitable1, visitable2)
- //
- // Visits visitable1 and visitable2 such that their values (which we
- // shall call x and y, respectively) are used as arguments in the
- // expression visitor(x, y).
- //
- namespace detail { namespace variant {
- template <typename Visitor, typename Value1, bool MoveSemantics>
- class apply_visitor_binary_invoke
- {
- public: // visitor typedefs
- typedef typename Visitor::result_type
- result_type;
- private: // representation
- Visitor& visitor_;
- Value1& value1_;
- public: // structors
- apply_visitor_binary_invoke(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
- : visitor_(visitor)
- , value1_(value1)
- {
- }
- public: // visitor interfaces
- 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: // visitor typedefs
- typedef typename Visitor::result_type
- result_type;
- private: // representation
- Visitor& visitor_;
- Visitable2& visitable2_;
- public: // structors
- apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
- : visitor_(visitor)
- , visitable2_(visitable2)
- {
- }
- public: // visitor interfaces
- 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&);
- };
- }} // namespace detail::variant
- //
- // nonconst-visitor version:
- //
- 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));
- }
- //
- // const-visitor version:
- //
- 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)
- //////////////////////////////////////////////////////////////////////////
- // function template apply_visitor(visitor, visitable1, visitable2)
- //
- // C++14 part.
- //
- namespace detail { namespace variant {
- template <typename Visitor, typename Value1, bool MoveSemantics>
- class apply_visitor_binary_invoke_cpp14
- {
- Visitor& visitor_;
- Value1& value1_;
- public: // structors
- apply_visitor_binary_invoke_cpp14(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
- : visitor_(visitor)
- , value1_(value1)
- {
- }
- public: // visitor interfaces
- 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: // structors
- apply_visitor_binary_unwrap_cpp14(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
- : visitor_(visitor)
- , visitable2_(visitable2)
- {
- }
- public: // visitor interfaces
- 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&);
- };
- }} // namespace detail::variant
- 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 // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
- } // namespace boost
- #endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
|