]> git.lyx.org Git - lyx.git/blob - 3rdparty/boost/boost/variant/detail/visitation_impl.hpp
Update to boost 1.72
[lyx.git] / 3rdparty / 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 namespace boost {
62 namespace detail { namespace variant {
63
64 ///////////////////////////////////////////////////////////////////////////////
65 // (detail) class apply_visitor_unrolled
66 //
67 // Tag type indicates when visitation_impl is unrolled.
68 //
69 struct 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
78 template <typename Iter, typename LastIter>
79 struct 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
89 template <typename LastIter>
90 struct 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
103 template <typename Visitor, typename VoidPtrCV, typename T>
104 inline typename Visitor::result_type
105 visitation_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
115 template <typename Visitor, typename VoidPtrCV, typename T>
116 inline typename Visitor::result_type
117 visitation_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
136 template <typename Visitor, typename VoidPtrCV, typename T, typename NoBackupFlag>
137 inline typename Visitor::result_type
138 visitation_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
156 template <typename Visitor, typename VoidPtrCV, typename NBF>
157 inline typename Visitor::result_type
158 visitation_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
171 template <
172       typename W, typename S
173     , typename Visitor, typename VPCV
174     , typename NBF
175     >
176 inline typename Visitor::result_type
177 visitation_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
188 template <
189       typename Which, typename step0
190     , typename Visitor, typename VoidPtrCV
191     , typename NoBackupFlag
192     >
193 BOOST_FORCEINLINE typename Visitor::result_type
194 visitation_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