aboutsummaryrefslogtreecommitdiff
path: root/src/compat.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/compat.h')
-rw-r--r--src/compat.h229
1 files changed, 80 insertions, 149 deletions
diff --git a/src/compat.h b/src/compat.h
index 3b0ebf4..bcea225 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -128,188 +128,119 @@ inline LuaType luaG_type(lua_State* const L_, int const idx_)
128 return static_cast<LuaType>(lua_type(L_, idx_)); 128 return static_cast<LuaType>(lua_type(L_, idx_));
129} 129}
130 130
131// ------------------------------------------------------------------------------------------------- 131// #################################################################################################
132// #################################################################################################
133// All the compatibility wrappers we expose start with luaG_
134// #################################################################################################
135// #################################################################################################
132 136
133// Default matches Lua 5.4 as of now 137// use this in place of lua_absindex to save a function call
134template <int VERSION, typename SPECIALIZE = void> 138inline int luaG_absindex(lua_State* L_, int idx_)
135struct Wrap
136{ 139{
137 static inline int lua_dump(lua_State* const L_, lua_Writer const writer_, void* const data_, int const strip_) 140 return (((idx_) >= 0 || (idx_) <= LUA_REGISTRYINDEX) ? (idx_) : lua_gettop(L_) + (idx_) + 1);
138 { 141}
139 return ::lua_dump(L_, writer_, data_, strip_);
140 }
141 142
142 static inline LuaType lua_getfield(lua_State* L_, int idx_, std::string_view const& k_) 143// #################################################################################################
143 {
144 // starting with Lua 5.3, lua_getfield returns the type of the pushed value
145 return static_cast<LuaType>(::lua_getfield(L_, idx_, k_.data()));
146 }
147 144
148 template <size_t N> 145template <typename LUA_DUMP>
149 static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) 146concept RequiresOldLuaDump = requires(LUA_DUMP f_) { { f_(nullptr, nullptr, nullptr) } -> std::same_as<int>; };
150 {
151 lua_createtable(L_, 0, N - 1);
152 ::luaL_setfuncs(L_, funcs_, 0);
153 }
154 147
155 static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int nup_) 148template <RequiresOldLuaDump LUA_DUMP>
156 { 149static inline int WrapLuaDump(LUA_DUMP f_, lua_State* const L_, lua_Writer const writer_, void* const data_, [[maybe_unused]] int const strip_)
157 ::luaL_setfuncs(L_, funcs_, nup_); 150{
158 } 151 return f_(L_, writer_, data_);
152}
159 153
160 static void luaL_setmetatable(lua_State* const L_, std::string_view const& tname_) 154// -------------------------------------------------------------------------------------------------
161 {
162 ::luaL_setmetatable(L_, tname_.data());
163 }
164};
165 155
166// ################################################################################################# 156template <typename LUA_DUMP>
157concept RequiresNewLuaDump = requires(LUA_DUMP f_) { { f_(nullptr, nullptr, nullptr, 0) } -> std::same_as<int>; };
167 158
168template <int VERSION> 159template <RequiresNewLuaDump LUA_DUMP>
169struct Wrap<VERSION, typename std::enable_if_t<VERSION == 503>> 160static inline int WrapLuaDump(LUA_DUMP f_, lua_State* const L_, lua_Writer const writer_, void* const data_, int const strip_)
170{ 161{
171 static inline int lua_dump(lua_State* L_, lua_Writer writer_, void* data_, int strip_) 162 return f_(L_, writer_, data_, strip_);
172 { 163}
173 return ::lua_dump(L_, writer_, data_, strip_);
174 }
175 164
176 static inline LuaType lua_getfield(lua_State* L_, int idx_, std::string_view const& k_) 165// -------------------------------------------------------------------------------------------------
177 {
178 // starting with Lua 5.3, lua_getfield returns the type of the pushed value
179 return static_cast<LuaType>(::lua_getfield(L_, idx_, k_.data()));
180 }
181 166
182 template <size_t N> 167static inline int luaG_dump(lua_State* const L_, lua_Writer const writer_, void* const data_, int const strip_)
183 static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) 168{
184 { 169 return WrapLuaDump(lua_dump, L_, writer_, data_, strip_);
185 lua_createtable(L_, 0, N - 1); 170}
186 ::luaL_setfuncs(L_, funcs_, 0);
187 }
188 171
189 static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int const nup_) 172// #################################################################################################
190 {
191 ::luaL_setfuncs(L_, funcs_, nup_);
192 }
193 173
194 static void luaL_setmetatable(lua_State* const L_, std::string_view const& tname_) 174int luaG_getalluservalues(lua_State* L_, int idx_);
195 {
196 ::luaL_setmetatable(L_, tname_.data());
197 }
198};
199 175
200// ################################################################################################# 176// #################################################################################################
201 177
202template <int VERSION> 178template <typename LUA_GETFIELD>
203struct Wrap<VERSION, typename std::enable_if_t<VERSION == 502>> 179concept RequiresOldLuaGetfield = requires(LUA_GETFIELD f_)
204{ 180{
205 static inline int lua_dump(lua_State* const L_, lua_Writer const writer_, void* const data_, [[maybe_unused]] int const strip_)
206 { 181 {
207 return ::lua_dump(L_, writer_, data_); 182 f_(nullptr, 0, nullptr)
208 } 183 } -> std::same_as<void>;
209
210 static inline LuaType lua_getfield(lua_State* L_, int idx_, std::string_view const& k_)
211 {
212 // before Lua 5.3, lua_getfield returns nothing
213 ::lua_getfield(L_, idx_, k_.data());
214 return luaG_type(L_, -1);
215 }
216
217 template <size_t N>
218 static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N])
219 {
220 ::lua_createtable(L_, 0, N - 1);
221 ::luaL_setfuncs(L_, funcs_, 0);
222 }
223
224 static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int const nup_)
225 {
226 ::luaL_setfuncs(L_, funcs_, nup_);
227 }
228
229 static void luaL_setmetatable(lua_State* const L_, std::string_view const& tname_)
230 {
231 ::luaL_setmetatable(L_, tname_.data());
232 }
233}; 184};
234 185
235// ################################################################################################# 186template <RequiresOldLuaGetfield LUA_GETFIELD>
236 187static inline int WrapLuaGetField(LUA_GETFIELD f_, lua_State* const L_, int const idx_, char const* const name_)
237template <int VERSION>
238struct Wrap<VERSION, typename std::enable_if_t<VERSION == 501>>
239{ 188{
240 static inline int lua_dump(lua_State* const L_, lua_Writer const writer_, void* const data_, [[maybe_unused]] int const strip_) 189 f_(L_, idx_, name_);
241 { 190 return lua_type(L_, -1);
242 return ::lua_dump(L_, writer_, data_); 191}
243 }
244
245 static inline LuaType lua_getfield(lua_State* L_, int idx_, std::string_view const& k_)
246 {
247 // before Lua 5.3, lua_getfield returns nothing
248 ::lua_getfield(L_, idx_, k_.data());
249 return luaG_type(L_, -1);
250 }
251
252 template<size_t N>
253 static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N])
254 {
255 lua_createtable(L_, 0, N - 1);
256 ::luaL_register(L_, nullptr, funcs_);
257 }
258 192
259 static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], [[maybe_unused]] int const nup_) 193// -------------------------------------------------------------------------------------------------
260 {
261 ::luaL_register(L_, nullptr, funcs_);
262 }
263 194
264 static void luaL_setmetatable(lua_State* const L_, std::string_view const& tname_) 195template <typename LUA_GETFIELD>
196concept RequiresNewLuaGetfield = requires(LUA_GETFIELD f_)
197{
265 { 198 {
266 luaL_getmetatable(L_, tname_.data()); 199 f_(nullptr, 0, nullptr)
267 lua_setmetatable(L_, -2); 200 } -> std::same_as<int>;
268 }
269}; 201};
270 202
271// ################################################################################################# 203template <RequiresNewLuaGetfield LUA_GETFIELD>
272// All the compatibility wrappers we expose start with luaG_ 204static inline int WrapLuaGetField(LUA_GETFIELD f_, lua_State* const L_, int const idx_, char const* const name_)
273
274// -------------------------------------------------------------------------------------------------
275
276// use this in place of lua_absindex to save a function call
277inline int luaG_absindex(lua_State* L_, int idx_)
278{ 205{
279 return (((idx_) >= 0 || (idx_) <= LUA_REGISTRYINDEX) ? (idx_) : lua_gettop(L_) + (idx_) + 1); 206 return f_(L_, idx_, name_);
280} 207}
281 208
282// ------------------------------------------------------------------------------------------------- 209// -------------------------------------------------------------------------------------------------
283 210
284inline int luaG_dump(lua_State* L_, lua_Writer writer_, void* data_, int strip_) 211static inline LuaType luaG_getfield(lua_State* const L_, int const idx_, std::string_view const& name_)
285{ 212{
286 return Wrap<LUA_VERSION_NUM>::lua_dump(L_, writer_, data_, strip_); 213 return static_cast<LuaType>(WrapLuaGetField(lua_getfield, L_, idx_, name_.data()));
287} 214}
288 215
289// ------------------------------------------------------------------------------------------------- 216// #################################################################################################
290 217
291int luaG_getalluservalues(lua_State* L_, int idx_); 218LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_);
292 219
293// ------------------------------------------------------------------------------------------------- 220// #################################################################################################
294 221
295[[nodiscard]] inline LuaType luaG_getfield(lua_State* L_, int idx_, std::string_view const& k_) 222inline void luaG_registerlibfuncs(lua_State* L_, luaL_Reg const* funcs_)
296{ 223{
297 return Wrap<LUA_VERSION_NUM>::lua_getfield(L_, idx_, k_); 224 // fake externs to make clang happy...
225 extern void luaL_register(lua_State*, char const*, luaL_Reg const*); // Lua 5.1
226 extern void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int nup_); // Lua 5.2+
227 if constexpr (LUA_VERSION_NUM == 501) {
228 luaL_register(L_, nullptr, funcs_);
229 } else {
230 luaL_setfuncs(L_, funcs_, 0);
231 }
298} 232}
299 233
300// ------------------------------------------------------------------------------------------------- 234// #################################################################################################
301
302LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_);
303
304// -------------------------------------------------------------------------------------------------
305 235
306template<size_t N> 236template <size_t N>
307inline void luaG_newlib(lua_State* const L_, luaL_Reg const (&funcs_)[N]) 237static inline void luaG_newlib(lua_State* const L_, luaL_Reg const (&funcs_)[N])
308{ 238{
309 (Wrap<LUA_VERSION_NUM>::luaL_newlib)(L_, funcs_); 239 lua_createtable(L_, 0, N - 1);
240 luaG_registerlibfuncs(L_, funcs_);
310} 241}
311 242
312// ------------------------------------------------------------------------------------------------- 243// #################################################################################################
313 244
314template <typename T> 245template <typename T>
315[[nodiscard]] T* luaG_newuserdatauv(lua_State* L_, int nuvalue_) 246[[nodiscard]] T* luaG_newuserdatauv(lua_State* L_, int nuvalue_)
@@ -317,7 +248,7 @@ template <typename T>
317 return static_cast<T*>(lua_newuserdatauv(L_, sizeof(T), nuvalue_)); 248 return static_cast<T*>(lua_newuserdatauv(L_, sizeof(T), nuvalue_));
318} 249}
319 250
320// ------------------------------------------------------------------------------------------------- 251// #################################################################################################
321 252
322inline void luaG_pushglobaltable(lua_State* const L_) 253inline void luaG_pushglobaltable(lua_State* const L_)
323{ 254{
@@ -328,21 +259,21 @@ inline void luaG_pushglobaltable(lua_State* const L_)
328#endif // LUA_GLOBALSINDEX 259#endif // LUA_GLOBALSINDEX
329} 260}
330 261
331// ------------------------------------------------------------------------------------------------- 262// #################################################################################################
332
333inline void luaG_registerlibfuncs(lua_State* L_, luaL_Reg const funcs_[])
334{
335 Wrap<LUA_VERSION_NUM>::luaL_setfuncs(L_, funcs_, 0);
336}
337
338// -------------------------------------------------------------------------------------------------
339 263
340inline void luaG_setmetatable(lua_State* const L_, std::string_view const& tname_) 264inline void luaG_setmetatable(lua_State* const L_, std::string_view const& tname_)
341{ 265{
342 return Wrap<LUA_VERSION_NUM>::luaL_setmetatable(L_, tname_); 266 // fake externs to make clang happy...
267 extern void luaL_setmetatable(lua_State* const L_, char const* const tname_); // Lua 5.2+
268 if constexpr (LUA_VERSION_NUM == 501) {
269 luaL_setmetatable(L_, tname_.data());
270 } else {
271 luaL_getmetatable(L_, tname_.data());
272 lua_setmetatable(L_, -2);
273 }
343} 274}
344 275
345// ------------------------------------------------------------------------------------------------- 276// #################################################################################################
346 277
347// a small helper to extract a full userdata pointer from the stack in a safe way 278// a small helper to extract a full userdata pointer from the stack in a safe way
348template <typename T> 279template <typename T>