diff options
Diffstat (limited to 'boost/variant/detail/apply_visitor_unary.hpp')
-rw-r--r-- | boost/variant/detail/apply_visitor_unary.hpp | 80 |
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 |