Line data Source code
1 : //----------------------------------------------------------------------------- 2 : // boost variant/detail/apply_visitor_unary.hpp header file 3 : // See http://www.boost.org for updates, documentation, and revision history. 4 : //----------------------------------------------------------------------------- 5 : // 6 : // Copyright (c) 2002-2003 Eric Friedman 7 : // Copyright (c) 2014-2025 Antony Polukhin 8 : // 9 : // Distributed under the Boost Software License, Version 1.0. (See 10 : // accompanying file LICENSE_1_0.txt or copy at 11 : // http://www.boost.org/LICENSE_1_0.txt) 12 : 13 : #ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP 14 : #define BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP 15 : 16 : #include <boost/config.hpp> 17 : #include <utility> 18 : 19 : #if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) 20 : # include <boost/mpl/distance.hpp> 21 : # include <boost/mpl/advance.hpp> 22 : # include <boost/mpl/deref.hpp> 23 : # include <boost/mpl/size.hpp> 24 : # include <boost/utility/declval.hpp> 25 : # include <boost/core/enable_if.hpp> 26 : # include <boost/type_traits/copy_cv_ref.hpp> 27 : # include <boost/type_traits/remove_reference.hpp> 28 : # include <boost/variant/detail/has_result_type.hpp> 29 : #endif 30 : 31 : namespace boost { 32 : 33 : ////////////////////////////////////////////////////////////////////////// 34 : // function template apply_visitor(visitor, visitable) 35 : // 36 : // Visits visitable with visitor. 37 : // 38 : 39 : // 40 : // nonconst-visitor version: 41 : // 42 : 43 : template <typename Visitor, typename Visitable> 44 : inline typename Visitor::result_type 45 : apply_visitor(Visitor& visitor, Visitable&& visitable) 46 : { 47 : return std::forward<Visitable>(visitable).apply_visitor(visitor); 48 : } 49 : 50 : // 51 : // const-visitor version: 52 : // 53 : 54 : template <typename Visitor, typename Visitable> 55 : inline typename Visitor::result_type 56 452 : apply_visitor(const Visitor& visitor, Visitable&& visitable) 57 : { 58 452 : return std::forward<Visitable>(visitable).apply_visitor(visitor); 59 : } 60 : 61 : 62 : #if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) 63 : #define BOOST_VARIANT_HAS_DECLTYPE_APPLY_VISITOR_RETURN_TYPE 64 : 65 : // C++14 66 : namespace detail { namespace variant { 67 : 68 : // This class serves only metaprogramming purposes. none of its methods must be called at runtime! 69 : template <class Visitor, class Variant> 70 : struct result_multideduce1 { 71 : typedef typename remove_reference<Variant>::type::types types; 72 : typedef typename boost::mpl::begin<types>::type begin_it; 73 : typedef typename boost::mpl::advance< 74 : begin_it, boost::mpl::int_<boost::mpl::size<types>::type::value - 1> 75 : >::type last_it; 76 : 77 : template <class It, class Dummy = void> // avoid explicit specialization in class scope 78 : struct deduce_impl { 79 : typedef typename boost::mpl::next<It>::type next_t; 80 : typedef typename boost::mpl::deref<It>::type value_t; 81 : typedef decltype(true ? boost::declval< Visitor& >()( boost::declval< copy_cv_ref_t< value_t, Variant > >() ) 82 : : boost::declval< typename deduce_impl<next_t>::type >()) type; 83 : }; 84 : 85 : template <class Dummy> 86 : struct deduce_impl<last_it, Dummy> { 87 : typedef typename boost::mpl::deref<last_it>::type value_t; 88 : typedef decltype(boost::declval< Visitor& >()( boost::declval< copy_cv_ref_t< value_t, Variant > >() )) type; 89 : }; 90 : 91 : typedef typename deduce_impl<begin_it>::type type; 92 : }; 93 : 94 : template <class Visitor, class Variant> 95 : struct result_wrapper1 96 : { 97 : typedef typename result_multideduce1<Visitor, Variant>::type result_type; 98 : 99 : Visitor&& visitor_; 100 : explicit result_wrapper1(Visitor&& visitor) BOOST_NOEXCEPT 101 : : visitor_(std::forward<Visitor>(visitor)) 102 : {} 103 : 104 : template <class T> 105 : result_type operator()(T&& val) const { 106 : return visitor_(std::forward<T>(val)); 107 : } 108 : }; 109 : 110 : }} // namespace detail::variant 111 : 112 : template <typename Visitor, typename Visitable> 113 : inline decltype(auto) apply_visitor(Visitor&& visitor, Visitable&& visitable, 114 : typename boost::disable_if< 115 : boost::detail::variant::has_result_type<Visitor>, 116 : bool 117 : >::type = true) 118 : { 119 : boost::detail::variant::result_wrapper1<Visitor, Visitable> cpp14_vis(std::forward<Visitor>(visitor)); 120 : return std::forward<Visitable>(visitable).apply_visitor(cpp14_vis); 121 : } 122 : 123 : #endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) 124 : 125 : } // namespace boost 126 : 127 : #endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP