aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--deep_test/deep_test.cpp135
-rw-r--r--deep_test/deep_test.vcxproj2
-rw-r--r--deep_test/deep_test.vcxproj.user13
-rw-r--r--deep_test/deeptest.lua19
-rw-r--r--src/compat.h64
5 files changed, 152 insertions, 81 deletions
diff --git a/deep_test/deep_test.cpp b/deep_test/deep_test.cpp
index 0a09921..da467f3 100644
--- a/deep_test/deep_test.cpp
+++ b/deep_test/deep_test.cpp
@@ -1,18 +1,12 @@
1#include "lanes/src/deep.h" 1#include "lanes/src/deep.h"
2#include "lanes/src/compat.h" 2#include "lanes/src/compat.h"
3 3
4#include <malloc.h>
5#include <memory.h>
6#include <assert.h>
7
8class MyDeepFactory : public DeepFactory 4class MyDeepFactory : public DeepFactory
9{ 5{
10 public: 6 public:
11
12 static MyDeepFactory Instance; 7 static MyDeepFactory Instance;
13 8
14 private: 9 private:
15
16 void createMetatable(lua_State* const L_) const override 10 void createMetatable(lua_State* const L_) const override
17 { 11 {
18 luaL_getmetatable(L_, "deep"); 12 luaL_getmetatable(L_, "deep");
@@ -28,6 +22,7 @@ class MyDeepFactory : public DeepFactory
28// a lanes-deep userdata. needs DeepPrelude and luaG_newdeepuserdata from Lanes code. 22// a lanes-deep userdata. needs DeepPrelude and luaG_newdeepuserdata from Lanes code.
29struct MyDeepUserdata : public DeepPrelude // Deep userdata MUST start with a DeepPrelude 23struct MyDeepUserdata : public DeepPrelude // Deep userdata MUST start with a DeepPrelude
30{ 24{
25 std::atomic<int> inUse{};
31 lua_Integer val{ 0 }; 26 lua_Integer val{ 0 };
32}; 27};
33 28
@@ -49,22 +44,20 @@ void MyDeepFactory::deleteDeepObjectInternal(lua_State* const L_, DeepPrelude* c
49 44
50// ################################################################################################# 45// #################################################################################################
51 46
52[[nodiscard]] static int deep_set(lua_State* const L_) 47[[nodiscard]] static int deep_gc(lua_State* L)
53{ 48{
54 MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L_, 1)) }; 49 MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) };
55 lua_Integer i = lua_tointeger(L_, 2);
56 _self->val = i;
57 return 0; 50 return 0;
58} 51}
59 52
60// ################################################################################################# 53// #################################################################################################
61 54
62[[nodiscard]] static int deep_setuv(lua_State* L) 55[[nodiscard]] static int deep_tostring(lua_State* L)
63{ 56{
64 MyDeepUserdata* const self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; 57 MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) };
65 int uv = (int) luaL_optinteger(L, 2, 1); 58 _self->inUse.fetch_add(1, std::memory_order_seq_cst);
66 lua_settop( L, 3); 59 lua_pushfstring(L, "%p:deep(%d)", lua_topointer(L, 1), _self->val);
67 lua_pushboolean( L, lua_setiuservalue( L, 1, uv) != 0); 60 _self->inUse.fetch_sub(1, std::memory_order_seq_cst);
68 return 1; 61 return 1;
69} 62}
70 63
@@ -73,44 +66,53 @@ void MyDeepFactory::deleteDeepObjectInternal(lua_State* const L_, DeepPrelude* c
73// won't actually do anything as deep userdata don't have uservalue slots 66// won't actually do anything as deep userdata don't have uservalue slots
74[[nodiscard]] static int deep_getuv(lua_State* L) 67[[nodiscard]] static int deep_getuv(lua_State* L)
75{ 68{
76 MyDeepUserdata* const self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; 69 MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) };
77 int uv = (int) luaL_optinteger(L, 2, 1); 70 _self->inUse.fetch_add(1, std::memory_order_seq_cst);
78 lua_getiuservalue( L, 1, uv); 71 int _uv = (int) luaL_optinteger(L, 2, 1);
72 lua_getiuservalue(L, 1, _uv);
73 _self->inUse.fetch_sub(1, std::memory_order_seq_cst);
79 return 1; 74 return 1;
80} 75}
81 76
82// ################################################################################################# 77// #################################################################################################
83 78
84[[nodiscard]] static int deep_tostring(lua_State* L) 79[[nodiscard]] static int deep_set(lua_State* const L_)
85{ 80{
86 MyDeepUserdata* const self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; 81 MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L_, 1)) };
87 lua_pushfstring(L, "%p:deep(%d)", lua_topointer(L, 1), self->val); 82 _self->inUse.fetch_add(1, std::memory_order_seq_cst);
88 return 1; 83 lua_Integer _i = lua_tointeger(L_, 2);
84 _self->val = _i;
85 _self->inUse.fetch_sub(1, std::memory_order_seq_cst);
86 return 0;
89} 87}
90 88
91// ################################################################################################# 89// #################################################################################################
92 90
93[[nodiscard]] static int deep_gc(lua_State* L) 91[[nodiscard]] static int deep_setuv(lua_State* L)
94{ 92{
95 MyDeepUserdata* const self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; 93 MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) };
96 return 0; 94 _self->inUse.fetch_add(1, std::memory_order_seq_cst);
95 int _uv = (int) luaL_optinteger(L, 2, 1);
96 lua_settop(L, 3);
97 lua_pushboolean(L, lua_setiuservalue(L, 1, _uv) != 0);
98 _self->inUse.fetch_sub(1, std::memory_order_seq_cst);
99 return 1;
97} 100}
98 101
99// ################################################################################################# 102// #################################################################################################
100 103
101static luaL_Reg const deep_mt[] = 104static luaL_Reg const deep_mt[] = {
102{ 105 { "__gc", deep_gc },
103 { "__tostring", deep_tostring}, 106 { "__tostring", deep_tostring },
104 { "__gc", deep_gc}, 107 { "getuv", deep_getuv },
105 { "set", deep_set}, 108 { "set", deep_set },
106 { "setuv", deep_setuv}, 109 { "setuv", deep_setuv },
107 { "getuv", deep_getuv},
108 { nullptr, nullptr } 110 { nullptr, nullptr }
109}; 111};
110 112
111// ################################################################################################# 113// #################################################################################################
112 114
113int luaD_new_deep( lua_State* L) 115int luaD_new_deep(lua_State* L)
114{ 116{
115 int const nuv{ static_cast<int>(luaL_optinteger(L, 1, 0)) }; 117 int const nuv{ static_cast<int>(luaL_optinteger(L, 1, 0)) };
116 lua_settop(L, 0); 118 lua_settop(L, 0);
@@ -141,8 +143,8 @@ struct MyClonableUserdata
141{ 143{
142 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1)); 144 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
143 int uv = (int) luaL_optinteger(L, 2, 1); 145 int uv = (int) luaL_optinteger(L, 2, 1);
144 lua_settop( L, 3); 146 lua_settop(L, 3);
145 lua_pushboolean( L, lua_setiuservalue( L, 1, uv) != 0); 147 lua_pushboolean(L, lua_setiuservalue(L, 1, uv) != 0);
146 return 1; 148 return 1;
147} 149}
148 150
@@ -152,7 +154,7 @@ struct MyClonableUserdata
152{ 154{
153 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1)); 155 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
154 int uv = (int) luaL_optinteger(L, 2, 1); 156 int uv = (int) luaL_optinteger(L, 2, 1);
155 lua_getiuservalue( L, 1, uv); 157 lua_getiuservalue(L, 1, uv);
156 return 1; 158 return 1;
157} 159}
158 160
@@ -178,19 +180,18 @@ struct MyClonableUserdata
178// this is all we need to make a userdata lanes-clonable. no dependency on Lanes code. 180// this is all we need to make a userdata lanes-clonable. no dependency on Lanes code.
179[[nodiscard]] static int clonable_lanesclone(lua_State* L) 181[[nodiscard]] static int clonable_lanesclone(lua_State* L)
180{ 182{
181 switch( lua_gettop(L)) 183 switch (lua_gettop(L)) {
182 { 184 case 3:
183 case 3:
184 { 185 {
185 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1)); 186 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
186 MyClonableUserdata* from = static_cast<MyClonableUserdata*>(lua_touserdata(L, 2)); 187 MyClonableUserdata* from = static_cast<MyClonableUserdata*>(lua_touserdata(L, 2));
187 size_t len = lua_tointeger(L, 3); 188 size_t len = lua_tointeger(L, 3);
188 assert( len == sizeof(MyClonableUserdata)); 189 assert(len == sizeof(MyClonableUserdata));
189 *self = *from; 190 *self = *from;
190 } 191 }
191 return 0; 192 return 0;
192 193
193 default: 194 default:
194 raise_luaL_error(L, "Lanes called clonable_lanesclone with unexpected parameters"); 195 raise_luaL_error(L, "Lanes called clonable_lanesclone with unexpected parameters");
195 } 196 }
196 return 0; 197 return 0;
@@ -198,34 +199,32 @@ struct MyClonableUserdata
198 199
199// ################################################################################################# 200// #################################################################################################
200 201
201static luaL_Reg const clonable_mt[] = 202static luaL_Reg const clonable_mt[] = {
202{ 203 { "__tostring", clonable_tostring },
203 { "__tostring", clonable_tostring}, 204 { "__gc", clonable_gc },
204 { "__gc", clonable_gc}, 205 { "__lanesclone", clonable_lanesclone },
205 { "__lanesclone", clonable_lanesclone}, 206 { "set", clonable_set },
206 { "set", clonable_set}, 207 { "setuv", clonable_setuv },
207 { "setuv", clonable_setuv}, 208 { "getuv", clonable_getuv },
208 { "getuv", clonable_getuv},
209 { nullptr, nullptr } 209 { nullptr, nullptr }
210}; 210};
211 211
212// ################################################################################################# 212// #################################################################################################
213 213
214int luaD_new_clonable( lua_State* L) 214int luaD_new_clonable(lua_State* L)
215{ 215{
216 int const nuv{ static_cast<int>(luaL_optinteger(L, 1, 1)) }; 216 int const _nuv{ static_cast<int>(luaL_optinteger(L, 1, 1)) };
217 lua_newuserdatauv( L, sizeof(MyClonableUserdata), nuv); 217 lua_newuserdatauv(L, sizeof(MyClonableUserdata), _nuv);
218 luaL_setmetatable( L, "clonable"); 218 luaG_setmetatable(L, "clonable");
219 return 1; 219 return 1;
220} 220}
221 221
222// ################################################################################################# 222// #################################################################################################
223// ################################################################################################# 223// #################################################################################################
224 224
225static luaL_Reg const deep_module[] = 225static luaL_Reg const deep_module[] = {
226{ 226 { "new_deep", luaD_new_deep },
227 { "new_deep", luaD_new_deep}, 227 { "new_clonable", luaD_new_clonable },
228 { "new_clonable", luaD_new_clonable},
229 { nullptr, nullptr } 228 { nullptr, nullptr }
230}; 229};
231 230
@@ -233,24 +232,24 @@ static luaL_Reg const deep_module[] =
233 232
234LANES_API int luaopen_deep_test(lua_State* L) 233LANES_API int luaopen_deep_test(lua_State* L)
235{ 234{
236 luaL_newlib( L, deep_module); // M 235 luaG_newlib<std::size(deep_module)>(L, deep_module); // M
237 236
238 // preregister the metatables for the types we can instantiate so that Lanes can know about them 237 // preregister the metatables for the types we can instantiate so that Lanes can know about them
239 if (luaL_newmetatable( L, "clonable")) // M mt 238 if (luaL_newmetatable(L, "clonable")) // M mt
240 { 239 {
241 luaL_setfuncs( L, clonable_mt, 0); 240 luaG_registerlibfuncs(L, clonable_mt);
242 lua_pushvalue(L, -1); // M mt mt 241 lua_pushvalue(L, -1); // M mt mt
243 lua_setfield(L, -2, "__index"); // M mt 242 lua_setfield(L, -2, "__index"); // M mt
244 } 243 }
245 lua_setfield(L, -2, "__clonableMT"); // M 244 lua_setfield(L, -2, "__clonableMT"); // M
246 245
247 if (luaL_newmetatable( L, "deep")) // mt 246 if (luaL_newmetatable(L, "deep")) // mt
248 { 247 {
249 luaL_setfuncs( L, deep_mt, 0); 248 luaG_registerlibfuncs(L, deep_mt);
250 lua_pushvalue(L, -1); // mt mt 249 lua_pushvalue(L, -1); // mt mt
251 lua_setfield(L, -2, "__index"); // mt 250 lua_setfield(L, -2, "__index"); // mt
252 } 251 }
253 lua_setfield(L, -2, "__deepMT"); // M 252 lua_setfield(L, -2, "__deepMT"); // M
254 253
255 return 1; 254 return 1;
256} 255}
diff --git a/deep_test/deep_test.vcxproj b/deep_test/deep_test.vcxproj
index 43b7ce0..298594e 100644
--- a/deep_test/deep_test.vcxproj
+++ b/deep_test/deep_test.vcxproj
@@ -556,7 +556,7 @@
556 </ClCompile> 556 </ClCompile>
557 <PostBuildEvent> 557 <PostBuildEvent>
558 <Command>xcopy /R /F /Y /I "$(TargetPath)" $(SolutionDir)..\Lua51\bin\$(Platform)\Debug\</Command> 558 <Command>xcopy /R /F /Y /I "$(TargetPath)" $(SolutionDir)..\Lua51\bin\$(Platform)\Debug\</Command>
559 <Message>Copy to Lua 5.2</Message> 559 <Message>Copy to Lua 5.1</Message>
560 </PostBuildEvent> 560 </PostBuildEvent>
561 <Link> 561 <Link>
562 <AdditionalDependencies>lua51.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> 562 <AdditionalDependencies>lua51.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
diff --git a/deep_test/deep_test.vcxproj.user b/deep_test/deep_test.vcxproj.user
index 24e3d31..257d4e9 100644
--- a/deep_test/deep_test.vcxproj.user
+++ b/deep_test/deep_test.vcxproj.user
@@ -3,20 +3,23 @@
3 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'"> 3 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'">
4 <LocalDebuggerCommand>$(SolutionDir)..\Lua53\bin\$(Platform)\Debug\lua53.exe</LocalDebuggerCommand> 4 <LocalDebuggerCommand>$(SolutionDir)..\Lua53\bin\$(Platform)\Debug\lua53.exe</LocalDebuggerCommand>
5 <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> 5 <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
6 <LocalDebuggerCommandArguments>-i</LocalDebuggerCommandArguments> 6 <LocalDebuggerCommandArguments>deeptest.lua</LocalDebuggerCommandArguments>
7 <LocalDebuggerWorkingDirectory>$(SolutionDir)Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory> 7 <LocalDebuggerWorkingDirectory>$(SolutionDir)Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory>
8 <RemoteDebuggerCommandArguments>deeptest.lua</RemoteDebuggerCommandArguments>
8 </PropertyGroup> 9 </PropertyGroup>
9 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|x64'"> 10 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|x64'">
10 <LocalDebuggerCommand>$(SolutionDir)..\Lua52\bin\$(Platform)\Debug\lua51.exe</LocalDebuggerCommand> 11 <LocalDebuggerCommand>$(SolutionDir)..\Lua51\bin\$(Platform)\Debug\lua51.exe</LocalDebuggerCommand>
11 <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> 12 <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
12 <LocalDebuggerCommandArguments>-i</LocalDebuggerCommandArguments> 13 <LocalDebuggerCommandArguments>-i deeptest.lua</LocalDebuggerCommandArguments>
13 <LocalDebuggerWorkingDirectory>$(SolutionDir)Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory> 14 <LocalDebuggerWorkingDirectory>$(SolutionDir)Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory>
15 <RemoteDebuggerCommandArguments>-i deeptest.lua</RemoteDebuggerCommandArguments>
14 </PropertyGroup> 16 </PropertyGroup>
15 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|x64'"> 17 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|x64'">
16 <LocalDebuggerCommand>$(SolutionDir)..\Lua51\bin\$(Platform)\Debug\lua52.exe</LocalDebuggerCommand> 18 <LocalDebuggerCommand>$(SolutionDir)..\Lua52\bin\$(Platform)\Debug\lua52.exe</LocalDebuggerCommand>
17 <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> 19 <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
18 <LocalDebuggerCommandArguments>-i</LocalDebuggerCommandArguments> 20 <LocalDebuggerCommandArguments>-i deeptest.lua</LocalDebuggerCommandArguments>
19 <LocalDebuggerWorkingDirectory>$(SolutionDir)Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory> 21 <LocalDebuggerWorkingDirectory>$(SolutionDir)Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory>
22 <RemoteDebuggerCommandArguments>-i deeptest.lua</RemoteDebuggerCommandArguments>
20 </PropertyGroup> 23 </PropertyGroup>
21 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug LuaJIT 2.1.0-beta3|x64'"> 24 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug LuaJIT 2.1.0-beta3|x64'">
22 <LocalDebuggerCommand>$(SolutionDir)..\LuaJIT-2.1.0-beta3\bin\$(Platform)\luajit210.exe</LocalDebuggerCommand> 25 <LocalDebuggerCommand>$(SolutionDir)..\LuaJIT-2.1.0-beta3\bin\$(Platform)\luajit210.exe</LocalDebuggerCommand>
diff --git a/deep_test/deeptest.lua b/deep_test/deeptest.lua
index 09b638c..89e6f0d 100644
--- a/deep_test/deeptest.lua
+++ b/deep_test/deeptest.lua
@@ -6,16 +6,21 @@ local dt = lanes.require "deep_test"
6 6
7local test_deep = true 7local test_deep = true
8local test_clonable = true 8local test_clonable = true
9local test_uvtype = "string" 9-- lua 5.1->5.2 support a single table uservalue
10-- lua 5.3->5.4 supports an arbitrary type uservalue
11local test_uvtype = (_VERSION == "Lua 5.4") and "function" or (_VERSION == "Lua 5.3") and "string" or "table"
12-- lua 5.4 supports multiple uservalues
10local nupvals = _VERSION == "Lua 5.4" and 3 or 1 13local nupvals = _VERSION == "Lua 5.4" and 3 or 1
11 14
12local makeUserValue = function( obj_) 15local makeUserValue = function( obj_)
13 if test_uvtype == "string" then 16 if test_uvtype == "table" then
17 return {"some uservalue"}
18 elseif test_uvtype == "string" then
14 return "some uservalue" 19 return "some uservalue"
15 elseif test_uvtype == "function" then 20 elseif test_uvtype == "function" then
16 -- a function that pull the userdata as upvalue 21 -- a function that pull the userdata as upvalue
17 local f = function() 22 local f = function()
18 return tostring( obj_) 23 return "-> '" .. tostring( obj_) .. "'"
19 end 24 end
20 return f 25 return f
21 end 26 end
@@ -25,7 +30,7 @@ local printDeep = function( prefix_, obj_, t_)
25 print( prefix_, obj_) 30 print( prefix_, obj_)
26 for uvi = 1, nupvals do 31 for uvi = 1, nupvals do
27 local uservalue = obj_:getuv(uvi) 32 local uservalue = obj_:getuv(uvi)
28 print ( "uv #" .. uvi, uservalue, type( uservalue) == "function" and uservalue() or "") 33 print ("uv #" .. uvi, type( uservalue), uservalue, type(uservalue) == "function" and uservalue() or "")
29 end 34 end
30 if t_ then 35 if t_ then
31 for k, v in pairs( t_) do 36 for k, v in pairs( t_) do
@@ -38,10 +43,7 @@ end
38local performTest = function( obj_) 43local performTest = function( obj_)
39 -- setup the userdata with some value and a uservalue 44 -- setup the userdata with some value and a uservalue
40 obj_:set( 666) 45 obj_:set( 666)
41 -- lua 5.1->5.2 support a single table uservalue
42 -- lua 5.3 supports an arbitrary type uservalue
43 obj_:setuv( 1, makeUserValue( obj_)) 46 obj_:setuv( 1, makeUserValue( obj_))
44 -- lua 5.4 supports multiple uservalues of arbitrary types
45 if nupvals > 1 then 47 if nupvals > 1 then
46 -- keep uv #2 as nil 48 -- keep uv #2 as nil
47 obj_:setuv( 3, "ENDUV") 49 obj_:setuv( 3, "ENDUV")
@@ -95,3 +97,6 @@ if test_clonable then
95 print "CLONABLE" 97 print "CLONABLE"
96 performTest( dt.new_clonable(nupvals)) 98 performTest( dt.new_clonable(nupvals))
97end 99end
100
101print "================================================================"
102print "TEST OK" \ No newline at end of file
diff --git a/src/compat.h b/src/compat.h
index 1789a8b..58af985 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -172,10 +172,22 @@ struct Wrap
172 return ::lua_dump(L_, writer_, data_, strip_); 172 return ::lua_dump(L_, writer_, data_, strip_);
173 } 173 }
174 174
175 template <size_t N>
176 static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N])
177 {
178 lua_createtable(L_, 0, N - 1);
179 ::luaL_setfuncs(L_, funcs_, 0);
180 }
181
175 static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int nup_) 182 static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int nup_)
176 { 183 {
177 ::luaL_setfuncs(L_, funcs_, nup_); 184 ::luaL_setfuncs(L_, funcs_, nup_);
178 } 185 }
186
187 static void luaL_setmetatable(lua_State* const L_, std::string_view const& tname_)
188 {
189 ::luaL_setmetatable(L_, tname_.data());
190 }
179}; 191};
180 192
181// ################################################################################################# 193// #################################################################################################
@@ -188,10 +200,22 @@ struct Wrap<VERSION, typename std::enable_if<VERSION == 503>::type>
188 return ::lua_dump(L_, writer_, data_, strip_); 200 return ::lua_dump(L_, writer_, data_, strip_);
189 } 201 }
190 202
203 template <size_t N>
204 static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N])
205 {
206 lua_createtable(L_, 0, N - 1);
207 ::luaL_setfuncs(L_, funcs_, 0);
208 }
209
191 static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int const nup_) 210 static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int const nup_)
192 { 211 {
193 ::luaL_setfuncs(L_, funcs_, nup_); 212 ::luaL_setfuncs(L_, funcs_, nup_);
194 } 213 }
214
215 static void luaL_setmetatable(lua_State* const L_, std::string_view const& tname_)
216 {
217 ::luaL_setmetatable(L_, tname_.data());
218 }
195}; 219};
196 220
197// ################################################################################################# 221// #################################################################################################
@@ -204,10 +228,22 @@ struct Wrap<VERSION, typename std::enable_if<VERSION == 502>::type>
204 return ::lua_dump(L_, writer_, data_); 228 return ::lua_dump(L_, writer_, data_);
205 } 229 }
206 230
231 template <size_t N>
232 static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N])
233 {
234 lua_createtable(L_, 0, N - 1);
235 ::luaL_setfuncs(L_, funcs_, 0);
236 }
237
207 static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int const nup_) 238 static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int const nup_)
208 { 239 {
209 ::luaL_setfuncs(L_, funcs_, nup_); 240 ::luaL_setfuncs(L_, funcs_, nup_);
210 } 241 }
242
243 static void luaL_setmetatable(lua_State* const L_, std::string_view const& tname_)
244 {
245 ::luaL_setmetatable(L_, tname_.data());
246 }
211}; 247};
212 248
213// ################################################################################################# 249// #################################################################################################
@@ -220,10 +256,23 @@ struct Wrap<VERSION, typename std::enable_if<VERSION == 501>::type>
220 return ::lua_dump(L_, writer_, data_); 256 return ::lua_dump(L_, writer_, data_);
221 } 257 }
222 258
259 template<size_t N>
260 static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N])
261 {
262 lua_createtable(L_, 0, N - 1);
263 ::luaL_register(L_, nullptr, funcs_);
264 }
265
223 static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], [[maybe_unused]] int const nup_) 266 static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], [[maybe_unused]] int const nup_)
224 { 267 {
225 ::luaL_register(L_, nullptr, funcs_); 268 ::luaL_register(L_, nullptr, funcs_);
226 } 269 }
270
271 static void luaL_setmetatable(lua_State* const L_, std::string_view const& tname_)
272 {
273 luaL_getmetatable(L_, tname_.data());
274 lua_setmetatable(L_, -2);
275 }
227}; 276};
228 277
229// ################################################################################################# 278// #################################################################################################
@@ -248,11 +297,26 @@ LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_);
248 297
249// ------------------------------------------------------------------------------------------------- 298// -------------------------------------------------------------------------------------------------
250 299
300template<size_t N>
301inline void luaG_newlib(lua_State* const L_, luaL_Reg const (&funcs_)[N])
302{
303 (Wrap<LUA_VERSION_NUM>::luaL_newlib)(L_, funcs_);
304}
305
306// -------------------------------------------------------------------------------------------------
307
251inline void luaG_registerlibfuncs(lua_State* L_, luaL_Reg const funcs_[]) 308inline void luaG_registerlibfuncs(lua_State* L_, luaL_Reg const funcs_[])
252{ 309{
253 Wrap<LUA_VERSION_NUM>::luaL_setfuncs(L_, funcs_, 0); 310 Wrap<LUA_VERSION_NUM>::luaL_setfuncs(L_, funcs_, 0);
254} 311}
255 312
313// -------------------------------------------------------------------------------------------------
314
315inline void luaG_setmetatable(lua_State* const L_, std::string_view const& tname_)
316{
317 return Wrap<LUA_VERSION_NUM>::luaL_setmetatable(L_, tname_);
318}
319
256// ################################################################################################# 320// #################################################################################################
257 321
258// must keep as a macro as long as we do constant string concatenations 322// must keep as a macro as long as we do constant string concatenations