3 #ifndef CDSLIB_OPT_MAKE_OPTIONS_VAR_H
4 #define CDSLIB_OPT_MAKE_OPTIONS_VAR_H
6 #ifndef CDSLIB_OPT_OPTIONS_H
7 # error <cds/opt/options.h> must be included instead of <cds/opt/make_options_var.h>
10 namespace cds { namespace opt {
14 template <typename OptionList, typename Option>
17 // Use "pack" member template to pack options
18 typedef typename Option::template pack<OptionList> type;
21 template <typename ...T> class typelist;
23 template <typename Typelist> struct typelist_head;
24 template <typename Head, typename ...Tail>
25 struct typelist_head< typelist<Head, Tail...> > {
28 template <typename Head>
29 struct typelist_head< typelist<Head> > {
33 template <typename Typelist> struct typelist_tail;
34 template <typename Head, typename ...Tail>
35 struct typelist_tail< typelist<Head, Tail...> > {
36 typedef typelist<Tail...> type;
38 template <typename Head>
39 struct typelist_tail< typelist<Head> > {
40 typedef typelist<> type;
43 template <typename OptionList, typename Typelist>
44 struct make_options_impl {
45 typedef typename make_options_impl<
48 typename typelist_head< Typelist >::type
50 typename typelist_tail<Typelist>::type
54 template <typename OptionList>
55 struct make_options_impl<OptionList, typelist<> > {
56 typedef OptionList type;
58 } // namespace details
61 /// make_options metafunction
62 /** @headerfile cds/opt/options.h
64 The metafunction converts option list \p Options to traits structure.
65 The result of metafunction is \p type.
67 Template parameter \p OptionList is default option set (default traits).
68 \p Options is option list.
70 template <typename OptionList, typename... Options>
72 #ifdef CDS_DOXYGEN_INVOKED
73 typedef implementation_defined type ; ///< Result of the metafunction
75 typedef typename details::make_options_impl< OptionList, details::typelist<Options...> >::type type;
80 // *****************************************************************
81 // find_type_traits metafunction
82 // *****************************************************************
86 template <typename... Options>
87 struct find_type_traits_option;
90 struct find_type_traits_option<> {
91 typedef cds::opt::none type;
94 template <typename Any>
95 struct find_type_traits_option< Any > {
96 typedef cds::opt::none type;
99 template <typename Any>
100 struct find_type_traits_option< cds::opt::type_traits< Any > > {
104 template <typename Any, typename... Options>
105 struct find_type_traits_option< cds::opt::type_traits< Any >, Options... > {
109 template <typename Any, typename... Options>
110 struct find_type_traits_option< Any, Options... > {
111 typedef typename find_type_traits_option< Options... >::type type;
113 } // namespace details
116 /// Metafunction to find opt::type_traits option in \p Options list
117 /** @headerfile cds/opt/options.h
119 If \p Options contains opt::type_traits option then it is the metafunction result.
120 Otherwise the result is \p DefaultOptons.
122 template <typename DefaultOptions, typename... Options>
123 struct find_type_traits {
124 typedef typename select_default< typename details::find_type_traits_option<Options...>::type, DefaultOptions>::type type ; ///< Metafunction result
128 // *****************************************************************
129 // find_option metafunction
130 // *****************************************************************
134 template <typename What, typename... Options>
140 template <typename A, typename B>
141 struct compare_option
143 typedef compare_fail type;
146 template <template <typename> class Opt, typename A, typename B>
147 struct compare_option< Opt<A>, Opt<B> >
149 typedef compare_ok type;
152 // Specializations for integral type of option
153 #define CDS_FIND_OPTION_INTEGRAL_SPECIALIZATION_( _type ) template <template <_type> class What, _type A, _type B> \
154 struct compare_option< What<A>, What<B> > { typedef compare_ok type ; };
156 // For user-defined enum types
157 #define CDS_DECLARE_FIND_OPTION_INTEGRAL_SPECIALIZATION( _type ) namespace cds { namespace opt { namespace details { CDS_FIND_OPTION_INTEGRAL_SPECIALIZATION_(_type ) }}}
159 CDS_FIND_OPTION_INTEGRAL_SPECIALIZATION_(bool)
160 CDS_FIND_OPTION_INTEGRAL_SPECIALIZATION_(char)
161 CDS_FIND_OPTION_INTEGRAL_SPECIALIZATION_(unsigned char)
162 CDS_FIND_OPTION_INTEGRAL_SPECIALIZATION_(signed char)
163 CDS_FIND_OPTION_INTEGRAL_SPECIALIZATION_(short int)
164 CDS_FIND_OPTION_INTEGRAL_SPECIALIZATION_(unsigned short int)
165 CDS_FIND_OPTION_INTEGRAL_SPECIALIZATION_(int)
166 CDS_FIND_OPTION_INTEGRAL_SPECIALIZATION_(unsigned int)
167 CDS_FIND_OPTION_INTEGRAL_SPECIALIZATION_(long)
168 CDS_FIND_OPTION_INTEGRAL_SPECIALIZATION_(unsigned long)
169 CDS_FIND_OPTION_INTEGRAL_SPECIALIZATION_(long long)
170 CDS_FIND_OPTION_INTEGRAL_SPECIALIZATION_(unsigned long long)
173 template <typename CompResult, typename Ok, typename Fail>
179 template <typename Ok, typename Fail>
180 struct select_option< compare_ok, Ok, Fail >
185 template <typename What>
186 struct find_option< What > {
190 template <typename What, typename Opt>
191 struct find_option< What, Opt > {
192 typedef typename select_option<
193 typename compare_option< What, Opt >::type
199 template <typename What, typename Opt, typename... Options>
200 struct find_option< What, Opt, Options... > {
201 typedef typename select_option<
202 typename compare_option< What, Opt >::type
204 ,typename find_option< What, Options... >::type
207 } // namespace details
210 /// Metafunction to find \p What option in \p Options list
211 /** @headerfile cds/opt/options.h
213 If \p Options contains \p What< Val > option for any \p Val then the result is \p What< Val >
214 Otherwise the result is \p What.
218 #include <cds/opt/options.h>
219 namespace co = cds::opt;
225 // Find option co::tag.
227 // res1 is co::tag< tag_a >
228 typedef co::find_option< co::tag< default_tag >, co::gc< cds::gc::HP >, co::tag< tag_a > >::type res1;
230 // res2 is default co::tag< default_tag >
231 typedef co::find_option< co::tag< default_tag >, co::less< x >, co::hash< H > >::type res2;
233 // Multiple option co::tag. The first option is selected
234 // res3 is default co::tag< tag_a >
235 typedef co::find_option< co::tag< default_tag >, co::tag< tag_a >, co::tag< tag_b > >::type res3;
239 template <typename What, typename... Options>
241 typedef typename details::find_option<What, Options...>::type type ; ///< Metafunction result
245 // *****************************************************************
246 // select metafunction
247 // *****************************************************************
252 template <typename What, typename... Pairs>
255 template <typename What, typename Value>
256 struct select< What, What, Value>
261 template <typename What, typename Tag, typename Value>
262 struct select<What, Tag, Value>
267 template <typename What, typename Value, typename... Pairs>
268 struct select< What, What, Value, Pairs...>
273 template <typename What, typename Tag, typename Value, typename... Pairs>
274 struct select< What, Tag, Value, Pairs...>
276 typedef typename select<What, Pairs...>::type type;
278 } // namespace details
281 /// Select option metafunction
282 /** @headerfile cds/opt/options.h
286 select <What, T1, R1, T2, R2, ... Tn, Rn> ::=
287 if What == T1 then return R1
288 if What == T2 then return R2
290 if What == Tn then return Rn
294 template <typename What, typename... Pairs>
296 typedef typename details::select< What, Pairs...>::type type ; ///< Metafunction result
299 }} // namespace cds::opt
301 #endif // #ifndef CDSLIB_OPT_MAKE_OPTIONS_STD_H