diff options
Diffstat (limited to 'src/uniquekey.h')
-rw-r--r-- | src/uniquekey.h | 91 |
1 files changed, 53 insertions, 38 deletions
diff --git a/src/uniquekey.h b/src/uniquekey.h index 84553a5..738cb51 100644 --- a/src/uniquekey.h +++ b/src/uniquekey.h | |||
@@ -5,77 +5,92 @@ | |||
5 | 5 | ||
6 | #include <bit> | 6 | #include <bit> |
7 | 7 | ||
8 | // ################################################################################################# | ||
9 | |||
8 | class UniqueKey | 10 | class UniqueKey |
9 | { | 11 | { |
10 | private: | 12 | protected: |
11 | 13 | ||
12 | uintptr_t m_storage; | 14 | uintptr_t const m_storage{ 0 }; |
13 | 15 | ||
14 | public: | 16 | public: |
15 | 17 | ||
16 | char const* m_debugName{ nullptr }; | 18 | char const* m_debugName{ nullptr }; |
17 | 19 | ||
20 | // --------------------------------------------------------------------------------------------- | ||
18 | constexpr explicit UniqueKey(uint64_t val_, char const* debugName_ = nullptr) | 21 | constexpr explicit UniqueKey(uint64_t val_, char const* debugName_ = nullptr) |
19 | #if LUAJIT_FLAVOR() == 64 // building against LuaJIT headers for 64 bits, light userdata is restricted to 47 significant bits, because LuaJIT uses the other bits for internal optimizations | 22 | #if LUAJIT_FLAVOR() == 64 // building against LuaJIT headers for 64 bits, light userdata is restricted to 47 significant bits, because LuaJIT uses the other bits for internal optimizations |
20 | : m_storage{ static_cast<uintptr_t>(val_ & 0x7fffffffffffull) } | 23 | : m_storage{ static_cast<uintptr_t>(val_ & 0x7FFFFFFFFFFFull) } |
21 | #else // LUAJIT_FLAVOR() | 24 | #else // LUAJIT_FLAVOR() |
22 | : m_storage{ static_cast<uintptr_t>(val_) } | 25 | : m_storage{ static_cast<uintptr_t>(val_) } |
23 | #endif // LUAJIT_FLAVOR() | 26 | #endif // LUAJIT_FLAVOR() |
24 | , m_debugName{ debugName_ } | 27 | , m_debugName{ debugName_ } |
25 | { | 28 | { |
26 | } | 29 | } |
30 | // --------------------------------------------------------------------------------------------- | ||
27 | constexpr UniqueKey(UniqueKey const& rhs_) = default; | 31 | constexpr UniqueKey(UniqueKey const& rhs_) = default; |
28 | constexpr bool operator!=(UniqueKey const& rhs_) const | 32 | // --------------------------------------------------------------------------------------------- |
33 | constexpr std::strong_ordering operator<=>(UniqueKey const& rhs_) const = default; | ||
34 | // --------------------------------------------------------------------------------------------- | ||
35 | bool equals(lua_State* const L_, int i_) const | ||
29 | { | 36 | { |
30 | return m_storage != rhs_.m_storage; | 37 | return lua_touserdata(L_, i_) == std::bit_cast<void*>(m_storage); |
31 | } | 38 | } |
32 | constexpr bool operator==(UniqueKey const& rhs_) const | 39 | // --------------------------------------------------------------------------------------------- |
40 | void pushKey(lua_State* const L_) const | ||
33 | { | 41 | { |
34 | return m_storage == rhs_.m_storage; | 42 | lua_pushlightuserdata(L_, std::bit_cast<void*>(m_storage)); |
35 | } | 43 | } |
44 | }; | ||
36 | 45 | ||
37 | void pushKey(lua_State* const L) const | 46 | // ################################################################################################# |
38 | { | 47 | |
39 | lua_pushlightuserdata(L, std::bit_cast<void*>(m_storage)); | 48 | class RegistryUniqueKey : public UniqueKey |
40 | } | 49 | { |
41 | bool equals(lua_State* const L, int i) const | 50 | public: |
42 | { | 51 | |
43 | return lua_touserdata(L, i) == std::bit_cast<void*>(m_storage); | 52 | using UniqueKey::UniqueKey; |
44 | } | 53 | |
45 | void pushValue(lua_State* const L) const | 54 | // --------------------------------------------------------------------------------------------- |
55 | void pushValue(lua_State* const L_) const | ||
46 | { | 56 | { |
47 | STACK_CHECK_START_REL(L, 0); | 57 | STACK_CHECK_START_REL(L_, 0); |
48 | pushKey(L); | 58 | pushKey(L_); |
49 | lua_rawget(L, LUA_REGISTRYINDEX); | 59 | lua_rawget(L_, LUA_REGISTRYINDEX); |
50 | STACK_CHECK(L, 1); | 60 | STACK_CHECK(L_, 1); |
51 | } | 61 | } |
62 | // --------------------------------------------------------------------------------------------- | ||
52 | template <typename OP> | 63 | template <typename OP> |
53 | void setValue(lua_State* L, OP operation_) const | 64 | void setValue(lua_State* L_, OP operation_) const |
54 | { | 65 | { |
55 | // Note we can't check stack consistency because operation is not always a push (could be insert, replace, whatever) | 66 | // Note we can't check stack consistency because operation is not always a push (could be insert, replace, whatever) |
56 | pushKey(L); // ... key | 67 | pushKey(L_); // ... key |
57 | operation_(L); // ... key value | 68 | operation_(L_); // ... key value |
58 | lua_rawset(L, LUA_REGISTRYINDEX); // ... | 69 | lua_rawset(L_, LUA_REGISTRYINDEX); // ... |
59 | } | 70 | } |
71 | // --------------------------------------------------------------------------------------------- | ||
60 | template <typename T> | 72 | template <typename T> |
61 | T* readLightUserDataValue(lua_State* const L) const | 73 | T* readLightUserDataValue(lua_State* const L_) const |
62 | { | 74 | { |
63 | STACK_GROW(L, 1); | 75 | STACK_GROW(L_, 1); |
64 | STACK_CHECK_START_REL(L, 0); | 76 | STACK_CHECK_START_REL(L_, 0); |
65 | pushValue(L); | 77 | pushValue(L_); |
66 | T* const value{ lua_tolightuserdata<T>(L, -1) }; // lightuserdata/nil | 78 | T* const value{ lua_tolightuserdata<T>(L_, -1) }; // lightuserdata/nil |
67 | lua_pop(L, 1); | 79 | lua_pop(L_, 1); |
68 | STACK_CHECK(L, 0); | 80 | STACK_CHECK(L_, 0); |
69 | return value; | 81 | return value; |
70 | } | 82 | } |
71 | bool readBoolValue(lua_State* const L) const | 83 | // --------------------------------------------------------------------------------------------- |
84 | bool readBoolValue(lua_State* const L_) const | ||
72 | { | 85 | { |
73 | STACK_GROW(L, 1); | 86 | STACK_GROW(L_, 1); |
74 | STACK_CHECK_START_REL(L, 0); | 87 | STACK_CHECK_START_REL(L_, 0); |
75 | pushValue(L); | 88 | pushValue(L_); |
76 | bool const value{ lua_toboolean(L, -1) ? true : false}; // bool/nil | 89 | bool const value{ lua_toboolean(L_, -1) ? true : false}; // bool/nil |
77 | lua_pop(L, 1); | 90 | lua_pop(L_, 1); |
78 | STACK_CHECK(L, 0); | 91 | STACK_CHECK(L_, 0); |
79 | return value; | 92 | return value; |
80 | } | 93 | } |
81 | }; | 94 | }; |
95 | |||
96 | // ################################################################################################# | ||