]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/variant/include/boost/variant/detail/apply_visitor_unary.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / variant / include / boost / variant / detail / apply_visitor_unary.hpp
CommitLineData
7c673cae
FG
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 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 <boost/detail/workaround.hpp>
18#include <boost/variant/detail/generic_result_type.hpp>
19
20#if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
21#include <boost/core/enable_if.hpp>
22#include <boost/mpl/not.hpp>
23#include <boost/type_traits/is_const.hpp>
24#endif
25
26#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
27# include <boost/mpl/distance.hpp>
28# include <boost/mpl/advance.hpp>
29# include <boost/mpl/deref.hpp>
30# include <boost/mpl/size.hpp>
31# include <boost/utility/declval.hpp>
32# include <boost/core/enable_if.hpp>
33# include <boost/variant/detail/has_result_type.hpp>
34#endif
35
36namespace boost {
37
38//////////////////////////////////////////////////////////////////////////
39// function template apply_visitor(visitor, visitable)
40//
41// Visits visitable with visitor.
42//
43
44//
45// nonconst-visitor version:
46//
47
48#if !BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
49
50# define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
51 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
52 /**/
53
54#else // EDG-based compilers
55
56# define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
57 typename enable_if< \
58 mpl::not_< is_const< V > > \
59 , BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
60 >::type \
61 /**/
62
63#endif // EDG-based compilers workaround
64
65template <typename Visitor, typename Visitable>
66inline
67 BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor)
68apply_visitor(Visitor& visitor, Visitable& visitable)
69{
70 return visitable.apply_visitor(visitor);
71}
72
73#undef BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE
74
75//
76// const-visitor version:
77//
78
79template <typename Visitor, typename Visitable>
80inline
81 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
82apply_visitor(const Visitor& visitor, Visitable& visitable)
83{
84 return visitable.apply_visitor(visitor);
85}
86
87
88#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
89
90// C++14
91namespace detail { namespace variant {
92
93// This class serves only metaprogramming purposes. none of its methods must be called at runtime!
94template <class Visitor, class Variant>
95struct result_multideduce1 {
96 typedef typename Variant::types types;
97 typedef typename boost::mpl::begin<types>::type begin_it;
98 typedef typename boost::mpl::advance<
99 begin_it, boost::mpl::int_<boost::mpl::size<types>::type::value - 1>
100 >::type last_it;
101
102 // For metaprogramming purposes ONLY! Do not use this method (and class) at runtime!
103 static Visitor& vis() BOOST_NOEXCEPT {
104 // Functions that work with lambdas must be defined in same translation unit.
105 // Because of that, we can not use `boost::decval<Visitor&>()` here.
106 Visitor&(*f)() = 0; // pointer to function
107 return f();
108 }
109
110 static decltype(auto) deduce_impl(last_it, unsigned /*helper*/) {
111 typedef typename boost::mpl::deref<last_it>::type value_t;
112 return vis()( boost::declval< value_t& >() );
113 }
114
115 template <class It>
116 static decltype(auto) deduce_impl(It, unsigned helper) {
117 typedef typename boost::mpl::next<It>::type next_t;
118 typedef typename boost::mpl::deref<It>::type value_t;
119 if (helper == boost::mpl::distance<begin_it, It>::type::value) {
120 return deduce_impl(next_t(), ++helper);
121 }
122
123 return vis()( boost::declval< value_t& >() );
124 }
125
126 static decltype(auto) deduce() {
127 return deduce_impl(begin_it(), 0);
128 }
129};
130
131template <class Visitor, class Variant>
132struct result_wrapper1
133{
134 typedef decltype(result_multideduce1<Visitor, Variant>::deduce()) result_type;
135
136 Visitor& visitor_;
137 explicit result_wrapper1(Visitor& visitor) BOOST_NOEXCEPT
138 : visitor_(visitor)
139 {}
140
141 template <class T>
142 result_type operator()(T& val) const {
143 return visitor_(val);
144 }
145};
146
147}} // namespace detail::variant
148
149template <typename Visitor, typename Visitable>
150inline decltype(auto) apply_visitor(Visitor& visitor, Visitable& visitable,
151 typename boost::disable_if<
152 boost::detail::variant::has_result_type<Visitor>
153 >::type* = 0)
154{
155 boost::detail::variant::result_wrapper1<Visitor, Visitable> cpp14_vis(visitor);
156 return visitable.apply_visitor(cpp14_vis);
157}
158
159template <typename Visitor, typename Visitable>
160inline decltype(auto) apply_visitor(const Visitor& visitor, Visitable& visitable,
161 typename boost::disable_if<
162 boost::detail::variant::has_result_type<Visitor>
163 >::type* = 0)
164{
165 boost::detail::variant::result_wrapper1<const Visitor, Visitable> cpp14_vis(visitor);
166 return visitable.apply_visitor(cpp14_vis);
167}
168
169#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
170
171} // namespace boost
172
173#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP