annotate DEPENDENCIES/generic/include/boost/variant/detail/apply_visitor_unary.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 //-----------------------------------------------------------------------------
Chris@16 2 // boost variant/detail/apply_visitor_unary.hpp header file
Chris@16 3 // See http://www.boost.org for updates, documentation, and revision history.
Chris@16 4 //-----------------------------------------------------------------------------
Chris@16 5 //
Chris@101 6 // Copyright (c) 2002-2003 Eric Friedman
Chris@101 7 // Copyright (c) 2014 Antony Polukhin
Chris@16 8 //
Chris@16 9 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 10 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 11 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 12
Chris@16 13 #ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP
Chris@16 14 #define BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP
Chris@16 15
Chris@16 16 #include "boost/config.hpp"
Chris@16 17 #include "boost/detail/workaround.hpp"
Chris@16 18 #include "boost/variant/detail/generic_result_type.hpp"
Chris@16 19
Chris@16 20 #if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
Chris@101 21 #include "boost/core/enable_if.hpp"
Chris@16 22 #include "boost/mpl/not.hpp"
Chris@16 23 #include "boost/type_traits/is_const.hpp"
Chris@16 24 #endif
Chris@16 25
Chris@101 26 #if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
Chris@101 27 # include <boost/mpl/distance.hpp>
Chris@101 28 # include <boost/mpl/advance.hpp>
Chris@101 29 # include <boost/mpl/deref.hpp>
Chris@101 30 # include <boost/mpl/size.hpp>
Chris@101 31 # include <boost/utility/declval.hpp>
Chris@101 32 # include <boost/core/enable_if.hpp>
Chris@101 33 # include "boost/variant/detail/has_result_type.hpp"
Chris@101 34 #endif
Chris@101 35
Chris@16 36 namespace boost {
Chris@16 37
Chris@16 38 //////////////////////////////////////////////////////////////////////////
Chris@16 39 // function template apply_visitor(visitor, visitable)
Chris@16 40 //
Chris@16 41 // Visits visitable with visitor.
Chris@16 42 //
Chris@16 43
Chris@16 44 //
Chris@16 45 // nonconst-visitor version:
Chris@16 46 //
Chris@16 47
Chris@16 48 #if !BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
Chris@16 49
Chris@16 50 # define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
Chris@16 51 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
Chris@16 52 /**/
Chris@16 53
Chris@16 54 #else // EDG-based compilers
Chris@16 55
Chris@16 56 # define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
Chris@16 57 typename enable_if< \
Chris@16 58 mpl::not_< is_const< V > > \
Chris@16 59 , BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
Chris@16 60 >::type \
Chris@16 61 /**/
Chris@16 62
Chris@16 63 #endif // EDG-based compilers workaround
Chris@16 64
Chris@16 65 template <typename Visitor, typename Visitable>
Chris@16 66 inline
Chris@16 67 BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor)
Chris@16 68 apply_visitor(Visitor& visitor, Visitable& visitable)
Chris@16 69 {
Chris@16 70 return visitable.apply_visitor(visitor);
Chris@16 71 }
Chris@16 72
Chris@16 73 #undef BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE
Chris@16 74
Chris@16 75 //
Chris@16 76 // const-visitor version:
Chris@16 77 //
Chris@16 78
Chris@16 79 template <typename Visitor, typename Visitable>
Chris@16 80 inline
Chris@16 81 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
Chris@16 82 apply_visitor(const Visitor& visitor, Visitable& visitable)
Chris@16 83 {
Chris@16 84 return visitable.apply_visitor(visitor);
Chris@16 85 }
Chris@16 86
Chris@101 87
Chris@101 88 #if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
Chris@101 89
Chris@101 90 // C++14
Chris@101 91 namespace detail { namespace variant {
Chris@101 92
Chris@101 93 // This class serves only metaprogramming purposes. none of its methods must be called at runtime!
Chris@101 94 template <class Visitor, class Variant>
Chris@101 95 struct result_multideduce1 {
Chris@101 96 typedef typename Variant::types types;
Chris@101 97 typedef typename boost::mpl::begin<types>::type begin_it;
Chris@101 98 typedef typename boost::mpl::advance<
Chris@101 99 begin_it, boost::mpl::int_<boost::mpl::size<types>::type::value - 1>
Chris@101 100 >::type last_it;
Chris@101 101
Chris@101 102 // For metaprogramming purposes ONLY! Do not use this method (and class) at runtime!
Chris@101 103 static Visitor& vis() BOOST_NOEXCEPT {
Chris@101 104 // Functions that work with lambdas must be defined in same translation unit.
Chris@101 105 // Because of that, we can not use `boost::decval<Visitor&>()` here.
Chris@101 106 Visitor&(*f)() = 0; // pointer to function
Chris@101 107 return f();
Chris@101 108 }
Chris@101 109
Chris@101 110 static decltype(auto) deduce_impl(last_it, unsigned /*helper*/) {
Chris@101 111 typedef typename boost::mpl::deref<last_it>::type value_t;
Chris@101 112 return vis()( boost::declval< value_t& >() );
Chris@101 113 }
Chris@101 114
Chris@101 115 template <class It>
Chris@101 116 static decltype(auto) deduce_impl(It, unsigned helper) {
Chris@101 117 typedef typename boost::mpl::next<It>::type next_t;
Chris@101 118 typedef typename boost::mpl::deref<It>::type value_t;
Chris@101 119 if (helper == boost::mpl::distance<begin_it, It>::type::value) {
Chris@101 120 return deduce_impl(next_t(), ++helper);
Chris@101 121 }
Chris@101 122
Chris@101 123 return vis()( boost::declval< value_t& >() );
Chris@101 124 }
Chris@101 125
Chris@101 126 static decltype(auto) deduce() {
Chris@101 127 return deduce_impl(begin_it(), 0);
Chris@101 128 }
Chris@101 129 };
Chris@101 130
Chris@101 131 template <class Visitor, class Variant>
Chris@101 132 struct result_wrapper1
Chris@101 133 {
Chris@101 134 typedef decltype(result_multideduce1<Visitor, Variant>::deduce()) result_type;
Chris@101 135
Chris@101 136 Visitor& visitor_;
Chris@101 137 explicit result_wrapper1(Visitor& visitor) BOOST_NOEXCEPT
Chris@101 138 : visitor_(visitor)
Chris@101 139 {}
Chris@101 140
Chris@101 141 template <class T>
Chris@101 142 result_type operator()(T& val) const {
Chris@101 143 return visitor_(val);
Chris@101 144 }
Chris@101 145 };
Chris@101 146
Chris@101 147 }} // namespace detail::variant
Chris@101 148
Chris@101 149 template <typename Visitor, typename Visitable>
Chris@101 150 inline decltype(auto) apply_visitor(Visitor& visitor, Visitable& visitable,
Chris@101 151 typename boost::disable_if<
Chris@101 152 boost::detail::variant::has_result_type<Visitor>
Chris@101 153 >::type* = 0)
Chris@101 154 {
Chris@101 155 boost::detail::variant::result_wrapper1<Visitor, Visitable> cpp14_vis(visitor);
Chris@101 156 return visitable.apply_visitor(cpp14_vis);
Chris@101 157 }
Chris@101 158
Chris@101 159 template <typename Visitor, typename Visitable>
Chris@101 160 inline decltype(auto) apply_visitor(const Visitor& visitor, Visitable& visitable,
Chris@101 161 typename boost::disable_if<
Chris@101 162 boost::detail::variant::has_result_type<Visitor>
Chris@101 163 >::type* = 0)
Chris@101 164 {
Chris@101 165 boost::detail::variant::result_wrapper1<const Visitor, Visitable> cpp14_vis(visitor);
Chris@101 166 return visitable.apply_visitor(cpp14_vis);
Chris@101 167 }
Chris@101 168
Chris@101 169 #endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
Chris@16 170
Chris@16 171 } // namespace boost
Chris@16 172
Chris@16 173 #endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP