based

Opinionated utility library
git clone git://git.dimitrijedobrota.com/based.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

commit 7cae92534482a20a534cc248416b582533a1a01b
parent 3506c973a5e2cff3e6494c34e7feb376990bd72e
author Dimitrije Dobrota < mail@dimitrijedobrota.com >
date Fri, 9 May 2025 17:01:56 +0200

Expand macros, split over multiple files, naming

Diffstat:
M include/based/enum/enum.hpp | ++++++++++++++++++++++++++++ ---------------------------
M include/based/enum/enum_flag.hpp | ++++++++++++++++++++++ ---------------------
M include/based/instrumentation/instrumented.hpp | + -
A include/based/macro/foreach.hpp | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A include/based/macro/foreach_1.hpp | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A include/based/macro/foreach_2.hpp | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A include/based/macro/get_macro.hpp | +++++++++++
D include/based/macro/macros.hpp | ---------------------------------------------------------------------------------
M test/source/enum_flag_test.cpp | + -
M test/source/enum_test.cpp | + -

10 files changed, 302 insertions(+), 138 deletions(-)


diff --git a/ include/based/enum/enum.hpp b/ include/based/enum/enum.hpp

@@ -3,55 +3,56 @@

#include <array>
#include <cassert>

#include "based/macro/macros.hpp"
#include "based/macro/foreach.hpp"
#include "based/macro/foreach_1.hpp"
#include "based/utility/forward.hpp"

// NOLINTBEGIN(*macro-usage*)

#define BASED_LIST_ELEM_STR(Name, Index) #Name,
#define BASED_DETAIL_NUMARGS(...) (std::array {__VA_ARGS__}.size())

#define BASED_LIST_STR(...) BASED_FOREACH(BASED_LIST_ELEM_STR, __VA_ARGS__)
#define BASED_DETAIL_LIST_ELEM_STR(Name, Index) #Name,

#define BASED_DETAIL_LIST_STR(...) \
BASED_FOREACH(BASED_DETAIL_LIST_ELEM_STR, __VA_ARGS__)

// NOLINTNEXTLINE(*macro-parentheses*)
#define BASED_SET(var, val) decltype(var) var = decltype(var) {val};
#define BASED_DETAIL_SET(var, val) decltype(var) var = decltype(var) {val};

#define BASED_DETAIL_ENUM_DECLARE_VAL(Name, Index) static const type Name;
#define BASED_DETAIL_DECLARE_ENUM_VAL(Name, Index) static const type Name;

#define BASED_DETAIL_ENUM_DECLARE_CASE(Qualifier, Name, Index) \
#define BASED_DETAIL_DECLARE_ENUM_CASE(Qualifier, Name, Index) \
case Qualifier::Name.value: \
return Name;

#define BASED_DETAIL_ENUM_DEFINE_VAL(Qualifier, Name, Index) \
inline constexpr BASED_SET( \
#define BASED_DETAIL_DEFINE_ENUM_VAL(Qualifier, Name, Index) \
inline constexpr BASED_DETAIL_SET( \
Qualifier::Name, Qualifier::type::size - (Index) - 1 \
)

#define BASED_DETAIL_ENUM_DEFINE_VALS(Qualifier, ...) \
BASED_FOREACH_1(Qualifier, BASED_DETAIL_ENUM_DEFINE_VAL, __VA_ARGS__)

#define BASED_DETAIL_ENUM_DEFINE_NAMES(Qualifier, ...) \
inline constexpr BASED_SET( \
Qualifier::type::names, BASED_LIST_STR(__VA_ARGS__) \
#define BASED_DETAIL_DEFINE_ENUM_NAMES(Qualifier, ...) \
inline constexpr BASED_DETAIL_SET( \
Qualifier::type::names, BASED_DETAIL_LIST_STR(__VA_ARGS__) \
)

#define BASED_DETAIL_ENUM_DEFINE_GET(Qualifier, Type, ...) \
#define BASED_DETAIL_DEFINE_ENUM_GET(Qualifier, Type, ...) \
inline const Qualifier::type& Qualifier::type::get(Type idx) \
{ \
/* NOLINTNEXTLINE(*paths-covered*) */ \
switch (idx) { \
BASED_FOREACH_1(Qualifier, BASED_DETAIL_ENUM_DECLARE_CASE, __VA_ARGS__) \
BASED_FOREACH_1(Qualifier, BASED_DETAIL_DECLARE_ENUM_CASE, __VA_ARGS__) \
default: \
break; \
} \
assert(0); /* NOLINT(*assert*,cert-dcl03-c) */ \
}

#define BASED_DETAIL_ENUM_DEFINE(Qualifier, Type, ...) \
BASED_DETAIL_ENUM_DEFINE_VALS(Qualifier, __VA_ARGS__) \
BASED_DETAIL_ENUM_DEFINE_NAMES(Qualifier, __VA_ARGS__) \
BASED_DETAIL_ENUM_DEFINE_GET(Qualifier, Type, __VA_ARGS__)
#define BASED_DETAIL_DEFINE_ENUM(Qualifier, Type, ...) \
BASED_FOREACH_1(Qualifier, BASED_DETAIL_DEFINE_ENUM_VAL, __VA_ARGS__) \
BASED_DETAIL_DEFINE_ENUM_NAMES(Qualifier, __VA_ARGS__) \
BASED_DETAIL_DEFINE_ENUM_GET(Qualifier, Type, __VA_ARGS__)

#define BASED_ENUM_DECLARE_ARRAY(Name) \
#define BASED_DECLARE_ENUM_ARRAY(Name) \
template<typename T> \
class array : public std::array<T, Name::type::size> \
{ \

@@ -94,7 +95,7 @@

} \
};

#define BASED_ENUM_DECLARE(Name, Type, ...) \
#define BASED_DECLARE_ENUM(Name, Type, ...) \
struct Name \
{ \
class type \

@@ -109,9 +110,9 @@

public: \
using size_t = Type; \
static constexpr size_t size = \
BASED_NUMARGS(BASED_LIST_STR(__VA_ARGS__)); \
BASED_DETAIL_NUMARGS(BASED_DETAIL_LIST_STR(__VA_ARGS__)); \
\
BASED_ENUM_DECLARE_ARRAY(Name) \
BASED_DECLARE_ENUM_ARRAY(Name) \
static const array<const char*> names; \
\
static const type& get(Type idx); \

@@ -124,13 +125,13 @@

Type value; \
}; \
\
BASED_FOREACH(BASED_DETAIL_ENUM_DECLARE_VAL, __VA_ARGS__) \
BASED_FOREACH(BASED_DETAIL_DECLARE_ENUM_VAL, __VA_ARGS__) \
};

