duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

preprocessor.hpp (6579B)


      1 #ifndef _C4_PREPROCESSOR_HPP_
      2 #define _C4_PREPROCESSOR_HPP_
      3 
      4 /** @file preprocessor.hpp Contains basic macros and preprocessor utilities.
      5  * @ingroup basic_headers */
      6 
      7 #ifdef __clang__
      8     /* NOTE: using , ## __VA_ARGS__ to deal with zero-args calls to
      9      * variadic macros is not portable, but works in clang, gcc, msvc, icc.
     10      * clang requires switching off compiler warnings for pedantic mode.
     11      * @see http://stackoverflow.com/questions/32047685/variadic-macro-without-arguments */
     12 #   pragma clang diagnostic push
     13 #   pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" // warning: token pasting of ',' and __VA_ARGS__ is a GNU extension
     14 #elif defined(__GNUC__)
     15     /* GCC also issues a warning for zero-args calls to variadic macros.
     16      * This warning is switched on with -pedantic and apparently there is no
     17      * easy way to turn it off as with clang. But marking this as a system
     18      * header works.
     19      * @see https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html
     20      * @see http://stackoverflow.com/questions/35587137/ */
     21 #   pragma GCC system_header
     22 #endif
     23 
     24 #define C4_WIDEN(str) L"" str
     25 
     26 #define C4_COUNTOF(arr) (sizeof(arr)/sizeof((arr)[0]))
     27 
     28 #define C4_EXPAND(arg) arg
     29 
     30 /** useful in some macro calls with template arguments */
     31 #define C4_COMMA ,
     32 /** useful in some macro calls with template arguments
     33  * @see C4_COMMA */
     34 #define C4_COMMA_X C4_COMMA
     35 
     36 /** expand and quote */
     37 #define C4_XQUOTE(arg) _C4_XQUOTE(arg)
     38 #define _C4_XQUOTE(arg) C4_QUOTE(arg)
     39 #define C4_QUOTE(arg) #arg
     40 
     41 /** expand and concatenate */
     42 #define C4_XCAT(arg1, arg2) _C4_XCAT(arg1, arg2)
     43 #define _C4_XCAT(arg1, arg2) C4_CAT(arg1, arg2)
     44 #define C4_CAT(arg1, arg2) arg1##arg2
     45 
     46 #define C4_VERSION_CAT(major, minor, patch) ((major)*10000 + (minor)*100 + (patch))
     47 
     48 /** A preprocessor foreach. Spectacular trick taken from:
     49  * http://stackoverflow.com/a/1872506/5875572
     50  * The first argument is for a macro receiving a single argument,
     51  * which will be called with every subsequent argument. There is
     52  * currently a limit of 32 arguments, and at least 1 must be provided.
     53  *
     54 Example:
     55 @code{.cpp}
     56 struct Example {
     57     int a;
     58     int b;
     59     int c;
     60 };
     61 // define a one-arg macro to be called
     62 #define PRN_STRUCT_OFFSETS(field) PRN_STRUCT_OFFSETS_(Example, field)
     63 #define PRN_STRUCT_OFFSETS_(structure, field) printf(C4_XQUOTE(structure) ":" C4_XQUOTE(field)" - offset=%zu\n", offsetof(structure, field));
     64 
     65 // now call the macro for a, b and c
     66 C4_FOR_EACH(PRN_STRUCT_OFFSETS, a, b, c);
     67 @endcode */
     68 #define C4_FOR_EACH(what, ...) C4_FOR_EACH_SEP(what, ;, __VA_ARGS__)
     69 
     70 /** same as C4_FOR_EACH(), but use a custom separator between statements.
     71  * If a comma is needed as the separator, use the C4_COMMA macro.
     72  * @see C4_FOR_EACH
     73  * @see C4_COMMA
     74  */
     75 #define C4_FOR_EACH_SEP(what, sep, ...) _C4_FOR_EACH_(_C4_FOR_EACH_NARG(__VA_ARGS__), what, sep, __VA_ARGS__)
     76 
     77 /// @cond dev
     78 
     79 #define _C4_FOR_EACH_01(what, sep, x) what(x) sep
     80 #define _C4_FOR_EACH_02(what, sep, x, ...) what(x) sep _C4_FOR_EACH_01(what, sep, __VA_ARGS__)
     81 #define _C4_FOR_EACH_03(what, sep, x, ...) what(x) sep _C4_FOR_EACH_02(what, sep, __VA_ARGS__)
     82 #define _C4_FOR_EACH_04(what, sep, x, ...) what(x) sep _C4_FOR_EACH_03(what, sep, __VA_ARGS__)
     83 #define _C4_FOR_EACH_05(what, sep, x, ...) what(x) sep _C4_FOR_EACH_04(what, sep, __VA_ARGS__)
     84 #define _C4_FOR_EACH_06(what, sep, x, ...) what(x) sep _C4_FOR_EACH_05(what, sep, __VA_ARGS__)
     85 #define _C4_FOR_EACH_07(what, sep, x, ...) what(x) sep _C4_FOR_EACH_06(what, sep, __VA_ARGS__)
     86 #define _C4_FOR_EACH_08(what, sep, x, ...) what(x) sep _C4_FOR_EACH_07(what, sep, __VA_ARGS__)
     87 #define _C4_FOR_EACH_09(what, sep, x, ...) what(x) sep _C4_FOR_EACH_08(what, sep, __VA_ARGS__)
     88 #define _C4_FOR_EACH_10(what, sep, x, ...) what(x) sep _C4_FOR_EACH_09(what, sep, __VA_ARGS__)
     89 #define _C4_FOR_EACH_11(what, sep, x, ...) what(x) sep _C4_FOR_EACH_10(what, sep, __VA_ARGS__)
     90 #define _C4_FOR_EACH_12(what, sep, x, ...) what(x) sep _C4_FOR_EACH_11(what, sep, __VA_ARGS__)
     91 #define _C4_FOR_EACH_13(what, sep, x, ...) what(x) sep _C4_FOR_EACH_12(what, sep, __VA_ARGS__)
     92 #define _C4_FOR_EACH_14(what, sep, x, ...) what(x) sep _C4_FOR_EACH_13(what, sep, __VA_ARGS__)
     93 #define _C4_FOR_EACH_15(what, sep, x, ...) what(x) sep _C4_FOR_EACH_14(what, sep, __VA_ARGS__)
     94 #define _C4_FOR_EACH_16(what, sep, x, ...) what(x) sep _C4_FOR_EACH_15(what, sep, __VA_ARGS__)
     95 #define _C4_FOR_EACH_17(what, sep, x, ...) what(x) sep _C4_FOR_EACH_16(what, sep, __VA_ARGS__)
     96 #define _C4_FOR_EACH_18(what, sep, x, ...) what(x) sep _C4_FOR_EACH_17(what, sep, __VA_ARGS__)
     97 #define _C4_FOR_EACH_19(what, sep, x, ...) what(x) sep _C4_FOR_EACH_18(what, sep, __VA_ARGS__)
     98 #define _C4_FOR_EACH_20(what, sep, x, ...) what(x) sep _C4_FOR_EACH_19(what, sep, __VA_ARGS__)
     99 #define _C4_FOR_EACH_21(what, sep, x, ...) what(x) sep _C4_FOR_EACH_20(what, sep, __VA_ARGS__)
    100 #define _C4_FOR_EACH_22(what, sep, x, ...) what(x) sep _C4_FOR_EACH_21(what, sep, __VA_ARGS__)
    101 #define _C4_FOR_EACH_23(what, sep, x, ...) what(x) sep _C4_FOR_EACH_22(what, sep, __VA_ARGS__)
    102 #define _C4_FOR_EACH_24(what, sep, x, ...) what(x) sep _C4_FOR_EACH_23(what, sep, __VA_ARGS__)
    103 #define _C4_FOR_EACH_25(what, sep, x, ...) what(x) sep _C4_FOR_EACH_24(what, sep, __VA_ARGS__)
    104 #define _C4_FOR_EACH_26(what, sep, x, ...) what(x) sep _C4_FOR_EACH_25(what, sep, __VA_ARGS__)
    105 #define _C4_FOR_EACH_27(what, sep, x, ...) what(x) sep _C4_FOR_EACH_26(what, sep, __VA_ARGS__)
    106 #define _C4_FOR_EACH_28(what, sep, x, ...) what(x) sep _C4_FOR_EACH_27(what, sep, __VA_ARGS__)
    107 #define _C4_FOR_EACH_29(what, sep, x, ...) what(x) sep _C4_FOR_EACH_28(what, sep, __VA_ARGS__)
    108 #define _C4_FOR_EACH_30(what, sep, x, ...) what(x) sep _C4_FOR_EACH_29(what, sep, __VA_ARGS__)
    109 #define _C4_FOR_EACH_31(what, sep, x, ...) what(x) sep _C4_FOR_EACH_30(what, sep, __VA_ARGS__)
    110 #define _C4_FOR_EACH_32(what, sep, x, ...) what(x) sep _C4_FOR_EACH_31(what, sep, __VA_ARGS__)
    111 #define _C4_FOR_EACH_NARG(...) _C4_FOR_EACH_NARG_(__VA_ARGS__, _C4_FOR_EACH_RSEQ_N())
    112 #define _C4_FOR_EACH_NARG_(...) _C4_FOR_EACH_ARG_N(__VA_ARGS__)
    113 #define _C4_FOR_EACH_ARG_N(_01, _02, _03, _04, _05, _06, _07, _08, _09, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, N, ...) N
    114 #define _C4_FOR_EACH_RSEQ_N() 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 09, 08, 07, 06, 05, 04, 03, 02, 01
    115 #define _C4_FOR_EACH_(N, what, sep, ...) C4_XCAT(_C4_FOR_EACH_, N)(what, sep, __VA_ARGS__)
    116 
    117 /// @endcond
    118 
    119 #ifdef __clang__
    120 #   pragma clang diagnostic pop
    121 #endif
    122 
    123 #endif /* _C4_PREPROCESSOR_HPP_ */