#ifndef TYPES_H
#define TYPES_H
#include <type_traits>
#include <cstdint>
// Some basic types that should build serializable structures from
template<typename T>
using Array = std::vector<T>;
using Boolean = bool;
using Byte = uint8_t;
using Char = int8_t;
using Unsigned32 = uint32_t;
using Unsigned64 = uint64_t;
using Integer32 = int32_t;
using Integer64 = int64_t;
using Float32 = float;
using Float64 = double;
using String = std::string;
// discourage 16bit types, CPUs aren't so efficient at these
// TODO: enums
/*
about enums:
Looks like C++17 might make reflection of enums nice.
http://aantron.github.io/better-enums/demo/C++17ReflectionProposal.html
In the mean time, something like this gets close with the use of an ugly macro where the enums are declared
however it provides similar syntax to what C++17 may have for using the reflection
http://melpon.org/wandbox/permlink/QelcwZNLi4gIx8Ux
*/
struct EnumBaseValue
{
Integer32 id;
String name;
};
struct EnumBase
{
String name;
Array<EnumBaseValue> values;
};
#define DECLARE_STRUCT(name) \
struct name { \
private: \
typedef name _this_type; \
static const char* _this_name() { return #name; } \
public: \
typedef struct { \
static const decltype(std::make_tuple()) tuple() { \
return std::make_tuple(); \
}
#define DECLARE_MEMBER(type, name, ...) \
} blah##name; \
\
type name = type(__VA_ARGS__); \
\
typedef struct { \
static type& get_##name(_this_type& _this) { \
return _this.name; \
} \
typedef decltype(std::tuple_cat(blah##name::tuple(), std::make_tuple(#name, get_##name))) ret_type; \
static const ret_type tuple() { \
return std::tuple_cat(blah##name::tuple(), std::make_tuple(#name, get_##name)); \
}
#define END_STRUCT() \
} last; \
template <class V> \
void Visit(V& v) \
{ \
v.Enter(_this_name()); \
static auto tup = last::tuple(); \
for_each(v, *this, tup); \
v.Exit(_this_name()); \
} \
};
#endif // TYPES_H