]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/variant/detail/visitation_impl.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / variant / detail / visitation_impl.hpp
1 //-----------------------------------------------------------------------------
2 // boost variant/detail/visitation_impl.hpp header file
3 // See http://www.boost.org for updates, documentation, and revision history.
4 //-----------------------------------------------------------------------------
5 //
6 // Copyright (c) 2003
7 // Eric Friedman
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_VISITATION_IMPL_HPP
14 #define BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP
15
16 #include <boost/config.hpp>
17
18 #include <boost/variant/detail/backup_holder.hpp>
19 #include <boost/variant/detail/cast_storage.hpp>
20 #include <boost/variant/detail/forced_return.hpp>
21 #include <boost/variant/variant_fwd.hpp> // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
22
23 #include <boost/mpl/eval_if.hpp>
24 #include <boost/mpl/bool.hpp>
25 #include <boost/mpl/identity.hpp>
26 #include <boost/mpl/int.hpp>
27 #include <boost/mpl/next.hpp>
28 #include <boost/mpl/deref.hpp>
29 #include <boost/mpl/or.hpp>
30 #include <boost/preprocessor/cat.hpp>
31 #include <boost/preprocessor/inc.hpp>
32 #include <boost/preprocessor/repeat.hpp>
33 #include <boost/type_traits/is_same.hpp>
34 #include <boost/type_traits/has_nothrow_copy.hpp>
35 #include <boost/type_traits/is_nothrow_move_constructible.hpp>
36
37 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
38 # pragma warning (push)
39 # pragma warning (disable : 4702) //unreachable code
40 #endif
41
42 ///////////////////////////////////////////////////////////////////////////////
43 // BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
44 //
45 // Unrolls variant's visitation mechanism to reduce template instantiation
46 // and potentially increase runtime performance. (TODO: Investigate further.)
47 //
48 #if !defined(BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
49
50 #ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
51 # include <boost/mpl/limits/list.hpp>
52 # define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT \
53 BOOST_MPL_LIMIT_LIST_SIZE
54 #else
55 # define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT \
56 BOOST_VARIANT_LIMIT_TYPES
57 #endif
58
59 #endif
60
61 // Define a compiler generic null pointer value
62 #if defined(BOOST_NO_CXX11_NULLPTR)
63 #define BOOST_VARIANT_NULL 0
64 #else
65 #define BOOST_VARIANT_NULL nullptr
66 #endif
67
68 namespace boost {
69 namespace detail { namespace variant {
70
71 ///////////////////////////////////////////////////////////////////////////////
72 // (detail) class apply_visitor_unrolled
73 //
74 // Tag type indicates when visitation_impl is unrolled.
75 //
76 struct apply_visitor_unrolled {};
77
78 ///////////////////////////////////////////////////////////////////////////////
79 // (detail) class template visitation_impl_step
80 //
81 // "Never ending" iterator range facilitates visitation_impl unrolling.
82 //
83
84
85 template <typename Iter, typename LastIter>
86 struct visitation_impl_step
87 {
88 typedef typename mpl::deref<Iter>::type type;
89
90 typedef typename mpl::next<Iter>::type next_iter;
91 typedef visitation_impl_step<
92 next_iter, LastIter
93 > next;
94 };
95
96 template <typename LastIter>
97 struct visitation_impl_step< LastIter,LastIter >
98 {
99 typedef apply_visitor_unrolled type;
100 typedef visitation_impl_step next;
101 };
102
103
104 ///////////////////////////////////////////////////////////////////////////////
105 // (detail) function template visitation_impl_invoke
106 //
107 // Invokes the given visitor on the specified type in the given storage.
108 //
109
110 template <typename Visitor, typename VoidPtrCV, typename T>
111 inline typename Visitor::result_type
112 visitation_impl_invoke_impl(
113 int, Visitor& visitor, VoidPtrCV storage, T*
114 , mpl::true_// never_uses_backup
115 )
116 {
117 return visitor.internal_visit(
118 cast_storage<T>(storage), 1L
119 );
120 }
121
122 template <typename Visitor, typename VoidPtrCV, typename T>
123 inline typename Visitor::result_type
124 visitation_impl_invoke_impl(
125 int internal_which, Visitor& visitor, VoidPtrCV storage, T*
126 , mpl::false_// never_uses_backup
127 )
128 {
129 if (internal_which >= 0)
130 {
131 return visitor.internal_visit(
132 cast_storage<T>(storage), 1L
133 );
134 }
135 else
136 {
137 return visitor.internal_visit(
138 cast_storage< backup_holder<T> >(storage), 1L
139 );
140 }
141 }
142
143 template <typename Visitor, typename VoidPtrCV, typename T, typename NoBackupFlag>
144 inline typename Visitor::result_type
145 visitation_impl_invoke(
146 int internal_which, Visitor& visitor, VoidPtrCV storage, T* t
147 , NoBackupFlag
148 , int
149 )
150 {
151 typedef typename mpl::or_<
152 NoBackupFlag
153 , is_nothrow_move_constructible<T>
154 , has_nothrow_copy<T>
155 >::type never_uses_backup;
156
157 return (visitation_impl_invoke_impl)(
158 internal_which, visitor, storage, t
159 , never_uses_backup()
160 );
161 }
162
163 template <typename Visitor, typename VoidPtrCV, typename NBF>
164 inline typename Visitor::result_type
165 visitation_impl_invoke(int, Visitor&, VoidPtrCV, apply_visitor_unrolled*, NBF, long)
166 {
167 // should never be here at runtime!
168 typedef typename Visitor::result_type result_type;
169 return ::boost::detail::variant::forced_return< result_type >();
170 }
171
172 ///////////////////////////////////////////////////////////////////////////////
173 // (detail) function template visitation_impl
174 //
175 // Invokes the given visitor on the type in the given variant storage.
176 //
177
178 template <
179 typename W, typename S
180 , typename Visitor, typename VPCV
181 , typename NBF
182 >
183 inline typename Visitor::result_type
184 visitation_impl(
185 int, int, Visitor&, VPCV
186 , mpl::true_ // is_apply_visitor_unrolled
187 , NBF, W* = BOOST_VARIANT_NULL, S* = BOOST_VARIANT_NULL
188 )
189 {
190 // should never be here at runtime!
191 typedef typename Visitor::result_type result_type;
192 return ::boost::detail::variant::forced_return< result_type >();
193 }
194
195 template <
196 typename Which, typename step0
197 , typename Visitor, typename VoidPtrCV
198 , typename NoBackupFlag
199 >
200 BOOST_FORCEINLINE typename Visitor::result_type
201 visitation_impl(
202 const int internal_which, const int logical_which
203 , Visitor& visitor, VoidPtrCV storage
204 , mpl::false_ // is_apply_visitor_unrolled
205 , NoBackupFlag no_backup_flag
206 , Which* = BOOST_VARIANT_NULL, step0* = BOOST_VARIANT_NULL
207 )
208 {
209 // Typedef apply_visitor_unrolled steps and associated types...
210 # define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF(z, N, _) \
211 typedef typename BOOST_PP_CAT(step,N)::type BOOST_PP_CAT(T,N); \
212 typedef typename BOOST_PP_CAT(step,N)::next \
213 BOOST_PP_CAT(step, BOOST_PP_INC(N)); \
214 /**/
215
216 BOOST_PP_REPEAT(
217 BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
218 , BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF
219 , _
220 )
221
222 # undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF
223
224 // ...switch on the target which-index value...
225 switch (logical_which)
226 {
227
228 // ...applying the appropriate case:
229 # define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE(z, N, _) \
230 case (Which::value + (N)): \
231 return (visitation_impl_invoke)( \
232 internal_which, visitor, storage \
233 , static_cast<BOOST_PP_CAT(T,N)*>(0) \
234 , no_backup_flag, 1L \
235 ); \
236 /**/
237
238 BOOST_PP_REPEAT(
239 BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
240 , BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
241 , _
242 )
243
244 # undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
245
246 default: break;
247 }
248
249 // If not handled in this iteration, continue unrolling:
250 typedef mpl::int_<
251 Which::value + (BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
252 > next_which;
253
254 typedef BOOST_PP_CAT(step, BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
255 next_step;
256
257 typedef typename next_step::type next_type;
258 typedef typename is_same< next_type,apply_visitor_unrolled >::type
259 is_apply_visitor_unrolled;
260
261 return detail::variant::visitation_impl(
262 internal_which, logical_which
263 , visitor, storage
264 , is_apply_visitor_unrolled()
265 , no_backup_flag
266 , static_cast<next_which*>(0), static_cast<next_step*>(0)
267 );
268 }
269
270 }} // namespace detail::variant
271 } // namespace boost
272
273 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
274 # pragma warning(pop)
275 #endif
276
277 #endif // BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP