AUI Framework  master
Cross-platform base for C++ UI apps
Loading...
Searching...
No Matches
APreprocessor.h
    1/*
    2 * AUI Framework - Declarative UI toolkit for modern C++20
    3 * Copyright (C) 2020-2025 Alex2772 and Contributors
    4 *
    5 * SPDX-License-Identifier: MPL-2.0
    6 *
    7 * This Source Code Form is subject to the terms of the Mozilla Public
    8 * License, v. 2.0. If a copy of the MPL was not distributed with this
    9 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
   10 */
   11
   12#pragma once
   13
   14// Code from several projects used here, such as boost and gtest.
   15
   16//NOLINTBEGIN(modernize-*,cppcoreguidelines-macro-*)
   17
   22#define AUI_PP_CAT(_1, _2) AUI_PP_INTERNAL_CAT(_1, _2)
   23
   28#define AUI_PP_STRINGIZE(...) AUI_PP_INTERNAL_STRINGIZE(__VA_ARGS__)
   29
   34#define AUI_PP_EMPTY(...)
   35
   40#define AUI_PP_COMMA(...) ,
   41
   46#define AUI_PP_IDENTITY(_1) _1
   47
   63#define AUI_PP_NARG(...) \
   64  AUI_PP_INTERNAL_16TH(  \
   65      (__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
   66
   72#define AUI_PP_HAS_COMMA(...) \
   73  AUI_PP_INTERNAL_16TH(       \
   74      (__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0))
   75
   80#define AUI_PP_HEAD(...) AUI_PP_INTERNAL_HEAD((__VA_ARGS__, unusedArg))
   81
   88#define AUI_PP_TAIL(...) AUI_PP_INTERNAL_TAIL((__VA_ARGS__))
   89
   94#define AUI_PP_VARIADIC_CALL(_Macro, ...) \
   95  AUI_PP_IDENTITY(                        \
   96      AUI_PP_CAT(_Macro, AUI_PP_NARG(__VA_ARGS__))(__VA_ARGS__))
   97
  128#define AUI_PP_IS_EMPTY(...)                                               \
  129  AUI_PP_INTERNAL_IS_EMPTY(AUI_PP_HAS_COMMA(__VA_ARGS__),                \
  130                             AUI_PP_HAS_COMMA(AUI_PP_COMMA __VA_ARGS__), \
  131                             AUI_PP_HAS_COMMA(__VA_ARGS__()),              \
  132                             AUI_PP_HAS_COMMA(AUI_PP_COMMA __VA_ARGS__()))
  133
  138#define AUI_PP_IF(_Cond, _Then, _Else) \
  139  AUI_PP_CAT(AUI_PP_INTERNAL_IF_, _Cond)(_Then, _Else)
  140
  150#define AUI_PP_GENERIC_IF(_Cond, _Then, _Else) \
  151  AUI_PP_REMOVE_PARENS(AUI_PP_IF(_Cond, _Then, _Else))
  152
  170#define AUI_PP_NARG0(...) \
  171  AUI_PP_IF(AUI_PP_IS_EMPTY(__VA_ARGS__), 0, AUI_PP_NARG(__VA_ARGS__))
  172
  177#define AUI_PP_IS_BEGIN_PARENS(...)                              \
  178  AUI_PP_HEAD(AUI_PP_CAT(AUI_PP_INTERNAL_IBP_IS_VARIADIC_R_, \
  179                             AUI_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
  180
  185#define AUI_PP_IS_ENCLOSED_PARENS(...)             \
  186  AUI_PP_IF(AUI_PP_IS_BEGIN_PARENS(__VA_ARGS__), \
  187              AUI_PP_IS_EMPTY(AUI_PP_EMPTY __VA_ARGS__), 0)
  188
  193#define AUI_PP_REMOVE_PARENS(...) AUI_PP_INTERNAL_REMOVE_PARENS __VA_ARGS__
  194
  203#define AUI_PP_FOR_EACH(_Macro, _Data, _Tuple)                        \
  204  AUI_PP_CAT(AUI_PP_INTERNAL_FOR_EACH_IMPL_, AUI_PP_NARG0 _Tuple) \
  205  (0, _Macro, _Data, _Tuple)
  206
  216#define AUI_PP_REPEAT(_Macro, _Data, _N)           \
  217  AUI_PP_CAT(AUI_PP_INTERNAL_FOR_EACH_IMPL_, _N) \
  218  (0, _Macro, _Data, AUI_PP_INTENRAL_EMPTY_TUPLE)
  219
  224#define AUI_PP_INC(_i) AUI_PP_CAT(AUI_PP_INTERNAL_INC_, _i)
  225
  230#define AUI_PP_COMMA_IF(_i) AUI_PP_CAT(AUI_PP_INTERNAL_COMMA_IF_, _i)
  231
  232/*
  233 * Internal details follow. Do not use any of these symbols outside of this file or we will break your code.
  234 */
  235#define AUI_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )
  236#define AUI_PP_INTERNAL_CAT(_1, _2) _1##_2
  237#define AUI_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__
  238#define AUI_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5
  239#define AUI_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4)                             \
  240  AUI_PP_HAS_COMMA(AUI_PP_INTERNAL_CAT_5(AUI_PP_INTERNAL_IS_EMPTY_CASE_, \
  241                                             _1, _2, _3, _4))
  242#define AUI_PP_INTERNAL_IS_EMPTY_CASE_0001 ,
  243#define AUI_PP_INTERNAL_IF_1(_Then, _Else) _Then
  244#define AUI_PP_INTERNAL_IF_0(_Then, _Else) _Else
  245
  246// Because of MSVC treating a token with a comma in it as a single token when
  247// passed to another macro, we need to force it to evaluate it as multiple
  248// tokens. We do that by using a "IDENTITY(MACRO PARENTHESIZED_ARGS)" macro. We
  249// define one per possible macro that relies on this behavior. Note "_Args" must
  250// be parenthesized.
  251#define AUI_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \
  252                                        _10, _11, _12, _13, _14, _15, _16,  \
  253                                        ...)                                \
  254  _16
  255#define AUI_PP_INTERNAL_16TH(_Args) \
  256  AUI_PP_IDENTITY(AUI_PP_INTERNAL_INTERNAL_16TH _Args)
  257#define AUI_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1
  258#define AUI_PP_INTERNAL_HEAD(_Args) \
  259  AUI_PP_IDENTITY(AUI_PP_INTERNAL_INTERNAL_HEAD _Args)
  260#define AUI_PP_INTERNAL_INTERNAL_TAIL(_1, ...) __VA_ARGS__
  261#define AUI_PP_INTERNAL_TAIL(_Args) \
  262  AUI_PP_IDENTITY(AUI_PP_INTERNAL_INTERNAL_TAIL _Args)
  263
  264#define AUI_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _
  265#define AUI_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,
  266#define AUI_PP_INTERNAL_IBP_IS_VARIADIC_R_AUI_PP_INTERNAL_IBP_IS_VARIADIC_C \
  267  0,
  268#define AUI_PP_INTERNAL_REMOVE_PARENS(...) __VA_ARGS__
  269#define AUI_PP_INTERNAL_INC_0 1
  270#define AUI_PP_INTERNAL_INC_1 2
  271#define AUI_PP_INTERNAL_INC_2 3
  272#define AUI_PP_INTERNAL_INC_3 4
  273#define AUI_PP_INTERNAL_INC_4 5
  274#define AUI_PP_INTERNAL_INC_5 6
  275#define AUI_PP_INTERNAL_INC_6 7
  276#define AUI_PP_INTERNAL_INC_7 8
  277#define AUI_PP_INTERNAL_INC_8 9
  278#define AUI_PP_INTERNAL_INC_9 10
  279#define AUI_PP_INTERNAL_INC_10 11
  280#define AUI_PP_INTERNAL_INC_11 12
  281#define AUI_PP_INTERNAL_INC_12 13
  282#define AUI_PP_INTERNAL_INC_13 14
  283#define AUI_PP_INTERNAL_INC_14 15
  284#define AUI_PP_INTERNAL_INC_15 16
  285#define AUI_PP_INTERNAL_COMMA_IF_0
  286#define AUI_PP_INTERNAL_COMMA_IF_1 ,
  287#define AUI_PP_INTERNAL_COMMA_IF_2 ,
  288#define AUI_PP_INTERNAL_COMMA_IF_3 ,
  289#define AUI_PP_INTERNAL_COMMA_IF_4 ,
  290#define AUI_PP_INTERNAL_COMMA_IF_5 ,
  291#define AUI_PP_INTERNAL_COMMA_IF_6 ,
  292#define AUI_PP_INTERNAL_COMMA_IF_7 ,
  293#define AUI_PP_INTERNAL_COMMA_IF_8 ,
  294#define AUI_PP_INTERNAL_COMMA_IF_9 ,
  295#define AUI_PP_INTERNAL_COMMA_IF_10 ,
  296#define AUI_PP_INTERNAL_COMMA_IF_11 ,
  297#define AUI_PP_INTERNAL_COMMA_IF_12 ,
  298#define AUI_PP_INTERNAL_COMMA_IF_13 ,
  299#define AUI_PP_INTERNAL_COMMA_IF_14 ,
  300#define AUI_PP_INTERNAL_COMMA_IF_15 ,
  301#define AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, _element) \
  302  _Macro(_i, _Data, _element)
  303#define AUI_PP_INTERNAL_FOR_EACH_IMPL_0(_i, _Macro, _Data, _Tuple)
  304#define AUI_PP_INTERNAL_FOR_EACH_IMPL_1(_i, _Macro, _Data, _Tuple) \
  305  AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, AUI_PP_HEAD _Tuple)
  306#define AUI_PP_INTERNAL_FOR_EACH_IMPL_2(_i, _Macro, _Data, _Tuple)    \
  307  AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, AUI_PP_HEAD _Tuple) \
  308  AUI_PP_INTERNAL_FOR_EACH_IMPL_1(AUI_PP_INC(_i), _Macro, _Data,    \
  309                                    (AUI_PP_TAIL _Tuple))
  310#define AUI_PP_INTERNAL_FOR_EACH_IMPL_3(_i, _Macro, _Data, _Tuple)    \
  311  AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, AUI_PP_HEAD _Tuple) \
  312  AUI_PP_INTERNAL_FOR_EACH_IMPL_2(AUI_PP_INC(_i), _Macro, _Data,    \
  313                                    (AUI_PP_TAIL _Tuple))
  314#define AUI_PP_INTERNAL_FOR_EACH_IMPL_4(_i, _Macro, _Data, _Tuple)    \
  315  AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, AUI_PP_HEAD _Tuple) \
  316  AUI_PP_INTERNAL_FOR_EACH_IMPL_3(AUI_PP_INC(_i), _Macro, _Data,    \
  317                                    (AUI_PP_TAIL _Tuple))
  318#define AUI_PP_INTERNAL_FOR_EACH_IMPL_5(_i, _Macro, _Data, _Tuple)    \
  319  AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, AUI_PP_HEAD _Tuple) \
  320  AUI_PP_INTERNAL_FOR_EACH_IMPL_4(AUI_PP_INC(_i), _Macro, _Data,    \
  321                                    (AUI_PP_TAIL _Tuple))
  322#define AUI_PP_INTERNAL_FOR_EACH_IMPL_6(_i, _Macro, _Data, _Tuple)    \
  323  AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, AUI_PP_HEAD _Tuple) \
  324  AUI_PP_INTERNAL_FOR_EACH_IMPL_5(AUI_PP_INC(_i), _Macro, _Data,    \
  325                                    (AUI_PP_TAIL _Tuple))
  326#define AUI_PP_INTERNAL_FOR_EACH_IMPL_7(_i, _Macro, _Data, _Tuple)    \
  327  AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, AUI_PP_HEAD _Tuple) \
  328  AUI_PP_INTERNAL_FOR_EACH_IMPL_6(AUI_PP_INC(_i), _Macro, _Data,    \
  329                                    (AUI_PP_TAIL _Tuple))
  330#define AUI_PP_INTERNAL_FOR_EACH_IMPL_8(_i, _Macro, _Data, _Tuple)    \
  331  AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, AUI_PP_HEAD _Tuple) \
  332  AUI_PP_INTERNAL_FOR_EACH_IMPL_7(AUI_PP_INC(_i), _Macro, _Data,    \
  333                                    (AUI_PP_TAIL _Tuple))
  334#define AUI_PP_INTERNAL_FOR_EACH_IMPL_9(_i, _Macro, _Data, _Tuple)    \
  335  AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, AUI_PP_HEAD _Tuple) \
  336  AUI_PP_INTERNAL_FOR_EACH_IMPL_8(AUI_PP_INC(_i), _Macro, _Data,    \
  337                                    (AUI_PP_TAIL _Tuple))
  338#define AUI_PP_INTERNAL_FOR_EACH_IMPL_10(_i, _Macro, _Data, _Tuple)   \
  339  AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, AUI_PP_HEAD _Tuple) \
  340  AUI_PP_INTERNAL_FOR_EACH_IMPL_9(AUI_PP_INC(_i), _Macro, _Data,    \
  341                                    (AUI_PP_TAIL _Tuple))
  342#define AUI_PP_INTERNAL_FOR_EACH_IMPL_11(_i, _Macro, _Data, _Tuple)   \
  343  AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, AUI_PP_HEAD _Tuple) \
  344  AUI_PP_INTERNAL_FOR_EACH_IMPL_10(AUI_PP_INC(_i), _Macro, _Data,   \
  345                                     (AUI_PP_TAIL _Tuple))
  346#define AUI_PP_INTERNAL_FOR_EACH_IMPL_12(_i, _Macro, _Data, _Tuple)   \
  347  AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, AUI_PP_HEAD _Tuple) \
  348  AUI_PP_INTERNAL_FOR_EACH_IMPL_11(AUI_PP_INC(_i), _Macro, _Data,   \
  349                                     (AUI_PP_TAIL _Tuple))
  350#define AUI_PP_INTERNAL_FOR_EACH_IMPL_13(_i, _Macro, _Data, _Tuple)   \
  351  AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, AUI_PP_HEAD _Tuple) \
  352  AUI_PP_INTERNAL_FOR_EACH_IMPL_12(AUI_PP_INC(_i), _Macro, _Data,   \
  353                                     (AUI_PP_TAIL _Tuple))
  354#define AUI_PP_INTERNAL_FOR_EACH_IMPL_14(_i, _Macro, _Data, _Tuple)   \
  355  AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, AUI_PP_HEAD _Tuple) \
  356  AUI_PP_INTERNAL_FOR_EACH_IMPL_13(AUI_PP_INC(_i), _Macro, _Data,   \
  357                                     (AUI_PP_TAIL _Tuple))
  358#define AUI_PP_INTERNAL_FOR_EACH_IMPL_15(_i, _Macro, _Data, _Tuple)   \
  359  AUI_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, AUI_PP_HEAD _Tuple) \
  360  AUI_PP_INTERNAL_FOR_EACH_IMPL_14(AUI_PP_INC(_i), _Macro, _Data,   \
  361                                     (AUI_PP_TAIL _Tuple))
  362
  363//NOLINTEND(modernize-*,cppcoreguidelines-macro-*)