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