NamedTuple.hpp
Go to the documentation of this file.
1 //
3 // Aurora C++ Library
4 // Copyright (c) 2012-2016 Jan Haller
5 //
6 // This software is provided 'as-is', without any express or implied
7 // warranty. In no event will the authors be held liable for any damages
8 // arising from the use of this software.
9 //
10 // Permission is granted to anyone to use this software for any purpose,
11 // including commercial applications, and to alter it and redistribute it
12 // freely, subject to the following restrictions:
13 //
14 // 1. The origin of this software must not be misrepresented; you must not
15 // claim that you wrote the original software. If you use this software
16 // in a product, an acknowledgment in the product documentation would be
17 // appreciated but is not required.
18 //
19 // 2. Altered source versions must be plainly marked as such, and must not be
20 // misrepresented as being the original software.
21 //
22 // 3. This notice may not be removed or altered from any source distribution.
23 //
25 
28 
29 #ifndef AURORA_NAMEDTUPLE_HPP
30 #define AURORA_NAMEDTUPLE_HPP
31 
33 #include <Aurora/Tools/Hash.hpp>
34 
35 #include <tuple>
36 
37 
40 
41 // Note: Inconsistent syntax "T const&" instead of "const T&" because T is not a real type, only text replacement
42 // Thus, the former leads to problems in cases like pointers
43 
44 // Constructor parameter
45 #define AURORA_DETAIL_PARAM_TV(Type, var) Type const& var
46 #define AURORA_DETAIL_PARAM_P(pair) AURORA_DETAIL_PARAM_TV pair
47 #define AURORA_DETAIL_PARAM(pair, index) AURORA_PP_COMMA_IF(index) AURORA_DETAIL_PARAM_P(pair)
48 
49 // Constructor initialization list: Value initialization / copy construction
50 #define AURORA_DETAIL_INIT_TV(Type, var) var(var)
51 #define AURORA_DETAIL_INIT_P(pair) AURORA_DETAIL_INIT_TV pair
52 #define AURORA_DETAIL_INIT(pair, index) AURORA_PP_COMMA_IF(index) AURORA_DETAIL_INIT_P(pair)
53 
54 // Constructor initialization list: Default construction
55 #define AURORA_DETAIL_INITDEFAULT_TV(Type, var) var()
56 #define AURORA_DETAIL_INITDEFAULT_P(pair) AURORA_DETAIL_INITDEFAULT_TV pair
57 #define AURORA_DETAIL_INITDEFAULT(pair, index) AURORA_PP_COMMA_IF(index) AURORA_DETAIL_INITDEFAULT_P(pair)
58 
59 // Member variable declaration
60 #define AURORA_DETAIL_MEMDECL_TV(Type, var) Type var;
61 #define AURORA_DETAIL_MEMDECL_P(pair) AURORA_DETAIL_MEMDECL_TV pair
62 #define AURORA_DETAIL_MEMDECL(pair, index) AURORA_DETAIL_MEMDECL_P(pair)
63 
64 // Variable passed as argument for std::make_tuple()
65 #define AURORA_DETAIL_VAR_TV(Type, var) var
66 #define AURORA_DETAIL_VAR_P(pair) AURORA_DETAIL_VAR_TV pair
67 #define AURORA_DETAIL_VAR(pair, index) AURORA_PP_COMMA_IF(index) AURORA_DETAIL_VAR_P(pair)
68 
69 // Type passed as template argument for std::tuple
70 #define AURORA_DETAIL_TYPE_TV(Type, var) Type
71 #define AURORA_DETAIL_TYPE_P(pair) AURORA_DETAIL_TYPE_TV pair
72 #define AURORA_DETAIL_TYPE(pair, index) AURORA_PP_COMMA_IF(index) AURORA_DETAIL_TYPE_P(pair)
73 
74 // Combine hash h with hash of member variable
75 #define AURORA_DETAIL_HASHCOMBINE_TV(Type, var) aurora::hashCombine(h, t.var);
76 #define AURORA_DETAIL_HASHCOMBINE_P(pair) AURORA_DETAIL_HASHCOMBINE_TV pair
77 #define AURORA_DETAIL_HASHCOMBINE(pair, index) AURORA_DETAIL_HASHCOMBINE_P(pair)
78 
79 // High-order macro to apply an extension
80 #define AURORA_DETAIL_EXTENSION(macro, index, args) macro args
81 
82 // Helper macro for AURORA_NT_DEFAULT_CTOR
83 #define AURORA_DETAIL_DEFAULT_CTOR(TupleName, typeVarPairs) \
84  TupleName() \
85  : AURORA_PP_FOREACH(AURORA_DETAIL_INITDEFAULT, typeVarPairs) \
86  { \
87  } \
88 
89 // Conversion function from named tuple to std::tuple
90 #define AURORA_DETAIL_TOSTDTUPLE(typeVarPairs) \
91  std::tuple<AURORA_PP_FOREACH(AURORA_DETAIL_TYPE, typeVarPairs)> toStdTuple() const \
92  { \
93  return std::make_tuple(AURORA_PP_FOREACH(AURORA_DETAIL_VAR, typeVarPairs)); \
94  } \
95 
96 // Macro to define base functionality within named tuple
97 #define AURORA_DETAIL_BASE_TUPLE(TupleName, typeVarPairs, extensions) \
98  /* Member variables */ \
99  AURORA_PP_FOREACH(AURORA_DETAIL_MEMDECL, typeVarPairs) \
100  \
101  /* Constructor */ \
102  explicit TupleName(AURORA_PP_FOREACH(AURORA_DETAIL_PARAM, typeVarPairs)) \
103  AURORA_PP_IF(AURORA_PP_SIZE(typeVarPairs), :, AURORA_PP_NOTHING) \
104  AURORA_PP_FOREACH(AURORA_DETAIL_INIT, typeVarPairs) \
105  { \
106  } \
107  \
108  /* toStdTuple() conversion function */ \
109  AURORA_DETAIL_TOSTDTUPLE(typeVarPairs) \
110 
111 // ---------------------------------------------------------------------------------------------------------------------------
112 
113 
118 #define AURORA_NT_EQUAL(TupleName, typeVarPairs) \
119  friend bool operator== (const TupleName& lhs, const TupleName& rhs) \
120  { \
121  return lhs.toStdTuple() == rhs.toStdTuple(); \
122  } \
123 
124 #define AURORA_NT_LESS(TupleName, typeVarPairs) \
129  friend bool operator< (const TupleName& lhs, const TupleName& rhs) \
130  { \
131  return lhs.toStdTuple() < rhs.toStdTuple(); \
132  } \
133 
134 #define AURORA_NT_HASHER(TupleName, typeVarPairs) \
139  struct Hasher \
140  { \
141  std::size_t operator() (const TupleName& t) const \
142  { \
143  std::size_t h = 0; \
144  AURORA_PP_FOREACH(AURORA_DETAIL_HASHCOMBINE, typeVarPairs) \
145  return h; \
146  } \
147  }; \
148 
149 #define AURORA_NT_DEFAULT_CTOR(TupleName, typeVarPairs) \
154 AURORA_PP_IF(AURORA_PP_SIZE(typeVarPairs), /* there is already a 0-argument ctor if size==0 */ \
155  AURORA_DETAIL_DEFAULT_CTOR, AURORA_PP_VA_CONSUME)(TupleName, typeVarPairs) \
156  /* Note: Above, we need PP_IF() to evaluate lazily, that's why the arguments are outside */
157 
158 
188 #define AURORA_NAMED_TUPLE(TupleName, typeVarPairs) \
189 struct TupleName \
190 { \
191  AURORA_DETAIL_BASE_TUPLE(TupleName, typeVarPairs, extensions) \
192 }; \
193 
194 #define AURORA_NAMED_TUPLE_EXT(TupleName, typeVarPairs, extensions) \
223 struct TupleName \
224 { \
225  AURORA_DETAIL_BASE_TUPLE(TupleName, typeVarPairs, extensions) \
226  \
227  /* All extensions -- use positive size because size creates problems with called high-order macros */ \
228  AURORA_PP_FOREACH_DATA_SIZED(AURORA_DETAIL_EXTENSION, AURORA_PP_POSITIVE_SIZE(extensions), \
229  extensions, (TupleName, typeVarPairs)) \
230 }; \
231 
232 
234 #endif // AURORA_NAMEDTUPLE_HPP
Extensions to std::hash.
Utilities for preprocessor metaprogramming.