ext-boost/boost/variant/detail/apply_visitor_binary.hpp

358 lines
10 KiB
C++
Raw Normal View History

2016-08-09 01:33:33 +00:00
//-----------------------------------------------------------------------------
// boost variant/detail/apply_visitor_binary.hpp header file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
2017-03-13 04:29:07 +00:00
// Copyright (c) 2002-2003 Eric Friedman
2019-08-24 13:39:04 +00:00
// Copyright (c) 2014-2019 Antony Polukhin
2016-08-09 01:33:33 +00:00
//
// 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
2017-03-13 04:29:07 +00:00
#include <boost/config.hpp>
2016-08-09 01:33:33 +00:00
2017-03-13 04:29:07 +00:00
#include <boost/variant/detail/apply_visitor_unary.hpp>
2016-08-09 01:33:33 +00:00
2017-03-13 04:29:07 +00:00
#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
# include <boost/variant/detail/has_result_type.hpp>
2016-08-09 01:33:33 +00:00
#endif
2018-01-01 20:31:13 +00:00
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
2019-08-24 13:39:04 +00:00
# include <boost/core/enable_if.hpp>
2018-01-01 20:31:13 +00:00
# include <boost/type_traits/is_lvalue_reference.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/move/move.hpp>
# include <boost/move/utility.hpp>
#endif
2016-08-09 01:33:33 +00:00
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 {
2018-01-01 20:31:13 +00:00
template <typename Visitor, typename Value1, bool MoveSemantics>
2016-08-09 01:33:33 +00:00
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
2018-01-01 20:31:13 +00:00
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <typename Value2>
2019-08-24 13:39:04 +00:00
typename enable_if_c<MoveSemantics && is_same<Value2, Value2>::value, result_type>::type
2018-01-01 20:31:13 +00:00
operator()(Value2&& value2)
{
return visitor_(::boost::move(value1_), ::boost::forward<Value2>(value2));
}
template <typename Value2>
2019-08-24 13:39:04 +00:00
typename disable_if_c<MoveSemantics && is_same<Value2, Value2>::value, result_type>::type
2018-01-01 20:31:13 +00:00
operator()(Value2&& value2)
{
return visitor_(value1_, ::boost::forward<Value2>(value2));
}
#else
2016-08-09 01:33:33 +00:00
template <typename Value2>
2019-08-24 13:39:04 +00:00
result_type
2016-08-09 01:33:33 +00:00
operator()(Value2& value2)
{
return visitor_(value1_, value2);
}
2018-01-01 20:31:13 +00:00
#endif
2016-08-09 01:33:33 +00:00
private:
apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&);
};
2018-01-01 20:31:13 +00:00
template <typename Visitor, typename Visitable2, bool MoveSemantics>
2016-08-09 01:33:33 +00:00
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
2018-01-01 20:31:13 +00:00
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <typename Value1>
2019-08-24 13:39:04 +00:00
typename enable_if_c<MoveSemantics && is_same<Value1, Value1>::value, result_type>::type
2018-01-01 20:31:13 +00:00
operator()(Value1&& value1)
{
apply_visitor_binary_invoke<
Visitor
, Value1
, ! ::boost::is_lvalue_reference<Value1>::value
> invoker(visitor_, value1);
return boost::apply_visitor(invoker, ::boost::move(visitable2_));
}
template <typename Value1>
2019-08-24 13:39:04 +00:00
typename disable_if_c<MoveSemantics && is_same<Value1, Value1>::value, result_type>::type
2018-01-01 20:31:13 +00:00
operator()(Value1&& value1)
{
apply_visitor_binary_invoke<
Visitor
, Value1
, ! ::boost::is_lvalue_reference<Value1>::value
> invoker(visitor_, value1);
return boost::apply_visitor(invoker, visitable2_);
}
#else
2016-08-09 01:33:33 +00:00
template <typename Value1>
2019-08-24 13:39:04 +00:00
result_type
2016-08-09 01:33:33 +00:00
operator()(Value1& value1)
{
apply_visitor_binary_invoke<
Visitor
, Value1
2018-01-01 20:31:13 +00:00
, false
2016-08-09 01:33:33 +00:00
> invoker(visitor_, value1);
return boost::apply_visitor(invoker, visitable2_);
}
2018-01-01 20:31:13 +00:00
#endif
2016-08-09 01:33:33 +00:00
private:
apply_visitor_binary_unwrap& operator=(const apply_visitor_binary_unwrap&);
};
}} // namespace detail::variant
//
// nonconst-visitor version:
//
2018-01-01 20:31:13 +00:00
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <typename Visitor, typename Visitable1, typename Visitable2>
2019-08-24 13:39:04 +00:00
inline typename Visitor::result_type
2018-01-01 20:31:13 +00:00
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, ::boost::forward<Visitable1>(visitable1));
}
#else
2016-08-09 01:33:33 +00:00
template <typename Visitor, typename Visitable1, typename Visitable2>
2019-08-24 13:39:04 +00:00
inline typename Visitor::result_type
2018-01-01 20:31:13 +00:00
apply_visitor( Visitor& visitor, Visitable1& visitable1, Visitable2& visitable2)
2016-08-09 01:33:33 +00:00
{
::boost::detail::variant::apply_visitor_binary_unwrap<
2018-01-01 20:31:13 +00:00
Visitor, Visitable2, false
2016-08-09 01:33:33 +00:00
> unwrapper(visitor, visitable2);
return boost::apply_visitor(unwrapper, visitable1);
}
2018-01-01 20:31:13 +00:00
#endif
2016-08-09 01:33:33 +00:00
//
// const-visitor version:
//
2018-01-01 20:31:13 +00:00
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
2016-08-09 01:33:33 +00:00
template <typename Visitor, typename Visitable1, typename Visitable2>
2019-08-24 13:39:04 +00:00
inline typename Visitor::result_type
2018-01-01 20:31:13 +00:00
apply_visitor( const Visitor& visitor , Visitable1&& visitable1 , Visitable2&& visitable2)
2016-08-09 01:33:33 +00:00
{
::boost::detail::variant::apply_visitor_binary_unwrap<
2018-01-01 20:31:13 +00:00
const Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
> unwrapper(visitor, visitable2);
return boost::apply_visitor(unwrapper, ::boost::forward<Visitable1>(visitable1));
}
#else
template <typename Visitor, typename Visitable1, typename Visitable2>
2019-08-24 13:39:04 +00:00
inline typename Visitor::result_type
2018-01-01 20:31:13 +00:00
apply_visitor( const Visitor& visitor , Visitable1& visitable1 , Visitable2& visitable2)
{
::boost::detail::variant::apply_visitor_binary_unwrap<
const Visitor, Visitable2, false
2016-08-09 01:33:33 +00:00
> unwrapper(visitor, visitable2);
return boost::apply_visitor(unwrapper, visitable1);
}
2018-01-01 20:31:13 +00:00
#endif
2017-03-13 04:29:07 +00:00
#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 {
2018-01-01 20:31:13 +00:00
template <typename Visitor, typename Value1, bool MoveSemantics>
2017-03-13 04:29:07 +00:00
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>
2018-01-01 20:31:13 +00:00
decltype(auto) operator()(Value2&& value2, typename enable_if_c<MoveSemantics && is_same<Value2, Value2>::value>::type* = 0)
2017-03-13 04:29:07 +00:00
{
2018-01-01 20:31:13 +00:00
return visitor_(::boost::move(value1_), ::boost::forward<Value2>(value2));
}
template <typename Value2>
decltype(auto) operator()(Value2&& value2, typename disable_if_c<MoveSemantics && is_same<Value2, Value2>::value>::type* = 0)
{
return visitor_(value1_, ::boost::forward<Value2>(value2));
2017-03-13 04:29:07 +00:00
}
private:
apply_visitor_binary_invoke_cpp14& operator=(const apply_visitor_binary_invoke_cpp14&);
};
2018-01-01 20:31:13 +00:00
template <typename Visitor, typename Visitable2, bool MoveSemantics>
2017-03-13 04:29:07 +00:00
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>
2018-01-01 20:31:13 +00:00
decltype(auto) operator()(Value1&& value1, typename enable_if_c<MoveSemantics && is_same<Value1, Value1>::value>::type* = 0)
2017-03-13 04:29:07 +00:00
{
apply_visitor_binary_invoke_cpp14<
Visitor
, Value1
2018-01-01 20:31:13 +00:00
, ! ::boost::is_lvalue_reference<Value1>::value
> invoker(visitor_, value1);
return boost::apply_visitor(invoker, ::boost::move(visitable2_));
}
template <typename Value1>
decltype(auto) operator()(Value1&& value1, typename disable_if_c<MoveSemantics && is_same<Value1, Value1>::value>::type* = 0)
{
apply_visitor_binary_invoke_cpp14<
Visitor
, Value1
, ! ::boost::is_lvalue_reference<Value1>::value
2017-03-13 04:29:07 +00:00
> 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>
2018-01-01 20:31:13 +00:00
inline decltype(auto) apply_visitor(Visitor& visitor, Visitable1&& visitable1, Visitable2&& visitable2,
2017-03-13 04:29:07 +00:00
typename boost::disable_if<
boost::detail::variant::has_result_type<Visitor>
>::type* = 0)
{
::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
2018-01-01 20:31:13 +00:00
Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
2017-03-13 04:29:07 +00:00
> unwrapper(visitor, visitable2);
2018-01-01 20:31:13 +00:00
return boost::apply_visitor(unwrapper, ::boost::forward<Visitable1>(visitable1));
2017-03-13 04:29:07 +00:00
}
template <typename Visitor, typename Visitable1, typename Visitable2>
2018-01-01 20:31:13 +00:00
inline decltype(auto) apply_visitor(const Visitor& visitor, Visitable1&& visitable1, Visitable2&& visitable2,
2017-03-13 04:29:07 +00:00
typename boost::disable_if<
boost::detail::variant::has_result_type<Visitor>
>::type* = 0)
{
::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
2018-01-01 20:31:13 +00:00
const Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
2017-03-13 04:29:07 +00:00
> unwrapper(visitor, visitable2);
2018-01-01 20:31:13 +00:00
return boost::apply_visitor(unwrapper, ::boost::forward<Visitable1>(visitable1));
2017-03-13 04:29:07 +00:00
}
2018-01-01 20:31:13 +00:00
2017-03-13 04:29:07 +00:00
#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
2016-08-09 01:33:33 +00:00
} // namespace boost
#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP