Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/intrusive/pack_options.hpp @ 102:f46d142149f5
Whoops, finish that update
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:13:41 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
101:c530137014c0 | 102:f46d142149f5 |
---|---|
1 ///////////////////////////////////////////////////////////////////////////// | |
2 // | |
3 // (C) Copyright Ion Gaztanaga 2013-2013 | |
4 // | |
5 // Distributed under the Boost Software License, Version 1.0. | |
6 // (See accompanying file LICENSE_1_0.txt or copy at | |
7 // http://www.boost.org/LICENSE_1_0.txt) | |
8 // | |
9 // See http://www.boost.org/libs/intrusive for documentation. | |
10 // | |
11 ///////////////////////////////////////////////////////////////////////////// | |
12 | |
13 #ifndef BOOST_INTRUSIVE_PACK_OPTIONS_HPP | |
14 #define BOOST_INTRUSIVE_PACK_OPTIONS_HPP | |
15 | |
16 #include <boost/intrusive/detail/config_begin.hpp> | |
17 | |
18 #if defined(BOOST_HAS_PRAGMA_ONCE) | |
19 # pragma once | |
20 #endif | |
21 | |
22 namespace boost { | |
23 namespace intrusive { | |
24 | |
25 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED | |
26 | |
27 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) | |
28 | |
29 template<class Prev, class Next> | |
30 struct do_pack | |
31 { | |
32 //Use "pack" member template to pack options | |
33 typedef typename Next::template pack<Prev> type; | |
34 }; | |
35 | |
36 template<class Prev> | |
37 struct do_pack<Prev, void> | |
38 { | |
39 //Avoid packing "void" to shorten template names | |
40 typedef Prev type; | |
41 }; | |
42 | |
43 template | |
44 < class DefaultOptions | |
45 , class O1 = void | |
46 , class O2 = void | |
47 , class O3 = void | |
48 , class O4 = void | |
49 , class O5 = void | |
50 , class O6 = void | |
51 , class O7 = void | |
52 , class O8 = void | |
53 , class O9 = void | |
54 , class O10 = void | |
55 , class O11 = void | |
56 > | |
57 struct pack_options | |
58 { | |
59 // join options | |
60 typedef | |
61 typename do_pack | |
62 < typename do_pack | |
63 < typename do_pack | |
64 < typename do_pack | |
65 < typename do_pack | |
66 < typename do_pack | |
67 < typename do_pack | |
68 < typename do_pack | |
69 < typename do_pack | |
70 < typename do_pack | |
71 < typename do_pack | |
72 < DefaultOptions | |
73 , O1 | |
74 >::type | |
75 , O2 | |
76 >::type | |
77 , O3 | |
78 >::type | |
79 , O4 | |
80 >::type | |
81 , O5 | |
82 >::type | |
83 , O6 | |
84 >::type | |
85 , O7 | |
86 >::type | |
87 , O8 | |
88 >::type | |
89 , O9 | |
90 >::type | |
91 , O10 | |
92 >::type | |
93 , O11 | |
94 >::type | |
95 type; | |
96 }; | |
97 #else | |
98 | |
99 //index_tuple | |
100 template<int... Indexes> | |
101 struct index_tuple{}; | |
102 | |
103 //build_number_seq | |
104 template<std::size_t Num, typename Tuple = index_tuple<> > | |
105 struct build_number_seq; | |
106 | |
107 template<std::size_t Num, int... Indexes> | |
108 struct build_number_seq<Num, index_tuple<Indexes...> > | |
109 : build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> > | |
110 {}; | |
111 | |
112 template<int... Indexes> | |
113 struct build_number_seq<0, index_tuple<Indexes...> > | |
114 { typedef index_tuple<Indexes...> type; }; | |
115 | |
116 template<class ...Types> | |
117 struct typelist | |
118 {}; | |
119 | |
120 //invert_typelist | |
121 template<class T> | |
122 struct invert_typelist; | |
123 | |
124 template<int I, typename Tuple> | |
125 struct typelist_element; | |
126 | |
127 template<int I, typename Head, typename... Tail> | |
128 struct typelist_element<I, typelist<Head, Tail...> > | |
129 { | |
130 typedef typename typelist_element<I-1, typelist<Tail...> >::type type; | |
131 }; | |
132 | |
133 template<typename Head, typename... Tail> | |
134 struct typelist_element<0, typelist<Head, Tail...> > | |
135 { | |
136 typedef Head type; | |
137 }; | |
138 | |
139 template<int ...Ints, class ...Types> | |
140 typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...> | |
141 inverted_typelist(index_tuple<Ints...>, typelist<Types...>) | |
142 { | |
143 return typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>(); | |
144 } | |
145 | |
146 //sizeof_typelist | |
147 template<class Typelist> | |
148 struct sizeof_typelist; | |
149 | |
150 template<class ...Types> | |
151 struct sizeof_typelist< typelist<Types...> > | |
152 { | |
153 static const std::size_t value = sizeof...(Types); | |
154 }; | |
155 | |
156 //invert_typelist_impl | |
157 template<class Typelist, class Indexes> | |
158 struct invert_typelist_impl; | |
159 | |
160 | |
161 template<class Typelist, int ...Ints> | |
162 struct invert_typelist_impl< Typelist, index_tuple<Ints...> > | |
163 { | |
164 static const std::size_t last_idx = sizeof_typelist<Typelist>::value - 1; | |
165 typedef typelist | |
166 <typename typelist_element<last_idx - Ints, Typelist>::type...> type; | |
167 }; | |
168 | |
169 template<class Typelist, int Int> | |
170 struct invert_typelist_impl< Typelist, index_tuple<Int> > | |
171 { | |
172 typedef Typelist type; | |
173 }; | |
174 | |
175 template<class Typelist> | |
176 struct invert_typelist_impl< Typelist, index_tuple<> > | |
177 { | |
178 typedef Typelist type; | |
179 }; | |
180 | |
181 //invert_typelist | |
182 template<class Typelist> | |
183 struct invert_typelist; | |
184 | |
185 template<class ...Types> | |
186 struct invert_typelist< typelist<Types...> > | |
187 { | |
188 typedef typelist<Types...> typelist_t; | |
189 typedef typename build_number_seq<sizeof...(Types)>::type indexes_t; | |
190 typedef typename invert_typelist_impl<typelist_t, indexes_t>::type type; | |
191 }; | |
192 | |
193 //Do pack | |
194 template<class Typelist> | |
195 struct do_pack; | |
196 | |
197 template<> | |
198 struct do_pack<typelist<> >; | |
199 | |
200 template<class Prev> | |
201 struct do_pack<typelist<Prev> > | |
202 { | |
203 typedef Prev type; | |
204 }; | |
205 | |
206 template<class Prev, class Last> | |
207 struct do_pack<typelist<Prev, Last> > | |
208 { | |
209 typedef typename Prev::template pack<Last> type; | |
210 }; | |
211 | |
212 template<class Prev, class ...Others> | |
213 struct do_pack<typelist<Prev, Others...> > | |
214 { | |
215 typedef typename Prev::template pack | |
216 <typename do_pack<typelist<Others...> >::type> type; | |
217 }; | |
218 | |
219 | |
220 template<class DefaultOptions, class ...Options> | |
221 struct pack_options | |
222 { | |
223 typedef typelist<DefaultOptions, Options...> typelist_t; | |
224 typedef typename invert_typelist<typelist_t>::type inverted_typelist; | |
225 typedef typename do_pack<inverted_typelist>::type type; | |
226 }; | |
227 | |
228 #endif //!defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) | |
229 | |
230 #define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) \ | |
231 template< class TYPE> \ | |
232 struct OPTION_NAME \ | |
233 { \ | |
234 template<class Base> \ | |
235 struct pack : Base \ | |
236 { \ | |
237 typedef TYPEDEF_EXPR TYPEDEF_NAME; \ | |
238 }; \ | |
239 }; \ | |
240 // | |
241 | |
242 #define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) \ | |
243 template< TYPE VALUE> \ | |
244 struct OPTION_NAME \ | |
245 { \ | |
246 template<class Base> \ | |
247 struct pack : Base \ | |
248 { \ | |
249 static const TYPE CONSTANT_NAME = VALUE; \ | |
250 }; \ | |
251 }; \ | |
252 // | |
253 | |
254 #else //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED | |
255 | |
256 //! This class is a utility that takes: | |
257 //! - a default options class defining initial static constant | |
258 //! and typedefs | |
259 //! - several options defined with BOOST_INTRUSIVE_OPTION_CONSTANT and | |
260 //! BOOST_INTRUSIVE_OPTION_TYPE | |
261 //! | |
262 //! and packs them together in a new type that defines all options as | |
263 //! member typedefs or static constant values. Given options of form: | |
264 //! | |
265 //! \code | |
266 //! BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, VoidPointer, my_pointer_type) | |
267 //! BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental) | |
268 //! \endcode | |
269 //! | |
270 //! the following expression | |
271 //! | |
272 //! \code | |
273 //! | |
274 //! struct default_options | |
275 //! { | |
276 //! typedef long int_type; | |
277 //! static const int int_constant = -1; | |
278 //! }; | |
279 //! | |
280 //! pack_options< default_options, my_pointer<void*>, incremental<true> >::type | |
281 //! \endcode | |
282 //! | |
283 //! will create a type that will contain the following typedefs/constants | |
284 //! | |
285 //! \code | |
286 //! struct unspecified_type | |
287 //! { | |
288 //! //Default options | |
289 //! typedef long int_type; | |
290 //! static const int int_constant = -1; | |
291 //! | |
292 //! //Packed options (will ovewrite any default option) | |
293 //! typedef void* my_pointer_type; | |
294 //! static const bool is_incremental = true; | |
295 //! }; | |
296 //! \endcode | |
297 //! | |
298 //! If an option is specified in the default options argument and later | |
299 //! redefined as an option, the last definition will prevail. | |
300 template<class DefaultOptions, class ...Options> | |
301 struct pack_options | |
302 { | |
303 typedef unspecified_type type; | |
304 }; | |
305 | |
306 //! Defines an option class of name OPTION_NAME that can be used to specify a type | |
307 //! of type TYPE... | |
308 //! | |
309 //! \code | |
310 //! struct OPTION_NAME<class TYPE> | |
311 //! { unspecified_content }; | |
312 //! \endcode | |
313 //! | |
314 //! ...that after being combined with | |
315 //! <code>boost::intrusive::pack_options</code>, | |
316 //! will typedef TYPE as a typedef of name TYPEDEF_NAME. Example: | |
317 //! | |
318 //! \code | |
319 //! //[includes and namespaces omitted for brevity] | |
320 //! | |
321 //! //This macro will create the following class: | |
322 //! // template<class VoidPointer> | |
323 //! // struct my_pointer | |
324 //! // { unspecified_content }; | |
325 //! BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, boost::remove_pointer<VoidPointer>::type, my_pointer_type) | |
326 //! | |
327 //! struct empty_default{}; | |
328 //! | |
329 //! typedef pack_options< empty_default, typename my_pointer<void*> >::type::my_pointer_type type; | |
330 //! | |
331 //! BOOST_STATIC_ASSERT(( boost::is_same<type, void>::value )); | |
332 //! | |
333 //! \endcode | |
334 #define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) | |
335 | |
336 //! Defines an option class of name OPTION_NAME that can be used to specify a constant | |
337 //! of type TYPE with value VALUE... | |
338 //! | |
339 //! \code | |
340 //! struct OPTION_NAME<TYPE VALUE> | |
341 //! { unspecified_content }; | |
342 //! \endcode | |
343 //! | |
344 //! ...that after being combined with | |
345 //! <code>boost::intrusive::pack_options</code>, | |
346 //! will contain a CONSTANT_NAME static constant of value VALUE. Example: | |
347 //! | |
348 //! \code | |
349 //! //[includes and namespaces omitted for brevity] | |
350 //! | |
351 //! //This macro will create the following class: | |
352 //! // template<bool Enabled> | |
353 //! // struct incremental | |
354 //! // { unspecified_content }; | |
355 //! BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental) | |
356 //! | |
357 //! struct empty_default{}; | |
358 //! | |
359 //! const bool is_incremental = pack_options< empty_default, incremental<true> >::type::is_incremental; | |
360 //! | |
361 //! BOOST_STATIC_ASSERT(( is_incremental == true )); | |
362 //! | |
363 //! \endcode | |
364 #define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) | |
365 | |
366 #endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED | |
367 | |
368 | |
369 } //namespace intrusive { | |
370 } //namespace boost { | |
371 | |
372 #include <boost/intrusive/detail/config_end.hpp> | |
373 | |
374 #endif //#ifndef BOOST_INTRUSIVE_PACK_OPTIONS_HPP |