#ifndef THIS_IS_MACRO_EXPAND_HELLO_THERE
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#endif
static void EmptyCall(){}
#define EXPAND(X) X
#define REMOVEBRACKET(...) __VA_ARGS__
#define TOSTRING_(a) #a
#define TOSTRING(a) TOSTRING_(a)
#define NUM_ARGS_(X32, X31, X30, X29, X28, X27, X26, X25, \
X24, X23, X22, X21, X20, X19, X18, X17, X16, X15, X14, X13, \
X12, X11, X10, X9, X8, X7, X6, X5, X4, X3, X2, X1, N, ...) N
#define NUM_ARGS(...) EXPAND(NUM_ARGS_(__VA_ARGS__, 32, 31, 30, \
29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, \
15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1))
#define FIRSTARG(X, ...) (X)
#define RESTARGS(X, ...) (__VA_ARGS__)
#define FIRSTTWOARG(X, Y, ...) (X,Y)
#define RESTTWOARG(X, Y, ...) (__VA_ARGS__)
#define FOREACH(MACRO, ...) FOREACH_(MACRO, (__VA_ARGS__))
#define FOREACH_(MACRO, ...) FOREACH__(NUM_ARGS __VA_ARGS__, MACRO, __VA_ARGS__)
#define FOREACH__(N, M, ...) FOREACH___(N, M, __VA_ARGS__)
#define FOREACH___(N, M, ...) FOREACH_##N(M, __VA_ARGS__)
#define FOREACH_1(M, ...) M __VA_ARGS__
#define FOREACH_2(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_1(M, RESTARGS __VA_ARGS__)
#define FOREACH_3(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_2(M, RESTARGS __VA_ARGS__)
#define FOREACH_4(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_3(M, RESTARGS __VA_ARGS__)
#define FOREACH_5(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_4(M, RESTARGS __VA_ARGS__)
#define FOREACH_6(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_5(M, RESTARGS __VA_ARGS__)
#define FOREACH_7(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_6(M, RESTARGS __VA_ARGS__)
#define FOREACH_8(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_7(M, RESTARGS __VA_ARGS__)
#define FOREACH_9(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_8(M, RESTARGS __VA_ARGS__)
#define FOREACH_10(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_9(M, RESTARGS __VA_ARGS__)
#define FOREACH_11(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_10(M, RESTARGS __VA_ARGS__)
#define FOREACH_12(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_11(M, RESTARGS __VA_ARGS__)
#define FOREACH_13(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_12(M, RESTARGS __VA_ARGS__)
#define FOREACH_14(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_13(M, RESTARGS __VA_ARGS__)
#define FOREACH_15(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_14(M, RESTARGS __VA_ARGS__)
#define FOREACH_16(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_15(M, RESTARGS __VA_ARGS__)
#define FOREACH_17(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_16(M, RESTARGS __VA_ARGS__)
#define FOREACH_18(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_17(M, RESTARGS __VA_ARGS__)
#define FOREACH_19(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_18(M, RESTARGS __VA_ARGS__)
#define FOREACH_20(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_19(M, RESTARGS __VA_ARGS__)
#define FOREACH_21(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_20(M, RESTARGS __VA_ARGS__)
#define FOREACH_22(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_21(M, RESTARGS __VA_ARGS__)
#define FOREACH_23(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_22(M, RESTARGS __VA_ARGS__)
#define FOREACH_24(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_23(M, RESTARGS __VA_ARGS__)
#define FOREACH_25(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_24(M, RESTARGS __VA_ARGS__)
#define FOREACH_26(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_25(M, RESTARGS __VA_ARGS__)
#define FOREACH_27(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_26(M, RESTARGS __VA_ARGS__)
#define FOREACH_28(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_27(M, RESTARGS __VA_ARGS__)
#define FOREACH_29(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_28(M, RESTARGS __VA_ARGS__)
#define FOREACH_30(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_29(M, RESTARGS __VA_ARGS__)
#define FOREACH_31(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_30(M, RESTARGS __VA_ARGS__)
#define FOREACH_32(M, ...) EXPAND(M FIRSTARG __VA_ARGS__) FOREACH_31(M, RESTARGS __VA_ARGS__)
#define FOLD(MACRO, ...) FOLD_(MACRO, (__VA_ARGS__))
#define FOLD_(MACRO, ...) FOLD__(NUM_ARGS __VA_ARGS__, MACRO, __VA_ARGS__)
#define FOLD__(N, M, ...) FOLD___(N, M, __VA_ARGS__)
#define FOLD___(N, M, ...) FOLD____(N, M, (EXPAND(M FIRSTTWOARG __VA_ARGS__),EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD____(N, M, ...) FOLD_##N(M, __VA_ARGS__)
#define FOLD_END(RESULT) RESULT
#define FOLD_2__(...) FOLD_END(EXPAND(REMOVEBRACKET __VA_ARGS__))
#define FOLD_2_(M, ...) FOLD_2__(FIRSTARG (__VA_ARGS__))
#define FOLD_2(M, ...) FOLD_2_( M, EXPAND(REMOVEBRACKET __VA_ARGS__) )
#define FOLD_3_(M, ...) FOLD_END(EXPAND __VA_ARGS__)
#define FOLD_3(M, ...) FOLD_3_( M, ( M FIRSTTWOARG __VA_ARGS__))
#define FOLD_4_(M, ...) FOLD_3(M,__VA_ARGS__)
#define FOLD_4(M, ...) FOLD_4_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_5_(M, ...) FOLD_4(M,__VA_ARGS__)
#define FOLD_5(M, ...) FOLD_5_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_6_(M, ...) FOLD_5(M,__VA_ARGS__)
#define FOLD_6(M, ...) FOLD_6_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_7_(M, ...) FOLD_6(M,__VA_ARGS__)
#define FOLD_7(M, ...) FOLD_7_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_8_(M, ...) FOLD_7(M,__VA_ARGS__)
#define FOLD_8(M, ...) FOLD_8_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_9_(M, ...) FOLD_8(M,__VA_ARGS__)
#define FOLD_9(M, ...) FOLD_9_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_10_(M, ...) FOLD_9(M,__VA_ARGS__)
#define FOLD_10(M, ...) FOLD_10_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_11_(M, ...) FOLD_10(M,__VA_ARGS__)
#define FOLD_11(M, ...) FOLD_11_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_12_(M, ...) FOLD_11(M,__VA_ARGS__)
#define FOLD_12(M, ...) FOLD_12_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_13_(M, ...) FOLD_12(M,__VA_ARGS__)
#define FOLD_13(M, ...) FOLD_13_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_14_(M, ...) FOLD_13(M,__VA_ARGS__)
#define FOLD_14(M, ...) FOLD_14_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_15_(M, ...) FOLD_14(M,__VA_ARGS__)
#define FOLD_15(M, ...) FOLD_15_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_16_(M, ...) FOLD_15(M,__VA_ARGS__)
#define FOLD_16(M, ...) FOLD_16_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_17_(M, ...) FOLD_16(M,__VA_ARGS__)
#define FOLD_17(M, ...) FOLD_17_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_18_(M, ...) FOLD_17(M,__VA_ARGS__)
#define FOLD_18(M, ...) FOLD_18_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_19_(M, ...) FOLD_18(M,__VA_ARGS__)
#define FOLD_19(M, ...) FOLD_19_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_20_(M, ...) FOLD_19(M,__VA_ARGS__)
#define FOLD_20(M, ...) FOLD_20_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_21_(M, ...) FOLD_20(M,__VA_ARGS__)
#define FOLD_21(M, ...) FOLD_21_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_22_(M, ...) FOLD_21(M,__VA_ARGS__)
#define FOLD_22(M, ...) FOLD_22_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_23_(M, ...) FOLD_22(M,__VA_ARGS__)
#define FOLD_23(M, ...) FOLD_23_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_24_(M, ...) FOLD_23(M,__VA_ARGS__)
#define FOLD_24(M, ...) FOLD_24_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_25_(M, ...) FOLD_24(M,__VA_ARGS__)
#define FOLD_25(M, ...) FOLD_25_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_26_(M, ...) FOLD_25(M,__VA_ARGS__)
#define FOLD_26(M, ...) FOLD_26_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_27_(M, ...) FOLD_26(M,__VA_ARGS__)
#define FOLD_27(M, ...) FOLD_27_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_28_(M, ...) FOLD_27(M,__VA_ARGS__)
#define FOLD_28(M, ...) FOLD_28_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_29_(M, ...) FOLD_28(M,__VA_ARGS__)
#define FOLD_29(M, ...) FOLD_29_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_30_(M, ...) FOLD_29(M,__VA_ARGS__)
#define FOLD_30(M, ...) FOLD_30_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_31_(M, ...) FOLD_30(M,__VA_ARGS__)
#define FOLD_31(M, ...) FOLD_31_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define FOLD_32_(M, ...) FOLD_31(M,__VA_ARGS__)
#define FOLD_32(M, ...) FOLD_32_(M,(M FIRSTTWOARG __VA_ARGS__, EXPAND(REMOVEBRACKET RESTTWOARG __VA_ARGS__)))
#define CONCAT_(a, b) a##b
#define CONCAT(...) FOLD(CONCAT_, __VA_ARGS__)
// Tests
//--------------------------------------------------------------------------------
//FOLD(bar,1,2)
//--------------------------------------------------------------------------------
//FOLD(foo,1,2,3)
//--------------------------------------------------------------------------------
//FOLD(dea,1,2,3,4)
//--------------------------------------------------------------------------------
//CONCAT(a,b)
//--------------------------------------------------------------------------------
//CONCAT(a,b,c)
//--------------------------------------------------------------------------------
//CONCAT(a,b,c,d)
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef char s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef bool b8;
typedef float f32;
typedef double f64;
typedef uintptr_t uptr;
typedef intptr_t sptr;
#define MAX_(a, b) ((a) > (b) ? (a) : (b))
#define MAX(...) FOLD(MAX_, __VA_ARGS__)
struct string{
s32 Size;
s32 Pos;
s8 *String;
};
#define Concat(...) FOLD(Concat_, __VA_ARGS__)
string *Concat_(string *Buffer, s8 *StringIn)
{
for(s32 i = 0, j = Buffer->Pos;
StringIn[i] != 0 && j < Buffer->Size - 1;
++i, ++j, ++Buffer->Pos)
{
Buffer->String[j] = StringIn[i];
}
return Buffer;
}
string *Concat_(string *Buffer, f64 NumberIn)
{
s8 TempBuffer[20];
snprintf(TempBuffer, 20, "%g", NumberIn);
Concat_(Buffer, TempBuffer);
return Buffer;
}
s32 main()
{
string SomeBuffer;
SomeBuffer.Size = 50;
SomeBuffer.Pos = 0;
SomeBuffer.String = (s8 *)calloc(1, 50);
FOLD(Concat_, &SomeBuffer, "tera_", 10.0, "dwera_", 32.07, "tag\n");
printf("String Concat(): %s", SomeBuffer.String);
printf("Macro CONCAT(): " TOSTRING( CONCAT(eple_, 2, _ter_, 9, _ea) ) "\n");
printf("FOLD(): " TOSTRING( FOLD(bar,1,2) ) "\n");
printf("FOLD(): " TOSTRING( FOLD(bar,1,2,3,4) ) "\n");
printf("MAX(): %i\n", MAX(32, 43) );
printf("MAX(): %i\n", MAX(1, 2, 3, 4, 5) );
return 0;
}