| /*============================================================================= |
| Boost.Wave: A Standard compliant C++ preprocessor library |
| http://www.boost.org/ |
| |
| Copyright (c) 2001-2010 Hartmut Kaiser. Distributed under the Boost |
| Software License, Version 1.0. (See accompanying file |
| LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| =============================================================================*/ |
| |
| // Tests more complex macro expansion. |
| |
| // token-pasting macro |
| #define CAT(a, b) PRIMITIVE_CAT(a, b) |
| #define PRIMITIVE_CAT(a, b) a ## b |
| |
| // splits a value that is about to expand into two parameters and returns |
| // either the zero-th or one-th element. |
| #define SPLIT(n, im) PRIMITIVE_CAT(SPLIT_, n)(im) |
| #define SPLIT_0(a, b) a |
| #define SPLIT_1(a, b) b |
| |
| // detects if the parameter is nullary parentheses () or something else. |
| // passing non-nullary parenthesis is invalid input. |
| #define IS_NULLARY(expr) \ |
| SPLIT( \ |
| 0, \ |
| CAT(IS_NULLARY_R_, IS_NULLARY_T expr) \ |
| ) \ |
| /**/ |
| #define IS_NULLARY_T() 1 |
| #define IS_NULLARY_R_1 1, ? |
| #define IS_NULLARY_R_IS_NULLARY_T 0, ? |
| |
| // expands to a macro that eats an n-element parenthesized expression. |
| #define EAT(n) PRIMITIVE_CAT(EAT_, n) |
| #define EAT_0() |
| #define EAT_1(a) |
| #define EAT_2(a, b) |
| #define EAT_3(a, b, c) |
| |
| // expands to a macro that removes the parentheses from an n-element |
| // parenthesized expression |
| #define REM(n) PRIMITIVE_CAT(REM_, n) |
| #define REM_0() |
| #define REM_1(a) a |
| #define REM_2(a, b) a, b |
| #define REM_3(a, b, c) a, b, c |
| |
| // expands to nothing |
| #define NIL |
| |
| // expands to 1 if x is less than y otherwise, it expands to 0 |
| #define LESS(x, y) \ |
| IS_NULLARY( \ |
| PRIMITIVE_CAT(LESS_, y)( \ |
| EAT(1), PRIMITIVE_CAT(LESS_, x) \ |
| )() \ |
| ) \ |
| /**/ |
| |
| #define LESS_0(a, b) a(EAT(2)) b(REM(1), NIL) |
| #define LESS_1(a, b) a(LESS_0) b(REM(1), NIL) |
| #define LESS_2(a, b) a(LESS_1) b(REM(1), NIL) |
| #define LESS_3(a, b) a(LESS_2) b(REM(1), NIL) |
| #define LESS_4(a, b) a(LESS_3) b(REM(1), NIL) |
| #define LESS_5(a, b) a(LESS_4) b(REM(1), NIL) |
| |
| // expands to the binary one's compliment of a binary input value. i.e. 0 or 1 |
| #define COMPL(n) PRIMITIVE_CAT(COMPL_, n) |
| #define COMPL_0 1 |
| #define COMPL_1 0 |
| |
| // these do the obvious... |
| #define GREATER(x, y) LESS(y, x) |
| #define LESS_EQUAL(x, y) COMPL(LESS(y, x)) |
| #define GREATER_EQUAL(x, y) COMPL(LESS(x, y)) |
| |
| // causes another rescan... |
| #define SCAN(x) x |
| |
| // expands to 1 if x is not equal to y. this one contains a workaround... |
| #define NOT_EQUAL(x, y) \ |
| IS_NULLARY( \ |
| SCAN( \ |
| PRIMITIVE_CAT(LESS_, x)( \ |
| EAT(1), \ |
| PRIMITIVE_CAT(LESS_, y) EAT(2) \ |
| )((), ...) \ |
| ) \ |
| ) \ |
| /**/ |
| #define EQUAL(x, y) COMPL(NOT_EQUAL(x, y)) |
| |
| //R #line 95 "t_1_024.cpp" |
| LESS(2, 3) //R 1 |
| LESS(3, 2) //R 0 |
| LESS(3, 3) //R 0 |
| GREATER(2, 3) //R 0 |
| GREATER(3, 2) //R 1 |
| GREATER(3, 3) //R 0 |
| LESS_EQUAL(2, 3) //R 1 |
| LESS_EQUAL(3, 2) //R 0 |
| LESS_EQUAL(3, 3) //R 1 |
| GREATER_EQUAL(2, 3) //R 0 |
| GREATER_EQUAL(3, 2) //R 1 |
| GREATER_EQUAL(3, 3) //R 1 |
| NOT_EQUAL(2, 3) //R 1 |
| NOT_EQUAL(3, 2) //R 1 |
| NOT_EQUAL(3, 3) //R 0 |
| EQUAL(2, 3) //R 0 |
| EQUAL(3, 2) //R 0 |
| EQUAL(3, 3) //R 1 |