1 /*=============================================================================
2     Boost.Wave: A Standard compliant C++ preprocessor library
3     http://www.boost.org/
4 
5     Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
6     Software License, Version 1.0. (See accompanying file
7     LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9 
10 // Tests more complex macro expansion.
11 
12 // token-pasting macro
13 #define CAT(a, b) PRIMITIVE_CAT(a, b)
14 #define PRIMITIVE_CAT(a, b) a ## b
15 
16 // splits a value that is about to expand into two parameters and returns
17 // either the zero-th or one-th element.
18 #define SPLIT(n, im) PRIMITIVE_CAT(SPLIT_, n)(im)
19 #define SPLIT_0(a, b) a
20 #define SPLIT_1(a, b) b
21 
22 // detects if the parameter is nullary parentheses () or something else.
23 // passing non-nullary parenthesis is invalid input.
24 #define IS_NULLARY(expr) \
25     SPLIT( \
26         0, \
27         CAT(IS_NULLARY_R_, IS_NULLARY_T expr) \
28     ) \
29     /**/
30 #define IS_NULLARY_T() 1
31 #define IS_NULLARY_R_1 1, ?
32 #define IS_NULLARY_R_IS_NULLARY_T 0, ?
33 
34 // expands to a macro that eats an n-element parenthesized expression.
35 #define EAT(n) PRIMITIVE_CAT(EAT_, n)
36 #define EAT_0()
37 #define EAT_1(a)
38 #define EAT_2(a, b)
39 #define EAT_3(a, b, c)
40 
41 // expands to a macro that removes the parentheses from an n-element
42 // parenthesized expression
43 #define REM(n) PRIMITIVE_CAT(REM_, n)
44 #define REM_0()
45 #define REM_1(a) a
46 #define REM_2(a, b) a, b
47 #define REM_3(a, b, c) a, b, c
48 
49 // expands to nothing
50 #define NIL
51 
52 // expands to 1 if x is less than y otherwise, it expands to 0
53 #define LESS(x, y) \
54     IS_NULLARY( \
55         PRIMITIVE_CAT(LESS_, y)( \
56             EAT(1), PRIMITIVE_CAT(LESS_, x) \
57         )() \
58     ) \
59     /**/
60 
61 #define LESS_0(a, b) a(EAT(2)) b(REM(1), NIL)
62 #define LESS_1(a, b) a(LESS_0) b(REM(1), NIL)
63 #define LESS_2(a, b) a(LESS_1) b(REM(1), NIL)
64 #define LESS_3(a, b) a(LESS_2) b(REM(1), NIL)
65 #define LESS_4(a, b) a(LESS_3) b(REM(1), NIL)
66 #define LESS_5(a, b) a(LESS_4) b(REM(1), NIL)
67 
68 // expands to the binary one's compliment of a binary input value.  i.e. 0 or 1
69 #define COMPL(n) PRIMITIVE_CAT(COMPL_, n)
70 #define COMPL_0 1
71 #define COMPL_1 0
72 
73 // these do the obvious...
74 #define GREATER(x, y) LESS(y, x)
75 #define LESS_EQUAL(x, y) COMPL(LESS(y, x))
76 #define GREATER_EQUAL(x, y) COMPL(LESS(x, y))
77 
78 // causes another rescan...
79 #define SCAN(x) x
80 
81 // expands to 1 if x is not equal to y. this one contains a workaround...
82 #define NOT_EQUAL(x, y) \
83     IS_NULLARY( \
84         SCAN( \
85             PRIMITIVE_CAT(LESS_, x)( \
86                 EAT(1), \
87                 PRIMITIVE_CAT(LESS_, y) EAT(2) \
88             )((), ...) \
89         ) \
90     ) \
91     /**/
92 #define EQUAL(x, y) COMPL(NOT_EQUAL(x, y))
93 
94 //R #line 95 "t_1_024.cpp"
95 LESS(2, 3)            //R 1
96 LESS(3, 2)            //R 0
97 LESS(3, 3)            //R 0
98 GREATER(2, 3)         //R 0
99 GREATER(3, 2)         //R 1
100 GREATER(3, 3)         //R 0
101 LESS_EQUAL(2, 3)      //R 1
102 LESS_EQUAL(3, 2)      //R 0
103 LESS_EQUAL(3, 3)      //R 1
104 GREATER_EQUAL(2, 3)   //R 0
105 GREATER_EQUAL(3, 2)   //R 1
106 GREATER_EQUAL(3, 3)   //R 1
107 NOT_EQUAL(2, 3)       //R 1
108 NOT_EQUAL(3, 2)       //R 1
109 NOT_EQUAL(3, 3)       //R 0
110 EQUAL(2, 3)           //R 0
111 EQUAL(3, 2)           //R 0
112 EQUAL(3, 3)           //R 1
113