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