summaryrefslogtreecommitdiff
path: root/boost/variant/detail/apply_visitor_unary.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/variant/detail/apply_visitor_unary.hpp')
-rw-r--r--boost/variant/detail/apply_visitor_unary.hpp80
1 files changed, 19 insertions, 61 deletions
diff --git a/boost/variant/detail/apply_visitor_unary.hpp b/boost/variant/detail/apply_visitor_unary.hpp
index 7e93a51415..71610cb674 100644
--- a/boost/variant/detail/apply_visitor_unary.hpp
+++ b/boost/variant/detail/apply_visitor_unary.hpp
@@ -4,7 +4,7 @@
//-----------------------------------------------------------------------------
//
// Copyright (c) 2002-2003 Eric Friedman
-// Copyright (c) 2014 Antony Polukhin
+// Copyright (c) 2014-2019 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -14,17 +14,8 @@
#define BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP
#include <boost/config.hpp>
-#include <boost/detail/workaround.hpp>
-#include <boost/variant/detail/generic_result_type.hpp>
#include <boost/move/utility.hpp>
-#if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
-#include <boost/core/enable_if.hpp>
-#include <boost/mpl/not.hpp>
-#include <boost/type_traits/is_const.hpp>
-#include <boost/type_traits/remove_reference.hpp>
-#endif
-
#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
# include <boost/mpl/distance.hpp>
# include <boost/mpl/advance.hpp>
@@ -32,6 +23,7 @@
# include <boost/mpl/size.hpp>
# include <boost/utility/declval.hpp>
# include <boost/core/enable_if.hpp>
+# include <boost/type_traits/remove_reference.hpp>
# include <boost/variant/detail/has_result_type.hpp>
#endif
@@ -47,59 +39,36 @@ namespace boost {
// 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
-
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <typename Visitor, typename Visitable>
-inline
- BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor)
+inline typename Visitor::result_type
apply_visitor(Visitor& visitor, Visitable&& visitable)
{
return ::boost::forward<Visitable>(visitable).apply_visitor(visitor);
}
#else
template <typename Visitor, typename Visitable>
-inline
- BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor)
+inline typename Visitor::result_type
apply_visitor(Visitor& visitor, Visitable& visitable)
{
return visitable.apply_visitor(visitor);
}
#endif
-#undef BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE
-
//
// const-visitor version:
//
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <typename Visitor, typename Visitable>
-inline
- BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
+inline typename Visitor::result_type
apply_visitor(const Visitor& visitor, Visitable&& visitable)
{
return ::boost::forward<Visitable>(visitable).apply_visitor(visitor);
}
#else
template <typename Visitor, typename Visitable>
-inline
- BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
+inline typename Visitor::result_type
apply_visitor(const Visitor& visitor, Visitable& visitable)
{
return visitable.apply_visitor(visitor);
@@ -108,6 +77,7 @@ apply_visitor(const Visitor& visitor, Visitable& visitable)
#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
+#define BOOST_VARIANT_HAS_DECLTYPE_APPLY_VISITOR_RETURN_TYPE
// C++14
namespace detail { namespace variant {
@@ -121,39 +91,27 @@ struct result_multideduce1 {
begin_it, boost::mpl::int_<boost::mpl::size<types>::type::value - 1>
>::type last_it;
- // For metaprogramming purposes ONLY! Do not use this method (and class) at runtime!
- static Visitor& vis() BOOST_NOEXCEPT {
- // Functions that work with lambdas must be defined in same translation unit.
- // Because of that, we can not use `boost::decval<Visitor&>()` here.
- Visitor&(*f)() = 0; // pointer to function
- return f();
- }
-
- static decltype(auto) deduce_impl(last_it, unsigned /*helper*/) {
- typedef typename boost::mpl::deref<last_it>::type value_t;
- return vis()( boost::declval< value_t& >() );
- }
-
- template <class It>
- static decltype(auto) deduce_impl(It, unsigned helper) {
+ template <class It, class Dummy = void> // avoid explicit specialization in class scope
+ struct deduce_impl {
typedef typename boost::mpl::next<It>::type next_t;
typedef typename boost::mpl::deref<It>::type value_t;
- if (helper == boost::mpl::distance<begin_it, It>::type::value) {
- return deduce_impl(next_t(), ++helper);
- }
+ typedef decltype(true ? boost::declval< Visitor& >()( boost::declval< value_t >() )
+ : boost::declval< typename deduce_impl<next_t>::type >()) type;
+ };
- return vis()( boost::declval< value_t& >() );
- }
+ template <class Dummy>
+ struct deduce_impl<last_it, Dummy> {
+ typedef typename boost::mpl::deref<last_it>::type value_t;
+ typedef decltype(boost::declval< Visitor& >()( boost::declval< value_t >() )) type;
+ };
- static decltype(auto) deduce() {
- return deduce_impl(begin_it(), 0);
- }
+ typedef typename deduce_impl<begin_it>::type type;
};
template <class Visitor, class Variant>
struct result_wrapper1
{
- typedef decltype(result_multideduce1<Visitor, Variant>::deduce()) result_type;
+ typedef typename result_multideduce1<Visitor, Variant>::type result_type;
Visitor&& visitor_;
explicit result_wrapper1(Visitor&& visitor) BOOST_NOEXCEPT