Created
October 29, 2021 18:45
-
-
Save thecppzoo/840b32bfa85953ea393c5ee4563a1e4a to your computer and use it in GitHub Desktop.
Data Orientation Macros
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This example requires the boost preprocessing library headers | |
#include <boost/preprocessor/seq/for_each_i.hpp> | |
#include <boost/preprocessor/seq/for_each.hpp> | |
#include <boost/preprocessor/punctuation/comma_if.hpp> | |
#include <boost/preprocessor/cat.hpp> | |
#include <boost/preprocessor/seq/transform.hpp> | |
#include <boost/preprocessor/seq/enum.hpp> | |
// Macro naming convention: | |
// The prefix ZOO_PP_ indicates the identifier is preprocessing | |
// The particle D_ indicates the macro is for Data Orientation techniques | |
// The particle SEQ_ indicates the macro is for boost preprocessing sequences | |
// The particle SEQI_ indicates the macro is used for BOOST_PP_SEQ_FOR_EACH_I | |
// The rest of the identifier indicates what it does | |
// handle, columnar state naming convention: | |
// The normal memory layout is declared as specified. | |
// The handle that corresponds to it uses the _handle suffix | |
// The columnar state global variable uses the prefix g_ | |
// for example, for a type called Example, its handle would be Example_handle | |
// and its global variable to hold their states g_Example | |
// General utility to remove parenthesis ("untuple") or force expansion | |
#define ZOO_PP_QUOTE(...) __VA_ARGS__ | |
// General utility to allow capturing lists of macro arguments as macros | |
#define ZOO_PP_INVOKE(macro, ...) macro(__VA_ARGS__) | |
// Specification format: | |
// Because C++ data types may have commas in them (templates with more than one | |
// argument, all specifications of types for macros have extra parenthesis for | |
// grouping into a single macro argument | |
// A data member is specified as a tuple of type and name, examples: | |
// ((int), anIntegerName) | |
// ((std::map<int, char>), aMapFromIntToChar) | |
// A function is specified as a tuple of return type, name, parameter list | |
// the parameter list is a boost sequence, that is, the sequence (a)(b)(c) | |
// has the three elements a, b and c | |
// A parameter has the same format as a data member. | |
// Examples: | |
// ((void), aFunctionThatReturnsVoidAndTakesTwoInts, (((int), firstArg))(((int), secondArg))) | |
// ( <- begins a tuple | |
// (void), <- the first tuple member is a type, parenthesis for grouping | |
// aFunctionThatReturnsVoidAndTakesTwoInts, <- second member, the name | |
// ( <- a sequence element | |
// ( <- a tuple | |
// (int)<- the type of the parameter, grouping with parenthesis | |
// , firstArg | |
// ) <- completes the tuple for the first function argument | |
// ) <- completes the first element in the sequence of f. args. | |
// (((int), secondArg)) <- second element in the sequence of f. args. | |
// ) <- end of the function specification | |
// ((void), modulus, ): will declare void modulus() | |
#define ZOO_PP_D_TYPE_FROM_MEMBER(type, name) type | |
#define ZOO_PP_D_NAME_FROM_MEMBER(type, name) name | |
// declares an identifier | |
// note the use of _QUOTE to remove parenthesis | |
#define ZOO_PP_D_DECLARE(type, name) ZOO_PP_QUOTE type name | |
#define ZOO_PP_D_DECLARE_MEMBER(type, name) ZOO_PP_D_DECLARE(type, name); | |
// Macros to declare a function | |
// Macro to pass to BOOST_SEQ_FOR_EACH_I with the sequence of arguments | |
#define ZOO_PP_D_SEQI_DECLARE_PARAMETER(R, _, ndx, argument) \ | |
BOOST_PP_COMMA_IF(ndx) ZOO_PP_D_DECLARE argument | |
#define ZOO_PP_D_DECLARE_PLAIN_FUNCTION(returnType, name, arguments) \ | |
ZOO_PP_QUOTE returnType \ | |
name \ | |
( \ | |
BOOST_PP_SEQ_FOR_EACH_I( \ | |
ZOO_PP_D_SEQI_DECLARE_PARAMETER, ~, arguments \ | |
) \ | |
); | |
// Macros to declare the normal memory layout type | |
#define ZOO_PP_D_SEQ_DECLARE_MEMBER(_, __, m) ZOO_PP_D_DECLARE_MEMBER m | |
#define ZOO_PP_D_SEQ_DECLARE_FUNCTION(_, __, f) \ | |
ZOO_PP_D_DECLARE_PLAIN_FUNCTION f | |
#define ZOO_PP_D_DECLARE_AGGREGATE(name, members, functions) \ | |
struct name { \ | |
BOOST_PP_SEQ_FOR_EACH( \ | |
ZOO_PP_D_SEQ_DECLARE_MEMBER, \ | |
~, \ | |
members \ | |
) \ | |
BOOST_PP_SEQ_FOR_EACH( \ | |
ZOO_PP_D_SEQ_DECLARE_FUNCTION, \ | |
~, \ | |
functions \ | |
) \ | |
}; | |
// Macros to declare the handle class | |
#define ZOO_PP_D_HANDLE_ACCESSOR(global, type, name) \ | |
ZOO_PP_QUOTE type &name() { return global.name[this->index_]; } | |
#define ZOO_PP_D_SEQ_HANDLE_ACCESSOR(_, global, member) \ | |
ZOO_PP_D_HANDLE_ACCESSOR( \ | |
global, \ | |
ZOO_PP_D_TYPE_FROM_MEMBER member, \ | |
ZOO_PP_D_NAME_FROM_MEMBER member \ | |
) | |
#define ZOO_PP_D_HANDLE(name, members, functions) \ | |
struct BOOST_PP_CAT(name, _handle) { \ | |
unsigned index_; \ | |
BOOST_PP_SEQ_FOR_EACH( \ | |
ZOO_PP_D_SEQ_HANDLE_ACCESSOR, \ | |
BOOST_PP_CAT(g_, name), \ | |
members \ | |
) \ | |
BOOST_PP_SEQ_FOR_EACH( \ | |
ZOO_PP_D_SEQ_DECLARE_FUNCTION, \ | |
~, \ | |
functions \ | |
) \ | |
}; | |
#define ZOO_PP_D_COLUMN_IMPL(functor, type, name) \ | |
functor<ZOO_PP_QUOTE type> name; | |
#define ZOO_PP_D_SEQ_COLUMN(_, functor, member) \ | |
ZOO_PP_D_COLUMN_IMPL( \ | |
functor, \ | |
ZOO_PP_D_TYPE_FROM_MEMBER member, \ | |
ZOO_PP_D_NAME_FROM_MEMBER member \ | |
) | |
#define ZOO_PP_D_COLUMNAR_STATE(storageTypeFunctor, name, members, functions) \ | |
struct { \ | |
BOOST_PP_SEQ_FOR_EACH(ZOO_PP_D_SEQ_COLUMN, storageTypeFunctor, members) \ | |
} BOOST_PP_CAT(g_, name); | |
#ifndef SP | |
#include <map> | |
#include <vector> | |
#include <optional> | |
#endif | |
struct Position {}; | |
struct Orientation {}; | |
#define SPRITE_SPECIFICATION \ | |
Sprite, \ | |
(((Position), p))(((Orientation), o))(((void *), data)), \ | |
(( \ | |
(double), distance, (((Position), point)) \ | |
)) \ | |
(( \ | |
(void), modulus, \ | |
)) | |
ZOO_PP_INVOKE(ZOO_PP_D_COLUMNAR_STATE, std::vector, SPRITE_SPECIFICATION) | |
ZOO_PP_INVOKE(ZOO_PP_D_DECLARE_AGGREGATE, SPRITE_SPECIFICATION) | |
ZOO_PP_INVOKE(ZOO_PP_D_HANDLE, SPRITE_SPECIFICATION) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment