Evo C++ Library v0.5.1
macro.h
Go to the documentation of this file.
1 // Evo C++ Library
2 /* Copyright 2019 Justin Crowell
3 Distributed under the BSD 2-Clause License -- see included file LICENSE.txt for details.
4 */
6 
7 #pragma once
8 #ifndef INCL_evo_macro_h
9 #define INCL_evo_macro_h
10 
11 #include "impl/sys.h"
12 
14 
16 #define EVO_STRINGIFY_IMPL(X) #X
17 #define EVO_CONCAT_IMPL(A, B) A##B
18 
19 #if defined(_MSC_VER)
20  #define EVO_COUNT_ARGS_IMPL_AUGMENT(...) DUMMY, __VA_ARGS__
21  #define EVO_COUNT_ARGS_IMPL_2(A1,A2,A3, A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20, \
22  A21,A22,A23,A24,A25,A26,A27,A28,A29,A30,A31,A32,A33,A34,A35,A36,A37,A38,A39,A40, \
23  A41,A42,A43,A44,A45,A46,A47,A48,A49,A50,A51,A52,A53,A54,A55,A56,A57,A58,A59,A60,N, ...) N
24  #define EVO_COUNT_ARGS_IMPL(...) EVO_EXPAND(EVO_COUNT_ARGS_IMPL_2(__VA_ARGS__, \
25  59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40, \
26  39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20, \
27  19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
28 #else
29  #define EVO_COUNT_ARGS_IMPL(A0,A1,A2,A3, A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20, \
30  A21,A22,A23,A24,A25,A26,A27,A28,A29,A30,A31,A32,A33,A34,A35,A36,A37,A38,A39,A40, \
31  A41,A42,A43,A44,A45,A46,A47,A48,A49,A50,A51,A52,A53,A54,A55,A56,A57,A58,A59,A60,N, ...) N
32 #endif
33 
34 #define EVO_MAP_FIELDS_IMPL_BASE_DEF(T, N, K) T N
35 #define EVO_MAP_FIELDS_IMPL_BASE_LOAD(T, N, K) N = evo::Convert<evo::SubString,T>::value(evo::lookupsub(map, K))
36 #define EVO_MAP_FIELDS_IMPL_BASE_SAVE(T, N, K) evo::Convert<evo::String,T>::set(map[K], N)
37 #define EVO_MAP_FIELDS_IMPL_BASE_DUMP(T, N, K) out << K << ':' << N << evo::NL
38 #define EVO_MAP_FIELDS_IMPL_BASE_DUMP2(T, N, K) out << EVO_STRINGIFY_IMPL(N) << ':' << N << evo::NL
39 
40 #define EVO_MAP_FIELDS_IMPL_2(BASE, T, N) BASE(T, N, EVO_STRINGIFY(N));
41 #define EVO_MAP_FIELDS_IMPL_4(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_2(BASE, __VA_ARGS__))
42 #define EVO_MAP_FIELDS_IMPL_6(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_4(BASE, __VA_ARGS__))
43 #define EVO_MAP_FIELDS_IMPL_8(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_6(BASE, __VA_ARGS__))
44 #define EVO_MAP_FIELDS_IMPL_10(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_8(BASE, __VA_ARGS__))
45 #define EVO_MAP_FIELDS_IMPL_12(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_10(BASE, __VA_ARGS__))
46 #define EVO_MAP_FIELDS_IMPL_14(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_12(BASE, __VA_ARGS__))
47 #define EVO_MAP_FIELDS_IMPL_16(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_14(BASE, __VA_ARGS__))
48 #define EVO_MAP_FIELDS_IMPL_18(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_16(BASE, __VA_ARGS__))
49 #define EVO_MAP_FIELDS_IMPL_20(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_18(BASE, __VA_ARGS__))
50 #define EVO_MAP_FIELDS_IMPL_22(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_20(BASE, __VA_ARGS__))
51 #define EVO_MAP_FIELDS_IMPL_24(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_22(BASE, __VA_ARGS__))
52 #define EVO_MAP_FIELDS_IMPL_26(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_24(BASE, __VA_ARGS__))
53 #define EVO_MAP_FIELDS_IMPL_28(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_26(BASE, __VA_ARGS__))
54 #define EVO_MAP_FIELDS_IMPL_30(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_28(BASE, __VA_ARGS__))
55 #define EVO_MAP_FIELDS_IMPL_32(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_30(BASE, __VA_ARGS__))
56 #define EVO_MAP_FIELDS_IMPL_34(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_32(BASE, __VA_ARGS__))
57 #define EVO_MAP_FIELDS_IMPL_36(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_34(BASE, __VA_ARGS__))
58 #define EVO_MAP_FIELDS_IMPL_38(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_36(BASE, __VA_ARGS__))
59 #define EVO_MAP_FIELDS_IMPL_40(BASE, T, N, ...) BASE(T, N, EVO_STRINGIFY(N)); EVO_EXPAND(EVO_MAP_FIELDS_IMPL_38(BASE, __VA_ARGS__))
60 
61 #define EVO_MAP_FIELDS_IMPL2_3(BASE, T, N, K) BASE(T, N, K);
62 #define EVO_MAP_FIELDS_IMPL2_6(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_3(BASE, __VA_ARGS__))
63 #define EVO_MAP_FIELDS_IMPL2_9(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_6(BASE, __VA_ARGS__))
64 #define EVO_MAP_FIELDS_IMPL2_12(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_9(BASE, __VA_ARGS__))
65 #define EVO_MAP_FIELDS_IMPL2_15(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_12(BASE, __VA_ARGS__))
66 #define EVO_MAP_FIELDS_IMPL2_18(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_15(BASE, __VA_ARGS__))
67 #define EVO_MAP_FIELDS_IMPL2_21(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_18(BASE, __VA_ARGS__))
68 #define EVO_MAP_FIELDS_IMPL2_24(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_21(BASE, __VA_ARGS__))
69 #define EVO_MAP_FIELDS_IMPL2_27(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_24(BASE, __VA_ARGS__))
70 #define EVO_MAP_FIELDS_IMPL2_30(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_27(BASE, __VA_ARGS__))
71 #define EVO_MAP_FIELDS_IMPL2_33(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_30(BASE, __VA_ARGS__))
72 #define EVO_MAP_FIELDS_IMPL2_36(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_33(BASE, __VA_ARGS__))
73 #define EVO_MAP_FIELDS_IMPL2_39(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_36(BASE, __VA_ARGS__))
74 #define EVO_MAP_FIELDS_IMPL2_42(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_39(BASE, __VA_ARGS__))
75 #define EVO_MAP_FIELDS_IMPL2_45(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_42(BASE, __VA_ARGS__))
76 #define EVO_MAP_FIELDS_IMPL2_48(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_45(BASE, __VA_ARGS__))
77 #define EVO_MAP_FIELDS_IMPL2_51(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_48(BASE, __VA_ARGS__))
78 #define EVO_MAP_FIELDS_IMPL2_54(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_51(BASE, __VA_ARGS__))
79 #define EVO_MAP_FIELDS_IMPL2_57(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_54(BASE, __VA_ARGS__))
80 #define EVO_MAP_FIELDS_IMPL2_60(BASE, T, N, K, ...) BASE(T, N, K); EVO_EXPAND(EVO_MAP_FIELDS_IMPL2_57(BASE, __VA_ARGS__))
81 
86 #define EVO_STRINGIFY(X) EVO_STRINGIFY_IMPL(X)
87 
92 #define EVO_CONCAT(A, B) EVO_CONCAT_IMPL(A, B)
93 
99 #define EVO_EXPAND(X) X
100 
105 #if defined(_MSC_VER)
106  #define EVO_COUNT_ARGS(...) EVO_COUNT_ARGS_IMPL(EVO_COUNT_ARGS_IMPL_AUGMENT(__VA_ARGS__))
107 #else
108  #define EVO_COUNT_ARGS(...) EVO_EXPAND(EVO_COUNT_ARGS_IMPL(0, ## __VA_ARGS__, \
109  60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40, \
110  39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20, \
111  19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
112 #endif
113 
192 #define EVO_MAP_FIELDS(...) \
193  EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_DEF, __VA_ARGS__)) \
194  template<class C> void load(const C& map) { \
195  EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_LOAD, __VA_ARGS__)) \
196  } \
197  template<class C> void save(C& map) const { \
198  EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_SAVE, __VA_ARGS__)) \
199  } \
200  template<class C> void dump(C& out) const { \
201  EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_DUMP, __VA_ARGS__)) \
202  }
203 
269 #define EVO_MAP_FIELDS_KEY(...) \
270  EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL2_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_DEF, __VA_ARGS__)) \
271  template<class M> void load(const M& map) { \
272  EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL2_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_LOAD, __VA_ARGS__)) \
273  } \
274  template<class M> void save(M& map) const { \
275  EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL2_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_SAVE, __VA_ARGS__)) \
276  } \
277  template<class C> void dump(C& out) const { \
278  EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL2_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_DUMP2, __VA_ARGS__)) \
279  }
280 
282 #endif
Evo implementation detail for system portability – this is included by most Evo headers, include this via: include <evo/type.h>.