Evo C++ Library v0.5.1
Macros
macro.h File Reference

Evo advanced preprocessor macros. More...

#include "impl/sys.h"

Go to the source code of this file.

Macros

#define EVO_CONCAT(A, B)   EVO_CONCAT_IMPL(A, B)
 Concatenate two tokens into a single token using the preprocessor. More...
 
#define EVO_COUNT_ARGS(...)
 Count number of arguments passed to macro. More...
 
#define EVO_EXPAND(X)   X
 Expand argument to itself. More...
 
#define EVO_MAP_FIELDS(...)
 Create a list of fields and templated load/save/dump helper methods. More...
 
#define EVO_MAP_FIELDS_KEY(...)
 Create a list of fields and templated load/save/dump helper methods. More...
 
#define EVO_STRINGIFY(X)   EVO_STRINGIFY_IMPL(X)
 Make argument token a string literal using the preprocessor. More...
 
#define INCL_evo_macro_h
 

Detailed Description

Evo advanced preprocessor macros.

Macro Definition Documentation

◆ EVO_CONCAT

#define EVO_CONCAT (   A,
 
)    EVO_CONCAT_IMPL(A, B)

Concatenate two tokens into a single token using the preprocessor.

Parameters
AToken beginning
BToken end

◆ EVO_COUNT_ARGS

#define EVO_COUNT_ARGS (   ...)
Value:
EVO_EXPAND(EVO_COUNT_ARGS_IMPL(0, ## __VA_ARGS__, \
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,0))
#define EVO_EXPAND(X)
Expand argument to itself.
Definition: macro.h:99

Count number of arguments passed to macro.

  • This usually requires at least 1 argument, otherwise some compilers (gcc, clang) have issues when C++11 (or newer) is enabled
  • This can be used to construct a macro name with the number of arguments used, ex: EVO_CONCAT(FOO_, EVO_COUNT_ARGS(a)) resolves to FOO_1

◆ EVO_EXPAND

#define EVO_EXPAND (   X)    X

Expand argument to itself.

  • This is a trick used to make sure the argument is used as-is, where in some cases it might get mangled from nesting macros (which often happens with MSVC, especially when passing VA_ARGS to another macro)
Parameters
XParameter to expand

◆ EVO_MAP_FIELDS

#define EVO_MAP_FIELDS (   ...)
Value:
EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_DEF, __VA_ARGS__)) \
template<class C> void load(const C& map) { \
EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_LOAD, __VA_ARGS__)) \
} \
template<class C> void save(C& map) const { \
EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_SAVE, __VA_ARGS__)) \
} \
template<class C> void dump(C& out) const { \
EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_DUMP, __VA_ARGS__)) \
}
#define EVO_CONCAT(A, B)
Concatenate two tokens into a single token using the preprocessor.
Definition: macro.h:92
#define EVO_COUNT_ARGS(...)
Count number of arguments passed to macro.
Definition: macro.h:108
#define EVO_EXPAND(X)
Expand argument to itself.
Definition: macro.h:99

Create a list of fields and templated load/save/dump helper methods.

  • This is normally used inside a struct and defines member variables and methods for it
  • This defines the fields listed, then defines these helper methods:
    • template<class T> void load(const T& map) – load from map into fields
    • template<class T> void save(T& map) const – save from fields to map
    • template<class T> void dump(T& out) const – dump fields to output stream/string
  • This supports a maximum of 20 fields (any more will give compiler errors) – for more use multiple structs
  • If you get a bunch of compiler errors using this, double check:
    • There's a pair of arguments for each field
      • The first field argument is a valid type, and the second is a valid field (variable) name
    • Any map passed to load() or save() must use the String type for both keys and values
    • Any stream or string passed to dump() supports all field types with operator<<()
    • All arguments are comma separated
    • Last argument doesn't end with a comma
  • See also: EVO_MAP_FIELDS2()
Parameters
...Fields to define, where each field is a pair of arguments as: type, name
Example
#include <evo/macro.h>
#include <evo/string.h>
#include <evo/maplist.h>
#include <evo/io.h>
using namespace evo;
struct MyFields {
bool, flag,
int, num,
ULong, unum,
String, str
)
};
int main() {
Console& c = con();
// Populate map with fields
map["flag"] = "true";
map["num"] = "123";
map["unum"] = "999";
map["str"] = "Hello";
// Load from map to struct
MyFields data;
data.load(map);
data.dump(c.out << "Dump:" << NL);
// Clear map and repopulate from struct
map.clear();
data.save(map);
// Print map items
c.out << NL << "Map:" << NL;
for (StrMapList::Iter iter(map); iter; ++iter)
c.out << iter->key() << " = " << iter->value() << NL;
return 0;
}
Dump:
flag:true
num:123
unum:999
str:Hello
Map:
flag = true
num = 123
str = Hello
unum = 999

◆ EVO_MAP_FIELDS_KEY

#define EVO_MAP_FIELDS_KEY (   ...)
Value:
EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL2_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_DEF, __VA_ARGS__)) \
template<class M> void load(const M& map) { \
EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL2_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_LOAD, __VA_ARGS__)) \
} \
template<class M> void save(M& map) const { \
EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL2_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_SAVE, __VA_ARGS__)) \
} \
template<class C> void dump(C& out) const { \
EVO_EXPAND(EVO_CONCAT(EVO_MAP_FIELDS_IMPL2_, EVO_COUNT_ARGS(__VA_ARGS__))(EVO_MAP_FIELDS_IMPL_BASE_DUMP2, __VA_ARGS__)) \
}
#define EVO_CONCAT(A, B)
Concatenate two tokens into a single token using the preprocessor.
Definition: macro.h:92
#define EVO_COUNT_ARGS(...)
Count number of arguments passed to macro.
Definition: macro.h:108
#define EVO_EXPAND(X)
Expand argument to itself.
Definition: macro.h:99

Create a list of fields and templated load/save/dump helper methods.

  • This is the same as EVO_MAP_FIELDS() but takes an additional argument per field to specify the map key string for the field
Parameters
...Fields to define, where each field is 3 arguments as: type, name, key
Example
#include <evo/macro.h>
#include <evo/string.h>
#include <evo/maplist.h>
#include <evo/io.h>
using namespace evo;
struct MyFields {
bool, flag, "flag-key",
int, num, "num-key",
ULong, unum, "unum-key",
String, str, "str-key"
)
};
int main() {
Console& c = con();
// Populate map with fields
map["flag-key"] = "true";
map["num-key"] = "123";
map["unum-key"] = "999";
map["str-key"] = "Hello";
// Load from map to struct
MyFields data;
data.load(map);
data.dump(c.out << "Dump:" << NL);
// Clear map and repopulate from struct
map.clear();
data.save(map);
// Print map items
c.out << NL << "Map:" << NL;
for (StrMapList::Iter iter(map); iter; ++iter)
c.out << iter->key() << " = " << iter->value() << NL;
return 0;
}
Dump:
flag:true
num:123
unum:999
str:Hello
Map:
flag-key = true
num-key = 123
str-key = Hello
unum-key = 999

◆ EVO_STRINGIFY

#define EVO_STRINGIFY (   X)    EVO_STRINGIFY_IMPL(X)

Make argument token a string literal using the preprocessor.

Parameters
XArgument to make a string literal

◆ INCL_evo_macro_h

#define INCL_evo_macro_h