diff options
Diffstat (limited to 'src/compat.h')
-rw-r--r-- | src/compat.h | 229 |
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 |
134 | template <int VERSION, typename SPECIALIZE = void> | 138 | inline int luaG_absindex(lua_State* L_, int idx_) |
135 | struct 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> | 145 | template <typename LUA_DUMP> |
149 | static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) | 146 | concept 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_) | 148 | template <RequiresOldLuaDump LUA_DUMP> |
156 | { | 149 | static 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 | // ################################################################################################# | 156 | template <typename LUA_DUMP> |
157 | concept RequiresNewLuaDump = requires(LUA_DUMP f_) { { f_(nullptr, nullptr, nullptr, 0) } -> std::same_as<int>; }; | ||
167 | 158 | ||
168 | template <int VERSION> | 159 | template <RequiresNewLuaDump LUA_DUMP> |
169 | struct Wrap<VERSION, typename std::enable_if_t<VERSION == 503>> | 160 | static 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> | 167 | static 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_) | 174 | int luaG_getalluservalues(lua_State* L_, int idx_); |
195 | { | ||
196 | ::luaL_setmetatable(L_, tname_.data()); | ||
197 | } | ||
198 | }; | ||
199 | 175 | ||
200 | // ################################################################################################# | 176 | // ################################################################################################# |
201 | 177 | ||
202 | template <int VERSION> | 178 | template <typename LUA_GETFIELD> |
203 | struct Wrap<VERSION, typename std::enable_if_t<VERSION == 502>> | 179 | concept 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 | // ################################################################################################# | 186 | template <RequiresOldLuaGetfield LUA_GETFIELD> |
236 | 187 | static inline int WrapLuaGetField(LUA_GETFIELD f_, lua_State* const L_, int const idx_, char const* const name_) | |
237 | template <int VERSION> | ||
238 | struct 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_) | 195 | template <typename LUA_GETFIELD> |
196 | concept 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 | // ################################################################################################# | 203 | template <RequiresNewLuaGetfield LUA_GETFIELD> |
272 | // All the compatibility wrappers we expose start with luaG_ | 204 | static 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 | ||
277 | inline 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 | ||
284 | inline int luaG_dump(lua_State* L_, lua_Writer writer_, void* data_, int strip_) | 211 | static 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 | ||
291 | int luaG_getalluservalues(lua_State* L_, int idx_); | 218 | LuaType 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_) | 222 | inline 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 | |||
302 | LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_); | ||
303 | |||
304 | // ------------------------------------------------------------------------------------------------- | ||
305 | 235 | ||
306 | template<size_t N> | 236 | template <size_t N> |
307 | inline void luaG_newlib(lua_State* const L_, luaL_Reg const (&funcs_)[N]) | 237 | static 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 | ||
314 | template <typename T> | 245 | template <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 | ||
322 | inline void luaG_pushglobaltable(lua_State* const L_) | 253 | inline 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 | |||
333 | inline 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 | ||
340 | inline void luaG_setmetatable(lua_State* const L_, std::string_view const& tname_) | 264 | inline 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 |
348 | template <typename T> | 279 | template <typename T> |