//----------------------------------------------------------------------------- | |
// 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 | |
// | |
// 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/detail/workaround.hpp" | |
#include "boost/variant/detail/generic_result_type.hpp" | |
#include "boost/variant/detail/apply_visitor_unary.hpp" | |
#if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302)) | |
#include "boost/utility/enable_if.hpp" | |
#include "boost/mpl/not.hpp" | |
#include "boost/type_traits/is_const.hpp" | |
#endif | |
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> | |
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) | |
: visitor_(visitor) | |
, value1_(value1) | |
{ | |
} | |
public: // visitor interfaces | |
template <typename Value2> | |
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) | |
operator()(Value2& value2) | |
{ | |
return visitor_(value1_, value2); | |
} | |
private: | |
apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&); | |
}; | |
template <typename Visitor, typename Visitable2> | |
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) | |
: visitor_(visitor) | |
, visitable2_(visitable2) | |
{ | |
} | |
public: // visitor interfaces | |
template <typename Value1> | |
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) | |
operator()(Value1& value1) | |
{ | |
apply_visitor_binary_invoke< | |
Visitor | |
, Value1 | |
> 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: | |
// | |
#if !BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302)) | |
# define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \ | |
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \ | |
/**/ | |
#else // EDG-based compilers | |
# define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \ | |
typename enable_if< \ | |
mpl::not_< is_const< V > > \ | |
, BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \ | |
>::type \ | |
/**/ | |
#endif // EDG-based compilers workaround | |
template <typename Visitor, typename Visitable1, typename Visitable2> | |
inline | |
BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor) | |
apply_visitor( | |
Visitor& visitor | |
, Visitable1& visitable1, Visitable2& visitable2 | |
) | |
{ | |
::boost::detail::variant::apply_visitor_binary_unwrap< | |
Visitor, Visitable2 | |
> unwrapper(visitor, visitable2); | |
return boost::apply_visitor(unwrapper, visitable1); | |
} | |
#undef BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE | |
// | |
// const-visitor version: | |
// | |
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) | |
template <typename Visitor, typename Visitable1, typename Visitable2> | |
inline | |
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE( | |
typename Visitor::result_type | |
) | |
apply_visitor( | |
const Visitor& visitor | |
, Visitable1& visitable1, Visitable2& visitable2 | |
) | |
{ | |
::boost::detail::variant::apply_visitor_binary_unwrap< | |
const Visitor, Visitable2 | |
> unwrapper(visitor, visitable2); | |
return boost::apply_visitor(unwrapper, visitable1); | |
} | |
#endif // MSVC7 and below exclusion | |
} // namespace boost | |
#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP |