]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/variant/include/boost/variant/detail/visitation_impl.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / variant / include / boost / variant / detail / visitation_impl.hpp
CommitLineData
7c673cae
FG
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/detail/generic_result_type.hpp>
22#include <boost/variant/variant_fwd.hpp> // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
23
24#include <boost/mpl/eval_if.hpp>
25#include <boost/mpl/bool.hpp>
26#include <boost/mpl/identity.hpp>
27#include <boost/mpl/int.hpp>
28#include <boost/mpl/next.hpp>
29#include <boost/mpl/deref.hpp>
30#include <boost/mpl/or.hpp>
31#include <boost/preprocessor/cat.hpp>
32#include <boost/preprocessor/inc.hpp>
33#include <boost/preprocessor/repeat.hpp>
34#include <boost/type_traits/is_same.hpp>
35#include <boost/type_traits/has_nothrow_copy.hpp>
36#include <boost/type_traits/is_nothrow_move_constructible.hpp>
37
38#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
39# pragma warning (push)
40# pragma warning (disable : 4702) //unreachable code
41#endif
42
43///////////////////////////////////////////////////////////////////////////////
44// BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
45//
46// Unrolls variant's visitation mechanism to reduce template instantiation
47// and potentially increase runtime performance. (TODO: Investigate further.)
48//
49#if !defined(BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
50
51#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
52# include <boost/mpl/limits/list.hpp>
53# define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT \
54 BOOST_MPL_LIMIT_LIST_SIZE
55#else
56# define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT \
57 BOOST_VARIANT_LIMIT_TYPES
58#endif
59
60#endif
61
62namespace boost {
63namespace detail { namespace variant {
64
65///////////////////////////////////////////////////////////////////////////////
66// (detail) class apply_visitor_unrolled
67//
68// Tag type indicates when visitation_impl is unrolled.
69//
70struct apply_visitor_unrolled {};
71
72///////////////////////////////////////////////////////////////////////////////
73// (detail) class template visitation_impl_step
74//
75// "Never ending" iterator range facilitates visitation_impl unrolling.
76//
77
78
79template <typename Iter, typename LastIter>
80struct visitation_impl_step
81{
82 typedef typename mpl::deref<Iter>::type type;
83
84 typedef typename mpl::next<Iter>::type next_iter;
85 typedef visitation_impl_step<
86 next_iter, LastIter
87 > next;
88};
89
90template <typename LastIter>
91struct visitation_impl_step< LastIter,LastIter >
92{
93 typedef apply_visitor_unrolled type;
94 typedef visitation_impl_step next;
95};
96
97
98///////////////////////////////////////////////////////////////////////////////
99// (detail) function template visitation_impl_invoke
100//
101// Invokes the given visitor on the specified type in the given storage.
102//
103
104template <typename Visitor, typename VoidPtrCV, typename T>
105inline
106 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
107visitation_impl_invoke_impl(
108 int, Visitor& visitor, VoidPtrCV storage, T*
109 , mpl::true_// never_uses_backup
110 )
111{
112 return visitor.internal_visit(
113 cast_storage<T>(storage), 1L
114 );
115}
116
117template <typename Visitor, typename VoidPtrCV, typename T>
118inline
119 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
120visitation_impl_invoke_impl(
121 int internal_which, Visitor& visitor, VoidPtrCV storage, T*
122 , mpl::false_// never_uses_backup
123 )
124{
125 if (internal_which >= 0)
126 {
127 return visitor.internal_visit(
128 cast_storage<T>(storage), 1L
129 );
130 }
131 else
132 {
133 return visitor.internal_visit(
134 cast_storage< backup_holder<T> >(storage), 1L
135 );
136 }
137}
138
139template <typename Visitor, typename VoidPtrCV, typename T, typename NoBackupFlag>
140inline
141 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
142visitation_impl_invoke(
143 int internal_which, Visitor& visitor, VoidPtrCV storage, T* t
144 , NoBackupFlag
145 , int
146 )
147{
148 typedef typename mpl::or_<
149 NoBackupFlag
150 , is_nothrow_move_constructible<T>
151 , has_nothrow_copy<T>
152 >::type never_uses_backup;
153
154 return (visitation_impl_invoke_impl)(
155 internal_which, visitor, storage, t
156 , never_uses_backup()
157 );
158}
159
160template <typename Visitor, typename VoidPtrCV, typename NBF>
161inline
162 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
163visitation_impl_invoke(int, Visitor&, VoidPtrCV, apply_visitor_unrolled*, NBF, long)
164{
165 // should never be here at runtime!
166 typedef typename Visitor::result_type result_type;
167 return ::boost::detail::variant::forced_return< result_type >();
168}
169
170///////////////////////////////////////////////////////////////////////////////
171// (detail) function template visitation_impl
172//
173// Invokes the given visitor on the type in the given variant storage.
174//
175
176template <
177 typename W, typename S
178 , typename Visitor, typename VPCV
179 , typename NBF
180 >
181inline
182 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
183visitation_impl(
184 int, int, Visitor&, VPCV
185 , mpl::true_ // is_apply_visitor_unrolled
186 , NBF, W* = 0, S* = 0
187 )
188{
189 // should never be here at runtime!
190 typedef typename Visitor::result_type result_type;
191 return ::boost::detail::variant::forced_return< result_type >();
192}
193
194template <
195 typename Which, typename step0
196 , typename Visitor, typename VoidPtrCV
197 , typename NoBackupFlag
198 >
199inline
200 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
201visitation_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* = 0, step0* = 0
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