Nebula
Loading...
Searching...
No Matches
id.h
Go to the documentation of this file.
1#pragma once
2//------------------------------------------------------------------------------
12//------------------------------------------------------------------------------
13#include <cstdint>
14#include "core/types.h"
15
16#define ID_32_TYPE(x) struct x { \
17 Ids::Id32 id; \
18 constexpr x() : id(Ids::InvalidId32) {}; \
19 constexpr x(const Ids::Id32 id) : id(id) {}; \
20 constexpr explicit operator Ids::Id32() const { return id; } \
21 static constexpr x Invalid() { return Ids::InvalidId32; } \
22 constexpr uint32_t HashCode() const { return id; } \
23 const bool operator==(const x& rhs) const { return id == rhs.id; } \
24 const bool operator!=(const x& rhs) const { return id != rhs.id; } \
25 const bool operator<(const x& rhs) const { return HashCode() < rhs.HashCode(); } \
26 const bool operator>(const x& rhs) const { return HashCode() > rhs.HashCode(); } \
27 template <typename T> constexpr T As() const { static_assert(sizeof(T) == sizeof(x), "Can only convert between ID types of equal size"); T ret; memcpy((void*)&ret, this, sizeof(T)); return ret; }; \
28 }; \
29 static constexpr x Invalid##x = Ids::InvalidId32;
30
31#define ID_16_TYPE(x) struct x { \
32 Ids::Id16 id; \
33 constexpr x() : id(Ids::InvalidId16) {}; \
34 constexpr x(const Ids::Id16 id) : id(id) {}; \
35 constexpr explicit operator Ids::Id16() const { return id; } \
36 static constexpr x Invalid() { return Ids::InvalidId16; } \
37 constexpr uint32_t HashCode() const { return (uint32_t)(id); } \
38 const bool operator==(const x& rhs) const { return id == rhs.id; } \
39 const bool operator!=(const x& rhs) const { return id != rhs.id; } \
40 const bool operator<(const x& rhs) const { return HashCode() < rhs.HashCode(); } \
41 const bool operator>(const x& rhs) const { return HashCode() > rhs.HashCode(); } \
42 template <typename T> constexpr T As() const { static_assert(sizeof(T) == sizeof(x), "Can only convert between ID types of equal size"); T ret; memcpy((void*)&ret, this, sizeof(T)); return ret; }; \
43 }; \
44 static constexpr x Invalid##x = Ids::InvalidId16;
45
46#define ID_32_24_8_NAMED_TYPE(x, id32_name, id24_name, id8_name, combined_name) struct x { \
47 Ids::Id32 id32_name : 32;\
48 union\
49 {\
50 struct\
51 {\
52 Ids::Id32 id24_name : 24;\
53 Ids::Id32 id8_name: 8;\
54 };\
55 Ids::Id32 combined_name;\
56 };\
57 constexpr x() : id32_name(Ids::InvalidId32), id24_name(Ids::InvalidId24), id8_name(Ids::InvalidId8) {};\
58 constexpr x(const Ids::Id32 id32, const Ids::Id24 id24, const Ids::Id8 id8) : id32_name(id32), id24_name(id24), id8_name(id8){} \
59 constexpr x(const Ids::Id64 id) : id32_name(Ids::Id::GetHigh(id)), id24_name(Ids::Index(Ids::Id::GetLow(id))), id8_name(Ids::Generation(Ids::Id::GetLow(id))) {};\
60 explicit constexpr operator Ids::Id64() const { return Ids::Id::MakeId32_24_8(id32_name, id24_name, id8_name); }\
61 static constexpr x Invalid() { return Ids::Id::MakeId32_24_8(Ids::InvalidId32, Ids::InvalidId24, Ids::InvalidId8); }\
62 constexpr uint32_t HashCode() const { return (uint32_t)combined_name; }\
63 constexpr Ids::Id64 HashCode64() const { return Ids::Id::MakeId32_24_8(id32_name, id24_name, id8_name); }\
64 const bool operator==(const x& rhs) const { return id32_name == rhs.id32_name && id24_name == rhs.id24_name && id8_name == rhs.id8_name; }\
65 const bool operator!=(const x& rhs) const { return id32_name != rhs.id32_name || id24_name != rhs.id24_name || id8_name != rhs.id8_name; }\
66 const bool operator<(const x& rhs) const { return HashCode64() < rhs.HashCode64(); }\
67 const bool operator>(const x& rhs) const { return HashCode64() > rhs.HashCode64(); }\
68 template <typename T> constexpr T As() const { static_assert(sizeof(T) == sizeof(x), "Can only convert between ID types of equal size"); T ret; memcpy((void*)&ret, this, sizeof(T)); return ret; }; \
69 }; \
70 static constexpr x Invalid##x = Ids::Id::MakeId32_24_8(Ids::InvalidId32, Ids::InvalidId24, Ids::InvalidId8);
71#define ID_32_24_8_TYPE(x) ID_32_24_8_NAMED_TYPE(x, parent, index, generation, id)
72
73#define ID_24_8_24_8_NAMED_TYPE(x, id24_0_name, id8_0_name, id24_1_name, id8_1_name, combined0_name, combined1_name) struct x { \
74 union\
75 {\
76 struct\
77 {\
78 Ids::Id32 id24_0_name : 24;\
79 Ids::Id8 id8_0_name : 8;\
80 };\
81 Ids::Id32 combined0_name;\
82 };\
83 union\
84 {\
85 struct\
86 {\
87 Ids::Id32 id24_1_name : 24;\
88 Ids::Id8 id8_1_name : 8;\
89 };\
90 Ids::Id32 combined1_name;\
91 };\
92 constexpr x() : combined0_name(Ids::InvalidId32), combined1_name(Ids::InvalidId32) {};\
93 constexpr x(const Ids::Id24 id24_0, const Ids::Id8 id8_0, const Ids::Id24 id24_1, const Ids::Id8 id8_1) : id24_0_name(id24_0), id8_0_name(id8_0), id24_1_name(id24_1), id8_1_name(id8_1) {} \
94 constexpr x(const Ids::Id64 id) : combined0_name(Ids::Id::GetLow(id)), combined1_name(Ids::Id::GetHigh(id)) {};\
95 explicit constexpr operator Ids::Id64() const { return Ids::Id::MakeId24_8_24_8(id24_0_name, id8_0_name, id24_1_name, id8_1_name); }\
96 static constexpr x Invalid() { return Ids::InvalidId64; }\
97 constexpr Ids::Id32 AllocId() const { return combined1_name; }\
98 constexpr uint32_t HashCode() const { return (uint32_t)combined0_name; }\
99 constexpr Ids::Id64 HashCode64() const { return Ids::Id::MakeId24_8_24_8(id24_0_name, id8_0_name, id24_1_name, id8_1_name); }\
100 const bool operator==(const x& rhs) const { return id24_0_name == rhs.id24_0_name && id8_0_name == rhs.id8_0_name && id24_1_name == rhs.id24_1_name && id8_1_name == rhs.id8_1_name; }\
101 const bool operator!=(const x& rhs) const { return id24_0_name != rhs.id24_0_name || id8_0_name != rhs.id8_0_name || id24_1_name != rhs.id24_1_name || id8_1_name != rhs.id8_1_name; }\
102 const bool operator<(const x& rhs) const { return HashCode64() < rhs.HashCode64(); }\
103 const bool operator>(const x& rhs) const { return HashCode64() > rhs.HashCode64(); }\
104 template <typename T> constexpr T As() const { static_assert(sizeof(T) == sizeof(x), "Can only convert between ID types of equal size"); T ret; memcpy((void*)&ret, this, sizeof(T)); return ret; }; \
105 }; \
106 static constexpr x Invalid##x = Ids::Id::MakeId24_8_24_8(Ids::InvalidId24, Ids::InvalidId8, Ids::InvalidId24, Ids::InvalidId8);
107#define ID_24_8_24_8_TYPE(x) ID_24_8_24_8_NAMED_TYPE(x, index0, generation0, index1, generation1, id0, id1)
108
109#define ID_24_8_NAMED_TYPE(x, id24_name, id8_name, combined_name) struct x { \
110 union \
111 {\
112 struct\
113 {\
114 Ids::Id32 id24_name : 24; \
115 Ids::Id32 id8_name : 8; \
116 };\
117 Ids::Id32 combined_name;\
118 }; \
119 constexpr x() : id24_name(Ids::InvalidId24), id8_name(Ids::InvalidId8) {} \
120 constexpr x(const Ids::Id24 id0, const Ids::Id8 id1) : id24_name(id0), id8_name(id1) {} \
121 constexpr x(const Ids::Id32 id) : combined_name(id) {};\
122 explicit constexpr operator Ids::Id32() const { return combined_name; }\
123 static constexpr x Invalid() { return Ids::InvalidId32; }\
124 constexpr uint32_t HashCode() const { return (uint32_t)combined_name; }\
125 const bool operator==(const x& rhs) const { return id24_name == rhs.id24_name && id8_name == rhs.id8_name; }\
126 const bool operator!=(const x& rhs) const { return id24_name != rhs.id24_name || id8_name != rhs.id8_name; }\
127 const bool operator<(const x& rhs) const { return HashCode() < rhs.HashCode(); }\
128 const bool operator>(const x& rhs) const { return HashCode() > rhs.HashCode(); }\
129 template <typename T> constexpr T As() const { static_assert(sizeof(T) == sizeof(x), "Can only convert between ID types of equal size"); T ret; memcpy((void*)&ret, this, sizeof(T)); return ret; }; \
130 }; \
131 static constexpr x Invalid##x = Ids::Id::MakeId24_8(Ids::InvalidId24, Ids::InvalidId8);
132#define ID_24_8_TYPE(x) ID_24_8_NAMED_TYPE(x, index, generation, id)
133
134namespace Ids
135{
136
137typedef uint64_t Id64;
138typedef uint32_t Id32;
139typedef uint32_t Id24;
140typedef uint16_t Id16;
141typedef uint8_t Id8;
142static constexpr Id64 InvalidId64 = 0xFFFFFFFFFFFFFFFF;
143static constexpr Id32 InvalidId32 = 0xFFFFFFFF;
144static constexpr Id24 InvalidId24 = 0x00FFFFFF;
145static constexpr Id16 InvalidId16 = 0xFFFF;
146static constexpr Id8 InvalidId8 = 0xFF;
147
148struct Id
149{
151 static void SetHigh(Id64& id, const Id32 bits);
153 static constexpr Id32 GetHigh(const Id64 id);
155 static constexpr Id16 GetHigh(const Id32 bits);
157 static constexpr Id24 GetBig(const Id32 bits);
159 static constexpr Id8 GetTiny(const Id32 bits);
161 static void SetLow(Id64& id, const Id32 bits);
163 static constexpr Id32 GetLow(const Id64 id);
165 static constexpr Id16 GetLow(const Id32 bits);
167 static constexpr Id64 MakeId64(const Id32 low, const Id32 high);
169 static constexpr Id32 MakeId32(const Id16 high, const Id16 low);
171 static constexpr Id32 MakeId24_8(const Id24 big, const Id8 tiny);
173 static constexpr Id64 MakeId32_24_8(const Id32 upper, const Id24 big, const Id8 tiny);
175 static constexpr Id64 MakeId32_16_16(const Id32 upper, const Id16 high, const Id16 low);
177 static constexpr Id64 MakeId24_8_24_8(const Id24 big0, const Id8 tiny0, const Id24 big1, const Id8 tiny1);
179 static void Split64(Id64 split, Id32& upper, Id32& lower);
181 static void Split32(Id32 split, Id16& upper, Id16& lower);
183 static void Split24_8(Id32 split, Id24& big, Id8& tiny);
184};
185
186//------------------------------------------------------------------------------
189inline void
190Id::SetHigh(Id64& id, const Id32 bits)
191{
192 id = (((uint64_t)bits) << 32) & 0xFFFFFFFF00000000;
193}
194
195//------------------------------------------------------------------------------
198inline constexpr Id32
200{
201 return (uint32_t)((id >> 32) & 0x00000000FFFFFFFF);
202}
203
204//------------------------------------------------------------------------------
207inline constexpr Id16
208Id::GetHigh(const Id32 bits)
209{
210 return (uint16_t)((bits >> 16) & 0x0000FFFF);
211}
212
213//------------------------------------------------------------------------------
216inline constexpr Id32
217Id::GetBig(const Id32 bits)
218{
219 return (bits & 0xFFFFFF00) >> 8;
220}
221
222//------------------------------------------------------------------------------
225inline constexpr Id8
226Id::GetTiny(const Id32 bits)
227{
228 return (bits & 0x000000FF);
229}
230
231//------------------------------------------------------------------------------
234inline void
235Id::SetLow(Id64& id, const Id32 bits)
236{
237 id = ((uint64_t)bits) & 0x00000000FFFFFFFF;
238}
239
240//------------------------------------------------------------------------------
243inline constexpr Id32
245{
246 return (uint32_t)((id) & 0x00000000FFFFFFFF);
247}
248
249//------------------------------------------------------------------------------
252inline constexpr Id16
253Id::GetLow(const Id32 bits)
254{
255 return (uint16_t)((bits) & 0x0000FFFF);
256}
257
258//------------------------------------------------------------------------------
261inline constexpr Ids::Id64
262Id::MakeId64(const Id32 high, const Id32 low)
263{
264 return (((uint64_t)low) & 0x00000000FFFFFFFF) + ((((uint64_t)high) << 32) & 0xFFFFFFFF00000000);
265}
266
267//------------------------------------------------------------------------------
270inline constexpr Id32
271Id::MakeId32(const Id16 high, const Id16 low)
272{
273 return (((uint32_t)low) & 0x0000FFFF) + ((((uint32_t)high) << 16) & 0xFFFF0000);
274}
275
276//------------------------------------------------------------------------------
279inline constexpr Id32
280Id::MakeId24_8(const Id24 big, const Id8 tiny)
281{
282 return (((uint32_t)tiny) & 0x000000FF) + ((big << 8) & 0xFFFFFF00);
283}
284
285//------------------------------------------------------------------------------
288inline constexpr Id64
289Id::MakeId32_24_8(const Id32 upper, const Id24 big, const Id8 tiny)
290{
291 return (((uint64_t)upper << 32) & 0xFFFFFFFF00000000) + (((uint64_t)tiny) & 0x00000000000000FF) + (((uint64_t)big << 8) & 0x00000000FFFFFF00);
292}
293
294
295//------------------------------------------------------------------------------
298inline constexpr Id64
299Id::MakeId32_16_16(const Id32 upper, const Id16 high, const Id16 low)
300{
301 return (((uint64_t)upper << 32) & 0xFFFFFFFF00000000) + (((uint64_t)high) & 0x00000000FFFF0000) + (((uint64_t)low << 8) & 0x000000000000FFFF);
302}
303
304//------------------------------------------------------------------------------
307inline constexpr Id64
308Id::MakeId24_8_24_8(const Id24 big0, const Id8 tiny0, const Id24 big1, const Id8 tiny1)
309{
310 return (((uint64_t)big0 << 40) & 0xFFFFFF0000000000) + (((uint64_t)tiny0 << 32) & 0x000000FF00000000) + (((uint64_t)big1 << 8) & 0x00000000FFFFFF00) + (((uint64_t)tiny1) & 0x00000000000000FF);
311}
312
313//------------------------------------------------------------------------------
316inline void
317Id::Split64(Id64 split, Id32& upper, Id32& lower)
318{
319 upper = GetHigh(split);
320 lower = GetLow(split);
321}
322
323//------------------------------------------------------------------------------
326inline void
327Id::Split32(Id32 split, Id16& upper, Id16& lower)
328{
329 upper = GetHigh(split);
330 lower = GetLow(split);
331}
332
333//------------------------------------------------------------------------------
336inline void
337Id::Split24_8(Id32 split, Id24& big, Id8& tiny)
338{
339 big = GetBig(split);
340 tiny = GetTiny(split);
341}
342
343} // namespace Ids
This simple Id pool implements a set of free and used consecutive integers.
Definition id.h:135
static constexpr Id24 InvalidId24
Definition id.h:144
static constexpr Id8 InvalidId8
Definition id.h:146
static constexpr Id64 InvalidId64
Definition id.h:142
uint32_t Id24
Definition id.h:139
uint8_t Id8
Definition id.h:141
uint32_t Id32
Definition id.h:138
static constexpr Id32 InvalidId32
Definition id.h:143
uint16_t Id16
Definition id.h:140
uint64_t Id64
Definition id.h:137
static constexpr Id16 InvalidId16
Definition id.h:145
This class implements some static helper functions to set high and low 32-bit integers,...
Definition id.h:149
static constexpr Id8 GetTiny(const Id32 bits)
get tiny piece of 24-8 bit integer
Definition id.h:226
static constexpr Id24 GetBig(const Id32 bits)
get big piece of 24-8 bit integer
Definition id.h:217
static void Split64(Id64 split, Id32 &upper, Id32 &lower)
split 64 bit integer into 2 32 0bit integers
Definition id.h:317
static constexpr Id32 GetLow(const Id64 id)
get low (rightmost) 32 bits
Definition id.h:244
static void Split32(Id32 split, Id16 &upper, Id16 &lower)
split 32 bit integer into 2 16 bit integers
Definition id.h:327
static constexpr Id32 GetHigh(const Id64 id)
get high (leftmost) 32 bits
Definition id.h:199
static constexpr Id64 MakeId32_24_8(const Id32 upper, const Id24 big, const Id8 tiny)
set 32-24-8 bits 64 bit integer
Definition id.h:289
static constexpr Id32 MakeId24_8(const Id24 big, const Id8 tiny)
set 24-8 bits in integer
Definition id.h:280
static constexpr Id64 MakeId24_8_24_8(const Id24 big0, const Id8 tiny0, const Id24 big1, const Id8 tiny1)
set 24-8-24-8 bits 64 bit integer
Definition id.h:308
static constexpr Id64 MakeId64(const Id32 low, const Id32 high)
create new Id using both high and low bits
Definition id.h:262
static void SetHigh(Id64 &id, const Id32 bits)
set high (leftmost) 32 bits
Definition id.h:190
static constexpr Id32 MakeId32(const Id16 high, const Id16 low)
set 16-16 bits id by low and high
Definition id.h:271
static void Split24_8(Id32 split, Id24 &big, Id8 &tiny)
split 32 bit integer into 24-8 bit integer
Definition id.h:337
static constexpr Id64 MakeId32_16_16(const Id32 upper, const Id16 high, const Id16 low)
set 32-16-16 bits 64 bit integer
Definition id.h:299
static void SetLow(Id64 &id, const Id32 bits)
set low (rightmost) 32 bits
Definition id.h:235