#define BASED_DEFINE_ENUM(Name, Type, ...) \
BASED_DETAIL_ENUM_DEFINE(Name, Type, __VA_ARGS__)
BASED_DETAIL_DEFINE_ENUM(Name, Type, __VA_ARGS__)

#define BASED_DEFINE_ENUM_CLASS(Class, Name, Type, ...) \
BASED_DETAIL_ENUM_DEFINE(Class::Name, Type, __VA_ARGS__)
BASED_DETAIL_DEFINE_ENUM(Class::Name, Type, __VA_ARGS__)

// NOLINTEND(*macro-usage*)

diff --git a/ include/based/enum/enum_flag.hpp b/ include/based/enum/enum_flag.hpp

@@ -2,49 +2,50 @@


#include <cassert>

#include "based/macro/macros.hpp"
#include "based/macro/foreach.hpp"
#include "based/macro/foreach_1.hpp"

// NOLINTBEGIN(*macro-usage*)

#define BASED_LIST_ELEM_STR(Name, Index) #Name,
#define BASED_DETAIL_NUMARGS(...) (std::array {__VA_ARGS__}.size())

#define BASED_LIST_STR(...) BASED_FOREACH(BASED_LIST_ELEM_STR, __VA_ARGS__)
#define BASED_DETAIL_LIST_ELEM_STR(Name, Index) #Name,

#define BASED_DETAIL_LIST_STR(...) \
BASED_FOREACH(BASED_DETAIL_LIST_ELEM_STR, __VA_ARGS__)

// NOLINTNEXTLINE(*macro-parentheses*)
#define BASED_SET(var, val) decltype(var) var = decltype(var) {val};
#define BASED_DETAIL_SET(var, val) decltype(var) var = decltype(var) {val};

#define BASED_DETAIL_ENUM_DECLARE_VAL(Name, Index) static const type Name;
#define BASED_DETAIL_DECLARE_ENUM_VAL(Name, Index) static const type Name;

#define BASED_DETAIL_ENUM_DECLARE_CASE(Qualifier, Name, Index) \
#define BASED_DETAIL_DECLARE_ENUM_CASE(Qualifier, Name, Index) \
case Qualifier::Name.value: \
return Name;

#define BASED_DETAIL_ENUM_DEFINE_FLAG_VAL(Qualifier, Name, Index) \
inline constexpr BASED_SET( \
#define BASED_DETAIL_DEFINE_ENUM_FLAG_VAL(Qualifier, Name, Index) \
inline constexpr BASED_DETAIL_SET( \
Qualifier::Name, \
Qualifier::type::size_t {1} << Qualifier::type::size_t {(Index)} \
)

#define BASED_DETAIL_ENUM_DEFINE_VALS(Qualifier, ...) \
BASED_FOREACH_1(Qualifier, BASED_DETAIL_ENUM_DEFINE_FLAG_VAL, __VA_ARGS__)

#define BASED_DETAIL_ENUM_DEFINE_GET(Qualifier, Type, ...) \
#define BASED_DETAIL_DEFINE_ENUM_GET(Qualifier, Type, ...) \
inline const Qualifier::type& Qualifier::type::get(Type idx) \
{ \
/* NOLINTNEXTLINE(*paths-covered*) */ \
switch (idx) { \
BASED_FOREACH_1(Qualifier, BASED_DETAIL_ENUM_DECLARE_CASE, __VA_ARGS__) \
BASED_FOREACH_1(Qualifier, BASED_DETAIL_DECLARE_ENUM_CASE, __VA_ARGS__) \
default: \
break; \
} \
assert(0); /* NOLINT(*assert*,cert-dcl03-c) */ \
}

#define BASED_DETAIL_ENUM_DEFINE(Qualifier, Type, ...) \
BASED_DETAIL_ENUM_DEFINE_VALS(Qualifier, __VA_ARGS__) \
BASED_DETAIL_ENUM_DEFINE_GET(Qualifier, Type, __VA_ARGS__)
#define BASED_DETAIL_DEFINE_ENUM(Qualifier, Type, ...) \
BASED_FOREACH_1(Qualifier, BASED_DETAIL_DEFINE_ENUM_FLAG_VAL, __VA_ARGS__) \
BASED_DETAIL_DEFINE_ENUM_GET(Qualifier, Type, __VA_ARGS__)

#define BASED_ENUM_DECLARE_FLAG(Name, Type, ...) \
#define BASED_DECLARE_ENUM_FLAG(Name, Type, ...) \
struct Name \
{ \
class type \

@@ -59,7 +60,7 @@

public: \
using size_t = Type; \
static constexpr size_t size = \
BASED_NUMARGS(BASED_LIST_STR(__VA_ARGS__)); \
BASED_DETAIL_NUMARGS(BASED_DETAIL_LIST_STR(__VA_ARGS__)); \
\
static const type& get(Type idx); \
\

@@ -139,13 +140,13 @@

Type value; \
}; \
\
BASED_FOREACH(BASED_DETAIL_ENUM_DECLARE_VAL, __VA_ARGS__) \
BASED_FOREACH(BASED_DETAIL_DECLARE_ENUM_VAL, __VA_ARGS__) \
};

