aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-10-24 15:18:11 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-10-24 15:18:11 +0200
commit678ee3fe8942ade73a46a1f4ec45e2216471a3f7 (patch)
tree59fec3ad510e0c607ced1b11be5ca92877c10341
parent4044e86ea4197535b70bc434634faf90cd2317d0 (diff)
downloadlanes-678ee3fe8942ade73a46a1f4ec45e2216471a3f7.tar.gz
lanes-678ee3fe8942ade73a46a1f4ec45e2216471a3f7.tar.bz2
lanes-678ee3fe8942ade73a46a1f4ec45e2216471a3f7.zip
Improve Unique some more
-rw-r--r--src/intercopycontext.cpp12
-rw-r--r--src/keeper.cpp2
-rw-r--r--src/unique.hpp31
3 files changed, 34 insertions, 11 deletions
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp
index 7244ed8..06cafbd 100644
--- a/src/intercopycontext.cpp
+++ b/src/intercopycontext.cpp
@@ -671,7 +671,7 @@ LuaType InterCopyContext::processConversion() const
671 671
672[[nodiscard]] bool InterCopyContext::tryCopyClonable() const 672[[nodiscard]] bool InterCopyContext::tryCopyClonable() const
673{ 673{
674 SourceIndex const _L1_i{ luaG_absindex(L1, L1_i) }; 674 SourceIndex const _L1_i{ luaG_absindex(L1, L1_i).value() };
675 void* const _source{ lua_touserdata(L1, _L1_i) }; 675 void* const _source{ lua_touserdata(L1, _L1_i) };
676 676
677 STACK_CHECK_START_REL(L1, 0); 677 STACK_CHECK_START_REL(L1, 0);
@@ -740,7 +740,7 @@ LuaType InterCopyContext::processConversion() const
740 // assign uservalues 740 // assign uservalues
741 UserValueIndex _uvi{ _nuv.value() }; 741 UserValueIndex _uvi{ _nuv.value() };
742 while (_uvi > 0) { 742 while (_uvi > 0) {
743 _c.L1_i = SourceIndex{ luaG_absindex(L1, kIdxTop) }; 743 _c.L1_i = SourceIndex{ luaG_absindex(L1, kIdxTop).value() };
744 if (_c.interCopyOne() != InterCopyResult::Success) { // L2: ... u uv 744 if (_c.interCopyOne() != InterCopyResult::Success) { // L2: ... u uv
745 raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); 745 raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1));
746 } 746 }
@@ -798,7 +798,7 @@ LuaType InterCopyContext::processConversion() const
798 STACK_GROW(L2, _nuv); 798 STACK_GROW(L2, _nuv);
799 UserValueIndex _uvi{ _nuv.value() }; 799 UserValueIndex _uvi{ _nuv.value() };
800 while (_uvi) { 800 while (_uvi) {
801 _c.L1_i = SourceIndex{ luaG_absindex(L1, kIdxTop) }; 801 _c.L1_i = SourceIndex{ luaG_absindex(L1, kIdxTop).value() };
802 if (_c.interCopyOne() != InterCopyResult::Success) { // L1: ... deep ... [uv]* L2: deep uv 802 if (_c.interCopyOne() != InterCopyResult::Success) { // L1: ... deep ... [uv]* L2: deep uv
803 raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); 803 raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1));
804 } 804 }
@@ -882,7 +882,7 @@ LuaType InterCopyContext::processConversion() const
882 InterCopyContext _c{ *this }; 882 InterCopyContext _c{ *this };
883 UserValueIndex _uvi{ _nuv.value() }; 883 UserValueIndex _uvi{ _nuv.value() };
884 while (_uvi > 0) { 884 while (_uvi > 0) {
885 _c.L1_i = SourceIndex{ luaG_absindex(L1, kIdxTop) }; 885 _c.L1_i = SourceIndex{ luaG_absindex(L1, kIdxTop).value() };
886 if (_c.interCopyOne() != InterCopyResult::Success) { // L2: ... mt u uv 886 if (_c.interCopyOne() != InterCopyResult::Success) { // L2: ... mt u uv
887 raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); 887 raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1));
888 } 888 }
@@ -1301,10 +1301,10 @@ namespace {
1301 for (StackIndex _i{ (L1_i != 0) ? L1_i.value() : (_top_L1 - n_ + 1) }, _j{ 1 }; _j <= n_; ++_i, ++_j) { 1301 for (StackIndex _i{ (L1_i != 0) ? L1_i.value() : (_top_L1 - n_ + 1) }, _j{ 1 }; _j <= n_; ++_i, ++_j) {
1302 char _tmpBuf[16]; 1302 char _tmpBuf[16];
1303 if (U->verboseErrors) { 1303 if (U->verboseErrors) {
1304 sprintf(_tmpBuf, "arg_%d", _j.operator int()); 1304 sprintf(_tmpBuf, "arg_%d", _j.value());
1305 _c.name = _tmpBuf; 1305 _c.name = _tmpBuf;
1306 } 1306 }
1307 _c.L1_i = SourceIndex{ _i }; 1307 _c.L1_i = SourceIndex{ _i.value() };
1308 _copyok = _c.interCopyOne(); // L2: ... cache {}n 1308 _copyok = _c.interCopyOne(); // L2: ... cache {}n
1309 if (_copyok != InterCopyResult::Success) { 1309 if (_copyok != InterCopyResult::Success) {
1310 break; 1310 break;
diff --git a/src/keeper.cpp b/src/keeper.cpp
index 4b1ae3d..8ab9681 100644
--- a/src/keeper.cpp
+++ b/src/keeper.cpp
@@ -928,7 +928,7 @@ void Keepers::initialize(Universe& U_, lua_State* L_, size_t const nbKeepers_, i
928 // copy package.path and package.cpath from the source state 928 // copy package.path and package.cpath from the source state
929 if (luaG_getmodule(L, LUA_LOADLIBNAME) != LuaType::NIL) { // L_: settings package _K: 929 if (luaG_getmodule(L, LUA_LOADLIBNAME) != LuaType::NIL) { // L_: settings package _K:
930 // when copying with mode LookupMode::ToKeeper, error message is pushed at the top of the stack, not raised immediately 930 // when copying with mode LookupMode::ToKeeper, error message is pushed at the top of the stack, not raised immediately
931 InterCopyContext _c{ U, DestState{ _K.value() }, SourceState{ L }, {}, SourceIndex{ luaG_absindex(L, kIdxTop) }, {}, LookupMode::ToKeeper, {} }; 931 InterCopyContext _c{ U, DestState{ _K.value() }, SourceState{ L }, {}, SourceIndex{ luaG_absindex(L, kIdxTop).value() }, {}, LookupMode::ToKeeper, {} };
932 if (_c.interCopyPackage() != InterCopyResult::Success) { // L_: settings ... error_msg _K: 932 if (_c.interCopyPackage() != InterCopyResult::Success) { // L_: settings ... error_msg _K:
933 // if something went wrong, the error message is at the top of the stack 933 // if something went wrong, the error message is at the top of the stack
934 lua_remove(L, -2); // L_: settings error_msg 934 lua_remove(L, -2); // L_: settings error_msg
diff --git a/src/unique.hpp b/src/unique.hpp
index 27ea71e..c214dbc 100644
--- a/src/unique.hpp
+++ b/src/unique.hpp
@@ -26,11 +26,13 @@ class Unique
26 constexpr Unique& operator=(Unique const&) = default; 26 constexpr Unique& operator=(Unique const&) = default;
27 constexpr Unique& operator=(Unique&&) = default; 27 constexpr Unique& operator=(Unique&&) = default;
28 28
29 // Forbid construction with any other class, especially with types that convert naturally to UnderlyingType. 29 // Forbid construction with any other class, especially with types that convert naturally to T.
30 // For instance, this prevents construction with a float when UnderlyingType is an integer type. 30 // For instance, this prevents construction with a float when T is an integer type.
31 // Conversion will have to be explicit and the developer will be aware of it. 31 // Conversion will have to be explicit and the developer will be aware of it.
32 // However we want to keep the same-type copy constructors (including with an inherited class), hence the enable_if stuff. 32 // However we want to keep the same-type copy constructors (including with an inherited class), hence the enable_if stuff.
33 template <typename AnyOtherClass, std::enable_if_t<!std::is_base_of_v<self, std::decay_t<AnyOtherClass>>, bool> = true> 33 template <typename AnyOtherClass, std::enable_if_t<!std::is_base_of_v<self, std::decay_t<AnyOtherClass>>, bool> = true>
34 Unique(AnyOtherClass const&) = delete;
35 template <typename AnyOtherClass, std::enable_if_t<!std::is_base_of_v<self, std::decay_t<AnyOtherClass>>, bool> = true>
34 Unique(AnyOtherClass&&) = delete; 36 Unique(AnyOtherClass&&) = delete;
35 37
36 // can't implicitly affect from base type 38 // can't implicitly affect from base type
@@ -38,8 +40,8 @@ class Unique
38 constexpr Unique& operator=(T&&) = delete; 40 constexpr Unique& operator=(T&&) = delete;
39 41
40 // cast 42 // cast
41 constexpr operator T() const noexcept { return val; } 43 constexpr operator T const&() const noexcept { return val; }
42 constexpr T value() const noexcept { return val; } 44 constexpr T const& value() const noexcept { return val; }
43 45
44 // pre-increment 46 // pre-increment
45 auto& operator++() noexcept 47 auto& operator++() noexcept
@@ -71,12 +73,33 @@ class Unique<T, TAG, std::enable_if_t<!std::is_scalar_v<T>>>
71: public T 73: public T
72{ 74{
73 public: 75 public:
76 using self = Unique<T, TAG, void>;
74 using type = T; 77 using type = T;
75 using T::T; 78 using T::T;
76 explicit Unique(T const& b_) 79 explicit Unique(T const& b_)
77 : T{ b_ } 80 : T{ b_ }
78 { 81 {
79 } 82 }
83
84 // rule of 5
85 constexpr Unique() = default;
86 constexpr Unique(Unique const&) = default;
87 constexpr Unique(Unique&&) = default;
88 constexpr Unique& operator=(Unique const&) = default;
89 constexpr Unique& operator=(Unique&&) = default;
90
91 // Forbid construction with any other class, especially with types that convert naturally to T.
92 // For instance, this prevents construction with a float when T is an integer type.
93 // Conversion will have to be explicit and the developer will be aware of it.
94 // However we want to keep the same-type copy constructors (including with an inherited class), hence the enable_if stuff.
95 template <typename AnyOtherClass, std::enable_if_t<!std::is_base_of_v<self, std::decay_t<AnyOtherClass>>, bool> = true>
96 Unique(AnyOtherClass const&) = delete;
97 template <typename AnyOtherClass, std::enable_if_t<!std::is_base_of_v<self, std::decay_t<AnyOtherClass>>, bool> = true>
98 Unique(AnyOtherClass&&) = delete;
99
100 // can't implicitly affect from base type
101 Unique& operator=(T const&) = delete;
102 constexpr Unique& operator=(T&&) = delete;
80}; 103};
81 104
82#define DECLARE_UNIQUE_TYPE(_name, _type) using _name = Unique<_type, class Unique_##_name##_Tag> 105#define DECLARE_UNIQUE_TYPE(_name, _type) using _name = Unique<_type, class Unique_##_name##_Tag>