]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/vmd/test/test_doc_example_switch.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / vmd / test / test_doc_example_switch.hpp
CommitLineData
7c673cae
FG
1
2// (C) Copyright Edward Diener 2011-2015
3// Use, modification and distribution are subject to the Boost Software License,
4// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt).
6
7#if !defined(BOOST_VMD_TEST_DOC_EXAMPLE_SWITCH_HPP)
8#define BOOST_VMD_TEST_DOC_EXAMPLE_SWITCH_HPP
9
10//[ example_switch
11
12#include <boost/vmd/detail/setup.hpp>
13
14#if BOOST_PP_VARIADICS
15
16#include <boost/preprocessor/cat.hpp>
17#include <boost/preprocessor/arithmetic/inc.hpp>
18#include <boost/preprocessor/comparison/equal.hpp>
19#include <boost/preprocessor/control/expr_iif.hpp>
20#include <boost/preprocessor/control/iif.hpp>
21#include <boost/preprocessor/control/while.hpp>
22#include <boost/preprocessor/tuple/elem.hpp>
23#include <boost/preprocessor/tuple/enum.hpp>
24#include <boost/preprocessor/facilities/expand.hpp>
25#include <boost/preprocessor/tuple/replace.hpp>
26#include <boost/preprocessor/tuple/size.hpp>
27#include <boost/preprocessor/variadic/to_tuple.hpp>
28#include <boost/preprocessor/variadic/size.hpp>
29#include <boost/vmd/equal.hpp>
30#include <boost/vmd/identity.hpp>
31#include <boost/vmd/is_empty.hpp>
32
33/*
34
35 State index into state values
36
37*/
38
39#define BOOST_VMD_SWITCH_STATE_ELEM_INDEX 2
40#define BOOST_VMD_SWITCH_STATE_ELEM_DEFAULT 4
41#define BOOST_VMD_SWITCH_STATE_ELEM_RESULT 5
42
43/*
44
45 Retrieve the state value, never changes
46
47*/
48
49#define BOOST_VMD_SWITCH_STATE_GET_VALUE(state) \
50 BOOST_PP_TUPLE_ELEM(0,state) \
51/**/
52
53/*
54
55 Retrieve the state tuple of values, never changes
56
57*/
58
59#define BOOST_VMD_SWITCH_STATE_GET_CHOICES(state) \
60 BOOST_PP_TUPLE_ELEM(1,state) \
61/**/
62
63/*
64
65 Retrieve the state index
66
67*/
68
69#define BOOST_VMD_SWITCH_STATE_GET_INDEX(state) \
70 BOOST_PP_TUPLE_ELEM(2,state) \
71/**/
72
73/*
74
75 Retrieve the state tuple of values size, never changes
76
77*/
78
79#define BOOST_VMD_SWITCH_STATE_GET_SIZE(state) \
80 BOOST_PP_TUPLE_ELEM(3,state) \
81/**/
82
83/*
84
85 Retrieve the state default tuple
86
87*/
88
89#define BOOST_VMD_SWITCH_STATE_GET_DEFAULT(state) \
90 BOOST_PP_TUPLE_ELEM(4,state) \
91/**/
92
93/*
94
95 Retrieve the state result tuple
96
97*/
98
99#define BOOST_VMD_SWITCH_STATE_GET_RESULT(state) \
100 BOOST_PP_TUPLE_ELEM(5,state) \
101/**/
102
103/*
104
105 Retrieve the current value tuple
106
107*/
108
109#define BOOST_VMD_SWITCH_STATE_GET_CURRENT_CHOICE(state) \
110 BOOST_PP_TUPLE_ELEM \
111 ( \
112 BOOST_VMD_SWITCH_STATE_GET_INDEX(state), \
113 BOOST_VMD_SWITCH_STATE_GET_CHOICES(state) \
114 ) \
115/**/
116
117/*
118
119 Expands to the state
120
121 value = value to compare against
122 tuple = choices as a tuple of values
123 size = size of tuple of values
124
125 None of these ever change in the WHILE state
126
127*/
128
129#define BOOST_VMD_SWITCH_STATE_EXPAND(value,tuple,size) \
130 (value,tuple,0,size,(0,),(,)) \
131/**/
132
133/*
134
135 Expands to the WHILE state
136
137 The state to our WHILE consists of a tuple of elements:
138
139 1: value to compare against
140 2: tuple of values. Each value is a value/macro pair or if the default just a macro
141 3: index into the values
142 4: tuple for default macro. 0 means no default macro, 1 means default macro and then second value is the default macro.
143 5: tuple of result matched. Emptiness means no result yet specified, 0 means no match, 1 means match and second value is the matching macro.
144
145*/
146
147#define BOOST_VMD_SWITCH_STATE(value,...) \
148 BOOST_VMD_SWITCH_STATE_EXPAND \
149 ( \
150 value, \
151 BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__), \
152 BOOST_PP_VARIADIC_SIZE(__VA_ARGS__) \
153 ) \
154/**/
155
156/*
157
158 Sets the state upon a successful match.
159
160 macro = is the matching macro found
161
162*/
163
164#define BOOST_VMD_SWITCH_OP_SUCCESS(d,state,macro) \
165 BOOST_PP_TUPLE_REPLACE_D \
166 ( \
167 d, \
168 state, \
169 BOOST_VMD_SWITCH_STATE_ELEM_RESULT, \
170 (1,macro) \
171 ) \
172/**/
173
174/*
175
176 Sets the state upon final failure to find a match.
177
178 def = default tuple macro, ignored
179
180*/
181
182#define BOOST_VMD_SWITCH_OP_FAILURE(d,state,def) \
183 BOOST_PP_TUPLE_REPLACE_D \
184 ( \
185 d, \
186 state, \
187 BOOST_VMD_SWITCH_STATE_ELEM_RESULT, \
188 (0,) \
189 ) \
190/**/
191
192/*
193
194 Increments the state index into the tuple values
195
196*/
197
198#define BOOST_VMD_SWITCH_OP_UPDATE_INDEX(d,state) \
199 BOOST_PP_TUPLE_REPLACE_D \
200 ( \
201 d, \
202 state, \
203 BOOST_VMD_SWITCH_STATE_ELEM_INDEX, \
204 BOOST_PP_INC(BOOST_VMD_SWITCH_STATE_GET_INDEX(state)) \
205 ) \
206/**/
207
208/*
209
210 Choose our current value's macro as our successful match
211
212 tuple = current tuple to test
213
214*/
215
216#define BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE_MATCH(d,state,tuple) \
217 BOOST_VMD_SWITCH_OP_SUCCESS(d,state,BOOST_PP_TUPLE_ELEM(1,tuple)) \
218/**/
219
220/*
221
222 Update our state index
223
224 tuple = current tuple to test, ignored
225
226*/
227
228#define BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE_UPDATE_INDEX(d,state,tuple) \
229 BOOST_VMD_SWITCH_OP_UPDATE_INDEX(d,state) \
230/**/
231
232/*
233
234 Test our current value against our value to compare against
235
236 tuple = current tuple to test
237
238*/
239
240#define BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE(d,state,tuple) \
241 BOOST_PP_IIF \
242 ( \
243 BOOST_VMD_EQUAL_D \
244 ( \
245 d, \
246 BOOST_VMD_SWITCH_STATE_GET_VALUE(state), \
247 BOOST_PP_TUPLE_ELEM(0,tuple) \
248 ), \
249 BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE_MATCH, \
250 BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE_UPDATE_INDEX \
251 ) \
252 (d,state,tuple) \
253/**/
254
255/*
256
257 Set our default macro and update the index in our WHILE state
258
259 tuple = current tuple to test
260
261*/
262
263#if BOOST_VMD_MSVC
264
265#define BOOST_VMD_SWITCH_OP_TEST_CURRENT_CREATE_DEFAULT_NN(number,name) \
266 (number,name) \
267/**/
268
269#define BOOST_VMD_SWITCH_OP_TEST_CURRENT_CREATE_DEFAULT(d,state,tuple) \
270 BOOST_VMD_SWITCH_OP_UPDATE_INDEX \
271 ( \
272 d, \
273 BOOST_PP_TUPLE_REPLACE_D \
274 ( \
275 d, \
276 state, \
277 BOOST_VMD_SWITCH_STATE_ELEM_DEFAULT, \
278 BOOST_VMD_SWITCH_OP_TEST_CURRENT_CREATE_DEFAULT_NN(1,BOOST_PP_TUPLE_ENUM(tuple)) \
279 ) \
280 ) \
281/**/
282
283#else
284
285#define BOOST_VMD_SWITCH_OP_TEST_CURRENT_CREATE_DEFAULT(d,state,tuple) \
286 BOOST_VMD_SWITCH_OP_UPDATE_INDEX \
287 ( \
288 d, \
289 BOOST_PP_TUPLE_REPLACE_D \
290 ( \
291 d, \
292 state, \
293 BOOST_VMD_SWITCH_STATE_ELEM_DEFAULT, \
294 (1,BOOST_PP_TUPLE_ENUM(tuple)) \
295 ) \
296 ) \
297/**/
298
299#endif
300
301/*
302
303 If our current value is a default macro, just set the default macro,
304 else test our current value.
305
306 tuple = current tuple to test
307
308*/
309
310#define BOOST_VMD_SWITCH_OP_TEST_CURRENT_TUPLE(d,state,tuple) \
311 BOOST_PP_IIF \
312 ( \
313 BOOST_PP_EQUAL_D \
314 ( \
315 d, \
316 BOOST_PP_TUPLE_SIZE(tuple), \
317 1 \
318 ), \
319 BOOST_VMD_SWITCH_OP_TEST_CURRENT_CREATE_DEFAULT, \
320 BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE \
321 ) \
322 (d,state,tuple) \
323/**/
324
325/*
326
327 Test the current value in our tuple of values
328
329*/
330
331#define BOOST_VMD_SWITCH_OP_TEST_CURRENT(d,state) \
332 BOOST_VMD_SWITCH_OP_TEST_CURRENT_TUPLE \
333 ( \
334 d, \
335 state, \
336 BOOST_VMD_SWITCH_STATE_GET_CURRENT_CHOICE(state) \
337 ) \
338/**/
339
340/*
341
342 Choose the default macro as our successful match
343
344 def = default tuple consisting of just the default macro name
345
346*/
347
348#define BOOST_VMD_SWITCH_OP_DEFAULT_RET_CHOSEN(d,state,def) \
349 BOOST_VMD_SWITCH_OP_SUCCESS \
350 ( \
351 d, \
352 state, \
353 BOOST_PP_TUPLE_ELEM(1,def) \
354 ) \
355/**/
356
357/*
358
359 If the default macro exists, choose it else indicate no macro was found
360
361 def = default tuple consisting of just the default macro name
362
363*/
364
365#define BOOST_VMD_SWITCH_OP_DEFAULT_RET(d,state,def) \
366 BOOST_PP_IIF \
367 ( \
368 BOOST_PP_TUPLE_ELEM(0,def), \
369 BOOST_VMD_SWITCH_OP_DEFAULT_RET_CHOSEN, \
370 BOOST_VMD_SWITCH_OP_FAILURE \
371 ) \
372 (d,state,def) \
373/**/
374
375/*
376
377 Try to choose the default macro if it exists
378
379*/
380
381#define BOOST_VMD_SWITCH_OP_DEFAULT(d,state) \
382 BOOST_VMD_SWITCH_OP_DEFAULT_RET \
383 ( \
384 d, \
385 state, \
386 BOOST_VMD_SWITCH_STATE_GET_DEFAULT(state) \
387 ) \
388/**/
389
390/*
391
392 WHILE loop operation
393
394 Check for the next value match or try to choose the default if all matches have been checked
395
396*/
397
398#define BOOST_VMD_SWITCH_OP(d,state) \
399 BOOST_PP_IIF \
400 ( \
401 BOOST_PP_EQUAL_D \
402 ( \
403 d, \
404 BOOST_VMD_SWITCH_STATE_GET_INDEX(state), \
405 BOOST_VMD_SWITCH_STATE_GET_SIZE(state) \
406 ), \
407 BOOST_VMD_SWITCH_OP_DEFAULT, \
408 BOOST_VMD_SWITCH_OP_TEST_CURRENT \
409 ) \
410 (d,state) \
411/**/
412
413/*
414
415 WHILE loop predicate
416
417 Continue the WHILE loop if a result has not yet been specified
418
419*/
420
421#define BOOST_VMD_SWITCH_PRED(d,state) \
422 BOOST_VMD_IS_EMPTY \
423 ( \
424 BOOST_PP_TUPLE_ELEM \
425 ( \
426 0, \
427 BOOST_VMD_SWITCH_STATE_GET_RESULT(state) \
428 ) \
429 ) \
430/**/
431
432/*
433
434 Invokes the function-like macro
435
436 macro = function-like macro name
437 tparams = tuple of macro parameters
438
439*/
440
441#define BOOST_VMD_SWITCH_PROCESS_INVOKE_MACRO(macro,tparams) \
442 BOOST_PP_EXPAND(macro tparams) \
443/**/
444
445/*
446
447 Processes our WHILE loop result
448
449 callp = tuple of parameters for the called macro
450 result = tuple. The first tuple element is 0
451 if no macro has been found or 1 if a macro
452 has been found. If 1 the second element is
453 the name of a function-like macro
454
455*/
456
457#define BOOST_VMD_SWITCH_PROCESS(callp,result) \
458 BOOST_PP_EXPR_IIF \
459 ( \
460 BOOST_PP_TUPLE_ELEM(0,result), \
461 BOOST_VMD_SWITCH_PROCESS_INVOKE_MACRO \
462 ( \
463 BOOST_PP_TUPLE_ELEM(1,result), \
464 callp \
465 ) \
466 ) \
467/**/
468
469/*
470
471 Use BOOST_VMD_SWITCH_IDENTITY to pass a fixed value instead
472 of a function-like macro as the second element of
473 any tuple of the variadic parameters, or as the default
474 value, to BOOST_VMD_SWITCH.
475
476*/
477
478#if BOOST_VMD_MSVC
479#define BOOST_VMD_SWITCH_IDENTITY(item) BOOST_PP_CAT(BOOST_VMD_IDENTITY(item),)
480#else
481#define BOOST_VMD_SWITCH_IDENTITY BOOST_VMD_IDENTITY
482#endif
483
484/*
485
486 Switch macro
487
488 Parameters are:
489
490 value = value to compare against. May be any VMD data value.
491 callp = tuple of parameters for the called macro
492 variadic parameters = each parameter must be a tuple.
493 Each tuple consists of a two-element tuple. The first element is
494 a value, which may be any VMD data value, and the second element
495 is the name of a function-like macro to be called if the value
496 is equal to the value to compare against. For a default value
497 the tuple is a single-element tuple which contains the name of
498 a function-like macro to be called if no other value matches.
499
500*/
501
502#define BOOST_VMD_SWITCH(value,callp,...) \
503 BOOST_VMD_SWITCH_PROCESS \
504 ( \
505 callp, \
506 BOOST_VMD_SWITCH_STATE_GET_RESULT \
507 ( \
508 BOOST_PP_WHILE \
509 ( \
510 BOOST_VMD_SWITCH_PRED, \
511 BOOST_VMD_SWITCH_OP, \
512 BOOST_VMD_SWITCH_STATE(value,__VA_ARGS__) \
513 ) \
514 ) \
515 ) \
516/**/
517
518#endif /* BOOST_PP_VARIADICS */
519
520//]
521
522#endif /* BOOST_VMD_TEST_DOC_EXAMPLE_SWITCH_HPP */