Remove cds/details/std/type_traits.h, use STL <type_traits> instead
[libcds.git] / tests / test-hdr / misc / find_option.cpp
1 //$$CDS-header$$
2
3 #include <type_traits>
4 #include <cds/opt/options.h>
5
6 // Value options
7 namespace {
8
9     template <int Val>
10     struct int_opt {
11         static const int value = Val;
12     };
13
14     template <bool Val>
15     struct bool_opt {
16         static const bool value = Val;
17     };
18
19     enum user_enum {
20         val_zero, val_one, val_two, val_three, val_four, val_five
21     };
22
23     template <user_enum Val>
24     struct enum_opt {
25         static const user_enum value = Val;
26     };
27 }
28
29 // Declare necessary cds::opt::find_option specialization for user-provided enum type
30 CDS_DECLARE_FIND_OPTION_INTEGRAL_SPECIALIZATION( user_enum )
31
32 #if CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION < 40500
33 // GCC 4.4 does not support local struct declarations
34 namespace {
35     struct tag_default;
36     struct tag_a;
37     struct tag_b;
38 }
39 #endif
40
41 void find_option_compiler_test()
42 {
43
44     // *************************************************
45     // Type options
46     //
47 #if !(CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION < 40500)
48     // GCC 4.4 does not support local struct declarations
49     struct tag_default;
50     struct tag_a;
51     struct tag_b;
52 #endif
53
54     // Option not found
55     static_assert( (std::is_same<
56         cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::stat<tag_a>, bool_opt<false> >::type,
57         cds::opt::tag<tag_default>
58     >::value), "Result != tag_default" );
59
60     // Option found once
61     static_assert( (std::is_same<
62         cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::tag<tag_a> >::type,
63         cds::opt::tag<tag_a>
64     >::value), "Result != tag_a" );
65
66     static_assert( (std::is_same<
67         cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::stat<tag_a>, cds::opt::tag<tag_a> >::type,
68         cds::opt::tag<tag_a>
69     >::value), "Result != tag_a" );
70
71     // First option
72     static_assert( (std::is_same<
73         cds::opt::find_option< cds::opt::tag<tag_default>
74         ,cds::opt::tag<tag_a>   // desired
75         ,cds::opt::stat<tag_a>
76         ,cds::opt::stat<tag_a>
77         ,cds::opt::stat<tag_a>
78         ,cds::opt::stat<tag_a>
79         ,cds::opt::stat<tag_a>
80         >::type,
81         cds::opt::tag<tag_a>
82     >::value), "Result != tag_a" );
83
84     // Last option
85     static_assert( (std::is_same<
86         cds::opt::find_option< cds::opt::tag<tag_default>
87         ,cds::opt::stat<tag_a>
88         ,cds::opt::stat<tag_a>
89         ,cds::opt::stat<tag_a>
90         ,cds::opt::stat<tag_a>
91         ,cds::opt::stat<tag_a>
92         ,cds::opt::tag<tag_a>   // desired
93         >::type,
94         cds::opt::tag<tag_a>
95     >::value), "Result != tag_a" );
96
97     // Middle option
98     static_assert( (std::is_same<
99         cds::opt::find_option< cds::opt::tag<tag_default>
100         ,cds::opt::stat<tag_a>
101         ,cds::opt::stat<tag_a>
102         ,cds::opt::stat<tag_a>
103         ,cds::opt::tag<tag_a>   // desired
104         ,cds::opt::stat<tag_a>
105         ,cds::opt::stat<tag_a>
106         >::type,
107         cds::opt::tag<tag_a>
108     >::value), "Result != tag_a" );
109
110     // Option not found
111     static_assert( (std::is_same<
112         cds::opt::find_option< cds::opt::tag<tag_default>
113         ,cds::opt::stat<tag_a>
114         ,cds::opt::stat<tag_a>
115         ,cds::opt::stat<tag_a>
116         ,cds::opt::stat<tag_default>
117         ,cds::opt::stat<tag_a>
118         ,cds::opt::stat<tag_a>
119         >::type,
120         cds::opt::tag<tag_default>
121     >::value), "Result != tag_default" );
122
123     // Multiple options
124     static_assert( (std::is_same<
125         cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::tag<tag_a>, cds::opt::tag<tag_b> >::type,
126         cds::opt::tag<tag_a>
127     >::value), "Result != tag_a" );
128
129     static_assert( (std::is_same<
130         cds::opt::find_option< cds::opt::tag<tag_default>
131         ,cds::opt::tag<tag_a>   // desired - first accepted
132         ,cds::opt::stat<tag_a>
133         ,cds::opt::stat<tag_a>
134         ,cds::opt::stat<tag_b>
135         ,cds::opt::stat<tag_a>
136         ,cds::opt::stat<tag_a>
137         ,cds::opt::tag<tag_b>    // desired
138         >::type,
139         cds::opt::tag<tag_a>
140     >::value), "Result != tag_a" );
141
142
143
144     // *****************************************************
145     // Value options
146
147     // Not found
148     static_assert( (std::is_same<
149         cds::opt::find_option< int_opt<15>, bool_opt<false>, cds::opt::stat<tag_a> >::type,
150         int_opt<15>
151     >::value), "Result != int_opt<15>" );
152
153     static_assert( (std::is_same<
154         cds::opt::find_option< int_opt<15>, int_opt<100>, cds::opt::stat<tag_a> >::type,
155         int_opt<100>
156     >::value), "Result != int_opt<100>" );
157
158     static_assert( (std::is_same<
159         cds::opt::find_option< int_opt<15>, int_opt<100>, cds::opt::stat<tag_a>, bool_opt<true>, int_opt<200> >::type,
160         int_opt<100>
161     >::value), "Result != int_opt<100>" );
162
163     // User-provided enum type
164     static_assert( (std::is_same<
165         cds::opt::find_option< enum_opt<val_zero>, int_opt<100>, cds::opt::stat<tag_a>, int_opt<200> >::type,
166         enum_opt<val_zero>
167     >::value), "Result != enum_opt<val_zero>" );
168
169     static_assert( (std::is_same<
170         cds::opt::find_option< enum_opt<val_zero>, int_opt<100>, cds::opt::stat<tag_a>, enum_opt<val_three>, int_opt<200> >::type,
171         enum_opt<val_three>
172     >::value), "Result != enum_opt<val_three>" );
173
174 }
175
176 void test_extracting_option_value()
177 {
178 #if !(CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION < 40500)
179     // GCC 4.4 does not support local struct declarations
180     struct tag_a;
181 #endif
182     // Define option
183     typedef cds::opt::tag< tag_a >  tag_option;
184
185     // What is the value of the tag_option?
186     // How we can extract tag_a from tag_option?
187     // Here is a solution:
188     typedef cds::opt::value< tag_option >::tag  tag_option_value;
189
190     // tag_option_value is the same as tag_a
191     static_assert( (std::is_same< tag_option_value, tag_a >::value), "Error getting the value of option: tag_option_value != tag_a" );
192
193     // Value-option
194     typedef cds::opt::alignment< 16 >   align_option;
195     static_assert( cds::opt::value< align_option >::alignment == 16, "Error getting the value of option: option value != 16" );
196 }