Merged branch 'master' of https://github.com/Nemo1369/libcds
[libcds.git] / test / unit / 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-2017
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 void find_option_compiler_test()
61 {
62
63     // *************************************************
64     // Type options
65     //
66     struct tag_default;
67     struct tag_a;
68     struct tag_b;
69
70     // Option not found
71     static_assert( (std::is_same<
72         cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::stat<tag_a>, bool_opt<false> >::type,
73         cds::opt::tag<tag_default>
74     >::value), "Result != tag_default" );
75
76     // Option found once
77     static_assert( (std::is_same<
78         cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::tag<tag_a> >::type,
79         cds::opt::tag<tag_a>
80     >::value), "Result != tag_a" );
81
82     static_assert( (std::is_same<
83         cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::stat<tag_a>, cds::opt::tag<tag_a> >::type,
84         cds::opt::tag<tag_a>
85     >::value), "Result != tag_a" );
86
87     // First option
88     static_assert( (std::is_same<
89         cds::opt::find_option< cds::opt::tag<tag_default>
90         ,cds::opt::tag<tag_a>   // desired
91         ,cds::opt::stat<tag_a>
92         ,cds::opt::stat<tag_a>
93         ,cds::opt::stat<tag_a>
94         ,cds::opt::stat<tag_a>
95         ,cds::opt::stat<tag_a>
96         >::type,
97         cds::opt::tag<tag_a>
98     >::value), "Result != tag_a" );
99
100     // Last option
101     static_assert( (std::is_same<
102         cds::opt::find_option< cds::opt::tag<tag_default>
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         ,cds::opt::tag<tag_a>   // desired
109         >::type,
110         cds::opt::tag<tag_a>
111     >::value), "Result != tag_a" );
112
113     // Middle option
114     static_assert( (std::is_same<
115         cds::opt::find_option< cds::opt::tag<tag_default>
116         ,cds::opt::stat<tag_a>
117         ,cds::opt::stat<tag_a>
118         ,cds::opt::stat<tag_a>
119         ,cds::opt::tag<tag_a>   // desired
120         ,cds::opt::stat<tag_a>
121         ,cds::opt::stat<tag_a>
122         >::type,
123         cds::opt::tag<tag_a>
124     >::value), "Result != tag_a" );
125
126     // Option not found
127     static_assert( (std::is_same<
128         cds::opt::find_option< cds::opt::tag<tag_default>
129         ,cds::opt::stat<tag_a>
130         ,cds::opt::stat<tag_a>
131         ,cds::opt::stat<tag_a>
132         ,cds::opt::stat<tag_default>
133         ,cds::opt::stat<tag_a>
134         ,cds::opt::stat<tag_a>
135         >::type,
136         cds::opt::tag<tag_default>
137     >::value), "Result != tag_default" );
138
139     // Multiple options
140     static_assert( (std::is_same<
141         cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::tag<tag_a>, cds::opt::tag<tag_b> >::type,
142         cds::opt::tag<tag_a>
143     >::value), "Result != tag_a" );
144
145     static_assert( (std::is_same<
146         cds::opt::find_option< cds::opt::tag<tag_default>
147         ,cds::opt::tag<tag_a>   // desired - first accepted
148         ,cds::opt::stat<tag_a>
149         ,cds::opt::stat<tag_a>
150         ,cds::opt::stat<tag_b>
151         ,cds::opt::stat<tag_a>
152         ,cds::opt::stat<tag_a>
153         ,cds::opt::tag<tag_b>    // desired
154         >::type,
155         cds::opt::tag<tag_a>
156     >::value), "Result != tag_a" );
157
158
159     // *****************************************************
160     // Value options
161
162     // Not found
163     static_assert( (std::is_same<
164         cds::opt::find_option< int_opt<15>, bool_opt<false>, cds::opt::stat<tag_a> >::type,
165         int_opt<15>
166     >::value), "Result != int_opt<15>" );
167
168     static_assert( (std::is_same<
169         cds::opt::find_option< int_opt<15>, int_opt<100>, cds::opt::stat<tag_a> >::type,
170         int_opt<100>
171     >::value), "Result != int_opt<100>" );
172
173     static_assert( (std::is_same<
174         cds::opt::find_option< int_opt<15>, int_opt<100>, cds::opt::stat<tag_a>, bool_opt<true>, int_opt<200> >::type,
175         int_opt<100>
176     >::value), "Result != int_opt<100>" );
177
178     // User-provided enum type
179     static_assert( (std::is_same<
180         cds::opt::find_option< enum_opt<val_zero>, int_opt<100>, cds::opt::stat<tag_a>, int_opt<200> >::type,
181         enum_opt<val_zero>
182     >::value), "Result != enum_opt<val_zero>" );
183
184     static_assert( (std::is_same<
185         cds::opt::find_option< enum_opt<val_zero>, int_opt<100>, cds::opt::stat<tag_a>, enum_opt<val_three>, int_opt<200> >::type,
186         enum_opt<val_three>
187     >::value), "Result != enum_opt<val_three>" );
188
189 }
190
191 void test_extracting_option_value()
192 {
193     struct tag_a;
194
195     // Define option
196     typedef cds::opt::tag< tag_a >  tag_option;
197
198     // What is the value of the tag_option?
199     // How we can extract tag_a from tag_option?
200     // Here is a solution:
201     typedef cds::opt::value< tag_option >::tag  tag_option_value;
202
203     // tag_option_value is the same as tag_a
204     static_assert( (std::is_same< tag_option_value, tag_a >::value), "Error getting the value of option: tag_option_value != tag_a" );
205
206     // Value-option
207     typedef cds::opt::alignment< 16 >   align_option;
208     static_assert( cds::opt::value< align_option >::alignment == 16, "Error getting the value of option: option value != 16" );
209 }