Empirical
class.h
Go to the documentation of this file.
1 // This file is part of Empirical, https://github.com/mercere99/Empirical/
2 // Copyright (C) Michigan State University, 2016.
3 // Released under the MIT Software license; see doc/LICENSE
4 //
5 //
6 // A re-engineering of tuple_struct.h, intended to be usable throughout Empirical.
7 //
8 // The EMP_CLASS macro builds an inexpensive class that
9 // * Can fully reflect on its contents. (todo)
10 // * Is easily serializable (todo)
11 // * Can be effortlessly moved between C++ and Javascript (todo)
12 //
13 // EMP_CLASS( NAME,
14 // TYPE1, ID1, DEFAULT1,
15 // TYPE2, ID2, DEFAULT2,
16 // etc... )
17 //
18 // If you want to just build member functions inside of a user-defined class, you
19 // can alternatively use:
20 //
21 // EMP_MEMBERS( TYPE1, ID1,
22 // TYPE2, ID2,
23 // etc... )
24 //
25 // Further, if you make the members private and need to add accessors, you can use:
26 //
27 // EMP_ACCESSORS( NAME,
28 // TYPE1, ID1,
29 // TYPE2, ID2,
30 // etc... )
31 //
32 // Finally, if you want it to build a specialized constructor for only these elements
33 // (which should be rare, since if you're not adding more to the class, you should just
34 // trigger EMP_CLASS), you can use:
35 //
36 // EMP_CONSTRUCTOR( NAME,
37 // TYPE1, ID1, DEFAULT1,
38 // TYPE2, ID2, DEFAULT2,
39 // etc... )
40 //
41 //
42 // Developer notes:
43 // Goal: Make it trival to build a class that has self-reflection.
44 // As such, it should interact will with serializaion and Javascript conversion.
45 //
46 // An alternative option is to do something similar to the config object. In order to build
47 // a dynamic class, one would just create a file with a full set of macro calls. They would
48 // need to be included several times -- it might not be possible, but if it is it wouild allow
49 // an arbitrarily large class definition.
50 
51 #ifndef EMP_CLASS_H
52 #define EMP_CLASS_H
53 
54 // EMP_MEMBERS expects a series of type/id pairs to setup.
55 #define EMP_CLASS_MEMBER_DECLARE(TYPE, ID) TYPE ID;
56 #define EMP_CLASS_MEMBERS(...) EMP_WRAP_ARG_PAIRS(EMP_MEMBER_DECLARE, __VA_ARGS__)
57 
58 // EMP_CLASS_ACCESSORS_DECLARE expect the name of this class, the type of the id,
59 // and the name of the id.
60 #define EMP_CLASS_ACCESSORS_DECLARE(NAME, TYPE, ID) \
61  public: TYPE Get ## ID() { return m_ ## ID; } \
62  NAME & Set ## ID(const TYPE & _in) { m_ ## ID = _in; return *this; }
63 
64 // EMP_CLASS_ACCESSORS expect the name of the class followd by type/id pairs to setup.
65 #define EMP_CLASS_ACCASSORS(NAME, ...) @CAO
66 
67 // EMP_CLASS_CONSTRUCTOR takes the class name followd by a set of types, ids, and default
68 // values which it uses to setup initialization.
69 #define EMP_CLASS_CONSTRUCTOR(NAME, ...) @CAO
70 
71 #define EMP_CLASS( NAME, ...) \
72  class NAME { \
73  private: \
74  EMP_CLASS_MEMBERS(EMP_FILTER_ARGS((i,i,x), __VA_ARGS__)) \
75  public: \
76  EMP_CLASS_ACCESSORS(NAME, EMP_FILTER_ARGS((i,i,x), __VA_ARGS__)) \
77  };
78 
79 
80 #endif