1 /*--------------------------------------------------------------------------*/ 2 /* Copyright 2019-2020 NXP */ 3 /* */ 4 /* NXP Confidential. This software is owned or controlled by NXP and may */ 5 /* only be used strictly in accordance with the applicable license terms. */ 6 /* By expressly accepting such terms or by downloading, installing, */ 7 /* activating and/or otherwise using the software, you are agreeing that */ 8 /* you have read, and that you agree to comply with and are bound by, such */ 9 /* license terms. If you do not agree to be bound by the applicable license */ 10 /* terms, then you may not retain, install, activate or otherwise use the */ 11 /* software. */ 12 /*--------------------------------------------------------------------------*/ 13 14 #ifndef MCUX_CSSL_C_PRE_PROCESSOR_H_ 15 #define MCUX_CSSL_C_PRE_PROCESSOR_H_ 16 17 /** 18 * @file mcuxCsslCPreProcessor.h 19 * @brief The default implementation is based on standard C preprocessor 20 * functionality 21 */ 22 23 #define MCUX_CSSL_CPP_ADD(a) + (a) 24 25 #define MCUX_CSSL_CPP_CAT_IMPL(a, b) a##b 26 27 #define MCUX_CSSL_CPP_CAT(a, b) \ 28 MCUX_CSSL_CPP_CAT_IMPL(a, b) 29 30 #define MCUX_CSSL_CPP_CAT3(a, b, c) \ 31 MCUX_CSSL_CPP_CAT(MCUX_CSSL_CPP_CAT(a, b), c) 32 33 #define MCUX_CSSL_CPP_CAT4(a, b, c, d) \ 34 MCUX_CSSL_CPP_CAT(MCUX_CSSL_CPP_CAT(a, b), MCUX_CSSL_CPP_CAT(c, d)) 35 36 #define MCUX_CSSL_CPP_CAT6(a, b, c, d, e, f) \ 37 MCUX_CSSL_CPP_CAT3( \ 38 MCUX_CSSL_CPP_CAT(a, b), \ 39 MCUX_CSSL_CPP_CAT(c, d), \ 40 MCUX_CSSL_CPP_CAT(e, f)) 41 42 #define MCUX_CSSL_CPP_SEQUENCE_32TO0() \ 43 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, \ 44 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 45 46 #define MCUX_CSSL_CPP_SEQUENCE_N_UNTIL_3TO0() \ 47 n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, \ 48 n, n, n, n, n, n, n, n, n, n, n, n, n, 3, 2, 1, 0 49 50 #define MCUX_CSSL_CPP_SEQUENCE_N_UNTIL_2TO0() \ 51 n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, \ 52 n, n, n, n, n, n, n, n, n, n, n, n, n, n, 2, 1, 0 53 54 #define MCUX_CSSL_CPP_ARG_N( \ 55 _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, \ 56 _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, \ 57 N, ...) \ 58 N 59 60 #define MCUX_CSSL_CPP_ARGCOUNT_IMPL(...) \ 61 MCUX_CSSL_CPP_ARG_N(__VA_ARGS__) 62 63 #define MCUX_CSSL_CPP_ARGCOUNT(...) \ 64 MCUX_CSSL_CPP_ARGCOUNT_IMPL(__VA_ARGS__,MCUX_CSSL_CPP_SEQUENCE_32TO0()) 65 66 #define MCUX_CSSL_CPP_ARGCOUNT_2N(...) \ 67 MCUX_CSSL_CPP_ARGCOUNT_IMPL(__VA_ARGS__,MCUX_CSSL_CPP_SEQUENCE_N_UNTIL_2TO0()) 68 69 #define MCUX_CSSL_CPP_ARGCOUNT_3N(...) \ 70 MCUX_CSSL_CPP_ARGCOUNT_IMPL(__VA_ARGS__,MCUX_CSSL_CPP_SEQUENCE_N_UNTIL_3TO0()) 71 72 #define MCUX_CSSL_CPP_OVERLOADED_IMPL(name, n) MCUX_CSSL_CPP_CAT_IMPL(name, n) 73 74 #define MCUX_CSSL_CPP_OVERLOADED(name, ...) \ 75 MCUX_CSSL_CPP_DEFER2(MCUX_CSSL_CPP_OVERLOADED_IMPL)()(name, MCUX_CSSL_CPP_ARGCOUNT(__VA_ARGS__)) 76 77 #define MCUX_CSSL_CPP_OVERLOADED1(name, ...) \ 78 MCUX_CSSL_CPP_IF_ELSE(MCUX_CSSL_CPP_HAS_ONE_ARG(__VA_ARGS__))( \ 79 /* If only one arg, use the 1 version */ \ 80 MCUX_CSSL_CPP_CAT(name,1)(MCUX_CSSL_CPP_FIRST(__VA_ARGS__, /* ensure extra argument: */ 0)) \ 81 )( \ 82 /* Otherwise the n version */ \ 83 MCUX_CSSL_CPP_CAT(name,n)(__VA_ARGS__) \ 84 ) 85 86 #define MCUX_CSSL_CPP_OVERLOADED2(name, ...) \ 87 MCUX_CSSL_CPP_OVERLOADED_IMPL(name, MCUX_CSSL_CPP_ARGCOUNT_2N(__VA_ARGS__))(__VA_ARGS__) 88 89 #define MCUX_CSSL_CPP_OVERLOADED3(name, ...) \ 90 MCUX_CSSL_CPP_OVERLOADED_IMPL(name, MCUX_CSSL_CPP_ARGCOUNT_3N(__VA_ARGS__))(__VA_ARGS__) 91 92 93 94 /***************************************************************************** 95 * Helper macros * 96 *****************************************************************************/ 97 98 /* Apply a macro to all arguments */ 99 #define MCUX_CSSL_CPP_MAP(__macro, ...) \ 100 MCUX_CSSL_CPP_EVAL(MCUX_CSSL_CPP_MAP_IMPL(__macro, __VA_ARGS__)) 101 102 /* Evaluate a complex macro (which needs multiple expansions to be processed) */ 103 #define MCUX_CSSL_CPP_EVAL(...) MCUX_CSSL_CPP_EVAL1024(__VA_ARGS__) 104 #define MCUX_CSSL_CPP_EVAL1024(...) MCUX_CSSL_CPP_EVAL512(MCUX_CSSL_CPP_EVAL512(__VA_ARGS__)) 105 #define MCUX_CSSL_CPP_EVAL512(...) MCUX_CSSL_CPP_EVAL256(MCUX_CSSL_CPP_EVAL256(__VA_ARGS__)) 106 #define MCUX_CSSL_CPP_EVAL256(...) MCUX_CSSL_CPP_EVAL128(MCUX_CSSL_CPP_EVAL128(__VA_ARGS__)) 107 #define MCUX_CSSL_CPP_EVAL128(...) MCUX_CSSL_CPP_EVAL64( MCUX_CSSL_CPP_EVAL64( __VA_ARGS__)) 108 #define MCUX_CSSL_CPP_EVAL64(...) MCUX_CSSL_CPP_EVAL32( MCUX_CSSL_CPP_EVAL32( __VA_ARGS__)) 109 #define MCUX_CSSL_CPP_EVAL32(...) MCUX_CSSL_CPP_EVAL16( MCUX_CSSL_CPP_EVAL16( __VA_ARGS__)) 110 #define MCUX_CSSL_CPP_EVAL16(...) MCUX_CSSL_CPP_EVAL8( MCUX_CSSL_CPP_EVAL8( __VA_ARGS__)) 111 #define MCUX_CSSL_CPP_EVAL8(...) MCUX_CSSL_CPP_EVAL4( MCUX_CSSL_CPP_EVAL4( __VA_ARGS__)) 112 #define MCUX_CSSL_CPP_EVAL4(...) MCUX_CSSL_CPP_EVAL2( MCUX_CSSL_CPP_EVAL2( __VA_ARGS__)) 113 #define MCUX_CSSL_CPP_EVAL2(...) MCUX_CSSL_CPP_EVAL1( MCUX_CSSL_CPP_EVAL1( __VA_ARGS__)) 114 #define MCUX_CSSL_CPP_EVAL1(...) __VA_ARGS__ 115 116 /* Recursive definition of map macro, assumes at least one argument */ 117 #define MCUX_CSSL_CPP_MAP_IMPL(__macro, ...) \ 118 /* Apply the macro to the first argument from the list */\ 119 __macro(MCUX_CSSL_CPP_FIRST(__VA_ARGS__, /* ensure second argument: */ 0)) \ 120 /* Only proceed if there are additional arguments */\ 121 MCUX_CSSL_CPP_IF(MCUX_CSSL_CPP_HAS_MORE_ARGS(__VA_ARGS__))( \ 122 /* Recursive call for remaining arguments */\ 123 MCUX_CSSL_CPP_DEFER2(MCUX_CSSL_CPP_MAP_IMPL_)()(__macro, \ 124 MCUX_CSSL_CPP_NEXT(__VA_ARGS__)) \ 125 ) 126 #define MCUX_CSSL_CPP_MAP_IMPL_() MCUX_CSSL_CPP_MAP_IMPL 127 128 /* Extract first argument (requires at least two arguments to be present) */ 129 #define MCUX_CSSL_CPP_FIRST(a, ...) a 130 /* Extract second argument (requires at least three arguments to be present) */ 131 #define MCUX_CSSL_CPP_SECOND(a, b, ...) b 132 /* Extract second argument (requires at least four arguments to be present) */ 133 #define MCUX_CSSL_CPP_THIRD(a, b, c, ...) c 134 /* Extract second argument (requires at least five arguments to be present) */ 135 #define MCUX_CSSL_CPP_FOURTH(a, b, c, d, ...) d 136 /* Remove the first argument from the list (requires at least two arguments to be present) */ 137 #define MCUX_CSSL_CPP_NEXT(...) MCUX_CSSL_CPP_NEXT_()(__VA_ARGS__) 138 #define MCUX_CSSL_CPP_NEXT_() MCUX_CSSL_CPP_NEXT__ 139 #define MCUX_CSSL_CPP_NEXT__(x, ...) __VA_ARGS__ 140 141 /* Check whether there is more then one argument */ 142 #define MCUX_CSSL_CPP_HAS_MORE_ARGS(...) \ 143 MCUX_CSSL_CPP_NOT(MCUX_CSSL_CPP_IS_MARKER(MCUX_CSSL_CPP_SECOND(__VA_ARGS__, MCUX_CSSL_CPP_MARKER(), MCUX_CSSL_CPP_MARKER()))) 144 145 #define MCUX_CSSL_CPP_HAS_ONE_ARG(...) \ 146 MCUX_CSSL_CPP_IS_MARKER(MCUX_CSSL_CPP_SECOND(__VA_ARGS__, MCUX_CSSL_CPP_MARKER(), MCUX_CSSL_CPP_MARKER())) 147 148 #define MCUX_CSSL_CPP_HAS_TWO_ARGS(...) \ 149 MCUX_CSSL_CPP_IS_MARKER(MCUX_CSSL_CPP_THIRD(__VA_ARGS__, MCUX_CSSL_CPP_MARKER(), MCUX_CSSL_CPP_MARKER(), MCUX_CSSL_CPP_MARKER())) 150 151 #define MCUX_CSSL_CPP_HAS_THREE_ARGS(...) \ 152 MCUX_CSSL_CPP_IS_MARKER(MCUX_CSSL_CPP_FOURTH(__VA_ARGS__, MCUX_CSSL_CPP_MARKER(), MCUX_CSSL_CPP_MARKER(), MCUX_CSSL_CPP_MARKER(), MCUX_CSSL_CPP_MARKER())) 153 154 155 /* Check whether the argument is MCUX_CSSL_CPP_MARKER(), return 1 if it is */ 156 #define MCUX_CSSL_CPP_IS_MARKER(...) \ 157 MCUX_CSSL_CPP_SECOND(__VA_ARGS__, 0, 0) 158 #define MCUX_CSSL_CPP_MARKER() \ 159 ~, 1 160 161 /* Convert any argument into a bool (either 0 or 1), by double negation */ 162 #define MCUX_CSSL_CPP_BOOL(x) MCUX_CSSL_CPP_NOT(MCUX_CSSL_CPP_NOT(x)) 163 164 /* Boolean negation (map value 0 to the marker, and check if we have the marker) */ 165 #define MCUX_CSSL_CPP_NOT(x) MCUX_CSSL_CPP_IS_MARKER(MCUX_CSSL_CPP_CAT(MCUX_CSSL_CPP_NOT_BOOL_, x)) 166 #define MCUX_CSSL_CPP_NOT_BOOL_0 MCUX_CSSL_CPP_MARKER() 167 168 /* Convert condition to bool */ 169 #define MCUX_CSSL_CPP_IF(condition) MCUX_CSSL_CPP_IF_(MCUX_CSSL_CPP_BOOL(condition)) 170 /* Convert bool to decision defines */ 171 #define MCUX_CSSL_CPP_IF_(condition) MCUX_CSSL_CPP_CAT(MCUX_CSSL_CPP_IF_BOOL_, condition) 172 /* If 0, do nothing*/ 173 #define MCUX_CSSL_CPP_IF_BOOL_0(...) 174 /* If 1, perform action */ 175 #define MCUX_CSSL_CPP_IF_BOOL_1(...) __VA_ARGS__ 176 177 /* Convert condition to bool */ 178 #define MCUX_CSSL_CPP_IF_ELSE(condition) MCUX_CSSL_CPP_IF_ELSE_IMPL(MCUX_CSSL_CPP_BOOL(condition)) 179 /* Convert bool to decision defines */ 180 #define MCUX_CSSL_CPP_IF_ELSE_IMPL(condition) MCUX_CSSL_CPP_CAT(MCUX_CSSL_CPP_IFE_BOOL_, condition) 181 /* If 0, ignore action */ 182 #define MCUX_CSSL_CPP_IFE_BOOL_0(...) MCUX_CSSL_CPP_IFE_BOOL_0_ELSE 183 /* Else 0, perform action */ 184 #define MCUX_CSSL_CPP_IFE_BOOL_0_ELSE(...) __VA_ARGS__ 185 /* If 1, perform action */ 186 #define MCUX_CSSL_CPP_IFE_BOOL_1(...) __VA_ARGS__ MCUX_CSSL_CPP_IFE_BOOL_1_ELSE 187 /* Else 1, ignore action */ 188 189 #define MCUX_CSSL_CPP_IFE_BOOL_1_ELSE(...) 190 191 /* Defer macro expansion */ 192 #define MCUX_CSSL_CPP_EMPTY() 193 #define MCUX_CSSL_CPP_DEFER1(macro) macro MCUX_CSSL_CPP_EMPTY() 194 #define MCUX_CSSL_CPP_DEFER2(macro) macro MCUX_CSSL_CPP_EMPTY MCUX_CSSL_CPP_EMPTY()() 195 196 #endif /* MCUX_CSSL_C_PRE_PROCESSOR_H_ */ 197