#define BASED_DEFINE_ENUM_FLAG(Name, Type, ...) \
BASED_DETAIL_ENUM_DEFINE(Name, Type, __VA_ARGS__)
BASED_DETAIL_DEFINE_ENUM(Name, Type, __VA_ARGS__)

#define BASED_DEFINE_ENUM_FLAG_CLASS(Class, Name, Type, ...) \
BASED_DETAIL_ENUM_DEFINE(Class::Name, Type, __VA_ARGS__)
BASED_DETAIL_DEFINE_ENUM(Class::Name, Type, __VA_ARGS__)

// NOLINTEND(*macro-usage*)

diff --git a/ include/based/instrumentation/instrumented.hpp b/ include/based/instrumentation/instrumented.hpp

@@ -17,7 +17,7 @@ namespace based


struct instrumented_base
{
BASED_ENUM_DECLARE(
BASED_DECLARE_ENUM(
op,
u8,
n,

diff --git a/ include/based/macro/foreach.hpp b/ include/based/macro/foreach.hpp

@@ -0,0 +1,78 @@

#pragma once

#include "based/macro/get_macro.hpp"

// NOLINTBEGIN(*macro-usage*)

// clang-format off
#define BASED_FE_0(WHAT)
#define BASED_FE_1(WHAT, X) WHAT(X, 0)
#define BASED_FE_2(WHAT, X, ...) WHAT(X, 1) BASED_FE_1(WHAT, __VA_ARGS__)
#define BASED_FE_3(WHAT, X, ...) WHAT(X, 2) BASED_FE_2(WHAT, __VA_ARGS__)
#define BASED_FE_4(WHAT, X, ...) WHAT(X, 3) BASED_FE_3(WHAT, __VA_ARGS__)
#define BASED_FE_5(WHAT, X, ...) WHAT(X, 4) BASED_FE_4(WHAT, __VA_ARGS__)
#define BASED_FE_6(WHAT, X, ...) WHAT(X, 5) BASED_FE_5(WHAT, __VA_ARGS__)
#define BASED_FE_7(WHAT, X, ...) WHAT(X, 6) BASED_FE_6(WHAT, __VA_ARGS__)
#define BASED_FE_8(WHAT, X, ...) WHAT(X, 7) BASED_FE_7(WHAT, __VA_ARGS__)
#define BASED_FE_9(WHAT, X, ...) WHAT(X, 8) BASED_FE_8(WHAT, __VA_ARGS__)
#define BASED_FE_10(WHAT, X, ...) WHAT(X, 9) BASED_FE_9(WHAT, __VA_ARGS__)
#define BASED_FE_11(WHAT, X, ...) WHAT(X, 10) BASED_FE_10(WHAT, __VA_ARGS__)
#define BASED_FE_12(WHAT, X, ...) WHAT(X, 11) BASED_FE_11(WHAT, __VA_ARGS__)
#define BASED_FE_13(WHAT, X, ...) WHAT(X, 12) BASED_FE_12(WHAT, __VA_ARGS__)
#define BASED_FE_14(WHAT, X, ...) WHAT(X, 13) BASED_FE_13(WHAT, __VA_ARGS__)
#define BASED_FE_15(WHAT, X, ...) WHAT(X, 14) BASED_FE_14(WHAT, __VA_ARGS__)
#define BASED_FE_16(WHAT, X, ...) WHAT(X, 15) BASED_FE_15(WHAT, __VA_ARGS__)
#define BASED_FE_17(WHAT, X, ...) WHAT(X, 16) BASED_FE_16(WHAT, __VA_ARGS__)
#define BASED_FE_18(WHAT, X, ...) WHAT(X, 17) BASED_FE_17(WHAT, __VA_ARGS__)
#define BASED_FE_19(WHAT, X, ...) WHAT(X, 18) BASED_FE_18(WHAT, __VA_ARGS__)
#define BASED_FE_20(WHAT, X, ...) WHAT(X, 19) BASED_FE_19(WHAT, __VA_ARGS__)
#define BASED_FE_21(WHAT, X, ...) WHAT(X, 20) BASED_FE_20(WHAT, __VA_ARGS__)
#define BASED_FE_22(WHAT, X, ...) WHAT(X, 21) BASED_FE_21(WHAT, __VA_ARGS__)
#define BASED_FE_23(WHAT, X, ...) WHAT(X, 22) BASED_FE_22(WHAT, __VA_ARGS__)
#define BASED_FE_24(WHAT, X, ...) WHAT(X, 23) BASED_FE_23(WHAT, __VA_ARGS__)
#define BASED_FE_25(WHAT, X, ...) WHAT(X, 24) BASED_FE_24(WHAT, __VA_ARGS__)
#define BASED_FE_26(WHAT, X, ...) WHAT(X, 25) BASED_FE_25(WHAT, __VA_ARGS__)
#define BASED_FE_27(WHAT, X, ...) WHAT(X, 26) BASED_FE_26(WHAT, __VA_ARGS__)
#define BASED_FE_28(WHAT, X, ...) WHAT(X, 27) BASED_FE_27(WHAT, __VA_ARGS__)
#define BASED_FE_29(WHAT, X, ...) WHAT(X, 28) BASED_FE_28(WHAT, __VA_ARGS__)
#define BASED_FE_30(WHAT, X, ...) WHAT(X, 29) BASED_FE_29(WHAT, __VA_ARGS__)
#define BASED_FE_31(WHAT, X, ...) WHAT(X, 30) BASED_FE_30(WHAT, __VA_ARGS__)
#define BASED_FE_32(WHAT, X, ...) WHAT(X, 31) BASED_FE_31(WHAT, __VA_ARGS__)
#define BASED_FE_33(WHAT, X, ...) WHAT(X, 32) BASED_FE_32(WHAT, __VA_ARGS__)
#define BASED_FE_34(WHAT, X, ...) WHAT(X, 33) BASED_FE_33(WHAT, __VA_ARGS__)
#define BASED_FE_35(WHAT, X, ...) WHAT(X, 34) BASED_FE_34(WHAT, __VA_ARGS__)
#define BASED_FE_36(WHAT, X, ...) WHAT(X, 35) BASED_FE_35(WHAT, __VA_ARGS__)
#define BASED_FE_37(WHAT, X, ...) WHAT(X, 36) BASED_FE_36(WHAT, __VA_ARGS__)
#define BASED_FE_38(WHAT, X, ...) WHAT(X, 37) BASED_FE_37(WHAT, __VA_ARGS__)
#define BASED_FE_39(WHAT, X, ...) WHAT(X, 38) BASED_FE_38(WHAT, __VA_ARGS__)
#define BASED_FE_40(WHAT, X, ...) WHAT(X, 39) BASED_FE_39(WHAT, __VA_ARGS__)
#define BASED_FE_41(WHAT, X, ...) WHAT(X, 40) BASED_FE_40(WHAT, __VA_ARGS__)
#define BASED_FE_42(WHAT, X, ...) WHAT(X, 41) BASED_FE_41(WHAT, __VA_ARGS__)
#define BASED_FE_43(WHAT, X, ...) WHAT(X, 42) BASED_FE_42(WHAT, __VA_ARGS__)
#define BASED_FE_44(WHAT, X, ...) WHAT(X, 43) BASED_FE_43(WHAT, __VA_ARGS__)
#define BASED_FE_45(WHAT, X, ...) WHAT(X, 44) BASED_FE_44(WHAT, __VA_ARGS__)
#define BASED_FE_46(WHAT, X, ...) WHAT(X, 45) BASED_FE_45(WHAT, __VA_ARGS__)
#define BASED_FE_47(WHAT, X, ...) WHAT(X, 46) BASED_FE_46(WHAT, __VA_ARGS__)
#define BASED_FE_48(WHAT, X, ...) WHAT(X, 47) BASED_FE_47(WHAT, __VA_ARGS__)
#define BASED_FE_49(WHAT, X, ...) WHAT(X, 48) BASED_FE_48(WHAT, __VA_ARGS__)
#define BASED_FE_50(WHAT, X, ...) WHAT(X, 49) BASED_FE_49(WHAT, __VA_ARGS__)
#define BASED_FE_51(WHAT, X, ...) WHAT(X, 50) BASED_FE_50(WHAT, __VA_ARGS__)
#define BASED_FE_52(WHAT, X, ...) WHAT(X, 51) BASED_FE_51(WHAT, __VA_ARGS__)
#define BASED_FE_53(WHAT, X, ...) WHAT(X, 52) BASED_FE_52(WHAT, __VA_ARGS__)
#define BASED_FE_54(WHAT, X, ...) WHAT(X, 53) BASED_FE_53(WHAT, __VA_ARGS__)
#define BASED_FE_55(WHAT, X, ...) WHAT(X, 54) BASED_FE_54(WHAT, __VA_ARGS__)
#define BASED_FE_56(WHAT, X, ...) WHAT(X, 55) BASED_FE_55(WHAT, __VA_ARGS__)
#define BASED_FE_57(WHAT, X, ...) WHAT(X, 56) BASED_FE_56(WHAT, __VA_ARGS__)
#define BASED_FE_58(WHAT, X, ...) WHAT(X, 57) BASED_FE_57(WHAT, __VA_ARGS__)
#define BASED_FE_59(WHAT, X, ...) WHAT(X, 58) BASED_FE_58(WHAT, __VA_ARGS__)
#define BASED_FE_60(WHAT, X, ...) WHAT(X, 59) BASED_FE_59(WHAT, __VA_ARGS__)
#define BASED_FE_61(WHAT, X, ...) WHAT(X, 60) BASED_FE_60(WHAT, __VA_ARGS__)
#define BASED_FE_62(WHAT, X, ...) WHAT(X, 61) BASED_FE_61(WHAT, __VA_ARGS__)
#define BASED_FE_63(WHAT, X, ...) WHAT(X, 62) BASED_FE_62(WHAT, __VA_ARGS__)
#define BASED_FE_64(WHAT, X, ...) WHAT(X, 63) BASED_FE_63(WHAT, __VA_ARGS__)
// clang-format on

#define BASED_FOREACH(action, ...) \
BASED_GET_MACRO(_0, __VA_ARGS__, BASED_FE_64, BASED_FE_63, BASED_FE_62, BASED_FE_61, BASED_FE_60, BASED_FE_59, BASED_FE_58, BASED_FE_57, BASED_FE_56, BASED_FE_55, BASED_FE_54, BASED_FE_53, BASED_FE_52, BASED_FE_51, BASED_FE_50, BASED_FE_49, BASED_FE_48, BASED_FE_47, BASED_FE_46, BASED_FE_45, BASED_FE_44, BASED_FE_43, BASED_FE_42, BASED_FE_41, BASED_FE_40, BASED_FE_39, BASED_FE_38, BASED_FE_37, BASED_FE_36, BASED_FE_35, BASED_FE_34, BASED_FE_33, BASED_FE_32, BASED_FE_31, BASED_FE_30, BASED_FE_29, BASED_FE_28, BASED_FE_27, BASED_FE_26, BASED_FE_25, BASED_FE_24, BASED_FE_23, BASED_FE_22, BASED_FE_21, BASED_FE_20, BASED_FE_19, BASED_FE_18, BASED_FE_17, BASED_FE_16, BASED_FE_15, BASED_FE_14, BASED_FE_13, BASED_FE_12, BASED_FE_11, BASED_FE_10, BASED_FE_9, BASED_FE_8, BASED_FE_7, BASED_FE_6, BASED_FE_5, BASED_FE_4, BASED_FE_3, BASED_FE_2, BASED_FE_1, BASED_FE_0)(action, __VA_ARGS__)

// NOLINTEND(*macro-usage*)

diff --git a/ include/based/macro/foreach_1.hpp b/ include/based/macro/foreach_1.hpp

@@ -0,0 +1,80 @@

#pragma once

#include "based/macro/get_macro.hpp"

// NOLINTBEGIN(*macro-usage*)

// clang-format off
#define BASED_FE_0_1(First, WHAT)
#define BASED_FE_1_1(First, WHAT, X) WHAT(First, X, 0)
#define BASED_FE_2_1(First, WHAT, X, ...) WHAT(First, X, 1) BASED_FE_1_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_3_1(First, WHAT, X, ...) WHAT(First, X, 2) BASED_FE_2_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_4_1(First, WHAT, X, ...) WHAT(First, X, 3) BASED_FE_3_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_5_1(First, WHAT, X, ...) WHAT(First, X, 4) BASED_FE_4_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_6_1(First, WHAT, X, ...) WHAT(First, X, 5) BASED_FE_5_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_7_1(First, WHAT, X, ...) WHAT(First, X, 6) BASED_FE_6_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_8_1(First, WHAT, X, ...) WHAT(First, X, 7) BASED_FE_7_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_9_1(First, WHAT, X, ...) WHAT(First, X, 8) BASED_FE_8_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_10_1(First, WHAT, X, ...) WHAT(First, X, 9) BASED_FE_9_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_11_1(First, WHAT, X, ...) WHAT(First, X, 10) BASED_FE_10_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_12_1(First, WHAT, X, ...) WHAT(First, X, 11) BASED_FE_11_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_13_1(First, WHAT, X, ...) WHAT(First, X, 12) BASED_FE_12_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_14_1(First, WHAT, X, ...) WHAT(First, X, 13) BASED_FE_13_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_15_1(First, WHAT, X, ...) WHAT(First, X, 14) BASED_FE_14_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_16_1(First, WHAT, X, ...) WHAT(First, X, 15) BASED_FE_15_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_17_1(First, WHAT, X, ...) WHAT(First, X, 16) BASED_FE_16_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_18_1(First, WHAT, X, ...) WHAT(First, X, 17) BASED_FE_17_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_19_1(First, WHAT, X, ...) WHAT(First, X, 18) BASED_FE_18_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_20_1(First, WHAT, X, ...) WHAT(First, X, 19) BASED_FE_19_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_21_1(First, WHAT, X, ...) WHAT(First, X, 20) BASED_FE_20_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_22_1(First, WHAT, X, ...) WHAT(First, X, 21) BASED_FE_21_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_23_1(First, WHAT, X, ...) WHAT(First, X, 22) BASED_FE_22_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_24_1(First, WHAT, X, ...) WHAT(First, X, 23) BASED_FE_23_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_25_1(First, WHAT, X, ...) WHAT(First, X, 24) BASED_FE_24_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_26_1(First, WHAT, X, ...) WHAT(First, X, 25) BASED_FE_25_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_27_1(First, WHAT, X, ...) WHAT(First, X, 26) BASED_FE_26_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_28_1(First, WHAT, X, ...) WHAT(First, X, 27) BASED_FE_27_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_29_1(First, WHAT, X, ...) WHAT(First, X, 28) BASED_FE_28_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_30_1(First, WHAT, X, ...) WHAT(First, X, 29) BASED_FE_29_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_31_1(First, WHAT, X, ...) WHAT(First, X, 30) BASED_FE_30_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_32_1(First, WHAT, X, ...) WHAT(First, X, 31) BASED_FE_31_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_33_1(First, WHAT, X, ...) WHAT(First, X, 32) BASED_FE_32_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_34_1(First, WHAT, X, ...) WHAT(First, X, 33) BASED_FE_33_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_35_1(First, WHAT, X, ...) WHAT(First, X, 34) BASED_FE_34_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_36_1(First, WHAT, X, ...) WHAT(First, X, 35) BASED_FE_35_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_37_1(First, WHAT, X, ...) WHAT(First, X, 36) BASED_FE_36_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_38_1(First, WHAT, X, ...) WHAT(First, X, 37) BASED_FE_37_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_39_1(First, WHAT, X, ...) WHAT(First, X, 38) BASED_FE_38_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_40_1(First, WHAT, X, ...) WHAT(First, X, 39) BASED_FE_39_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_41_1(First, WHAT, X, ...) WHAT(First, X, 40) BASED_FE_40_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_42_1(First, WHAT, X, ...) WHAT(First, X, 41) BASED_FE_41_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_43_1(First, WHAT, X, ...) WHAT(First, X, 42) BASED_FE_42_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_44_1(First, WHAT, X, ...) WHAT(First, X, 43) BASED_FE_43_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_45_1(First, WHAT, X, ...) WHAT(First, X, 44) BASED_FE_44_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_46_1(First, WHAT, X, ...) WHAT(First, X, 45) BASED_FE_45_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_47_1(First, WHAT, X, ...) WHAT(First, X, 46) BASED_FE_46_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_48_1(First, WHAT, X, ...) WHAT(First, X, 47) BASED_FE_47_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_49_1(First, WHAT, X, ...) WHAT(First, X, 48) BASED_FE_48_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_50_1(First, WHAT, X, ...) WHAT(First, X, 49) BASED_FE_49_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_51_1(First, WHAT, X, ...) WHAT(First, X, 50) BASED_FE_50_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_52_1(First, WHAT, X, ...) WHAT(First, X, 51) BASED_FE_51_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_53_1(First, WHAT, X, ...) WHAT(First, X, 52) BASED_FE_52_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_54_1(First, WHAT, X, ...) WHAT(First, X, 53) BASED_FE_53_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_55_1(First, WHAT, X, ...) WHAT(First, X, 54) BASED_FE_60_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_56_1(First, WHAT, X, ...) WHAT(First, X, 55) BASED_FE_61_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_57_1(First, WHAT, X, ...) WHAT(First, X, 56) BASED_FE_62_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_58_1(First, WHAT, X, ...) WHAT(First, X, 57) BASED_FE_57_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_59_1(First, WHAT, X, ...) WHAT(First, X, 58) BASED_FE_58_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_60_1(First, WHAT, X, ...) WHAT(First, X, 59) BASED_FE_59_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_61_1(First, WHAT, X, ...) WHAT(First, X, 60) BASED_FE_60_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_62_1(First, WHAT, X, ...) WHAT(First, X, 61) BASED_FE_61_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_63_1(First, WHAT, X, ...) WHAT(First, X, 62) BASED_FE_62_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_64_1(First, WHAT, X, ...) WHAT(First, X, 63) BASED_FE_63_1(First, WHAT, __VA_ARGS__)
// clang-format on

#define BASED_FOREACH_1(First, action, ...) \
BASED_GET_MACRO(_0, __VA_ARGS__, BASED_FE_64_1, BASED_FE_63_1, BASED_FE_62_1, BASED_FE_61_1, BASED_FE_60_1, BASED_FE_59_1, BASED_FE_58_1, BASED_FE_57_1, BASED_FE_56_1, BASED_FE_55_1, BASED_FE_54_1, BASED_FE_53_1, BASED_FE_52_1, BASED_FE_51_1, BASED_FE_50_1, BASED_FE_49_1, BASED_FE_48_1, BASED_FE_47_1, BASED_FE_46_1, BASED_FE_45_1, BASED_FE_44_1, BASED_FE_43_1, BASED_FE_42_1, BASED_FE_41_1, BASED_FE_40_1, BASED_FE_39_1, BASED_FE_38_1, BASED_FE_37_1, BASED_FE_36_1, BASED_FE_35_1, BASED_FE_34_1, BASED_FE_33_1, BASED_FE_32_1, BASED_FE_31_1, BASED_FE_30_1, BASED_FE_29_1, BASED_FE_28_1, BASED_FE_27_1, BASED_FE_26_1, BASED_FE_25_1, BASED_FE_24_1, BASED_FE_23_1, BASED_FE_22_1, BASED_FE_21_1, BASED_FE_20_1, BASED_FE_19_1, BASED_FE_18_1, BASED_FE_17_1, BASED_FE_16_1, BASED_FE_15_1, BASED_FE_14_1, BASED_FE_13_1, BASED_FE_12_1, BASED_FE_11_1, BASED_FE_10_1, BASED_FE_9_1, BASED_FE_8_1, BASED_FE_7_1, BASED_FE_6_1, BASED_FE_5_1, BASED_FE_4_1, BASED_FE_3_1, BASED_FE_2_1, BASED_FE_1_1, BASED_FE_0_1)( \
First, action, __VA_ARGS__ \
)

// NOLINTEND(*macro-usage*)

diff --git a/ include/based/macro/foreach_2.hpp b/ include/based/macro/foreach_2.hpp

@@ -0,0 +1,80 @@

#pragma once

#include "based/macro/get_macro.hpp"

// NOLINTBEGIN(*macro-usage*)

// clang-format off
#define BASED_FE_0_2(First, Second, WHAT)
#define BASED_FE_1_2(First, Second, WHAT, X) WHAT(First, Second, X, 0)
#define BASED_FE_2_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 1) BASED_FE_1_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_3_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 2) BASED_FE_2_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_4_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 3) BASED_FE_3_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_5_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 4) BASED_FE_4_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_6_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 5) BASED_FE_5_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_7_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 6) BASED_FE_6_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_8_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 7) BASED_FE_7_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_9_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 8) BASED_FE_8_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_10_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 9) BASED_FE_9_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_11_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 10) BASED_FE_10_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_12_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 11) BASED_FE_11_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_13_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 12) BASED_FE_12_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_14_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 13) BASED_FE_13_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_15_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 14) BASED_FE_14_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_16_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 15) BASED_FE_15_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_17_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 16) BASED_FE_16_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_18_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 17) BASED_FE_17_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_19_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 18) BASED_FE_18_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_20_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 19) BASED_FE_19_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_21_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 20) BASED_FE_20_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_22_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 21) BASED_FE_21_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_23_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 22) BASED_FE_22_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_24_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 23) BASED_FE_23_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_25_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 24) BASED_FE_24_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_26_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 25) BASED_FE_25_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_27_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 26) BASED_FE_26_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_28_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 27) BASED_FE_27_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_29_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 28) BASED_FE_28_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_30_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 29) BASED_FE_29_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_31_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 30) BASED_FE_30_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_32_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 31) BASED_FE_31_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_33_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 32) BASED_FE_32_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_34_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 33) BASED_FE_33_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_35_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 34) BASED_FE_34_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_36_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 35) BASED_FE_35_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_37_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 36) BASED_FE_36_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_38_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 37) BASED_FE_37_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_39_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 38) BASED_FE_38_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_40_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 39) BASED_FE_39_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_41_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 40) BASED_FE_40_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_42_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 41) BASED_FE_41_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_43_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 42) BASED_FE_42_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_44_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 43) BASED_FE_43_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_45_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 44) BASED_FE_44_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_46_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 45) BASED_FE_45_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_47_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 46) BASED_FE_46_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_48_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 47) BASED_FE_47_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_49_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 48) BASED_FE_48_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_50_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 49) BASED_FE_49_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_51_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 50) BASED_FE_50_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_52_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 51) BASED_FE_51_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_53_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 52) BASED_FE_52_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_54_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 53) BASED_FE_53_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_55_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 54) BASED_FE_54_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_56_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 55) BASED_FE_55_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_57_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 56) BASED_FE_56_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_58_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 57) BASED_FE_57_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_59_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 58) BASED_FE_58_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_60_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 59) BASED_FE_59_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_61_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 60) BASED_FE_60_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_62_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 61) BASED_FE_61_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_63_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 62) BASED_FE_62_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_64_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 63) BASED_FE_63_2(First, Second, WHAT, __VA_ARGS__)
// clang-format on

#define BASED_FOREACH_2(First, Second, action, ...) \
BASED_GET_MACRO(_0, __VA_ARGS__, BASED_FE_64_2, BASED_FE_63_2, BASED_FE_62_2, BASED_FE_61_2, BASED_FE_60_2, BASED_FE_59_2, BASED_FE_58_2, BASED_FE_57_2, BASED_FE_56_2, BASED_FE_55_2, BASED_FE_54_2, BASED_FE_53_2, BASED_FE_52_2, BASED_FE_51_2, BASED_FE_50_2, BASED_FE_49_2, BASED_FE_48_2, BASED_FE_47_2, BASED_FE_46_2, BASED_FE_45_2, BASED_FE_44_2, BASED_FE_43_2, BASED_FE_42_2, BASED_FE_41_2, BASED_FE_40_2, BASED_FE_39_2, BASED_FE_38_2, BASED_FE_37_2, BASED_FE_36_2, BASED_FE_35_2, BASED_FE_34_2, BASED_FE_33_2, BASED_FE_32_2, BASED_FE_31_2, BASED_FE_30_2, BASED_FE_29_2, BASED_FE_28_2, BASED_FE_27_2, BASED_FE_26_2, BASED_FE_25_2, BASED_FE_24_2, BASED_FE_23_2, BASED_FE_22_2, BASED_FE_21_2, BASED_FE_20_2, BASED_FE_19_2, BASED_FE_18_2, BASED_FE_17_2, BASED_FE_16_2, BASED_FE_15_2, BASED_FE_14_2, BASED_FE_13_2, BASED_FE_12_2, BASED_FE_11_2, BASED_FE_10_2, BASED_FE_9_2, BASED_FE_8_2, BASED_FE_7_2, BASED_FE_6_2, BASED_FE_5_2, BASED_FE_4_2, BASED_FE_3_2, BASED_FE_2_2, BASED_FE_1_2, BASED_FE_0_2)( \
First, Second, action, __VA_ARGS__ \
)

// NOLINTEND(*macro-usage*)

diff --git a/ include/based/macro/get_macro.hpp b/ include/based/macro/get_macro.hpp

@@ -0,0 +1,11 @@

#pragma once

// clang-format off
#define BASED_GET_MACRO( \
_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, \
_16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, \
_30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, \
_44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, \
_58, _59, _60, _61, _62, _63, _64, NAME, ... \
) NAME
// clang-format on

diff --git a/ include/based/macro/macros.hpp b/ include/based/macro/macros.hpp

@@ -1,87 +0,0 @@

#pragma once

// NOLINTBEGIN(*macro-usage*)

#define BASED_NUMARGS(...) (std::array {__VA_ARGS__}.size())

// clang-format off
#define BASED_GET_MACRO( \
_0, _1, _2, _3, _4, _5, _6, _7, \
_8, _9, _10, _11, _12, _13, _14, _15, \
NAME, ... \
) NAME
// clang-format on

// clang-format off
#define BASED_FE_0(WHAT)
#define BASED_FE_1(WHAT, X) WHAT(X, 0)
#define BASED_FE_2(WHAT, X, ...) WHAT(X, 1) BASED_FE_1(WHAT, __VA_ARGS__)
#define BASED_FE_3(WHAT, X, ...) WHAT(X, 2) BASED_FE_2(WHAT, __VA_ARGS__)
#define BASED_FE_4(WHAT, X, ...) WHAT(X, 3) BASED_FE_3(WHAT, __VA_ARGS__)
#define BASED_FE_5(WHAT, X, ...) WHAT(X, 4) BASED_FE_4(WHAT, __VA_ARGS__)
#define BASED_FE_6(WHAT, X, ...) WHAT(X, 5) BASED_FE_5(WHAT, __VA_ARGS__)
#define BASED_FE_7(WHAT, X, ...) WHAT(X, 6) BASED_FE_6(WHAT, __VA_ARGS__)
#define BASED_FE_8(WHAT, X, ...) WHAT(X, 7) BASED_FE_7(WHAT, __VA_ARGS__)
#define BASED_FE_9(WHAT, X, ...) WHAT(X, 8) BASED_FE_8(WHAT, __VA_ARGS__)
#define BASED_FE_10(WHAT, X, ...) WHAT(X, 9) BASED_FE_9(WHAT, __VA_ARGS__)
#define BASED_FE_11(WHAT, X, ...) WHAT(X, 10) BASED_FE_10(WHAT, __VA_ARGS__)
#define BASED_FE_12(WHAT, X, ...) WHAT(X, 11) BASED_FE_11(WHAT, __VA_ARGS__)
#define BASED_FE_13(WHAT, X, ...) WHAT(X, 12) BASED_FE_12(WHAT, __VA_ARGS__)
#define BASED_FE_14(WHAT, X, ...) WHAT(X, 13) BASED_FE_13(WHAT, __VA_ARGS__)
#define BASED_FE_15(WHAT, X, ...) WHAT(X, 14) BASED_FE_14(WHAT, __VA_ARGS__)
// clang-format on

#define BASED_FOREACH(action, ...) \
BASED_GET_MACRO(_0, __VA_ARGS__, BASED_FE_15, BASED_FE_14, BASED_FE_13, BASED_FE_12, BASED_FE_11, BASED_FE_10, BASED_FE_9, BASED_FE_8, BASED_FE_7, BASED_FE_6, BASED_FE_5, BASED_FE_4, BASED_FE_3, BASED_FE_2, BASED_FE_1, BASED_FE_0)( \
action, __VA_ARGS__ \
)

// clang-format off
#define BASED_FE_0_1(First, WHAT)
#define BASED_FE_1_1(First, WHAT, X) WHAT(First, X, 0)
#define BASED_FE_2_1(First, WHAT, X, ...) WHAT(First, X, 1) BASED_FE_1_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_3_1(First, WHAT, X, ...) WHAT(First, X, 2) BASED_FE_2_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_4_1(First, WHAT, X, ...) WHAT(First, X, 3) BASED_FE_3_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_5_1(First, WHAT, X, ...) WHAT(First, X, 4) BASED_FE_4_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_6_1(First, WHAT, X, ...) WHAT(First, X, 5) BASED_FE_5_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_7_1(First, WHAT, X, ...) WHAT(First, X, 6) BASED_FE_6_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_8_1(First, WHAT, X, ...) WHAT(First, X, 7) BASED_FE_7_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_9_1(First, WHAT, X, ...) WHAT(First, X, 8) BASED_FE_8_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_10_1(First, WHAT, X, ...) WHAT(First, X, 9) BASED_FE_9_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_11_1(First, WHAT, X, ...) WHAT(First, X, 10) BASED_FE_10_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_12_1(First, WHAT, X, ...) WHAT(First, X, 11) BASED_FE_11_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_13_1(First, WHAT, X, ...) WHAT(First, X, 12) BASED_FE_12_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_14_1(First, WHAT, X, ...) WHAT(First, X, 13) BASED_FE_13_1(First, WHAT, __VA_ARGS__)
#define BASED_FE_15_1(First, WHAT, X, ...) WHAT(First, X, 14) BASED_FE_14_1(First, WHAT, __VA_ARGS__)
// clang-format on

#define BASED_FOREACH_1(First, action, ...) \
BASED_GET_MACRO(_0, __VA_ARGS__, BASED_FE_15_1, BASED_FE_14_1, BASED_FE_13_1, BASED_FE_12_1, BASED_FE_11_1, BASED_FE_10_1, BASED_FE_9_1, BASED_FE_8_1, BASED_FE_7_1, BASED_FE_6_1, BASED_FE_5_1, BASED_FE_4_1, BASED_FE_3_1, BASED_FE_2_1, BASED_FE_1_1, BASED_FE_0_1)( \
First, action, __VA_ARGS__ \
)

// clang-format off
#define BASED_FE_0_2(First, Second, WHAT)
#define BASED_FE_1_2(First, Second, WHAT, X) WHAT(First, Second, X, 0)
#define BASED_FE_2_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 1) BASED_FE_1_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_3_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 2) BASED_FE_2_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_4_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 3) BASED_FE_3_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_5_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 4) BASED_FE_4_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_6_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 5) BASED_FE_5_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_7_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 6) BASED_FE_6_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_8_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 7) BASED_FE_7_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_9_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 8) BASED_FE_8_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_10_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 9) BASED_FE_9_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_11_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 10) BASED_FE_10_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_12_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 11) BASED_FE_11_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_13_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 12) BASED_FE_12_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_14_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 13) BASED_FE_13_2(First, Second, WHAT, __VA_ARGS__)
#define BASED_FE_15_2(First, Second, WHAT, X, ...) WHAT(First, Second, X, 14) BASED_FE_14_2(First, Second, WHAT, __VA_ARGS__)
// clang-format on

#define BASED_FOREACH_2(First, Second, action, ...) \
BASED_GET_MACRO(_0, __VA_ARGS__, BASED_FE_15_2, BASED_FE_14_2, BASED_FE_13_2, BASED_FE_12_2, BASED_FE_11_2, BASED_FE_10_2, BASED_FE_9_2, BASED_FE_8_2, BASED_FE_7_2, BASED_FE_6_2, BASED_FE_5_2, BASED_FE_4_2, BASED_FE_3_2, BASED_FE_2_2, BASED_FE_1_2, BASED_FE_0_2)( \
First, Second, action, __VA_ARGS__ \
)

// NOLINTEND(*macro-usage*)

diff --git a/ test/source/enum_flag_test.cpp b/ test/source/enum_flag_test.cpp

@@ -12,7 +12,7 @@

#include "based/concepts/is/same.hpp"
#include "based/types/types.hpp"

BASED_ENUM_DECLARE_FLAG(var, based::u8, a, b, c)
BASED_DECLARE_ENUM_FLAG(var, based::u8, a, b, c)
BASED_DEFINE_ENUM_FLAG(var, based::u8, a, b, c)

TEST_CASE("types", "[enum/enum]")

diff --git a/ test/source/enum_test.cpp b/ test/source/enum_test.cpp

@@ -15,7 +15,7 @@


struct test
{
BASED_ENUM_DECLARE(var, based::u8, a, b, c)
BASED_DECLARE_ENUM(var, based::u8, a, b, c)

[[nodiscard]] int get_var(var::type req) const;