Added copyright and license
[libcds.git] / tests / test-hdr / misc / find_option.cpp
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8     
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13       list of conditions and the following disclaimer.
14
15     * Redistributions in binary form must reproduce the above copyright notice,
16       this list of conditions and the following disclaimer in the documentation
17       and/or other materials provided with the distribution.
18
19     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     
29 */
30
31 #include <type_traits>
32 #include <cds/opt/options.h>
33
34 // Value options
35 namespace {
36
37     template <int Val>
38     struct int_opt {
39         static const int value = Val;
40     };
41
42     template <bool Val>
43     struct bool_opt {
44         static const bool value = Val;
45     };
46
47     enum user_enum {
48         val_zero, val_one, val_two, val_three, val_four, val_five
49     };
50
51     template <user_enum Val>
52     struct enum_opt {
53         static const user_enum value = Val;
54     };
55 }
56
57 // Declare necessary cds::opt::find_option specialization for user-provided enum type
58 CDS_DECLARE_FIND_OPTION_INTEGRAL_SPECIALIZATION( user_enum )
59
60 #if CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION < 40500
61 // GCC 4.4 does not support local struct declarations
62 namespace {
63     struct tag_default;
64     struct tag_a;
65     struct tag_b;
66 }
67 #endif
68
69 void find_option_compiler_test()
70 {
71
72     // *************************************************
73     // Type options
74     //
75 #if !(CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION < 40500)
76     // GCC 4.4 does not support local struct declarations
77     struct tag_default;
78     struct tag_a;
79     struct tag_b;
80 #endif
81
82     // Option not found
83     static_assert( (std::is_same<
84         cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::stat<tag_a>, bool_opt<false> >::type,
85         cds::opt::tag<tag_default>
86     >::value), "Result != tag_default" );
87
88     // Option found once
89     static_assert( (std::is_same<
90         cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::tag<tag_a> >::type,
91         cds::opt::tag<tag_a>
92     >::value), "Result != tag_a" );
93
94     static_assert( (std::is_same<
95         cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::stat<tag_a>, cds::opt::tag<tag_a> >::type,
96         cds::opt::tag<tag_a>
97     >::value), "Result != tag_a" );
98
99     // First option
100     static_assert( (std::is_same<
101         cds::opt::find_option< cds::opt::tag<tag_default>
102         ,cds::opt::tag<tag_a>   // desired
103         ,cds::opt::stat<tag_a>
104         ,cds::opt::stat<tag_a>
105         ,cds::opt::stat<tag_a>
106         ,cds::opt::stat<tag_a>
107         ,cds::opt::stat<tag_a>
108         >::type,
109         cds::opt::tag<tag_a>
110     >::value), "Result != tag_a" );
111
112     // Last option
113     static_assert( (std::is_same<
114         cds::opt::find_option< cds::opt::tag<tag_default>
115         ,cds::opt::stat<tag_a>
116         ,cds::opt::stat<tag_a>
117         ,cds::opt::stat<tag_a>
118         ,cds::opt::stat<tag_a>
119         ,cds::opt::stat<tag_a>
120         ,cds::opt::tag<tag_a>   // desired
121         >::type,
122         cds::opt::tag<tag_a>
123     >::value), "Result != tag_a" );
124
125     // Middle option
126     static_assert( (std::is_same<
127         cds::opt::find_option< cds::opt::tag<tag_default>
128         ,cds::opt::stat<tag_a>
129         ,cds::opt::stat<tag_a>
130         ,cds::opt::stat<tag_a>
131         ,cds::opt::tag<tag_a>   // desired
132         ,cds::opt::stat<tag_a>
133         ,cds::opt::stat<tag_a>
134         >::type,
135         cds::opt::tag<tag_a>
136     >::value), "Result != tag_a" );
137
138     // Option not found
139     static_assert( (std::is_same<
140         cds::opt::find_option< cds::opt::tag<tag_default>
141         ,cds::opt::stat<tag_a>
142         ,cds::opt::stat<tag_a>
143         ,cds::opt::stat<tag_a>
144         ,cds::opt::stat<tag_default>
145         ,cds::opt::stat<tag_a>
146         ,cds::opt::stat<tag_a>
147         >::type,
148         cds::opt::tag<tag_default>
149     >::value), "Result != tag_default" );
150
151     // Multiple options
152     static_assert( (std::is_same<
153         cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::tag<tag_a>, cds::opt::tag<tag_b> >::type,
154         cds::opt::tag<tag_a>
155     >::value), "Result != tag_a" );
156
157     static_assert( (std::is_same<
158         cds::opt::find_option< cds::opt::tag<tag_default>
159         ,cds::opt::tag<tag_a>   // desired - first accepted
160         ,cds::opt::stat<tag_a>
161         ,cds::opt::stat<tag_a>
162         ,cds::opt::stat<tag_b>
163         ,cds::opt::stat<tag_a>
164         ,cds::opt::stat<tag_a>
165         ,cds::opt::tag<tag_b>    // desired
166         >::type,
167         cds::opt::tag<tag_a>
168     >::value), "Result != tag_a" );
169
170
171
172     // *****************************************************
173     // Value options
174
175     // Not found
176     static_assert( (std::is_same<
177         cds::opt::find_option< int_opt<15>, bool_opt<false>, cds::opt::stat<tag_a> >::type,
178         int_opt<15>
179     >::value), "Result != int_opt<15>" );
180
181     static_assert( (std::is_same<
182         cds::opt::find_option< int_opt<15>, int_opt<100>, cds::opt::stat<tag_a> >::type,
183         int_opt<100>
184     >::value), "Result != int_opt<100>" );
185
186     static_assert( (std::is_same<
187         cds::opt::find_option< int_opt<15>, int_opt<100>, cds::opt::stat<tag_a>, bool_opt<true>, int_opt<200> >::type,
188         int_opt<100>
189     >::value), "Result != int_opt<100>" );
190
191     // User-provided enum type
192     static_assert( (std::is_same<
193         cds::opt::find_option< enum_opt<val_zero>, int_opt<100>, cds::opt::stat<tag_a>, int_opt<200> >::type,
194         enum_opt<val_zero>
195     >::value), "Result != enum_opt<val_zero>" );
196
197     static_assert( (std::is_same<
198         cds::opt::find_option< enum_opt<val_zero>, int_opt<100>, cds::opt::stat<tag_a>, enum_opt<val_three>, int_opt<200> >::type,
199         enum_opt<val_three>
200     >::value), "Result != enum_opt<val_three>" );
201
202 }
203
204 void test_extracting_option_value()
205 {
206 #if !(CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION < 40500)
207     // GCC 4.4 does not support local struct declarations
208     struct tag_a;
209 #endif
210     // Define option
211     typedef cds::opt::tag< tag_a >  tag_option;
212
213     // What is the value of the tag_option?
214     // How we can extract tag_a from tag_option?
215     // Here is a solution:
216     typedef cds::opt::value< tag_option >::tag  tag_option_value;
217
218     // tag_option_value is the same as tag_a
219     static_assert( (std::is_same< tag_option_value, tag_a >::value), "Error getting the value of option: tag_option_value != tag_a" );
220
221     // Value-option
222     typedef cds::opt::alignment< 16 >   align_option;
223     static_assert( cds::opt::value< align_option >::alignment == 16, "Error getting the value of option: option value != 16" );
224 }