//Macro vargs counter (max count 64)

#define MACRO_VA_NUM_ARGS_IMPL(_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,_63, _64, N,...) N

#define MACRO_VA_NUM_ARGS(...) MACRO_VA_NUM_ARGS_IMPL(__VA_ARGS__, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 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)

//Forces a macro to concatenate and evaluate, rather than stop.

#define MACRO_CAT(a, ...) MACRO_PRIMITIVE_CAT(a, __VA_ARGS__)

#define MACRO_PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__

//Repeats x, "ONES" times (1-9, easy to expand to 10, 100 etc.)

#define _MACRO_REP_(x)

#define _MACRO_REP_1(x) x

#define _MACRO_REP_2(x) _MACRO_REP_1(x) _MACRO_REP_1(x)

#define _MACRO_REP_3(x) _MACRO_REP_2(x) _MACRO_REP_1(x)

#define _MACRO_REP_4(x) _MACRO_REP_3(x) _MACRO_REP_1(x)

#define _MACRO_REP_5(x) _MACRO_REP_4(x) _MACRO_REP_1(x)

#define _MACRO_REP_6(x) _MACRO_REP_5(x) _MACRO_REP_1(x)

#define _MACRO_REP_7(x) _MACRO_REP_6(x) _MACRO_REP_1(x)

#define _MACRO_REP_8(x) _MACRO_REP_7(x) _MACRO_REP_1(x)

#define _MACRO_REP_9(x) _MACRO_REP_8(x) _MACRO_REP_1(x)

#define _MACRO_REP_IMP(ONES, x) _MACRO_REP_##ONES(x)

#define MACRO_REP(ONES, x) _MACRO_REP_IMP(ONES, x)

//Same as above but instead goes through an "array" of vargs like so: namespace <arg x> {

//Only supports 0 to 9 easy to expand, same as above

#define _MACRO_NAMESPACE_START0(name1, ...)

#define _MACRO_NAMESPACE_START1(name1, ...) namespace name1 {

#define _MACRO_NAMESPACE_START2(name1, ...) _MACRO_NAMESPACE_START1(name1) _MACRO_NAMESPACE_START1(__VA_ARGS__)

#define _MACRO_NAMESPACE_START3(name1, ...) _MACRO_NAMESPACE_START1(name1) _MACRO_NAMESPACE_START2(__VA_ARGS__)

#define _MACRO_NAMESPACE_START4(name1, ...) _MACRO_NAMESPACE_START1(name1) _MACRO_NAMESPACE_START3(__VA_ARGS__)

#define _MACRO_NAMESPACE_START5(name1, ...) _MACRO_NAMESPACE_START1(name1) _MACRO_NAMESPACE_START4(__VA_ARGS__)

#define _MACRO_NAMESPACE_START6(name1, ...) _MACRO_NAMESPACE_START1(name1) _MACRO_NAMESPACE_START5(__VA_ARGS__)

#define _MACRO_NAMESPACE_START7(name1, ...) _MACRO_NAMESPACE_START1(name1) _MACRO_NAMESPACE_START6(__VA_ARGS__)

#define _MACRO_NAMESPACE_START8(name1, ...) _MACRO_NAMESPACE_START1(name1) _MACRO_NAMESPACE_START7(__VA_ARGS__)

#define _MACRO_NAMESPACE_START9(name1, ...) _MACRO_NAMESPACE_START1(name1) _MACRO_NAMESPACE_START8(__VA_ARGS__)

//Redirection macro to concatenate properly

#define _MACRO_NAMESPACE_START(count, ...) MACRO_CAT(_MACRO_NAMESPACE_START, count(__VA_ARGS__))

//Namespace definition macros

#define NAMESPACE_START(...) _MACRO_NAMESPACE_START(MACRO_VA_NUM_ARGS(__VA_ARGS__), __VA_ARGS__)

#define NAMESPACE_END(...) MACRO_REP(MACRO_VA_NUM_ARGS(__VA_ARGS__), })

// ////////

//

// Usage example:

// NAMESPACE_START(libraryname, util, containers)

// typedef some_type some_other_type;

// class SomeClass {

// ...

// };

// NAMESPACE_END(libraryname, util, containers)

//

//