]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/variant/detail/visitation_impl.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / 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>
7c673cae
FG
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
61namespace boost {
62namespace detail { namespace variant {
63
64///////////////////////////////////////////////////////////////////////////////
65// (detail) class apply_visitor_unrolled
66//
67// Tag type indicates when visitation_impl is unrolled.
68//
69struct apply_visitor_unrolled {};
70
71///////////////////////////////////////////////////////////////////////////////
72// (detail) class template visitation_impl_step
73//
74// "Never ending" iterator range facilitates visitation_impl unrolling.
75//
76
77
78template <typename Iter, typename LastIter>
79struct visitation_impl_step
80{
81 typedef typename mpl::deref<Iter>::type type;
82
83 typedef typename mpl::next<Iter>::type next_iter;
84 typedef visitation_impl_step<
85 next_iter, LastIter
86 > next;
87};
88
89template <typename LastIter>
90struct visitation_impl_step< LastIter,LastIter >
91{
92 typedef apply_visitor_unrolled type;
93 typedef visitation_impl_step next;
94};
95
96
97///////////////////////////////////////////////////////////////////////////////
98// (detail) function template visitation_impl_invoke
99//
100// Invokes the given visitor on the specified type in the given storage.
101//
102
103template <typename Visitor, typename VoidPtrCV, typename T>
92f5a8d4 104inline typename Visitor::result_type
7c673cae
FG
105visitation_impl_invoke_impl(
106 int, Visitor& visitor, VoidPtrCV storage, T*
107 , mpl::true_// never_uses_backup
108 )
109{
110 return visitor.internal_visit(
111 cast_storage<T>(storage), 1L
112 );
113}
114
115template <typename Visitor, typename VoidPtrCV, typename T>
92f5a8d4 116inline typename Visitor::result_type
7c673cae
FG
117visitation_impl_invoke_impl(
118 int internal_which, Visitor& visitor, VoidPtrCV storage, T*
119 , mpl::false_// never_uses_backup
120 )
121{
122 if (internal_which >= 0)
123 {
124 return visitor.internal_visit(
125 cast_storage<T>(storage), 1L
126 );
127 }
128 else
129 {
130 return visitor.internal_visit(
131 cast_storage< backup_holder<T> >(storage), 1L
132 );
133 }
134}
135
136template <typename Visitor, typename VoidPtrCV, typename T, typename NoBackupFlag>
92f5a8d4 137inline typename Visitor::result_type
7c673cae
FG
138visitation_impl_invoke(
139 int internal_which, Visitor& visitor, VoidPtrCV storage, T* t
140 , NoBackupFlag
141 , int
142 )
143{
144 typedef typename mpl::or_<
145 NoBackupFlag
146 , is_nothrow_move_constructible<T>
147 , has_nothrow_copy<T>
148 >::type never_uses_backup;
149
150 return (visitation_impl_invoke_impl)(
151 internal_which, visitor, storage, t
152 , never_uses_backup()
153 );
154}
155
156template <typename Visitor, typename VoidPtrCV, typename NBF>
92f5a8d4 157inline typename Visitor::result_type
7c673cae
FG
158visitation_impl_invoke(int, Visitor&, VoidPtrCV, apply_visitor_unrolled*, NBF, long)
159{
160 // should never be here at runtime!
161 typedef typename Visitor::result_type result_type;
162 return ::boost::detail::variant::forced_return< result_type >();
163}
164
165///////////////////////////////////////////////////////////////////////////////
166// (detail) function template visitation_impl
167//
168// Invokes the given visitor on the type in the given variant storage.
169//
170
171template <
172 typename W, typename S
173 , typename Visitor, typename VPCV
174 , typename NBF
175 >
92f5a8d4 176inline typename Visitor::result_type
7c673cae
FG
177visitation_impl(
178 int, int, Visitor&, VPCV
179 , mpl::true_ // is_apply_visitor_unrolled
180 , NBF, W* = 0, S* = 0
181 )
182{
183 // should never be here at runtime!
184 typedef typename Visitor::result_type result_type;
185 return ::boost::detail::variant::forced_return< result_type >();
186}
187
188template <
189 typename Which, typename step0
190 , typename Visitor, typename VoidPtrCV
191 , typename NoBackupFlag
192 >
92f5a8d4 193BOOST_FORCEINLINE typename Visitor::result_type
7c673cae
FG
194visitation_impl(
195 const int internal_which, const int logical_which
196 , Visitor& visitor, VoidPtrCV storage
197 , mpl::false_ // is_apply_visitor_unrolled
198 , NoBackupFlag no_backup_flag
199 , Which* = 0, step0* = 0
200 )
201{
202 // Typedef apply_visitor_unrolled steps and associated types...
203# define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF(z, N, _) \
204 typedef typename BOOST_PP_CAT(step,N)::type BOOST_PP_CAT(T,N); \
205 typedef typename BOOST_PP_CAT(step,N)::next \
206 BOOST_PP_CAT(step, BOOST_PP_INC(N)); \
207 /**/
208
209 BOOST_PP_REPEAT(
210 BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
211 , BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF
212 , _
213 )
214
215# undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF
216
217 // ...switch on the target which-index value...
218 switch (logical_which)
219 {
220
221 // ...applying the appropriate case:
222# define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE(z, N, _) \
223 case (Which::value + (N)): \
224 return (visitation_impl_invoke)( \
225 internal_which, visitor, storage \
226 , static_cast<BOOST_PP_CAT(T,N)*>(0) \
227 , no_backup_flag, 1L \
228 ); \
229 /**/
230
231 BOOST_PP_REPEAT(
232 BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
233 , BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
234 , _
235 )
236
237# undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
238
239 default: break;
240 }
241
242 // If not handled in this iteration, continue unrolling:
243 typedef mpl::int_<
244 Which::value + (BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
245 > next_which;
246
247 typedef BOOST_PP_CAT(step, BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
248 next_step;
249
250 typedef typename next_step::type next_type;
251 typedef typename is_same< next_type,apply_visitor_unrolled >::type
252 is_apply_visitor_unrolled;
253
254 return detail::variant::visitation_impl(
255 internal_which, logical_which
256 , visitor, storage
257 , is_apply_visitor_unrolled()
258 , no_backup_flag
259 , static_cast<next_which*>(0), static_cast<next_step*>(0)
260 );
261}
262
263}} // namespace detail::variant
264} // namespace boost
265
266#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
267# pragma warning(pop)
268#endif
269
270#endif // BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP