sol.hpp
Go to the documentation of this file.
1 // The MIT License (MIT)
2 
3 // Copyright (c) 2013-2020 Rapptz, ThePhD and contributors
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 // this software and associated documentation files (the "Software"), to deal in
7 // the Software without restriction, including without limitation the rights to
8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 // the Software, and to permit persons to whom the Software is furnished to do so,
10 // subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 // This file was generated with a script.
23 // Generated 2020-10-03 21:34:24.496436 UTC
24 // This header was generated with sol v3.2.1 (revision 48eea7b5)
25 // https://github.com/ThePhD/sol2
26 
27 #ifndef SOL_SINGLE_INCLUDE_HPP
28 #define SOL_SINGLE_INCLUDE_HPP
29 
30 // beginning of sol/sol.hpp
31 
32 #ifndef SOL_HPP
33 #define SOL_HPP
34 
35 // beginning of sol/version.hpp
36 
37 #include <sol/config.hpp>
38 
39 #include <cstdint>
40 
41 #define SOL_VERSION_MAJOR 3
42 #define SOL_VERSION_MINOR 5
43 #define SOL_VERSION_PATCH 0
44 #define SOL_VERSION_STRING "3.5.0"
45 #define SOL_VERSION ((SOL_VERSION_MAJOR * 100000) + (SOL_VERSION_MINOR * 100) + (SOL_VERSION_PATCH))
46 
47 #define SOL_IS_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) != 0)
48 #define SOL_IS_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3) == 0)
49 #define SOL_IS_DEFAULT_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) > 3)
50 #define SOL_IS_DEFAULT_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3 OP_SYMBOL 3) < 0)
51 
52 #define SOL_ON |
53 #define SOL_OFF ^
54 #define SOL_DEFAULT_ON +
55 #define SOL_DEFAULT_OFF -
56 
57 #if defined(_MSC_VER)
58  #define SOL_COMPILER_CLANG_I_ SOL_OFF
59  #define SOL_COMPILER_GCC_I_ SOL_OFF
60  #define SOL_COMPILER_EDG_I_ SOL_OFF
61  #define SOL_COMPILER_VCXX_I_ SOL_ON
62 #elif defined(__clang__)
63  #define SOL_COMPILER_CLANG_I_ SOL_ON
64  #define SOL_COMPILER_GCC_I_ SOL_OFF
65  #define SOL_COMPILER_EDG_I_ SOL_OFF
66  #define SOL_COMPILER_VCXX_I_ SOL_OFF
67 #elif defined(__GNUC__)
68  #define SOL_COMPILER_CLANG_I_ SOL_OFF
69  #define SOL_COMPILER_GCC_I_ SOL_ON
70  #define SOL_COMPILER_EDG_I_ SOL_OFF
71  #define SOL_COMPILER_VCXX_I_ SOL_OFF
72 #else
73  #define SOL_COMPILER_CLANG_I_ SOL_OFF
74  #define SOL_COMPILER_GCC_I_ SOL_OFF
75  #define SOL_COMPILER_EDG_I_ SOL_OFF
76  #define SOL_COMPILER_VCXX_I_ SOL_OFF
77 #endif
78 
79 #if defined(__MINGW32__)
80  #define SOL_COMPILER_FRONTEND_MINGW_I_ SOL_ON
81 #else
82  #define SOL_COMPILER_FRONTEND_MINGW_I_ SOL_OFF
83 #endif
84 
85 #if SIZE_MAX <= 0xFFFFULL
86  #define SOL_PLATFORM_X16_I_ SOL_ON
87  #define SOL_PLATFORM_X86_I_ SOL_OFF
88  #define SOL_PLATFORM_X64_I_ SOL_OFF
89 #elif SIZE_MAX <= 0xFFFFFFFFULL
90  #define SOL_PLATFORM_X16_I_ SOL_OFF
91  #define SOL_PLATFORM_X86_I_ SOL_ON
92  #define SOL_PLATFORM_X64_I_ SOL_OFF
93 #else
94  #define SOL_PLATFORM_X16_I_ SOL_OFF
95  #define SOL_PLATFORM_X86_I_ SOL_OFF
96  #define SOL_PLATFORM_X64_I_ SOL_ON
97 #endif
98 
99 #define SOL_PLATFORM_ARM32_I_ SOL_OFF
100 #define SOL_PLATFORM_ARM64_I_ SOL_OFF
101 
102 #if defined(_WIN32)
103  #define SOL_PLATFORM_WINDOWS_I_ SOL_ON
104 #else
105  #define SOL_PLATFORM_WINDOWS_I_ SOL_OFF
106 #endif
107 #if defined(__APPLE__)
108  #define SOL_PLATFORM_APPLE_I_ SOL_ON
109 #else
110  #define SOL_PLATFORM_APPLE_I_ SOL_OFF
111 #endif
112 #if defined(__unix__)
113  #define SOL_PLATFORM_UNIXLIKE_I_ SOL_ON
114 #else
115  #define SOL_PLATFORM_UNIXLIKE_I_ SOL_OFF
116 #endif
117 #if defined(__linux__)
118  #define SOL_PLATFORM_LINUXLIKE_I_ SOL_ON
119 #else
120  #define SOL_PLATFORM_LINUXLIKE_I_ SOL_OFF
121 #endif
122 
123 #define SOL_PLATFORM_APPLE_IPHONE_I_ SOL_OFF
124 #define SOL_PLATFORM_BSDLIKE_I_ SOL_OFF
125 
126 #if defined(SOL_IN_DEBUG_DETECTED)
127  #if SOL_IN_DEBUG_DETECTED != 0
128  #define SOL_DEBUG_BUILD_I_ SOL_ON
129  #else
130  #define SOL_DEBUG_BUILD_I_ SOL_OFF
131  #endif
132 #elif !defined(NDEBUG)
133  #if SOL_IS_ON(SOL_COMPILER_VCXX_I_) && defined(_DEBUG)
134  #define SOL_DEBUG_BUILD_I_ SOL_ON
135  #elif (SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_GCC_I_)) && !defined(__OPTIMIZE__)
136  #define SOL_DEBUG_BUILD_I_ SOL_ON
137  #else
138  #define SOL_DEBUG_BUILD_I_ SOL_OFF
139  #endif
140 #else
141  #define SOL_DEBUG_BUILD_I_ SOL_DEFAULT_OFF
142 #endif // We are in a debug mode of some sort
143 
144 #if defined(SOL_NO_EXCEPTIONS)
145  #if (SOL_NO_EXCEPTIONS != 0)
146  #define SOL_EXCEPTIONS_I_ SOL_OFF
147  #else
148  #define SOL_EXCEPTIONS_I_ SOL_ON
149  #endif
150 #elif SOL_IS_ON(SOL_COMPILER_VCXX_I_)
151  #if !defined(_CPPUNWIND)
152  #define SOL_EXCEPTIONS_I_ SOL_OFF
153  #else
154  #define SOL_EXCEPTIONS_I_ SOL_ON
155  #endif
156 #elif SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_GCC_I_)
157  #if !defined(__EXCEPTIONS)
158  #define SOL_EXCEPTIONS_I_ SOL_OFF
159  #else
160  #define SOL_EXCEPTIONS_I_ SOL_ON
161  #endif
162 #else
163  #define SOL_EXCEPTIONS_I_ SOL_DEFAULT_ON
164 #endif
165 
166 #if defined(SOL_NO_RTTI)
167  #if (SOL_NO_RTTI != 0)
168  #define SOL_RTTI_I_ SOL_OFF
169  #else
170  #define SOL_RTTI_I_ SOL_ON
171  #endif
172 #elif SOL_IS_ON(SOL_COMPILER_VCXX_I_)
173  #if !defined(_CPPRTTI)
174  #define SOL_RTTI_I_ SOL_OFF
175  #else
176  #define SOL_RTTI_I_ SOL_ON
177  #endif
178 #elif SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_GCC_I_)
179  #if !defined(__GXX_RTTI)
180  #define SOL_RTTI_I_ SOL_OFF
181  #else
182  #define SOL_RTTI_I_ SOL_ON
183  #endif
184 #else
185  #define SOL_RTTI_I_ SOL_DEFAULT_ON
186 #endif
187 
188 #if defined(SOL_NO_THREAD_LOCAL) && (SOL_NO_THREAD_LOCAL != 0)
189  #define SOL_USE_THREAD_LOCAL_I_ SOL_OFF
190 #else
191  #define SOL_USE_THREAD_LOCAL_I_ SOL_DEFAULT_ON
192 #endif // thread_local keyword is bjorked on some platforms
193 
194 #if defined(SOL_ALL_SAFETIES_ON) && (SOL_ALL_SAFETIES_ON != 0)
195  #define SOL_ALL_SAFETIES_ON_I_ SOL_ON
196 #else
197  #define SOL_ALL_SAFETIES_ON_I_ SOL_DEFAULT_OFF
198 #endif
199 
200 #if defined(SOL_SAFE_GETTER) && (SOL_SAFE_GETTER != 0)
201  #define SOL_SAFE_GETTER_I_ SOL_ON
202 #else
203  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
204  #define SOL_SAFE_GETTER_I_ SOL_ON
205  #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
206  #define SOL_SAFE_GETTER_I_ SOL_DEFAULT_ON
207  #else
208  #define SOL_SAFE_GETTER_I_ SOL_DEFAULT_OFF
209  #endif
210 #endif
211 
212 #if defined(SOL_SAFE_USERTYPE) && (SOL_SAFE_USERTYPE != 0)
213  #define SOL_SAFE_USERTYPE_I_ SOL_ON
214 #else
215  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
216  #define SOL_SAFE_USERTYPE_I_ SOL_ON
217  #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
218  #define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_ON
219  #else
220  #define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_OFF
221  #endif
222 #endif
223 
224 #if defined(SOL_SAFE_REFERENCES) && (SOL_SAFE_REFERENCES != 0)
225  #define SOL_SAFE_REFERENCES_I_ SOL_ON
226 #else
227  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
228  #define SOL_SAFE_REFERENCES_I_ SOL_ON
229  #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
230  #define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_ON
231  #else
232  #define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_OFF
233  #endif
234 #endif
235 
236 #if (defined(SOL_SAFE_FUNCTIONS) && (SOL_SAFE_FUNCTIONS != 0)) \
237  || (defined(SOL_SAFE_FUNCTION_OBJECTS) && (SOL_SAFE_FUNCTION_OBJECTS != 0))
238  #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON
239 #else
240  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
241  #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON
242  #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
243  #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_ON
244  #else
245  #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_OFF
246  #endif
247 #endif
248 
249 #if defined(SOL_SAFE_FUNCTION_CALLS) && (SOL_SAFE_FUNCTION_CALLS != 0)
250  #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON
251 #else
252  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
253  #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON
254  #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
255  #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_ON
256  #else
257  #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_OFF
258  #endif
259 #endif
260 
261 #if defined(SOL_SAFE_PROXIES) && (SOL_SAFE_PROXIES != 0)
262  #define SOL_SAFE_PROXIES_I_ SOL_ON
263 #else
264  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
265  #define SOL_SAFE_PROXIES_I_ SOL_ON
266  #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
267  #define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_ON
268  #else
269  #define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_OFF
270  #endif
271 #endif
272 
273 #if defined(SOL_SAFE_NUMERICS) && (SOL_SAFE_NUMERICS != 0)
274  #define SOL_SAFE_NUMERICS_I_ SOL_ON
275 #else
276  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
277  #define SOL_SAFE_NUMERICS_I_ SOL_ON
278  #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
279  #define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_ON
280  #else
281  #define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_OFF
282  #endif
283 #endif
284 
285 #if defined(SOL_SAFE_STACK_CHECK) && (SOL_SAFE_STACK_CHECK != 0)
286  #define SOL_SAFE_STACK_CHECK_I_ SOL_ON
287 #else
288  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
289  #define SOL_SAFE_STACK_CHECK_I_ SOL_ON
290  #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
291  #define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_ON
292  #else
293  #define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_OFF
294  #endif
295 #endif
296 
297 #if (defined(SOL_NO_CHECK_NUMBER_PRECISION) && (SOL_NO_CHECK_NUMBER_PRECISION != 0)) \
298  || (defined(SOL_NO_CHECKING_NUMBER_PRECISION) && (SOL_NO_CHECKING_NUMBER_PRECISION != 0))
299  #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_OFF
300 #else
301  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
302  #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON
303  #elif SOL_IS_ON(SOL_SAFE_NUMERICS_I_)
304  #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON
305  #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
306  #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_ON
307  #else
308  #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_OFF
309  #endif
310 #endif
311 
312 #if defined(SOL_STRINGS_ARE_NUMBERS)
313  #if (SOL_STRINGS_ARE_NUMBERS != 0)
314  #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_ON
315  #else
316  #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_OFF
317  #endif
318 #else
319  #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_DEFAULT_OFF
320 #endif
321 
322 #if defined(SOL_ENABLE_INTEROP) && (SOL_ENABLE_INTEROP != 0) \
323  || defined(SOL_USE_INTEROP) && (SOL_USE_INTEROP != 0)
324  #define SOL_USE_INTEROP_I_ SOL_ON
325 #else
326  #define SOL_USE_INTEROP_I_ SOL_DEFAULT_OFF
327 #endif
328 
329 #if defined(SOL_NO_NIL)
330  #if (SOL_NO_NIL != 0)
331  #define SOL_NIL_I_ SOL_OFF
332  #else
333  #define SOL_NIL_I_ SOL_ON
334  #endif
335 #elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) || defined(__OBJC__) || defined(nil)
336  #define SOL_NIL_I_ SOL_DEFAULT_OFF
337 #else
338  #define SOL_NIL_I_ SOL_DEFAULT_ON
339 #endif
340 
341 #if defined(SOL_USERTYPE_TYPE_BINDING_INFO)
342  #if (SOL_USERTYPE_TYPE_BINDING_INFO != 0)
343  #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_ON
344  #else
345  #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_OFF
346  #endif
347 #else
348  #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_DEFAULT_ON
349 #endif // We should generate a my_type.__type table with lots of class information for usertypes
350 
351 #if defined(SOL_AUTOMAGICAL_TYPES_BY_DEFAULT)
352  #if (SOL_AUTOMAGICAL_TYPES_BY_DEFAULT != 0)
353  #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON
354  #else
355  #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF
356  #endif
357 #elif defined(SOL_DEFAULT_AUTOMAGICAL_USERTYPES)
358  #if (SOL_DEFAULT_AUTOMAGICAL_USERTYPES != 0)
359  #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON
360  #else
361  #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF
362  #endif
363 #else
364  #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_DEFAULT_ON
365 #endif // make is_automagical on/off by default
366 
367 #if defined(SOL_STD_VARIANT)
368  #if (SOL_STD_VARIANT != 0)
369  #define SOL_STD_VARIANT_I_ SOL_ON
370  #else
371  #define SOL_STD_VARIANT_I_ SOL_OFF
372  #endif
373 #else
374  #if SOL_IS_ON(SOL_COMPILER_CLANG_I_) && SOL_IS_ON(SOL_PLATFORM_APPLE_I_)
375  #if defined(__has_include)
376  #if __has_include(<variant>)
377  #define SOL_STD_VARIANT_I_ SOL_ON
378  #else
379  #define SOL_STD_VARIANT_I_ SOL_OFF
380  #endif
381  #else
382  #define SOL_STD_VARIANT_I_ SOL_OFF
383  #endif
384  #else
385  #define SOL_STD_VARIANT_I_ SOL_DEFAULT_ON
386  #endif
387 #endif // make is_automagical on/off by default
388 
389 #if defined(SOL_NOEXCEPT_FUNCTION_TYPE)
390  #if (SOL_NOEXCEPT_FUNCTION_TYPE != 0)
391  #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON
392  #else
393  #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF
394  #endif
395 #else
396  #if defined(__cpp_noexcept_function_type)
397  #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON
398  #elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) && (defined(_MSVC_LANG) && (_MSVC_LANG < 201403L))
399  // There is a bug in the VC++ compiler??
400  // on /std:c++latest under x86 conditions (VS 15.5.2),
401  // compiler errors are tossed for noexcept markings being on function types
402  // that are identical in every other way to their non-noexcept marked types function types...
403  // VS 2019: There is absolutely a bug.
404  #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF
405  #else
406  #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_DEFAULT_ON
407  #endif
408 #endif // noexcept is part of a function's type
409 
410 #if defined(SOL_STACK_STRING_OPTIMIZATION_SIZE) && SOL_STACK_STRING_OPTIMIZATION_SIZE > 0
411  #define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ SOL_STACK_STRING_OPTIMIZATION_SIZE
412 #else
413  #define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ 1024
414 #endif
415 
416 #if defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0
417  #define SOL_ID_SIZE_I_ SOL_ID_SIZE
418 #else
419  #define SOL_ID_SIZE_I_ 512
420 #endif
421 
422 #if defined(LUA_IDSIZE) && LUA_IDSIZE > 0
423  #define SOL_FILE_ID_SIZE_I_ LUA_IDSIZE
424 #elif defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0
425  #define SOL_FILE_ID_SIZE_I_ SOL_FILE_ID_SIZE
426 #else
427  #define SOL_FILE_ID_SIZE_I_ 2048
428 #endif
429 
430 #if defined(SOL_PRINT_ERRORS)
431  #if (SOL_PRINT_ERRORS != 0)
432  #define SOL_PRINT_ERRORS_I_ SOL_ON
433  #else
434  #define SOL_PRINT_ERRORS_I_ SOL_OFF
435  #endif
436 #else
437  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
438  #define SOL_PRINT_ERRORS_I_ SOL_ON
439  #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
440  #define SOL_PRINT_ERRORS_I_ SOL_DEFAULT_ON
441  #else
442  #define SOL_PRINT_ERRORS_I_ SOL_OFF
443  #endif
444 #endif
445 
446 #if defined(SOL_DEFAULT_PASS_ON_ERROR) && (SOL_DEFAULT_PASS_ON_ERROR != 0)
447  #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_ON
448 #else
449  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
450  #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_ON
451  #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
452  #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_DEFAULT_ON
453  #else
454  #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_OFF
455  #endif
456 #endif
457 
458 #if defined(SOL_USING_CXX_LUA)
459  #if (SOL_USING_CXX_LUA != 0)
460  #define SOL_USE_CXX_LUA_I_ SOL_ON
461  #else
462  #define SOL_USE_CXX_LUA_I_ SOL_OFF
463  #endif
464 #elif defined(SOL_USE_CXX_LUA)
465  #if (SOL_USE_CXX_LUA != 0)
466  #define SOL_USE_CXX_LUA_I_ SOL_ON
467  #else
468  #define SOL_USE_CXX_LUA_I_ SOL_OFF
469  #endif
470 #else
471  #define SOL_USE_CXX_LUA_I_ SOL_OFF
472 #endif
473 
474 #if defined(SOL_USING_CXX_LUAJIT)
475  #if (SOL_USING_CXX_LUA != 0)
476  #define SOL_USE_CXX_LUAJIT_I_ SOL_ON
477  #else
478  #define SOL_USE_CXX_LUAJIT_I_ SOL_OFF
479  #endif
480 #elif defined(SOL_USE_CXX_LUAJIT)
481  #if (SOL_USE_CXX_LUA != 0)
482  #define SOL_USE_CXX_LUAJIT_I_ SOL_ON
483  #else
484  #define SOL_USE_CXX_LUAJIT_I_ SOL_OFF
485  #endif
486 #else
487  #define SOL_USE_CXX_LUAJIT_I_ SOL_OFF
488 #endif
489 
490 #if defined(SOL_NO_LUA_HPP)
491  #if (SOL_NO_LUA_HPP != 0)
492  #define SOL_USE_LUA_HPP_I_ SOL_OFF
493  #else
494  #define SOL_USE_LUA_HPP_I_ SOL_ON
495  #endif
496 #elif defined(SOL_USING_CXX_LUA)
497  #define SOL_USE_LUA_HPP_I_ SOL_OFF
498 #elif defined(__has_include)
499  #if __has_include(<lua.hpp>)
500  #define SOL_USE_LUA_HPP_I_ SOL_ON
501  #else
502  #define SOL_USE_LUA_HPP_I_ SOL_OFF
503  #endif
504 #else
505  #define SOL_USE_LUA_HPP_I_ SOL_DEFAULT_ON
506 #endif
507 
508 #if defined(SOL_CONTAINERS_START)
509  #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START
510 #elif defined(SOL_CONTAINERS_START_INDEX)
511  #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START_INDEX
512 #elif defined(SOL_CONTAINER_START_INDEX)
513  #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINER_START_INDEX
514 #else
515  #define SOL_CONTAINER_START_INDEX_I_ 1
516 #endif
517 
518 #if defined (SOL_NO_MEMORY_ALIGNMENT)
519  #if (SOL_NO_MEMORY_ALIGNMENT != 0)
520  #define SOL_ALIGN_MEMORY_I_ SOL_OFF
521  #else
522  #define SOL_ALIGN_MEMORY_I_ SOL_ON
523  #endif
524 #else
525  #define SOL_ALIGN_MEMORY_I_ SOL_DEFAULT_ON
526 #endif
527 
528 #if defined(SOL_USE_BOOST)
529  #if (SOL_USE_BOOST != 0)
530  #define SOL_USE_BOOST_I_ SOL_ON
531  #else
532  #define SOL_USE_BOOST_I_ SOL_OFF
533  #endif
534 #else
535  #define SOL_USE_BOOST_I_ SOL_OFF
536 #endif
537 
538 #if defined(SOL_USE_UNSAFE_BASE_LOOKUP)
539  #if (SOL_USE_UNSAFE_BASE_LOOKUP != 0)
540  #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_ON
541  #else
542  #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_OFF
543  #endif
544 #else
545  #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_OFF
546 #endif
547 
548 #if defined(SOL_INSIDE_UNREAL)
549  #if (SOL_INSIDE_UNREAL != 0)
550  #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_ON
551  #else
552  #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_OFF
553  #endif
554 #else
555  #if defined(UE_BUILD_DEBUG) || defined(UE_BUILD_DEVELOPMENT) || defined(UE_BUILD_TEST) || defined(UE_BUILD_SHIPPING) || defined(UE_SERVER)
556  #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_ON
557  #else
558  #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_DEFAULT_OFF
559  #endif
560 #endif
561 
562 #if defined(SOL_NO_COMPAT)
563  #if (SOL_NO_COMPAT != 0)
564  #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_OFF
565  #else
566  #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_ON
567  #endif
568 #else
569  #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_DEFAULT_ON
570 #endif
571 
572 #if defined(SOL_GET_FUNCTION_POINTER_UNSAFE)
573  #if (SOL_GET_FUNCTION_POINTER_UNSAFE != 0)
574  #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_ON
575  #else
576  #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_OFF
577  #endif
578 #else
579  #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_DEFAULT_OFF
580 #endif
581 
582 #if SOL_IS_ON(SOL_COMPILER_FRONTEND_MINGW_I_) && defined(__GNUC__) && (__GNUC__ < 6)
583  // MinGW is off its rocker in some places...
584  #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_ON
585 #else
586  #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_DEFAULT_OFF
587 #endif
588 
589 // end of sol/version.hpp
590 
591 #if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE_I_)
592 #ifdef check
593 #pragma push_macro("check")
594 #undef check
595 #endif
596 #endif // Unreal Engine 4 Bullshit
597 
598 #if SOL_IS_ON(SOL_COMPILER_GCC_I_)
599 #pragma GCC diagnostic push
600 #pragma GCC diagnostic ignored "-Wshadow"
601 #pragma GCC diagnostic ignored "-Wconversion"
602 #if __GNUC__ > 6
603 #pragma GCC diagnostic ignored "-Wnoexcept-type"
604 #endif
605 #elif SOL_IS_ON(SOL_COMPILER_CLANG_I_)
606 #elif SOL_IS_ON(SOL_COMPILER_VCXX_I_)
607 #pragma warning(push)
608 #pragma warning(disable : 4505) // unreferenced local function has been removed GEE THANKS
609 #endif // clang++ vs. g++ vs. VC++
610 
611 // beginning of sol/forward.hpp
612 
613 #ifndef SOL_FORWARD_HPP
614 #define SOL_FORWARD_HPP
615 
616 #include <utility>
617 #include <type_traits>
618 #include <string_view>
619 
620 #if SOL_IS_ON(SOL_USE_CXX_LUA_I_) || SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_)
621 struct lua_State;
622 #else
623 extern "C" {
624 struct lua_State;
625 }
626 #endif // C++ Mangling for Lua vs. Not
627 
628 namespace sol {
629 
630  enum class type;
631 
632  class stateless_reference;
633  template <bool b>
634  class basic_reference;
635  using reference = basic_reference<false>;
636  using main_reference = basic_reference<true>;
637  class stateless_stack_reference;
638  class stack_reference;
639 
640  template <typename A>
641  class basic_bytecode;
642 
643  struct lua_value;
644 
645  struct proxy_base_tag;
646  template <typename>
647  struct proxy_base;
648  template <typename, typename>
649  struct table_proxy;
650 
651  template <bool, typename>
652  class basic_table_core;
653  template <bool b>
654  using table_core = basic_table_core<b, reference>;
655  template <bool b>
656  using main_table_core = basic_table_core<b, main_reference>;
657  template <bool b>
658  using stack_table_core = basic_table_core<b, stack_reference>;
659  template <typename base_type>
660  using basic_table = basic_table_core<false, base_type>;
661  using table = table_core<false>;
662  using global_table = table_core<true>;
663  using main_table = main_table_core<false>;
664  using main_global_table = main_table_core<true>;
665  using stack_table = stack_table_core<false>;
666  using stack_global_table = stack_table_core<true>;
667 
668  template <typename>
669  struct basic_lua_table;
670  using lua_table = basic_lua_table<reference>;
671  using stack_lua_table = basic_lua_table<stack_reference>;
672 
673  template <typename T, typename base_type>
674  class basic_usertype;
675  template <typename T>
676  using usertype = basic_usertype<T, reference>;
677  template <typename T>
678  using stack_usertype = basic_usertype<T, stack_reference>;
679 
680  template <typename base_type>
681  class basic_metatable;
682  using metatable = basic_metatable<reference>;
683  using stack_metatable = basic_metatable<stack_reference>;
684 
685  template <typename base_t>
686  struct basic_environment;
687  using environment = basic_environment<reference>;
688  using main_environment = basic_environment<main_reference>;
689  using stack_environment = basic_environment<stack_reference>;
690 
691  template <typename T, bool>
692  class basic_function;
693  template <typename T, bool, typename H>
694  class basic_protected_function;
695  using unsafe_function = basic_function<reference, false>;
696  using safe_function = basic_protected_function<reference, false, reference>;
697  using main_unsafe_function = basic_function<main_reference, false>;
698  using main_safe_function = basic_protected_function<main_reference, false, reference>;
699  using stack_unsafe_function = basic_function<stack_reference, false>;
700  using stack_safe_function = basic_protected_function<stack_reference, false, reference>;
701  using stack_aligned_unsafe_function = basic_function<stack_reference, true>;
702  using stack_aligned_safe_function = basic_protected_function<stack_reference, true, reference>;
707 #if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_)
708  using function = protected_function;
712 #else
713  using function = unsafe_function;
717 #endif
718  using stack_aligned_stack_handler_function = basic_protected_function<stack_reference, true, stack_reference>;
719 
720  struct unsafe_function_result;
721  struct protected_function_result;
722  using safe_function_result = protected_function_result;
723 #if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_)
725 #else
726  using function_result = unsafe_function_result;
727 #endif
728 
729  template <typename base_t>
730  class basic_object_base;
731  template <typename base_t>
732  class basic_object;
733  template <typename base_t>
734  class basic_userdata;
735  template <typename base_t>
736  class basic_lightuserdata;
737  template <typename base_t>
738  class basic_coroutine;
739  template <typename base_t>
740  class basic_thread;
741 
742  using object = basic_object<reference>;
743  using userdata = basic_userdata<reference>;
744  using lightuserdata = basic_lightuserdata<reference>;
745  using thread = basic_thread<reference>;
746  using coroutine = basic_coroutine<reference>;
747  using main_object = basic_object<main_reference>;
748  using main_userdata = basic_userdata<main_reference>;
749  using main_lightuserdata = basic_lightuserdata<main_reference>;
750  using main_coroutine = basic_coroutine<main_reference>;
751  using stack_object = basic_object<stack_reference>;
752  using stack_userdata = basic_userdata<stack_reference>;
753  using stack_lightuserdata = basic_lightuserdata<stack_reference>;
754  using stack_thread = basic_thread<stack_reference>;
755  using stack_coroutine = basic_coroutine<stack_reference>;
756 
757  struct stack_proxy_base;
758  struct stack_proxy;
759  struct variadic_args;
760  struct variadic_results;
761  struct stack_count;
762  struct this_state;
763  struct this_main_state;
764  struct this_environment;
765 
766  class state_view;
767  class state;
768 
769  template <typename T>
770  struct as_table_t;
771  template <typename T>
772  struct as_container_t;
773  template <typename T>
774  struct nested;
775  template <typename T>
776  struct light;
777  template <typename T>
778  struct user;
779  template <typename T>
780  struct as_args_t;
781  template <typename T>
782  struct protect_t;
783  template <typename F, typename... Policies>
784  struct policy_wrapper;
785 
786  template <typename T>
787  struct usertype_traits;
788  template <typename T>
789  struct unique_usertype_traits;
790 
791  template <typename... Args>
792  struct types {
793  typedef std::make_index_sequence<sizeof...(Args)> indices;
794  static constexpr std::size_t size() {
795  return sizeof...(Args);
796  }
797  };
798 
799  template <typename T>
800  struct derive : std::false_type {
801  typedef types<> type;
802  };
803 
804  template <typename T>
805  struct base : std::false_type {
806  typedef types<> type;
807  };
808 
809  template <typename T>
810  struct weak_derive {
811  static bool value;
812  };
813 
814  template <typename T>
815  bool weak_derive<T>::value = false;
816 
817  namespace stack {
818  struct record;
819  }
820 
821 #if SOL_IS_OFF(SOL_USE_BOOST_I_)
822  template <class T>
823  class optional;
824 
825  template <class T>
826  class optional<T&>;
827 #endif
828 
829  using check_handler_type = int(lua_State*, int, type, type, const char*);
830 
831 } // namespace sol
832 
833 #define SOL_BASE_CLASSES(T, ...) \
834  namespace sol { \
835  template <> \
836  struct base<T> : std::true_type { \
837  typedef ::sol::types<__VA_ARGS__> type; \
838  }; \
839  } \
840  void a_sol3_detail_function_decl_please_no_collide()
841 #define SOL_DERIVED_CLASSES(T, ...) \
842  namespace sol { \
843  template <> \
844  struct derive<T> : std::true_type { \
845  typedef ::sol::types<__VA_ARGS__> type; \
846  }; \
847  } \
848  void a_sol3_detail_function_decl_please_no_collide()
849 
850 #endif // SOL_FORWARD_HPP
851 // end of sol/forward.hpp
852 
853 // beginning of sol/forward_detail.hpp
854 
855 #ifndef SOL_FORWARD_DETAIL_HPP
856 #define SOL_FORWARD_DETAIL_HPP
857 
858 // beginning of sol/traits.hpp
859 
860 // beginning of sol/tuple.hpp
861 
862 // beginning of sol/base_traits.hpp
863 
864 #include <type_traits>
865 
866 namespace sol {
867  namespace detail {
868  struct unchecked_t {};
870  } // namespace detail
871 
872  namespace meta {
873  using sfinae_yes_t = std::true_type;
874  using sfinae_no_t = std::false_type;
875 
876  template <typename T>
877  using void_t = void;
878 
879  template <typename T>
880  using unqualified = std::remove_cv<std::remove_reference_t<T>>;
881 
882  template <typename T>
884 
885  namespace meta_detail {
886  template <typename T>
888 
889  template <template <class...> class Test, class, class... Args>
890  struct is_detected : std::false_type {};
891 
892  template <template <class...> class Test, class... Args>
893  struct is_detected<Test, void_t<Test<Args...>>, Args...> : std::true_type {};
894  } // namespace meta_detail
895 
896  template <template <class...> class Trait, class... Args>
897  using is_detected = typename meta_detail::is_detected<Trait, void, Args...>::type;
898 
899  template <template <class...> class Trait, class... Args>
900  constexpr inline bool is_detected_v = is_detected<Trait, Args...>::value;
901 
902  template <std::size_t I>
903  using index_value = std::integral_constant<std::size_t, I>;
904 
905  template <bool>
906  struct conditional {
907  template <typename T, typename U>
908  using type = T;
909  };
910 
911  template <>
912  struct conditional<false> {
913  template <typename T, typename U>
914  using type = U;
915  };
916 
917  template <bool B, typename T, typename U>
919 
920  namespace meta_detail {
921  template <typename T, template <typename...> class Templ>
922  struct is_specialization_of : std::false_type {};
923  template <typename... T, template <typename...> class Templ>
924  struct is_specialization_of<Templ<T...>, Templ> : std::true_type {};
925  } // namespace meta_detail
926 
927  template <typename T, template <typename...> class Templ>
929 
930  template <typename T, template <typename...> class Templ>
931  inline constexpr bool is_specialization_of_v = is_specialization_of<std::remove_cv_t<T>, Templ>::value;
932 
933  template <typename T>
934  struct identity {
935  typedef T type;
936  };
937 
938  template <typename T>
939  using identity_t = typename identity<T>::type;
940 
941  template <typename T>
943 
944  } // namespace meta
945 } // namespace sol
946 
947 // end of sol/base_traits.hpp
948 
949 #include <tuple>
950 #include <cstddef>
951 
952 namespace sol {
953  namespace detail {
954  using swallow = std::initializer_list<int>;
955  } // namespace detail
956 
957  namespace meta {
958  template <typename T>
960 
961  template <typename T>
962  constexpr inline bool is_tuple_v = is_tuple<T>::value;
963 
964  namespace detail {
965  template <typename... Args>
966  struct tuple_types_ { typedef types<Args...> type; };
967 
968  template <typename... Args>
969  struct tuple_types_<std::tuple<Args...>> { typedef types<Args...> type; };
970  } // namespace detail
971 
972  template <typename... Args>
973  using tuple_types = typename detail::tuple_types_<Args...>::type;
974 
975  template <typename Arg>
977 
978  template <typename Arg>
980 
981  template <typename... Args>
982  struct pop_front_type<types<Args...>> {
983  typedef void front_type;
984  typedef types<Args...> type;
985  };
986 
987  template <typename Arg, typename... Args>
988  struct pop_front_type<types<Arg, Args...>> {
989  typedef Arg front_type;
990  typedef types<Args...> type;
991  };
992 
993  template <std::size_t N, typename Tuple>
994  using tuple_element = std::tuple_element<N, std::remove_reference_t<Tuple>>;
995 
996  template <std::size_t N, typename Tuple>
997  using tuple_element_t = std::tuple_element_t<N, std::remove_reference_t<Tuple>>;
998 
999  template <std::size_t N, typename Tuple>
1001 
1002  template <std::size_t N, typename Tuple>
1004 
1005  } // namespace meta
1006 } // namespace sol
1007 
1008 // end of sol/tuple.hpp
1009 
1010 // beginning of sol/bind_traits.hpp
1011 
1012 namespace sol { namespace meta {
1013  namespace meta_detail {
1014 
1015  template <class F>
1017  struct nat {};
1018  template <class G>
1019  static auto test(int) -> decltype(&G::operator(), void());
1020  template <class>
1021  static auto test(...) -> nat;
1022 
1023  using type = std::is_void<decltype(test<F>(0))>;
1024  };
1025  } // namespace meta_detail
1026 
1027  template <class F>
1029 
1030  namespace meta_detail {
1031 
1032  template <std::size_t I, typename T>
1034 
1035  template <std::size_t I>
1036  struct void_tuple_element<I, std::tuple<>> {
1037  typedef void type;
1038  };
1039 
1040  template <std::size_t I, typename T>
1042 
1043  template <bool it_is_noexcept, bool has_c_variadic, typename T, typename R, typename... Args>
1044  struct basic_traits {
1045  private:
1047 
1048  public:
1049  inline static constexpr const bool is_noexcept = it_is_noexcept;
1050  inline static constexpr bool is_member_function = std::is_void<T>::value;
1051  inline static constexpr bool has_c_var_arg = has_c_variadic;
1052  inline static constexpr std::size_t arity = sizeof...(Args);
1053  inline static constexpr std::size_t free_arity = sizeof...(Args) + static_cast<std::size_t>(!std::is_void<T>::value);
1054  typedef types<Args...> args_list;
1055  typedef std::tuple<Args...> args_tuple;
1056  typedef T object_type;
1057  typedef R return_type;
1059  typedef R(function_type)(Args...);
1061  typedef meta::conditional_t<std::is_void<T>::value, R(Args...), R(first_type, Args...)> free_function_type;
1062  typedef meta::conditional_t<std::is_void<T>::value, R (*)(Args...), R (*)(first_type, Args...)> free_function_pointer_type;
1063  typedef std::remove_pointer_t<free_function_pointer_type> signature_type;
1064  template <std::size_t i>
1066  };
1067 
1069  struct fx_traits : basic_traits<false, false, void, void> {};
1070 
1071  // Free Functions
1072  template <typename R, typename... Args>
1073  struct fx_traits<R(Args...), false> : basic_traits<false, false, void, R, Args...> {
1074  typedef R (*function_pointer_type)(Args...);
1075  };
1076 
1077  template <typename R, typename... Args>
1078  struct fx_traits<R (*)(Args...), false> : basic_traits<false, false, void, R, Args...> {
1079  typedef R (*function_pointer_type)(Args...);
1080  };
1081 
1082  template <typename R, typename... Args>
1083  struct fx_traits<R(Args..., ...), false> : basic_traits<false, true, void, R, Args...> {
1084  typedef R (*function_pointer_type)(Args..., ...);
1085  };
1086 
1087  template <typename R, typename... Args>
1088  struct fx_traits<R (*)(Args..., ...), false> : basic_traits<false, true, void, R, Args...> {
1089  typedef R (*function_pointer_type)(Args..., ...);
1090  };
1091 
1092  // Member Functions
1093  /* C-Style Variadics */
1094  template <typename T, typename R, typename... Args>
1095  struct fx_traits<R (T::*)(Args...), false> : basic_traits<false, false, T, R, Args...> {
1096  typedef R (T::*function_pointer_type)(Args...);
1097  };
1098 
1099  template <typename T, typename R, typename... Args>
1100  struct fx_traits<R (T::*)(Args..., ...), false> : basic_traits<false, true, T, R, Args...> {
1101  typedef R (T::*function_pointer_type)(Args..., ...);
1102  };
1103 
1104  /* Const Volatile */
1105  template <typename T, typename R, typename... Args>
1106  struct fx_traits<R (T::*)(Args...) const, false> : basic_traits<false, false, T, R, Args...> {
1107  typedef R (T::*function_pointer_type)(Args...) const;
1108  };
1109 
1110  template <typename T, typename R, typename... Args>
1111  struct fx_traits<R (T::*)(Args..., ...) const, false> : basic_traits<false, true, T, R, Args...> {
1112  typedef R (T::*function_pointer_type)(Args..., ...) const;
1113  };
1114 
1115  template <typename T, typename R, typename... Args>
1116  struct fx_traits<R (T::*)(Args...) const volatile, false> : basic_traits<false, false, T, R, Args...> {
1117  typedef R (T::*function_pointer_type)(Args...) const volatile;
1118  };
1119 
1120  template <typename T, typename R, typename... Args>
1121  struct fx_traits<R (T::*)(Args..., ...) const volatile, false> : basic_traits<false, true, T, R, Args...> {
1122  typedef R (T::*function_pointer_type)(Args..., ...) const volatile;
1123  };
1124 
1125  /* Member Function Qualifiers */
1126  template <typename T, typename R, typename... Args>
1127  struct fx_traits<R (T::*)(Args...)&, false> : basic_traits<false, false, T, R, Args...> {
1128  typedef R (T::*function_pointer_type)(Args...) &;
1129  };
1130 
1131  template <typename T, typename R, typename... Args>
1132  struct fx_traits<R (T::*)(Args..., ...)&, false> : basic_traits<false, true, T, R, Args...> {
1133  typedef R (T::*function_pointer_type)(Args..., ...) &;
1134  };
1135 
1136  template <typename T, typename R, typename... Args>
1137  struct fx_traits<R (T::*)(Args...) const&, false> : basic_traits<false, false, T, R, Args...> {
1138  typedef R (T::*function_pointer_type)(Args...) const&;
1139  };
1140 
1141  template <typename T, typename R, typename... Args>
1142  struct fx_traits<R (T::*)(Args..., ...) const&, false> : basic_traits<false, true, T, R, Args...> {
1143  typedef R (T::*function_pointer_type)(Args..., ...) const&;
1144  };
1145 
1146  template <typename T, typename R, typename... Args>
1147  struct fx_traits<R (T::*)(Args...) const volatile&, false> : basic_traits<false, false, T, R, Args...> {
1148  typedef R (T::*function_pointer_type)(Args...) const volatile&;
1149  };
1150 
1151  template <typename T, typename R, typename... Args>
1152  struct fx_traits<R (T::*)(Args..., ...) const volatile&, false> : basic_traits<false, true, T, R, Args...> {
1153  typedef R (T::*function_pointer_type)(Args..., ...) const volatile&;
1154  };
1155 
1156  template <typename T, typename R, typename... Args>
1157  struct fx_traits<R (T::*)(Args...)&&, false> : basic_traits<false, false, T, R, Args...> {
1158  typedef R (T::*function_pointer_type)(Args...) &&;
1159  };
1160 
1161  template <typename T, typename R, typename... Args>
1162  struct fx_traits<R (T::*)(Args..., ...)&&, false> : basic_traits<false, true, T, R, Args...> {
1163  typedef R (T::*function_pointer_type)(Args..., ...) &&;
1164  };
1165 
1166  template <typename T, typename R, typename... Args>
1167  struct fx_traits<R (T::*)(Args...) const&&, false> : basic_traits<false, false, T, R, Args...> {
1168  typedef R (T::*function_pointer_type)(Args...) const&&;
1169  };
1170 
1171  template <typename T, typename R, typename... Args>
1172  struct fx_traits<R (T::*)(Args..., ...) const&&, false> : basic_traits<false, true, T, R, Args...> {
1173  typedef R (T::*function_pointer_type)(Args..., ...) const&&;
1174  };
1175 
1176  template <typename T, typename R, typename... Args>
1177  struct fx_traits<R (T::*)(Args...) const volatile&&, false> : basic_traits<false, false, T, R, Args...> {
1178  typedef R (T::*function_pointer_type)(Args...) const volatile&&;
1179  };
1180 
1181  template <typename T, typename R, typename... Args>
1182  struct fx_traits<R (T::*)(Args..., ...) const volatile&&, false> : basic_traits<false, true, T, R, Args...> {
1183  typedef R (T::*function_pointer_type)(Args..., ...) const volatile&&;
1184  };
1185 
1186 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
1187 
1188  template <typename R, typename... Args>
1189  struct fx_traits<R(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
1190  typedef R (*function_pointer_type)(Args...) noexcept;
1191  };
1192 
1193  template <typename R, typename... Args>
1194  struct fx_traits<R (*)(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
1195  typedef R (*function_pointer_type)(Args...) noexcept;
1196  };
1197 
1198  template <typename R, typename... Args>
1199  struct fx_traits<R(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
1200  typedef R (*function_pointer_type)(Args..., ...) noexcept;
1201  };
1202 
1203  template <typename R, typename... Args>
1204  struct fx_traits<R (*)(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
1205  typedef R (*function_pointer_type)(Args..., ...) noexcept;
1206  };
1207 
1208  template <typename T, typename R, typename... Args>
1209  struct fx_traits<R (T::*)(Args...) noexcept, false> : basic_traits<true, false, T, R, Args...> {
1210  typedef R (T::*function_pointer_type)(Args...) noexcept;
1211  };
1212 
1213  template <typename T, typename R, typename... Args>
1214  struct fx_traits<R (T::*)(Args..., ...) noexcept, false> : basic_traits<true, true, T, R, Args...> {
1215  typedef R (T::*function_pointer_type)(Args..., ...) noexcept;
1216  };
1217 
1218  /* Const Volatile */
1219  template <typename T, typename R, typename... Args>
1220  struct fx_traits<R (T::*)(Args...) const noexcept, false> : basic_traits<true, false, T, R, Args...> {
1221  typedef R (T::*function_pointer_type)(Args...) const noexcept;
1222  };
1223 
1224  template <typename T, typename R, typename... Args>
1225  struct fx_traits<R (T::*)(Args..., ...) const noexcept, false> : basic_traits<true, true, T, R, Args...> {
1226  typedef R (T::*function_pointer_type)(Args..., ...) const noexcept;
1227  };
1228 
1229  template <typename T, typename R, typename... Args>
1230  struct fx_traits<R (T::*)(Args...) const volatile noexcept, false> : basic_traits<true, false, T, R, Args...> {
1231  typedef R (T::*function_pointer_type)(Args...) const volatile noexcept;
1232  };
1233 
1234  template <typename T, typename R, typename... Args>
1235  struct fx_traits<R (T::*)(Args..., ...) const volatile noexcept, false> : basic_traits<true, true, T, R, Args...> {
1236  typedef R (T::*function_pointer_type)(Args..., ...) const volatile noexcept;
1237  };
1238 
1239  template <typename T, typename R, typename... Args>
1240  struct fx_traits<R (T::*)(Args...) & noexcept, false> : basic_traits<true, false, T, R, Args...> {
1241  typedef R (T::*function_pointer_type)(Args...) & noexcept;
1242  };
1243 
1244  template <typename T, typename R, typename... Args>
1245  struct fx_traits<R (T::*)(Args..., ...) & noexcept, false> : basic_traits<true, true, T, R, Args...> {
1246  typedef R (T::*function_pointer_type)(Args..., ...) & noexcept;
1247  };
1248 
1249  template <typename T, typename R, typename... Args>
1250  struct fx_traits<R (T::*)(Args...) const& noexcept, false> : basic_traits<true, false, T, R, Args...> {
1251  typedef R (T::*function_pointer_type)(Args...) const& noexcept;
1252  };
1253 
1254  template <typename T, typename R, typename... Args>
1255  struct fx_traits<R (T::*)(Args..., ...) const& noexcept, false> : basic_traits<true, true, T, R, Args...> {
1256  typedef R (T::*function_pointer_type)(Args..., ...) const& noexcept;
1257  };
1258 
1259  template <typename T, typename R, typename... Args>
1260  struct fx_traits<R (T::*)(Args...) const volatile& noexcept, false> : basic_traits<true, false, T, R, Args...> {
1261  typedef R (T::*function_pointer_type)(Args...) const volatile& noexcept;
1262  };
1263 
1264  template <typename T, typename R, typename... Args>
1265  struct fx_traits<R (T::*)(Args..., ...) const volatile& noexcept, false> : basic_traits<true, true, T, R, Args...> {
1266  typedef R (T::*function_pointer_type)(Args..., ...) const volatile& noexcept;
1267  };
1268 
1269  template <typename T, typename R, typename... Args>
1270  struct fx_traits<R (T::*)(Args...) && noexcept, false> : basic_traits<true, false, T, R, Args...> {
1271  typedef R (T::*function_pointer_type)(Args...) && noexcept;
1272  };
1273 
1274  template <typename T, typename R, typename... Args>
1275  struct fx_traits<R (T::*)(Args..., ...) && noexcept, false> : basic_traits<true, true, T, R, Args...> {
1276  typedef R (T::*function_pointer_type)(Args..., ...) && noexcept;
1277  };
1278 
1279  template <typename T, typename R, typename... Args>
1280  struct fx_traits<R (T::*)(Args...) const&& noexcept, false> : basic_traits<true, false, T, R, Args...> {
1281  typedef R (T::*function_pointer_type)(Args...) const&& noexcept;
1282  };
1283 
1284  template <typename T, typename R, typename... Args>
1285  struct fx_traits<R (T::*)(Args..., ...) const&& noexcept, false> : basic_traits<true, true, T, R, Args...> {
1286  typedef R (T::*function_pointer_type)(Args..., ...) const&& noexcept;
1287  };
1288 
1289  template <typename T, typename R, typename... Args>
1290  struct fx_traits<R (T::*)(Args...) const volatile&& noexcept, false> : basic_traits<true, false, T, R, Args...> {
1291  typedef R (T::*function_pointer_type)(Args...) const volatile&& noexcept;
1292  };
1293 
1294  template <typename T, typename R, typename... Args>
1295  struct fx_traits<R (T::*)(Args..., ...) const volatile&& noexcept, false> : basic_traits<true, true, T, R, Args...> {
1296  typedef R (T::*function_pointer_type)(Args..., ...) const volatile&& noexcept;
1297  };
1298 
1299 #endif // noexcept is part of a function's type
1300 
1301 #if SOL_IS_ON(SOL_COMPILER_VCXX_I_) && SOL_IS_ON(SOL_PLATFORM_X86_I_)
1302  template <typename R, typename... Args>
1303  struct fx_traits<R __stdcall(Args...), false> : basic_traits<false, false, void, R, Args...> {
1304  typedef R(__stdcall* function_pointer_type)(Args...);
1305  };
1306 
1307  template <typename R, typename... Args>
1308  struct fx_traits<R(__stdcall*)(Args...), false> : basic_traits<false, false, void, R, Args...> {
1309  typedef R(__stdcall* function_pointer_type)(Args...);
1310  };
1311 
1312  template <typename T, typename R, typename... Args>
1313  struct fx_traits<R (__stdcall T::*)(Args...), false> : basic_traits<false, false, T, R, Args...> {
1314  typedef R (__stdcall T::*function_pointer_type)(Args...);
1315  };
1316 
1317  /* Const Volatile */
1318  template <typename T, typename R, typename... Args>
1319  struct fx_traits<R (__stdcall T::*)(Args...) const, false> : basic_traits<false, false, T, R, Args...> {
1320  typedef R (__stdcall T::*function_pointer_type)(Args...) const;
1321  };
1322 
1323  template <typename T, typename R, typename... Args>
1324  struct fx_traits<R (__stdcall T::*)(Args...) const volatile, false> : basic_traits<false, false, T, R, Args...> {
1325  typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile;
1326  };
1327 
1328  /* Member Function Qualifiers */
1329  template <typename T, typename R, typename... Args>
1330  struct fx_traits<R (__stdcall T::*)(Args...)&, false> : basic_traits<false, false, T, R, Args...> {
1331  typedef R (__stdcall T::*function_pointer_type)(Args...) &;
1332  };
1333 
1334  template <typename T, typename R, typename... Args>
1335  struct fx_traits<R (__stdcall T::*)(Args...) const&, false> : basic_traits<false, false, T, R, Args...> {
1336  typedef R (__stdcall T::*function_pointer_type)(Args...) const&;
1337  };
1338 
1339  template <typename T, typename R, typename... Args>
1340  struct fx_traits<R (__stdcall T::*)(Args...) const volatile&, false> : basic_traits<false, false, T, R, Args...> {
1341  typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&;
1342  };
1343 
1344  template <typename T, typename R, typename... Args>
1345  struct fx_traits<R (__stdcall T::*)(Args...)&&, false> : basic_traits<false, false, T, R, Args...> {
1346  typedef R (__stdcall T::*function_pointer_type)(Args...) &&;
1347  };
1348 
1349  template <typename T, typename R, typename... Args>
1350  struct fx_traits<R (__stdcall T::*)(Args...) const&&, false> : basic_traits<false, false, T, R, Args...> {
1351  typedef R (__stdcall T::*function_pointer_type)(Args...) const&&;
1352  };
1353 
1354  template <typename T, typename R, typename... Args>
1355  struct fx_traits<R (__stdcall T::*)(Args...) const volatile&&, false> : basic_traits<false, false, T, R, Args...> {
1356  typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&&;
1357  };
1358 
1359 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
1360 
1361  template <typename R, typename... Args>
1362  struct fx_traits<R __stdcall(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
1363  typedef R(__stdcall* function_pointer_type)(Args...) noexcept;
1364  };
1365 
1366  template <typename R, typename... Args>
1367  struct fx_traits<R(__stdcall*)(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
1368  typedef R(__stdcall* function_pointer_type)(Args...) noexcept;
1369  };
1370 
1371  /* __stdcall cannot be applied to functions with varargs*/
1372  /*template <typename R, typename... Args>
1373  struct fx_traits<__stdcall R(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
1374  typedef R(__stdcall* function_pointer_type)(Args..., ...) noexcept;
1375  };
1376 
1377  template <typename R, typename... Args>
1378  struct fx_traits<R (__stdcall *)(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
1379  typedef R(__stdcall* function_pointer_type)(Args..., ...) noexcept;
1380  };*/
1381 
1382  template <typename T, typename R, typename... Args>
1383  struct fx_traits<R (__stdcall T::*)(Args...) noexcept, false> : basic_traits<true, false, T, R, Args...> {
1384  typedef R (__stdcall T::*function_pointer_type)(Args...) noexcept;
1385  };
1386 
1387  /* __stdcall does not work with varargs */
1388  /*template <typename T, typename R, typename... Args>
1389  struct fx_traits<R (__stdcall T::*)(Args..., ...) noexcept, false> : basic_traits<true, true, T, R, Args...> {
1390  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) noexcept;
1391  };*/
1392 
1393  /* Const Volatile */
1394  template <typename T, typename R, typename... Args>
1395  struct fx_traits<R (__stdcall T::*)(Args...) const noexcept, false> : basic_traits<true, false, T, R, Args...> {
1396  typedef R (__stdcall T::*function_pointer_type)(Args...) const noexcept;
1397  };
1398 
1399  /* __stdcall does not work with varargs */
1400  /*template <typename T, typename R, typename... Args>
1401  struct fx_traits<R (__stdcall T::*)(Args..., ...) const noexcept, false> : basic_traits<true, true, T, R, Args...> {
1402  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const noexcept;
1403  };*/
1404 
1405  template <typename T, typename R, typename... Args>
1406  struct fx_traits<R (__stdcall T::*)(Args...) const volatile noexcept, false> : basic_traits<true, false, T, R, Args...> {
1407  typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile noexcept;
1408  };
1409 
1410  /* __stdcall does not work with varargs */
1411  /*template <typename T, typename R, typename... Args>
1412  struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile noexcept, false> : basic_traits<true, true, T, R, Args...> {
1413  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const volatile noexcept;
1414  };*/
1415 
1416  template <typename T, typename R, typename... Args>
1417  struct fx_traits<R (__stdcall T::*)(Args...) & noexcept, false> : basic_traits<true, false, T, R, Args...> {
1418  typedef R (__stdcall T::*function_pointer_type)(Args...) & noexcept;
1419  };
1420 
1421  /* __stdcall does not work with varargs */
1422  /*template <typename T, typename R, typename... Args>
1423  struct fx_traits<R (__stdcall T::*)(Args..., ...) & noexcept, false> : basic_traits<true, true, T, R, Args...> {
1424  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) & noexcept;
1425  };*/
1426 
1427  template <typename T, typename R, typename... Args>
1428  struct fx_traits<R (__stdcall T::*)(Args...) const& noexcept, false> : basic_traits<true, false, T, R, Args...> {
1429  typedef R (__stdcall T::*function_pointer_type)(Args...) const& noexcept;
1430  };
1431 
1432  /* __stdcall does not work with varargs */
1433  /*template <typename T, typename R, typename... Args>
1434  struct fx_traits<R (__stdcall T::*)(Args..., ...) const& noexcept, false> : basic_traits<true, true, T, R, Args...> {
1435  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const& noexcept;
1436  };*/
1437 
1438  template <typename T, typename R, typename... Args>
1439  struct fx_traits<R (__stdcall T::*)(Args...) const volatile& noexcept, false> : basic_traits<true, false, T, R, Args...> {
1440  typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile& noexcept;
1441  };
1442 
1443  /* __stdcall does not work with varargs */
1444  /*template <typename T, typename R, typename... Args>
1445  struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile& noexcept, false> : basic_traits<true, true, T, R, Args...> {
1446  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const volatile& noexcept;
1447  };*/
1448 
1449  template <typename T, typename R, typename... Args>
1450  struct fx_traits<R (__stdcall T::*)(Args...) && noexcept, false> : basic_traits<true, false, T, R, Args...> {
1451  typedef R (__stdcall T::*function_pointer_type)(Args...) && noexcept;
1452  };
1453 
1454  /* __stdcall does not work with varargs */
1455  /*template <typename T, typename R, typename... Args>
1456  struct fx_traits<R (__stdcall T::*)(Args..., ...) && noexcept, false> : basic_traits<true, true, T, R, Args...> {
1457  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) && noexcept;
1458  };*/
1459 
1460  template <typename T, typename R, typename... Args>
1461  struct fx_traits<R (__stdcall T::*)(Args...) const&& noexcept, false> : basic_traits<true, false, T, R, Args...> {
1462  typedef R (__stdcall T::*function_pointer_type)(Args...) const&& noexcept;
1463  };
1464 
1465  /* __stdcall does not work with varargs */
1466  /*template <typename T, typename R, typename... Args>
1467  struct fx_traits<R (__stdcall T::*)(Args..., ...) const&& noexcept, false> : basic_traits<true, true, T, R, Args...> {
1468  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const&& noexcept;
1469  };*/
1470 
1471  template <typename T, typename R, typename... Args>
1472  struct fx_traits<R (__stdcall T::*)(Args...) const volatile&& noexcept, false> : basic_traits<true, false, T, R, Args...> {
1473  typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&& noexcept;
1474  };
1475 
1476  /* __stdcall does not work with varargs */
1477  /*template <typename T, typename R, typename... Args>
1478  struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile&& noexcept, false> : basic_traits<true, true, T, R, Args...> {
1479  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const volatile&& noexcept;
1480  };*/
1481 #endif // noexcept is part of a function's type
1482 #endif // __stdcall x86 VC++ bug
1483 
1484  template <typename Signature>
1485  struct fx_traits<Signature, true>
1486  : public fx_traits<typename fx_traits<decltype(&Signature::operator())>::function_type, false> {};
1487 
1490  : public fx_traits<std::decay_t<Signature>> {};
1491 
1492  template <typename R, typename T>
1493  struct callable_traits<R(T::*), true> {
1494  typedef meta::conditional_t<std::is_array_v<R>, std::add_lvalue_reference_t<R>, R> return_type;
1495  typedef return_type Arg;
1496  typedef T object_type;
1497  using signature_type = R(T::*);
1498  inline static constexpr bool is_noexcept = false;
1499  inline static constexpr bool is_member_function = false;
1500  inline static constexpr std::size_t arity = 1;
1501  inline static constexpr std::size_t free_arity = 2;
1502  typedef std::tuple<Arg> args_tuple;
1506  typedef return_type(function_type)(T&, return_type);
1507  typedef return_type (*function_pointer_type)(T&, Arg);
1508  typedef return_type (*free_function_pointer_type)(T&, Arg);
1509  template <std::size_t i>
1511  };
1512 
1513  } // namespace meta_detail
1514 
1515  template <typename Signature>
1517 
1518  template <typename Signature>
1520 
1521  template <typename Signature>
1523 
1524  template <typename Signature>
1526 }} // namespace sol::meta
1527 
1528 // end of sol/bind_traits.hpp
1529 
1530 // beginning of sol/pointer_like.hpp
1531 
1532 #include <utility>
1533 #include <type_traits>
1534 
1535 namespace sol {
1536 
1537  namespace meta {
1538  namespace meta_detail {
1539  template <typename T>
1540  using is_dereferenceable_test = decltype(*std::declval<T>());
1541 
1542  template <typename T>
1543  using is_explicitly_dereferenceable_test = decltype(std::declval<T>().operator*());
1544  }
1545 
1546  template <typename T>
1547  using is_pointer_like = std::integral_constant<bool, !std::is_array_v<T> && (std::is_pointer_v<T> || is_detected_v<meta_detail::is_explicitly_dereferenceable_test, T>)>;
1548 
1549  template <typename T>
1551  } // namespace meta
1552 
1553  namespace detail {
1554 
1555  template <typename T>
1556  auto unwrap(T&& item) -> decltype(std::forward<T>(item)) {
1557  return std::forward<T>(item);
1558  }
1559 
1560  template <typename T>
1561  T& unwrap(std::reference_wrapper<T> arg) {
1562  return arg.get();
1563  }
1564 
1565  template <typename T>
1566  inline decltype(auto) deref(T&& item) {
1567  using Tu = meta::unqualified_t<T>;
1568  if constexpr (meta::is_pointer_like_v<Tu>) {
1569  return *std::forward<T>(item);
1570  }
1571  else {
1572  return std::forward<T>(item);
1573  }
1574  }
1575 
1576  template <typename T>
1577  inline decltype(auto) deref_move_only(T&& item) {
1578  using Tu = meta::unqualified_t<T>;
1579  if constexpr (meta::is_pointer_like_v<Tu> && !std::is_pointer_v<Tu> && !std::is_copy_constructible_v<Tu>) {
1580  return *std::forward<T>(item);
1581  }
1582  else {
1583  return std::forward<T>(item);
1584  }
1585  }
1586 
1587  template <typename T>
1588  inline T* ptr(T& val) {
1589  return std::addressof(val);
1590  }
1591 
1592  template <typename T>
1593  inline T* ptr(std::reference_wrapper<T> val) {
1594  return std::addressof(val.get());
1595  }
1596 
1597  template <typename T>
1598  inline T* ptr(T* val) {
1599  return val;
1600  }
1601  } // namespace detail
1602 } // namespace sol
1603 
1604 // end of sol/pointer_like.hpp
1605 
1606 // beginning of sol/string_view.hpp
1607 
1608 #include <cstddef>
1609 #include <string>
1610 #include <string_view>
1611 #include <functional>
1612 
1613 namespace sol {
1614  template <typename C, typename T = std::char_traits<C>>
1615  using basic_string_view = std::basic_string_view<C, T>;
1616 
1621  typedef std::hash<std::string_view> string_view_hash;
1622 } // namespace sol
1623 
1624 // end of sol/string_view.hpp
1625 
1626 #include <type_traits>
1627 #include <cstdint>
1628 #include <memory>
1629 #include <functional>
1630 #include <array>
1631 #include <iterator>
1632 #include <iosfwd>
1633 #if SOL_IS_ON(SOL_STD_VARIANT_I_)
1634 #include <variant>
1635 #endif // variant is weird on XCode, thanks XCode
1636 
1637 namespace sol { namespace meta {
1638  template <typename T>
1639  struct unwrapped {
1640  typedef T type;
1641  };
1642 
1643  template <typename T>
1644  struct unwrapped<std::reference_wrapper<T>> {
1645  typedef T type;
1646  };
1647 
1648  template <typename T>
1650 
1651  template <typename T>
1652  struct unwrap_unqualified : unwrapped<unqualified_t<T>> {};
1653 
1654  template <typename T>
1656 
1657  template <typename T>
1659 
1660  template <typename R, typename T>
1661  struct remove_member_pointer<R T::*> {
1662  typedef R type;
1663  };
1664 
1665  template <typename R, typename T>
1666  struct remove_member_pointer<R T::*const> {
1667  typedef R type;
1668  };
1669 
1670  template <typename T>
1672 
1673  template <typename T, typename...>
1674  struct all_same : std::true_type {};
1675 
1676  template <typename T, typename U, typename... Args>
1677  struct all_same<T, U, Args...> : std::integral_constant<bool, std::is_same<T, U>::value && all_same<T, Args...>::value> {};
1678 
1679  template <typename T, typename...>
1680  struct any_same : std::false_type {};
1681 
1682  template <typename T, typename U, typename... Args>
1683  struct any_same<T, U, Args...> : std::integral_constant<bool, std::is_same<T, U>::value || any_same<T, Args...>::value> {};
1684 
1685  template <typename T, typename... Args>
1686  constexpr inline bool any_same_v = any_same<T, Args...>::value;
1687 
1688  template <bool B>
1689  using boolean = std::integral_constant<bool, B>;
1690 
1691  template <bool B>
1692  constexpr inline bool boolean_v = boolean<B>::value;
1693 
1694  template <typename T>
1696 
1697  template <typename T>
1698  constexpr inline bool neg_v = neg<T>::value;
1699 
1700  template <typename... Args>
1701  struct all : boolean<true> {};
1702 
1703  template <typename T, typename... Args>
1704  struct all<T, Args...> : std::conditional_t<T::value, all<Args...>, boolean<false>> {};
1705 
1706  template <typename... Args>
1707  struct any : boolean<false> {};
1708 
1709  template <typename T, typename... Args>
1710  struct any<T, Args...> : std::conditional_t<T::value, boolean<true>, any<Args...>> {};
1711 
1712  template <typename T, typename... Args>
1713  constexpr inline bool all_v = all<T, Args...>::value;
1714 
1715  template <typename T, typename... Args>
1716  constexpr inline bool any_v = any<T, Args...>::value;
1717 
1718  enum class enable_t { _ };
1719 
1720  constexpr const auto enabler = enable_t::_;
1721 
1722  template <bool value, typename T = void>
1723  using disable_if_t = std::enable_if_t<!value, T>;
1724 
1725  template <typename... Args>
1726  using enable = std::enable_if_t<all<Args...>::value, enable_t>;
1727 
1728  template <typename... Args>
1729  using disable = std::enable_if_t<neg<all<Args...>>::value, enable_t>;
1730 
1731  template <typename... Args>
1732  using enable_any = std::enable_if_t<any<Args...>::value, enable_t>;
1733 
1734  template <typename... Args>
1735  using disable_any = std::enable_if_t<neg<any<Args...>>::value, enable_t>;
1736 
1737  template <typename V, typename... Vs>
1738  struct find_in_pack_v : boolean<false> {};
1739 
1740  template <typename V, typename Vs1, typename... Vs>
1741  struct find_in_pack_v<V, Vs1, Vs...> : any<boolean<(V::value == Vs1::value)>, find_in_pack_v<V, Vs...>> {};
1742 
1743  namespace meta_detail {
1744  template <std::size_t I, typename T, typename... Args>
1745  struct index_in_pack : std::integral_constant<std::size_t, SIZE_MAX> {};
1746 
1747  template <std::size_t I, typename T, typename T1, typename... Args>
1748  struct index_in_pack<I, T, T1, Args...>
1749  : conditional_t<std::is_same<T, T1>::value, std::integral_constant<std::ptrdiff_t, I>, index_in_pack<I + 1, T, Args...>> {};
1750  } // namespace meta_detail
1751 
1752  template <typename T, typename... Args>
1753  struct index_in_pack : meta_detail::index_in_pack<0, T, Args...> {};
1754 
1755  template <typename T, typename List>
1756  struct index_in : meta_detail::index_in_pack<0, T, List> {};
1757 
1758  template <typename T, typename... Args>
1759  struct index_in<T, types<Args...>> : meta_detail::index_in_pack<0, T, Args...> {};
1760 
1761  template <std::size_t I, typename... Args>
1762  struct at_in_pack {};
1763 
1764  template <std::size_t I, typename... Args>
1765  using at_in_pack_t = typename at_in_pack<I, Args...>::type;
1766 
1767  template <std::size_t I, typename Arg, typename... Args>
1768  struct at_in_pack<I, Arg, Args...> : std::conditional<I == 0, Arg, at_in_pack_t<I - 1, Args...>> {};
1769 
1770  template <typename Arg, typename... Args>
1771  struct at_in_pack<0, Arg, Args...> {
1772  typedef Arg type;
1773  };
1774 
1775  namespace meta_detail {
1776  template <typename, typename TI>
1778 
1779  template <typename, typename TI>
1781 
1782  template <typename, typename>
1783  using on_always = std::true_type;
1784 
1785  template <template <typename...> class When, std::size_t Limit, std::size_t I, template <typename...> class Pred, typename... Ts>
1786  struct count_when_for_pack : std::integral_constant<std::size_t, 0> {};
1787  template <template <typename...> class When, std::size_t Limit, std::size_t I, template <typename...> class Pred, typename T, typename... Ts>
1788  struct count_when_for_pack<When, Limit, I, Pred, T, Ts...> : conditional_t < sizeof...(Ts)
1789  == 0
1790  || Limit<2, std::integral_constant<std::size_t, I + static_cast<std::size_t>(Limit != 0 && Pred<T>::value)>,
1791  count_when_for_pack<When, Limit - static_cast<std::size_t>(When<T, std::integral_constant<std::size_t, I>>::value),
1792  I + static_cast<std::size_t>(When<T, std::integral_constant<std::size_t, I>>::value&& Pred<T>::value), Pred, Ts...>> {};
1793  } // namespace meta_detail
1794 
1795  template <template <typename...> class Pred, typename... Ts>
1796  struct count_for_pack : meta_detail::count_when_for_pack<meta_detail::on_always, sizeof...(Ts), 0, Pred, Ts...> {};
1797 
1798  template <template <typename...> class Pred, typename... Ts>
1799  inline constexpr std::size_t count_for_pack_v = count_for_pack<Pred, Ts...>::value;
1800 
1801  template <template <typename...> class Pred, typename List>
1802  struct count_for;
1803 
1804  template <template <typename...> class Pred, typename... Args>
1805  struct count_for<Pred, types<Args...>> : count_for_pack<Pred, Args...> {};
1806 
1807  template <std::size_t Limit, template <typename...> class Pred, typename... Ts>
1808  struct count_for_to_pack : meta_detail::count_when_for_pack<meta_detail::on_always, Limit, 0, Pred, Ts...> {};
1809 
1810  template <std::size_t Limit, template <typename...> class Pred, typename... Ts>
1811  inline constexpr std::size_t count_for_to_pack_v = count_for_to_pack<Limit, Pred, Ts...>::value;
1812 
1813  template <template <typename...> class When, std::size_t Limit, template <typename...> class Pred, typename... Ts>
1814  struct count_when_for_to_pack : meta_detail::count_when_for_pack<When, Limit, 0, Pred, Ts...> {};
1815 
1816  template <template <typename...> class When, std::size_t Limit, template <typename...> class Pred, typename... Ts>
1817  inline constexpr std::size_t count_when_for_to_pack_v = count_when_for_to_pack<When, Limit, Pred, Ts...>::value;
1818 
1819  template <template <typename...> class Pred, typename... Ts>
1820  using count_even_for_pack = count_when_for_to_pack<meta_detail::on_even, sizeof...(Ts), Pred, Ts...>;
1821 
1822  template <template <typename...> class Pred, typename... Ts>
1823  inline constexpr std::size_t count_even_for_pack_v = count_even_for_pack<Pred, Ts...>::value;
1824 
1825  template <template <typename...> class Pred, typename... Ts>
1826  using count_odd_for_pack = count_when_for_to_pack<meta_detail::on_odd, sizeof...(Ts), Pred, Ts...>;
1827 
1828  template <template <typename...> class Pred, typename... Ts>
1829  inline constexpr std::size_t count_odd_for_pack_v = count_odd_for_pack<Pred, Ts...>::value;
1830 
1831  template <typename... Args>
1832  struct return_type {
1833  typedef std::tuple<Args...> type;
1834  };
1835 
1836  template <typename T>
1837  struct return_type<T> {
1838  typedef T type;
1839  };
1840 
1841  template <>
1842  struct return_type<> {
1843  typedef void type;
1844  };
1845 
1846  template <typename... Args>
1847  using return_type_t = typename return_type<Args...>::type;
1848 
1849  namespace meta_detail {
1850  template <typename>
1851  struct always_true : std::true_type {};
1852  struct is_invokable_tester {
1853  template <typename Fun, typename... Args>
1854  static always_true<decltype(std::declval<Fun>()(std::declval<Args>()...))> test(int);
1855  template <typename...>
1856  static std::false_type test(...);
1857  };
1858  } // namespace meta_detail
1859 
1860  template <typename T>
1861  struct is_invokable;
1862  template <typename Fun, typename... Args>
1863  struct is_invokable<Fun(Args...)> : decltype(meta_detail::is_invokable_tester::test<Fun, Args...>(0)) {};
1864 
1865  namespace meta_detail {
1866 
1867  template <typename T, typename = void>
1868  struct is_callable : std::is_function<std::remove_pointer_t<T>> {};
1869 
1870  template <typename T>
1871  struct is_callable<T,
1872  std::enable_if_t<std::is_final<unqualified_t<T>>::value && std::is_class<unqualified_t<T>>::value
1873  && std::is_same<decltype(void(&T::operator())), void>::value>> {};
1874 
1875  template <typename T>
1876  struct is_callable<T,
1877  std::enable_if_t<!std::is_final<unqualified_t<T>>::value && std::is_class<unqualified_t<T>>::value
1878  && std::is_destructible<unqualified_t<T>>::value>> {
1879  struct F {
1880  void operator()() {};
1881  };
1882  struct Derived : T, F {};
1883  template <typename U, U>
1884  struct Check;
1885 
1886  template <typename V>
1887  static sfinae_no_t test(Check<void (F::*)(), &V::operator()>*);
1888 
1889  template <typename>
1890  static sfinae_yes_t test(...);
1891 
1892  static constexpr bool value = std::is_same_v<decltype(test<Derived>(0)), sfinae_yes_t>;
1893  };
1894 
1895  template <typename T>
1896  struct is_callable<T,
1897  std::enable_if_t<!std::is_final<unqualified_t<T>>::value && std::is_class<unqualified_t<T>>::value
1898  && !std::is_destructible<unqualified_t<T>>::value>> {
1899  struct F {
1900  void operator()() {};
1901  };
1902  struct Derived : T, F {
1903  ~Derived() = delete;
1904  };
1905  template <typename U, U>
1906  struct Check;
1907 
1908  template <typename V>
1909  static sfinae_no_t test(Check<void (F::*)(), &V::operator()>*);
1910 
1911  template <typename>
1912  static sfinae_yes_t test(...);
1913 
1914  static constexpr bool value = std::is_same_v<decltype(test<Derived>(0)), sfinae_yes_t>;
1915  };
1916 
1917  struct has_begin_end_impl {
1918  template <typename T, typename U = unqualified_t<T>, typename B = decltype(std::declval<U&>().begin()),
1919  typename E = decltype(std::declval<U&>().end())>
1920  static std::true_type test(int);
1921 
1922  template <typename...>
1923  static std::false_type test(...);
1924  };
1925 
1926  struct has_key_type_impl {
1927  template <typename T, typename U = unqualified_t<T>, typename V = typename U::key_type>
1928  static std::true_type test(int);
1929 
1930  template <typename...>
1931  static std::false_type test(...);
1932  };
1933 
1934  struct has_key_comp_impl {
1935  template <typename T, typename V = decltype(std::declval<unqualified_t<T>>().key_comp())>
1936  static std::true_type test(int);
1937 
1938  template <typename...>
1939  static std::false_type test(...);
1940  };
1941 
1942  struct has_load_factor_impl {
1943  template <typename T, typename V = decltype(std::declval<unqualified_t<T>>().load_factor())>
1944  static std::true_type test(int);
1945 
1946  template <typename...>
1947  static std::false_type test(...);
1948  };
1949 
1950  struct has_mapped_type_impl {
1951  template <typename T, typename V = typename unqualified_t<T>::mapped_type>
1952  static std::true_type test(int);
1953 
1954  template <typename...>
1955  static std::false_type test(...);
1956  };
1957 
1958  struct has_value_type_impl {
1959  template <typename T, typename V = typename unqualified_t<T>::value_type>
1960  static std::true_type test(int);
1961 
1962  template <typename...>
1963  static std::false_type test(...);
1964  };
1965 
1966  struct has_iterator_impl {
1967  template <typename T, typename V = typename unqualified_t<T>::iterator>
1968  static std::true_type test(int);
1969 
1970  template <typename...>
1971  static std::false_type test(...);
1972  };
1973 
1974  struct has_key_value_pair_impl {
1975  template <typename T, typename U = unqualified_t<T>, typename V = typename U::value_type, typename F = decltype(std::declval<V&>().first),
1976  typename S = decltype(std::declval<V&>().second)>
1977  static std::true_type test(int);
1978 
1979  template <typename...>
1980  static std::false_type test(...);
1981  };
1982 
1983  template <typename T>
1984  struct has_push_back_test {
1985  private:
1986  template <typename C>
1987  static sfinae_yes_t test(decltype(std::declval<C>().push_back(std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
1988  template <typename C>
1989  static sfinae_no_t test(...);
1990 
1991  public:
1992  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
1993  };
1994 
1995  template <typename T>
1996  struct has_insert_test {
1997  private:
1998  template <typename C>
1999  static sfinae_yes_t test(decltype(std::declval<C>().insert(std::declval<std::add_rvalue_reference_t<typename C::const_iterator>>(),
2000  std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
2001  template <typename C>
2002  static sfinae_no_t test(...);
2003 
2004  public:
2005  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
2006  };
2007 
2008  template <typename T>
2009  struct has_insert_after_test {
2010  private:
2011  template <typename C>
2012  static sfinae_yes_t test(decltype(std::declval<C>().insert_after(std::declval<std::add_rvalue_reference_t<typename C::const_iterator>>(),
2013  std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
2014  template <typename C>
2015  static sfinae_no_t test(...);
2016 
2017  public:
2018  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
2019  };
2020 
2021  template <typename T>
2022  struct has_size_test {
2023  private:
2024  template <typename C>
2025  static sfinae_yes_t test(decltype(std::declval<C>().size())*);
2026  template <typename C>
2027  static sfinae_no_t test(...);
2028 
2029  public:
2030  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
2031  };
2032 
2033  template <typename T>
2034  struct has_max_size_test {
2035  private:
2036  template <typename C>
2037  static sfinae_yes_t test(decltype(std::declval<C>().max_size())*);
2038  template <typename C>
2039  static sfinae_no_t test(...);
2040 
2041  public:
2042  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
2043  };
2044 
2045  template <typename T>
2046  struct has_to_string_test {
2047  private:
2048  template <typename C>
2049  static sfinae_yes_t test(decltype(std::declval<C>().to_string())*);
2050  template <typename C>
2051  static sfinae_no_t test(...);
2052 
2053  public:
2054  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
2055  };
2056 
2057  template <typename T, typename U, typename = void>
2058  class supports_op_less_test : public std::false_type {};
2059  template <typename T, typename U>
2060  class supports_op_less_test<T, U, void_t<decltype(std::declval<T&>() < std::declval<U&>())>>
2061  : public std::integral_constant<bool,
2062  !is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>> {};
2063 
2064  template <typename T, typename U, typename = void>
2065  class supports_op_equal_test : public std::false_type {};
2066  template <typename T, typename U>
2067  class supports_op_equal_test<T, U, void_t<decltype(std::declval<T&>() == std::declval<U&>())>>
2068  : public std::integral_constant<bool,
2069  !is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>> {};
2070 
2071  template <typename T, typename U, typename = void>
2072  class supports_op_less_equal_test : public std::false_type {};
2073  template <typename T, typename U>
2074  class supports_op_less_equal_test<T, U, void_t<decltype(std::declval<T&>() <= std::declval<U&>())>>
2075  : public std::integral_constant<bool,
2076  !is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>> {};
2077 
2078  template <typename T, typename U, typename = void>
2079  class supports_op_left_shift_test : public std::false_type {};
2080  template <typename T, typename U>
2081  class supports_op_left_shift_test<T, U, void_t<decltype(std::declval<T&>() << std::declval<U&>())>> : public std::true_type {};
2082 
2083  template <typename T, typename = void>
2084  class supports_adl_to_string_test : public std::false_type {};
2085  template <typename T>
2086  class supports_adl_to_string_test<T, void_t<decltype(to_string(std::declval<const T&>()))>> : public std::true_type {};
2087 
2088  template <typename T, bool b>
2089  struct is_matched_lookup_impl : std::false_type {};
2090  template <typename T>
2091  struct is_matched_lookup_impl<T, true> : std::is_same<typename T::key_type, typename T::value_type> {};
2092 
2093  template <typename T>
2094  using non_void_t = meta::conditional_t<std::is_void_v<T>, ::sol::detail::unchecked_t, T>;
2095  } // namespace meta_detail
2096 
2097  template <typename T, typename U = T>
2098  class supports_op_less : public meta_detail::supports_op_less_test<T, U> {};
2099 
2100  template <typename T, typename U = T>
2101  class supports_op_equal : public meta_detail::supports_op_equal_test<T, U> {};
2102 
2103  template <typename T, typename U = T>
2104  class supports_op_less_equal : public meta_detail::supports_op_less_equal_test<T, U> {};
2105 
2106  template <typename T, typename U = T>
2107  class supports_op_left_shift : public meta_detail::supports_op_left_shift_test<T, U> {};
2108 
2109  template <typename T>
2110  class supports_adl_to_string : public meta_detail::supports_adl_to_string_test<T> {};
2111 
2112  template <typename T>
2113  class supports_to_string_member : public meta::boolean<meta_detail::has_to_string_test<meta_detail::non_void_t<T>>::value> {};
2114 
2115  template <typename T>
2116  using is_callable = boolean<meta_detail::is_callable<T>::value>;
2117 
2118  template <typename T>
2119  constexpr inline bool is_callable_v = is_callable<T>::value;
2120 
2121  template <typename T>
2122  struct has_begin_end : decltype(meta_detail::has_begin_end_impl::test<T>(0)) {};
2123 
2124  template <typename T>
2125  constexpr inline bool has_begin_end_v = has_begin_end<T>::value;
2126 
2127  template <typename T>
2128  struct has_key_value_pair : decltype(meta_detail::has_key_value_pair_impl::test<T>(0)) {};
2129 
2130  template <typename T>
2131  struct has_key_type : decltype(meta_detail::has_key_type_impl::test<T>(0)) {};
2132 
2133  template <typename T>
2134  struct has_key_comp : decltype(meta_detail::has_key_comp_impl::test<T>(0)) {};
2135 
2136  template <typename T>
2137  struct has_load_factor : decltype(meta_detail::has_load_factor_impl::test<T>(0)) {};
2138 
2139  template <typename T>
2140  struct has_mapped_type : decltype(meta_detail::has_mapped_type_impl::test<T>(0)) {};
2141 
2142  template <typename T>
2143  struct has_iterator : decltype(meta_detail::has_iterator_impl::test<T>(0)) {};
2144 
2145  template <typename T>
2146  struct has_value_type : decltype(meta_detail::has_value_type_impl::test<T>(0)) {};
2147 
2148  template <typename T>
2149  using has_push_back = meta::boolean<meta_detail::has_push_back_test<T>::value>;
2150 
2151  template <typename T>
2152  using has_max_size = meta::boolean<meta_detail::has_max_size_test<T>::value>;
2153 
2154  template <typename T>
2155  using has_insert = meta::boolean<meta_detail::has_insert_test<T>::value>;
2156 
2157  template <typename T>
2158  using has_insert_after = meta::boolean<meta_detail::has_insert_after_test<T>::value>;
2159 
2160  template <typename T>
2161  using has_size = meta::boolean<meta_detail::has_size_test<T>::value>;
2162 
2163  template <typename T>
2164  using is_associative = meta::all<has_key_type<T>, has_key_value_pair<T>, has_mapped_type<T>>;
2165 
2166  template <typename T>
2167  using is_lookup = meta::all<has_key_type<T>, has_value_type<T>>;
2168 
2169  template <typename T>
2170  using is_ordered = meta::all<has_key_comp<T>, meta::neg<has_load_factor<T>>>;
2171 
2172  template <typename T>
2173  using is_matched_lookup = meta_detail::is_matched_lookup_impl<T, is_lookup<T>::value>;
2174 
2175  template <typename T>
2176  using is_initializer_list = meta::is_specialization_of<T, std::initializer_list>;
2177 
2178  template <typename T>
2179  constexpr inline bool is_initializer_list_v = is_initializer_list<T>::value;
2180 
2181  template <typename T, typename CharT = char>
2182  using is_string_literal_array_of = boolean<std::is_array_v<T> && std::is_same_v<std::remove_all_extents_t<T>, CharT>>;
2183 
2184  template <typename T, typename CharT = char>
2185  constexpr inline bool is_string_literal_array_of_v = is_string_literal_array_of<T, CharT>::value;
2186 
2187  template <typename T>
2188  using is_string_literal_array = boolean<std::is_array_v<T> && any_same_v<std::remove_all_extents_t<T>, char, char16_t, char32_t, wchar_t>>;
2189 
2190  template <typename T>
2191  constexpr inline bool is_string_literal_array_v = is_string_literal_array<T>::value;
2192 
2193  template <typename T, typename CharT>
2194  struct is_string_of : std::false_type {};
2195 
2196  template <typename CharT, typename CharTargetT, typename TraitsT, typename AllocT>
2197  struct is_string_of<std::basic_string<CharT, TraitsT, AllocT>, CharTargetT> : std::is_same<CharT, CharTargetT> {};
2198 
2199  template <typename T, typename CharT>
2200  constexpr inline bool is_string_of_v = is_string_of<T, CharT>::value;
2201 
2202  template <typename T, typename CharT>
2203  struct is_string_view_of : std::false_type {};
2204 
2205  template <typename CharT, typename CharTargetT, typename TraitsT>
2206  struct is_string_view_of<std::basic_string_view<CharT, TraitsT>, CharTargetT> : std::is_same<CharT, CharTargetT> {};
2207 
2208  template <typename T, typename CharT>
2209  constexpr inline bool is_string_view_of_v = is_string_view_of<T, CharT>::value;
2210 
2211  template <typename T>
2212  using is_string_like
2213  = meta::boolean<is_specialization_of_v<T, std::basic_string> || is_specialization_of_v<T, std::basic_string_view> || is_string_literal_array_v<T>>;
2214 
2215  template <typename T>
2216  constexpr inline bool is_string_like_v = is_string_like<T>::value;
2217 
2218  template <typename T, typename CharT = char>
2219  using is_string_constructible = meta::boolean<
2220  is_string_literal_array_of_v<T,
2221  CharT> || std::is_same_v<T, const CharT*> || std::is_same_v<T, CharT> || is_string_of_v<T, CharT> || std::is_same_v<T, std::initializer_list<CharT>> || is_string_view_of_v<T, CharT>>;
2222 
2223  template <typename T, typename CharT = char>
2224  constexpr inline bool is_string_constructible_v = is_string_constructible<T, CharT>::value;
2225 
2226  template <typename T>
2227  using is_string_like_or_constructible = meta::boolean<is_string_like_v<T> || is_string_constructible_v<T>>;
2228 
2229  template <typename T>
2230  struct is_pair : std::false_type {};
2231 
2232  template <typename T1, typename T2>
2233  struct is_pair<std::pair<T1, T2>> : std::true_type {};
2234 
2235  template <typename T, typename Char>
2236  using is_c_str_of = any<std::is_same<T, const Char*>, std::is_same<T, Char const* const>, std::is_same<T, Char*>, is_string_of<T, Char>,
2237  is_string_literal_array_of<T, Char>>;
2238 
2239  template <typename T, typename Char>
2240  constexpr inline bool is_c_str_of_v = is_c_str_of<T, Char>::value;
2241 
2242  template <typename T>
2243  using is_c_str = is_c_str_of<T, char>;
2244 
2245  template <typename T>
2246  constexpr inline bool is_c_str_v = is_c_str<T>::value;
2247 
2248  template <typename T>
2249  struct is_move_only : all<neg<std::is_reference<T>>, neg<std::is_copy_constructible<unqualified_t<T>>>, std::is_move_constructible<unqualified_t<T>>> {};
2250 
2251  template <typename T>
2252  using is_not_move_only = neg<is_move_only<T>>;
2253 
2254  namespace meta_detail {
2255  template <typename T>
2256  decltype(auto) force_tuple(T&& x) {
2257  if constexpr (meta::is_specialization_of_v<meta::unqualified_t<T>, std::tuple>) {
2258  return std::forward<T>(x);
2259  }
2260  else {
2261  return std::tuple<T>(std::forward<T>(x));
2262  }
2263  }
2264  } // namespace meta_detail
2265 
2266  template <typename... X>
2267  decltype(auto) tuplefy(X&&... x) {
2268  return std::tuple_cat(meta_detail::force_tuple(std::forward<X>(x))...);
2269  }
2270 
2271  template <typename T, typename = void>
2272  struct iterator_tag {
2273  using type = std::input_iterator_tag;
2274  };
2275 
2276  template <typename T>
2277  struct iterator_tag<T, conditional_t<false, typename std::iterator_traits<T>::iterator_category, void>> {
2278  using type = typename std::iterator_traits<T>::iterator_category;
2279  };
2280 
2281 }} // namespace sol::meta
2282 
2283 // end of sol/traits.hpp
2284 
2285 namespace sol {
2286  namespace detail {
2287  const bool default_safe_function_calls =
2288 #if SOL_IS_ON(SOL_SAFE_FUNCTION_CALLS_I_)
2289  true;
2290 #else
2291  false;
2292 #endif
2293  } // namespace detail
2294 
2295  namespace meta { namespace meta_detail {
2296  }} // namespace meta::meta_detail
2297 
2298  namespace stack { namespace stack_detail {
2299  using undefined_method_func = void (*)(stack_reference);
2300 
2301  template <typename T>
2302  void set_undefined_methods_on(stack_reference);
2303 
2304  struct undefined_metatable;
2305  }} // namespace stack::stack_detail
2306 } // namespace sol
2307 
2308 #endif // SOL_FORWARD_DETAIL_HPP
2309 // end of sol/forward_detail.hpp
2310 
2311 // beginning of sol/bytecode.hpp
2312 
2313 // beginning of sol/compatibility.hpp
2314 
2315 // beginning of sol/compatibility/lua_version.hpp
2316 
2317 #if SOL_IS_ON(SOL_USE_CXX_LUA_I_)
2318  #include <lua.h>
2319  #include <lualib.h>
2320  #include <lauxlib.h>
2321 #elif SOL_IS_ON(SOL_USE_LUA_HPP_I_)
2322  #include <lua.hpp>
2323 #else
2324  extern "C" {
2325  #include <lua.h>
2326  #include <lauxlib.h>
2327  #include <lualib.h>
2328  }
2329 #endif // C++ Mangling for Lua vs. Not
2330 
2331 #if defined(SOL_LUAJIT)
2332  #if (SOL_LUAJIT != 0)
2333  #define SOL_USE_LUAJIT_I_ SOL_ON
2334  #else
2335  #define SOL_USE_LUAJIT_I_ SOL_OFF
2336  #endif
2337 #elif defined(LUAJIT_VERSION)
2338  #define SOL_USE_LUAJIT_I_ SOL_OFF
2339 #else
2340  #define SOL_USE_LUAJIT_I_ SOL_DEFAULT_OFF
2341 #endif // luajit
2342 
2343 #if SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_)
2344  #include <luajit.h>
2345 #elif SOL_IS_ON(SOL_USE_LUAJIT_I_)
2346  extern "C" {
2347  #include <luajit.h>
2348  }
2349 #endif // C++ LuaJIT ... whatever that means
2350 
2351 #if defined(SOL_LUAJIT_VERSION)
2352  #define SOL_LUAJIT_VERSION_I_ SOL_LUAJIT_VERSION
2353 #elif SOL_IS_ON(SOL_USE_LUAJIT_I_)
2354  #define SOL_LUAJIT_VERSION_I_ LUAJIT_VERSION_NUM
2355 #else
2356  #define SOL_LUAJIT_VERSION_I_ 0
2357 #endif
2358 
2359 #if defined(MOONJIT_VERSION)
2360  #define SOL_USE_MOONJIT_I_ SOL_ON
2361 #else
2362  #define SOL_USE_MOONJIT_I_ SOL_OFF
2363 #endif
2364 
2365 #if !defined(SOL_LUA_VERSION)
2366  #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 502
2367  #define SOL_LUA_VERSION LUA_VERSION_NUM
2368  #elif defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
2369  #define SOL_LUA_VERSION LUA_VERSION_NUM
2370  #elif !defined(LUA_VERSION_NUM) || !(LUA_VERSION_NUM)
2371  // Definitely 5.0
2372  #define SOL_LUA_VERSION 500
2373  #else
2374  // ??? Not sure, assume latest?
2375  #define SOL_LUA_VERSION 504
2376  #endif // Lua Version 503, 502, 501 || luajit, 500
2377 #endif // SOL_LUA_VERSION
2378 
2379 #if defined(SOL_LUA_VERSION)
2380  #define SOL_LUA_VESION_I_ SOL_LUA_VERSION
2381 #else
2382  #define SOL_LUA_VESION_I_ 504
2383 #endif
2384 
2385 #if defined(SOL_EXCEPTIONS_ALWAYS_UNSAFE)
2386  #if (SOL_EXCEPTIONS_ALWAYS_UNSAFE != 0)
2387  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF
2388  #else
2389  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_ON
2390  #endif
2391 #elif defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
2392  #if (SOL_EXCEPTIONS_SAFE_PROPAGATION != 0)
2393  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_ON
2394  #else
2395  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF
2396  #endif
2397 #elif SOL_LUAJIT_VERSION_I_ >= 20100
2398  // LuaJIT 2.1.0-beta3 and better have exception support locked in for all platforms (mostly)
2399  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
2400 #elif SOL_LUAJIT_VERSION_I_ >= 20000
2401  // LuaJIT 2.0.x have exception support only on x64 builds
2402  #if SOL_IS_ON(SOL_PLATFORM_X64_I_)
2403  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
2404  #else
2405  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF
2406  #endif
2407 #else
2408  // otherwise, there is no exception safety for
2409  // shoving exceptions through Lua and errors should
2410  // always be serialized
2411  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_OFF
2412 #endif // LuaJIT beta 02.01.00 have better exception handling on all platforms since beta3
2413 
2414 #if defined(SOL_LUAJIT_USE_EXCEPTION_TRAMPOLINE)
2415  #if (SOL_LUAJIT_USE_EXCEPTION_TRAMPOLINE != 0)
2416  #define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_ON
2417  #else
2418  #define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_OFF
2419  #endif
2420 #else
2421  #if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_) && SOL_IS_ON(SOL_USE_LUAJIT_I_)
2422  #define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_ON
2423  #else
2424  #define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_DEFAULT_OFF
2425  #endif
2426 #endif
2427 
2428 #if defined(SOL_LUAL_STREAM_HAS_CLOSE_FUNCTION)
2429  #if (SOL_LUAL_STREAM_HAS_CLOSE_FUNCTION != 0)
2430  #define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_ON
2431  #else
2432  #define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_OFF
2433  #endif
2434 #else
2435  #if SOL_IS_OFF(SOL_USE_LUAJIT_I_) && (SOL_LUA_VERSION > 501)
2436  #define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_ON
2437  #else
2438  #define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_DEFAULT_OFF
2439  #endif
2440 #endif
2441 
2442 // end of sol/compatibility/lua_version.hpp
2443 
2444 #if SOL_IS_ON(SOL_USE_COMPATIBILITY_LAYER_I_)
2445 
2446 #if SOL_IS_ON(SOL_USE_CXX_LUA_I_) || SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_)
2447 #ifndef COMPAT53_LUA_CPP
2448 #define COMPAT53_LUA_CPP 1
2449 #endif // Build Lua Compat layer as C++
2450 #endif
2451 #ifndef COMPAT53_INCLUDE_SOURCE
2452 #define COMPAT53_INCLUDE_SOURCE 1
2453 #endif // Build Compat Layer Inline
2454 
2455 // beginning of sol/compatibility/compat-5.3.h
2456 
2457 #ifndef KEPLER_PROJECT_COMPAT53_H_
2458 #define KEPLER_PROJECT_COMPAT53_H_
2459 
2460 #include <stddef.h>
2461 #include <limits.h>
2462 #include <string.h>
2463 #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
2464 extern "C" {
2465 #endif
2466 #include <lua.h>
2467 #include <lauxlib.h>
2468 #include <lualib.h>
2469 #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
2470 }
2471 #endif
2472 
2473 #ifndef COMPAT53_PREFIX
2474 /* we chose this name because many other lua bindings / libs have
2475 * their own compatibility layer, and that use the compat53 declaration
2476 * frequently, causing all kinds of linker / compiler issues
2477 */
2478 # define COMPAT53_PREFIX kp_compat53
2479 #endif // COMPAT53_PREFIX
2480 
2481 #ifndef COMPAT53_API
2482 # if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE
2483 # if defined(__GNUC__) || defined(__clang__)
2484 # define COMPAT53_API __attribute__((__unused__)) static inline
2485 # else
2486 # define COMPAT53_API static inline
2487 # endif /* Clang/GCC */
2488 # else /* COMPAT53_INCLUDE_SOURCE */
2489 /* we are not including source, so everything is extern */
2490 # define COMPAT53_API extern
2491 # endif /* COMPAT53_INCLUDE_SOURCE */
2492 #endif /* COMPAT53_PREFIX */
2493 
2494 #define COMPAT53_CONCAT_HELPER(a, b) a##b
2495 #define COMPAT53_CONCAT(a, b) COMPAT53_CONCAT_HELPER(a, b)
2496 
2497 /* declarations for Lua 5.1 */
2498 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
2499 
2500 /* XXX not implemented:
2501 * lua_arith (new operators)
2502 * lua_upvalueid
2503 * lua_upvaluejoin
2504 * lua_version
2505 * lua_yieldk
2506 */
2507 
2508 #ifndef LUA_OK
2509 # define LUA_OK 0
2510 #endif
2511 #ifndef LUA_OPADD
2512 # define LUA_OPADD 0
2513 #endif
2514 #ifndef LUA_OPSUB
2515 # define LUA_OPSUB 1
2516 #endif
2517 #ifndef LUA_OPMUL
2518 # define LUA_OPMUL 2
2519 #endif
2520 #ifndef LUA_OPDIV
2521 # define LUA_OPDIV 3
2522 #endif
2523 #ifndef LUA_OPMOD
2524 # define LUA_OPMOD 4
2525 #endif
2526 #ifndef LUA_OPPOW
2527 # define LUA_OPPOW 5
2528 #endif
2529 #ifndef LUA_OPUNM
2530 # define LUA_OPUNM 6
2531 #endif
2532 #ifndef LUA_OPEQ
2533 # define LUA_OPEQ 0
2534 #endif
2535 #ifndef LUA_OPLT
2536 # define LUA_OPLT 1
2537 #endif
2538 #ifndef LUA_OPLE
2539 # define LUA_OPLE 2
2540 #endif
2541 
2542 /* LuaJIT/Lua 5.1 does not have the updated
2543 * error codes for thread status/function returns (but some patched versions do)
2544 * define it only if it's not found
2545 */
2546 #if !defined(LUA_ERRGCMM)
2547 /* Use + 2 because in some versions of Lua (Lua 5.1)
2548 * LUA_ERRFILE is defined as (LUA_ERRERR+1)
2549 * so we need to avoid it (LuaJIT might have something at this
2550 * integer value too)
2551 */
2552 # define LUA_ERRGCMM (LUA_ERRERR + 2)
2553 #endif /* LUA_ERRGCMM define */
2554 
2555 #if !defined(MOONJIT_VERSION)
2556 typedef size_t lua_Unsigned;
2557 #endif
2558 
2559 typedef struct luaL_Buffer_53 {
2560  luaL_Buffer b; /* make incorrect code crash! */
2561  char *ptr;
2562  size_t nelems;
2563  size_t capacity;
2564  lua_State *L2;
2565 } luaL_Buffer_53;
2566 #define luaL_Buffer luaL_Buffer_53
2567 
2568 /* In PUC-Rio 5.1, userdata is a simple FILE*
2569 * In LuaJIT, it's a struct where the first member is a FILE*
2570 * We can't support the `closef` member
2571 */
2572 typedef struct luaL_Stream {
2573  FILE *f;
2574 } luaL_Stream;
2575 
2576 #define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex)
2577 COMPAT53_API int lua_absindex(lua_State *L, int i);
2578 
2579 #define lua_arith COMPAT53_CONCAT(COMPAT53_PREFIX, _arith)
2580 COMPAT53_API void lua_arith(lua_State *L, int op);
2581 
2582 #define lua_compare COMPAT53_CONCAT(COMPAT53_PREFIX, _compare)
2583 COMPAT53_API int lua_compare(lua_State *L, int idx1, int idx2, int op);
2584 
2585 #define lua_copy COMPAT53_CONCAT(COMPAT53_PREFIX, _copy)
2586 COMPAT53_API void lua_copy(lua_State *L, int from, int to);
2587 
2588 #define lua_getuservalue(L, i) \
2589  (lua_getfenv((L), (i)), lua_type((L), -1))
2590 #define lua_setuservalue(L, i) \
2591  (luaL_checktype((L), -1, LUA_TTABLE), lua_setfenv((L), (i)))
2592 
2593 #define lua_len COMPAT53_CONCAT(COMPAT53_PREFIX, _len)
2594 COMPAT53_API void lua_len(lua_State *L, int i);
2595 
2596 #define lua_pushstring(L, s) \
2597  (lua_pushstring((L), (s)), lua_tostring((L), -1))
2598 
2599 #define lua_pushlstring(L, s, len) \
2600  ((((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len))), lua_tostring((L), -1))
2601 
2602 #ifndef luaL_newlibtable
2603 # define luaL_newlibtable(L, l) \
2604  (lua_createtable((L), 0, sizeof((l))/sizeof(*(l))-1))
2605 #endif
2606 #ifndef luaL_newlib
2607 # define luaL_newlib(L, l) \
2608  (luaL_newlibtable((L), (l)), luaL_register((L), NULL, (l)))
2609 #endif
2610 
2611 #ifndef lua_pushglobaltable
2612 # define lua_pushglobaltable(L) \
2613  lua_pushvalue((L), LUA_GLOBALSINDEX)
2614 #endif
2615 #define lua_rawgetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawgetp)
2616 COMPAT53_API int lua_rawgetp(lua_State *L, int i, const void *p);
2617 
2618 #define lua_rawsetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawsetp)
2619 COMPAT53_API void lua_rawsetp(lua_State *L, int i, const void *p);
2620 
2621 #define lua_rawlen(L, i) lua_objlen((L), (i))
2622 
2623 #define lua_tointeger(L, i) lua_tointegerx((L), (i), NULL)
2624 
2625 #define lua_tonumberx COMPAT53_CONCAT(COMPAT53_PREFIX, _tonumberx)
2626 COMPAT53_API lua_Number lua_tonumberx(lua_State *L, int i, int *isnum);
2627 
2628 #define luaL_checkversion COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkversion)
2629 COMPAT53_API void luaL_checkversion(lua_State *L);
2630 
2631 #define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
2632 COMPAT53_API int lua_load(lua_State *L, lua_Reader reader, void *data, const char* source, const char* mode);
2633 
2634 #define luaL_loadfilex COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadfilex)
2635 COMPAT53_API int luaL_loadfilex(lua_State *L, const char *filename, const char *mode);
2636 
2637 #define luaL_loadbufferx COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadbufferx)
2638 COMPAT53_API int luaL_loadbufferx(lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
2639 
2640 #define luaL_checkstack COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkstack_53)
2641 COMPAT53_API void luaL_checkstack(lua_State *L, int sp, const char *msg);
2642 
2643 #define luaL_getsubtable COMPAT53_CONCAT(COMPAT53_PREFIX, L_getsubtable)
2644 COMPAT53_API int luaL_getsubtable(lua_State* L, int i, const char *name);
2645 
2646 #define luaL_len COMPAT53_CONCAT(COMPAT53_PREFIX, L_len)
2647 COMPAT53_API lua_Integer luaL_len(lua_State *L, int i);
2648 
2649 #define luaL_setfuncs COMPAT53_CONCAT(COMPAT53_PREFIX, L_setfuncs)
2650 COMPAT53_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup);
2651 
2652 #define luaL_setmetatable COMPAT53_CONCAT(COMPAT53_PREFIX, L_setmetatable)
2653 COMPAT53_API void luaL_setmetatable(lua_State *L, const char *tname);
2654 
2655 #define luaL_testudata COMPAT53_CONCAT(COMPAT53_PREFIX, L_testudata)
2656 COMPAT53_API void *luaL_testudata(lua_State *L, int i, const char *tname);
2657 
2658 #define luaL_traceback COMPAT53_CONCAT(COMPAT53_PREFIX, L_traceback)
2659 COMPAT53_API void luaL_traceback(lua_State *L, lua_State *L1, const char *msg, int level);
2660 
2661 #define luaL_fileresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_fileresult)
2662 COMPAT53_API int luaL_fileresult(lua_State *L, int stat, const char *fname);
2663 
2664 #define luaL_execresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_execresult)
2665 COMPAT53_API int luaL_execresult(lua_State *L, int stat);
2666 
2667 #define lua_callk(L, na, nr, ctx, cont) \
2668  ((void)(ctx), (void)(cont), lua_call((L), (na), (nr)))
2669 #define lua_pcallk(L, na, nr, err, ctx, cont) \
2670  ((void)(ctx), (void)(cont), lua_pcall((L), (na), (nr), (err)))
2671 
2672 #define lua_resume(L, from, nargs) \
2673  ((void)(from), lua_resume((L), (nargs)))
2674 
2675 #define luaL_buffinit COMPAT53_CONCAT(COMPAT53_PREFIX, _buffinit_53)
2676 COMPAT53_API void luaL_buffinit(lua_State *L, luaL_Buffer_53 *B);
2677 
2678 #define luaL_prepbuffsize COMPAT53_CONCAT(COMPAT53_PREFIX, _prepbufsize_53)
2679 COMPAT53_API char *luaL_prepbuffsize(luaL_Buffer_53 *B, size_t s);
2680 
2681 #define luaL_addlstring COMPAT53_CONCAT(COMPAT53_PREFIX, _addlstring_53)
2682 COMPAT53_API void luaL_addlstring(luaL_Buffer_53 *B, const char *s, size_t l);
2683 
2684 #define luaL_addvalue COMPAT53_CONCAT(COMPAT53_PREFIX, _addvalue_53)
2685 COMPAT53_API void luaL_addvalue(luaL_Buffer_53 *B);
2686 
2687 #define luaL_pushresult COMPAT53_CONCAT(COMPAT53_PREFIX, _pushresult_53)
2688 COMPAT53_API void luaL_pushresult(luaL_Buffer_53 *B);
2689 
2690 #undef luaL_buffinitsize
2691 #define luaL_buffinitsize(L, B, s) \
2692  (luaL_buffinit((L), (B)), luaL_prepbuffsize((B), (s)))
2693 
2694 #undef luaL_prepbuffer
2695 #define luaL_prepbuffer(B) \
2696  luaL_prepbuffsize((B), LUAL_BUFFERSIZE)
2697 
2698 #undef luaL_addchar
2699 #define luaL_addchar(B, c) \
2700  ((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize((B), 1)), \
2701  ((B)->ptr[(B)->nelems++] = (c)))
2702 
2703 #undef luaL_addsize
2704 #define luaL_addsize(B, s) \
2705  ((B)->nelems += (s))
2706 
2707 #undef luaL_addstring
2708 #define luaL_addstring(B, s) \
2709  luaL_addlstring((B), (s), strlen((s)))
2710 
2711 #undef luaL_pushresultsize
2712 #define luaL_pushresultsize(B, s) \
2713  (luaL_addsize((B), (s)), luaL_pushresult((B)))
2714 
2715 #if defined(LUA_COMPAT_APIINTCASTS)
2716 #define lua_pushunsigned(L, n) \
2717  lua_pushinteger((L), (lua_Integer)(n))
2718 #define lua_tounsignedx(L, i, is) \
2719  ((lua_Unsigned)lua_tointegerx((L), (i), (is)))
2720 #define lua_tounsigned(L, i) \
2721  lua_tounsignedx((L), (i), NULL)
2722 #define luaL_checkunsigned(L, a) \
2723  ((lua_Unsigned)luaL_checkinteger((L), (a)))
2724 #define luaL_optunsigned(L, a, d) \
2725  ((lua_Unsigned)luaL_optinteger((L), (a), (lua_Integer)(d)))
2726 #endif
2727 
2728 #endif /* Lua 5.1 only */
2729 
2730 /* declarations for Lua 5.1 and 5.2 */
2731 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 502
2732 
2733 typedef int lua_KContext;
2734 
2735 typedef int(*lua_KFunction)(lua_State *L, int status, lua_KContext ctx);
2736 
2737 #define lua_dump(L, w, d, s) \
2738  ((void)(s), lua_dump((L), (w), (d)))
2739 
2740 #define lua_getfield(L, i, k) \
2741  (lua_getfield((L), (i), (k)), lua_type((L), -1))
2742 
2743 #define lua_gettable(L, i) \
2744  (lua_gettable((L), (i)), lua_type((L), -1))
2745 
2746 #define lua_geti COMPAT53_CONCAT(COMPAT53_PREFIX, _geti)
2747 COMPAT53_API int lua_geti(lua_State *L, int index, lua_Integer i);
2748 
2749 #define lua_isinteger COMPAT53_CONCAT(COMPAT53_PREFIX, _isinteger)
2750 COMPAT53_API int lua_isinteger(lua_State *L, int index);
2751 
2752 #define lua_tointegerx COMPAT53_CONCAT(COMPAT53_PREFIX, _tointegerx_53)
2753 COMPAT53_API lua_Integer lua_tointegerx(lua_State *L, int i, int *isnum);
2754 
2755 #define lua_numbertointeger(n, p) \
2756  ((*(p) = (lua_Integer)(n)), 1)
2757 
2758 #define lua_rawget(L, i) \
2759  (lua_rawget((L), (i)), lua_type((L), -1))
2760 
2761 #define lua_rawgeti(L, i, n) \
2762  (lua_rawgeti((L), (i), (n)), lua_type((L), -1))
2763 
2764 #define lua_rotate COMPAT53_CONCAT(COMPAT53_PREFIX, _rotate)
2765 COMPAT53_API void lua_rotate(lua_State *L, int idx, int n);
2766 
2767 #define lua_seti COMPAT53_CONCAT(COMPAT53_PREFIX, _seti)
2768 COMPAT53_API void lua_seti(lua_State *L, int index, lua_Integer i);
2769 
2770 #define lua_stringtonumber COMPAT53_CONCAT(COMPAT53_PREFIX, _stringtonumber)
2771 COMPAT53_API size_t lua_stringtonumber(lua_State *L, const char *s);
2772 
2773 #define luaL_tolstring COMPAT53_CONCAT(COMPAT53_PREFIX, L_tolstring)
2774 COMPAT53_API const char *luaL_tolstring(lua_State *L, int idx, size_t *len);
2775 
2776 #define luaL_getmetafield(L, o, e) \
2777  (luaL_getmetafield((L), (o), (e)) ? lua_type((L), -1) : LUA_TNIL)
2778 
2779 #define luaL_newmetatable(L, tn) \
2780  (luaL_newmetatable((L), (tn)) ? (lua_pushstring((L), (tn)), lua_setfield((L), -2, "__name"), 1) : 0)
2781 
2782 #define luaL_requiref COMPAT53_CONCAT(COMPAT53_PREFIX, L_requiref_53)
2783 COMPAT53_API void luaL_requiref(lua_State *L, const char *modname,
2784  lua_CFunction openf, int glb);
2785 
2786 #endif /* Lua 5.1 and Lua 5.2 */
2787 
2788 /* declarations for Lua 5.2 */
2789 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 502
2790 
2791 /* XXX not implemented:
2792 * lua_isyieldable
2793 * lua_getextraspace
2794 * lua_arith (new operators)
2795 * lua_pushfstring (new formats)
2796 */
2797 
2798 #define lua_getglobal(L, n) \
2799  (lua_getglobal((L), (n)), lua_type((L), -1))
2800 
2801 #define lua_getuservalue(L, i) \
2802  (lua_getuservalue((L), (i)), lua_type((L), -1))
2803 
2804 #define lua_pushlstring(L, s, len) \
2805  (((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len)))
2806 
2807 #define lua_rawgetp(L, i, p) \
2808  (lua_rawgetp((L), (i), (p)), lua_type((L), -1))
2809 
2810 #define LUA_KFUNCTION(_name) \
2811  static int (_name)(lua_State *L, int status, lua_KContext ctx); \
2812  static int (_name ## _52)(lua_State *L) { \
2813  lua_KContext ctx; \
2814  int status = lua_getctx(L, &ctx); \
2815  return (_name)(L, status, ctx); \
2816  } \
2817  static int (_name)(lua_State *L, int status, lua_KContext ctx)
2818 
2819 #define lua_pcallk(L, na, nr, err, ctx, cont) \
2820  lua_pcallk((L), (na), (nr), (err), (ctx), cont ## _52)
2821 
2822 #define lua_callk(L, na, nr, ctx, cont) \
2823  lua_callk((L), (na), (nr), (ctx), cont ## _52)
2824 
2825 #define lua_yieldk(L, nr, ctx, cont) \
2826  lua_yieldk((L), (nr), (ctx), cont ## _52)
2827 
2828 #ifdef lua_call
2829 # undef lua_call
2830 # define lua_call(L, na, nr) \
2831  (lua_callk)((L), (na), (nr), 0, NULL)
2832 #endif
2833 
2834 #ifdef lua_pcall
2835 # undef lua_pcall
2836 # define lua_pcall(L, na, nr, err) \
2837  (lua_pcallk)((L), (na), (nr), (err), 0, NULL)
2838 #endif
2839 
2840 #ifdef lua_yield
2841 # undef lua_yield
2842 # define lua_yield(L, nr) \
2843  (lua_yieldk)((L), (nr), 0, NULL)
2844 #endif
2845 
2846 #endif /* Lua 5.2 only */
2847 
2848 /* other Lua versions */
2849 #if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 || LUA_VERSION_NUM > 504
2850 
2851 # error "unsupported Lua version (i.e. not Lua 5.1, 5.2, 5.3, or 5.4)"
2852 
2853 #endif /* other Lua versions except 5.1, 5.2, 5.3, and 5.4 */
2854 
2855 /* helper macro for defining continuation functions (for every version
2856 * *except* Lua 5.2) */
2857 #ifndef LUA_KFUNCTION
2858 #define LUA_KFUNCTION(_name) \
2859  static int (_name)(lua_State *L, int status, lua_KContext ctx)
2860 #endif
2861 
2862 #if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE == 1
2863 // beginning of sol/compatibility/compat-5.3.c.h
2864 
2865 #include <stddef.h>
2866 #include <stdlib.h>
2867 #include <string.h>
2868 #include <ctype.h>
2869 #include <errno.h>
2870 #include <stdio.h>
2871 
2872 /* don't compile it again if it already is included via compat53.h */
2873 #ifndef KEPLER_PROJECT_COMPAT53_C_
2874 #define KEPLER_PROJECT_COMPAT53_C_
2875 
2876 /* definitions for Lua 5.1 only */
2877 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
2878 
2879 #ifndef COMPAT53_FOPEN_NO_LOCK
2880 #if defined(_MSC_VER)
2881 #define COMPAT53_FOPEN_NO_LOCK 1
2882 #else /* otherwise */
2883 #define COMPAT53_FOPEN_NO_LOCK 0
2884 #endif /* VC++ only so far */
2885 #endif /* No-lock fopen_s usage if possible */
2886 
2887 #if defined(_MSC_VER) && COMPAT53_FOPEN_NO_LOCK
2888 #include <share.h>
2889 #endif /* VC++ _fsopen for share-allowed file read */
2890 
2891 #ifndef COMPAT53_HAVE_STRERROR_R
2892 #if defined(__GLIBC__) || defined(_POSIX_VERSION) || defined(__APPLE__) || (!defined(__MINGW32__) && defined(__GNUC__) && (__GNUC__ < 6))
2893 #define COMPAT53_HAVE_STRERROR_R 1
2894 #else /* none of the defines matched: define to 0 */
2895 #define COMPAT53_HAVE_STRERROR_R 0
2896 #endif /* have strerror_r of some form */
2897 #endif /* strerror_r */
2898 
2899 #ifndef COMPAT53_HAVE_STRERROR_S
2900 #if defined(_MSC_VER) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || (defined(__STDC_LIB_EXT1__) && __STDC_LIB_EXT1__)
2901 #define COMPAT53_HAVE_STRERROR_S 1
2902 #else /* not VC++ or C11 */
2903 #define COMPAT53_HAVE_STRERROR_S 0
2904 #endif /* strerror_s from VC++ or C11 */
2905 #endif /* strerror_s */
2906 
2907 #ifndef COMPAT53_LUA_FILE_BUFFER_SIZE
2908 #define COMPAT53_LUA_FILE_BUFFER_SIZE 4096
2909 #endif /* Lua File Buffer Size */
2910 
2911 static char* compat53_strerror(int en, char* buff, size_t sz) {
2912 #if COMPAT53_HAVE_STRERROR_R
2913  /* use strerror_r here, because it's available on these specific platforms */
2914  if (sz > 0) {
2915  buff[0] = '\0';
2916  /* we don't care whether the GNU version or the XSI version is used: */
2917  if (strerror_r(en, buff, sz)) {
2918  /* Yes, we really DO want to ignore the return value!
2919  * GCC makes that extra hard, not even a (void) cast will do. */
2920  }
2921  if (buff[0] == '\0') {
2922  /* Buffer is unchanged, so we probably have called GNU strerror_r which
2923  * returned a static constant string. Chances are that strerror will
2924  * return the same static constant string and therefore be thread-safe. */
2925  return strerror(en);
2926  }
2927  }
2928  return buff; /* sz is 0 *or* strerror_r wrote into the buffer */
2929 #elif COMPAT53_HAVE_STRERROR_S
2930  /* for MSVC and other C11 implementations, use strerror_s since it's
2931  * provided by default by the libraries */
2932  strerror_s(buff, sz, en);
2933  return buff;
2934 #else
2935  /* fallback, but strerror is not guaranteed to be threadsafe due to modifying
2936  * errno itself and some impls not locking a static buffer for it ... but most
2937  * known systems have threadsafe errno: this might only change if the locale
2938  * is changed out from under someone while this function is being called */
2939  (void)buff;
2940  (void)sz;
2941  return strerror(en);
2942 #endif
2943 }
2944 
2945 COMPAT53_API int lua_absindex(lua_State* L, int i) {
2946  if (i < 0 && i > LUA_REGISTRYINDEX)
2947  i += lua_gettop(L) + 1;
2948  return i;
2949 }
2950 
2951 static void compat53_call_lua(lua_State* L, char const code[], size_t len, int nargs, int nret) {
2952  lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)code);
2953  if (lua_type(L, -1) != LUA_TFUNCTION) {
2954  lua_pop(L, 1);
2955  if (luaL_loadbuffer(L, code, len, "=none"))
2956  lua_error(L);
2957  lua_pushvalue(L, -1);
2958  lua_rawsetp(L, LUA_REGISTRYINDEX, (void*)code);
2959  }
2960  lua_insert(L, -nargs - 1);
2961  lua_call(L, nargs, nret);
2962 }
2963 
2964 static const char compat53_arith_code[]
2965  = "local op,a,b=...\n"
2966  "if op==0 then return a+b\n"
2967  "elseif op==1 then return a-b\n"
2968  "elseif op==2 then return a*b\n"
2969  "elseif op==3 then return a/b\n"
2970  "elseif op==4 then return a%b\n"
2971  "elseif op==5 then return a^b\n"
2972  "elseif op==6 then return -a\n"
2973  "end\n";
2974 
2975 COMPAT53_API void lua_arith(lua_State* L, int op) {
2976  if (op < LUA_OPADD || op > LUA_OPUNM)
2977  luaL_error(L, "invalid 'op' argument for lua_arith");
2978  luaL_checkstack(L, 5, "not enough stack slots");
2979  if (op == LUA_OPUNM)
2980  lua_pushvalue(L, -1);
2981  lua_pushnumber(L, op);
2982  lua_insert(L, -3);
2983  compat53_call_lua(L, compat53_arith_code, sizeof(compat53_arith_code) - 1, 3, 1);
2984 }
2985 
2986 static const char compat53_compare_code[]
2987  = "local a,b=...\n"
2988  "return a<=b\n";
2989 
2990 COMPAT53_API int lua_compare(lua_State* L, int idx1, int idx2, int op) {
2991  int result = 0;
2992  switch (op) {
2993  case LUA_OPEQ:
2994  return lua_equal(L, idx1, idx2);
2995  case LUA_OPLT:
2996  return lua_lessthan(L, idx1, idx2);
2997  case LUA_OPLE:
2998  luaL_checkstack(L, 5, "not enough stack slots");
2999  idx1 = lua_absindex(L, idx1);
3000  idx2 = lua_absindex(L, idx2);
3001  lua_pushvalue(L, idx1);
3002  lua_pushvalue(L, idx2);
3003  compat53_call_lua(L, compat53_compare_code, sizeof(compat53_compare_code) - 1, 2, 1);
3004  result = lua_toboolean(L, -1);
3005  lua_pop(L, 1);
3006  return result;
3007  default:
3008  luaL_error(L, "invalid 'op' argument for lua_compare");
3009  }
3010  return 0;
3011 }
3012 
3013 COMPAT53_API void lua_copy(lua_State* L, int from, int to) {
3014  int abs_to = lua_absindex(L, to);
3015  luaL_checkstack(L, 1, "not enough stack slots");
3016  lua_pushvalue(L, from);
3017  lua_replace(L, abs_to);
3018 }
3019 
3020 COMPAT53_API void lua_len(lua_State* L, int i) {
3021  switch (lua_type(L, i)) {
3022  case LUA_TSTRING:
3023  lua_pushnumber(L, (lua_Number)lua_objlen(L, i));
3024  break;
3025  case LUA_TTABLE:
3026  if (!luaL_callmeta(L, i, "__len"))
3027  lua_pushnumber(L, (lua_Number)lua_objlen(L, i));
3028  break;
3029  case LUA_TUSERDATA:
3030  if (luaL_callmeta(L, i, "__len"))
3031  break;
3032  /* FALLTHROUGH */
3033  default:
3034  luaL_error(L, "attempt to get length of a %s value", lua_typename(L, lua_type(L, i)));
3035  }
3036 }
3037 
3038 COMPAT53_API int lua_rawgetp(lua_State* L, int i, const void* p) {
3039  int abs_i = lua_absindex(L, i);
3040  lua_pushlightuserdata(L, (void*)p);
3041  lua_rawget(L, abs_i);
3042  return lua_type(L, -1);
3043 }
3044 
3045 COMPAT53_API void lua_rawsetp(lua_State* L, int i, const void* p) {
3046  int abs_i = lua_absindex(L, i);
3047  luaL_checkstack(L, 1, "not enough stack slots");
3048  lua_pushlightuserdata(L, (void*)p);
3049  lua_insert(L, -2);
3050  lua_rawset(L, abs_i);
3051 }
3052 
3053 COMPAT53_API lua_Number lua_tonumberx(lua_State* L, int i, int* isnum) {
3054  lua_Number n = lua_tonumber(L, i);
3055  if (isnum != NULL) {
3056  *isnum = (n != 0 || lua_isnumber(L, i));
3057  }
3058  return n;
3059 }
3060 
3062  (void)L;
3063 }
3064 
3065 COMPAT53_API void luaL_checkstack(lua_State* L, int sp, const char* msg) {
3066  if (!lua_checkstack(L, sp + LUA_MINSTACK)) {
3067  if (msg != NULL)
3068  luaL_error(L, "stack overflow (%s)", msg);
3069  else {
3070  lua_pushliteral(L, "stack overflow");
3071  lua_error(L);
3072  }
3073  }
3074 }
3075 
3076 COMPAT53_API int luaL_getsubtable(lua_State* L, int i, const char* name) {
3077  int abs_i = lua_absindex(L, i);
3078  luaL_checkstack(L, 3, "not enough stack slots");
3079  lua_pushstring(L, name);
3080  lua_gettable(L, abs_i);
3081  if (lua_istable(L, -1))
3082  return 1;
3083  lua_pop(L, 1);
3084  lua_newtable(L);
3085  lua_pushstring(L, name);
3086  lua_pushvalue(L, -2);
3087  lua_settable(L, abs_i);
3088  return 0;
3089 }
3090 
3092  lua_Integer res = 0;
3093  int isnum = 0;
3094  luaL_checkstack(L, 1, "not enough stack slots");
3095  lua_len(L, i);
3096  res = lua_tointegerx(L, -1, &isnum);
3097  lua_pop(L, 1);
3098  if (!isnum)
3099  luaL_error(L, "object length is not an integer");
3100  return res;
3101 }
3102 
3103 COMPAT53_API void luaL_setfuncs(lua_State* L, const luaL_Reg* l, int nup) {
3104  luaL_checkstack(L, nup + 1, "too many upvalues");
3105  for (; l->name != NULL; l++) { /* fill the table with given functions */
3106  int i;
3107  lua_pushstring(L, l->name);
3108  for (i = 0; i < nup; i++) /* copy upvalues to the top */
3109  lua_pushvalue(L, -(nup + 1));
3110  lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
3111  lua_settable(L, -(nup + 3)); /* table must be below the upvalues, the name and the closure */
3112  }
3113  lua_pop(L, nup); /* remove upvalues */
3114 }
3115 
3116 COMPAT53_API void luaL_setmetatable(lua_State* L, const char* tname) {
3117  luaL_checkstack(L, 1, "not enough stack slots");
3118  luaL_getmetatable(L, tname);
3119  lua_setmetatable(L, -2);
3120 }
3121 
3122 COMPAT53_API void* luaL_testudata(lua_State* L, int i, const char* tname) {
3123  void* p = lua_touserdata(L, i);
3124  luaL_checkstack(L, 2, "not enough stack slots");
3125  if (p == NULL || !lua_getmetatable(L, i))
3126  return NULL;
3127  else {
3128  int res = 0;
3129  luaL_getmetatable(L, tname);
3130  res = lua_rawequal(L, -1, -2);
3131  lua_pop(L, 2);
3132  if (!res)
3133  p = NULL;
3134  }
3135  return p;
3136 }
3137 
3138 static int compat53_countlevels(lua_State* L) {
3139  lua_Debug ar;
3140  int li = 1, le = 1;
3141  /* find an upper bound */
3142  while (lua_getstack(L, le, &ar)) {
3143  li = le;
3144  le *= 2;
3145  }
3146  /* do a binary search */
3147  while (li < le) {
3148  int m = (li + le) / 2;
3149  if (lua_getstack(L, m, &ar))
3150  li = m + 1;
3151  else
3152  le = m;
3153  }
3154  return le - 1;
3155 }
3156 
3157 static int compat53_findfield(lua_State* L, int objidx, int level) {
3158  if (level == 0 || !lua_istable(L, -1))
3159  return 0; /* not found */
3160  lua_pushnil(L); /* start 'next' loop */
3161  while (lua_next(L, -2)) { /* for each pair in table */
3162  if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */
3163  if (lua_rawequal(L, objidx, -1)) { /* found object? */
3164  lua_pop(L, 1); /* remove value (but keep name) */
3165  return 1;
3166  }
3167  else if (compat53_findfield(L, objidx, level - 1)) { /* try recursively */
3168  lua_remove(L, -2); /* remove table (but keep name) */
3169  lua_pushliteral(L, ".");
3170  lua_insert(L, -2); /* place '.' between the two names */
3171  lua_concat(L, 3);
3172  return 1;
3173  }
3174  }
3175  lua_pop(L, 1); /* remove value */
3176  }
3177  return 0; /* not found */
3178 }
3179 
3180 static int compat53_pushglobalfuncname(lua_State* L, lua_Debug* ar) {
3181  int top = lua_gettop(L);
3182  lua_getinfo(L, "f", ar); /* push function */
3183  lua_pushvalue(L, LUA_GLOBALSINDEX);
3184  if (compat53_findfield(L, top + 1, 2)) {
3185  lua_copy(L, -1, top + 1); /* move name to proper place */
3186  lua_pop(L, 2); /* remove pushed values */
3187  return 1;
3188  }
3189  else {
3190  lua_settop(L, top); /* remove function and global table */
3191  return 0;
3192  }
3193 }
3194 
3195 static void compat53_pushfuncname(lua_State* L, lua_Debug* ar) {
3196  if (*ar->namewhat != '\0') /* is there a name? */
3197  lua_pushfstring(L, "function " LUA_QS, ar->name);
3198  else if (*ar->what == 'm') /* main? */
3199  lua_pushliteral(L, "main chunk");
3200  else if (*ar->what == 'C') {
3201  if (compat53_pushglobalfuncname(L, ar)) {
3202  lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
3203  lua_remove(L, -2); /* remove name */
3204  }
3205  else
3206  lua_pushliteral(L, "?");
3207  }
3208  else
3209  lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
3210 }
3211 
3212 #define COMPAT53_LEVELS1 12 /* size of the first part of the stack */
3213 #define COMPAT53_LEVELS2 10 /* size of the second part of the stack */
3214 
3215 COMPAT53_API void luaL_traceback(lua_State* L, lua_State* L1, const char* msg, int level) {
3216  lua_Debug ar;
3217  int top = lua_gettop(L);
3218  int numlevels = compat53_countlevels(L1);
3219  int mark = (numlevels > COMPAT53_LEVELS1 + COMPAT53_LEVELS2) ? COMPAT53_LEVELS1 : 0;
3220  if (msg)
3221  lua_pushfstring(L, "%s\n", msg);
3222  lua_pushliteral(L, "stack traceback:");
3223  while (lua_getstack(L1, level++, &ar)) {
3224  if (level == mark) { /* too many levels? */
3225  lua_pushliteral(L, "\n\t..."); /* add a '...' */
3226  level = numlevels - COMPAT53_LEVELS2; /* and skip to last ones */
3227  }
3228  else {
3229  lua_getinfo(L1, "Slnt", &ar);
3230  lua_pushfstring(L, "\n\t%s:", ar.short_src);
3231  if (ar.currentline > 0)
3232  lua_pushfstring(L, "%d:", ar.currentline);
3233  lua_pushliteral(L, " in ");
3234  compat53_pushfuncname(L, &ar);
3235  lua_concat(L, lua_gettop(L) - top);
3236  }
3237  }
3238  lua_concat(L, lua_gettop(L) - top);
3239 }
3240 
3241 COMPAT53_API int luaL_fileresult(lua_State* L, int stat, const char* fname) {
3242  const char* serr = NULL;
3243  int en = errno; /* calls to Lua API may change this value */
3244  char buf[512] = { 0 };
3245  if (stat) {
3246  lua_pushboolean(L, 1);
3247  return 1;
3248  }
3249  else {
3250  lua_pushnil(L);
3251  serr = compat53_strerror(en, buf, sizeof(buf));
3252  if (fname)
3253  lua_pushfstring(L, "%s: %s", fname, serr);
3254  else
3255  lua_pushstring(L, serr);
3256  lua_pushnumber(L, (lua_Number)en);
3257  return 3;
3258  }
3259 }
3260 
3261 static int compat53_checkmode(lua_State* L, const char* mode, const char* modename, int err) {
3262  if (mode && strchr(mode, modename[0]) == NULL) {
3263  lua_pushfstring(L, "attempt to load a %s chunk (mode is '%s')", modename, mode);
3264  return err;
3265  }
3266  return LUA_OK;
3267 }
3268 
3269 typedef struct {
3270  lua_Reader reader;
3271  void* ud;
3272  int has_peeked_data;
3273  const char* peeked_data;
3274  size_t peeked_data_size;
3275 } compat53_reader_data;
3276 
3277 static const char* compat53_reader(lua_State* L, void* ud, size_t* size) {
3278  compat53_reader_data* data = (compat53_reader_data*)ud;
3279  if (data->has_peeked_data) {
3280  data->has_peeked_data = 0;
3281  *size = data->peeked_data_size;
3282  return data->peeked_data;
3283  }
3284  else
3285  return data->reader(L, data->ud, size);
3286 }
3287 
3288 COMPAT53_API int lua_load(lua_State* L, lua_Reader reader, void* data, const char* source, const char* mode) {
3289  int status = LUA_OK;
3290  compat53_reader_data compat53_data = { reader, data, 1, 0, 0 };
3291  compat53_data.peeked_data = reader(L, data, &(compat53_data.peeked_data_size));
3292  if (compat53_data.peeked_data && compat53_data.peeked_data_size && compat53_data.peeked_data[0] == LUA_SIGNATURE[0]) /* binary file? */
3293  status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX);
3294  else
3295  status = compat53_checkmode(L, mode, "text", LUA_ERRSYNTAX);
3296  if (status != LUA_OK)
3297  return status;
3298  /* we need to call the original 5.1 version of lua_load! */
3299 #undef lua_load
3300  return lua_load(L, compat53_reader, &compat53_data, source);
3301 #define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
3302 }
3303 
3304 typedef struct {
3305  int n; /* number of pre-read characters */
3306  FILE* f; /* file being read */
3307  char buff[COMPAT53_LUA_FILE_BUFFER_SIZE]; /* area for reading file */
3308 } compat53_LoadF;
3309 
3310 static const char* compat53_getF(lua_State* L, void* ud, size_t* size) {
3311  compat53_LoadF* lf = (compat53_LoadF*)ud;
3312  (void)L; /* not used */
3313  if (lf->n > 0) { /* are there pre-read characters to be read? */
3314  *size = lf->n; /* return them (chars already in buffer) */
3315  lf->n = 0; /* no more pre-read characters */
3316  }
3317  else { /* read a block from file */
3318  /* 'fread' can return > 0 *and* set the EOF flag. If next call to
3319  'compat53_getF' called 'fread', it might still wait for user input.
3320  The next check avoids this problem. */
3321  if (feof(lf->f))
3322  return NULL;
3323  *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */
3324  }
3325  return lf->buff;
3326 }
3327 
3328 static int compat53_errfile(lua_State* L, const char* what, int fnameindex) {
3329  char buf[512] = { 0 };
3330  const char* serr = compat53_strerror(errno, buf, sizeof(buf));
3331  const char* filename = lua_tostring(L, fnameindex) + 1;
3332  lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
3333  lua_remove(L, fnameindex);
3334  return LUA_ERRFILE;
3335 }
3336 
3337 static int compat53_skipBOM(compat53_LoadF* lf) {
3338  const char* p = "\xEF\xBB\xBF"; /* UTF-8 BOM mark */
3339  int c;
3340  lf->n = 0;
3341  do {
3342  c = getc(lf->f);
3343  if (c == EOF || c != *(const unsigned char*)p++)
3344  return c;
3345  lf->buff[lf->n++] = (char)c; /* to be read by the parser */
3346  } while (*p != '\0');
3347  lf->n = 0; /* prefix matched; discard it */
3348  return getc(lf->f); /* return next character */
3349 }
3350 
3351 /*
3352 ** reads the first character of file 'f' and skips an optional BOM mark
3353 ** in its beginning plus its first line if it starts with '#'. Returns
3354 ** true if it skipped the first line. In any case, '*cp' has the
3355 ** first "valid" character of the file (after the optional BOM and
3356 ** a first-line comment).
3357 */
3358 static int compat53_skipcomment(compat53_LoadF* lf, int* cp) {
3359  int c = *cp = compat53_skipBOM(lf);
3360  if (c == '#') { /* first line is a comment (Unix exec. file)? */
3361  do { /* skip first line */
3362  c = getc(lf->f);
3363  } while (c != EOF && c != '\n');
3364  *cp = getc(lf->f); /* skip end-of-line, if present */
3365  return 1; /* there was a comment */
3366  }
3367  else
3368  return 0; /* no comment */
3369 }
3370 
3371 COMPAT53_API int luaL_loadfilex(lua_State* L, const char* filename, const char* mode) {
3372  compat53_LoadF lf;
3373  int status, readstatus;
3374  int c;
3375  int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
3376  if (filename == NULL) {
3377  lua_pushliteral(L, "=stdin");
3378  lf.f = stdin;
3379  }
3380  else {
3381  lua_pushfstring(L, "@%s", filename);
3382 #if defined(_MSC_VER)
3383  /* This code is here to stop a deprecation error that stops builds
3384  * if a certain macro is defined. While normally not caring would
3385  * be best, some header-only libraries and builds can't afford to
3386  * dictate this to the user. A quick check shows that fopen_s this
3387  * goes back to VS 2005, and _fsopen goes back to VS 2003 .NET,
3388  * possibly even before that so we don't need to do any version
3389  * number checks, since this has been there since forever. */
3390 
3391  /* TO USER: if you want the behavior of typical fopen_s/fopen,
3392  * which does lock the file on VC++, define the macro used below to 0 */
3393 #if COMPAT53_FOPEN_NO_LOCK
3394  lf.f = _fsopen(filename, "r", _SH_DENYNO); /* do not lock the file in any way */
3395  if (lf.f == NULL)
3396  return compat53_errfile(L, "open", fnameindex);
3397 #else /* use default locking version */
3398  if (fopen_s(&lf.f, filename, "r") != 0)
3399  return compat53_errfile(L, "open", fnameindex);
3400 #endif /* Locking vs. No-locking fopen variants */
3401 #else
3402  lf.f = fopen(filename, "r"); /* default stdlib doesn't forcefully lock files here */
3403  if (lf.f == NULL)
3404  return compat53_errfile(L, "open", fnameindex);
3405 #endif
3406  }
3407  if (compat53_skipcomment(&lf, &c)) /* read initial portion */
3408  lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */
3409  if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
3410 #if defined(_MSC_VER)
3411  if (freopen_s(&lf.f, filename, "rb", lf.f) != 0)
3412  return compat53_errfile(L, "reopen", fnameindex);
3413 #else
3414  lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
3415  if (lf.f == NULL)
3416  return compat53_errfile(L, "reopen", fnameindex);
3417 #endif
3418  compat53_skipcomment(&lf, &c); /* re-read initial portion */
3419  }
3420  if (c != EOF)
3421  lf.buff[lf.n++] = (char)c; /* 'c' is the first character of the stream */
3422  status = lua_load(L, &compat53_getF, &lf, lua_tostring(L, -1), mode);
3423  readstatus = ferror(lf.f);
3424  if (filename)
3425  fclose(lf.f); /* close file (even in case of errors) */
3426  if (readstatus) {
3427  lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
3428  return compat53_errfile(L, "read", fnameindex);
3429  }
3430  lua_remove(L, fnameindex);
3431  return status;
3432 }
3433 
3434 COMPAT53_API int luaL_loadbufferx(lua_State* L, const char* buff, size_t sz, const char* name, const char* mode) {
3435  int status = LUA_OK;
3436  if (sz > 0 && buff[0] == LUA_SIGNATURE[0]) {
3437  status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX);
3438  }
3439  else {
3440  status = compat53_checkmode(L, mode, "text", LUA_ERRSYNTAX);
3441  }
3442  if (status != LUA_OK)
3443  return status;
3444  return luaL_loadbuffer(L, buff, sz, name);
3445 }
3446 
3447 #if !defined(l_inspectstat) \
3448  && (defined(unix) || defined(__unix) || defined(__unix__) || defined(__TOS_AIX__) || defined(_SYSTYPE_BSD) || (defined(__APPLE__) && defined(__MACH__)))
3449 /* some form of unix; check feature macros in unistd.h for details */
3450 #include <unistd.h>
3451 /* check posix version; the relevant include files and macros probably
3452  * were available before 2001, but I'm not sure */
3453 #if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
3454 #include <sys/wait.h>
3455 #define l_inspectstat(stat, what) \
3456  if (WIFEXITED(stat)) { \
3457  stat = WEXITSTATUS(stat); \
3458  } \
3459  else if (WIFSIGNALED(stat)) { \
3460  stat = WTERMSIG(stat); \
3461  what = "signal"; \
3462  }
3463 #endif
3464 #endif
3465 
3466 /* provide default (no-op) version */
3467 #if !defined(l_inspectstat)
3468 #define l_inspectstat(stat, what) ((void)0)
3469 #endif
3470 
3471 COMPAT53_API int luaL_execresult(lua_State* L, int stat) {
3472  const char* what = "exit";
3473  if (stat == -1)
3474  return luaL_fileresult(L, 0, NULL);
3475  else {
3476  l_inspectstat(stat, what);
3477  if (*what == 'e' && stat == 0)
3478  lua_pushboolean(L, 1);
3479  else
3480  lua_pushnil(L);
3481  lua_pushstring(L, what);
3482  lua_pushinteger(L, stat);
3483  return 3;
3484  }
3485 }
3486 
3487 COMPAT53_API void luaL_buffinit(lua_State* L, luaL_Buffer_53* B) {
3488  /* make it crash if used via pointer to a 5.1-style luaL_Buffer */
3489  B->b.p = NULL;
3490  B->b.L = NULL;
3491  B->b.lvl = 0;
3492  /* reuse the buffer from the 5.1-style luaL_Buffer though! */
3493  B->ptr = B->b.buffer;
3494  B->capacity = LUAL_BUFFERSIZE;
3495  B->nelems = 0;
3496  B->L2 = L;
3497 }
3498 
3499 COMPAT53_API char* luaL_prepbuffsize(luaL_Buffer_53* B, size_t s) {
3500  if (B->capacity - B->nelems < s) { /* needs to grow */
3501  char* newptr = NULL;
3502  size_t newcap = B->capacity * 2;
3503  if (newcap - B->nelems < s)
3504  newcap = B->nelems + s;
3505  if (newcap < B->capacity) /* overflow */
3506  luaL_error(B->L2, "buffer too large");
3507  newptr = (char*)lua_newuserdata(B->L2, newcap);
3508  memcpy(newptr, B->ptr, B->nelems);
3509  if (B->ptr != B->b.buffer)
3510  lua_replace(B->L2, -2); /* remove old buffer */
3511  B->ptr = newptr;
3512  B->capacity = newcap;
3513  }
3514  return B->ptr + B->nelems;
3515 }
3516 
3517 COMPAT53_API void luaL_addlstring(luaL_Buffer_53* B, const char* s, size_t l) {
3518  memcpy(luaL_prepbuffsize(B, l), s, l);
3519  luaL_addsize(B, l);
3520 }
3521 
3522 COMPAT53_API void luaL_addvalue(luaL_Buffer_53* B) {
3523  size_t len = 0;
3524  const char* s = lua_tolstring(B->L2, -1, &len);
3525  if (!s)
3526  luaL_error(B->L2, "cannot convert value to string");
3527  if (B->ptr != B->b.buffer)
3528  lua_insert(B->L2, -2); /* userdata buffer must be at stack top */
3529  luaL_addlstring(B, s, len);
3530  lua_remove(B->L2, B->ptr != B->b.buffer ? -2 : -1);
3531 }
3532 
3533 void luaL_pushresult(luaL_Buffer_53* B) {
3534  lua_pushlstring(B->L2, B->ptr, B->nelems);
3535  if (B->ptr != B->b.buffer)
3536  lua_replace(B->L2, -2); /* remove userdata buffer */
3537 }
3538 
3539 #endif /* Lua 5.1 */
3540 
3541 /* definitions for Lua 5.1 and Lua 5.2 */
3542 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 502
3543 
3545  index = lua_absindex(L, index);
3546  lua_pushinteger(L, i);
3547  lua_gettable(L, index);
3548  return lua_type(L, -1);
3549 }
3550 
3551 COMPAT53_API int lua_isinteger(lua_State* L, int index) {
3552  if (lua_type(L, index) == LUA_TNUMBER) {
3553  lua_Number n = lua_tonumber(L, index);
3554  lua_Integer i = lua_tointeger(L, index);
3555  if (i == n)
3556  return 1;
3557  }
3558  return 0;
3559 }
3560 
3561 COMPAT53_API lua_Integer lua_tointegerx(lua_State* L, int i, int* isnum) {
3562  int ok = 0;
3563  lua_Number n = lua_tonumberx(L, i, &ok);
3564  if (ok) {
3565  if (n == (lua_Integer)n) {
3566  if (isnum)
3567  *isnum = 1;
3568  return (lua_Integer)n;
3569  }
3570  }
3571  if (isnum)
3572  *isnum = 0;
3573  return 0;
3574 }
3575 
3576 static void compat53_reverse(lua_State* L, int a, int b) {
3577  for (; a < b; ++a, --b) {
3578  lua_pushvalue(L, a);
3579  lua_pushvalue(L, b);
3580  lua_replace(L, a);
3581  lua_replace(L, b);
3582  }
3583 }
3584 
3585 COMPAT53_API void lua_rotate(lua_State* L, int idx, int n) {
3586  int n_elems = 0;
3587  idx = lua_absindex(L, idx);
3588  n_elems = lua_gettop(L) - idx + 1;
3589  if (n < 0)
3590  n += n_elems;
3591  if (n > 0 && n < n_elems) {
3592  luaL_checkstack(L, 2, "not enough stack slots available");
3593  n = n_elems - n;
3594  compat53_reverse(L, idx, idx + n - 1);
3595  compat53_reverse(L, idx + n, idx + n_elems - 1);
3596  compat53_reverse(L, idx, idx + n_elems - 1);
3597  }
3598 }
3599 
3600 COMPAT53_API void lua_seti(lua_State* L, int index, lua_Integer i) {
3601  luaL_checkstack(L, 1, "not enough stack slots available");
3602  index = lua_absindex(L, index);
3603  lua_pushinteger(L, i);
3604  lua_insert(L, -2);
3605  lua_settable(L, index);
3606 }
3607 
3608 #if !defined(lua_str2number)
3609 #define lua_str2number(s, p) strtod((s), (p))
3610 #endif
3611 
3612 COMPAT53_API size_t lua_stringtonumber(lua_State* L, const char* s) {
3613  char* endptr;
3614  lua_Number n = lua_str2number(s, &endptr);
3615  if (endptr != s) {
3616  while (*endptr != '\0' && isspace((unsigned char)*endptr))
3617  ++endptr;
3618  if (*endptr == '\0') {
3619  lua_pushnumber(L, n);
3620  return endptr - s + 1;
3621  }
3622  }
3623  return 0;
3624 }
3625 
3626 COMPAT53_API const char* luaL_tolstring(lua_State* L, int idx, size_t* len) {
3627  if (!luaL_callmeta(L, idx, "__tostring")) {
3628  int t = lua_type(L, idx), tt = 0;
3629  char const* name = NULL;
3630  switch (t) {
3631  case LUA_TNIL:
3632  lua_pushliteral(L, "nil");
3633  break;
3634  case LUA_TSTRING:
3635  case LUA_TNUMBER:
3636  lua_pushvalue(L, idx);
3637  break;
3638  case LUA_TBOOLEAN:
3639  if (lua_toboolean(L, idx))
3640  lua_pushliteral(L, "true");
3641  else
3642  lua_pushliteral(L, "false");
3643  break;
3644  default:
3645  tt = luaL_getmetafield(L, idx, "__name");
3646  name = (tt == LUA_TSTRING) ? lua_tostring(L, -1) : lua_typename(L, t);
3647  lua_pushfstring(L, "%s: %p", name, lua_topointer(L, idx));
3648  if (tt != LUA_TNIL)
3649  lua_replace(L, -2);
3650  break;
3651  }
3652  }
3653  else {
3654  if (!lua_isstring(L, -1))
3655  luaL_error(L, "'__tostring' must return a string");
3656  }
3657  return lua_tolstring(L, -1, len);
3658 }
3659 
3660 COMPAT53_API void luaL_requiref(lua_State* L, const char* modname, lua_CFunction openf, int glb) {
3661  luaL_checkstack(L, 3, "not enough stack slots available");
3662  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
3663  if (lua_getfield(L, -1, modname) == LUA_TNIL) {
3664  lua_pop(L, 1);
3665  lua_pushcfunction(L, openf);
3666  lua_pushstring(L, modname);
3667  lua_call(L, 1, 1);
3668  lua_pushvalue(L, -1);
3669  lua_setfield(L, -3, modname);
3670  }
3671  if (glb) {
3672  lua_pushvalue(L, -1);
3673  lua_setglobal(L, modname);
3674  }
3675  lua_replace(L, -2);
3676 }
3677 
3678 #endif /* Lua 5.1 and 5.2 */
3679 
3680 #endif /* KEPLER_PROJECT_COMPAT53_C_ */
3681 
3682 /*********************************************************************
3683  * This file contains parts of Lua 5.2's and Lua 5.3's source code:
3684  *
3685  * Copyright (C) 1994-2014 Lua.org, PUC-Rio.
3686  *
3687  * Permission is hereby granted, free of charge, to any person obtaining
3688  * a copy of this software and associated documentation files (the
3689  * "Software"), to deal in the Software without restriction, including
3690  * without limitation the rights to use, copy, modify, merge, publish,
3691  * distribute, sublicense, and/or sell copies of the Software, and to
3692  * permit persons to whom the Software is furnished to do so, subject to
3693  * the following conditions:
3694  *
3695  * The above copyright notice and this permission notice shall be
3696  * included in all copies or substantial portions of the Software.
3697  *
3698  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3699  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3700  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
3701  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
3702  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
3703  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
3704  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3705  *********************************************************************/
3706 // end of sol/compatibility/compat-5.3.c.h
3707 
3708 #endif
3709 
3710 #endif /* KEPLER_PROJECT_COMPAT53_H_ */
3711 
3712 // end of sol/compatibility/compat-5.3.h
3713 
3714 // beginning of sol/compatibility/compat-5.4.h
3715 
3716 #ifndef NOT_KEPLER_PROJECT_COMPAT54_H_
3717 #define NOT_KEPLER_PROJECT_COMPAT54_H_
3718 
3719 #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
3720 extern "C" {
3721 #endif
3722 #include <lua.h>
3723 #include <lauxlib.h>
3724 #include <lualib.h>
3725 #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
3726 }
3727 #endif
3728 
3729 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 504
3730 
3731 #if !defined(LUA_ERRGCMM)
3732 /* So Lua 5.4 actually removes this, which breaks sol2...
3733  man, this API is quite unstable...!
3734 */
3735 # define LUA_ERRGCMM (LUA_ERRERR + 2)
3736 #endif /* LUA_ERRGCMM define */
3737 
3738 #endif // Lua 5.4 only
3739 
3740 #endif // NOT_KEPLER_PROJECT_COMPAT54_H_// end of sol/compatibility/compat-5.4.h
3741 
3742 #endif
3743 
3744 // end of sol/compatibility.hpp
3745 
3746 #include <vector>
3747 #include <cstdint>
3748 #include <cstddef>
3749 
3750 namespace sol {
3751 
3752  template <typename Allocator = std::allocator<std::byte>>
3753  class basic_bytecode : private std::vector<std::byte, Allocator> {
3754  private:
3755  using base_t = std::vector<std::byte, Allocator>;
3756 
3757  public:
3758  using typename base_t::allocator_type;
3759  using typename base_t::const_iterator;
3760  using typename base_t::const_pointer;
3761  using typename base_t::const_reference;
3762  using typename base_t::const_reverse_iterator;
3763  using typename base_t::difference_type;
3764  using typename base_t::iterator;
3765  using typename base_t::pointer;
3766  using typename base_t::reference;
3767  using typename base_t::reverse_iterator;
3768  using typename base_t::size_type;
3769  using typename base_t::value_type;
3770 
3771  using base_t::base_t;
3772  using base_t::operator=;
3773 
3774  using base_t::data;
3775  using base_t::empty;
3776  using base_t::max_size;
3777  using base_t::size;
3778 
3779  using base_t::at;
3780  using base_t::operator[];
3781  using base_t::back;
3782  using base_t::front;
3783 
3784  using base_t::begin;
3785  using base_t::cbegin;
3786  using base_t::cend;
3787  using base_t::end;
3788 
3789  using base_t::crbegin;
3790  using base_t::crend;
3791  using base_t::rbegin;
3792  using base_t::rend;
3793 
3794  using base_t::get_allocator;
3795  using base_t::swap;
3796 
3797  using base_t::clear;
3798  using base_t::emplace;
3799  using base_t::emplace_back;
3800  using base_t::erase;
3801  using base_t::insert;
3802  using base_t::pop_back;
3803  using base_t::push_back;
3804  using base_t::reserve;
3805  using base_t::resize;
3806  using base_t::shrink_to_fit;
3807 
3809  return string_view(reinterpret_cast<const char*>(this->data()), this->size());
3810  }
3811  };
3812 
3813  template <typename Container>
3814  inline int basic_insert_dump_writer(lua_State*, const void* memory, size_t memory_size, void* userdata) {
3815  using storage_t = Container;
3816  const std::byte* p_code = static_cast<const std::byte*>(memory);
3817  storage_t& bc = *static_cast<storage_t*>(userdata);
3818 #if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
3819  bc.insert(bc.cend(), p_code, p_code + memory_size);
3820 #else
3821  try {
3822  bc.insert(bc.cend(), p_code, p_code + memory_size);
3823  }
3824  catch (...) {
3825  return -1;
3826  }
3827 #endif
3828  return 0;
3829  }
3830 
3832 
3833  constexpr inline auto bytecode_dump_writer = &basic_insert_dump_writer<bytecode>;
3834 
3835 } // namespace sol
3836 
3837 // end of sol/bytecode.hpp
3838 
3839 // beginning of sol/stack.hpp
3840 
3841 // beginning of sol/trampoline.hpp
3842 
3843 // beginning of sol/types.hpp
3844 
3845 // beginning of sol/error.hpp
3846 
3847 #include <stdexcept>
3848 #include <string>
3849 #include <array>
3850 
3851 namespace sol {
3852  namespace detail {
3853  struct direct_error_tag {};
3855 
3856  struct error_result {
3857  int results;
3858  const char* format_string;
3859  std::array<const char*, 4> args_strings;
3860 
3861  error_result() : results(0), format_string(nullptr) {
3862  }
3863 
3864  error_result(int results) : results(results), format_string(nullptr) {
3865  }
3866 
3867  error_result(const char* fmt, const char* msg) : results(0), format_string(fmt) {
3868  args_strings[0] = msg;
3869  }
3870  };
3871 
3872  inline int handle_errors(lua_State* L, const error_result& er) {
3873  if (er.format_string == nullptr) {
3874  return er.results;
3875  }
3876  return luaL_error(L, er.format_string, er.args_strings[0], er.args_strings[1], er.args_strings[2], er.args_strings[3]);
3877  }
3878  } // namespace detail
3879 
3880  class error : public std::runtime_error {
3881  private:
3882  // Because VC++ is upsetting, most of the time!
3884 
3885  public:
3886  error(const std::string& str) : error(detail::direct_error, "lua: error: " + str) {
3887  }
3888  error(std::string&& str) : error(detail::direct_error, "lua: error: " + std::move(str)) {
3889  }
3890  error(detail::direct_error_tag, const std::string& str) : std::runtime_error(""), what_reason(str) {
3891  }
3892  error(detail::direct_error_tag, std::string&& str) : std::runtime_error(""), what_reason(std::move(str)) {
3893  }
3894 
3895  error(const error& e) = default;
3896  error(error&& e) = default;
3897  error& operator=(const error& e) = default;
3898  error& operator=(error&& e) = default;
3899 
3900  virtual const char* what() const noexcept override {
3901  return what_reason.c_str();
3902  }
3903  };
3904 
3905 } // namespace sol
3906 
3907 // end of sol/error.hpp
3908 
3909 // beginning of sol/optional.hpp
3910 
3911 // beginning of sol/in_place.hpp
3912 
3913 #include <cstddef>
3914 #include <utility>
3915 
3916 namespace sol {
3917 
3921 
3922  template <typename T>
3923  using in_place_type_t = std::in_place_type_t<T>;
3924  template <typename T>
3925  constexpr std::in_place_type_t<T> in_place_type {};
3926 
3927  template <size_t I>
3928  using in_place_index_t = std::in_place_index_t<I>;
3929  template <size_t I>
3931 
3932 } // namespace sol
3933 
3934 // end of sol/in_place.hpp
3935 
3936 #if SOL_IS_ON(SOL_USE_BOOST_I_)
3937 #include <boost/optional.hpp>
3938 #else
3939 // beginning of sol/optional_implementation.hpp
3940 
3941 #define SOL_TL_OPTIONAL_VERSION_MAJOR 0
3942 #define SOL_TL_OPTIONAL_VERSION_MINOR 5
3943 
3944 #include <exception>
3945 #include <functional>
3946 #include <new>
3947 #include <type_traits>
3948 #include <utility>
3949 #include <cstdlib>
3950 #include <optional>
3951 
3952 #if (defined(_MSC_VER) && _MSC_VER == 1900)
3953 #define SOL_TL_OPTIONAL_MSVC2015
3954 #endif
3955 
3956 #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && !defined(__clang__))
3957 #define SOL_TL_OPTIONAL_GCC49
3958 #endif
3959 
3960 #if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && !defined(__clang__))
3961 #define SOL_TL_OPTIONAL_GCC54
3962 #endif
3963 
3964 #if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && !defined(__clang__))
3965 #define SOL_TL_OPTIONAL_GCC55
3966 #endif
3967 
3968 #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && !defined(__clang__))
3969 #define SOL_TL_OPTIONAL_NO_CONSTRR
3970 
3971 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) std::has_trivial_copy_constructor<T>::value
3972 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::has_trivial_copy_assign<T>::value
3973 
3974 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
3975 
3976 #elif (defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__))
3977 #ifndef SOL_TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
3978 #define SOL_TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
3979 namespace sol { namespace detail {
3980  template <class T>
3981  struct is_trivially_copy_constructible : std::is_trivially_copy_constructible<T> {};
3982 #ifdef _GLIBCXX_VECTOR
3983  template <class T, class A>
3984  struct is_trivially_copy_constructible<std::vector<T, A>> : std::is_trivially_copy_constructible<T> {};
3985 #endif
3986 }} // namespace sol::detail
3987 #endif
3988 
3989 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) sol::detail::is_trivially_copy_constructible<T>::value
3990 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::is_trivially_copy_assignable<T>::value
3991 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
3992 #else
3993 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) std::is_trivially_copy_constructible<T>::value
3994 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::is_trivially_copy_assignable<T>::value
3995 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
3996 #endif
3997 
3998 #if __cplusplus > 201103L
3999 #define SOL_TL_OPTIONAL_CXX14
4000 #endif
4001 
4002 #if (__cplusplus == 201103L || defined(SOL_TL_OPTIONAL_MSVC2015) || defined(SOL_TL_OPTIONAL_GCC49))
4003 #define SOL_TL_OPTIONAL_11_CONSTEXPR
4004 #else
4005 #define SOL_TL_OPTIONAL_11_CONSTEXPR constexpr
4007 #endif
4008 
4009 namespace sol {
4010 #ifndef SOL_TL_MONOSTATE_INPLACE_MUTEX
4011 #define SOL_TL_MONOSTATE_INPLACE_MUTEX
4012  class monostate {};
4014 #endif
4015 
4016  template <class T>
4017  class optional;
4018 
4020  namespace detail {
4021 #ifndef SOL_TL_TRAITS_MUTEX
4022 #define SOL_TL_TRAITS_MUTEX
4023  // C++14-style aliases for brevity
4024  template <class T>
4026  template <class T>
4028  template <class T>
4029  using decay_t = typename std::decay<T>::type;
4030  template <bool E, class T = void>
4032  template <bool B, class T, class F>
4034 
4035  // std::conjunction from C++17
4036  template <class...>
4037  struct conjunction : std::true_type {};
4038  template <class B>
4039  struct conjunction<B> : B {};
4040  template <class B, class... Bs>
4041  struct conjunction<B, Bs...> : std::conditional<bool(B::value), conjunction<Bs...>, B>::type {};
4042 
4043 #if defined(_LIBCPP_VERSION) && __cplusplus == 201103L
4044 #define SOL_TL_OPTIONAL_LIBCXX_MEM_FN_WORKAROUND
4045 #endif
4046 
4047 #ifdef SOL_TL_OPTIONAL_LIBCXX_MEM_FN_WORKAROUND
4048  template <class T>
4049  struct is_pointer_to_non_const_member_func : std::false_type {};
4050  template <class T, class Ret, class... Args>
4051  struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...)> : std::true_type {};
4052  template <class T, class Ret, class... Args>
4053  struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...)&> : std::true_type {};
4054  template <class T, class Ret, class... Args>
4055  struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) &&> : std::true_type {};
4056  template <class T, class Ret, class... Args>
4057  struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile> : std::true_type {};
4058  template <class T, class Ret, class... Args>
4059  struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile&> : std::true_type {};
4060  template <class T, class Ret, class... Args>
4061  struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile&&> : std::true_type {};
4062 
4063  template <class T>
4064  struct is_const_or_const_ref : std::false_type {};
4065  template <class T>
4066  struct is_const_or_const_ref<T const&> : std::true_type {};
4067  template <class T>
4068  struct is_const_or_const_ref<T const> : std::true_type {};
4069 #endif
4070 
4071  // std::invoke from C++17
4072  // https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround
4073  template <typename Fn, typename... Args,
4074 #ifdef SOL_TL_OPTIONAL_LIBCXX_MEM_FN_WORKAROUND
4075  typename = enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value && is_const_or_const_ref<Args...>::value)>,
4076 #endif
4077  typename = enable_if_t<std::is_member_pointer<decay_t<Fn>>::value>, int = 0>
4078  constexpr auto invoke(Fn&& f, Args&&... args) noexcept(noexcept(std::mem_fn(f)(std::forward<Args>(args)...)))
4079  -> decltype(std::mem_fn(f)(std::forward<Args>(args)...)) {
4080  return std::mem_fn(f)(std::forward<Args>(args)...);
4081  }
4082 
4083  template <typename Fn, typename... Args, typename = enable_if_t<!std::is_member_pointer<decay_t<Fn>>::value>>
4084  constexpr auto invoke(Fn&& f, Args&&... args) noexcept(noexcept(std::forward<Fn>(f)(std::forward<Args>(args)...)))
4085  -> decltype(std::forward<Fn>(f)(std::forward<Args>(args)...)) {
4086  return std::forward<Fn>(f)(std::forward<Args>(args)...);
4087  }
4088 
4089  // std::invoke_result from C++17
4090  template <class F, class, class... Us>
4092 
4093  template <class F, class... Us>
4094  struct invoke_result_impl<F, decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...), void()), Us...> {
4095  using type = decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...));
4096  };
4097 
4098  template <class F, class... Us>
4100 
4101  template <class F, class... Us>
4102  using invoke_result_t = typename invoke_result<F, Us...>::type;
4103 #endif
4104 
4105  // std::void_t from C++17
4106  template <class...>
4107  struct voider {
4108  using type = void;
4109  };
4110  template <class... Ts>
4111  using void_t = typename voider<Ts...>::type;
4112 
4113  // Trait for checking if a type is a sol::optional
4114  template <class T>
4115  struct is_optional_impl : std::false_type {};
4116  template <class T>
4117  struct is_optional_impl<optional<T>> : std::true_type {};
4118  template <class T>
4120 
4121  // Change void to sol::monostate
4122  template <class U>
4124 
4125  template <class F, class U, class = invoke_result_t<F, U>>
4127 
4128  // Check if invoking F for some Us returns void
4129  template <class F, class = void, class... U>
4131  template <class F, class... U>
4132  struct returns_void_impl<F, void_t<invoke_result_t<F, U...>>, U...> : std::is_void<invoke_result_t<F, U...>> {};
4133  template <class F, class... U>
4135 
4136  template <class T, class... U>
4137  using enable_if_ret_void = enable_if_t<returns_void<T&&, U...>::value>;
4138 
4139  template <class T, class... U>
4140  using disable_if_ret_void = enable_if_t<!returns_void<T&&, U...>::value>;
4141 
4142  template <class T, class U>
4143  using enable_forward_value = detail::enable_if_t<std::is_constructible<T, U&&>::value && !std::is_same<detail::decay_t<U>, in_place_t>::value
4144  && !std::is_same<optional<T>, detail::decay_t<U>>::value>;
4145 
4146  template <class T, class U, class Other>
4147  using enable_from_other = detail::enable_if_t<std::is_constructible<T, Other>::value && !std::is_constructible<T, optional<U>&>::value
4148  && !std::is_constructible<T, optional<U>&&>::value && !std::is_constructible<T, const optional<U>&>::value
4149  && !std::is_constructible<T, const optional<U>&&>::value && !std::is_convertible<optional<U>&, T>::value
4150  && !std::is_convertible<optional<U>&&, T>::value && !std::is_convertible<const optional<U>&, T>::value
4151  && !std::is_convertible<const optional<U>&&, T>::value>;
4152 
4153  template <class T, class U>
4155  && !detail::conjunction<std::is_scalar<T>, std::is_same<T, detail::decay_t<U>>>::value && std::is_constructible<T, U>::value
4157 
4158  template <class T, class U, class Other>
4160  && !std::is_constructible<T, optional<U>&>::value && !std::is_constructible<T, optional<U>&&>::value
4161  && !std::is_constructible<T, const optional<U>&>::value && !std::is_constructible<T, const optional<U>&&>::value
4162  && !std::is_convertible<optional<U>&, T>::value && !std::is_convertible<optional<U>&&, T>::value
4163  && !std::is_convertible<const optional<U>&, T>::value && !std::is_convertible<const optional<U>&&, T>::value
4164  && !std::is_assignable<T&, optional<U>&>::value && !std::is_assignable<T&, optional<U>&&>::value
4165  && !std::is_assignable<T&, const optional<U>&>::value && !std::is_assignable<T&, const optional<U>&&>::value>;
4166 
4167 #ifdef _MSC_VER
4168  // TODO make a version which works with MSVC
4169  template <class T, class U = T>
4170  struct is_swappable : std::true_type {};
4171 
4172  template <class T, class U = T>
4173  struct is_nothrow_swappable : std::true_type {};
4174 #else
4175  // https://stackoverflow.com/questions/26744589/what-is-a-proper-way-to-implement-is-swappable-to-test-for-the-swappable-concept
4176  namespace swap_adl_tests {
4177  // if swap ADL finds this then it would call std::swap otherwise (same
4178  // signature)
4179  struct tag {};
4180 
4181  template <class T>
4182  tag swap(T&, T&);
4183  template <class T, std::size_t N>
4184  tag swap(T (&a)[N], T (&b)[N]);
4185 
4186  // helper functions to test if an unqualified swap is possible, and if it
4187  // becomes std::swap
4188  template <class, class>
4189  std::false_type can_swap(...) noexcept(false);
4190  template <class T, class U, class = decltype(swap(std::declval<T&>(), std::declval<U&>()))>
4191  std::true_type can_swap(int) noexcept(noexcept(swap(std::declval<T&>(), std::declval<U&>())));
4192 
4193  template <class, class>
4194  std::false_type uses_std(...);
4195  template <class T, class U>
4196  std::is_same<decltype(swap(std::declval<T&>(), std::declval<U&>())), tag> uses_std(int);
4197 
4198  template <class T>
4200  : std::integral_constant<bool, std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_assignable<T>::value> {};
4201 
4202  template <class T, std::size_t N>
4204 
4205  template <class T, class U>
4206  struct is_adl_swap_noexcept : std::integral_constant<bool, noexcept(can_swap<T, U>(0))> {};
4207  } // namespace swap_adl_tests
4208 
4209  template <class T, class U = T>
4210  struct is_swappable : std::integral_constant<bool,
4211  decltype(detail::swap_adl_tests::can_swap<T, U>(0))::value
4212  && (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value
4213  || (std::is_move_assignable<T>::value && std::is_move_constructible<T>::value))> {};
4214 
4215  template <class T, std::size_t N>
4216  struct is_swappable<T[N], T[N]> : std::integral_constant<bool,
4217  decltype(detail::swap_adl_tests::can_swap<T[N], T[N]>(0))::value
4218  && (!decltype(detail::swap_adl_tests::uses_std<T[N], T[N]>(0))::value || is_swappable<T, T>::value)> {};
4219 
4220  template <class T, class U = T>
4222  : std::integral_constant<bool,
4223  is_swappable<T, U>::value
4224  && ((decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value&& detail::swap_adl_tests::is_std_swap_noexcept<T>::value)
4225  || (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value&& detail::swap_adl_tests::is_adl_swap_noexcept<T, U>::value))> {};
4226 #endif
4227 
4228  // The storage base manages the actual storage, and correctly propagates
4229  // trivial destruction from T. This case is for when T is not trivially
4230  // destructible.
4233  SOL_TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept : m_dummy(), m_has_value(false) {
4234  }
4235 
4236  template <class... U>
4237  SOL_TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U&&... u) : m_value(std::forward<U>(u)...), m_has_value(true) {
4238  }
4239 
4241  if (m_has_value) {
4242  m_value.~T();
4243  m_has_value = false;
4244  }
4245  }
4246 
4247  struct dummy {};
4248  union {
4251  };
4252 
4254  };
4255 
4256  // This case is for when T is trivially destructible.
4257  template <class T>
4258  struct optional_storage_base<T, true> {
4259  SOL_TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept : m_dummy(), m_has_value(false) {
4260  }
4261 
4262  template <class... U>
4263  SOL_TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U&&... u) : m_value(std::forward<U>(u)...), m_has_value(true) {
4264  }
4265 
4266  // No destructor, so this class is trivially destructible
4267 
4268  struct dummy {};
4269  union {
4272  };
4273 
4274  bool m_has_value = false;
4275  };
4276 
4277  // This base class provides some handy member functions which can be used in
4278  // further derived classes
4279  template <class T>
4282 
4283  void hard_reset() noexcept {
4284  get().~T();
4285  this->m_has_value = false;
4286  }
4287 
4288  template <class... Args>
4289  void construct(Args&&... args) noexcept {
4290  new (std::addressof(this->m_value)) T(std::forward<Args>(args)...);
4291  this->m_has_value = true;
4292  }
4293 
4294  template <class Opt>
4295  void assign(Opt&& rhs) {
4296  if (this->has_value()) {
4297  if (rhs.has_value()) {
4298  this->m_value = std::forward<Opt>(rhs).get();
4299  }
4300  else {
4301  this->m_value.~T();
4302  this->m_has_value = false;
4303  }
4304  }
4305 
4306  else if (rhs.has_value()) {
4307  construct(std::forward<Opt>(rhs).get());
4308  }
4309  }
4310 
4311  bool has_value() const {
4312  return this->m_has_value;
4313  }
4314 
4316  return this->m_value;
4317  }
4318  SOL_TL_OPTIONAL_11_CONSTEXPR const T& get() const& {
4319  return this->m_value;
4320  }
4322  return std::move(this->m_value);
4323  }
4324 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
4325  constexpr const T&& get() const&& {
4326  return std::move(this->m_value);
4327  }
4328 #endif
4329  };
4330 
4331  // This class manages conditionally having a trivial copy constructor
4332  // This specialization is for when T is trivially copy constructible
4333  template <class T, bool = SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)>
4336  };
4337 
4338  // This specialization is for when T is not trivially copy constructible
4339  template <class T>
4342 
4343  using base_t::base_t;
4344 
4345  optional_copy_base() = default;
4347  if (rhs.has_value()) {
4348  this->construct(rhs.get());
4349  }
4350  else {
4351  this->m_has_value = false;
4352  }
4353  }
4354 
4355  optional_copy_base(optional_copy_base&& rhs) = default;
4356  optional_copy_base& operator=(const optional_copy_base& rhs) = default;
4357  optional_copy_base& operator=(optional_copy_base&& rhs) = default;
4358  };
4359 
4360 #ifndef SOL_TL_OPTIONAL_GCC49
4364  };
4365 #else
4366  template <class T, bool = false>
4367  struct optional_move_base;
4368 #endif
4369  template <class T>
4370  struct optional_move_base<T, false> : optional_copy_base<T> {
4372 
4373  optional_move_base() = default;
4374  optional_move_base(const optional_move_base& rhs) = default;
4375 
4376  optional_move_base(optional_move_base&& rhs) noexcept(std::is_nothrow_move_constructible<T>::value) {
4377  if (rhs.has_value()) {
4378  this->construct(std::move(rhs.get()));
4379  }
4380  else {
4381  this->m_has_value = false;
4382  }
4383  }
4384  optional_move_base& operator=(const optional_move_base& rhs) = default;
4385  optional_move_base& operator=(optional_move_base&& rhs) = default;
4386  };
4387 
4388  // This class manages conditionally having a trivial copy assignment operator
4389  template <class T,
4394  };
4395 
4396  template <class T>
4399 
4400  optional_copy_assign_base() = default;
4402 
4405  this->assign(rhs);
4406  return *this;
4407  }
4408  optional_copy_assign_base& operator=(optional_copy_assign_base&& rhs) = default;
4409  };
4410 
4411 #ifndef SOL_TL_OPTIONAL_GCC49
4412  template <class T,
4416  };
4417 #else
4418  template <class T, bool = false>
4420 #endif
4421 
4422  template <class T>
4425 
4426  optional_move_assign_base() = default;
4428 
4430 
4431  optional_move_assign_base& operator=(const optional_move_assign_base& rhs) = default;
4432 
4434  std::is_nothrow_move_constructible<T>::value&& std::is_nothrow_move_assignable<T>::value) {
4435  this->assign(std::move(rhs));
4436  return *this;
4437  }
4438  };
4439 
4440  // optional_delete_ctor_base will conditionally delete copy and move
4441  // constructors depending on whether T is copy/move constructible
4444  optional_delete_ctor_base() = default;
4447  optional_delete_ctor_base& operator=(const optional_delete_ctor_base&) = default;
4448  optional_delete_ctor_base& operator=(optional_delete_ctor_base&&) noexcept = default;
4449  };
4450 
4451  template <class T>
4452  struct optional_delete_ctor_base<T, true, false> {
4453  optional_delete_ctor_base() = default;
4456  optional_delete_ctor_base& operator=(const optional_delete_ctor_base&) = default;
4457  optional_delete_ctor_base& operator=(optional_delete_ctor_base&&) noexcept = default;
4458  };
4459 
4460  template <class T>
4461  struct optional_delete_ctor_base<T, false, true> {
4462  optional_delete_ctor_base() = default;
4465  optional_delete_ctor_base& operator=(const optional_delete_ctor_base&) = default;
4466  optional_delete_ctor_base& operator=(optional_delete_ctor_base&&) noexcept = default;
4467  };
4468 
4469  template <class T>
4470  struct optional_delete_ctor_base<T, false, false> {
4471  optional_delete_ctor_base() = default;
4474  optional_delete_ctor_base& operator=(const optional_delete_ctor_base&) = default;
4475  optional_delete_ctor_base& operator=(optional_delete_ctor_base&&) noexcept = default;
4476  };
4477 
4478  // optional_delete_assign_base will conditionally delete copy and move
4479  // constructors depending on whether T is copy/move constructible + assignable
4483  optional_delete_assign_base() = default;
4486  optional_delete_assign_base& operator=(const optional_delete_assign_base&) = default;
4487  optional_delete_assign_base& operator=(optional_delete_assign_base&&) noexcept = default;
4488  };
4489 
4490  template <class T>
4491  struct optional_delete_assign_base<T, true, false> {
4492  optional_delete_assign_base() = default;
4495  optional_delete_assign_base& operator=(const optional_delete_assign_base&) = default;
4496  optional_delete_assign_base& operator=(optional_delete_assign_base&&) noexcept = delete;
4497  };
4498 
4499  template <class T>
4500  struct optional_delete_assign_base<T, false, true> {
4501  optional_delete_assign_base() = default;
4504  optional_delete_assign_base& operator=(const optional_delete_assign_base&) = delete;
4505  optional_delete_assign_base& operator=(optional_delete_assign_base&&) noexcept = default;
4506  };
4507 
4508  template <class T>
4509  struct optional_delete_assign_base<T, false, false> {
4510  optional_delete_assign_base() = default;
4513  optional_delete_assign_base& operator=(const optional_delete_assign_base&) = delete;
4514  optional_delete_assign_base& operator=(optional_delete_assign_base&&) noexcept = delete;
4515  };
4516 
4517  } // namespace detail
4518 
4521 
4531  using std::nullopt;
4532 
4533  class bad_optional_access : public std::exception {
4534  public:
4535  bad_optional_access() = default;
4536  const char* what() const noexcept {
4537  return "Optional has no value";
4538  }
4539  };
4540 
4547  template <class T>
4548  class optional : private detail::optional_move_assign_base<T>,
4552 
4553  static_assert(!std::is_same<T, in_place_t>::value, "instantiation of optional with in_place_t is ill-formed");
4554  static_assert(!std::is_same<detail::decay_t<T>, nullopt_t>::value, "instantiation of optional with nullopt_t is ill-formed");
4555 
4556  public:
4557 #if defined(SOL_TL_OPTIONAL_CXX14) && !defined(SOL_TL_OPTIONAL_GCC49) && !defined(SOL_TL_OPTIONAL_GCC54) && !defined(SOL_TL_OPTIONAL_GCC55)
4558  template <class F>
4569  SOL_TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f) & {
4571  static_assert(detail::is_optional<result>::value, "F must return an optional");
4572 
4573  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
4574  }
4575 
4578  template <class F>
4579  SOL_TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f) && {
4581  static_assert(detail::is_optional<result>::value, "F must return an optional");
4582 
4583  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : result(nullopt);
4584  }
4585 
4588  template <class F>
4589  constexpr auto and_then(F&& f) const& {
4591  static_assert(detail::is_optional<result>::value, "F must return an optional");
4592 
4593  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
4594  }
4595 
4596 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
4597  template <class F>
4600  constexpr auto and_then(F&& f) const&& {
4602  static_assert(detail::is_optional<result>::value, "F must return an optional");
4603 
4604  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : result(nullopt);
4605  }
4606 #endif
4607 #else
4608  template <class F>
4621  static_assert(detail::is_optional<result>::value, "F must return an optional");
4622 
4623  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
4624  }
4625 
4628  template <class F>
4631  static_assert(detail::is_optional<result>::value, "F must return an optional");
4632 
4633  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : result(nullopt);
4634  }
4635 
4638  template <class F>
4641  static_assert(detail::is_optional<result>::value, "F must return an optional");
4642 
4643  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
4644  }
4645 
4646 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
4647  template <class F>
4652  static_assert(detail::is_optional<result>::value, "F must return an optional");
4653 
4654  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : result(nullopt);
4655  }
4656 #endif
4657 #endif
4658 
4659 #if defined(SOL_TL_OPTIONAL_CXX14) && !defined(SOL_TL_OPTIONAL_GCC49) && !defined(SOL_TL_OPTIONAL_GCC54) && !defined(SOL_TL_OPTIONAL_GCC55)
4660  template <class F>
4670  SOL_TL_OPTIONAL_11_CONSTEXPR auto map(F&& f) & {
4671  return optional_map_impl(*this, std::forward<F>(f));
4672  }
4673 
4676  template <class F>
4677  SOL_TL_OPTIONAL_11_CONSTEXPR auto map(F&& f) && {
4678  return optional_map_impl(std::move(*this), std::forward<F>(f));
4679  }
4680 
4683  template <class F>
4684  constexpr auto map(F&& f) const& {
4685  return optional_map_impl(*this, std::forward<F>(f));
4686  }
4687 
4690  template <class F>
4691  constexpr auto map(F&& f) const&& {
4692  return optional_map_impl(std::move(*this), std::forward<F>(f));
4693  }
4694 #else
4695  template <class F>
4705  SOL_TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval<optional&>(), std::declval<F&&>())) map(F&& f) & {
4706  return optional_map_impl(*this, std::forward<F>(f));
4707  }
4708 
4711  template <class F>
4712  SOL_TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval<optional&&>(), std::declval<F&&>())) map(F&& f) && {
4713  return optional_map_impl(std::move(*this), std::forward<F>(f));
4714  }
4715 
4718  template <class F>
4719  constexpr decltype(optional_map_impl(std::declval<const optional&>(), std::declval<F&&>())) map(F&& f) const& {
4720  return optional_map_impl(*this, std::forward<F>(f));
4721  }
4722 
4723 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
4724  template <class F>
4727  constexpr decltype(optional_map_impl(std::declval<const optional&&>(), std::declval<F&&>())) map(F&& f) const&& {
4728  return optional_map_impl(std::move(*this), std::forward<F>(f));
4729  }
4730 #endif
4731 #endif
4732 
4742  template <class F, detail::enable_if_ret_void<F>* = nullptr>
4744  if (has_value())
4745  return *this;
4746 
4747  std::forward<F>(f)();
4748  return nullopt;
4749  }
4750 
4752  template <class F, detail::disable_if_ret_void<F>* = nullptr>
4754  return has_value() ? *this : std::forward<F>(f)();
4755  }
4756 
4759  template <class F, detail::enable_if_ret_void<F>* = nullptr>
4760  optional<T> or_else(F&& f) && {
4761  if (has_value())
4762  return std::move(*this);
4763 
4764  std::forward<F>(f)();
4765  return nullopt;
4766  }
4767 
4769  template <class F, detail::disable_if_ret_void<F>* = nullptr>
4771  return has_value() ? std::move(*this) : std::forward<F>(f)();
4772  }
4773 
4776  template <class F, detail::enable_if_ret_void<F>* = nullptr>
4777  optional<T> or_else(F&& f) const& {
4778  if (has_value())
4779  return *this;
4780 
4781  std::forward<F>(f)();
4782  return nullopt;
4783  }
4784 
4786  template <class F, detail::disable_if_ret_void<F>* = nullptr>
4788  return has_value() ? *this : std::forward<F>(f)();
4789  }
4790 
4791 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
4792  template <class F, detail::enable_if_ret_void<F>* = nullptr>
4794  optional<T> or_else(F&& f) const&& {
4795  if (has_value())
4796  return std::move(*this);
4797 
4798  std::forward<F>(f)();
4799  return nullopt;
4800  }
4801 
4803  template <class F, detail::disable_if_ret_void<F>* = nullptr>
4804  optional<T> or_else(F&& f) const&& {
4805  return has_value() ? std::move(*this) : std::forward<F>(f)();
4806  }
4807 #endif
4808 
4816  template <class F, class U>
4817  U map_or(F&& f, U&& u) & {
4818  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u);
4819  }
4820 
4822  template <class F, class U>
4823  U map_or(F&& f, U&& u) && {
4824  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u);
4825  }
4826 
4828  template <class F, class U>
4829  U map_or(F&& f, U&& u) const& {
4830  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u);
4831  }
4832 
4833 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
4834  template <class F, class U>
4836  U map_or(F&& f, U&& u) const&& {
4837  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u);
4838  }
4839 #endif
4840 
4850  template <class F, class U>
4852  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u)();
4853  }
4854 
4858  template <class F, class U>
4860  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u)();
4861  }
4862 
4866  template <class F, class U>
4868  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u)();
4869  }
4870 
4871 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
4872  template <class F, class U>
4876  detail::invoke_result_t<U> map_or_else(F&& f, U&& u) const&& {
4877  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u)();
4878  }
4879 #endif
4880 
4882  template <class U>
4885  return has_value() ? result { u } : result { nullopt };
4886  }
4887 
4891  return has_value() ? *this : rhs;
4892  }
4893 
4895  constexpr optional disjunction(const optional& rhs) const& {
4896  return has_value() ? *this : rhs;
4897  }
4898 
4901  return has_value() ? std::move(*this) : rhs;
4902  }
4903 
4904 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
4905  constexpr optional disjunction(const optional& rhs) const&& {
4907  return has_value() ? std::move(*this) : rhs;
4908  }
4909 #endif
4910 
4913  return has_value() ? *this : std::move(rhs);
4914  }
4915 
4917  constexpr optional disjunction(optional&& rhs) const& {
4918  return has_value() ? *this : std::move(rhs);
4919  }
4920 
4923  return has_value() ? std::move(*this) : std::move(rhs);
4924  }
4925 
4926 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
4927  constexpr optional disjunction(optional&& rhs) const&& {
4929  return has_value() ? std::move(*this) : std::move(rhs);
4930  }
4931 #endif
4932 
4936  optional ret = *this;
4937  reset();
4938  return ret;
4939  }
4940 
4942  optional take() const& {
4943  optional ret = *this;
4944  reset();
4945  return ret;
4946  }
4947 
4950  optional ret = std::move(*this);
4951  reset();
4952  return ret;
4953  }
4954 
4955 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
4956  optional take() const&& {
4958  optional ret = std::move(*this);
4959  reset();
4960  return ret;
4961  }
4962 #endif
4963 
4964  using value_type = T;
4965 
4968  constexpr optional() noexcept = default;
4969 
4971  constexpr optional(nullopt_t) noexcept {
4972  }
4973 
4978  SOL_TL_OPTIONAL_11_CONSTEXPR optional(const optional& rhs) = default;
4979 
4985 
4989  template <class... Args>
4991  : base(in_place, std::forward<Args>(args)...) {
4992  }
4993 
4996  template <class U, class... Args>
4997  SOL_TL_OPTIONAL_11_CONSTEXPR explicit optional(detail::enable_if_t<std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value, in_place_t>,
4998  std::initializer_list<U> il, Args&&... args) {
4999  this->construct(il, std::forward<Args>(args)...);
5000  }
5001 
5002 #if 0 // SOL_MODIFICATION
5006  constexpr optional(U&& u) : base(in_place, std::forward<U>(u)) {
5007  }
5008 
5011  constexpr explicit optional(U&& u) : base(in_place, std::forward<U>(u)) {
5012  }
5013 #else
5014  constexpr optional(T&& u) : base(in_place, std::move(u)) {
5017  }
5018 
5020  constexpr optional(const T& u) : base(in_place, u) {
5021  }
5022 #endif // sol3 modification
5023 
5026  template <class U, detail::enable_from_other<T, U, const U&>* = nullptr, detail::enable_if_t<std::is_convertible<const U&, T>::value>* = nullptr>
5027  optional(const optional<U>& rhs) {
5028  if (rhs.has_value()) {
5029  this->construct(*rhs);
5030  }
5031  }
5032 
5034  template <class U, detail::enable_from_other<T, U, const U&>* = nullptr, detail::enable_if_t<!std::is_convertible<const U&, T>::value>* = nullptr>
5035  explicit optional(const optional<U>& rhs) {
5036  if (rhs.has_value()) {
5037  this->construct(*rhs);
5038  }
5039  }
5040 
5043  template <class U, detail::enable_from_other<T, U, U&&>* = nullptr, detail::enable_if_t<std::is_convertible<U&&, T>::value>* = nullptr>
5045  if (rhs.has_value()) {
5046  this->construct(std::move(*rhs));
5047  }
5048  }
5049 
5051  template <class U, detail::enable_from_other<T, U, U&&>* = nullptr, detail::enable_if_t<!std::is_convertible<U&&, T>::value>* = nullptr>
5052  explicit optional(optional<U>&& rhs) {
5053  this->construct(std::move(*rhs));
5054  }
5055 
5057  ~optional() = default;
5058 
5062  optional& operator=(nullopt_t) noexcept {
5063  if (has_value()) {
5064  this->m_value.~T();
5065  this->m_has_value = false;
5066  }
5067 
5068  return *this;
5069  }
5070 
5075  optional& operator=(const optional& rhs) = default;
5076 
5081  optional& operator=(optional&& rhs) = default;
5082 
5086  template <class U = T, detail::enable_assign_forward<T, U>* = nullptr>
5087  optional& operator=(U&& u) {
5088  if (has_value()) {
5089  this->m_value = std::forward<U>(u);
5090  }
5091  else {
5092  this->construct(std::forward<U>(u));
5093  }
5094 
5095  return *this;
5096  }
5097 
5103  template <class U, detail::enable_assign_from_other<T, U, const U&>* = nullptr>
5104  optional& operator=(const optional<U>& rhs) {
5105  if (has_value()) {
5106  if (rhs.has_value()) {
5107  this->m_value = *rhs;
5108  }
5109  else {
5110  this->hard_reset();
5111  }
5112  }
5113 
5114  if (rhs.has_value()) {
5115  this->construct(*rhs);
5116  }
5117 
5118  return *this;
5119  }
5120 
5121  // TODO check exception guarantee
5127  template <class U, detail::enable_assign_from_other<T, U, U>* = nullptr>
5128  optional& operator=(optional<U>&& rhs) {
5129  if (has_value()) {
5130  if (rhs.has_value()) {
5131  this->m_value = std::move(*rhs);
5132  }
5133  else {
5134  this->hard_reset();
5135  }
5136  }
5137 
5138  if (rhs.has_value()) {
5139  this->construct(std::move(*rhs));
5140  }
5141 
5142  return *this;
5143  }
5144 
5148  template <class... Args>
5149  T& emplace(Args&&... args) {
5150  static_assert(std::is_constructible<T, Args&&...>::value, "T must be constructible with Args");
5151 
5152  *this = nullopt;
5153  this->construct(std::forward<Args>(args)...);
5154  return value();
5155  }
5156 
5159  template <class U, class... Args>
5160  detail::enable_if_t<std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value, T&> emplace(std::initializer_list<U> il, Args&&... args) {
5161  *this = nullopt;
5162  this->construct(il, std::forward<Args>(args)...);
5163  return value();
5164  }
5165 
5173  if (has_value()) {
5174  if (rhs.has_value()) {
5175  using std::swap;
5176  swap(**this, *rhs);
5177  }
5178  else {
5179  new (std::addressof(rhs.m_value)) T(std::move(this->m_value));
5180  this->m_value.T::~T();
5181  }
5182  }
5183  else if (rhs.has_value()) {
5184  new (std::addressof(this->m_value)) T(std::move(rhs.m_value));
5185  rhs.m_value.T::~T();
5186  }
5187  }
5188 
5193  constexpr const T* operator->() const {
5194  return std::addressof(this->m_value);
5195  }
5196 
5200  return std::addressof(this->m_value);
5201  }
5202 
5208  return this->m_value;
5209  }
5210 
5213  constexpr const T& operator*() const& {
5214  return this->m_value;
5215  }
5216 
5219  return std::move(this->m_value);
5220  }
5221 
5222 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5223  constexpr const T&& operator*() const&& {
5225  return std::move(this->m_value);
5226  }
5227 #endif
5228 
5231  constexpr bool has_value() const noexcept {
5232  return this->m_has_value;
5233  }
5234 
5236  constexpr explicit operator bool() const noexcept {
5237  return this->m_has_value;
5238  }
5239 
5245  if (has_value())
5246  return this->m_value;
5247 #if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
5248  std::abort();
5249 #else
5250  throw bad_optional_access();
5251 #endif // No exceptions allowed
5252  }
5256  if (has_value())
5257  return this->m_value;
5258 #if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
5259  std::abort();
5260 #else
5261  throw bad_optional_access();
5262 #endif // No exceptions allowed
5263  }
5266  if (has_value())
5267  return std::move(this->m_value);
5268 #if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
5269  std::abort();
5270 #else
5271  throw bad_optional_access();
5272 #endif // No exceptions allowed
5273  }
5274 
5275 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5276  SOL_TL_OPTIONAL_11_CONSTEXPR const T&& value() const&& {
5278  if (has_value())
5279  return std::move(this->m_value);
5280 #if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
5281  std::abort();
5282 #else
5283  throw bad_optional_access();
5284 #endif // No exceptions allowed
5285  }
5286 #endif
5287 
5290  template <class U>
5291  constexpr T value_or(U&& u) const& {
5292  static_assert(std::is_copy_constructible<T>::value && std::is_convertible<U&&, T>::value, "T must be copy constructible and convertible from U");
5293  return has_value() ? **this : static_cast<T>(std::forward<U>(u));
5294  }
5295 
5297  template <class U>
5299  static_assert(std::is_move_constructible<T>::value && std::is_convertible<U&&, T>::value, "T must be move constructible and convertible from U");
5300  return has_value() ? **this : static_cast<T>(std::forward<U>(u));
5301  }
5302 
5304  void reset() noexcept {
5305  if (has_value()) {
5306  this->m_value.~T();
5307  this->m_has_value = false;
5308  }
5309  }
5310  }; // namespace sol
5311 
5318  template <class T, class U>
5319  inline constexpr bool operator==(const optional<T>& lhs, const optional<U>& rhs) {
5320  return lhs.has_value() == rhs.has_value() && (!lhs.has_value() || *lhs == *rhs);
5321  }
5323  template <class T, class U>
5324  inline constexpr bool operator!=(const optional<T>& lhs, const optional<U>& rhs) {
5325  return lhs.has_value() != rhs.has_value() || (lhs.has_value() && *lhs != *rhs);
5326  }
5328  template <class T, class U>
5329  inline constexpr bool operator<(const optional<T>& lhs, const optional<U>& rhs) {
5330  return rhs.has_value() && (!lhs.has_value() || *lhs < *rhs);
5331  }
5333  template <class T, class U>
5334  inline constexpr bool operator>(const optional<T>& lhs, const optional<U>& rhs) {
5335  return lhs.has_value() && (!rhs.has_value() || *lhs > *rhs);
5336  }
5338  template <class T, class U>
5339  inline constexpr bool operator<=(const optional<T>& lhs, const optional<U>& rhs) {
5340  return !lhs.has_value() || (rhs.has_value() && *lhs <= *rhs);
5341  }
5343  template <class T, class U>
5344  inline constexpr bool operator>=(const optional<T>& lhs, const optional<U>& rhs) {
5345  return !rhs.has_value() || (lhs.has_value() && *lhs >= *rhs);
5346  }
5347 
5351  template <class T>
5352  inline constexpr bool operator==(const optional<T>& lhs, nullopt_t) noexcept {
5353  return !lhs.has_value();
5354  }
5356  template <class T>
5357  inline constexpr bool operator==(nullopt_t, const optional<T>& rhs) noexcept {
5358  return !rhs.has_value();
5359  }
5361  template <class T>
5362  inline constexpr bool operator!=(const optional<T>& lhs, nullopt_t) noexcept {
5363  return lhs.has_value();
5364  }
5366  template <class T>
5367  inline constexpr bool operator!=(nullopt_t, const optional<T>& rhs) noexcept {
5368  return rhs.has_value();
5369  }
5371  template <class T>
5372  inline constexpr bool operator<(const optional<T>&, nullopt_t) noexcept {
5373  return false;
5374  }
5376  template <class T>
5377  inline constexpr bool operator<(nullopt_t, const optional<T>& rhs) noexcept {
5378  return rhs.has_value();
5379  }
5381  template <class T>
5382  inline constexpr bool operator<=(const optional<T>& lhs, nullopt_t) noexcept {
5383  return !lhs.has_value();
5384  }
5386  template <class T>
5387  inline constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept {
5388  return true;
5389  }
5391  template <class T>
5392  inline constexpr bool operator>(const optional<T>& lhs, nullopt_t) noexcept {
5393  return lhs.has_value();
5394  }
5396  template <class T>
5397  inline constexpr bool operator>(nullopt_t, const optional<T>&) noexcept {
5398  return false;
5399  }
5401  template <class T>
5402  inline constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept {
5403  return true;
5404  }
5406  template <class T>
5407  inline constexpr bool operator>=(nullopt_t, const optional<T>& rhs) noexcept {
5408  return !rhs.has_value();
5409  }
5410 
5416  template <class T, class U>
5417  inline constexpr bool operator==(const optional<T>& lhs, const U& rhs) {
5418  return lhs.has_value() ? *lhs == rhs : false;
5419  }
5421  template <class T, class U>
5422  inline constexpr bool operator==(const U& lhs, const optional<T>& rhs) {
5423  return rhs.has_value() ? lhs == *rhs : false;
5424  }
5426  template <class T, class U>
5427  inline constexpr bool operator!=(const optional<T>& lhs, const U& rhs) {
5428  return lhs.has_value() ? *lhs != rhs : true;
5429  }
5431  template <class T, class U>
5432  inline constexpr bool operator!=(const U& lhs, const optional<T>& rhs) {
5433  return rhs.has_value() ? lhs != *rhs : true;
5434  }
5436  template <class T, class U>
5437  inline constexpr bool operator<(const optional<T>& lhs, const U& rhs) {
5438  return lhs.has_value() ? *lhs < rhs : true;
5439  }
5441  template <class T, class U>
5442  inline constexpr bool operator<(const U& lhs, const optional<T>& rhs) {
5443  return rhs.has_value() ? lhs < *rhs : false;
5444  }
5446  template <class T, class U>
5447  inline constexpr bool operator<=(const optional<T>& lhs, const U& rhs) {
5448  return lhs.has_value() ? *lhs <= rhs : true;
5449  }
5451  template <class T, class U>
5452  inline constexpr bool operator<=(const U& lhs, const optional<T>& rhs) {
5453  return rhs.has_value() ? lhs <= *rhs : false;
5454  }
5456  template <class T, class U>
5457  inline constexpr bool operator>(const optional<T>& lhs, const U& rhs) {
5458  return lhs.has_value() ? *lhs > rhs : false;
5459  }
5461  template <class T, class U>
5462  inline constexpr bool operator>(const U& lhs, const optional<T>& rhs) {
5463  return rhs.has_value() ? lhs > *rhs : true;
5464  }
5466  template <class T, class U>
5467  inline constexpr bool operator>=(const optional<T>& lhs, const U& rhs) {
5468  return lhs.has_value() ? *lhs >= rhs : false;
5469  }
5471  template <class T, class U>
5472  inline constexpr bool operator>=(const U& lhs, const optional<T>& rhs) {
5473  return rhs.has_value() ? lhs >= *rhs : true;
5474  }
5475 
5478  void swap(optional<T>& lhs, optional<T>& rhs) noexcept(noexcept(lhs.swap(rhs))) {
5479  return lhs.swap(rhs);
5480  }
5481 
5482  namespace detail {
5483  struct i_am_secret {};
5484  } // namespace detail
5485 
5487  inline constexpr optional<Ret> make_optional(U&& v) {
5488  return optional<Ret>(std::forward<U>(v));
5489  }
5490 
5491  template <class T, class... Args>
5492  inline constexpr optional<T> make_optional(Args&&... args) {
5493  return optional<T>(in_place, std::forward<Args>(args)...);
5494  }
5495  template <class T, class U, class... Args>
5496  inline constexpr optional<T> make_optional(std::initializer_list<U> il, Args&&... args) {
5497  return optional<T>(in_place, il, std::forward<Args>(args)...);
5498  }
5499 
5500 #if __cplusplus >= 201703L
5501  template <class T>
5502  optional(T)->optional<T>;
5503 #endif
5504 
5506  namespace detail {
5507 #ifdef SOL_TL_OPTIONAL_CXX14
5508  template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
5509  detail::enable_if_t<!std::is_void<Ret>::value>* = nullptr>
5510  constexpr auto optional_map_impl(Opt&& opt, F&& f) {
5511  return opt.has_value() ? detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt)) : optional<Ret>(nullopt);
5512  }
5513 
5514  template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
5515  detail::enable_if_t<std::is_void<Ret>::value>* = nullptr>
5516  auto optional_map_impl(Opt&& opt, F&& f) {
5517  if (opt.has_value()) {
5518  detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt));
5519  return make_optional(monostate {});
5520  }
5521 
5522  return optional<monostate>(nullopt);
5523  }
5524 #else
5525  template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
5526  detail::enable_if_t<!std::is_void<Ret>::value>* = nullptr>
5527 
5528  constexpr auto optional_map_impl(Opt&& opt, F&& f) -> optional<Ret> {
5529  return opt.has_value() ? detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt)) : optional<Ret>(nullopt);
5530  }
5531 
5532  template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
5533  detail::enable_if_t<std::is_void<Ret>::value>* = nullptr>
5534 
5535  auto optional_map_impl(Opt&& opt, F&& f) -> optional<monostate> {
5536  if (opt.has_value()) {
5537  detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt));
5538  return monostate {};
5539  }
5540 
5541  return nullopt;
5542  }
5543 #endif
5544  } // namespace detail
5545 
5568  template <class T>
5569  class optional<T&> {
5570  public:
5571 #if defined(SOL_TL_OPTIONAL_CXX14) && !defined(SOL_TL_OPTIONAL_GCC49) && !defined(SOL_TL_OPTIONAL_GCC54) && !defined(SOL_TL_OPTIONAL_GCC55)
5572  template <class F>
5583  SOL_TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f) & {
5585  static_assert(detail::is_optional<result>::value, "F must return an optional");
5586 
5587  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
5588  }
5589 
5592  template <class F>
5593  SOL_TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f) && {
5595  static_assert(detail::is_optional<result>::value, "F must return an optional");
5596 
5597  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
5598  }
5599 
5602  template <class F>
5603  constexpr auto and_then(F&& f) const& {
5605  static_assert(detail::is_optional<result>::value, "F must return an optional");
5606 
5607  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
5608  }
5609 
5610 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5611  template <class F>
5614  constexpr auto and_then(F&& f) const&& {
5616  static_assert(detail::is_optional<result>::value, "F must return an optional");
5617 
5618  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
5619  }
5620 #endif
5621 #else
5622  template <class F>
5635  static_assert(detail::is_optional<result>::value, "F must return an optional");
5636 
5637  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
5638  }
5639 
5642  template <class F>
5645  static_assert(detail::is_optional<result>::value, "F must return an optional");
5646 
5647  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
5648  }
5649 
5652  template <class F>
5655  static_assert(detail::is_optional<result>::value, "F must return an optional");
5656 
5657  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
5658  }
5659 
5660 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5661  template <class F>
5666  static_assert(detail::is_optional<result>::value, "F must return an optional");
5667 
5668  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
5669  }
5670 #endif
5671 #endif
5672 
5673 #if defined(SOL_TL_OPTIONAL_CXX14) && !defined(SOL_TL_OPTIONAL_GCC49) && !defined(SOL_TL_OPTIONAL_GCC54) && !defined(SOL_TL_OPTIONAL_GCC55)
5674  template <class F>
5684  SOL_TL_OPTIONAL_11_CONSTEXPR auto map(F&& f) & {
5685  return detail::optional_map_impl(*this, std::forward<F>(f));
5686  }
5687 
5690  template <class F>
5691  SOL_TL_OPTIONAL_11_CONSTEXPR auto map(F&& f) && {
5692  return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
5693  }
5694 
5697  template <class F>
5698  constexpr auto map(F&& f) const& {
5699  return detail::optional_map_impl(*this, std::forward<F>(f));
5700  }
5701 
5704  template <class F>
5705  constexpr auto map(F&& f) const&& {
5706  return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
5707  }
5708 #else
5709  template <class F>
5719  SOL_TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl(std::declval<optional&>(), std::declval<F&&>())) map(F&& f) & {
5720  return detail::optional_map_impl(*this, std::forward<F>(f));
5721  }
5722 
5725  template <class F>
5726  SOL_TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl(std::declval<optional&&>(), std::declval<F&&>())) map(F&& f) && {
5727  return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
5728  }
5729 
5732  template <class F>
5733  constexpr decltype(detail::optional_map_impl(std::declval<const optional&>(), std::declval<F&&>())) map(F&& f) const& {
5734  return detail::optional_map_impl(*this, std::forward<F>(f));
5735  }
5736 
5737 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5738  template <class F>
5741  constexpr decltype(detail::optional_map_impl(std::declval<const optional&&>(), std::declval<F&&>())) map(F&& f) const&& {
5742  return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
5743  }
5744 #endif
5745 #endif
5746 
5755  template <class F, detail::enable_if_ret_void<F>* = nullptr>
5757  if (has_value())
5758  return *this;
5759 
5760  std::forward<F>(f)();
5761  return nullopt;
5762  }
5763 
5765  template <class F, detail::disable_if_ret_void<F>* = nullptr>
5767  return has_value() ? *this : std::forward<F>(f)();
5768  }
5769 
5772  template <class F, detail::enable_if_ret_void<F>* = nullptr>
5773  optional<T> or_else(F&& f) && {
5774  if (has_value())
5775  return std::move(*this);
5776 
5777  std::forward<F>(f)();
5778  return nullopt;
5779  }
5780 
5782  template <class F, detail::disable_if_ret_void<F>* = nullptr>
5784  return has_value() ? std::move(*this) : std::forward<F>(f)();
5785  }
5786 
5789  template <class F, detail::enable_if_ret_void<F>* = nullptr>
5790  optional<T> or_else(F&& f) const& {
5791  if (has_value())
5792  return *this;
5793 
5794  std::forward<F>(f)();
5795  return nullopt;
5796  }
5797 
5799  template <class F, detail::disable_if_ret_void<F>* = nullptr>
5801  return has_value() ? *this : std::forward<F>(f)();
5802  }
5803 
5804 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5805  template <class F, detail::enable_if_ret_void<F>* = nullptr>
5807  optional<T> or_else(F&& f) const&& {
5808  if (has_value())
5809  return std::move(*this);
5810 
5811  std::forward<F>(f)();
5812  return nullopt;
5813  }
5814 
5816  template <class F, detail::disable_if_ret_void<F>* = nullptr>
5817  optional<T> or_else(F&& f) const&& {
5818  return has_value() ? std::move(*this) : std::forward<F>(f)();
5819  }
5820 #endif
5821 
5829  template <class F, class U>
5830  U map_or(F&& f, U&& u) & {
5831  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u);
5832  }
5833 
5835  template <class F, class U>
5836  U map_or(F&& f, U&& u) && {
5837  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u);
5838  }
5839 
5841  template <class F, class U>
5842  U map_or(F&& f, U&& u) const& {
5843  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u);
5844  }
5845 
5846 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5847  template <class F, class U>
5849  U map_or(F&& f, U&& u) const&& {
5850  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u);
5851  }
5852 #endif
5853 
5863  template <class F, class U>
5865  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u)();
5866  }
5867 
5871  template <class F, class U>
5873  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u)();
5874  }
5875 
5879  template <class F, class U>
5881  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u)();
5882  }
5883 
5884 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5885  template <class F, class U>
5889  detail::invoke_result_t<U> map_or_else(F&& f, U&& u) const&& {
5890  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u)();
5891  }
5892 #endif
5893 
5895  template <class U>
5898  return has_value() ? result { u } : result { nullopt };
5899  }
5900 
5904  return has_value() ? *this : rhs;
5905  }
5906 
5908  constexpr optional disjunction(const optional& rhs) const& {
5909  return has_value() ? *this : rhs;
5910  }
5911 
5914  return has_value() ? std::move(*this) : rhs;
5915  }
5916 
5917 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5918  constexpr optional disjunction(const optional& rhs) const&& {
5920  return has_value() ? std::move(*this) : rhs;
5921  }
5922 #endif
5923 
5926  return has_value() ? *this : std::move(rhs);
5927  }
5928 
5930  constexpr optional disjunction(optional&& rhs) const& {
5931  return has_value() ? *this : std::move(rhs);
5932  }
5933 
5936  return has_value() ? std::move(*this) : std::move(rhs);
5937  }
5938 
5939 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5940  constexpr optional disjunction(optional&& rhs) const&& {
5942  return has_value() ? std::move(*this) : std::move(rhs);
5943  }
5944 #endif
5945 
5949  optional ret = *this;
5950  reset();
5951  return ret;
5952  }
5953 
5955  optional take() const& {
5956  optional ret = *this;
5957  reset();
5958  return ret;
5959  }
5960 
5963  optional ret = std::move(*this);
5964  reset();
5965  return ret;
5966  }
5967 
5968 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5969  optional take() const&& {
5971  optional ret = std::move(*this);
5972  reset();
5973  return ret;
5974  }
5975 #endif
5976 
5977  using value_type = T&;
5978 
5981  constexpr optional() noexcept : m_value(nullptr) {
5982  }
5983 
5985  constexpr optional(nullopt_t) noexcept : m_value(nullptr) {
5986  }
5987 
5992  SOL_TL_OPTIONAL_11_CONSTEXPR optional(const optional& rhs) noexcept = default;
5993 
5999 
6002  template <class U = T, detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>* = nullptr>
6003  constexpr optional(U&& u) : m_value(std::addressof(u)) {
6004  static_assert(std::is_lvalue_reference<U>::value, "U must be an lvalue");
6005  }
6006 
6008  template <class U>
6009  constexpr explicit optional(const optional<U>& rhs) : optional(*rhs) {
6010  }
6011 
6013  ~optional() = default;
6014 
6019  m_value = nullptr;
6020  return *this;
6021  }
6022 
6027  optional& operator=(const optional& rhs) = default;
6028 
6033  template <class U = T, detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>* = nullptr>
6035  static_assert(std::is_lvalue_reference<U>::value, "U must be an lvalue");
6036  m_value = std::addressof(u);
6037  return *this;
6038  }
6039 
6044  template <class U>
6046  m_value = std::addressof(rhs.value());
6047  return *this;
6048  }
6049 
6054  template <class... Args>
6055  T& emplace(Args&&... args) noexcept {
6056  static_assert(std::is_constructible<T, Args&&...>::value, "T must be constructible with Args");
6057 
6058  *this = nullopt;
6059  this->construct(std::forward<Args>(args)...);
6060  }
6061 
6068  void swap(optional& rhs) noexcept {
6069  std::swap(m_value, rhs.m_value);
6070  }
6071 
6076  constexpr const T* operator->() const {
6077  return m_value;
6078  }
6079 
6083  return m_value;
6084  }
6085 
6091  return *m_value;
6092  }
6093 
6096  constexpr const T& operator*() const {
6097  return *m_value;
6098  }
6099 
6102  constexpr bool has_value() const noexcept {
6103  return m_value != nullptr;
6104  }
6105 
6107  constexpr explicit operator bool() const noexcept {
6108  return m_value != nullptr;
6109  }
6110 
6116  if (has_value())
6117  return *m_value;
6118 #if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
6119  std::abort();
6120 #else
6121  throw bad_optional_access();
6122 #endif // No exceptions allowed
6123  }
6127  if (has_value())
6128  return *m_value;
6129 #if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
6130  std::abort();
6131 #else
6132  throw bad_optional_access();
6133 #endif // No exceptions allowed
6134  }
6135 
6138  template <class U>
6139  constexpr T& value_or(U&& u) const {
6140  static_assert(std::is_convertible<U&&, T&>::value, "T must be convertible from U");
6141  return has_value() ? const_cast<T&>(**this) : static_cast<T&>(std::forward<U>(u));
6142  }
6143 
6145  void reset() noexcept {
6146  m_value = nullptr;
6147  }
6148 
6149  private:
6151  };
6152 
6153 } // namespace sol
6154 
6155 namespace std {
6156  // TODO SFINAE
6157  template <class T>
6158  struct hash<::sol::optional<T>> {
6159  ::std::size_t operator()(const ::sol::optional<T>& o) const {
6160  if (!o.has_value())
6161  return 0;
6162 
6163  return ::std::hash<::sol::detail::remove_const_t<T>>()(*o);
6164  }
6165  };
6166 } // namespace std
6167 
6168 // end of sol/optional_implementation.hpp
6169 
6170 #endif // Boost vs. Better optional
6171 
6172 #include <optional>
6173 
6174 namespace sol {
6175 
6176 #if SOL_IS_ON(SOL_USE_BOOST_I_)
6177  template <typename T>
6178  using optional = boost::optional<T>;
6179  using nullopt_t = boost::none_t;
6180  const nullopt_t nullopt = boost::none;
6181 #endif // Boost vs. Better optional
6182 
6183  namespace meta {
6184  template <typename T>
6186 
6187  template <typename T>
6188  constexpr inline bool is_optional_v = is_optional<T>::value;
6189  } // namespace meta
6190 
6191  namespace detail {
6192  template <typename T>
6194  inline static constexpr std::nullopt_t value = std::nullopt;
6195  };
6196 
6197 #if SOL_IS_ON(SOL_USE_BOOST_I_)
6198  template <typename T>
6199  struct associated_nullopt<boost::optional<T>> {
6200  inline static constexpr std::nullopt_t value = boost::nullopt;
6201  };
6202 #endif // Boost nullopt
6203 
6204  template <typename T>
6206  } // namespace detail
6207 } // namespace sol
6208 
6209 // end of sol/optional.hpp
6210 
6211 // beginning of sol/raii.hpp
6212 
6213 #include <memory>
6214 
6215 namespace sol {
6216  namespace detail {
6218  template <typename T, typename... Args>
6219  static void construct(T&& obj, Args&&... args) {
6220  typedef meta::unqualified_t<T> Tu;
6221  std::allocator<Tu> alloc{};
6222  std::allocator_traits<std::allocator<Tu>>::construct(alloc, std::forward<T>(obj), std::forward<Args>(args)...);
6223  }
6224 
6225  template <typename T, typename... Args>
6226  void operator()(T&& obj, Args&&... args) const {
6227  construct(std::forward<T>(obj), std::forward<Args>(args)...);
6228  }
6229  };
6230 
6232  template <typename T>
6233  static void destroy(T&& obj) {
6234  std::allocator<meta::unqualified_t<T>> alloc{};
6235  alloc.destroy(obj);
6236  }
6237 
6238  template <typename T>
6239  void operator()(T&& obj) const {
6240  destroy(std::forward<T>(obj));
6241  }
6242  };
6243 
6244  struct deleter {
6245  template <typename T>
6246  void operator()(T* p) const {
6247  delete p;
6248  }
6249  };
6250 
6251  struct state_deleter {
6252  void operator()(lua_State* L) const {
6253  lua_close(L);
6254  }
6255  };
6256 
6257  template <typename T, typename Dx, typename... Args>
6258  inline std::unique_ptr<T, Dx> make_unique_deleter(Args&&... args) {
6259  return std::unique_ptr<T, Dx>(new T(std::forward<Args>(args)...));
6260  }
6261 
6262  template <typename Tag, typename T>
6263  struct tagged {
6264  private:
6266 
6267  public:
6268  template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, tagged>> = meta::enabler>
6269  tagged(Arg&& arg, Args&&... args)
6270  : value_(std::forward<Arg>(arg), std::forward<Args>(args)...) {
6271  }
6272 
6273  T& value() & {
6274  return value_;
6275  }
6276 
6277  T const& value() const& {
6278  return value_;
6279  }
6280 
6281  T&& value() && {
6282  return std::move(value_);
6283  }
6284  };
6285  } // namespace detail
6286 
6287  template <typename... Args>
6288  struct constructor_list {};
6289 
6290  template <typename... Args>
6291  using constructors = constructor_list<Args...>;
6292 
6294 
6295  struct no_construction {};
6297 
6300 
6301  template <typename... Functions>
6303  std::tuple<Functions...> functions;
6304  template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, constructor_wrapper>> = meta::enabler>
6305  constructor_wrapper(Arg&& arg, Args&&... args)
6306  : functions(std::forward<Arg>(arg), std::forward<Args>(args)...) {
6307  }
6308  };
6309 
6310  template <typename... Functions>
6311  inline auto initializers(Functions&&... functions) {
6312  return constructor_wrapper<std::decay_t<Functions>...>(std::forward<Functions>(functions)...);
6313  }
6314 
6315  template <typename... Functions>
6317  std::tuple<Functions...> functions;
6318  template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, factory_wrapper>> = meta::enabler>
6319  factory_wrapper(Arg&& arg, Args&&... args)
6320  : functions(std::forward<Arg>(arg), std::forward<Args>(args)...) {
6321  }
6322  };
6323 
6324  template <typename... Functions>
6325  inline auto factories(Functions&&... functions) {
6326  return factory_wrapper<std::decay_t<Functions>...>(std::forward<Functions>(functions)...);
6327  }
6328 
6329  template <typename Function>
6331  Function fx;
6333  : fx(std::move(f)) {
6334  }
6335  };
6336 
6337  template <>
6339 
6341 
6342  template <typename Fx>
6343  inline auto destructor(Fx&& fx) {
6344  return destructor_wrapper<std::decay_t<Fx>>(std::forward<Fx>(fx));
6345  }
6346 
6347 } // namespace sol
6348 
6349 // end of sol/raii.hpp
6350 
6351 // beginning of sol/policies.hpp
6352 
6353 #include <array>
6354 
6355 namespace sol {
6356  namespace detail {
6357  struct policy_base_tag {};
6358  } // namespace detail
6359 
6360  template <int Target, int... In>
6363  template <int... In>
6366 
6368  int target;
6369  std::array<int, 64> stack_indices;
6370  std::size_t len;
6371 
6372  template <typename... Args>
6373  stack_dependencies(int stack_target, Args&&... args) : target(stack_target), stack_indices(), len(sizeof...(Args)) {
6374  std::size_t i = 0;
6375  (void)detail::swallow{ int(), (stack_indices[i++] = static_cast<int>(std::forward<Args>(args)), int())... };
6376  }
6377 
6378  int& operator[](std::size_t i) {
6379  return stack_indices[i];
6380  }
6381 
6382  const int& operator[](std::size_t i) const {
6383  return stack_indices[i];
6384  }
6385 
6386  std::size_t size() const {
6387  return len;
6388  }
6389  };
6390 
6391  template <typename F, typename... Policies>
6392  struct policy_wrapper {
6393  typedef std::index_sequence_for<Policies...> indices;
6394 
6396  std::tuple<Policies...> policies;
6397 
6398  template <typename Fx, typename... Args, meta::enable<meta::neg<std::is_same<meta::unqualified_t<Fx>, policy_wrapper>>> = meta::enabler>
6399  policy_wrapper(Fx&& fx, Args&&... args) : value(std::forward<Fx>(fx)), policies(std::forward<Args>(args)...) {
6400  }
6401 
6402  policy_wrapper(const policy_wrapper&) = default;
6403  policy_wrapper& operator=(const policy_wrapper&) = default;
6404  policy_wrapper(policy_wrapper&&) = default;
6405  policy_wrapper& operator=(policy_wrapper&&) = default;
6406  };
6407 
6408  template <typename F, typename... Args>
6409  auto policies(F&& f, Args&&... args) {
6410  return policy_wrapper<std::decay_t<F>, std::decay_t<Args>...>(std::forward<F>(f), std::forward<Args>(args)...);
6411  }
6412 
6413  namespace detail {
6414  template <typename T>
6416 
6417  template <typename T>
6418  inline constexpr bool is_policy_v = is_policy<T>::value;
6419  } // namespace detail
6420 } // namespace sol
6421 
6422 // end of sol/policies.hpp
6423 
6424 // beginning of sol/ebco.hpp
6425 
6426 #include <type_traits>
6427 #include <utility>
6428 
6429 namespace sol { namespace detail {
6430 
6431  template <typename T, std::size_t tag = 0, typename = void>
6432  struct ebco {
6434 
6435  ebco() = default;
6436  ebco(const ebco&) = default;
6437  ebco(ebco&&) = default;
6438  ebco& operator=(const ebco&) = default;
6439  ebco& operator=(ebco&&) = default;
6440  ebco(const T& v) : value_(v){};
6441  ebco(T&& v) : value_(std::move(v)){};
6442  ebco& operator=(const T& v) {
6443  value_ = v;
6444  return *this;
6445  }
6446  ebco& operator=(T&& v) {
6447  value_ = std::move(v);
6448  return *this;
6449  };
6450  template <typename Arg, typename... Args,
6451  typename = std::enable_if_t<!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
6452  ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T>>>
6453  ebco(Arg&& arg, Args&&... args) : T(std::forward<Arg>(arg), std::forward<Args>(args)...){}
6454 
6455  T& value() & {
6456  return value_;
6457  }
6458 
6459  T const& value() const & {
6460  return value_;
6461  }
6462 
6463  T&& value() && {
6464  return std::move(value_);
6465  }
6466  };
6467 
6468  template <typename T, std::size_t tag>
6469  struct ebco<T, tag, std::enable_if_t<!std::is_reference_v<T> && std::is_class_v<T> && !std::is_final_v<T>>> : T {
6470  ebco() = default;
6471  ebco(const ebco&) = default;
6472  ebco(ebco&&) = default;
6473  ebco(const T& v) : T(v){};
6474  ebco(T&& v) : T(std::move(v)){};
6475  template <typename Arg, typename... Args,
6476  typename = std::enable_if_t<!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
6477  ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T>>>
6478  ebco(Arg&& arg, Args&&... args) : T(std::forward<Arg>(arg), std::forward<Args>(args)...) {
6479  }
6480 
6481  ebco& operator=(const ebco&) = default;
6482  ebco& operator=(ebco&&) = default;
6483  ebco& operator=(const T& v) {
6484  static_cast<T&>(*this) = v;
6485  return *this;
6486  }
6487  ebco& operator=(T&& v) {
6488  static_cast<T&>(*this) = std::move(v);
6489  return *this;
6490  };
6491 
6492  T& value() & {
6493  return static_cast<T&>(*this);
6494  }
6495 
6496  T const& value() const & {
6497  return static_cast<T const&>(*this);
6498  }
6499 
6500  T&& value() && {
6501  return std::move(static_cast<T&>(*this));
6502  }
6503  };
6504 
6505  template <typename T, std::size_t tag>
6506  struct ebco<T&, tag> {
6507  T& ref;
6508 
6509  ebco() = default;
6510  ebco(const ebco&) = default;
6511  ebco(ebco&&) = default;
6512  ebco(T& v) : ref(v){};
6513 
6514  ebco& operator=(const ebco&) = default;
6515  ebco& operator=(ebco&&) = default;
6516  ebco& operator=(T& v) {
6517  ref = v;
6518  return *this;
6519  }
6520 
6521  T& value() const {
6522  return const_cast<ebco<T&, tag>&>(*this).ref;
6523  }
6524  };
6525 
6526  template <typename T, std::size_t tag>
6527  struct ebco<T&&, tag> {
6528  T&& ref;
6529 
6530  ebco() = default;
6531  ebco(const ebco&) = default;
6532  ebco(ebco&&) = default;
6533  ebco(T&& v) : ref(v){};
6534 
6535  ebco& operator=(const ebco&) = default;
6536  ebco& operator=(ebco&&) = default;
6537  ebco& operator=(T&& v) {
6538  ref = std::move(v);
6539  return *this;
6540  }
6541 
6542  T& value() & {
6543  return ref;
6544  }
6545 
6546  const T& value() const & {
6547  return ref;
6548  }
6549 
6550  T&& value() && {
6551  return std::move(ref);
6552  }
6553  };
6554 
6555 }} // namespace sol::detail
6556 
6557 // end of sol/ebco.hpp
6558 
6559 #include <array>
6560 #include <initializer_list>
6561 #include <string>
6562 #include <string_view>
6563 #include <optional>
6564 #if SOL_IS_ON(SOL_STD_VARIANT_I_)
6565 #include <variant>
6566 #endif // variant shenanigans (thanks, Mac OSX)
6567 
6568 namespace sol {
6569  namespace detail {
6570 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
6571  typedef int (*lua_CFunction_noexcept)(lua_State* L) noexcept;
6572 #else
6573  typedef int (*lua_CFunction_noexcept)(lua_State* L);
6574 #endif // noexcept function type for lua_CFunction
6575 
6576  template <typename T>
6577  struct unique_usertype { };
6578 
6579  template <typename T>
6581  T& item;
6582  implicit_wrapper(T* item) : item(*item) {
6583  }
6584  implicit_wrapper(T& item) : item(item) {
6585  }
6586  operator T&() {
6587  return item;
6588  }
6589  operator T*() {
6590  return std::addressof(item);
6591  }
6592  };
6593 
6594  struct yield_tag_t { };
6596  } // namespace detail
6597 
6598  struct lua_nil_t { };
6599  inline constexpr lua_nil_t lua_nil {};
6601  return true;
6602  }
6604  return false;
6605  }
6606 #if SOL_IS_ON(SOL_NIL_I_)
6607  using nil_t = lua_nil_t;
6608  inline constexpr const nil_t& nil = lua_nil;
6609 #endif
6610 
6611  namespace detail {
6612  struct non_lua_nil_t { };
6613  } // namespace detail
6614 
6615  struct metatable_key_t { };
6617 
6618  struct env_key_t { };
6619  const env_key_t env_key = {};
6620 
6621  struct no_metatable_t { };
6623 
6624  template <typename T>
6625  struct yielding_t {
6626  T func;
6627 
6628  yielding_t() = default;
6629  yielding_t(const yielding_t&) = default;
6630  yielding_t(yielding_t&&) = default;
6631  yielding_t& operator=(const yielding_t&) = default;
6632  yielding_t& operator=(yielding_t&&) = default;
6633  template <typename Arg,
6636  yielding_t(Arg&& arg) : func(std::forward<Arg>(arg)) {
6637  }
6638  template <typename Arg0, typename Arg1, typename... Args>
6639  yielding_t(Arg0&& arg0, Arg1&& arg1, Args&&... args) : func(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...) {
6640  }
6641  };
6642 
6643  template <typename F>
6645  return yielding_t<std::decay_t<F>>(std::forward<F>(f));
6646  }
6647 
6648  typedef std::remove_pointer_t<lua_CFunction> lua_CFunction_ref;
6649 
6650  template <typename T>
6651  struct non_null { };
6652 
6653  template <typename... Args>
6654  struct function_sig { };
6655 
6656  struct upvalue_index {
6657  int index;
6658  upvalue_index(int idx) : index(lua_upvalueindex(idx)) {
6659  }
6660 
6661  operator int() const {
6662  return index;
6663  }
6664  };
6665 
6666  struct raw_index {
6667  int index;
6668  raw_index(int i) : index(i) {
6669  }
6670 
6671  operator int() const {
6672  return index;
6673  }
6674  };
6675 
6677  int index;
6678  absolute_index(lua_State* L, int idx) : index(lua_absindex(L, idx)) {
6679  }
6680 
6681  operator int() const {
6682  return index;
6683  }
6684  };
6685 
6686  struct ref_index {
6687  int index;
6688  ref_index(int idx) : index(idx) {
6689  }
6690 
6691  operator int() const {
6692  return index;
6693  }
6694  };
6695 
6696  struct stack_count {
6697  int count;
6698 
6699  stack_count(int cnt) : count(cnt) {
6700  }
6701  };
6702 
6704  void* value;
6705  lightuserdata_value(void* data) : value(data) {
6706  }
6707  operator void*() const {
6708  return value;
6709  }
6710  };
6711 
6713  void* value;
6714  userdata_value(void* data) : value(data) {
6715  }
6716  operator void*() const {
6717  return value;
6718  }
6719  };
6720 
6721  template <typename L>
6722  struct light {
6723  L* value;
6724 
6725  light(L& x) : value(std::addressof(x)) {
6726  }
6727  light(L* x) : value(x) {
6728  }
6729  light(void* x) : value(static_cast<L*>(x)) {
6730  }
6731  operator L*() const {
6732  return value;
6733  }
6734  operator L&() const {
6735  return *value;
6736  }
6737  };
6738 
6739  template <typename T>
6740  auto make_light(T& l) {
6742  return light<L>(l);
6743  }
6744 
6745  template <typename U>
6746  struct user {
6748 
6749  user(U&& x) : value(std::forward<U>(x)) {
6750  }
6751  operator std::add_pointer_t<std::remove_reference_t<U>>() {
6752  return std::addressof(value);
6753  }
6754  operator std::add_lvalue_reference_t<U>() {
6755  return value;
6756  }
6757  operator std::add_const_t<std::add_lvalue_reference_t<U>> &() const {
6758  return value;
6759  }
6760  };
6761 
6762  template <typename T>
6763  auto make_user(T&& u) {
6765  return user<U>(std::forward<T>(u));
6766  }
6767 
6768  template <typename T>
6770  T key;
6771 
6772  metatable_registry_key(T key) : key(std::forward<T>(key)) {
6773  }
6774  };
6775 
6776  template <typename T>
6777  auto meta_registry_key(T&& key) {
6778  typedef meta::unqualified_t<T> K;
6779  return metatable_registry_key<K>(std::forward<T>(key));
6780  }
6781 
6782  template <typename... Upvalues>
6783  struct closure {
6785  std::tuple<Upvalues...> upvalues;
6786  closure(lua_CFunction f, Upvalues... targetupvalues) : c_function(f), upvalues(std::forward<Upvalues>(targetupvalues)...) {
6787  }
6788  };
6789 
6790  template <>
6791  struct closure<> {
6794  closure(lua_CFunction f, int upvalue_count = 0) : c_function(f), upvalues(upvalue_count) {
6795  }
6796  };
6797 
6799 
6800  template <typename... Args>
6801  closure<Args...> make_closure(lua_CFunction f, Args&&... args) {
6802  return closure<Args...>(f, std::forward<Args>(args)...);
6803  }
6804 
6805  template <typename Sig, typename... Ps>
6807  std::tuple<Ps...> arguments;
6808  template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, function_arguments>> = meta::enabler>
6809  function_arguments(Arg&& arg, Args&&... args) : arguments(std::forward<Arg>(arg), std::forward<Args>(args)...) {
6810  }
6811  };
6812 
6813  template <typename Sig = function_sig<>, typename... Args>
6814  auto as_function(Args&&... args) {
6815  return function_arguments<Sig, std::decay_t<Args>...>(std::forward<Args>(args)...);
6816  }
6817 
6818  template <typename Sig = function_sig<>, typename... Args>
6819  auto as_function_reference(Args&&... args) {
6820  return function_arguments<Sig, Args...>(std::forward<Args>(args)...);
6821  }
6822 
6823  template <typename T>
6824  struct as_table_t {
6825  private:
6827 
6828  public:
6829  as_table_t() = default;
6830  as_table_t(const as_table_t&) = default;
6831  as_table_t(as_table_t&&) = default;
6832  as_table_t& operator=(const as_table_t&) = default;
6833  as_table_t& operator=(as_table_t&&) = default;
6834  template <typename Arg,
6837  as_table_t(Arg&& arg) : value_(std::forward<Arg>(arg)) {
6838  }
6839  template <typename Arg0, typename Arg1, typename... Args>
6840  as_table_t(Arg0&& arg0, Arg1&& arg1, Args&&... args) : value_(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...) {
6841  }
6842 
6843  T& value() & {
6844  return value_;
6845  }
6846 
6847  T&& value() && {
6848  return std::move(value_);
6849  }
6850 
6851  const T& value() const& {
6852  return value_;
6853  }
6854 
6855  operator std::add_lvalue_reference_t<T>() {
6856  return value_;
6857  }
6858  };
6859 
6860  template <typename T>
6861  struct nested {
6862  private:
6864 
6865  public:
6866  using nested_type = T;
6867 
6868  nested() = default;
6869  nested(const nested&) = default;
6870  nested(nested&&) = default;
6871  nested& operator=(const nested&) = default;
6872  nested& operator=(nested&&) = default;
6873  template <typename Arg,
6876  nested(Arg&& arg) : value_(std::forward<Arg>(arg)) {
6877  }
6878  template <typename Arg0, typename Arg1, typename... Args>
6879  nested(Arg0&& arg0, Arg1&& arg1, Args&&... args) : value_(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...) {
6880  }
6881 
6882  T& value() & {
6883  return value_;
6884  }
6885 
6886  T&& value() && {
6887  return std::move(value_);
6888  }
6889 
6890  const T& value() const& {
6891  return value_;
6892  }
6893 
6894  operator std::add_lvalue_reference_t<T>() {
6895  return value_;
6896  }
6897  };
6898 
6899  struct nested_tag_t { };
6900  constexpr inline nested_tag_t nested_tag {};
6901 
6902  template <typename T>
6903  as_table_t<T> as_table_ref(T&& container) {
6904  return as_table_t<T>(std::forward<T>(container));
6905  }
6906 
6907  template <typename T>
6909  return as_table_t<meta::unqualified_t<T>>(std::forward<T>(container));
6910  }
6911 
6912  template <typename T>
6913  nested<T> as_nested_ref(T&& container) {
6914  return nested<T>(std::forward<T>(container));
6915  }
6916 
6917  template <typename T>
6919  return nested<meta::unqualified_t<T>>(std::forward<T>(container));
6920  }
6921 
6922  template <typename T>
6923  struct as_container_t {
6924  private:
6926 
6927  public:
6928  using type = T;
6929 
6930  as_container_t() = default;
6931  as_container_t(const as_container_t&) = default;
6932  as_container_t(as_container_t&&) = default;
6933  as_container_t& operator=(const as_container_t&) = default;
6934  as_container_t& operator=(as_container_t&&) = default;
6935  template <typename Arg,
6938  as_container_t(Arg&& arg) : value_(std::forward<Arg>(arg)) {
6939  }
6940  template <typename Arg0, typename Arg1, typename... Args>
6941  as_container_t(Arg0&& arg0, Arg1&& arg1, Args&&... args) : value_(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...) {
6942  }
6943 
6944  T& value() & {
6945  return value_;
6946  }
6947 
6948  T&& value() && {
6949  return std::move(value_);
6950  }
6951 
6952  const T& value() const& {
6953  return value_;
6954  }
6955  };
6956 
6957  template <typename T>
6958  struct as_container_t<T&> {
6959  private:
6960  std::reference_wrapper<T> value_;
6961 
6962  public:
6963  as_container_t(T& value) : value_(value) {
6964  }
6965 
6966  T& value() {
6967  return value_;
6968  }
6969 
6970  operator T&() {
6971  return value();
6972  }
6973  };
6974 
6975  template <typename T>
6976  auto as_container(T&& value) {
6977  return as_container_t<T>(std::forward<T>(value));
6978  }
6979 
6980  template <typename T>
6981  struct push_invoke_t {
6982  private:
6984 
6985  public:
6986  push_invoke_t() = default;
6987  push_invoke_t(const push_invoke_t&) = default;
6988  push_invoke_t(push_invoke_t&&) = default;
6989  push_invoke_t& operator=(const push_invoke_t&) = default;
6990  push_invoke_t& operator=(push_invoke_t&&) = default;
6991  template <typename Arg,
6994  push_invoke_t(Arg&& arg) : value_(std::forward<Arg>(arg)) {
6995  }
6996  template <typename Arg0, typename Arg1, typename... Args>
6997  push_invoke_t(Arg0&& arg0, Arg1&& arg1, Args&&... args) : value_(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...) {
6998  }
6999 
7000  T& value() & {
7001  return value_;
7002  }
7003 
7004  T&& value() && {
7005  return std::move(value_);
7006  }
7007 
7008  const T& value() const& {
7009  return value_;
7010  }
7011  };
7012 
7013  template <typename T>
7014  struct push_invoke_t<T&> {
7015  std::reference_wrapper<T> value_;
7016 
7017  push_invoke_t(T& value) : value_(value) {
7018  }
7019 
7020  T& value() {
7021  return value_;
7022  }
7023  };
7024 
7025  template <typename Fx>
7026  auto push_invoke(Fx&& fx) {
7027  return push_invoke_t<Fx>(std::forward<Fx>(fx));
7028  }
7029 
7030  struct override_value_t { };
7032  struct update_if_empty_t { };
7034  struct create_if_nil_t { };
7036 
7037  namespace detail {
7038  enum insert_mode { none = 0x0, update_if_empty = 0x01, override_value = 0x02, create_if_nil = 0x04 };
7039 
7040  template <typename T, typename...>
7041  using is_insert_mode = std::integral_constant<bool,
7042  std::is_same_v<T, override_value_t> || std::is_same_v<T, update_if_empty_t> || std::is_same_v<T, create_if_nil_t>>;
7043 
7044  template <typename T, typename...>
7046  } // namespace detail
7047 
7048  struct this_state {
7050 
7051  this_state(lua_State* Ls) : L(Ls) {
7052  }
7053 
7054  operator lua_State*() const noexcept {
7055  return lua_state();
7056  }
7057 
7058  lua_State* operator->() const noexcept {
7059  return lua_state();
7060  }
7061 
7062  lua_State* lua_state() const noexcept {
7063  return L;
7064  }
7065  };
7066 
7069 
7071  }
7072 
7073  operator lua_State*() const noexcept {
7074  return lua_state();
7075  }
7076 
7077  lua_State* operator->() const noexcept {
7078  return lua_state();
7079  }
7080 
7081  lua_State* lua_state() const noexcept {
7082  return L;
7083  }
7084  };
7085 
7086  struct new_table {
7087  int sequence_hint = 0;
7088  int map_hint = 0;
7089 
7090  new_table() = default;
7091  new_table(const new_table&) = default;
7092  new_table(new_table&&) = default;
7093  new_table& operator=(const new_table&) = default;
7094  new_table& operator=(new_table&&) = default;
7095 
7096  new_table(int sequence_hint, int map_hint = 0) : sequence_hint(sequence_hint), map_hint(map_hint) {
7097  }
7098  };
7099 
7100  const new_table create = {};
7101 
7102  enum class lib : char {
7103  // print, assert, and other base functions
7104  base,
7105  // require and other package functions
7106  package,
7107  // coroutine functions and utilities
7108  coroutine,
7109  // string library
7110  string,
7111  // functionality from the OS
7112  os,
7113  // all things math
7114  math,
7115  // the table manipulator and observer functions
7116  table,
7117  // the debug library
7118  debug,
7119  // the bit library: different based on which you're using
7120  bit32,
7121  // input/output library
7122  io,
7123  // LuaJIT only
7124  ffi,
7125  // LuaJIT only
7126  jit,
7127  // library for handling utf8: new to Lua
7128  utf8,
7129  // do not use
7130  count
7131  };
7132 
7133  enum class call_syntax { dot = 0, colon = 1 };
7134 
7135  enum class load_mode {
7136  any = 0,
7137  text = 1,
7138  binary = 2,
7139  };
7140 
7141  enum class call_status : int {
7142  ok = LUA_OK,
7143  yielded = LUA_YIELD,
7144  runtime = LUA_ERRRUN,
7145  memory = LUA_ERRMEM,
7146  handler = LUA_ERRERR,
7147  gc = LUA_ERRGCMM,
7149  file = LUA_ERRFILE,
7150  };
7151 
7152  enum class thread_status : int {
7153  ok = LUA_OK,
7154  yielded = LUA_YIELD,
7155  runtime = LUA_ERRRUN,
7156  memory = LUA_ERRMEM,
7157  gc = LUA_ERRGCMM,
7158  handler = LUA_ERRERR,
7159  dead = -1,
7160  };
7161 
7162  enum class load_status : int {
7163  ok = LUA_OK,
7165  memory = LUA_ERRMEM,
7166  gc = LUA_ERRGCMM,
7167  file = LUA_ERRFILE,
7168  };
7169 
7170  enum class gc_mode : int {
7171  incremental = 0,
7172  generational = 1,
7174  };
7175 
7176  enum class type : int {
7177  none = LUA_TNONE,
7178  lua_nil = LUA_TNIL,
7179 #if SOL_IS_ON(SOL_NIL_I_)
7180  nil = lua_nil,
7181 #endif // Objective C/C++ Keyword that's found in OSX SDK and OBJC -- check for all forms to protect
7182  string = LUA_TSTRING,
7183  number = LUA_TNUMBER,
7184  thread = LUA_TTHREAD,
7185  boolean = LUA_TBOOLEAN,
7186  function = LUA_TFUNCTION,
7189  table = LUA_TTABLE,
7190  poly = -0xFFFF
7191  };
7192 
7194  static const std::array<std::string, 10> names { { "ok",
7195  "yielded",
7196  "runtime",
7197  "memory",
7198  "handler",
7199  "gc",
7200  "syntax",
7201  "file",
7202  "CRITICAL_EXCEPTION_FAILURE",
7203  "CRITICAL_INDETERMINATE_STATE_FAILURE" } };
7204  switch (c) {
7205  case call_status::ok:
7206  return names[0];
7207  case call_status::yielded:
7208  return names[1];
7209  case call_status::runtime:
7210  return names[2];
7211  case call_status::memory:
7212  return names[3];
7213  case call_status::handler:
7214  return names[4];
7215  case call_status::gc:
7216  return names[5];
7217  case call_status::syntax:
7218  return names[6];
7219  case call_status::file:
7220  return names[7];
7221  }
7222  if (static_cast<std::ptrdiff_t>(c) == -1) {
7223  // One of the many cases where a critical exception error has occurred
7224  return names[8];
7225  }
7226  return names[9];
7227  }
7228 
7230  switch (c) {
7231  case call_status::ok:
7232  case call_status::yielded:
7233  case call_status::runtime:
7234  case call_status::memory:
7235  case call_status::handler:
7236  case call_status::gc:
7237  case call_status::syntax:
7238  case call_status::file:
7239  return false;
7240  }
7241  return true;
7242  }
7243 
7245  static const std::array<std::string, 7> names {
7246  { "ok", "memory", "gc", "syntax", "file", "CRITICAL_EXCEPTION_FAILURE", "CRITICAL_INDETERMINATE_STATE_FAILURE" }
7247  };
7248  switch (c) {
7249  case load_status::ok:
7250  return names[0];
7251  case load_status::memory:
7252  return names[1];
7253  case load_status::gc:
7254  return names[2];
7255  case load_status::syntax:
7256  return names[3];
7257  case load_status::file:
7258  return names[4];
7259  }
7260  if (static_cast<int>(c) == -1) {
7261  // One of the many cases where a critical exception error has occurred
7262  return names[5];
7263  }
7264  return names[6];
7265  }
7266 
7268  static const std::array<std::string, 3> names { {
7269  "bt",
7270  "t",
7271  "b",
7272  } };
7273  return names[static_cast<std::size_t>(c)];
7274  }
7275 
7276  enum class meta_function {
7277  construct,
7278  index,
7279  new_index,
7280  mode,
7281  call,
7282  call_function = call,
7283  metatable,
7284  to_string,
7285  length,
7286  unary_minus,
7287  addition,
7288  subtraction,
7290  division,
7291  modulus,
7292  power_of,
7293  involution = power_of,
7294  concatenation,
7295  equal_to,
7296  less_than,
7302  bitwise_not,
7303  bitwise_and,
7304  bitwise_or,
7305  bitwise_xor,
7306  pairs,
7307  ipairs,
7308  next,
7309  type,
7310  type_info,
7312  storage,
7313  gc_names,
7314  static_index,
7316  };
7317 
7319 
7320  inline const std::array<std::string, 37>& meta_function_names() {
7321  static const std::array<std::string, 37> names = { { "new",
7322  "__index",
7323  "__newindex",
7324  "__mode",
7325  "__call",
7326  "__metatable",
7327  "__tostring",
7328  "__len",
7329  "__unm",
7330  "__add",
7331  "__sub",
7332  "__mul",
7333  "__div",
7334  "__mod",
7335  "__pow",
7336  "__concat",
7337  "__eq",
7338  "__lt",
7339  "__le",
7340  "__gc",
7341 
7342  "__idiv",
7343  "__shl",
7344  "__shr",
7345  "__bnot",
7346  "__band",
7347  "__bor",
7348  "__bxor",
7349 
7350  "__pairs",
7351  "__ipairs",
7352  "next",
7353 
7354  "__type",
7355  "__typeinfo",
7356  "__sol.call_new",
7357  "__sol.storage",
7358  "__sol.gc_names",
7359  "__sol.static_index",
7360  "__sol.static_new_index" } };
7361  return names;
7362  }
7363 
7365  return meta_function_names()[static_cast<int>(mf)];
7366  }
7367 
7368  inline type type_of(lua_State* L, int index) {
7369  return static_cast<type>(lua_type(L, index));
7370  }
7371 
7372  inline std::string type_name(lua_State* L, type t) {
7373  return lua_typename(L, static_cast<int>(t));
7374  }
7375 
7376  template <typename T>
7378  : std::integral_constant<bool, std::is_base_of_v<reference, T> || std::is_base_of_v<main_reference, T> || std::is_base_of_v<stack_reference, T>> { };
7379 
7380  template <typename T>
7382 
7383  template <typename T>
7384  struct is_lua_reference_or_proxy : std::integral_constant<bool, is_lua_reference_v<T> || meta::is_specialization_of_v<T, table_proxy>> { };
7385 
7386  template <typename T>
7388 
7389  template <typename T>
7390  struct is_transparent_argument : std::false_type { };
7391 
7392  template <typename T>
7394 
7395  template <>
7396  struct is_transparent_argument<this_state> : std::true_type { };
7397  template <>
7398  struct is_transparent_argument<this_main_state> : std::true_type { };
7399  template <>
7400  struct is_transparent_argument<this_environment> : std::true_type { };
7401  template <>
7402  struct is_transparent_argument<variadic_args> : std::true_type { };
7403  template <typename T>
7404  struct is_variadic_arguments : std::is_same<T, variadic_args> { };
7405 
7406  template <typename T>
7408  : std::integral_constant<bool,
7409  !std::is_same_v<state_view,
7410  T> && !std::is_same_v<state, T> && !meta::is_initializer_list_v<T> && !meta::is_string_like_v<T> && !meta::is_string_literal_array_v<T> && !is_transparent_argument_v<T> && !is_lua_reference_v<T> && (meta::has_begin_end_v<T> || std::is_array_v<T>)> {
7411  };
7412 
7413  template <typename T>
7414  constexpr inline bool is_container_v = is_container<T>::value;
7415 
7416  template <typename T>
7417  struct is_to_stringable : meta::any<meta::supports_to_string_member<meta::unqualified_t<T>>, meta::supports_adl_to_string<meta::unqualified_t<T>>,
7418  meta::supports_op_left_shift<std::ostream, meta::unqualified_t<T>>> { };
7419 
7420  namespace detail {
7421  template <typename T, typename = void>
7422  struct lua_type_of : std::integral_constant<type, type::userdata> { };
7423 
7424  template <typename C, typename T, typename A>
7425  struct lua_type_of<std::basic_string<C, T, A>> : std::integral_constant<type, type::string> { };
7426 
7427  template <typename C, typename T>
7428  struct lua_type_of<basic_string_view<C, T>> : std::integral_constant<type, type::string> { };
7429 
7430  template <std::size_t N>
7431  struct lua_type_of<char[N]> : std::integral_constant<type, type::string> { };
7432 
7433  template <std::size_t N>
7434  struct lua_type_of<wchar_t[N]> : std::integral_constant<type, type::string> { };
7435 
7436  template <std::size_t N>
7437  struct lua_type_of<char16_t[N]> : std::integral_constant<type, type::string> { };
7438 
7439  template <std::size_t N>
7440  struct lua_type_of<char32_t[N]> : std::integral_constant<type, type::string> { };
7441 
7442  template <>
7443  struct lua_type_of<char> : std::integral_constant<type, type::string> { };
7444 
7445  template <>
7446  struct lua_type_of<wchar_t> : std::integral_constant<type, type::string> { };
7447 
7448  template <>
7449  struct lua_type_of<char16_t> : std::integral_constant<type, type::string> { };
7450 
7451  template <>
7452  struct lua_type_of<char32_t> : std::integral_constant<type, type::string> { };
7453 
7454  template <>
7455  struct lua_type_of<const char*> : std::integral_constant<type, type::string> { };
7456 
7457  template <>
7458  struct lua_type_of<const char16_t*> : std::integral_constant<type, type::string> { };
7459 
7460  template <>
7461  struct lua_type_of<const char32_t*> : std::integral_constant<type, type::string> { };
7462 
7463  template <>
7464  struct lua_type_of<bool> : std::integral_constant<type, type::boolean> { };
7465 
7466  template <>
7467  struct lua_type_of<lua_nil_t> : std::integral_constant<type, type::lua_nil> { };
7468 
7469  template <>
7470  struct lua_type_of<nullopt_t> : std::integral_constant<type, type::lua_nil> { };
7471 
7472  template <>
7473  struct lua_type_of<lua_value> : std::integral_constant<type, type::poly> { };
7474 
7475  template <>
7476  struct lua_type_of<detail::non_lua_nil_t> : std::integral_constant<type, type::poly> { };
7477 
7478  template <>
7479  struct lua_type_of<std::nullptr_t> : std::integral_constant<type, type::lua_nil> { };
7480 
7481  template <>
7482  struct lua_type_of<error> : std::integral_constant<type, type::string> { };
7483 
7484  template <bool b, typename Base>
7485  struct lua_type_of<basic_table_core<b, Base>> : std::integral_constant<type, type::table> { };
7486 
7487  template <typename Base>
7488  struct lua_type_of<basic_lua_table<Base>> : std::integral_constant<type, type::table> { };
7489 
7490  template <typename Base>
7491  struct lua_type_of<basic_metatable<Base>> : std::integral_constant<type, type::table> { };
7492 
7493  template <typename T, typename Base>
7494  struct lua_type_of<basic_usertype<T, Base>> : std::integral_constant<type, type::table> { };
7495 
7496  template <>
7497  struct lua_type_of<metatable_key_t> : std::integral_constant<type, type::table> { };
7498 
7499  template <typename B>
7500  struct lua_type_of<basic_environment<B>> : std::integral_constant<type, type::poly> { };
7501 
7502  template <>
7503  struct lua_type_of<env_key_t> : std::integral_constant<type, type::poly> { };
7504 
7505  template <>
7506  struct lua_type_of<new_table> : std::integral_constant<type, type::table> { };
7507 
7508  template <typename T>
7509  struct lua_type_of<as_table_t<T>> : std::integral_constant<type, type::table> { };
7510 
7511  template <typename T>
7512  struct lua_type_of<std::initializer_list<T>> : std::integral_constant<type, type::table> { };
7513 
7514  template <bool b>
7515  struct lua_type_of<basic_reference<b>> : std::integral_constant<type, type::poly> { };
7516 
7517  template <>
7518  struct lua_type_of<stack_reference> : std::integral_constant<type, type::poly> { };
7519 
7520  template <typename Base>
7521  struct lua_type_of<basic_object<Base>> : std::integral_constant<type, type::poly> { };
7522 
7523  template <typename... Args>
7524  struct lua_type_of<std::tuple<Args...>> : std::integral_constant<type, type::poly> { };
7525 
7526  template <typename A, typename B>
7527  struct lua_type_of<std::pair<A, B>> : std::integral_constant<type, type::poly> { };
7528 
7529  template <>
7530  struct lua_type_of<void*> : std::integral_constant<type, type::lightuserdata> { };
7531 
7532  template <>
7533  struct lua_type_of<const void*> : std::integral_constant<type, type::lightuserdata> { };
7534 
7535  template <>
7536  struct lua_type_of<lightuserdata_value> : std::integral_constant<type, type::lightuserdata> { };
7537 
7538  template <>
7539  struct lua_type_of<userdata_value> : std::integral_constant<type, type::userdata> { };
7540 
7541  template <typename T>
7542  struct lua_type_of<light<T>> : std::integral_constant<type, type::lightuserdata> { };
7543 
7544  template <typename T>
7545  struct lua_type_of<user<T>> : std::integral_constant<type, type::userdata> { };
7546 
7547  template <typename Base>
7548  struct lua_type_of<basic_lightuserdata<Base>> : std::integral_constant<type, type::lightuserdata> { };
7549 
7550  template <typename Base>
7551  struct lua_type_of<basic_userdata<Base>> : std::integral_constant<type, type::userdata> { };
7552 
7553  template <>
7554  struct lua_type_of<lua_CFunction> : std::integral_constant<type, type::function> { };
7555 
7556  template <>
7557  struct lua_type_of<std::remove_pointer_t<lua_CFunction>> : std::integral_constant<type, type::function> { };
7558 
7559  template <typename Base, bool aligned>
7560  struct lua_type_of<basic_function<Base, aligned>> : std::integral_constant<type, type::function> { };
7561 
7562  template <typename Base, bool aligned, typename Handler>
7563  struct lua_type_of<basic_protected_function<Base, aligned, Handler>> : std::integral_constant<type, type::function> { };
7564 
7565  template <typename Base>
7566  struct lua_type_of<basic_coroutine<Base>> : std::integral_constant<type, type::function> { };
7567 
7568  template <typename Base>
7569  struct lua_type_of<basic_thread<Base>> : std::integral_constant<type, type::thread> { };
7570 
7571  template <typename Signature>
7572  struct lua_type_of<std::function<Signature>> : std::integral_constant<type, type::function> { };
7573 
7574  template <typename T>
7575  struct lua_type_of<optional<T>> : std::integral_constant<type, type::poly> { };
7576 
7577  template <typename T>
7578  struct lua_type_of<std::optional<T>> : std::integral_constant<type, type::poly> { };
7579 
7580  template <>
7581  struct lua_type_of<variadic_args> : std::integral_constant<type, type::poly> { };
7582 
7583  template <>
7584  struct lua_type_of<variadic_results> : std::integral_constant<type, type::poly> { };
7585 
7586  template <>
7587  struct lua_type_of<stack_count> : std::integral_constant<type, type::poly> { };
7588 
7589  template <>
7590  struct lua_type_of<this_state> : std::integral_constant<type, type::poly> { };
7591 
7592  template <>
7593  struct lua_type_of<this_main_state> : std::integral_constant<type, type::poly> { };
7594 
7595  template <>
7596  struct lua_type_of<this_environment> : std::integral_constant<type, type::poly> { };
7597 
7598  template <>
7599  struct lua_type_of<type> : std::integral_constant<type, type::poly> { };
7600 
7601 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
7602  template <typename T>
7603  struct lua_type_of<T*> : std::integral_constant<type, std::is_function_v<T> ? type::function : type::userdata> { };
7604 #else
7605  template <typename T>
7606  struct lua_type_of<T*> : std::integral_constant<type, type::userdata> { };
7607 #endif
7608 
7609  template <typename T>
7610  struct lua_type_of<T, std::enable_if_t<std::is_arithmetic_v<T> || std::is_same_v<T, lua_Number> || std::is_same_v<T, lua_Integer>>>
7611  : std::integral_constant<type, type::number> { };
7612 
7613  template <typename T>
7614  struct lua_type_of<T, std::enable_if_t<std::is_function_v<T>>> : std::integral_constant<type, type::function> { };
7615 
7616  template <typename T>
7617  struct lua_type_of<T, std::enable_if_t<std::is_enum_v<T>>> : std::integral_constant<type, type::number> { };
7618 
7619  template <>
7620  struct lua_type_of<meta_function> : std::integral_constant<type, type::string> { };
7621 
7622 #if SOL_IS_ON(SOL_STD_VARIANT_I_)
7623  template <typename... Tn>
7624  struct lua_type_of<std::variant<Tn...>> : std::integral_constant<type, type::poly> { };
7625 #endif // std::variant deployment sucks on Clang
7626 
7627  template <typename T>
7628  struct lua_type_of<nested<T>> : meta::conditional_t<::sol::is_container_v<T>, std::integral_constant<type, type::table>, lua_type_of<T>> { };
7629 
7630  template <typename C, C v, template <typename...> class V, typename... Args>
7631  struct accumulate : std::integral_constant<C, v> { };
7632 
7633  template <typename C, C v, template <typename...> class V, typename T, typename... Args>
7634  struct accumulate<C, v, V, T, Args...> : accumulate<C, v + V<T>::value, V, Args...> { };
7635 
7636  template <typename C, C v, template <typename...> class V, typename List>
7638 
7639  template <typename C, C v, template <typename...> class V, typename... Args>
7640  struct accumulate_list<C, v, V, types<Args...>> : accumulate<C, v, V, Args...> { };
7641  } // namespace detail
7642 
7643  template <typename T>
7646  };
7647 
7648  template <typename T>
7649  inline constexpr type lua_type_of_v = lua_type_of<T>::value;
7650 
7651  template <typename T>
7652  struct lua_size : std::integral_constant<int, 1> {
7654  };
7655 
7656  template <typename A, typename B>
7657  struct lua_size<std::pair<A, B>> : std::integral_constant<int, lua_size<A>::value + lua_size<B>::value> { };
7658 
7659  template <typename... Args>
7660  struct lua_size<std::tuple<Args...>> : std::integral_constant<int, detail::accumulate<int, 0, lua_size, Args...>::value> { };
7661 
7662  template <typename T>
7663  inline constexpr int lua_size_v = lua_size<T>::value;
7664 
7665  namespace detail {
7666  template <typename...>
7667  struct void_ {
7668  typedef void type;
7669  };
7670  template <typename T, typename = void>
7671  struct has_internal_marker_impl : std::false_type { };
7672  template <typename T>
7674 
7675  template <typename T>
7677 
7678  template <typename T>
7680  } // namespace detail
7681 
7682  template <typename T>
7684  : std::integral_constant<bool,
7685  type::userdata
7686  != lua_type_of_v<
7687  T> || ((type::userdata == lua_type_of_v<T>)&&detail::has_internal_marker_v<lua_type_of<T>> && !detail::has_internal_marker_v<lua_size<T>>)
7688  || is_lua_reference_or_proxy_v<T> || meta::is_specialization_of_v<T, std::tuple> || meta::is_specialization_of_v<T, std::pair>> { };
7689 
7690  template <typename T>
7692 
7693  template <typename T>
7694  struct is_main_threaded : std::is_base_of<main_reference, T> { };
7695 
7696  template <typename T>
7697  struct is_stack_based : std::is_base_of<stack_reference, T> { };
7698  template <>
7699  struct is_stack_based<variadic_args> : std::true_type { };
7700  template <>
7701  struct is_stack_based<unsafe_function_result> : std::true_type { };
7702  template <>
7703  struct is_stack_based<protected_function_result> : std::true_type { };
7704  template <>
7705  struct is_stack_based<stack_proxy> : std::true_type { };
7706  template <>
7707  struct is_stack_based<stack_proxy_base> : std::true_type { };
7708  template <>
7709  struct is_stack_based<stack_count> : std::true_type { };
7710 
7711  template <typename T>
7713 
7714  template <typename T>
7715  struct is_lua_primitive<T*> : std::true_type { };
7716  template <>
7717  struct is_lua_primitive<unsafe_function_result> : std::true_type { };
7718  template <>
7719  struct is_lua_primitive<protected_function_result> : std::true_type { };
7720  template <typename T>
7721  struct is_lua_primitive<std::reference_wrapper<T>> : std::true_type { };
7722  template <typename T>
7723  struct is_lua_primitive<user<T>> : std::true_type { };
7724  template <typename T>
7726  template <typename T>
7727  struct is_lua_primitive<optional<T>> : std::true_type { };
7728  template <typename T>
7729  struct is_lua_primitive<std::optional<T>> : std::true_type { };
7730  template <typename T>
7731  struct is_lua_primitive<as_table_t<T>> : std::true_type { };
7732  template <typename T>
7733  struct is_lua_primitive<nested<T>> : std::true_type { };
7734  template <>
7735  struct is_lua_primitive<userdata_value> : std::true_type { };
7736  template <>
7737  struct is_lua_primitive<lightuserdata_value> : std::true_type { };
7738  template <>
7739  struct is_lua_primitive<stack_proxy> : std::true_type { };
7740  template <>
7741  struct is_lua_primitive<stack_proxy_base> : std::true_type { };
7742  template <typename T>
7744 
7745  template <typename T>
7746  struct is_lua_index : std::is_integral<T> { };
7747  template <>
7748  struct is_lua_index<raw_index> : std::true_type { };
7749  template <>
7750  struct is_lua_index<absolute_index> : std::true_type { };
7751  template <>
7752  struct is_lua_index<ref_index> : std::true_type { };
7753  template <>
7754  struct is_lua_index<upvalue_index> : std::true_type { };
7755 
7756  template <typename Signature>
7757  struct lua_bind_traits : meta::bind_traits<Signature> {
7758  private:
7760 
7761  public:
7763  static const std::size_t true_arity = base_t::arity;
7766  static const std::size_t true_free_arity = base_t::free_arity;
7768  - meta::count_for<is_transparent_argument, typename base_t::args_list>::value;
7769  };
7770 
7771  template <typename T>
7772  struct is_table : std::false_type { };
7773  template <bool x, typename T>
7774  struct is_table<basic_table_core<x, T>> : std::true_type { };
7775  template <typename T>
7776  struct is_table<basic_lua_table<T>> : std::true_type { };
7777 
7778  template <typename T>
7779  inline constexpr bool is_table_v = is_table<T>::value;
7780 
7781  template <typename T>
7782  struct is_stack_table : std::false_type { };
7783  template <bool x, typename T>
7784  struct is_stack_table<basic_table_core<x, T>> : std::integral_constant<bool, std::is_base_of_v<stack_reference, T>> { };
7785  template <typename T>
7786  struct is_stack_table<basic_lua_table<T>> : std::integral_constant<bool, std::is_base_of_v<stack_reference, T>> { };
7787 
7788  template <typename T>
7790 
7791  template <typename T>
7792  struct is_function : std::false_type { };
7793  template <typename T, bool aligned>
7794  struct is_function<basic_function<T, aligned>> : std::true_type { };
7795  template <typename T, bool aligned, typename Handler>
7796  struct is_function<basic_protected_function<T, aligned, Handler>> : std::true_type { };
7797 
7798  template <typename T>
7800 
7801  template <typename T>
7803 
7804  template <typename T>
7806 
7807  template <typename T>
7808  inline constexpr bool is_userdata_v = is_userdata<T>::value;
7809 
7810  template <typename T>
7811  using is_environment = std::integral_constant<bool, is_userdata_v<T> || is_table_v<T> || meta::is_specialization_of_v<T, basic_environment>>;
7812 
7813  template <typename T>
7815 
7816  template <typename T>
7817  using is_table_like = std::integral_constant<bool, is_table_v<T> || is_environment_v<T> || is_userdata_v<T>>;
7818 
7819  template <typename T>
7820  inline constexpr bool is_table_like_v = is_table_like<T>::value;
7821 
7822  template <typename T>
7824  : std::integral_constant<bool,
7825  (SOL_IS_ON(SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_))
7826  || (std::is_array_v<
7827  meta::unqualified_t<T>> || (!std::is_same_v<meta::unqualified_t<T>, state> && !std::is_same_v<meta::unqualified_t<T>, state_view>))> {
7828  };
7829 
7830  template <typename T>
7831  inline type type_of() {
7832  return lua_type_of<meta::unqualified_t<T>>::value;
7833  }
7834 
7835  namespace detail {
7836  template <typename T>
7837  struct is_non_factory_constructor : std::false_type { };
7838 
7839  template <typename... Args>
7840  struct is_non_factory_constructor<constructors<Args...>> : std::true_type { };
7841 
7842  template <typename... Args>
7843  struct is_non_factory_constructor<constructor_wrapper<Args...>> : std::true_type { };
7844 
7845  template <>
7846  struct is_non_factory_constructor<no_construction> : std::true_type { };
7847 
7848  template <typename T>
7850 
7851  template <typename T>
7853 
7854  template <typename... Args>
7855  struct is_constructor<factory_wrapper<Args...>> : std::true_type { };
7856 
7857  template <typename T>
7858  struct is_constructor<protect_t<T>> : is_constructor<meta::unqualified_t<T>> { };
7859 
7860  template <typename F, typename... Policies>
7861  struct is_constructor<policy_wrapper<F, Policies...>> : is_constructor<meta::unqualified_t<F>> { };
7862 
7863  template <typename T>
7865 
7866  template <typename... Args>
7868 
7869  template <typename... Args>
7870  inline constexpr bool any_is_constructor_v = any_is_constructor<Args...>::value;
7871 
7872  template <typename T>
7873  struct is_destructor : std::false_type { };
7874 
7875  template <typename Fx>
7876  struct is_destructor<destructor_wrapper<Fx>> : std::true_type { };
7877 
7878  template <typename... Args>
7880 
7881  template <typename... Args>
7882  inline constexpr bool any_is_destructor_v = any_is_destructor<Args...>::value;
7883  } // namespace detail
7884 
7885  template <typename T>
7886  using is_lua_c_function = meta::any<std::is_same<lua_CFunction, T>, std::is_same<detail::lua_CFunction_noexcept, T>, std::is_same<lua_CFunction_ref, T>>;
7887 
7888  template <typename T>
7890 
7892  bool default_constructor = true;
7893  bool destructor = true;
7894  bool pairs_operator = true;
7895  bool to_string_operator = true;
7896  bool call_operator = true;
7897  bool less_than_operator = true;
7898  bool less_than_or_equal_to_operator = true;
7899  bool length_operator = true;
7900  bool equal_to_operator = true;
7901  };
7902 
7903 } // namespace sol
7904 
7905 // end of sol/types.hpp
7906 
7907 #include <exception>
7908 #include <cstring>
7909 
7910 #if SOL_IS_ON(SOL_PRINT_ERRORS_I_)
7911 #include <iostream>
7912 #endif
7913 
7914 namespace sol {
7915  // must push a single object to be the error object
7916  // NOTE: the VAST MAJORITY of all Lua libraries -- C or otherwise -- expect a string for the type of error
7917  // break this convention at your own risk
7919 
7920  namespace detail {
7921  inline const char (&default_exception_handler_name())[11] {
7922  static const char name[11] = "sol.\xE2\x98\xA2\xE2\x98\xA2";
7923  return name;
7924  }
7925 
7926  // must push at least 1 object on the stack
7927  inline int default_exception_handler(lua_State* L, optional<const std::exception&>, string_view what) {
7928 #if SOL_IS_ON(SOL_PRINT_ERRORS_I_)
7929  std::cerr << "[sol3] An exception occurred: ";
7930  std::cerr.write(what.data(), what.size());
7931  std::cerr << std::endl;
7932 #endif
7933  lua_pushlstring(L, what.data(), what.size());
7934  return 1;
7935  }
7936 
7937  inline int call_exception_handler(lua_State* L, optional<const std::exception&> maybe_ex, string_view what) {
7939  type t = static_cast<type>(lua_type(L, -1));
7940  if (t != type::lightuserdata) {
7941  lua_pop(L, 1);
7942  return default_exception_handler(L, std::move(maybe_ex), std::move(what));
7943  }
7944  void* vfunc = lua_touserdata(L, -1);
7945  lua_pop(L, 1);
7946  if (vfunc == nullptr) {
7947  return default_exception_handler(L, std::move(maybe_ex), std::move(what));
7948  }
7949  exception_handler_function exfunc = reinterpret_cast<exception_handler_function>(vfunc);
7950  return exfunc(L, std::move(maybe_ex), std::move(what));
7951  }
7952 
7953 #if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
7954  template <lua_CFunction f>
7955  int static_trampoline(lua_State* L) noexcept {
7956  return f(L);
7957  }
7958 
7959 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
7960  template <lua_CFunction_noexcept f>
7961  int static_trampoline_noexcept(lua_State* L) noexcept {
7962  return f(L);
7963  }
7964 #else
7965  template <lua_CFunction f>
7966  int static_trampoline_noexcept(lua_State* L) noexcept {
7967  return f(L);
7968  }
7969 #endif
7970 
7971  template <typename Fx, typename... Args>
7972  int trampoline(lua_State* L, Fx&& f, Args&&... args) noexcept {
7973  return f(L, std::forward<Args>(args)...);
7974  }
7975 
7976  inline int c_trampoline(lua_State* L, lua_CFunction f) noexcept {
7977  return trampoline(L, f);
7978  }
7979 #else
7980 
7982 #if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS_I_)
7983  return f(L);
7984 
7985 #else
7986  try {
7987  return f(L);
7988  }
7989  catch (const char* cs) {
7990  call_exception_handler(L, optional<const std::exception&>(nullopt), string_view(cs));
7991  }
7992  catch (const std::string& s) {
7993  call_exception_handler(L, optional<const std::exception&>(nullopt), string_view(s.c_str(), s.size()));
7994  }
7995  catch (const std::exception& e) {
7996  call_exception_handler(L, optional<const std::exception&>(e), e.what());
7997  }
7998 #if SOL_IS_OFF(SOL_USE_LUAJIT_I_)
7999  // LuaJIT cannot have the catchall when the safe propagation is on
8000  // but LuaJIT will swallow all C++ errors
8001  // if we don't at least catch std::exception ones
8002  catch (...) {
8003  call_exception_handler(L, optional<const std::exception&>(nullopt), "caught (...) exception");
8004  }
8005 #endif // LuaJIT cannot have the catchall, but we must catch std::exceps for it
8006  return lua_error(L);
8007 #endif // Safe exceptions
8008  }
8009 
8010  template <lua_CFunction f>
8012  return lua_cfunction_trampoline(L, f);
8013  }
8014 
8015 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
8016  template <lua_CFunction_noexcept f>
8018  return f(L);
8019  }
8020 #else
8021  template <lua_CFunction f>
8022  int static_trampoline_noexcept(lua_State* L) noexcept {
8023  return f(L);
8024  }
8025 #endif
8026 
8027  template <typename Fx, typename... Args>
8028  int trampoline(lua_State* L, Fx&& f, Args&&... args) {
8029  if constexpr (meta::bind_traits<meta::unqualified_t<Fx>>::is_noexcept) {
8030  return f(L, std::forward<Args>(args)...);
8031  }
8032  else {
8033 #if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS_I_)
8034  return f(L, std::forward<Args>(args)...);
8035 #else
8036  try {
8037  return f(L, std::forward<Args>(args)...);
8038  }
8039  catch (const char* cs) {
8040  call_exception_handler(L, optional<const std::exception&>(nullopt), string_view(cs));
8041  }
8042  catch (const std::string& s) {
8043  call_exception_handler(L, optional<const std::exception&>(nullopt), string_view(s.c_str(), s.size()));
8044  }
8045  catch (const std::exception& e) {
8046  call_exception_handler(L, optional<const std::exception&>(e), e.what());
8047  }
8048 #if SOL_IS_OFF(SOL_USE_LUAJIT_I_)
8049  // LuaJIT cannot have the catchall when the safe propagation is on
8050  // but LuaJIT will swallow all C++ errors
8051  // if we don't at least catch std::exception ones
8052  catch (...) {
8053  call_exception_handler(L, optional<const std::exception&>(nullopt), "caught (...) exception");
8054  }
8055 #endif
8056  return lua_error(L);
8057 #endif
8058  }
8059  }
8060 
8062  return trampoline(L, f);
8063  }
8064 #endif // Exceptions vs. No Exceptions
8065 
8066  template <typename F, F fx>
8068  if constexpr (meta::bind_traits<F>::is_noexcept) {
8069  return static_trampoline_noexcept<fx>(L);
8070  }
8071  else {
8072  return static_trampoline<fx>(L);
8073  }
8074  }
8075  } // namespace detail
8076 
8078  static_assert(sizeof(void*) >= sizeof(exception_handler_function),
8079  "void* storage is too small to transport the exception handler: please file a bug on the sol2 issue tracker to get this looked at!");
8080  void* storage;
8081  std::memcpy(&storage, &exf, sizeof(exception_handler_function));
8082  lua_pushlightuserdata(L, storage);
8084  }
8085 } // namespace sol
8086 
8087 // end of sol/trampoline.hpp
8088 
8089 // beginning of sol/stack_core.hpp
8090 
8091 // beginning of sol/inheritance.hpp
8092 
8093 // beginning of sol/usertype_traits.hpp
8094 
8095 // beginning of sol/demangle.hpp
8096 
8097 #include <string>
8098 #include <array>
8099 #include <cctype>
8100 #if SOL_IS_ON(SOL_MINGW_CCTYPE_IS_POISONED_I_)
8101 extern "C" {
8102 #include <ctype.h>
8103 }
8104 #endif // MinGW is on some stuff
8105 #include <locale>
8106 
8107 namespace sol { namespace detail {
8108  inline constexpr std::array<string_view, 9> removals { { "{anonymous}",
8109  "(anonymous namespace)",
8110  "public:",
8111  "private:",
8112  "protected:",
8113  "struct ",
8114  "class ",
8115  "`anonymous-namespace'",
8116  "`anonymous namespace'" } };
8117 
8118 #if SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_)
8119  inline std::string ctti_get_type_name_from_sig(std::string name) {
8120  // cardinal sins from MINGW
8121  using namespace std;
8122  std::size_t start = name.find_first_of('[');
8123  start = name.find_first_of('=', start);
8124  std::size_t end = name.find_last_of(']');
8125  if (end == std::string::npos)
8126  end = name.size();
8127  if (start == std::string::npos)
8128  start = 0;
8129  if (start < name.size() - 1)
8130  start += 1;
8131  name = name.substr(start, end - start);
8132  start = name.rfind("seperator_mark");
8133  if (start != std::string::npos) {
8134  name.erase(start - 2, name.length());
8135  }
8136  while (!name.empty() && isblank(name.front()))
8137  name.erase(name.begin());
8138  while (!name.empty() && isblank(name.back()))
8139  name.pop_back();
8140 
8141  for (std::size_t r = 0; r < removals.size(); ++r) {
8142  auto found = name.find(removals[r]);
8143  while (found != std::string::npos) {
8144  name.erase(found, removals[r].size());
8145  found = name.find(removals[r]);
8146  }
8147  }
8148 
8149  return name;
8150  }
8151 
8152  template <typename T, class seperator_mark = int>
8153  inline std::string ctti_get_type_name() {
8154  return ctti_get_type_name_from_sig(__PRETTY_FUNCTION__);
8155  }
8156 #elif SOL_IS_ON(SOL_COMPILER_VCXX_I_)
8157  inline std::string ctti_get_type_name_from_sig(std::string name) {
8158  std::size_t start = name.find("get_type_name");
8159  if (start == std::string::npos)
8160  start = 0;
8161  else
8162  start += 13;
8163  if (start < name.size() - 1)
8164  start += 1;
8165  std::size_t end = name.find_last_of('>');
8166  if (end == std::string::npos)
8167  end = name.size();
8168  name = name.substr(start, end - start);
8169  if (name.find("struct", 0) == 0)
8170  name.replace(0, 6, "", 0);
8171  if (name.find("class", 0) == 0)
8172  name.replace(0, 5, "", 0);
8173  while (!name.empty() && isblank(name.front()))
8174  name.erase(name.begin());
8175  while (!name.empty() && isblank(name.back()))
8176  name.pop_back();
8177 
8178  for (std::size_t r = 0; r < removals.size(); ++r) {
8179  auto found = name.find(removals[r]);
8180  while (found != std::string::npos) {
8181  name.erase(found, removals[r].size());
8182  found = name.find(removals[r]);
8183  }
8184  }
8185 
8186  return name;
8187  }
8188 
8189  template <typename T>
8190  std::string ctti_get_type_name() {
8191  return ctti_get_type_name_from_sig(__FUNCSIG__);
8192  }
8193 #else
8194 #error Compiler not supported for demangling
8195 #endif // compilers
8196 
8197  template <typename T>
8199  std::string realname = ctti_get_type_name<T>();
8200  return realname;
8201  }
8202 
8204  // This isn't the most complete but it'll do for now...?
8205  static const std::array<std::string, 10> ops = {
8206  { "operator<", "operator<<", "operator<<=", "operator<=", "operator>", "operator>>", "operator>>=", "operator>=", "operator->", "operator->*" }
8207  };
8208  int level = 0;
8209  std::ptrdiff_t idx = 0;
8210  for (idx = static_cast<std::ptrdiff_t>(realname.empty() ? 0 : realname.size() - 1); idx > 0; --idx) {
8211  if (level == 0 && realname[idx] == ':') {
8212  break;
8213  }
8214  bool isleft = realname[idx] == '<';
8215  bool isright = realname[idx] == '>';
8216  if (!isleft && !isright)
8217  continue;
8218  bool earlybreak = false;
8219  for (const auto& op : ops) {
8220  std::size_t nisop = realname.rfind(op, idx);
8221  if (nisop == std::string::npos)
8222  continue;
8223  std::size_t nisopidx = idx - op.size() + 1;
8224  if (nisop == nisopidx) {
8225  idx = static_cast<std::ptrdiff_t>(nisopidx);
8226  earlybreak = true;
8227  }
8228  break;
8229  }
8230  if (earlybreak) {
8231  continue;
8232  }
8233  level += isleft ? -1 : 1;
8234  }
8235  if (idx > 0) {
8236  realname.erase(0, realname.length() < static_cast<std::size_t>(idx) ? realname.length() : idx + 1);
8237  }
8238  return realname;
8239  }
8240 
8241  template <typename T>
8243  std::string realname = ctti_get_type_name<T>();
8244  return short_demangle_from_type_name(realname);
8245  }
8246 
8247  template <typename T>
8249  static const std::string d = demangle_once<T>();
8250  return d;
8251  }
8252 
8253  template <typename T>
8255  static const std::string d = short_demangle_once<T>();
8256  return d;
8257  }
8258 }} // namespace sol::detail
8259 
8260 // end of sol/demangle.hpp
8261 
8262 namespace sol {
8263 
8264  template <typename T>
8265  struct usertype_traits {
8266  static const std::string& name() {
8267  static const std::string& n = detail::short_demangle<T>();
8268  return n;
8269  }
8270  static const std::string& qualified_name() {
8271  static const std::string& q_n = detail::demangle<T>();
8272  return q_n;
8273  }
8274  static const std::string& metatable() {
8275  static const std::string m = std::string("sol.").append(detail::demangle<T>());
8276  return m;
8277  }
8278  static const std::string& user_metatable() {
8279  static const std::string u_m = std::string("sol.").append(detail::demangle<T>()).append(".user");
8280  return u_m;
8281  }
8282  static const std::string& user_gc_metatable() {
8283  static const std::string u_g_m = std::string("sol.").append(detail::demangle<T>()).append(".user\xE2\x99\xBB");
8284  return u_g_m;
8285  }
8286  static const std::string& gc_table() {
8287  static const std::string g_t = std::string("sol.").append(detail::demangle<T>()).append(".\xE2\x99\xBB");
8288  return g_t;
8289  }
8290  };
8291 
8292 } // namespace sol
8293 
8294 // end of sol/usertype_traits.hpp
8295 
8296 // beginning of sol/unique_usertype_traits.hpp
8297 
8298 #include <memory>
8299 
8300 namespace sol {
8301 
8302  template <typename T>
8303  struct unique_usertype_traits {
8304  typedef T type;
8305  typedef T actual_type;
8306  template <typename X>
8308 
8309  static const bool value = false;
8310 
8311  template <typename U>
8312  static bool is_null(U&&) {
8313  return false;
8314  }
8315 
8316  template <typename U>
8317  static auto get(U&& value) {
8318  return std::addressof(detail::deref(value));
8319  }
8320  };
8321 
8322  template <typename T>
8323  struct unique_usertype_traits<std::shared_ptr<T>> {
8324  typedef T type;
8325  typedef std::shared_ptr<T> actual_type;
8326  // rebind is non-void
8327  // if and only if unique usertype
8328  // is cast-capable
8329  template <typename X>
8330  using rebind_base = std::shared_ptr<X>;
8331 
8332  static const bool value = true;
8333 
8334  static bool is_null(const actual_type& p) {
8335  return p == nullptr;
8336  }
8337 
8338  static type* get(const actual_type& p) {
8339  return p.get();
8340  }
8341  };
8342 
8343  template <typename T, typename D>
8344  struct unique_usertype_traits<std::unique_ptr<T, D>> {
8345  using type = T;
8346  using actual_type = std::unique_ptr<T, D>;
8347 
8348  static const bool value = true;
8349 
8350  static bool is_null(const actual_type& p) {
8351  return p == nullptr;
8352  }
8353 
8354  static type* get(const actual_type& p) {
8355  return p.get();
8356  }
8357  };
8358 
8359  template <typename T>
8360  struct is_unique_usertype : std::integral_constant<bool, unique_usertype_traits<T>::value> {};
8361 
8362  template <typename T>
8364 
8365  namespace detail {
8366  template <typename T, typename Rebind = void>
8367  using is_base_rebindable_test = typename T::template rebind_base<Rebind>;
8368  }
8369 
8370  template <typename T>
8372 
8373  template <typename T>
8375 
8376  namespace detail {
8377  template <typename T, typename = void>
8378  struct is_base_rebindable_non_void_sfinae : std::false_type {};
8379 
8380  template <typename T>
8381  struct is_base_rebindable_non_void_sfinae<T, std::enable_if_t<is_base_rebindable_v<T>>>
8382  : std::integral_constant<bool, !std::is_void_v<typename T::template rebind_base<void>>> {};
8383  } // namespace detail
8384 
8385  template <typename T>
8387 
8388  template <typename T>
8390 
8391 } // namespace sol
8392 
8393 // end of sol/unique_usertype_traits.hpp
8394 
8395 namespace sol {
8396  template <typename... Args>
8397  struct base_list {};
8398  template <typename... Args>
8399  using bases = base_list<Args...>;
8400 
8403 
8404  template <typename... Args>
8405  struct is_to_stringable<base_list<Args...>> : std::false_type {};
8406 
8407  namespace detail {
8408 
8409  inline decltype(auto) base_class_check_key() {
8410  static const auto& key = "class_check";
8411  return key;
8412  }
8413 
8414  inline decltype(auto) base_class_cast_key() {
8415  static const auto& key = "class_cast";
8416  return key;
8417  }
8418 
8419  inline decltype(auto) base_class_index_propogation_key() {
8420  static const auto& key = u8"\xF0\x9F\x8C\xB2.index";
8421  return key;
8422  }
8423 
8424  inline decltype(auto) base_class_new_index_propogation_key() {
8425  static const auto& key = u8"\xF0\x9F\x8C\xB2.new_index";
8426  return key;
8427  }
8428 
8429  template <typename T>
8430  struct inheritance {
8431  typedef typename base<T>::type bases_t;
8432 
8433  static bool type_check_bases(types<>, const string_view&) {
8434  return false;
8435  }
8436 
8437  template <typename Base, typename... Args>
8439  return ti == usertype_traits<Base>::qualified_name() || type_check_bases(types<Args...>(), ti);
8440  }
8441 
8442  static bool type_check(const string_view& ti) {
8443  return ti == usertype_traits<T>::qualified_name() || type_check_bases(bases_t(), ti);
8444  }
8445 
8446  template <typename ...Bases>
8447  static bool type_check_with(const string_view& ti) {
8448  return ti == usertype_traits<T>::qualified_name() || type_check_bases(types<Bases...>(), ti);
8449  }
8450 
8451  static void* type_cast_bases(types<>, T*, const string_view&) {
8452  return nullptr;
8453  }
8454 
8455  template <typename Base, typename... Args>
8456  static void* type_cast_bases(types<Base, Args...>, T* data, const string_view& ti) {
8457  // Make sure to convert to T first, and then dynamic cast to the proper type
8458  return ti != usertype_traits<Base>::qualified_name() ? type_cast_bases(types<Args...>(), data, ti) : static_cast<void*>(static_cast<Base*>(data));
8459  }
8460 
8461  static void* type_cast(void* voiddata, const string_view& ti) {
8462  T* data = static_cast<T*>(voiddata);
8463  return static_cast<void*>(ti != usertype_traits<T>::qualified_name() ? type_cast_bases(bases_t(), data, ti) : data);
8464  }
8465 
8466  template <typename... Bases>
8467  static void* type_cast_with(void* voiddata, const string_view& ti) {
8468  T* data = static_cast<T*>(voiddata);
8469  return static_cast<void*>(ti != usertype_traits<T>::qualified_name() ? type_cast_bases(types<Bases...>(), data, ti) : data);
8470  }
8471 
8472  template <typename U>
8473  static bool type_unique_cast_bases(types<>, void*, void*, const string_view&) {
8474  return 0;
8475  }
8476 
8477  template <typename U, typename Base, typename... Args>
8478  static int type_unique_cast_bases(types<Base, Args...>, void* source_data, void* target_data, const string_view& ti) {
8479  using uu_traits = unique_usertype_traits<U>;
8480  using base_ptr = typename uu_traits::template rebind_base<Base>;
8482  if (base_ti == ti) {
8483  if (target_data != nullptr) {
8484  U* source = static_cast<U*>(source_data);
8485  base_ptr* target = static_cast<base_ptr*>(target_data);
8486  // perform proper derived -> base conversion
8487  *target = *source;
8488  }
8489  return 2;
8490  }
8491  return type_unique_cast_bases<U>(types<Args...>(), source_data, target_data, ti);
8492  }
8493 
8494  template <typename U>
8495  static int type_unique_cast(void* source_data, void* target_data, const string_view& ti, const string_view& rebind_ti) {
8496  typedef unique_usertype_traits<U> uu_traits;
8497  if constexpr (is_base_rebindable_v<uu_traits>) {
8498  typedef typename uu_traits::template rebind_base<void> rebind_t;
8499  typedef meta::conditional_t<std::is_void<rebind_t>::value, types<>, bases_t> cond_bases_t;
8501  if (rebind_ti != this_rebind_ti) {
8502  // this is not even of the same unique type
8503  return 0;
8504  }
8506  if (ti == this_ti) {
8507  // direct match, return 1
8508  return 1;
8509  }
8510  return type_unique_cast_bases<U>(cond_bases_t(), source_data, target_data, ti);
8511  }
8512  else {
8513  (void)rebind_ti;
8515  if (ti == this_ti) {
8516  // direct match, return 1
8517  return 1;
8518  }
8519  return type_unique_cast_bases<U>(types<>(), source_data, target_data, ti);
8520  }
8521  }
8522 
8523  template <typename U, typename... Bases>
8524  static int type_unique_cast_with(void* source_data, void* target_data, const string_view& ti, const string_view& rebind_ti) {
8525  using uc_bases_t = types<Bases...>;
8526  typedef unique_usertype_traits<U> uu_traits;
8527  if constexpr (is_base_rebindable_v<uu_traits>) {
8528  using rebind_t = typename uu_traits::template rebind_base<void>;
8529  using cond_bases_t = meta::conditional_t<std::is_void<rebind_t>::value, types<>, uc_bases_t>;
8531  if (rebind_ti != this_rebind_ti) {
8532  // this is not even of the same unique type
8533  return 0;
8534  }
8536  if (ti == this_ti) {
8537  // direct match, return 1
8538  return 1;
8539  }
8540  return type_unique_cast_bases<U>(cond_bases_t(), source_data, target_data, ti);
8541  }
8542  else {
8543  (void)rebind_ti;
8545  if (ti == this_ti) {
8546  // direct match, return 1
8547  return 1;
8548  }
8549  return type_unique_cast_bases<U>(types<>(), source_data, target_data, ti);
8550  }
8551  }
8552  };
8553 
8557  } // namespace detail
8558 } // namespace sol
8559 
8560 // end of sol/inheritance.hpp
8561 
8562 // beginning of sol/error_handler.hpp
8563 
8564 #include <cstdio>
8565 
8566 namespace sol {
8567 
8568  namespace detail {
8569  constexpr const char* not_a_number = "not a numeric type";
8570  constexpr const char* not_a_number_or_number_string = "not a numeric type or numeric string";
8571  constexpr const char* not_a_number_integral = "not a numeric type that fits exactly an integer (number maybe has significant decimals)";
8572  constexpr const char* not_a_number_or_number_string_integral
8573  = "not a numeric type or a numeric string that fits exactly an integer (e.g. number maybe has significant decimals)";
8574 
8575  constexpr const char* not_enough_stack_space = "not enough space left on Lua stack";
8576  constexpr const char* not_enough_stack_space_floating = "not enough space left on Lua stack for a floating point number";
8577  constexpr const char* not_enough_stack_space_integral = "not enough space left on Lua stack for an integral number";
8578  constexpr const char* not_enough_stack_space_string = "not enough space left on Lua stack for a string";
8579  constexpr const char* not_enough_stack_space_meta_function_name = "not enough space left on Lua stack for the name of a meta_function";
8580  constexpr const char* not_enough_stack_space_userdata = "not enough space left on Lua stack to create a sol3 userdata";
8581  constexpr const char* not_enough_stack_space_generic = "not enough space left on Lua stack to push valuees";
8582  constexpr const char* not_enough_stack_space_environment = "not enough space left on Lua stack to retrieve environment";
8583  constexpr const char* protected_function_error = "caught (...) unknown error during protected_function call";
8584 
8585  inline void accumulate_and_mark(const std::string& n, std::string& aux_message, int& marker) {
8586  if (marker > 0) {
8587  aux_message += ", ";
8588  }
8589  aux_message += n;
8590  ++marker;
8591  }
8592  } // namespace detail
8593 
8594  inline std::string associated_type_name(lua_State* L, int index, type t) {
8595  switch (t) {
8596  case type::poly:
8597  return "anything";
8598  case type::userdata: {
8599 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
8600  luaL_checkstack(L, 2, "not enough space to push get the type name");
8601 #endif // make sure stack doesn't overflow
8602  if (lua_getmetatable(L, index) == 0) {
8603  break;
8604  }
8605  lua_pushlstring(L, "__name", 6);
8606  lua_rawget(L, -2);
8607  size_t sz;
8608  const char* name = lua_tolstring(L, -1, &sz);
8609  std::string tn(name, static_cast<std::string::size_type>(sz));
8610  lua_pop(L, 2);
8611  return tn;
8612  }
8613  default:
8614  break;
8615  }
8616  return lua_typename(L, static_cast<int>(t));
8617  }
8618 
8619  inline int push_type_panic_string(lua_State* L, int index, type expected, type actual, string_view message, string_view aux_message) noexcept {
8620  const char* err = message.size() == 0
8621  ? (aux_message.size() == 0 ? "stack index %d, expected %s, received %s" : "stack index %d, expected %s, received %s: %s")
8622  : "stack index %d, expected %s, received %s: %s %s";
8623  const char* type_name = expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected));
8624  {
8625  std::string actual_name = associated_type_name(L, index, actual);
8626  lua_pushfstring(L, err, index, type_name, actual_name.c_str(), message.data(), aux_message.data());
8627  }
8628  return 1;
8629  }
8630 
8631  inline int type_panic_string(lua_State* L, int index, type expected, type actual, string_view message = "") noexcept(false) {
8632  push_type_panic_string(L, index, expected, actual, message, "");
8633  return lua_error(L);
8634  }
8635 
8636  inline int type_panic_c_str(lua_State* L, int index, type expected, type actual, const char* message = nullptr) noexcept(false) {
8637  push_type_panic_string(L, index, expected, actual, message == nullptr ? "" : message, "");
8638  return lua_error(L);
8639  }
8640 
8641  struct type_panic_t {
8642  int operator()(lua_State* L, int index, type expected, type actual) const noexcept(false) {
8643  return type_panic_c_str(L, index, expected, actual, nullptr);
8644  }
8645  int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
8646  return type_panic_c_str(L, index, expected, actual, message.data());
8647  }
8648  };
8649 
8651 
8653  int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
8654  push_type_panic_string(L, index, expected, actual, message, "(type check failed in constructor)");
8655  return lua_error(L);
8656  }
8657  };
8658 
8659  template <typename F = void>
8661  int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
8662  push_type_panic_string(L, index, expected, actual, message, "(bad argument to variable or function call)");
8663  return lua_error(L);
8664  }
8665  };
8666 
8667  template <typename R, typename... Args>
8668  struct argument_handler<types<R, Args...>> {
8669  int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
8670  {
8671  std::string aux_message = "(bad argument into '";
8672  aux_message += detail::demangle<R>();
8673  aux_message += "(";
8674  int marker = 0;
8675  (void)detail::swallow { int(), (detail::accumulate_and_mark(detail::demangle<Args>(), aux_message, marker), int())... };
8676  aux_message += ")')";
8677  push_type_panic_string(L, index, expected, actual, message, aux_message);
8678  }
8679  return lua_error(L);
8680  }
8681  };
8682 
8683  // Specify this function as the handler for lua::check if you know there's nothing wrong
8684  inline int no_panic(lua_State*, int, type, type, const char* = nullptr) noexcept {
8685  return 0;
8686  }
8687 
8688  inline void type_error(lua_State* L, int expected, int actual) noexcept(false) {
8689  luaL_error(L, "expected %s, received %s", lua_typename(L, expected), lua_typename(L, actual));
8690  }
8691 
8692  inline void type_error(lua_State* L, type expected, type actual) noexcept(false) {
8693  type_error(L, static_cast<int>(expected), static_cast<int>(actual));
8694  }
8695 
8696  inline void type_assert(lua_State* L, int index, type expected, type actual) noexcept(false) {
8697  if (expected != type::poly && expected != actual) {
8698  type_panic_c_str(L, index, expected, actual, nullptr);
8699  }
8700  }
8701 
8702  inline void type_assert(lua_State* L, int index, type expected) {
8703  type actual = type_of(L, index);
8704  type_assert(L, index, expected, actual);
8705  }
8706 
8707 } // namespace sol
8708 
8709 // end of sol/error_handler.hpp
8710 
8711 // beginning of sol/reference.hpp
8712 
8713 // beginning of sol/stack_reference.hpp
8714 
8715 namespace sol {
8716  namespace detail {
8717  inline bool xmovable(lua_State* leftL, lua_State* rightL) {
8718  if (rightL == nullptr || leftL == nullptr || leftL == rightL) {
8719  return false;
8720  }
8721  const void* leftregistry = lua_topointer(leftL, LUA_REGISTRYINDEX);
8722  const void* rightregistry = lua_topointer(rightL, LUA_REGISTRYINDEX);
8723  return leftregistry == rightregistry;
8724  }
8725  } // namespace detail
8726 
8728  private:
8729  friend class stack_reference;
8730 
8731  int index = 0;
8732 
8733  int registry_index() const noexcept {
8734  return LUA_NOREF;
8735  }
8736 
8737  public:
8738  stateless_stack_reference() noexcept = default;
8741  }
8743  }
8745  }
8747  }
8749  }
8750  stateless_stack_reference(lua_State*, ref_index) noexcept = delete;
8751  stateless_stack_reference(ref_index) noexcept = delete;
8752  stateless_stack_reference(const reference&) noexcept = delete;
8753  stateless_stack_reference(const stateless_stack_reference&) noexcept = default;
8754  stateless_stack_reference(stateless_stack_reference&& o) noexcept = default;
8755  stateless_stack_reference& operator=(stateless_stack_reference&&) noexcept = default;
8756  stateless_stack_reference& operator=(const stateless_stack_reference&) noexcept = default;
8757 
8758  int push(lua_State* L) const noexcept {
8759 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
8760  luaL_checkstack(L, 1, "not enough Lua stack space to push a single reference value");
8761 #endif // make sure stack doesn't overflow
8762  lua_pushvalue(L, index);
8763  return 1;
8764  }
8765 
8766  void pop(lua_State* L, int n = 1) const noexcept {
8767  lua_pop(L, n);
8768  }
8769 
8770  int stack_index() const noexcept {
8771  return index;
8772  }
8773 
8774  const void* pointer(lua_State* L) const noexcept {
8775  const void* vp = lua_topointer(L, stack_index());
8776  return vp;
8777  }
8778 
8779  type get_type(lua_State* L) const noexcept {
8780  int result = lua_type(L, index);
8781  return static_cast<type>(result);
8782  }
8783 
8784  bool valid(lua_State* L) const noexcept {
8785  type t = get_type(L);
8786  return t != type::lua_nil && t != type::none;
8787  }
8788 
8789  void abandon(lua_State* = nullptr) {
8790  index = 0;
8791  }
8792  };
8793 
8795  private:
8796  lua_State* luastate = nullptr;
8797 
8798  public:
8799  stack_reference() noexcept = default;
8801  : stack_reference() {};
8802  stack_reference(lua_State* L, lua_nil_t) noexcept : stateless_stack_reference(L, 0), luastate(L) {
8803  }
8804  stack_reference(lua_State* L, int i) noexcept : stateless_stack_reference(L, i), luastate(L) {
8805  }
8807  }
8808  stack_reference(lua_State* L, raw_index i) noexcept : stateless_stack_reference(L, i), luastate(L) {
8809  }
8810  stack_reference(lua_State* L, ref_index i) noexcept = delete;
8811  stack_reference(lua_State* L, const reference& r) noexcept = delete;
8813  : luastate(L) {
8814  if (!r.valid()) {
8815  index = 0;
8816  return;
8817  }
8818  int i = r.stack_index();
8819  if (detail::xmovable(lua_state(), r.lua_state())) {
8820 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
8821  luaL_checkstack(L, 1, "not enough Lua stack space to push a single reference value");
8822 #endif // make sure stack doesn't overflow
8823  lua_pushvalue(r.lua_state(), r.index);
8824  lua_xmove(r.lua_state(), luastate, 1);
8825  i = absolute_index(luastate, -1);
8826  }
8827  index = i;
8828  }
8829  stack_reference(stack_reference&& o) noexcept = default;
8830  stack_reference& operator=(stack_reference&&) noexcept = default;
8831  stack_reference(const stack_reference&) noexcept = default;
8832  stack_reference& operator=(const stack_reference&) noexcept = default;
8833 
8834  int push() const noexcept {
8835  return push(lua_state());
8836  }
8837 
8838  int push(lua_State* Ls) const noexcept {
8840  }
8841 
8842  void pop() const noexcept {
8843  pop(lua_state());
8844  }
8845 
8846  void pop(lua_State* Ls, int n = 1) const noexcept {
8848  }
8849 
8850  const void* pointer() const noexcept {
8851  return stateless_stack_reference::pointer(lua_state());
8852  }
8853 
8854  type get_type() const noexcept {
8855  return stateless_stack_reference::get_type(lua_state());
8856  }
8857 
8858  lua_State* lua_state() const noexcept {
8859  return luastate;
8860  }
8861 
8862  bool valid() const noexcept {
8863  return stateless_stack_reference::valid(lua_state());
8864  }
8865 
8866  void abandon () {
8868  }
8869  };
8870 
8871  inline bool operator==(const stack_reference& l, const stack_reference& r) {
8872  return lua_compare(l.lua_state(), l.stack_index(), r.stack_index(), LUA_OPEQ) == 0;
8873  }
8874 
8875  inline bool operator!=(const stack_reference& l, const stack_reference& r) {
8876  return !operator==(l, r);
8877  }
8878 
8879  inline bool operator==(const stack_reference& lhs, const lua_nil_t&) {
8880  return !lhs.valid();
8881  }
8882 
8883  inline bool operator==(const lua_nil_t&, const stack_reference& rhs) {
8884  return !rhs.valid();
8885  }
8886 
8887  inline bool operator!=(const stack_reference& lhs, const lua_nil_t&) {
8888  return lhs.valid();
8889  }
8890 
8891  inline bool operator!=(const lua_nil_t&, const stack_reference& rhs) {
8892  return rhs.valid();
8893  }
8894 
8896  bool operator()(const lua_nil_t& lhs, const stack_reference& rhs) const {
8897  return lhs == rhs;
8898  }
8899 
8900  bool operator()(const stack_reference& lhs, const lua_nil_t& rhs) const {
8901  return lhs == rhs;
8902  }
8903 
8904  bool operator()(const stack_reference& lhs, const stack_reference& rhs) const {
8905  return lhs == rhs;
8906  }
8907  };
8908 
8911  typedef std::size_t result_type;
8912 
8913  result_type operator()(const argument_type& lhs) const {
8914  std::hash<const void*> h;
8915  return h(lhs.pointer());
8916  }
8917  };
8918 } // namespace sol
8919 
8920 // end of sol/stack_reference.hpp
8921 
8922 #include <functional>
8923 
8924 namespace sol {
8925  namespace detail {
8926  inline const char (&default_main_thread_name())[9] {
8927  static const char name[9] = "sol.\xF0\x9F\x93\x8C";
8928  return name;
8929  }
8930  } // namespace detail
8931 
8932  namespace stack {
8933  inline void remove(lua_State* L, int rawindex, int count) {
8934  if (count < 1)
8935  return;
8936  int top = lua_gettop(L);
8937  if (top < 1) {
8938  return;
8939  }
8940  if (rawindex == -count || top == rawindex) {
8941  // Slice them right off the top
8942  lua_pop(L, static_cast<int>(count));
8943  return;
8944  }
8945 
8946  // Remove each item one at a time using stack operations
8947  // Probably slower, maybe, haven't benchmarked,
8948  // but necessary
8949  int index = lua_absindex(L, rawindex);
8950  if (index < 0) {
8951  index = lua_gettop(L) + (index + 1);
8952  }
8953  int last = index + count;
8954  for (int i = index; i < last; ++i) {
8955  lua_remove(L, index);
8956  }
8957  }
8958 
8961  int index;
8962  int count;
8963  push_popper_at(lua_State* luastate, int index = -1, int count = 1) : L(luastate), index(index), count(count) {
8964  }
8966  remove(L, index, count);
8967  }
8968  };
8969 
8970  template <bool top_level>
8971  struct push_popper_n {
8973  int t;
8974  push_popper_n(lua_State* luastate, int x) : L(luastate), t(x) {
8975  }
8976  push_popper_n(const push_popper_n&) = delete;
8977  push_popper_n(push_popper_n&&) = default;
8978  push_popper_n& operator=(const push_popper_n&) = delete;
8979  push_popper_n& operator=(push_popper_n&&) = default;
8981  lua_pop(L, t);
8982  }
8983  };
8984 
8985  template <>
8986  struct push_popper_n<true> {
8988  }
8989  };
8990 
8991  template <bool, typename T, typename = void>
8992  struct push_popper {
8994  T t;
8995  int idx;
8996 
8997  push_popper(T x) : t(x), idx(lua_absindex(t.lua_state(), -t.push())) {
8998  }
8999 
9000  int index_of(const Tu&) {
9001  return idx;
9002  }
9003 
9005  t.pop();
9006  }
9007  };
9008 
9009  template <typename T, typename C>
9010  struct push_popper<true, T, C> {
9012 
9014  }
9015 
9016  int index_of(const Tu&) {
9017  return -1;
9018  }
9019 
9021  }
9022  };
9023 
9024  template <typename T>
9025  struct push_popper<false, T, std::enable_if_t<is_stack_based_v<meta::unqualified_t<T>>>> {
9027 
9029  }
9030 
9031  int index_of(const Tu& r) {
9032  return r.stack_index();
9033  }
9034 
9036  }
9037  };
9038 
9039  template <bool top_level = false, typename T>
9041  return push_popper<top_level, T>(std::forward<T>(x));
9042  }
9043 
9044  template <typename T>
9046  int c = x.push();
9047  lua_State* L = x.lua_state();
9048  return push_popper_at(L, lua_absindex(L, -c), c);
9049  }
9050 
9051  template <bool top_level = false>
9053  return push_popper_n<top_level>(L, x);
9054  }
9055  } // namespace stack
9056 
9057  inline lua_State* main_thread(lua_State* L, lua_State* backup_if_unsupported = nullptr) {
9058 #if SOL_LUA_VESION_I_ < 502
9059  if (L == nullptr)
9060  return backup_if_unsupported;
9062  auto pp = stack::pop_n(L, 1);
9063  if (type_of(L, -1) == type::thread) {
9064  return lua_tothread(L, -1);
9065  }
9066  return backup_if_unsupported;
9067 #else
9068  if (L == nullptr)
9069  return backup_if_unsupported;
9071  lua_State* Lmain = lua_tothread(L, -1);
9072  lua_pop(L, 1);
9073  return Lmain;
9074 #endif // Lua 5.2+ has the main thread unqualified_getter
9075  }
9076 
9077  namespace detail {
9078  struct global_tag {
9079  } const global_ {};
9080  struct no_safety_tag {
9081  } const no_safety {};
9082 
9083  template <bool b>
9084  inline lua_State* pick_main_thread(lua_State* L, lua_State* backup_if_unsupported = nullptr) {
9085  (void)L;
9086  (void)backup_if_unsupported;
9087  if (b) {
9088  return main_thread(L, backup_if_unsupported);
9089  }
9090  return L;
9091  }
9092  } // namespace detail
9093 
9095  private:
9096  template <bool o_main_only>
9097  friend class basic_reference;
9098 
9099  int ref = LUA_NOREF;
9100 
9101  int copy(lua_State* L) const noexcept {
9102  if (ref == LUA_NOREF)
9103  return LUA_NOREF;
9104  push(L);
9105  return luaL_ref(L, LUA_REGISTRYINDEX);
9106  }
9107 
9109  if (valid(L)) {
9110  deref(L);
9111  }
9112  ref = r.copy(L);
9113  return rL;
9114  }
9115 
9117  if (valid(L)) {
9118  deref(L);
9119  }
9120  ref = r.ref;
9121  r.ref = LUA_NOREF;
9122  return rL;
9123  }
9124 
9125  protected:
9126  int stack_index() const noexcept {
9127  return -1;
9128  }
9129 
9131 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
9132  luaL_checkstack(L, 1, "not enough Lua stack space to push this reference value");
9133 #endif // make sure stack doesn't overflow
9135  ref = luaL_ref(L, LUA_REGISTRYINDEX);
9136  }
9137 
9138  stateless_reference(int raw_ref_index) noexcept : ref(raw_ref_index) {
9139  }
9140 
9141  public:
9142  stateless_reference() noexcept = default;
9144  }
9145  stateless_reference(const stack_reference& r) noexcept : stateless_reference(r.lua_state(), r.stack_index()) {
9146  }
9147  stateless_reference(stack_reference&& r) noexcept : stateless_reference(r.lua_state(), r.stack_index()) {
9148  }
9150  if (r.ref == LUA_REFNIL) {
9151  ref = LUA_REFNIL;
9152  return;
9153  }
9154  if (r.ref == LUA_NOREF || L == nullptr) {
9155  ref = LUA_NOREF;
9156  return;
9157  }
9158  ref = r.copy(L);
9159  }
9160 
9162  if (r.ref == LUA_REFNIL) {
9163  ref = LUA_REFNIL;
9164  return;
9165  }
9166  if (r.ref == LUA_NOREF || L == nullptr) {
9167  ref = LUA_NOREF;
9168  return;
9169  }
9170  ref = r.ref;
9171  r.ref = LUA_NOREF;
9172  }
9173 
9175  if (L == nullptr || r.lua_state() == nullptr || r.get_type() == type::none) {
9176  ref = LUA_NOREF;
9177  return;
9178  }
9179  if (r.get_type() == type::lua_nil) {
9180  ref = LUA_REFNIL;
9181  return;
9182  }
9183  if (L != r.lua_state() && !detail::xmovable(L, r.lua_state())) {
9184  return;
9185  }
9186  r.push(L);
9187  ref = luaL_ref(L, LUA_REGISTRYINDEX);
9188  }
9189 
9190  stateless_reference(lua_State* L, int index = -1) noexcept {
9191  // use L to stick with that state's execution stack
9192 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
9193  luaL_checkstack(L, 1, "not enough Lua stack space to push this reference value");
9194 #endif // make sure stack doesn't overflow
9195  lua_pushvalue(L, index);
9196  ref = luaL_ref(L, LUA_REGISTRYINDEX);
9197  }
9199  lua_rawgeti(L, LUA_REGISTRYINDEX, index.index);
9200  ref = luaL_ref(L, LUA_REGISTRYINDEX);
9201  }
9203  }
9204 
9205  ~stateless_reference() noexcept = default;
9206 
9207  stateless_reference(const stateless_reference& o) noexcept = delete;
9208  stateless_reference& operator=(const stateless_reference& r) noexcept = delete;
9209 
9210  stateless_reference(stateless_reference&& o) noexcept : ref(o.ref) {
9211  o.ref = LUA_NOREF;
9212  }
9213 
9215  ref = o.ref;
9216  o.ref = LUA_NOREF;
9217  return *this;
9218  }
9219 
9220  int push(lua_State* L) const noexcept {
9221 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
9222  luaL_checkstack(L, 1, "not enough Lua stack space to push this reference value");
9223 #endif // make sure stack doesn't overflow
9224  lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
9225  return 1;
9226  }
9227 
9228  void pop(lua_State* L, int n = 1) const noexcept {
9229  lua_pop(L, n);
9230  }
9231 
9232  int registry_index() const noexcept {
9233  return ref;
9234  }
9235 
9236  bool valid(lua_State*) const noexcept {
9237  return !(ref == LUA_NOREF || ref == LUA_REFNIL);
9238  }
9239 
9240  const void* pointer(lua_State* L) const noexcept {
9241  int si = push(L);
9242  const void* vp = lua_topointer(L, -si);
9243  lua_pop(L, si);
9244  return vp;
9245  }
9246 
9247  type get_type(lua_State* L) const noexcept {
9248  int p = push(L);
9249  int result = lua_type(L, -1);
9250  pop(L, p);
9251  return static_cast<type>(result);
9252  }
9253 
9254  void abandon(lua_State* = nullptr) {
9255  ref = LUA_NOREF;
9256  }
9257 
9258  void deref(lua_State* L) const noexcept {
9259  luaL_unref(L, LUA_REGISTRYINDEX, ref);
9260  }
9261  };
9262 
9263  template <bool main_only = false>
9264  class basic_reference : public stateless_reference {
9265  private:
9266  template <bool o_main_only>
9267  friend class basic_reference;
9268  lua_State* luastate = nullptr; // non-owning
9269 
9270  template <bool r_main_only>
9272  if (valid()) {
9273  deref();
9274  }
9275  if (r.ref == LUA_REFNIL) {
9276  luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
9277  ref = LUA_REFNIL;
9278  return;
9279  }
9280  if (r.ref == LUA_NOREF) {
9281  luastate = r.luastate;
9282  ref = LUA_NOREF;
9283  return;
9284  }
9285  if (detail::xmovable(lua_state(), r.lua_state())) {
9286  r.push(lua_state());
9287  ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
9288  return;
9289  }
9290  luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
9291  ref = r.copy();
9292  }
9293 
9294  template <bool r_main_only>
9296  if (valid()) {
9297  deref();
9298  }
9299  if (r.ref == LUA_REFNIL) {
9300  luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
9301  ref = LUA_REFNIL;
9302  return;
9303  }
9304  if (r.ref == LUA_NOREF) {
9305  luastate = r.luastate;
9306  ref = LUA_NOREF;
9307  return;
9308  }
9309  if (detail::xmovable(lua_state(), r.lua_state())) {
9310  r.push(lua_state());
9311  ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
9312  return;
9313  }
9314 
9315  luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
9316  ref = r.ref;
9317  r.ref = LUA_NOREF;
9318  r.luastate = nullptr;
9319  }
9320 
9321  protected:
9323  : basic_reference(detail::pick_main_thread<main_only>(L, L), detail::global_, detail::global_) {
9324  }
9325 
9327  }
9328 
9329  basic_reference(lua_State* oL, const basic_reference<!main_only>& o) noexcept : stateless_reference(oL, o), luastate(oL) {
9330  }
9331 
9332  void deref() const noexcept {
9333  return stateless_reference::deref(lua_state());
9334  }
9335 
9336  int copy() const noexcept {
9337  return copy(lua_state());
9338  }
9339 
9340  int copy(lua_State* L) const noexcept {
9341  return stateless_reference::copy(L);
9342  }
9343 
9344  public:
9345  basic_reference() noexcept = default;
9347  }
9348  basic_reference(const stack_reference& r) noexcept : basic_reference(r.lua_state(), r.stack_index()) {
9349  }
9350  basic_reference(stack_reference&& r) noexcept : basic_reference(r.lua_state(), r.stack_index()) {
9351  }
9352  template <bool r_main_only>
9353  basic_reference(lua_State* L, const basic_reference<r_main_only>& r) noexcept : luastate(detail::pick_main_thread<main_only>(L, L)) {
9354  if (r.ref == LUA_REFNIL) {
9355  ref = LUA_REFNIL;
9356  return;
9357  }
9358  if (r.ref == LUA_NOREF || lua_state() == nullptr) {
9359  ref = LUA_NOREF;
9360  return;
9361  }
9362  if (detail::xmovable(lua_state(), r.lua_state())) {
9363  r.push(lua_state());
9364  ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
9365  return;
9366  }
9367  ref = r.copy();
9368  }
9369 
9370  template <bool r_main_only>
9371  basic_reference(lua_State* L, basic_reference<r_main_only>&& r) noexcept : luastate(detail::pick_main_thread<main_only>(L, L)) {
9372  if (r.ref == LUA_REFNIL) {
9373  ref = LUA_REFNIL;
9374  return;
9375  }
9376  if (r.ref == LUA_NOREF || lua_state() == nullptr) {
9377  ref = LUA_NOREF;
9378  return;
9379  }
9380  if (detail::xmovable(lua_state(), r.lua_state())) {
9381  r.push(lua_state());
9382  ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
9383  return;
9384  }
9385  ref = r.ref;
9386  r.ref = LUA_NOREF;
9387  r.luastate = nullptr;
9388  }
9389 
9390  basic_reference(lua_State* L, const stack_reference& r) noexcept : luastate(detail::pick_main_thread<main_only>(L, L)) {
9391  if (lua_state() == nullptr || r.lua_state() == nullptr || r.get_type() == type::none) {
9392  ref = LUA_NOREF;
9393  return;
9394  }
9395  if (r.get_type() == type::lua_nil) {
9396  ref = LUA_REFNIL;
9397  return;
9398  }
9399  if (lua_state() != r.lua_state() && !detail::xmovable(lua_state(), r.lua_state())) {
9400  return;
9401  }
9402  r.push(lua_state());
9403  ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
9404  }
9405  basic_reference(lua_State* L, int index = -1) noexcept : luastate(detail::pick_main_thread<main_only>(L, L)) {
9406  // use L to stick with that state's execution stack
9407 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
9408  luaL_checkstack(L, 1, "not enough Lua stack space to push this reference value");
9409 #endif // make sure stack doesn't overflow
9410  lua_pushvalue(L, index);
9411  ref = luaL_ref(L, LUA_REGISTRYINDEX);
9412  }
9413  basic_reference(lua_State* L, ref_index index) noexcept : luastate(detail::pick_main_thread<main_only>(L, L)) {
9414  lua_rawgeti(lua_state(), LUA_REGISTRYINDEX, index.index);
9415  ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
9416  }
9417  basic_reference(lua_State* L, lua_nil_t) noexcept : luastate(detail::pick_main_thread<main_only>(L, L)) {
9418  }
9419 
9420  ~basic_reference() noexcept {
9421  if (lua_state() == nullptr || ref == LUA_NOREF)
9422  return;
9423  deref();
9424  }
9425 
9426  basic_reference(const basic_reference& o) noexcept : stateless_reference(o.copy()), luastate(o.lua_state()) {
9427  }
9428 
9429  basic_reference(basic_reference&& o) noexcept : stateless_reference(std::move(o)), luastate(o.lua_state()) {
9430  o.luastate = nullptr;
9431  }
9432 
9434  : basic_reference(detail::pick_main_thread<main_only>(o.lua_state(), o.lua_state()), o) {
9435  }
9436 
9438  : stateless_reference(std::move(o)), luastate(detail::pick_main_thread<main_only>(o.lua_state(), o.lua_state())) {
9439  o.luastate = nullptr;
9440  o.ref = LUA_NOREF;
9441  }
9442 
9444  move_assign(std::move(r));
9445  return *this;
9446  }
9447 
9449  copy_assign(r);
9450  return *this;
9451  }
9452 
9454  move_assign(std::move(r));
9455  return *this;
9456  }
9457 
9459  copy_assign(r);
9460  return *this;
9461  }
9462 
9464  if (valid()) {
9465  deref();
9466  }
9467  luastate = nullptr;
9468  ref = LUA_NOREF;
9469  return *this;
9470  }
9471 
9472  template <typename Super>
9473  basic_reference& operator=(proxy_base<Super>&& r);
9474 
9475  template <typename Super>
9476  basic_reference& operator=(const proxy_base<Super>& r);
9477 
9478  int push() const noexcept {
9479  return push(lua_state());
9480  }
9481 
9482  int push(lua_State* L) const noexcept {
9483 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
9484  luaL_checkstack(L, 1, "not enough Lua stack space to push this reference value");
9485 #endif // make sure stack doesn't overflow
9486  if (lua_state() == nullptr) {
9487  lua_pushnil(L);
9488  return 1;
9489  }
9490  lua_rawgeti(lua_state(), LUA_REGISTRYINDEX, ref);
9491  if (L != lua_state()) {
9492  lua_xmove(lua_state(), L, 1);
9493  }
9494  return 1;
9495  }
9496 
9497  void pop() const noexcept {
9498  pop(lua_state());
9499  }
9500 
9501  void pop(lua_State* L, int n = 1) const noexcept {
9503  }
9504 
9505  int registry_index() const noexcept {
9507  }
9508 
9509  bool valid() const noexcept {
9510  return stateless_reference::valid(lua_state());
9511  }
9512 
9513  const void* pointer() const noexcept {
9514  return stateless_reference::pointer(lua_state());
9515  }
9516 
9517  explicit operator bool() const noexcept {
9518  return valid();
9519  }
9520 
9521  type get_type() const noexcept {
9522  return stateless_reference::get_type(lua_state());
9523  }
9524 
9525  lua_State* lua_state() const noexcept {
9526  return luastate;
9527  }
9528  };
9529 
9530  template <bool lb, bool rb>
9531  inline bool operator==(const basic_reference<lb>& l, const basic_reference<rb>& r) {
9532  auto ppl = stack::push_pop(l);
9533  auto ppr = stack::push_pop(r);
9534  return lua_compare(l.lua_state(), -1, -2, LUA_OPEQ) == 1;
9535  }
9536 
9537  template <bool lb, bool rb>
9538  inline bool operator!=(const basic_reference<lb>& l, const basic_reference<rb>& r) {
9539  return !operator==(l, r);
9540  }
9541 
9542  template <bool lb>
9543  inline bool operator==(const basic_reference<lb>& l, const stack_reference& r) {
9544  auto ppl = stack::push_pop(l);
9545  return lua_compare(l.lua_state(), -1, r.stack_index(), LUA_OPEQ) == 1;
9546  }
9547 
9548  template <bool lb>
9549  inline bool operator!=(const basic_reference<lb>& l, const stack_reference& r) {
9550  return !operator==(l, r);
9551  }
9552 
9553  template <bool rb>
9554  inline bool operator==(const stack_reference& l, const basic_reference<rb>& r) {
9555  auto ppr = stack::push_pop(r);
9556  return lua_compare(l.lua_state(), -1, r.stack_index(), LUA_OPEQ) == 1;
9557  }
9558 
9559  template <bool rb>
9560  inline bool operator!=(const stack_reference& l, const basic_reference<rb>& r) {
9561  return !operator==(l, r);
9562  }
9563 
9564  template <bool lb>
9565  inline bool operator==(const basic_reference<lb>& lhs, const lua_nil_t&) {
9566  return !lhs.valid();
9567  }
9568 
9569  template <bool rb>
9570  inline bool operator==(const lua_nil_t&, const basic_reference<rb>& rhs) {
9571  return !rhs.valid();
9572  }
9573 
9574  template <bool lb>
9575  inline bool operator!=(const basic_reference<lb>& lhs, const lua_nil_t&) {
9576  return lhs.valid();
9577  }
9578 
9579  template <bool rb>
9580  inline bool operator!=(const lua_nil_t&, const basic_reference<rb>& rhs) {
9581  return rhs.valid();
9582  }
9583 
9585  template <bool rb>
9586  bool operator()(const lua_nil_t& lhs, const basic_reference<rb>& rhs) const {
9587  return lhs == rhs;
9588  }
9589 
9590  template <bool lb>
9591  bool operator()(const basic_reference<lb>& lhs, const lua_nil_t& rhs) const {
9592  return lhs == rhs;
9593  }
9594 
9595  template <bool lb, bool rb>
9596  bool operator()(const basic_reference<lb>& lhs, const basic_reference<rb>& rhs) const {
9597  return lhs == rhs;
9598  }
9599 
9600  template <bool lb>
9601  bool operator()(const basic_reference<lb>& lhs, const stack_reference& rhs) const {
9602  return lhs == rhs;
9603  }
9604 
9605  template <bool rb>
9606  bool operator()(const stack_reference& lhs, const basic_reference<rb>& rhs) const {
9607  return lhs == rhs;
9608  }
9609  };
9610 
9613  typedef std::size_t result_type;
9614 
9615  template <bool lb>
9616  result_type operator()(const basic_reference<lb>& lhs) const {
9617  std::hash<const void*> h;
9618  return h(lhs.pointer());
9619  }
9620  };
9621 } // namespace sol
9622 
9623 // end of sol/reference.hpp
9624 
9625 // beginning of sol/tie.hpp
9626 
9627 namespace sol {
9628 
9629  namespace detail {
9630  template <typename T>
9631  struct is_speshul : std::false_type {};
9632  } // namespace detail
9633 
9634  template <typename T>
9635  struct tie_size : std::tuple_size<T> {};
9636 
9637  template <typename T>
9638  struct is_tieable : std::integral_constant<bool, (::sol::tie_size<T>::value > 0)> {};
9639 
9640  template <typename... Tn>
9641  struct tie_t : public std::tuple<std::add_lvalue_reference_t<Tn>...> {
9642  private:
9643  typedef std::tuple<std::add_lvalue_reference_t<Tn>...> base_t;
9644 
9645  template <typename T>
9646  void set(std::false_type, T&& target) {
9647  std::get<0>(*this) = std::forward<T>(target);
9648  }
9649 
9650  template <typename T>
9651  void set(std::true_type, T&& target) {
9652  typedef tie_size<meta::unqualified_t<T>> value_size;
9653  typedef tie_size<std::tuple<Tn...>> tie_size;
9655  typedef std::make_index_sequence<indices_size::value> indices;
9656  set_extra(detail::is_speshul<meta::unqualified_t<T>>(), indices(), std::forward<T>(target));
9657  }
9658 
9659  template <std::size_t... I, typename T>
9660  void set_extra(std::true_type, std::index_sequence<I...>, T&& target) {
9661  using std::get;
9662  (void)detail::swallow{0,
9663  (get<I>(static_cast<base_t&>(*this)) = get<I>(types<Tn...>(), target), 0)..., 0};
9664  }
9665 
9666  template <std::size_t... I, typename T>
9667  void set_extra(std::false_type, std::index_sequence<I...>, T&& target) {
9668  using std::get;
9669  (void)detail::swallow{0,
9670  (get<I>(static_cast<base_t&>(*this)) = get<I>(target), 0)..., 0};
9671  }
9672 
9673  public:
9674  using base_t::base_t;
9675 
9676  template <typename T>
9677  tie_t& operator=(T&& value) {
9678  typedef is_tieable<meta::unqualified_t<T>> tieable;
9679  set(tieable(), std::forward<T>(value));
9680  return *this;
9681  }
9682  };
9683 
9684  template <typename... Tn>
9685  struct tie_size<tie_t<Tn...>> : std::tuple_size<std::tuple<Tn...>> {};
9686 
9687  namespace adl_barrier_detail {
9688  template <typename... Tn>
9689  inline tie_t<std::remove_reference_t<Tn>...> tie(Tn&&... argn) {
9690  return tie_t<std::remove_reference_t<Tn>...>(std::forward<Tn>(argn)...);
9691  }
9692  } // namespace adl_barrier_detail
9693 
9694  using namespace adl_barrier_detail;
9695 
9696 } // namespace sol
9697 
9698 // end of sol/tie.hpp
9699 
9700 // beginning of sol/stack_guard.hpp
9701 
9702 #include <functional>
9703 
9704 namespace sol {
9705  namespace detail {
9706  inline void stack_fail(int, int) {
9707 #if !(defined(SOL_NO_EXCEPTIONS) && SOL_NO_EXCEPTIONS)
9708  throw error(detail::direct_error, "imbalanced stack after operation finish");
9709 #else
9710  // Lol, what do you want, an error printout? :3c
9711  // There's no sane default here. The right way would be C-style abort(), and that's not acceptable, so
9712  // hopefully someone will register their own stack_fail thing for the `fx` parameter of stack_guard.
9713 #endif // No Exceptions
9714  }
9715  } // namespace detail
9716 
9717  struct stack_guard {
9719  int top;
9720  std::function<void(int, int)> on_mismatch;
9721 
9723  }
9724  stack_guard(lua_State* L, int top, std::function<void(int, int)> fx = detail::stack_fail) : L(L), top(top), on_mismatch(std::move(fx)) {
9725  }
9726  bool check_stack(int modification = 0) const {
9727  int bottom = lua_gettop(L) + modification;
9728  if (top == bottom) {
9729  return true;
9730  }
9731  on_mismatch(top, bottom);
9732  return false;
9733  }
9735  check_stack();
9736  }
9737  };
9738 } // namespace sol
9739 
9740 // end of sol/stack_guard.hpp
9741 
9742 #include <vector>
9743 #include <bitset>
9744 #include <forward_list>
9745 #include <string>
9746 #include <algorithm>
9747 #include <sstream>
9748 #include <optional>
9749 
9750 namespace sol {
9751  namespace detail {
9752  struct with_function_tag { };
9753  struct as_reference_tag { };
9754  template <typename T>
9755  struct as_pointer_tag { };
9756  template <typename T>
9757  struct as_value_tag { };
9758  template <typename T>
9759  struct as_unique_tag { };
9760  template <typename T>
9761  struct as_table_tag { };
9762 
9764 
9765  using unique_destructor = void (*)(void*);
9767 
9768  inline void* align(std::size_t alignment, std::size_t size, void*& ptr, std::size_t& space, std::size_t& required_space) {
9769  // this handels arbitrary alignments...
9770  // make this into a power-of-2-only?
9771  // actually can't: this is a C++14-compatible framework,
9772  // power of 2 alignment is C++17
9773  std::uintptr_t initial = reinterpret_cast<std::uintptr_t>(ptr);
9774  std::uintptr_t offby = static_cast<std::uintptr_t>(initial % alignment);
9775  std::uintptr_t padding = (alignment - offby) % alignment;
9776  required_space += size + padding;
9777  if (space < required_space) {
9778  return nullptr;
9779  }
9780  ptr = static_cast<void*>(static_cast<char*>(ptr) + padding);
9781  space -= padding;
9782  return ptr;
9783  }
9784 
9785  inline void* align(std::size_t alignment, std::size_t size, void*& ptr, std::size_t& space) {
9786  std::size_t required_space = 0;
9787  return align(alignment, size, ptr, space, required_space);
9788  }
9789 
9790  inline void align_one(std::size_t a, std::size_t s, void*& target_alignment) {
9791  std::size_t space = (std::numeric_limits<std::size_t>::max)();
9792  target_alignment = align(a, s, target_alignment, space);
9793  target_alignment = static_cast<void*>(static_cast<char*>(target_alignment) + s);
9794  }
9795 
9796  template <typename... Args>
9797  std::size_t aligned_space_for(void* alignment = nullptr) {
9798  // use temporary storage to prevent strict UB shenanigans
9799  char alignment_shim[(std::max)({ sizeof(Args)... }) + (std::max)({ alignof(Args)... })] {};
9800  char* start = alignment == nullptr ? static_cast<char*>(alignment) : alignment_shim;
9801  (void)detail::swallow { int {}, (align_one(std::alignment_of_v<Args>, sizeof(Args), alignment), int {})... };
9802  return static_cast<char*>(alignment) - start;
9803  }
9804 
9805  inline void* align_usertype_pointer(void* ptr) {
9806  using use_align = std::integral_constant<bool,
9807 #if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
9808  false
9809 #else
9811 #endif
9812  >;
9813  if (!use_align::value) {
9814  return ptr;
9815  }
9816  std::size_t space = (std::numeric_limits<std::size_t>::max)();
9817  return align(std::alignment_of<void*>::value, sizeof(void*), ptr, space);
9818  }
9819 
9820  template <bool pre_aligned = false, bool pre_shifted = false>
9822  using use_align = std::integral_constant<bool,
9823 #if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
9824  false
9825 #else
9827 #endif
9828  >;
9829  if (!pre_aligned) {
9830  ptr = align_usertype_pointer(ptr);
9831  }
9832  if (!pre_shifted) {
9833  ptr = static_cast<void*>(static_cast<char*>(ptr) + sizeof(void*));
9834  }
9835  if (!use_align::value) {
9836  return static_cast<void*>(static_cast<void**>(ptr) + 1);
9837  }
9838  std::size_t space = (std::numeric_limits<std::size_t>::max)();
9840  }
9841 
9842  template <bool pre_aligned = false, bool pre_shifted = false>
9844  using use_align = std::integral_constant<bool,
9845 #if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
9846  false
9847 #else
9849 #endif
9850  >;
9851  if (!pre_aligned) {
9853  }
9854  if (!pre_shifted) {
9855  ptr = static_cast<void*>(static_cast<char*>(ptr) + sizeof(unique_destructor));
9856  }
9857  if (!use_align::value) {
9858  return ptr;
9859  }
9860  std::size_t space = (std::numeric_limits<std::size_t>::max)();
9861  return align(std::alignment_of<unique_tag>::value, sizeof(unique_tag), ptr, space);
9862  }
9863 
9864  template <typename T, bool pre_aligned = false, bool pre_shifted = false>
9866  typedef std::integral_constant<bool,
9867 #if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
9868  false
9869 #else
9870  (std::alignment_of_v<T> > 1)
9871 #endif
9872  >
9873  use_align;
9874  if (!pre_aligned) {
9875  ptr = align_usertype_unique_tag(ptr);
9876  }
9877  if (!pre_shifted) {
9878  ptr = static_cast<void*>(static_cast<char*>(ptr) + sizeof(unique_tag));
9879  }
9880  if (!use_align::value) {
9881  return ptr;
9882  }
9883  std::size_t space = (std::numeric_limits<std::size_t>::max)();
9884  return align(std::alignment_of_v<T>, sizeof(T), ptr, space);
9885  }
9886 
9887  template <typename T>
9888  void* align_user(void* ptr) {
9889  typedef std::integral_constant<bool,
9890 #if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
9891  false
9892 #else
9893  (std::alignment_of_v<T> > 1)
9894 #endif
9895  >
9896  use_align;
9897  if (!use_align::value) {
9898  return ptr;
9899  }
9900  std::size_t space = (std::numeric_limits<std::size_t>::max)();
9901  return align(std::alignment_of_v<T>, sizeof(T), ptr, space);
9902  }
9903 
9904  template <typename T>
9906  typedef std::integral_constant<bool,
9907 #if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
9908  false
9909 #else
9911 #endif
9912  >
9913  use_align;
9914  if (!use_align::value) {
9915  T** pointerpointer = static_cast<T**>(lua_newuserdata(L, sizeof(T*)));
9916  return pointerpointer;
9917  }
9918  static const std::size_t initial_size = aligned_space_for<T*>(nullptr);
9919  static const std::size_t misaligned_size = aligned_space_for<T*>(reinterpret_cast<void*>(0x1));
9920 
9921  std::size_t allocated_size = initial_size;
9922  void* unadjusted = lua_newuserdata(L, initial_size);
9923  void* adjusted = align(std::alignment_of<T*>::value, sizeof(T*), unadjusted, allocated_size);
9924  if (adjusted == nullptr) {
9925  lua_pop(L, 1);
9926  // what kind of absolute garbage trash allocator are we dealing with?
9927  // whatever, add some padding in the case of MAXIMAL alignment waste...
9928  allocated_size = misaligned_size;
9929  unadjusted = lua_newuserdata(L, allocated_size);
9930  adjusted = align(std::alignment_of<T*>::value, sizeof(T*), unadjusted, allocated_size);
9931  if (adjusted == nullptr) {
9932  // trash allocator can burn in hell
9933  lua_pop(L, 1);
9934  // luaL_error(L, "if you are the one that wrote this allocator you should feel bad for doing a
9935  // worse job than malloc/realloc and should go read some books, yeah?");
9936  luaL_error(L, "cannot properly align memory for '%s'", detail::demangle<T*>().data());
9937  }
9938  }
9939  return static_cast<T**>(adjusted);
9940  }
9941 
9942  inline bool attempt_alloc(lua_State* L, std::size_t ptr_align, std::size_t ptr_size, std::size_t value_align, std::size_t value_size,
9943  std::size_t allocated_size, void*& pointer_adjusted, void*& data_adjusted) {
9944  void* adjusted = lua_newuserdata(L, allocated_size);
9945  pointer_adjusted = align(ptr_align, ptr_size, adjusted, allocated_size);
9946  if (pointer_adjusted == nullptr) {
9947  lua_pop(L, 1);
9948  return false;
9949  }
9950  // subtract size of what we're going to allocate there
9951  allocated_size -= ptr_size;
9952  adjusted = static_cast<void*>(static_cast<char*>(pointer_adjusted) + ptr_size);
9953  data_adjusted = align(value_align, value_size, adjusted, allocated_size);
9954  if (data_adjusted == nullptr) {
9955  lua_pop(L, 1);
9956  return false;
9957  }
9958  return true;
9959  }
9960 
9961  inline bool attempt_alloc_unique(lua_State* L, std::size_t ptr_align, std::size_t ptr_size, std::size_t real_align, std::size_t real_size,
9962  std::size_t allocated_size, void*& pointer_adjusted, void*& dx_adjusted, void*& id_adjusted, void*& data_adjusted) {
9963  void* adjusted = lua_newuserdata(L, allocated_size);
9964  pointer_adjusted = align(ptr_align, ptr_size, adjusted, allocated_size);
9965  if (pointer_adjusted == nullptr) {
9966  lua_pop(L, 1);
9967  return false;
9968  }
9969  allocated_size -= ptr_size;
9970 
9971  adjusted = static_cast<void*>(static_cast<char*>(pointer_adjusted) + ptr_size);
9972  dx_adjusted = align(std::alignment_of_v<unique_destructor>, sizeof(unique_destructor), adjusted, allocated_size);
9973  if (dx_adjusted == nullptr) {
9974  lua_pop(L, 1);
9975  return false;
9976  }
9977  allocated_size -= sizeof(unique_destructor);
9978 
9979  adjusted = static_cast<void*>(static_cast<char*>(dx_adjusted) + sizeof(unique_destructor));
9980 
9981  id_adjusted = align(std::alignment_of_v<unique_tag>, sizeof(unique_tag), adjusted, allocated_size);
9982  if (id_adjusted == nullptr) {
9983  lua_pop(L, 1);
9984  return false;
9985  }
9986  allocated_size -= sizeof(unique_tag);
9987 
9988  adjusted = static_cast<void*>(static_cast<char*>(id_adjusted) + sizeof(unique_tag));
9989  data_adjusted = align(real_align, real_size, adjusted, allocated_size);
9990  if (data_adjusted == nullptr) {
9991  lua_pop(L, 1);
9992  return false;
9993  }
9994  return true;
9995  }
9996 
9997  template <typename T>
9999  typedef std::integral_constant<bool,
10000 #if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
10001  false
10002 #else
10003  (std::alignment_of<T*>::value > 1 || std::alignment_of_v<T> > 1)
10004 #endif
10005  >
10006  use_align;
10007  if (!use_align::value) {
10008  T** pointerpointer = static_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
10009  T*& pointerreference = *pointerpointer;
10010  T* allocationtarget = reinterpret_cast<T*>(pointerpointer + 1);
10011  pointerreference = allocationtarget;
10012  return allocationtarget;
10013  }
10014 
10015  /* the assumption is that `lua_newuserdata` -- unless someone
10016  passes a specific lua_Alloc that gives us bogus, un-aligned pointers
10017  -- uses malloc, which tends to hand out more or less aligned pointers to memory
10018  (most of the time, anyhow)
10019 
10020  but it's not guaranteed, so we have to do a post-adjustment check and increase padding
10021 
10022  we do this preliminarily with compile-time stuff, to see
10023  if we strike lucky with the allocator and alignment values
10024 
10025  otherwise, we have to re-allocate the userdata and
10026  over-allocate some space for additional padding because
10027  compilers are optimized for aligned reads/writes
10028  (and clang will barf UBsan errors on us for not being aligned)
10029  */
10030  static const std::size_t initial_size = aligned_space_for<T*, T>(nullptr);
10031  static const std::size_t misaligned_size = aligned_space_for<T*, T>(reinterpret_cast<void*>(0x1));
10032 
10033  void* pointer_adjusted;
10034  void* data_adjusted;
10035  bool result
10036  = attempt_alloc(L, std::alignment_of_v<T*>, sizeof(T*), std::alignment_of_v<T>, sizeof(T), initial_size, pointer_adjusted, data_adjusted);
10037  if (!result) {
10038  // we're likely to get something that fails to perform the proper allocation a second time,
10039  // so we use the suggested_new_size bump to help us out here
10040  pointer_adjusted = nullptr;
10041  data_adjusted = nullptr;
10042  result = attempt_alloc(
10043  L, std::alignment_of_v<T*>, sizeof(T*), std::alignment_of_v<T>, sizeof(T), misaligned_size, pointer_adjusted, data_adjusted);
10044  if (!result) {
10045  if (pointer_adjusted == nullptr) {
10046  luaL_error(L, "aligned allocation of userdata block (pointer section) for '%s' failed", detail::demangle<T>().c_str());
10047  }
10048  else {
10049  luaL_error(L, "aligned allocation of userdata block (data section) for '%s' failed", detail::demangle<T>().c_str());
10050  }
10051  return nullptr;
10052  }
10053  }
10054 
10055  T** pointerpointer = reinterpret_cast<T**>(pointer_adjusted);
10056  T*& pointerreference = *pointerpointer;
10057  T* allocationtarget = reinterpret_cast<T*>(data_adjusted);
10058  pointerreference = allocationtarget;
10059  return allocationtarget;
10060  }
10061 
10062  template <typename T, typename Real>
10064  typedef std::integral_constant<bool,
10065 #if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
10066  false
10067 #else
10070 #endif
10071  >
10072  use_align;
10073  if (!use_align::value) {
10074  pref = static_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(detail::unique_destructor) + sizeof(unique_tag) + sizeof(Real)));
10075  dx = static_cast<detail::unique_destructor*>(static_cast<void*>(pref + 1));
10076  id = static_cast<unique_tag*>(static_cast<void*>(dx + 1));
10077  Real* mem = static_cast<Real*>(static_cast<void*>(id + 1));
10078  return mem;
10079  }
10080 
10081  static const std::size_t initial_size = aligned_space_for<T*, unique_destructor, unique_tag, Real>(nullptr);
10082  static const std::size_t misaligned_size = aligned_space_for<T*, unique_destructor, unique_tag, Real>(reinterpret_cast<void*>(0x1));
10083 
10084  void* pointer_adjusted;
10085  void* dx_adjusted;
10086  void* id_adjusted;
10087  void* data_adjusted;
10088  bool result = attempt_alloc_unique(L,
10089  std::alignment_of_v<T*>,
10090  sizeof(T*),
10091  std::alignment_of_v<Real>,
10092  sizeof(Real),
10093  initial_size,
10094  pointer_adjusted,
10095  dx_adjusted,
10096  id_adjusted,
10097  data_adjusted);
10098  if (!result) {
10099  // we're likely to get something that fails to perform the proper allocation a second time,
10100  // so we use the suggested_new_size bump to help us out here
10101  pointer_adjusted = nullptr;
10102  dx_adjusted = nullptr;
10103  id_adjusted = nullptr;
10104  data_adjusted = nullptr;
10105  result = attempt_alloc_unique(L,
10106  std::alignment_of_v<T*>,
10107  sizeof(T*),
10108  std::alignment_of_v<Real>,
10109  sizeof(Real),
10110  misaligned_size,
10111  pointer_adjusted,
10112  dx_adjusted,
10113  id_adjusted,
10114  data_adjusted);
10115  if (!result) {
10116  if (pointer_adjusted == nullptr) {
10117  luaL_error(L, "aligned allocation of userdata block (pointer section) for '%s' failed", detail::demangle<T>().c_str());
10118  }
10119  else if (dx_adjusted == nullptr) {
10120  luaL_error(L, "aligned allocation of userdata block (deleter section) for '%s' failed", detail::demangle<T>().c_str());
10121  }
10122  else {
10123  luaL_error(L, "aligned allocation of userdata block (data section) for '%s' failed", detail::demangle<T>().c_str());
10124  }
10125  return nullptr;
10126  }
10127  }
10128 
10129  pref = static_cast<T**>(pointer_adjusted);
10130  dx = static_cast<detail::unique_destructor*>(dx_adjusted);
10131  id = static_cast<unique_tag*>(id_adjusted);
10132  Real* mem = static_cast<Real*>(data_adjusted);
10133  return mem;
10134  }
10135 
10136  template <typename T>
10138  typedef std::integral_constant<bool,
10139 #if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
10140  false
10141 #else
10142  (std::alignment_of_v<T> > 1)
10143 #endif
10144  >
10145  use_align;
10146  if (!use_align::value) {
10147  T* pointer = static_cast<T*>(lua_newuserdata(L, sizeof(T)));
10148  return pointer;
10149  }
10150 
10151  static const std::size_t initial_size = aligned_space_for<T>(nullptr);
10152  static const std::size_t misaligned_size = aligned_space_for<T>(reinterpret_cast<void*>(0x1));
10153 
10154  std::size_t allocated_size = initial_size;
10155  void* unadjusted = lua_newuserdata(L, allocated_size);
10156  void* adjusted = align(std::alignment_of_v<T>, sizeof(T), unadjusted, allocated_size);
10157  if (adjusted == nullptr) {
10158  lua_pop(L, 1);
10159  // try again, add extra space for alignment padding
10160  allocated_size = misaligned_size;
10161  unadjusted = lua_newuserdata(L, allocated_size);
10162  adjusted = align(std::alignment_of_v<T>, sizeof(T), unadjusted, allocated_size);
10163  if (adjusted == nullptr) {
10164  lua_pop(L, 1);
10165  luaL_error(L, "cannot properly align memory for '%s'", detail::demangle<T>().data());
10166  }
10167  }
10168  return static_cast<T*>(adjusted);
10169  }
10170 
10171  template <typename T>
10173  void* memory = lua_touserdata(L, 1);
10174  memory = align_usertype_pointer(memory);
10175  T** pdata = static_cast<T**>(memory);
10176  T* data = *pdata;
10177  std::allocator<T> alloc {};
10178  std::allocator_traits<std::allocator<T>>::destroy(alloc, data);
10179  return 0;
10180  }
10181 
10182  template <typename T>
10184  void* memory = lua_touserdata(L, 1);
10185  memory = align_usertype_unique_destructor(memory);
10186  unique_destructor& dx = *static_cast<unique_destructor*>(memory);
10187  memory = align_usertype_unique_tag<true>(memory);
10188  (dx)(memory);
10189  return 0;
10190  }
10191 
10192  template <typename T>
10194  void* memory = lua_touserdata(L, 1);
10195  memory = align_user<T>(memory);
10196  T* data = static_cast<T*>(memory);
10197  std::allocator<T> alloc;
10198  std::allocator_traits<std::allocator<T>>::destroy(alloc, data);
10199  return 0;
10200  }
10201 
10202  template <typename T, typename Real>
10204  memory = align_usertype_unique<Real, true>(memory);
10205  Real* target = static_cast<Real*>(memory);
10206  std::allocator<Real> alloc;
10207  std::allocator_traits<std::allocator<Real>>::destroy(alloc, target);
10208  }
10209 
10210  template <typename T>
10212  return luaL_error(L,
10213  "cannot call the destructor for '%s': it is either hidden (protected/private) or removed with '= "
10214  "delete' and thusly this type is being destroyed without properly destructing, invoking undefined "
10215  "behavior: please bind a usertype and specify a custom destructor to define the behavior properly",
10216  detail::demangle<T>().data());
10217  }
10218 
10219  template <typename T>
10220  void reserve(T&, std::size_t) {
10221  }
10222 
10223  template <typename T, typename Al>
10224  void reserve(std::vector<T, Al>& vec, std::size_t hint) {
10225  vec.reserve(hint);
10226  }
10227 
10228  template <typename T, typename Tr, typename Al>
10229  void reserve(std::basic_string<T, Tr, Al>& str, std::size_t hint) {
10230  str.reserve(hint);
10231  }
10232 
10234  return true;
10235  }
10236 
10239  std::bitset<64>& properties;
10241 
10242  properties_enrollment_allowed(int& times, std::bitset<64>& props, automagic_enrollments& enroll)
10243  : times_through(times), properties(props), enrollments(enroll) {
10244  }
10245 
10246  bool operator()(meta_function mf) const {
10247  bool p = properties[static_cast<int>(mf)];
10248  if (times_through > 0) {
10249  return p;
10250  }
10251  switch (mf) {
10252  case meta_function::length:
10253  return enrollments.length_operator && !p;
10254  case meta_function::pairs:
10255  return enrollments.pairs_operator && !p;
10256  case meta_function::call:
10257  return enrollments.call_operator && !p;
10259  return enrollments.less_than_operator && !p;
10261  return enrollments.less_than_or_equal_to_operator && !p;
10263  return enrollments.equal_to_operator && !p;
10264  default:
10265  break;
10266  }
10267  return !p;
10268  }
10269  };
10270 
10273  int& index;
10274 
10275  indexed_insert(lua_reg_table& cont, int& idx) : l(cont), index(idx) {
10276  }
10278  l[index] = luaL_Reg { to_string(mf).c_str(), f };
10279  ++index;
10280  }
10281  };
10282  } // namespace detail
10283 
10284  namespace stack {
10285 
10286  template <typename T, bool global = false, bool raw = false, typename = void>
10288  template <typename T, typename P, bool global = false, bool raw = false, typename = void>
10290 
10291  template <typename T, bool global = false, bool raw = false, typename = void>
10293 
10294  template <typename T, typename = void>
10296  template <typename T, typename = void>
10298 
10299  template <typename T, typename = void>
10301  template <typename T, typename = void>
10303 
10304  template <typename T, typename = void>
10305  struct popper;
10306 
10307  template <typename T, typename = void>
10309 
10310  template <typename T, type t, typename = void>
10312  template <typename T, type t, typename = void>
10314 
10315  template <typename T, typename = void>
10317  template <typename T, typename = void>
10319 
10320  struct probe {
10321  bool success;
10322  int levels;
10323 
10324  probe(bool s, int l) : success(s), levels(l) {
10325  }
10326 
10327  operator bool() const {
10328  return success;
10329  };
10330  };
10331 
10332  struct record {
10333  int last;
10334  int used;
10335 
10336  record() noexcept : last(), used() {
10337  }
10338  void use(int count) noexcept {
10339  last = count;
10340  used += count;
10341  }
10342  };
10343 
10344  namespace stack_detail {
10345  template <typename Function>
10346  Function* get_function_pointer(lua_State*, int, record&) noexcept;
10347  template <typename Function, typename Handler>
10348  bool check_function_pointer(lua_State* L, int index, Handler&& handler, record& tracking) noexcept;
10349  } // namespace stack_detail
10350 
10351  } // namespace stack
10352 
10353  namespace meta { namespace meta_detail {
10354 
10355  template <typename T>
10356  using adl_sol_lua_get_test_t = decltype(sol_lua_get(types<T>(), static_cast<lua_State*>(nullptr), -1, std::declval<stack::record&>()));
10357 
10358  template <typename T>
10360  = decltype(sol_lua_interop_get(types<T>(), static_cast<lua_State*>(nullptr), -1, static_cast<void*>(nullptr), std::declval<stack::record&>()));
10361 
10362  template <typename T>
10363  using adl_sol_lua_check_test_t = decltype(sol_lua_check(types<T>(), static_cast<lua_State*>(nullptr), -1, no_panic, std::declval<stack::record&>()));
10364 
10365  template <typename T>
10367  = decltype(sol_lua_interop_check(types<T>(), static_cast<lua_State*>(nullptr), -1, type::none, no_panic, std::declval<stack::record&>()));
10368 
10369  template <typename T>
10371  = decltype(sol_lua_check_get(types<T>(), static_cast<lua_State*>(nullptr), -1, no_panic, std::declval<stack::record&>()));
10372 
10373  template <typename... Args>
10374  using adl_sol_lua_push_test_t = decltype(sol_lua_push(static_cast<lua_State*>(nullptr), std::declval<Args>()...));
10375 
10376  template <typename T, typename... Args>
10377  using adl_sol_lua_push_exact_test_t = decltype(sol_lua_push(types<T>(), static_cast<lua_State*>(nullptr), std::declval<Args>()...));
10378 
10379  template <typename T>
10380  inline constexpr bool is_adl_sol_lua_get_v = meta::is_detected_v<adl_sol_lua_get_test_t, T>;
10381 
10382  template <typename T>
10383  inline constexpr bool is_adl_sol_lua_interop_get_v = meta::is_detected_v<adl_sol_lua_interop_get_test_t, T>;
10384 
10385  template <typename T>
10386  inline constexpr bool is_adl_sol_lua_check_v = meta::is_detected_v<adl_sol_lua_check_test_t, T>;
10387 
10388  template <typename T>
10389  inline constexpr bool is_adl_sol_lua_interop_check_v = meta::is_detected_v<adl_sol_lua_interop_check_test_t, T>;
10390 
10391  template <typename T>
10392  inline constexpr bool is_adl_sol_lua_check_get_v = meta::is_detected_v<adl_sol_lua_check_get_test_t, T>;
10393 
10394  template <typename... Args>
10396 
10397  template <typename T, typename... Args>
10399  }} // namespace meta::meta_detail
10400 
10401  namespace stack {
10402  namespace stack_detail {
10403  constexpr const char* not_enough_stack_space = "not enough space left on Lua stack";
10404  constexpr const char* not_enough_stack_space_floating = "not enough space left on Lua stack for a floating point number";
10405  constexpr const char* not_enough_stack_space_integral = "not enough space left on Lua stack for an integral number";
10406  constexpr const char* not_enough_stack_space_string = "not enough space left on Lua stack for a string";
10407  constexpr const char* not_enough_stack_space_meta_function_name = "not enough space left on Lua stack for the name of a meta_function";
10408  constexpr const char* not_enough_stack_space_userdata = "not enough space left on Lua stack to create a sol3 userdata";
10409  constexpr const char* not_enough_stack_space_generic = "not enough space left on Lua stack to push valuees";
10410  constexpr const char* not_enough_stack_space_environment = "not enough space left on Lua stack to retrieve environment";
10411 
10412  template <typename T>
10413  struct strip {
10414  typedef T type;
10415  };
10416  template <typename T>
10417  struct strip<std::reference_wrapper<T>> {
10418  typedef T& type;
10419  };
10420  template <typename T>
10421  struct strip<user<T>> {
10422  typedef T& type;
10423  };
10424  template <typename T>
10425  struct strip<non_null<T>> {
10426  typedef T type;
10427  };
10428  template <typename T>
10429  using strip_t = typename strip<T>::type;
10430 
10431  template <typename C>
10432  static int get_size_hint(C& c) {
10433  return static_cast<int>(c.size());
10434  }
10435 
10436  template <typename V, typename Al>
10437  static int get_size_hint(const std::forward_list<V, Al>&) {
10438  // forward_list makes me sad
10439  return static_cast<int>(32);
10440  }
10441 
10442  template <typename T>
10443  decltype(auto) unchecked_unqualified_get(lua_State* L, int index, record& tracking) {
10444  using Tu = meta::unqualified_t<T>;
10445  if constexpr (meta::meta_detail::is_adl_sol_lua_get_v<Tu>) {
10446  return sol_lua_get(types<Tu>(), L, index, tracking);
10447  }
10448  else {
10450  (void)g;
10451  return g.get(L, index, tracking);
10452  }
10453  }
10454 
10455  template <typename T>
10456  decltype(auto) unchecked_get(lua_State* L, int index, record& tracking) {
10457  if constexpr (meta::meta_detail::is_adl_sol_lua_get_v<T>) {
10458  return sol_lua_get(types<T>(), L, index, tracking);
10459  }
10460  else {
10461  qualified_getter<T> g {};
10462  (void)g;
10463  return g.get(L, index, tracking);
10464  }
10465  }
10466 
10467  template <typename T>
10468  decltype(auto) unqualified_interop_get(lua_State* L, int index, void* unadjusted_pointer, record& tracking) {
10469  using Tu = meta::unqualified_t<T>;
10470  if constexpr (meta::meta_detail::is_adl_sol_lua_interop_get_v<Tu>) {
10471  return sol_lua_interop_get(types<Tu>(), L, index, unadjusted_pointer, tracking);
10472  }
10473  else {
10474  (void)L;
10475  (void)index;
10476  (void)unadjusted_pointer;
10477  (void)tracking;
10478  using Ti = stack_detail::strip_t<Tu>;
10479  return std::pair<bool, Ti*> { false, nullptr };
10480  }
10481  }
10482 
10483  template <typename T>
10484  decltype(auto) interop_get(lua_State* L, int index, void* unadjusted_pointer, record& tracking) {
10485  if constexpr (meta::meta_detail::is_adl_sol_lua_interop_get_v<T>) {
10486  return sol_lua_interop_get(types<T>(), L, index, unadjusted_pointer, tracking);
10487  }
10488  else {
10489  return unqualified_interop_get<T>(L, index, unadjusted_pointer, tracking);
10490  }
10491  }
10492 
10493  template <typename T, typename Handler>
10494  bool unqualified_interop_check(lua_State* L, int index, type index_type, Handler&& handler, record& tracking) {
10495  using Tu = meta::unqualified_t<T>;
10496  if constexpr (meta::meta_detail::is_adl_sol_lua_interop_check_v<Tu>) {
10497  return sol_lua_interop_check(types<Tu>(), L, index, index_type, std::forward<Handler>(handler), tracking);
10498  }
10499  else {
10500  (void)L;
10501  (void)index;
10502  (void)index_type;
10503  (void)handler;
10504  (void)tracking;
10505  return false;
10506  }
10507  }
10508 
10509  template <typename T, typename Handler>
10510  bool interop_check(lua_State* L, int index, type index_type, Handler&& handler, record& tracking) {
10511  if constexpr (meta::meta_detail::is_adl_sol_lua_interop_check_v<T>) {
10512  return sol_lua_interop_check(types<T>(), L, index, index_type, std::forward<Handler>(handler), tracking);
10513  }
10514  else {
10515  return unqualified_interop_check<T>(L, index, index_type, std::forward<Handler>(handler), tracking);
10516  }
10517  }
10518 
10520 
10523  const char* key;
10525 
10526  undefined_metatable(lua_State* l, const char* k, undefined_method_func umf) : L(l), key(k), on_new_table(umf) {
10527  }
10528 
10529  void operator()() const {
10530  if (luaL_newmetatable(L, key) == 1) {
10531  on_new_table(stack_reference(L, -1));
10532  }
10533  lua_setmetatable(L, -2);
10534  }
10535  };
10536  } // namespace stack_detail
10537 
10538  inline bool maybe_indexable(lua_State* L, int index = -1) {
10539  type t = type_of(L, index);
10540  return t == type::userdata || t == type::table;
10541  }
10542 
10543  inline int top(lua_State* L) {
10544  return lua_gettop(L);
10545  }
10546 
10547  inline bool is_main_thread(lua_State* L) {
10548  int ismainthread = lua_pushthread(L);
10549  lua_pop(L, 1);
10550  return ismainthread == 1;
10551  }
10552 
10554  if (is_main_thread(L)) {
10555  return;
10556  }
10557  int stacksize = lua_gettop(L);
10558  if (stacksize < 1) {
10559  return;
10560  }
10561  if (type_of(L, 1) != type::function) {
10562  return;
10563  }
10564  // well now we're screwed...
10565  // we can clean the stack and pray it doesn't destroy anything?
10566  lua_pop(L, stacksize);
10567  }
10568 
10569  inline void clear(lua_State* L, int table_index) {
10570  lua_pushnil(L);
10571  while (lua_next(L, table_index) != 0) {
10572  // remove value
10573  lua_pop(L, 1);
10574  // duplicate key to protect form rawset
10575  lua_pushvalue(L, -1);
10576  // push new value
10577  lua_pushnil(L);
10578  // table_index%[key] = nil
10579  lua_rawset(L, table_index);
10580  }
10581  }
10582 
10583  inline void clear(reference& r) {
10584  auto pp = push_pop<false>(r);
10585  int stack_index = pp.index_of(r);
10586  clear(r.lua_state(), stack_index);
10587  }
10588 
10589  inline void clear(stack_reference& r) {
10590  clear(r.lua_state(), r.stack_index());
10591  }
10592 
10593  template <typename T, typename... Args>
10594  int push(lua_State* L, T&& t, Args&&... args) {
10595  using Tu = meta::unqualified_t<T>;
10596  if constexpr (meta::meta_detail::is_adl_sol_lua_push_exact_v<T, T, Args...>) {
10597  return sol_lua_push(types<T>(), L, std::forward<T>(t), std::forward<Args>(args)...);
10598  }
10599  else if constexpr (meta::meta_detail::is_adl_sol_lua_push_exact_v<Tu, T, Args...>) {
10600  return sol_lua_push(types<Tu>(), L, std::forward<T>(t), std::forward<Args>(args)...);
10601  }
10602  else if constexpr (meta::meta_detail::is_adl_sol_lua_push_v<T, Args...>) {
10603  return sol_lua_push(L, std::forward<T>(t), std::forward<Args>(args)...);
10604  }
10605  else {
10607  (void)p;
10608  return p.push(L, std::forward<T>(t), std::forward<Args>(args)...);
10609  }
10610  }
10611 
10612  // overload allows to use a pusher of a specific type, but pass in any kind of args
10613  template <typename T, typename Arg, typename... Args, typename = std::enable_if_t<!std::is_same<T, Arg>::value>>
10614  int push(lua_State* L, Arg&& arg, Args&&... args) {
10615  using Tu = meta::unqualified_t<T>;
10616  if constexpr (meta::meta_detail::is_adl_sol_lua_push_exact_v<T, Arg, Args...>) {
10617  return sol_lua_push(types<T>(), L, std::forward<Arg>(arg), std::forward<Args>(args)...);
10618  }
10619  else if constexpr (meta::meta_detail::is_adl_sol_lua_push_exact_v<Tu, Arg, Args...>) {
10620  return sol_lua_push(types<Tu>(), L, std::forward<Arg>(arg), std::forward<Args>(args)...);
10621  }
10622  else if constexpr (meta::meta_detail::is_adl_sol_lua_push_v<Arg, Args...>) {
10623  return sol_lua_push(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
10624  }
10625  else {
10627  (void)p;
10628  return p.push(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
10629  }
10630  }
10631 
10632  template <typename T, typename... Args>
10633  int push_userdata(lua_State* L, T&& t, Args&&... args) {
10634  using U = meta::unqualified_t<T>;
10638  return stack::push<Tr>(L, std::forward<T>(t), std::forward<Args>(args)...);
10639  }
10640 
10641  template <typename T, typename Arg, typename... Args>
10642  int push_userdata(lua_State* L, Arg&& arg, Args&&... args) {
10643  using U = meta::unqualified_t<T>;
10647  return stack::push<Tr>(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
10648  }
10649 
10650  namespace stack_detail {
10651 
10652  template <typename T, typename Arg, typename... Args>
10653  int push_reference(lua_State* L, Arg&& arg, Args&&... args) {
10654  using use_reference_tag = meta::all<std::is_lvalue_reference<T>,
10659  return stack::push<Tr>(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
10660  }
10661 
10662  } // namespace stack_detail
10663 
10664  template <typename T, typename... Args>
10665  int push_reference(lua_State* L, T&& t, Args&&... args) {
10666  return stack_detail::push_reference<T>(L, std::forward<T>(t), std::forward<Args>(args)...);
10667  }
10668 
10669  template <typename T, typename Arg, typename... Args>
10670  int push_reference(lua_State* L, Arg&& arg, Args&&... args) {
10671  return stack_detail::push_reference<T>(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
10672  }
10673 
10674  inline int multi_push(lua_State*) {
10675  // do nothing
10676  return 0;
10677  }
10678 
10679  template <typename T, typename... Args>
10680  int multi_push(lua_State* L, T&& t, Args&&... args) {
10681  int pushcount = push(L, std::forward<T>(t));
10682  void(detail::swallow { (pushcount += stack::push(L, std::forward<Args>(args)), 0)... });
10683  return pushcount;
10684  }
10685 
10687  // do nothing
10688  return 0;
10689  }
10690 
10691  template <typename T, typename... Args>
10692  int multi_push_reference(lua_State* L, T&& t, Args&&... args) {
10693  int pushcount = push_reference(L, std::forward<T>(t));
10694  void(detail::swallow { (pushcount += stack::push_reference(L, std::forward<Args>(args)), 0)... });
10695  return pushcount;
10696  }
10697 
10698  template <typename T, typename Handler>
10699  bool unqualified_check(lua_State* L, int index, Handler&& handler, record& tracking) {
10700  using Tu = meta::unqualified_t<T>;
10701  if constexpr (meta::meta_detail::is_adl_sol_lua_check_v<Tu>) {
10702  return sol_lua_check(types<Tu>(), L, index, std::forward<Handler>(handler), tracking);
10703  }
10704  else {
10706  // VC++ has a bad warning here: shut it up
10707  (void)c;
10708  return c.check(L, index, std::forward<Handler>(handler), tracking);
10709  }
10710  }
10711 
10712  template <typename T, typename Handler>
10713  bool unqualified_check(lua_State* L, int index, Handler&& handler) {
10714  record tracking {};
10715  return unqualified_check<T>(L, index, std::forward<Handler>(handler), tracking);
10716  }
10717 
10718  template <typename T>
10720  auto handler = no_panic;
10721  return unqualified_check<T>(L, index, handler);
10722  }
10723 
10724  template <typename T, typename Handler>
10725  bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
10726  if constexpr (meta::meta_detail::is_adl_sol_lua_check_v<T>) {
10727  return sol_lua_check(types<T>(), L, index, std::forward<Handler>(handler), tracking);
10728  }
10729  else {
10730  using Tu = meta::unqualified_t<T>;
10732  // VC++ has a bad warning here: shut it up
10733  (void)c;
10734  return c.check(L, index, std::forward<Handler>(handler), tracking);
10735  }
10736  }
10737 
10738  template <typename T, typename Handler>
10739  bool check(lua_State* L, int index, Handler&& handler) {
10740  record tracking {};
10741  return check<T>(L, index, std::forward<Handler>(handler), tracking);
10742  }
10743 
10744  template <typename T>
10745  bool check(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
10746  auto handler = no_panic;
10747  return check<T>(L, index, handler);
10748  }
10749 
10750  template <typename T, typename Handler>
10751  bool check_usertype(lua_State* L, int index, type, Handler&& handler, record& tracking) {
10752  using Tu = meta::unqualified_t<T>;
10754  return check<detail_t>(L, index, std::forward<Handler>(handler), tracking);
10755  }
10756 
10757  template <typename T, typename Handler>
10758  bool check_usertype(lua_State* L, int index, Handler&& handler, record& tracking) {
10759  using Tu = meta::unqualified_t<T>;
10761  return check<detail_t>(L, index, std::forward<Handler>(handler), tracking);
10762  }
10763 
10764  template <typename T, typename Handler>
10765  bool check_usertype(lua_State* L, int index, Handler&& handler) {
10766  record tracking {};
10767  return check_usertype<T>(L, index, std::forward<Handler>(handler), tracking);
10768  }
10769 
10770  template <typename T>
10771  bool check_usertype(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
10772  auto handler = no_panic;
10773  return check_usertype<T>(L, index, handler);
10774  }
10775 
10776  template <typename T, typename Handler>
10777  decltype(auto) unqualified_check_get(lua_State* L, int index, Handler&& handler, record& tracking) {
10778  using Tu = meta::unqualified_t<T>;
10779  if constexpr (meta::meta_detail::is_adl_sol_lua_check_get_v<T>) {
10780  return sol_lua_check_get(types<T>(), L, index, std::forward<Handler>(handler), tracking);
10781  }
10782  else if constexpr (meta::meta_detail::is_adl_sol_lua_check_get_v<Tu>) {
10783  return sol_lua_check_get(types<Tu>(), L, index, std::forward<Handler>(handler), tracking);
10784  }
10785  else {
10787  (void)cg;
10788  return cg.get(L, index, std::forward<Handler>(handler), tracking);
10789  }
10790  }
10791 
10792  template <typename T, typename Handler>
10793  decltype(auto) unqualified_check_get(lua_State* L, int index, Handler&& handler) {
10794  record tracking {};
10795  return unqualified_check_get<T>(L, index, handler, tracking);
10796  }
10797 
10798  template <typename T>
10799  decltype(auto) unqualified_check_get(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
10800  auto handler = no_panic;
10801  return unqualified_check_get<T>(L, index, handler);
10802  }
10803 
10804  template <typename T, typename Handler>
10805  decltype(auto) check_get(lua_State* L, int index, Handler&& handler, record& tracking) {
10806  if constexpr (meta::meta_detail::is_adl_sol_lua_check_get_v<T>) {
10807  return sol_lua_check_get(types<T>(), L, index, std::forward<Handler>(handler), tracking);
10808  }
10809  else {
10811  (void)cg;
10812  return cg.get(L, index, std::forward<Handler>(handler), tracking);
10813  }
10814  }
10815 
10816  template <typename T, typename Handler>
10817  decltype(auto) check_get(lua_State* L, int index, Handler&& handler) {
10818  record tracking {};
10819  return check_get<T>(L, index, handler, tracking);
10820  }
10821 
10822  template <typename T>
10823  decltype(auto) check_get(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
10824  auto handler = no_panic;
10825  return check_get<T>(L, index, handler);
10826  }
10827 
10828  namespace stack_detail {
10829 
10830  template <typename Handler>
10831  bool check_types(lua_State*, int, Handler&&, record&) {
10832  return true;
10833  }
10834 
10835  template <typename T, typename... Args, typename Handler>
10836  bool check_types(lua_State* L, int firstargument, Handler&& handler, record& tracking) {
10837  if (!stack::check<T>(L, firstargument + tracking.used, handler, tracking))
10838  return false;
10839  return check_types<Args...>(L, firstargument, std::forward<Handler>(handler), tracking);
10840  }
10841 
10842  template <typename... Args, typename Handler>
10843  bool check_types(types<Args...>, lua_State* L, int index, Handler&& handler, record& tracking) {
10844  return check_types<Args...>(L, index, std::forward<Handler>(handler), tracking);
10845  }
10846 
10847  } // namespace stack_detail
10848 
10849  template <typename... Args, typename Handler>
10850  bool multi_check(lua_State* L, int index, Handler&& handler, record& tracking) {
10851  return stack_detail::check_types<Args...>(L, index, std::forward<Handler>(handler), tracking);
10852  }
10853 
10854  template <typename... Args, typename Handler>
10855  bool multi_check(lua_State* L, int index, Handler&& handler) {
10856  record tracking {};
10857  return multi_check<Args...>(L, index, std::forward<Handler>(handler), tracking);
10858  }
10859 
10860  template <typename... Args>
10861  bool multi_check(lua_State* L, int index) {
10862  return multi_check<Args...>(L, index);
10863  }
10864 
10865  template <typename T>
10866  auto unqualified_get(lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_unqualified_get<T>(L, index, tracking)) {
10867 #if SOL_IS_ON(SOL_SAFE_GETTER_I_)
10868  static constexpr bool is_op = meta::is_optional_v<T>;
10869  if constexpr (is_op) {
10870  return stack_detail::unchecked_unqualified_get<T>(L, index, tracking);
10871  }
10872  else {
10874  return stack_detail::unchecked_unqualified_get<T>(L, index, tracking);
10875  }
10876  auto op = unqualified_check_get<T>(L, index, type_panic_c_str, tracking);
10877  return *std::move(op);
10878  }
10879 #else
10880  return stack_detail::unchecked_unqualified_get<T>(L, index, tracking);
10881 #endif
10882  }
10883 
10884  template <typename T>
10885  decltype(auto) unqualified_get(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
10886  record tracking {};
10887  return unqualified_get<T>(L, index, tracking);
10888  }
10889 
10890  template <typename T>
10891  auto get(lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_get<T>(L, index, tracking)) {
10892 #if SOL_IS_ON(SOL_SAFE_GETTER_I_)
10893  static constexpr bool is_op = meta::is_optional_v<T>;
10894  if constexpr (is_op) {
10895  return stack_detail::unchecked_get<T>(L, index, tracking);
10896  }
10897  else {
10899  return stack_detail::unchecked_get<T>(L, index, tracking);
10900  }
10901  auto op = check_get<T>(L, index, type_panic_c_str, tracking);
10902  return *std::move(op);
10903  }
10904 #else
10905  return stack_detail::unchecked_get<T>(L, index, tracking);
10906 #endif
10907  }
10908 
10909  template <typename T>
10910  decltype(auto) get(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
10911  record tracking {};
10912  return get<T>(L, index, tracking);
10913  }
10914 
10915  template <typename T>
10916  decltype(auto) get_usertype(lua_State* L, int index, record& tracking) {
10918  return get<UT>(L, index, tracking);
10919  }
10920 
10921  template <typename T>
10922  decltype(auto) get_usertype(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
10923  record tracking {};
10924  return get_usertype<T>(L, index, tracking);
10925  }
10926 
10927  template <typename T>
10928  decltype(auto) pop(lua_State* L) {
10929  return popper<meta::unqualified_t<T>> {}.pop(L);
10930  }
10931 
10932  template <bool global = false, bool raw = false, typename Key>
10933  void get_field(lua_State* L, Key&& key) {
10934  field_getter<meta::unqualified_t<Key>, global, raw> {}.get(L, std::forward<Key>(key));
10935  }
10936 
10937  template <bool global = false, bool raw = false, typename Key>
10938  void get_field(lua_State* L, Key&& key, int tableindex) {
10939  field_getter<meta::unqualified_t<Key>, global, raw> {}.get(L, std::forward<Key>(key), tableindex);
10940  }
10941 
10942  template <bool global = false, typename Key>
10943  void raw_get_field(lua_State* L, Key&& key) {
10944  get_field<global, true>(L, std::forward<Key>(key));
10945  }
10946 
10947  template <bool global = false, typename Key>
10948  void raw_get_field(lua_State* L, Key&& key, int tableindex) {
10949  get_field<global, true>(L, std::forward<Key>(key), tableindex);
10950  }
10951 
10952  template <bool global = false, bool raw = false, typename C = detail::non_lua_nil_t, typename Key>
10954  return probe_field_getter<meta::unqualified_t<Key>, C, global, raw> {}.get(L, std::forward<Key>(key));
10955  }
10956 
10957  template <bool global = false, bool raw = false, typename C = detail::non_lua_nil_t, typename Key>
10958  probe probe_get_field(lua_State* L, Key&& key, int tableindex) {
10959  return probe_field_getter<meta::unqualified_t<Key>, C, global, raw> {}.get(L, std::forward<Key>(key), tableindex);
10960  }
10961 
10962  template <bool global = false, typename C = detail::non_lua_nil_t, typename Key>
10964  return probe_get_field<global, true, C>(L, std::forward<Key>(key));
10965  }
10966 
10967  template <bool global = false, typename C = detail::non_lua_nil_t, typename Key>
10968  probe probe_raw_get_field(lua_State* L, Key&& key, int tableindex) {
10969  return probe_get_field<global, true, C>(L, std::forward<Key>(key), tableindex);
10970  }
10971 
10972  template <bool global = false, bool raw = false, typename Key, typename Value>
10973  void set_field(lua_State* L, Key&& key, Value&& value) {
10974  field_setter<meta::unqualified_t<Key>, global, raw> {}.set(L, std::forward<Key>(key), std::forward<Value>(value));
10975  }
10976 
10977  template <bool global = false, bool raw = false, typename Key, typename Value>
10978  void set_field(lua_State* L, Key&& key, Value&& value, int tableindex) {
10979  field_setter<meta::unqualified_t<Key>, global, raw> {}.set(L, std::forward<Key>(key), std::forward<Value>(value), tableindex);
10980  }
10981 
10982  template <bool global = false, typename Key, typename Value>
10983  void raw_set_field(lua_State* L, Key&& key, Value&& value) {
10984  set_field<global, true>(L, std::forward<Key>(key), std::forward<Value>(value));
10985  }
10986 
10987  template <bool global = false, typename Key, typename Value>
10988  void raw_set_field(lua_State* L, Key&& key, Value&& value, int tableindex) {
10989  set_field<global, true>(L, std::forward<Key>(key), std::forward<Value>(value), tableindex);
10990  }
10991 
10992  template <typename T, typename F>
10993  void modify_unique_usertype_as(const stack_reference& obj, F&& f) {
10994  using u_traits = unique_usertype_traits<T>;
10995  void* raw = lua_touserdata(obj.lua_state(), obj.stack_index());
10996  void* ptr_memory = detail::align_usertype_pointer(raw);
10997  void* uu_memory = detail::align_usertype_unique<T>(raw);
10998  T& uu = *static_cast<T*>(uu_memory);
10999  f(uu);
11000  *static_cast<void**>(ptr_memory) = static_cast<void*>(u_traits::get(uu));
11001  }
11002 
11003  template <typename F>
11004  void modify_unique_usertype(const stack_reference& obj, F&& f) {
11006  using T = typename bt::template arg_at<0>;
11007  using Tu = meta::unqualified_t<T>;
11008  modify_unique_usertype_as<Tu>(obj, std::forward<F>(f));
11009  }
11010 
11011  } // namespace stack
11012 
11013  namespace detail {
11014 
11015  template <typename T>
11016  lua_CFunction make_destructor(std::true_type) {
11017  if constexpr (is_unique_usertype_v<T>) {
11018  return &unique_destruct<T>;
11019  }
11020  else if constexpr (!std::is_pointer_v<T>) {
11021  return &usertype_alloc_destruct<T>;
11022  }
11023  else {
11024  return &cannot_destruct<T>;
11025  }
11026  }
11027 
11028  template <typename T>
11029  lua_CFunction make_destructor(std::false_type) {
11030  return &cannot_destruct<T>;
11031  }
11032 
11033  template <typename T>
11035  return make_destructor<T>(std::is_destructible<T>());
11036  }
11037 
11038  struct no_comp {
11039  template <typename A, typename B>
11040  bool operator()(A&&, B&&) const {
11041  return false;
11042  }
11043  };
11044 
11045  template <typename T>
11047  return stack::push(L, stack::check<T>(L, 1, &no_panic));
11048  }
11049 
11050  template <typename T>
11051  int member_default_to_string(std::true_type, lua_State* L) {
11052  decltype(auto) ts = stack::get<T>(L, 1).to_string();
11053  return stack::push(L, std::forward<decltype(ts)>(ts));
11054  }
11055 
11056  template <typename T>
11057  int member_default_to_string(std::false_type, lua_State* L) {
11058  return luaL_error(L,
11059  "cannot perform to_string on '%s': no 'to_string' overload in namespace, 'to_string' member "
11060  "function, or operator<<(ostream&, ...) present",
11061  detail::demangle<T>().data());
11062  }
11063 
11064  template <typename T>
11065  int adl_default_to_string(std::true_type, lua_State* L) {
11066  using namespace std;
11067  decltype(auto) ts = to_string(stack::get<T>(L, 1));
11068  return stack::push(L, std::forward<decltype(ts)>(ts));
11069  }
11070 
11071  template <typename T>
11072  int adl_default_to_string(std::false_type, lua_State* L) {
11073  return member_default_to_string<T>(meta::supports_to_string_member<T>(), L);
11074  }
11075 
11076  template <typename T>
11077  int oss_default_to_string(std::true_type, lua_State* L) {
11078  std::ostringstream oss;
11079  oss << stack::unqualified_get<T>(L, 1);
11080  return stack::push(L, oss.str());
11081  }
11082 
11083  template <typename T>
11084  int oss_default_to_string(std::false_type, lua_State* L) {
11085  return adl_default_to_string<T>(meta::supports_adl_to_string<T>(), L);
11086  }
11087 
11088  template <typename T>
11090  return oss_default_to_string<T>(meta::supports_op_left_shift<std::ostream, T>(), L);
11091  }
11092 
11093  template <typename T>
11095  decltype(auto) self = stack::unqualified_get<T>(L, 1);
11096  return stack::push(L, self.size());
11097  }
11098 
11099  template <typename T, typename Op>
11101  if constexpr (std::is_void_v<T>) {
11102  return stack::push(L, false);
11103  }
11104  else {
11105  auto maybel = stack::unqualified_check_get<T>(L, 1);
11106  if (!maybel) {
11107  return stack::push(L, false);
11108  }
11109  auto mayber = stack::unqualified_check_get<T>(L, 2);
11110  if (!mayber) {
11111  return stack::push(L, false);
11112  }
11113  decltype(auto) l = *maybel;
11114  decltype(auto) r = *mayber;
11115  if constexpr (std::is_same_v<no_comp, Op>) {
11116  std::equal_to<> op;
11117  return stack::push(L, op(detail::ptr(l), detail::ptr(r)));
11118  }
11119  else {
11120  if constexpr (std::is_same_v<std::equal_to<>, Op> // clang-format hack
11121  || std::is_same_v<std::less_equal<>, Op> //
11122  || std::is_same_v<std::less_equal<>, Op>) { //
11123  if (detail::ptr(l) == detail::ptr(r)) {
11124  return stack::push(L, true);
11125  }
11126  }
11127  Op op;
11128  return stack::push(L, op(detail::deref(l), detail::deref(r)));
11129  }
11130  }
11131  }
11132 
11133  template <typename T, typename IFx, typename Fx>
11134  void insert_default_registrations(IFx&& ifx, Fx&& fx);
11135 
11136  template <typename T, bool, bool>
11138 
11139  template <typename T>
11140  struct get_is_primitive<T, true, false>
11141  : meta::neg<std::is_reference<decltype(sol_lua_get(types<T>(), nullptr, -1, std::declval<stack::record&>()))>> { };
11142 
11143  template <typename T>
11144  struct get_is_primitive<T, false, true>
11145  : meta::neg<std::is_reference<decltype(sol_lua_get(types<meta::unqualified_t<T>>(), nullptr, -1, std::declval<stack::record&>()))>> { };
11146 
11147  template <typename T>
11148  struct get_is_primitive<T, true, true> : get_is_primitive<T, true, false> { };
11149 
11150  } // namespace detail
11151 
11152  template <typename T>
11154  : detail::get_is_primitive<T, meta::meta_detail::is_adl_sol_lua_get_v<T>, meta::meta_detail::is_adl_sol_lua_get_v<meta::unqualified_t<T>>> { };
11155 
11156 } // namespace sol
11157 
11158 // end of sol/stack_core.hpp
11159 
11160 // beginning of sol/stack_check.hpp
11161 
11162 // beginning of sol/stack_check_unqualified.hpp
11163 
11164 #include <memory>
11165 #include <functional>
11166 #include <utility>
11167 #include <cmath>
11168 #include <optional>
11169 #if SOL_IS_ON(SOL_STD_VARIANT_I_)
11170 #include <variant>
11171 #endif // variant shenanigans
11172 
11173 namespace sol { namespace stack {
11174  namespace stack_detail {
11175  inline bool impl_check_metatable(lua_State* L, int index, const std::string& metakey, bool poptable) {
11176  luaL_getmetatable(L, &metakey[0]);
11177  const type expectedmetatabletype = static_cast<type>(lua_type(L, -1));
11178  if (expectedmetatabletype != type::lua_nil) {
11179  if (lua_rawequal(L, -1, index) == 1) {
11180  lua_pop(L, 1 + static_cast<int>(poptable));
11181  return true;
11182  }
11183  }
11184  lua_pop(L, 1);
11185  return false;
11186  }
11187 
11188  template <typename T, bool poptable = true>
11189  inline bool check_metatable(lua_State* L, int index = -2) {
11190  return impl_check_metatable(L, index, usertype_traits<T>::metatable(), poptable);
11191  }
11192 
11193  template <type expected, int (*check_func)(lua_State*, int)>
11194  struct basic_check {
11195  template <typename Handler>
11196  static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
11197  tracking.use(1);
11198  bool success = check_func(L, index) == 1;
11199  if (!success) {
11200  // expected type, actual type
11201  handler(L, index, expected, type_of(L, index), "");
11202  }
11203  return success;
11204  }
11205  };
11206  } // namespace stack_detail
11207 
11208  template <typename T, typename>
11210  template <typename Handler>
11211  static bool check(lua_State*, int, type, Handler&&, record&) {
11212  return false;
11213  }
11214  };
11215 
11216  template <typename T, typename>
11218  template <typename Handler>
11219  static bool check(lua_State* L, int index, type index_type, Handler&& handler, record& tracking) {
11220  return stack_detail::unqualified_interop_check<T>(L, index, index_type, std::forward<Handler>(handler), tracking);
11221  }
11222  };
11223 
11224  template <typename T, type expected, typename>
11225  struct unqualified_checker {
11226  template <typename Handler>
11227  static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
11228  if constexpr (std::is_same_v<T, bool>) {
11229  tracking.use(1);
11230  bool success = lua_isboolean(L, index) == 1;
11231  if (!success) {
11232  // expected type, actual type
11233  handler(L, index, expected, type_of(L, index), "");
11234  }
11235  return success;
11236  }
11237  else if constexpr (meta::any_same_v<T, char /* , char8_t*/, char16_t, char32_t>) {
11238  return stack::check<std::basic_string<T>>(L, index, std::forward<Handler>(handler), tracking);
11239  }
11240  else if constexpr (std::is_integral_v<T> || std::is_same_v<T, lua_Integer>) {
11241  tracking.use(1);
11242 #if SOL_LUA_VESION_I_ >= 503
11243  // Lua 5.3 and greater checks for numeric precision
11244 #if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS_I_)
11245  // imprecise, sloppy conversions
11246  int isnum = 0;
11247  lua_tointegerx(L, index, &isnum);
11248  const bool success = isnum != 0;
11249  if (!success) {
11250  // expected type, actual type
11252  }
11253 #elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_)
11254  // this check is precise, do not convert
11255  if (lua_isinteger(L, index) == 1) {
11256  return true;
11257  }
11258  const bool success = false;
11259  if (!success) {
11260  // expected type, actual type
11262  }
11263 #else
11264  // Numerics are neither safe nor string-convertible
11265  type t = type_of(L, index);
11266  const bool success = t == type::number;
11267 #endif
11268  if (!success) {
11269  // expected type, actual type
11270  handler(L, index, type::number, type_of(L, index), detail::not_a_number);
11271  }
11272  return success;
11273 #else
11274  // Lua 5.2 and below checks
11275 #if SOL_IS_OFF(SOL_STRINGS_ARE_NUMBERS_I_)
11276  // must pre-check, because it will convert
11277  type t = type_of(L, index);
11278  if (t != type::number) {
11279  // expected type, actual type
11280  handler(L, index, type::number, t, detail::not_a_number);
11281  return false;
11282  }
11283 #endif // Do not allow strings to be numbers
11284 
11285 #if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_)
11286  int isnum = 0;
11287  const lua_Number v = lua_tonumberx(L, index, &isnum);
11288  const bool success = isnum != 0 && static_cast<lua_Number>(llround(v)) == v;
11289 #else
11290  const bool success = true;
11291 #endif // Safe numerics and number precision checking
11292  if (!success) {
11293  // Use defines to provide a better error message!
11294 #if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS_I_)
11296 #elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_)
11298 #else
11299  handler(L, index, type::number, t, detail::not_a_number);
11300 #endif
11301  }
11302  return success;
11303 #endif
11304  }
11305  else if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, lua_Number>) {
11306  tracking.use(1);
11307 #if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS_I_)
11308  bool success = lua_isnumber(L, index) == 1;
11309  if (!success) {
11310  // expected type, actual type
11312  }
11313  return success;
11314 #else
11315  type t = type_of(L, index);
11316  bool success = t == type::number;
11317  if (!success) {
11318  // expected type, actual type
11319  handler(L, index, type::number, t, detail::not_a_number);
11320  }
11321  return success;
11322 #endif // Strings are Numbers
11323  }
11324  else if constexpr (meta::any_same_v<T, type, this_state, this_main_state, this_environment, variadic_args>) {
11325  (void)L;
11326  (void)index;
11327  (void)handler;
11328  tracking.use(0);
11329  return true;
11330  }
11331  else if constexpr (is_unique_usertype_v<T>) {
11332  using proper_T = typename unique_usertype_traits<T>::type;
11333  const type indextype = type_of(L, index);
11334  tracking.use(1);
11335  if (indextype != type::userdata) {
11336  handler(L, index, type::userdata, indextype, "value is not a userdata");
11337  return false;
11338  }
11339  if (lua_getmetatable(L, index) == 0) {
11340  return true;
11341  }
11342  int metatableindex = lua_gettop(L);
11344  void* memory = lua_touserdata(L, index);
11347  bool success = &detail::usertype_unique_alloc_destroy<proper_T, T> == pdx;
11348  if (!success) {
11349  memory = detail::align_usertype_unique_tag<true>(memory);
11350 #if 0
11351  // New version
11352 #else
11353  const char*& name_tag = *static_cast<const char**>(memory);
11354  success = usertype_traits<T>::qualified_name() == name_tag;
11355 #endif
11356  if (!success) {
11357  handler(L, index, type::userdata, indextype, "value is a userdata but is not the correct unique usertype");
11358  }
11359  }
11360  return success;
11361  }
11362  lua_pop(L, 1);
11363  handler(L, index, type::userdata, indextype, "unrecognized userdata (not pushed by sol?)");
11364  return false;
11365  }
11366  else if constexpr (meta::any_same_v<T, lua_nil_t, std::nullopt_t, nullopt_t>) {
11367  bool success = lua_isnil(L, index);
11368  if (success) {
11369  tracking.use(1);
11370  return success;
11371  }
11372  tracking.use(0);
11373  success = lua_isnone(L, index);
11374  if (!success) {
11375  // expected type, actual type
11376  handler(L, index, expected, type_of(L, index), "");
11377  }
11378  return success;
11379  }
11380  else if constexpr (std::is_same_v<T, env_key_t>) {
11381  tracking.use(1);
11382  type t = type_of(L, index);
11383  if (t == type::table || t == type::none || t == type::lua_nil || t == type::userdata) {
11384  return true;
11385  }
11386  handler(L, index, type::table, t, "value cannot not have a valid environment");
11387  return true;
11388  }
11389  else if constexpr (std::is_same_v<T, detail::non_lua_nil_t>) {
11390  return !stack::unqualified_check<lua_nil_t>(L, index, std::forward<Handler>(handler), tracking);
11391  }
11392  else if constexpr (meta::is_specialization_of_v<T, basic_lua_table>) {
11393  tracking.use(1);
11394  type t = type_of(L, index);
11395  if (t != type::table) {
11396  handler(L, index, type::table, t, "value is not a table");
11397  return false;
11398  }
11399  return true;
11400  }
11401  else if constexpr (meta::is_specialization_of_v<T, basic_bytecode>) {
11402  tracking.use(1);
11403  type t = type_of(L, index);
11404  if (t != type::function) {
11405  handler(L, index, type::function, t, "value is not a function that can be dumped");
11406  return false;
11407  }
11408  return true;
11409  }
11410  else if constexpr (meta::is_specialization_of_v<T, basic_environment>) {
11411  tracking.use(1);
11412  if (lua_getmetatable(L, index) == 0) {
11413  return true;
11414  }
11415  type t = type_of(L, -1);
11416  if (t == type::table || t == type::none || t == type::lua_nil) {
11417  lua_pop(L, 1);
11418  return true;
11419  }
11420  if (t != type::userdata) {
11421  lua_pop(L, 1);
11422  handler(L, index, type::table, t, "value does not have a valid metatable");
11423  return false;
11424  }
11425  return true;
11426  }
11427  else if constexpr (std::is_same_v<T, metatable_key_t>) {
11428  tracking.use(1);
11429  if (lua_getmetatable(L, index) == 0) {
11430  return true;
11431  }
11432  type t = type_of(L, -1);
11433  if (t == type::table || t == type::none || t == type::lua_nil) {
11434  lua_pop(L, 1);
11435  return true;
11436  }
11437  if (t != type::userdata) {
11438  lua_pop(L, 1);
11439  handler(L, index, expected, t, "value does not have a valid metatable");
11440  return false;
11441  }
11442  return true;
11443  }
11444  else if constexpr (std::is_same_v<T, luaL_Stream*> || std::is_same_v<T, luaL_Stream>) {
11445  if (lua_getmetatable(L, index) == 0) {
11446  type t = type_of(L, index);
11447  handler(L, index, expected, t, "value is not a valid luaL_Stream (has no metatable/is not a valid value)");
11448  return false;
11449  }
11451  if (type_of(L, index) != type::table) {
11452  type t = type_of(L, index);
11453  lua_pop(L, 1);
11454  handler(L,
11455  index,
11456  expected,
11457  t,
11458  "value is not a valid luaL_Stream (there is no metatable for luaL_Stream -- did you forget to "
11459  "my_lua_state.open_libraries(sol::lib::state) or equivalent?)");
11460  return false;
11461  }
11462  int is_stream_table = lua_compare(L, -1, -2, LUA_OPEQ);
11463  lua_pop(L, 2);
11464  if (is_stream_table == 0) {
11465  type t = type_of(L, index);
11466  handler(L, index, expected, t, "value is not a valid luaL_Stream (incorrect metatable)");
11467  return false;
11468  }
11469  return true;
11470  }
11471  else if constexpr (meta::is_optional_v<T>) {
11472  using ValueType = typename T::value_type;
11473  (void)handler;
11474  type t = type_of(L, index);
11475  if (t == type::none) {
11476  tracking.use(0);
11477  return true;
11478  }
11479  if (t == type::lua_nil) {
11480  tracking.use(1);
11481  return true;
11482  }
11483  return stack::unqualified_check<ValueType>(L, index, no_panic, tracking);
11484  }
11485 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
11486  else if constexpr (std::is_function_v<T> || (std::is_pointer_v<T> && std::is_function_v<std::remove_pointer_t<T>>)) {
11487  return stack_detail::check_function_pointer<std::remove_pointer_t<T>>(L, index, std::forward<Handler>(handler), tracking);
11488  }
11489 #endif
11490  else if constexpr (expected == type::userdata) {
11491  if constexpr (meta::any_same_v<T, userdata_value> || meta::is_specialization_of_v<T, basic_userdata>) {
11492  tracking.use(1);
11493  type t = type_of(L, index);
11494  bool success = t == type::userdata;
11495  if (!success) {
11496  // expected type, actual type
11497  handler(L, index, type::userdata, t, "");
11498  }
11499  return success;
11500  }
11501  else if constexpr (meta::is_specialization_of_v<T, user>) {
11503  (void)c;
11504  return c.check(L, index, std::forward<Handler>(handler), tracking);
11505  }
11506  else {
11507  if constexpr (std::is_pointer_v<T>) {
11508  return check_usertype<T>(L, index, std::forward<Handler>(handler), tracking);
11509  }
11510  else if constexpr (meta::is_specialization_of_v<T, std::reference_wrapper>) {
11511  using T_internal = typename T::type;
11512  return stack::check<T_internal>(L, index, std::forward<Handler>(handler), tracking);
11513  }
11514  else {
11515  return check_usertype<T>(L, index, std::forward<Handler>(handler), tracking);
11516  }
11517  }
11518  }
11519  else if constexpr (expected == type::poly) {
11520  tracking.use(1);
11521  bool success = is_lua_reference_v<T> || !lua_isnone(L, index);
11522  if (!success) {
11523  // expected type, actual type
11524  handler(L, index, type::poly, type_of(L, index), "");
11525  }
11526  return success;
11527  }
11528  else if constexpr (expected == type::lightuserdata) {
11529  tracking.use(1);
11530  type t = type_of(L, index);
11531  bool success = t == type::userdata || t == type::lightuserdata;
11532  if (!success) {
11533  // expected type, actual type
11534  handler(L, index, type::lightuserdata, t, "");
11535  }
11536  return success;
11537  }
11538  else if constexpr (expected == type::function) {
11539  if constexpr (meta::any_same_v<T, lua_CFunction, std::remove_pointer_t<lua_CFunction>, c_closure>) {
11540  tracking.use(1);
11541  bool success = lua_iscfunction(L, index) == 1;
11542  if (!success) {
11543  // expected type, actual type
11544  handler(L, index, expected, type_of(L, index), "");
11545  }
11546  return success;
11547  }
11548  else {
11549  tracking.use(1);
11550  type t = type_of(L, index);
11551  if (t == type::lua_nil || t == type::none || t == type::function) {
11552  // allow for lua_nil to be returned
11553  return true;
11554  }
11555  if (t != type::userdata && t != type::table) {
11556  handler(L, index, type::function, t, "must be a function or table or a userdata");
11557  return false;
11558  }
11559  // Do advanced check for call-style userdata?
11560  static const auto& callkey = to_string(meta_function::call);
11561  if (lua_getmetatable(L, index) == 0) {
11562  // No metatable, no __call key possible
11563  handler(L, index, type::function, t, "value is not a function and does not have overriden metatable");
11564  return false;
11565  }
11566  if (lua_isnoneornil(L, -1)) {
11567  lua_pop(L, 1);
11568  handler(L, index, type::function, t, "value is not a function and does not have valid metatable");
11569  return false;
11570  }
11571  lua_getfield(L, -1, &callkey[0]);
11572  if (lua_isnoneornil(L, -1)) {
11573  lua_pop(L, 2);
11574  handler(L, index, type::function, t, "value's metatable does not have __call overridden in metatable, cannot call this type");
11575  return false;
11576  }
11577  // has call, is definitely a function
11578  lua_pop(L, 2);
11579  return true;
11580  }
11581  }
11582  else if constexpr (expected == type::table) {
11583  tracking.use(1);
11584  type t = type_of(L, index);
11585  if (t == type::table) {
11586  return true;
11587  }
11588  if (t != type::userdata) {
11589  handler(L, index, type::table, t, "value is not a table or a userdata that can behave like one");
11590  return false;
11591  }
11592  return true;
11593  }
11594  else {
11595  tracking.use(1);
11596  const type indextype = type_of(L, index);
11597  bool success = expected == indextype;
11598  if (!success) {
11599  // expected type, actual type, message
11600  handler(L, index, expected, indextype, "");
11601  }
11602  return success;
11603  }
11604  }
11605  };
11606 
11607  template <typename T>
11608  struct unqualified_checker<non_null<T>, type::userdata> : unqualified_checker<T, lua_type_of_v<T>> { };
11609 
11610  template <typename T>
11611  struct unqualified_checker<detail::as_value_tag<T>, type::userdata> {
11612  template <typename Handler>
11613  static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
11614  const type indextype = type_of(L, index);
11615  return check(types<T>(), L, index, indextype, std::forward<Handler>(handler), tracking);
11616  }
11617 
11618  template <typename U, typename Handler>
11619  static bool check(types<U>, lua_State* L, int index, type indextype, Handler&& handler, record& tracking) {
11620  if constexpr (
11621  std::is_same_v<T,
11622  lightuserdata_value> || std::is_same_v<T, userdata_value> || std::is_same_v<T, userdata> || std::is_same_v<T, lightuserdata>) {
11623  tracking.use(1);
11624  if (indextype != type::userdata) {
11625  handler(L, index, type::userdata, indextype, "value is not a valid userdata");
11626  return false;
11627  }
11628  return true;
11629  }
11630  else {
11631 #if SOL_IS_ON(SOL_USE_INTEROP_I_)
11632  if (stack_detail::interop_check<U>(L, index, indextype, handler, tracking)) {
11633  return true;
11634  }
11635 #endif // interop extensibility
11636  tracking.use(1);
11637  if (indextype != type::userdata) {
11638  handler(L, index, type::userdata, indextype, "value is not a valid userdata");
11639  return false;
11640  }
11641  if (lua_getmetatable(L, index) == 0) {
11642  return true;
11643  }
11644  int metatableindex = lua_gettop(L);
11645  if (stack_detail::check_metatable<U>(L, metatableindex))
11646  return true;
11647  if (stack_detail::check_metatable<U*>(L, metatableindex))
11648  return true;
11650  return true;
11651  if (stack_detail::check_metatable<as_container_t<U>>(L, metatableindex))
11652  return true;
11653  bool success = false;
11654  bool has_derived = derive<T>::value || weak_derive<T>::value;
11655  if (has_derived) {
11656 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
11658 #endif // make sure stack doesn't overflow
11659  auto pn = stack::pop_n(L, 1);
11661  lua_rawget(L, metatableindex);
11662  if (type_of(L, -1) != type::lua_nil) {
11663  void* basecastdata = lua_touserdata(L, -1);
11664  detail::inheritance_check_function ic = reinterpret_cast<detail::inheritance_check_function>(basecastdata);
11665  success = ic(usertype_traits<T>::qualified_name());
11666  }
11667  }
11668  lua_pop(L, 1);
11669  if (!success) {
11670  handler(L, index, type::userdata, indextype, "value at this index does not properly reflect the desired type");
11671  return false;
11672  }
11673  return true;
11674  }
11675  }
11676  };
11677 
11678  template <typename T>
11679  struct unqualified_checker<detail::as_pointer_tag<T>, type::userdata> {
11680  template <typename Handler>
11681  static bool check(lua_State* L, int index, type indextype, Handler&& handler, record& tracking) {
11682  if (indextype == type::lua_nil) {
11683  tracking.use(1);
11684  return true;
11685  }
11686  return check_usertype<std::remove_pointer_t<T>>(L, index, std::forward<Handler>(handler), tracking);
11687  }
11688 
11689  template <typename Handler>
11690  static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
11691  const type indextype = type_of(L, index);
11692  return check(L, index, indextype, std::forward<Handler>(handler), tracking);
11693  }
11694  };
11695 
11696  template <typename... Args>
11697  struct unqualified_checker<std::tuple<Args...>, type::poly> {
11698  template <typename Handler>
11699  static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
11700  return stack::multi_check<Args...>(L, index, std::forward<Handler>(handler), tracking);
11701  }
11702  };
11703 
11704  template <typename A, typename B>
11705  struct unqualified_checker<std::pair<A, B>, type::poly> {
11706  template <typename Handler>
11707  static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
11708  return stack::multi_check<A, B>(L, index, std::forward<Handler>(handler), tracking);
11709  }
11710  };
11711 
11712 #if SOL_IS_ON(SOL_STD_VARIANT_I_)
11713 
11714  template <typename... Tn>
11715  struct unqualified_checker<std::variant<Tn...>, type::poly> {
11716  typedef std::variant<Tn...> V;
11717  typedef std::variant_size<V> V_size;
11718  typedef std::integral_constant<bool, V_size::value == 0> V_is_empty;
11719 
11720  template <typename Handler>
11721  static bool is_one(std::integral_constant<std::size_t, 0>, lua_State* L, int index, Handler&& handler, record& tracking) {
11722  if constexpr (V_is_empty::value) {
11723  if (lua_isnone(L, index)) {
11724  return true;
11725  }
11726  }
11727  tracking.use(1);
11728  handler(L, index, type::poly, type_of(L, index), "value does not fit any type present in the variant");
11729  return false;
11730  }
11731 
11732  template <std::size_t I, typename Handler>
11733  static bool is_one(std::integral_constant<std::size_t, I>, lua_State* L, int index, Handler&& handler, record& tracking) {
11734  typedef std::variant_alternative_t<I - 1, V> T;
11735  record temp_tracking = tracking;
11736  if (stack::check<T>(L, index, no_panic, temp_tracking)) {
11737  tracking = temp_tracking;
11738  return true;
11739  }
11740  return is_one(std::integral_constant<std::size_t, I - 1>(), L, index, std::forward<Handler>(handler), tracking);
11741  }
11742 
11743  template <typename Handler>
11744  static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
11745  return is_one(std::integral_constant<std::size_t, V_size::value>(), L, index, std::forward<Handler>(handler), tracking);
11746  }
11747  };
11748 
11749 #endif // variant shenanigans
11750 
11751 }} // namespace sol::stack
11752 
11753 // end of sol/stack_check_unqualified.hpp
11754 
11755 // beginning of sol/stack_check_qualified.hpp
11756 
11757 namespace sol {
11758 namespace stack {
11759 
11760  template <typename X, type expected, typename>
11761  struct qualified_checker {
11762  template <typename Handler>
11763  static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
11764  if constexpr (!std::is_reference_v<X> && is_unique_usertype_v<X>) {
11766  using T = typename u_traits::type;
11767  if constexpr (is_base_rebindable_non_void_v<u_traits>) {
11768  using rebind_t = typename u_traits::template rebind_base<void>;
11769  // we have a unique pointer type that can be
11770  // rebound to a base/derived type
11771  const type indextype = type_of(L, index);
11772  tracking.use(1);
11773  if (indextype != type::userdata) {
11774  handler(L, index, type::userdata, indextype, "value is not a userdata");
11775  return false;
11776  }
11777  void* memory = lua_touserdata(L, index);
11780  if (&detail::usertype_unique_alloc_destroy<T, X> == pdx) {
11781  return true;
11782  }
11783  if constexpr (derive<T>::value) {
11784  memory = detail::align_usertype_unique_tag<true, false>(memory);
11785  detail::unique_tag& ic = *reinterpret_cast<detail::unique_tag*>(memory);
11788  if (ic(nullptr, nullptr, ti, rebind_ti) != 0) {
11789  return true;
11790  }
11791  }
11792  handler(L, index, type::userdata, indextype, "value is a userdata but is not the correct unique usertype");
11793  return false;
11794  }
11795  else {
11796  return stack::unqualified_check<X>(L, index, std::forward<Handler>(handler), tracking);
11797  }
11798  }
11799  else if constexpr (!std::is_reference_v<X> && is_container_v<X>) {
11800  if (type_of(L, index) == type::userdata) {
11801  return stack::unqualified_check<X>(L, index, std::forward<Handler>(handler), tracking);
11802  }
11803  else {
11804  return stack::unqualified_check<nested<X>>(L, index, std::forward<Handler>(handler), tracking);
11805  }
11806  }
11807  else if constexpr (!std::is_reference_v<X> && meta::is_specialization_of_v<X, nested>) {
11808  using NestedX = typename meta::unqualified_t<X>::nested_type;
11809  return stack::check<NestedX>(L, index, ::std::forward<Handler>(handler), tracking);
11810  }
11811  else {
11812  return stack::unqualified_check<X>(L, index, std::forward<Handler>(handler), tracking);
11813  }
11814  }
11815  };
11816 }
11817 } // namespace sol::stack
11818 
11819 // end of sol/stack_check_qualified.hpp
11820 
11821 // end of sol/stack_check.hpp
11822 
11823 // beginning of sol/stack_get.hpp
11824 
11825 // beginning of sol/stack_get_unqualified.hpp
11826 
11827 // beginning of sol/overload.hpp
11828 
11829 #include <utility>
11830 
11831 namespace sol {
11832  template <typename... Functions>
11833  struct overload_set {
11834  std::tuple<Functions...> functions;
11835  template <typename Arg, typename... Args, meta::disable<std::is_same<overload_set, meta::unqualified_t<Arg>>> = meta::enabler>
11836  overload_set(Arg&& arg, Args&&... args)
11837  : functions(std::forward<Arg>(arg), std::forward<Args>(args)...) {
11838  }
11839  overload_set(const overload_set&) = default;
11840  overload_set(overload_set&&) = default;
11841  overload_set& operator=(const overload_set&) = default;
11842  overload_set& operator=(overload_set&&) = default;
11843  };
11844 
11845  template <typename... Args>
11846  decltype(auto) overload(Args&&... args) {
11847  return overload_set<std::decay_t<Args>...>(std::forward<Args>(args)...);
11848  }
11849 } // namespace sol
11850 
11851 // end of sol/overload.hpp
11852 
11853 // beginning of sol/unicode.hpp
11854 
11855 #include <array>
11856 #include <cstring>
11857 
11858 namespace sol {
11859  // Everything here was lifted pretty much straight out of
11860  // ogonek, because fuck figuring it out=
11861  namespace unicode {
11862  enum class error_code {
11863  ok = 0,
11870  };
11871 
11872  inline const string_view& to_string(error_code ec) {
11873  static const string_view storage[7] = {
11874  "ok",
11875  "invalid code points",
11876  "invalid code unit",
11877  "invalid leading surrogate",
11878  "invalid trailing surrogate",
11879  "sequence too short",
11880  "overlong sequence"
11881  };
11882  return storage[static_cast<std::size_t>(ec)];
11883  }
11884 
11885  template <typename It>
11888  char32_t codepoint;
11889  It next;
11890  };
11891 
11892  template <typename C>
11895  std::size_t code_units_size;
11896  std::array<C, 4> code_units;
11897  };
11898 
11900  // codepoint related
11901  static constexpr char32_t last_code_point = 0x10FFFF;
11902 
11903  static constexpr char32_t first_lead_surrogate = 0xD800;
11904  static constexpr char32_t last_lead_surrogate = 0xDBFF;
11905 
11906  static constexpr char32_t first_trail_surrogate = 0xDC00;
11907  static constexpr char32_t last_trail_surrogate = 0xDFFF;
11908 
11909  static constexpr char32_t first_surrogate = first_lead_surrogate;
11910  static constexpr char32_t last_surrogate = last_trail_surrogate;
11911 
11912  static constexpr bool is_lead_surrogate(char32_t u) {
11913  return u >= first_lead_surrogate && u <= last_lead_surrogate;
11914  }
11915  static constexpr bool is_trail_surrogate(char32_t u) {
11916  return u >= first_trail_surrogate && u <= last_trail_surrogate;
11917  }
11918  static constexpr bool is_surrogate(char32_t u) {
11919  return u >= first_surrogate && u <= last_surrogate;
11920  }
11921 
11922  // utf8 related
11923  static constexpr auto last_1byte_value = 0x7Fu;
11924  static constexpr auto last_2byte_value = 0x7FFu;
11925  static constexpr auto last_3byte_value = 0xFFFFu;
11926 
11927  static constexpr auto start_2byte_mask = 0x80u;
11928  static constexpr auto start_3byte_mask = 0xE0u;
11929  static constexpr auto start_4byte_mask = 0xF0u;
11930 
11931  static constexpr auto continuation_mask = 0xC0u;
11932  static constexpr auto continuation_signature = 0x80u;
11933 
11934  static constexpr bool is_invalid(unsigned char b) {
11935  return b == 0xC0 || b == 0xC1 || b > 0xF4;
11936  }
11937 
11938  static constexpr bool is_continuation(unsigned char b) {
11939  return (b & unicode_detail::continuation_mask) == unicode_detail::continuation_signature;
11940  }
11941 
11942  static constexpr bool is_overlong(char32_t u, std::size_t bytes) {
11943  return u <= unicode_detail::last_1byte_value || (u <= unicode_detail::last_2byte_value && bytes > 2)
11944  || (u <= unicode_detail::last_3byte_value && bytes > 3);
11945  }
11946 
11947  static constexpr int sequence_length(unsigned char b) {
11948  return (b & start_2byte_mask) == 0 ? 1
11949  : (b & start_3byte_mask) != start_3byte_mask ? 2
11950  : (b & start_4byte_mask) != start_4byte_mask ? 3
11951  : 4;
11952  }
11953 
11954  static constexpr char32_t decode(unsigned char b0, unsigned char b1) {
11955  return ((b0 & 0x1F) << 6) | (b1 & 0x3F);
11956  }
11957  static constexpr char32_t decode(unsigned char b0, unsigned char b1, unsigned char b2) {
11958  return ((b0 & 0x0F) << 12) | ((b1 & 0x3F) << 6) | (b2 & 0x3F);
11959  }
11960  static constexpr char32_t decode(unsigned char b0, unsigned char b1, unsigned char b2, unsigned char b3) {
11961  return ((b0 & 0x07) << 18) | ((b1 & 0x3F) << 12) | ((b2 & 0x3F) << 6) | (b3 & 0x3F);
11962  }
11963 
11964  // utf16 related
11965  static constexpr char32_t last_bmp_value = 0xFFFF;
11966  static constexpr char32_t normalizing_value = 0x10000;
11967  static constexpr int lead_surrogate_bitmask = 0xFFC00;
11968  static constexpr int trail_surrogate_bitmask = 0x3FF;
11969  static constexpr int lead_shifted_bits = 10;
11970  static constexpr char32_t replacement = 0xFFFD;
11971 
11972  static char32_t combine_surrogates(char16_t lead, char16_t trail) {
11973  auto hi = lead - first_lead_surrogate;
11974  auto lo = trail - first_trail_surrogate;
11975  return normalizing_value + ((hi << lead_shifted_bits) | lo);
11976  }
11977  };
11978 
11981  er.error = error_code::ok;
11982  if (codepoint <= unicode_detail::last_1byte_value) {
11983  er.code_units_size = 1;
11984  er.code_units = std::array<char, 4>{ { static_cast<char>(codepoint) } };
11985  }
11986  else if (codepoint <= unicode_detail::last_2byte_value) {
11987  er.code_units_size = 2;
11988  er.code_units = std::array<char, 4>{{
11989  static_cast<char>(0xC0 | ((codepoint & 0x7C0) >> 6)),
11990  static_cast<char>(0x80 | (codepoint & 0x3F)),
11991  }};
11992  }
11993  else if (codepoint <= unicode_detail::last_3byte_value) {
11994  er.code_units_size = 3;
11995  er.code_units = std::array<char, 4>{{
11996  static_cast<char>(0xE0 | ((codepoint & 0xF000) >> 12)),
11997  static_cast<char>(0x80 | ((codepoint & 0xFC0) >> 6)),
11998  static_cast<char>(0x80 | (codepoint & 0x3F)),
11999  }};
12000  }
12001  else {
12002  er.code_units_size = 4;
12003  er.code_units = std::array<char, 4>{ {
12004  static_cast<char>(0xF0 | ((codepoint & 0x1C0000) >> 18)),
12005  static_cast<char>(0x80 | ((codepoint & 0x3F000) >> 12)),
12006  static_cast<char>(0x80 | ((codepoint & 0xFC0) >> 6)),
12007  static_cast<char>(0x80 | (codepoint & 0x3F)),
12008  } };
12009  }
12010  return er;
12011  }
12012 
12015 
12016  if (codepoint <= unicode_detail::last_bmp_value) {
12017  er.code_units_size = 1;
12018  er.code_units = std::array<char16_t, 4>{ { static_cast<char16_t>(codepoint) } };
12019  er.error = error_code::ok;
12020  }
12021  else {
12022  auto normal = codepoint - unicode_detail::normalizing_value;
12023  auto lead = unicode_detail::first_lead_surrogate + ((normal & unicode_detail::lead_surrogate_bitmask) >> unicode_detail::lead_shifted_bits);
12024  auto trail = unicode_detail::first_trail_surrogate + (normal & unicode_detail::trail_surrogate_bitmask);
12025  er.code_units = std::array<char16_t, 4>{ {
12026  static_cast<char16_t>(lead),
12027  static_cast<char16_t>(trail)
12028  } };
12029  er.code_units_size = 2;
12030  er.error = error_code::ok;
12031  }
12032  return er;
12033  }
12034 
12037  er.code_units_size = 1;
12038  er.code_units[0] = codepoint;
12039  er.error = error_code::ok;
12040  return er;
12041  }
12042 
12043  template <typename It>
12044  inline decoded_result<It> utf8_to_code_point(It it, It last) {
12045  decoded_result<It> dr;
12046  if (it == last) {
12047  dr.next = it;
12048  dr.error = error_code::sequence_too_short;
12049  return dr;
12050  }
12051 
12052  unsigned char b0 = *it;
12053  std::size_t length = unicode_detail::sequence_length(b0);
12054 
12055  if (length == 1) {
12056  dr.codepoint = static_cast<char32_t>(b0);
12057  dr.error = error_code::ok;
12058  ++it;
12059  dr.next = it;
12060  return dr;
12061  }
12062 
12063  if (unicode_detail::is_invalid(b0) || unicode_detail::is_continuation(b0)) {
12064  dr.error = error_code::invalid_code_unit;
12065  dr.next = it;
12066  return dr;
12067  }
12068 
12069  ++it;
12070  std::array<unsigned char, 4> b;
12071  b[0] = b0;
12072  for (std::size_t i = 1; i < length; ++i) {
12073  b[i] = *it;
12074  if (!unicode_detail::is_continuation(b[i])) {
12075  dr.error = error_code::invalid_code_unit;
12076  dr.next = it;
12077  return dr;
12078  }
12079  ++it;
12080  }
12081 
12082  char32_t decoded;
12083  switch (length) {
12084  case 2:
12085  decoded = unicode_detail::decode(b[0], b[1]);
12086  break;
12087  case 3:
12088  decoded = unicode_detail::decode(b[0], b[1], b[2]);
12089  break;
12090  default:
12091  decoded = unicode_detail::decode(b[0], b[1], b[2], b[3]);
12092  break;
12093  }
12094 
12095  if (unicode_detail::is_overlong(decoded, length)) {
12096  dr.error = error_code::overlong_sequence;
12097  return dr;
12098  }
12099  if (unicode_detail::is_surrogate(decoded) || decoded > unicode_detail::last_code_point) {
12100  dr.error = error_code::invalid_code_point;
12101  return dr;
12102  }
12103 
12104  // then everything is fine
12105  dr.codepoint = decoded;
12106  dr.error = error_code::ok;
12107  dr.next = it;
12108  return dr;
12109  }
12110 
12111  template <typename It>
12112  inline decoded_result<It> utf16_to_code_point(It it, It last) {
12113  decoded_result<It> dr;
12114  if (it == last) {
12115  dr.next = it;
12116  dr.error = error_code::sequence_too_short;
12117  return dr;
12118  }
12119 
12120  char16_t lead = static_cast<char16_t>(*it);
12121 
12122  if (!unicode_detail::is_surrogate(lead)) {
12123  ++it;
12124  dr.codepoint = static_cast<char32_t>(lead);
12125  dr.next = it;
12126  dr.error = error_code::ok;
12127  return dr;
12128  }
12129  if (!unicode_detail::is_lead_surrogate(lead)) {
12130  dr.error = error_code::invalid_leading_surrogate;
12131  dr.next = it;
12132  return dr;
12133  }
12134 
12135  ++it;
12136  auto trail = *it;
12137  if (!unicode_detail::is_trail_surrogate(trail)) {
12138  dr.error = error_code::invalid_trailing_surrogate;
12139  dr.next = it;
12140  return dr;
12141  }
12142 
12143  dr.codepoint = unicode_detail::combine_surrogates(lead, trail);
12144  dr.next = ++it;
12145  dr.error = error_code::ok;
12146  return dr;
12147  }
12148 
12149  template <typename It>
12150  inline decoded_result<It> utf32_to_code_point(It it, It last) {
12151  decoded_result<It> dr;
12152  if (it == last) {
12153  dr.next = it;
12154  dr.error = error_code::sequence_too_short;
12155  return dr;
12156  }
12157  dr.codepoint = static_cast<char32_t>(*it);
12158  dr.next = ++it;
12159  dr.error = error_code::ok;
12160  return dr;
12161  }
12162  }
12163 }
12164 // end of sol/unicode.hpp
12165 
12166 #include <memory>
12167 #include <functional>
12168 #include <utility>
12169 #include <cstdlib>
12170 #include <cmath>
12171 #include <string_view>
12172 #if SOL_IS_ON(SOL_STD_VARIANT_I_)
12173 #include <variant>
12174 #endif // Apple clang screwed up
12175 
12176 namespace sol { namespace stack {
12177 
12178  namespace stack_detail {
12179  template <typename Ch>
12181  std::size_t needed_size;
12182 
12183  count_code_units_utf() : needed_size(0) {
12184  }
12185 
12187  needed_size += er.code_units_size;
12188  }
12189  };
12190 
12191  template <typename Ch, typename ErCh>
12193  Ch* target_;
12194 
12195  copy_code_units_utf(Ch* target) : target_(target) {
12196  }
12197 
12199  std::memcpy(target_, er.code_units.data(), er.code_units_size * sizeof(ErCh));
12200  target_ += er.code_units_size;
12201  }
12202  };
12203 
12204  template <typename Ch, typename F>
12205  inline void convert(const char* strb, const char* stre, F&& f) {
12206  char32_t cp = 0;
12207  for (const char* strtarget = strb; strtarget < stre;) {
12208  auto dr = unicode::utf8_to_code_point(strtarget, stre);
12209  if (dr.error != unicode::error_code::ok) {
12211  ++strtarget;
12212  }
12213  else {
12214  cp = dr.codepoint;
12215  strtarget = dr.next;
12216  }
12217  if constexpr (std::is_same_v<Ch, char32_t>) {
12218  auto er = unicode::code_point_to_utf32(cp);
12219  f(er);
12220  }
12221  else {
12222  auto er = unicode::code_point_to_utf16(cp);
12223  f(er);
12224  }
12225  }
12226  }
12227 
12228  template <typename BaseCh, typename S>
12229  inline S get_into(lua_State* L, int index, record& tracking) {
12230  using Ch = typename S::value_type;
12231  tracking.use(1);
12232  size_t len;
12233  auto utf8p = lua_tolstring(L, index, &len);
12234  if (len < 1)
12235  return S();
12236  const char* strb = utf8p;
12237  const char* stre = utf8p + len;
12239  convert<BaseCh>(strb, stre, count_units);
12240  S r(count_units.needed_size, static_cast<Ch>(0));
12241  r.resize(count_units.needed_size);
12242  Ch* target = &r[0];
12244  convert<BaseCh>(strb, stre, copy_units);
12245  return r;
12246  }
12247  } // namespace stack_detail
12248 
12249  template <typename T, typename>
12250  struct unqualified_getter {
12251  static decltype(auto) get(lua_State* L, int index, record& tracking) {
12252  if constexpr (std::is_same_v<T, bool>) {
12253  tracking.use(1);
12254  return lua_toboolean(L, index) != 0;
12255  }
12256  else if constexpr (std::is_enum_v<T>) {
12257  tracking.use(1);
12258  return static_cast<T>(lua_tointegerx(L, index, nullptr));
12259  }
12260  else if constexpr (std::is_integral_v<T> || std::is_same_v<T, lua_Integer>) {
12261  tracking.use(1);
12262 #if SOL_LUA_VESION_I_ >= 503
12263  if (lua_isinteger(L, index) != 0) {
12264  return static_cast<T>(lua_tointeger(L, index));
12265  }
12266 #endif
12267  return static_cast<T>(llround(lua_tonumber(L, index)));
12268  }
12269  else if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, lua_Number>) {
12270  tracking.use(1);
12271  return static_cast<T>(lua_tonumber(L, index));
12272  }
12273  else if constexpr (is_lua_reference_v<T>) {
12274  tracking.use(1);
12275  return T(L, index);
12276  }
12277  else if constexpr (is_unique_usertype_v<T>) {
12278  using Real = typename unique_usertype_traits<T>::actual_type;
12279 
12280  tracking.use(1);
12281  void* memory = lua_touserdata(L, index);
12282  memory = detail::align_usertype_unique<Real>(memory);
12283  Real* mem = static_cast<Real*>(memory);
12284  return *mem;
12285  }
12286  else if constexpr (meta::is_optional_v<T>) {
12287  using ValueType = typename T::value_type;
12288  return unqualified_check_getter<ValueType>::template get_using<T>(L, index, no_panic, tracking);
12289  }
12290  else if constexpr (std::is_same_v<T, luaL_Stream*>) {
12291  luaL_Stream* pstream = static_cast<luaL_Stream*>(lua_touserdata(L, index));
12292  return pstream;
12293  }
12294  else if constexpr (std::is_same_v<T, luaL_Stream>) {
12295  luaL_Stream* pstream = static_cast<luaL_Stream*>(lua_touserdata(L, index));
12296  return *pstream;
12297  }
12298 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
12299  else if constexpr (std::is_function_v<T> || (std::is_pointer_v<T> && std::is_function_v<std::remove_pointer_t<T>>)) {
12300  return stack_detail::get_function_pointer<std::remove_pointer_t<T>>(L, index, tracking);
12301  }
12302 #endif
12303  else {
12304  return stack_detail::unchecked_unqualified_get<detail::as_value_tag<T>>(L, index, tracking);
12305  }
12306  }
12307  };
12308 
12309  template <typename X, typename>
12310  struct qualified_getter {
12311  static decltype(auto) get(lua_State* L, int index, record& tracking) {
12312  using Tu = meta::unqualified_t<X>;
12313  static constexpr bool is_userdata_of_some_kind
12314  = !std::is_reference_v<
12315  X> && is_container_v<Tu> && std::is_default_constructible_v<Tu> && !is_lua_primitive_v<Tu> && !is_transparent_argument_v<Tu>;
12316  if constexpr (is_userdata_of_some_kind) {
12317  if (type_of(L, index) == type::userdata) {
12318  return static_cast<Tu>(stack_detail::unchecked_unqualified_get<Tu>(L, index, tracking));
12319  }
12320  else {
12321  return stack_detail::unchecked_unqualified_get<sol::nested<Tu>>(L, index, tracking);
12322  }
12323  }
12324  else if constexpr (!std::is_reference_v<X> && is_unique_usertype_v<Tu> && !is_base_rebindable_non_void_v<unique_usertype_traits<Tu>>) {
12325  using u_traits = unique_usertype_traits<Tu>;
12326  using T = typename u_traits::type;
12327  using Real = typename u_traits::actual_type;
12328  tracking.use(1);
12329  void* memory = lua_touserdata(L, index);
12332  if (&detail::usertype_unique_alloc_destroy<T, X> == pdx) {
12333  memory = detail::align_usertype_unique_tag<true, false>(memory);
12334  memory = detail::align_usertype_unique<Real, true, false>(memory);
12335  Real* mem = static_cast<Real*>(memory);
12336  return static_cast<Real>(*mem);
12337  }
12338  Real r(nullptr);
12339  if constexpr (!derive<T>::value) {
12340  // TODO: abort / terminate, maybe only in debug modes?
12341  return static_cast<Real>(std::move(r));
12342  }
12343  else {
12344  memory = detail::align_usertype_unique_tag<true, false>(memory);
12345  detail::unique_tag& ic = *reinterpret_cast<detail::unique_tag*>(memory);
12346  memory = detail::align_usertype_unique<Real, true, false>(memory);
12348  int cast_operation;
12349  if constexpr (is_base_rebindable_v<u_traits>) {
12350  using rebind_t = typename u_traits::template rebind_base<void>;
12352  cast_operation = ic(memory, &r, ti, rebind_ti);
12353  }
12354  else {
12355  string_view rebind_ti("");
12356  cast_operation = ic(memory, &r, ti, rebind_ti);
12357  }
12358  switch (cast_operation) {
12359  case 1: {
12360  // it's a perfect match,
12361  // alias memory directly
12362  Real* mem = static_cast<Real*>(memory);
12363  return static_cast<Real>(*mem);
12364  }
12365  case 2:
12366  // it's a base match, return the
12367  // aliased creation
12368  return static_cast<Real>(std::move(r));
12369  default:
12370  // uh oh..
12371  break;
12372  }
12373  // TODO: abort / terminate, maybe only in debug modes?
12374  return static_cast<Real>(r);
12375  }
12376  }
12377  else {
12378  return stack_detail::unchecked_unqualified_get<Tu>(L, index, tracking);
12379  }
12380  }
12381  };
12382 
12383  template <typename T>
12386 
12387  template <typename V>
12388  static void push_back_at_end(std::true_type, types<V>, lua_State* L, T& cont, std::size_t) {
12389  cont.push_back(stack::get<V>(L, -lua_size<V>::value));
12390  }
12391 
12392  template <typename V>
12393  static void push_back_at_end(std::false_type, types<V> t, lua_State* L, T& cont, std::size_t idx) {
12394  insert_at_end(meta::has_insert<Tu>(), t, L, cont, idx);
12395  }
12396 
12397  template <typename V>
12398  static void insert_at_end(std::true_type, types<V>, lua_State* L, T& cont, std::size_t) {
12399  using std::cend;
12400  cont.insert(cend(cont), stack::get<V>(L, -lua_size<V>::value));
12401  }
12402 
12403  template <typename V>
12404  static void insert_at_end(std::false_type, types<V>, lua_State* L, T& cont, std::size_t idx) {
12405  cont[idx] = stack::get<V>(L, -lua_size<V>::value);
12406  }
12407 
12408  static bool max_size_check(std::false_type, T&, std::size_t) {
12409  return false;
12410  }
12411 
12412  static bool max_size_check(std::true_type, T& cont, std::size_t idx) {
12413  return idx >= cont.max_size();
12414  }
12415 
12416  static T get(lua_State* L, int relindex, record& tracking) {
12417  return get(meta::is_associative<Tu>(), L, relindex, tracking);
12418  }
12419 
12420  static T get(std::false_type, lua_State* L, int relindex, record& tracking) {
12421  typedef typename Tu::value_type V;
12422  return get(types<V>(), L, relindex, tracking);
12423  }
12424 
12425  template <typename V>
12426  static T get(types<V> t, lua_State* L, int relindex, record& tracking) {
12427  tracking.use(1);
12428 
12429  // the W4 flag is really great,
12430  // so great that it can tell my for loops (twice nested)
12431  // below never actually terminate
12432  // without hitting where the gotos have infested
12433 
12434  // so now I would get the error W4XXX unreachable
12435  // me that the return cont at the end of this function
12436  // which is fair until other compilers complain
12437  // that there isn't a return and that based on
12438  // SOME MAGICAL FORCE
12439  // control flow falls off the end of a non-void function
12440  // so it needs to be there for the compilers that are
12441  // too flimsy to analyze the basic blocks...
12442  // (I'm sure I should file a bug but those compilers are already
12443  // in the wild; it doesn't matter if I fix them,
12444  // someone else is still going to get some old-ass compiler
12445  // and then bother me about the unclean build for the 30th
12446  // time)
12447 
12448  // "Why not an IIFE?"
12449  // Because additional lambdas / functions which serve as
12450  // capture-all-and-then-invoke bloat binary sizes
12451  // by an actually detectable amount
12452  // (one user uses sol2 pretty heavily and 22 MB of binary size
12453  // was saved by reducing reliance on lambdas in templates)
12454 
12455  // This would really be solved by having break N;
12456  // be a real, proper thing...
12457  // but instead, we have to use labels and gotos
12458  // and earn the universal vitriol of the dogmatic
12459  // programming community
12460 
12461  // all in all: W4 is great!~
12462 
12463  int index = lua_absindex(L, relindex);
12464  T cont;
12465  std::size_t idx = 0;
12466 #if SOL_LUA_VESION_I_ >= 503
12467  // This method is HIGHLY performant over regular table iteration
12468  // thanks to the Lua API changes in 5.3
12469  // Questionable in 5.4
12470  for (lua_Integer i = 0;; i += lua_size<V>::value) {
12471  if (max_size_check(meta::has_max_size<Tu>(), cont, idx)) {
12472  // see above comment
12473  goto done;
12474  }
12475  bool isnil = false;
12476  for (int vi = 0; vi < lua_size<V>::value; ++vi) {
12477 #if defined(LUA_NILINTABLE) && LUA_NILINTABLE && SOL_LUA_VESION_I_ >= 600
12478 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
12480 #endif // make sure stack doesn't overflow
12481  lua_pushinteger(L, static_cast<lua_Integer>(i + vi));
12482  if (lua_keyin(L, index) == 0) {
12483  // it's time to stop
12484  isnil = true;
12485  }
12486  else {
12487  // we have a key, have to get the value
12488  lua_geti(L, index, i + vi);
12489  }
12490 #else
12491  type vt = static_cast<type>(lua_geti(L, index, i + vi));
12492  isnil = vt == type::none || vt == type::lua_nil;
12493 #endif
12494  if (isnil) {
12495  if (i == 0) {
12496  break;
12497  }
12498 #if defined(LUA_NILINTABLE) && LUA_NILINTABLE && SOL_LUA_VESION_I_ >= 600
12499  lua_pop(L, vi);
12500 #else
12501  lua_pop(L, (vi + 1));
12502 #endif
12503  // see above comment
12504  goto done;
12505  }
12506  }
12507  if (isnil) {
12508 #if defined(LUA_NILINTABLE) && LUA_NILINTABLE && SOL_LUA_VESION_I_ >= 600
12509 #else
12511 #endif
12512  continue;
12513  }
12514 
12515  push_back_at_end(meta::has_push_back<Tu>(), t, L, cont, idx);
12516  ++idx;
12518  }
12519 #else
12520  // Zzzz slower but necessary thanks to the lower version API and missing functions qq
12521  for (lua_Integer i = 0;; i += lua_size<V>::value, lua_pop(L, lua_size<V>::value)) {
12522  if (idx >= cont.max_size()) {
12523  // see above comment
12524  goto done;
12525  }
12526 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
12528 #endif // make sure stack doesn't overflow
12529  bool isnil = false;
12530  for (int vi = 0; vi < lua_size<V>::value; ++vi) {
12531  lua_pushinteger(L, i);
12532  lua_gettable(L, index);
12533  type vt = type_of(L, -1);
12534  isnil = vt == type::lua_nil;
12535  if (isnil) {
12536  if (i == 0) {
12537  break;
12538  }
12539  lua_pop(L, (vi + 1));
12540  // see above comment
12541  goto done;
12542  }
12543  }
12544  if (isnil)
12545  continue;
12546  push_back_at_end(meta::has_push_back<Tu>(), t, L, cont, idx);
12547  ++idx;
12548  }
12549 #endif
12550  done:
12551  return cont;
12552  }
12553 
12554  static T get(std::true_type, lua_State* L, int index, record& tracking) {
12555  typedef typename Tu::value_type P;
12556  typedef typename P::first_type K;
12557  typedef typename P::second_type V;
12558  return get(types<K, V>(), L, index, tracking);
12559  }
12560 
12561  template <typename K, typename V>
12562  static T get(types<K, V>, lua_State* L, int relindex, record& tracking) {
12563  tracking.use(1);
12564 
12565 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
12567 #endif // make sure stack doesn't overflow
12568 
12569  T associative;
12570  int index = lua_absindex(L, relindex);
12571  lua_pushnil(L);
12572  while (lua_next(L, index) != 0) {
12573  decltype(auto) key = stack::check_get<K>(L, -2);
12574  if (!key) {
12575  lua_pop(L, 1);
12576  continue;
12577  }
12578  associative.emplace(std::forward<decltype(*key)>(*key), stack::get<V>(L, -1));
12579  lua_pop(L, 1);
12580  }
12581  return associative;
12582  }
12583  };
12584 
12585  template <typename T, typename Al>
12586  struct unqualified_getter<as_table_t<std::forward_list<T, Al>>> {
12587  typedef std::forward_list<T, Al> C;
12588 
12589  static C get(lua_State* L, int relindex, record& tracking) {
12590  return get(meta::has_key_value_pair<C>(), L, relindex, tracking);
12591  }
12592 
12593  static C get(std::true_type, lua_State* L, int index, record& tracking) {
12594  typedef typename T::value_type P;
12595  typedef typename P::first_type K;
12596  typedef typename P::second_type V;
12597  return get(types<K, V>(), L, index, tracking);
12598  }
12599 
12600  static C get(std::false_type, lua_State* L, int relindex, record& tracking) {
12601  typedef typename C::value_type V;
12602  return get(types<V>(), L, relindex, tracking);
12603  }
12604 
12605  template <typename V>
12606  static C get(types<V>, lua_State* L, int relindex, record& tracking) {
12607  tracking.use(1);
12608 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
12610 #endif // make sure stack doesn't overflow
12611 
12612  int index = lua_absindex(L, relindex);
12613  C cont;
12614  auto at = cont.cbefore_begin();
12615  std::size_t idx = 0;
12616 #if SOL_LUA_VESION_I_ >= 503
12617  // This method is HIGHLY performant over regular table iteration thanks to the Lua API changes in 5.3
12618  for (lua_Integer i = 0;; i += lua_size<V>::value, lua_pop(L, lua_size<V>::value)) {
12619  if (idx >= cont.max_size()) {
12620  goto done;
12621  }
12622  bool isnil = false;
12623  for (int vi = 0; vi < lua_size<V>::value; ++vi) {
12624  type t = static_cast<type>(lua_geti(L, index, i + vi));
12625  isnil = t == type::lua_nil;
12626  if (isnil) {
12627  if (i == 0) {
12628  break;
12629  }
12630  lua_pop(L, (vi + 1));
12631  goto done;
12632  }
12633  }
12634  if (isnil)
12635  continue;
12636  at = cont.insert_after(at, stack::get<V>(L, -lua_size<V>::value));
12637  ++idx;
12638  }
12639 #else
12640  // Zzzz slower but necessary thanks to the lower version API and missing functions qq
12641  for (lua_Integer i = 0;; i += lua_size<V>::value, lua_pop(L, lua_size<V>::value)) {
12642  if (idx >= cont.max_size()) {
12643  goto done;
12644  }
12645  bool isnil = false;
12646  for (int vi = 0; vi < lua_size<V>::value; ++vi) {
12647  lua_pushinteger(L, i);
12648  lua_gettable(L, index);
12649  type t = type_of(L, -1);
12650  isnil = t == type::lua_nil;
12651  if (isnil) {
12652  if (i == 0) {
12653  break;
12654  }
12655  lua_pop(L, (vi + 1));
12656  goto done;
12657  }
12658  }
12659  if (isnil)
12660  continue;
12661  at = cont.insert_after(at, stack::get<V>(L, -lua_size<V>::value));
12662  ++idx;
12663  }
12664 #endif
12665  done:
12666  return cont;
12667  }
12668 
12669  template <typename K, typename V>
12670  static C get(types<K, V>, lua_State* L, int relindex, record& tracking) {
12671  tracking.use(1);
12672 
12673 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
12675 #endif // make sure stack doesn't overflow
12676 
12677  C associative;
12678  auto at = associative.cbefore_begin();
12679  int index = lua_absindex(L, relindex);
12680  lua_pushnil(L);
12681  while (lua_next(L, index) != 0) {
12682  decltype(auto) key = stack::check_get<K>(L, -2);
12683  if (!key) {
12684  lua_pop(L, 1);
12685  continue;
12686  }
12687  at = associative.emplace_after(at, std::forward<decltype(*key)>(*key), stack::get<V>(L, -1));
12688  lua_pop(L, 1);
12689  }
12690  return associative;
12691  }
12692  };
12693 
12694  template <typename T>
12696  static T get(lua_State* L, int index, record& tracking) {
12697  using Tu = meta::unqualified_t<T>;
12698  if constexpr (is_container_v<Tu>) {
12699  if constexpr (meta::is_associative<Tu>::value) {
12700  typedef typename T::value_type P;
12701  typedef typename P::first_type K;
12702  typedef typename P::second_type V;
12704  // VC++ has a bad warning here: shut it up
12705  (void)g;
12706  return g.get(types<K, nested<V>>(), L, index, tracking);
12707  }
12708  else {
12709  typedef typename T::value_type V;
12711  // VC++ has a bad warning here: shut it up
12712  (void)g;
12713  return g.get(types<nested<V>>(), L, index, tracking);
12714  }
12715  }
12716  else {
12718  // VC++ has a bad warning here: shut it up
12719  (void)g;
12720  return g.get(L, index, tracking);
12721  }
12722  }
12723  };
12724 
12725  template <typename T>
12727  static decltype(auto) get(lua_State* L, int index, record& tracking) {
12728  return stack::unqualified_get<T>(L, index, tracking);
12729  }
12730  };
12731 
12732  template <typename T>
12734  static decltype(auto) get(lua_State* L, int index, record& tracking) {
12735  return stack::unqualified_get<T*>(L, index, tracking);
12736  }
12737  };
12738 
12739  template <>
12741  static userdata_value get(lua_State* L, int index, record& tracking) {
12742  tracking.use(1);
12743  return userdata_value(lua_touserdata(L, index));
12744  }
12745  };
12746 
12747  template <>
12749  static lightuserdata_value get(lua_State* L, int index, record& tracking) {
12750  tracking.use(1);
12751  return lightuserdata_value(lua_touserdata(L, index));
12752  }
12753  };
12754 
12755  template <typename T>
12757  static light<T> get(lua_State* L, int index, record& tracking) {
12758  tracking.use(1);
12759  void* memory = lua_touserdata(L, index);
12760  return light<T>(static_cast<T*>(memory));
12761  }
12762  };
12763 
12764  template <typename T>
12766  static std::add_lvalue_reference_t<T> get(lua_State* L, int index, record& tracking) {
12767  tracking.use(1);
12768  void* memory = lua_touserdata(L, index);
12769  memory = detail::align_user<T>(memory);
12770  return *static_cast<std::remove_reference_t<T>*>(memory);
12771  }
12772  };
12773 
12774  template <typename T>
12775  struct unqualified_getter<user<T*>> {
12776  static T* get(lua_State* L, int index, record& tracking) {
12777  tracking.use(1);
12778  void* memory = lua_touserdata(L, index);
12779  memory = detail::align_user<T*>(memory);
12780  return static_cast<T*>(memory);
12781  }
12782  };
12783 
12784  template <>
12785  struct unqualified_getter<type> {
12786  static type get(lua_State* L, int index, record& tracking) {
12787  tracking.use(1);
12788  return static_cast<type>(lua_type(L, index));
12789  }
12790  };
12791 
12792  template <>
12794  static std::string get(lua_State* L, int index, record& tracking) {
12795  tracking.use(1);
12796  std::size_t len;
12797  auto str = lua_tolstring(L, index, &len);
12798  return std::string(str, len);
12799  }
12800  };
12801 
12802  template <>
12803  struct unqualified_getter<const char*> {
12804  static const char* get(lua_State* L, int index, record& tracking) {
12805  tracking.use(1);
12806  size_t sz;
12807  return lua_tolstring(L, index, &sz);
12808  }
12809  };
12810 
12811  template <>
12812  struct unqualified_getter<char> {
12813  static char get(lua_State* L, int index, record& tracking) {
12814  tracking.use(1);
12815  size_t len;
12816  auto str = lua_tolstring(L, index, &len);
12817  return len > 0 ? str[0] : '\0';
12818  }
12819  };
12820 
12821  template <typename Traits>
12822  struct unqualified_getter<basic_string_view<char, Traits>> {
12823  static string_view get(lua_State* L, int index, record& tracking) {
12824  tracking.use(1);
12825  size_t sz;
12826  const char* str = lua_tolstring(L, index, &sz);
12827  return basic_string_view<char, Traits>(str, sz);
12828  }
12829  };
12830 
12831  template <typename Traits, typename Al>
12832  struct unqualified_getter<std::basic_string<wchar_t, Traits, Al>> {
12833  using S = std::basic_string<wchar_t, Traits, Al>;
12834  static S get(lua_State* L, int index, record& tracking) {
12836  return stack_detail::get_into<Ch, S>(L, index, tracking);
12837  }
12838  };
12839 
12840  template <typename Traits, typename Al>
12841  struct unqualified_getter<std::basic_string<char16_t, Traits, Al>> {
12842  static std::basic_string<char16_t, Traits, Al> get(lua_State* L, int index, record& tracking) {
12843  return stack_detail::get_into<char16_t, std::basic_string<char16_t, Traits, Al>>(L, index, tracking);
12844  }
12845  };
12846 
12847  template <typename Traits, typename Al>
12848  struct unqualified_getter<std::basic_string<char32_t, Traits, Al>> {
12849  static std::basic_string<char32_t, Traits, Al> get(lua_State* L, int index, record& tracking) {
12850  return stack_detail::get_into<char32_t, std::basic_string<char32_t, Traits, Al>>(L, index, tracking);
12851  }
12852  };
12853 
12854  template <>
12855  struct unqualified_getter<char16_t> {
12856  static char16_t get(lua_State* L, int index, record& tracking) {
12857  string_view utf8 = stack::get<string_view>(L, index, tracking);
12858  const char* strb = utf8.data();
12859  const char* stre = utf8.data() + utf8.size();
12860  char32_t cp = 0;
12861  auto dr = unicode::utf8_to_code_point(strb, stre);
12862  if (dr.error != unicode::error_code::ok) {
12864  }
12865  else {
12866  cp = dr.codepoint;
12867  }
12868  auto er = unicode::code_point_to_utf16(cp);
12869  return er.code_units[0];
12870  }
12871  };
12872 
12873  template <>
12874  struct unqualified_getter<char32_t> {
12875  static char32_t get(lua_State* L, int index, record& tracking) {
12876  string_view utf8 = stack::get<string_view>(L, index, tracking);
12877  const char* strb = utf8.data();
12878  const char* stre = utf8.data() + utf8.size();
12879  char32_t cp = 0;
12880  auto dr = unicode::utf8_to_code_point(strb, stre);
12881  if (dr.error != unicode::error_code::ok) {
12883  }
12884  else {
12885  cp = dr.codepoint;
12886  }
12887  auto er = unicode::code_point_to_utf32(cp);
12888  return er.code_units[0];
12889  }
12890  };
12891 
12892  template <>
12893  struct unqualified_getter<wchar_t> {
12894  static wchar_t get(lua_State* L, int index, record& tracking) {
12897  (void)g;
12898  auto c = g.get(L, index, tracking);
12899  return static_cast<wchar_t>(c);
12900  }
12901  };
12902 
12903  template <>
12905  static meta_function get(lua_State* L, int index, record& tracking) {
12906  tracking.use(1);
12907  const char* name = unqualified_getter<const char*> {}.get(L, index, tracking);
12908  const auto& mfnames = meta_function_names();
12909  for (std::size_t i = 0; i < mfnames.size(); ++i)
12910  if (mfnames[i] == name)
12911  return static_cast<meta_function>(i);
12912  return meta_function::construct;
12913  }
12914  };
12915 
12916  template <>
12918  static lua_nil_t get(lua_State*, int, record& tracking) {
12919  tracking.use(1);
12920  return lua_nil;
12921  }
12922  };
12923 
12924  template <>
12925  struct unqualified_getter<std::nullptr_t> {
12926  static std::nullptr_t get(lua_State*, int, record& tracking) {
12927  tracking.use(1);
12928  return nullptr;
12929  }
12930  };
12931 
12932  template <>
12934  static nullopt_t get(lua_State*, int, record& tracking) {
12935  tracking.use(1);
12936  return nullopt;
12937  }
12938  };
12939 
12940  template <>
12942  static this_state get(lua_State* L, int, record& tracking) {
12943  tracking.use(0);
12944  return this_state(L);
12945  }
12946  };
12947 
12948  template <>
12950  static this_main_state get(lua_State* L, int, record& tracking) {
12951  tracking.use(0);
12952  return this_main_state(main_thread(L, L));
12953  }
12954  };
12955 
12956  template <>
12958  static lua_CFunction get(lua_State* L, int index, record& tracking) {
12959  tracking.use(1);
12960  return lua_tocfunction(L, index);
12961  }
12962  };
12963 
12964  template <>
12966  static c_closure get(lua_State* L, int index, record& tracking) {
12967  tracking.use(1);
12968  return c_closure(lua_tocfunction(L, index), -1);
12969  }
12970  };
12971 
12972  template <>
12974  static error get(lua_State* L, int index, record& tracking) {
12975  tracking.use(1);
12976  size_t sz = 0;
12977  const char* err = lua_tolstring(L, index, &sz);
12978  if (err == nullptr) {
12979  return error(detail::direct_error, "");
12980  }
12981  return error(detail::direct_error, std::string(err, sz));
12982  }
12983  };
12984 
12985  template <>
12987  static void* get(lua_State* L, int index, record& tracking) {
12988  tracking.use(1);
12989  return lua_touserdata(L, index);
12990  }
12991  };
12992 
12993  template <>
12994  struct unqualified_getter<const void*> {
12995  static const void* get(lua_State* L, int index, record& tracking) {
12996  tracking.use(1);
12997  return lua_touserdata(L, index);
12998  }
12999  };
13000 
13001  template <typename T>
13002  struct unqualified_getter<detail::as_value_tag<T>> {
13003  static T* get_no_lua_nil(lua_State* L, int index, record& tracking) {
13004  void* memory = lua_touserdata(L, index);
13005 #if SOL_IS_ON(SOL_USE_INTEROP_I_)
13006  auto ugr = stack_detail::interop_get<T>(L, index, memory, tracking);
13007  if (ugr.first) {
13008  return ugr.second;
13009  }
13010 #endif // interop extensibility
13011  tracking.use(1);
13012  void* rawdata = detail::align_usertype_pointer(memory);
13013  void** pudata = static_cast<void**>(rawdata);
13014  void* udata = *pudata;
13015  return get_no_lua_nil_from(L, udata, index, tracking);
13016  }
13017 
13018  static T* get_no_lua_nil_from(lua_State* L, void* udata, int index, record&) {
13019  bool has_derived = derive<T>::value || weak_derive<T>::value;
13020  if (has_derived) {
13021  if (lua_getmetatable(L, index) == 1) {
13023  if (type_of(L, -1) != type::lua_nil) {
13024  void* basecastdata = lua_touserdata(L, -1);
13025  detail::inheritance_cast_function ic = reinterpret_cast<detail::inheritance_cast_function>(basecastdata);
13026  // use the casting function to properly adjust the pointer for the desired T
13027  udata = ic(udata, usertype_traits<T>::qualified_name());
13028  }
13029  lua_pop(L, 2);
13030  }
13031  }
13032  T* obj = static_cast<T*>(udata);
13033  return obj;
13034  }
13035 
13036  static T& get(lua_State* L, int index, record& tracking) {
13037  return *get_no_lua_nil(L, index, tracking);
13038  }
13039  };
13040 
13041  template <typename T>
13042  struct unqualified_getter<detail::as_pointer_tag<T>> {
13043  static T* get(lua_State* L, int index, record& tracking) {
13044  type t = type_of(L, index);
13045  if (t == type::lua_nil) {
13046  tracking.use(1);
13047  return nullptr;
13048  }
13050  // Avoid VC++ warning
13051  (void)g;
13052  return g.get_no_lua_nil(L, index, tracking);
13053  }
13054  };
13055 
13056  template <typename T>
13058  static T* get(lua_State* L, int index, record& tracking) {
13060  // Avoid VC++ warning
13061  (void)g;
13062  return g.get_no_lua_nil(L, index, tracking);
13063  }
13064  };
13065 
13066  template <typename T>
13067  struct unqualified_getter<T&> {
13068  static T& get(lua_State* L, int index, record& tracking) {
13070  // Avoid VC++ warning
13071  (void)g;
13072  return g.get(L, index, tracking);
13073  }
13074  };
13075 
13076  template <typename T>
13077  struct unqualified_getter<std::reference_wrapper<T>> {
13078  static T& get(lua_State* L, int index, record& tracking) {
13080  // Avoid VC++ warning
13081  (void)g;
13082  return g.get(L, index, tracking);
13083  }
13084  };
13085 
13086  template <typename T>
13087  struct unqualified_getter<T*> {
13088  static T* get(lua_State* L, int index, record& tracking) {
13089 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
13090  if constexpr (std::is_function_v<T>) {
13091  return stack_detail::get_function_pointer<T>(L, index, tracking);
13092  }
13093  else {
13095  // Avoid VC++ warning
13096  (void)g;
13097  return g.get(L, index, tracking);
13098  }
13099 #else
13101  // Avoid VC++ warning
13102  (void)g;
13103  return g.get(L, index, tracking);
13104 #endif
13105  }
13106  };
13107 
13108  template <typename... Tn>
13109  struct unqualified_getter<std::tuple<Tn...>> {
13110  typedef std::tuple<decltype(stack::get<Tn>(nullptr, 0))...> R;
13111 
13112  template <typename... Args>
13113  static R apply(std::index_sequence<>, lua_State*, int, record&, Args&&... args) {
13114  // Fuck you too, VC++
13115  return R { std::forward<Args>(args)... };
13116  }
13117 
13118  template <std::size_t I, std::size_t... Ix, typename... Args>
13119  static R apply(std::index_sequence<I, Ix...>, lua_State* L, int index, record& tracking, Args&&... args) {
13120  // Fuck you too, VC++
13121  typedef std::tuple_element_t<I, std::tuple<Tn...>> T;
13122  return apply(std::index_sequence<Ix...>(), L, index, tracking, std::forward<Args>(args)..., stack::get<T>(L, index + tracking.used, tracking));
13123  }
13124 
13125  static R get(lua_State* L, int index, record& tracking) {
13126  return apply(std::make_index_sequence<sizeof...(Tn)>(), L, index, tracking);
13127  }
13128  };
13129 
13130  template <typename A, typename B>
13131  struct unqualified_getter<std::pair<A, B>> {
13132  static decltype(auto) get(lua_State* L, int index, record& tracking) {
13133  return std::pair<decltype(stack::get<A>(L, index)), decltype(stack::get<B>(L, index))> { stack::get<A>(L, index, tracking),
13134  stack::get<B>(L, index + tracking.used, tracking) };
13135  }
13136  };
13137 
13138 #if SOL_IS_ON(SOL_STD_VARIANT_I_)
13139 
13140  template <typename... Tn>
13141  struct unqualified_getter<std::variant<Tn...>> {
13142  using V = std::variant<Tn...>;
13143 
13144  static V get_one(std::integral_constant<std::size_t, std::variant_size_v<V>>, lua_State* L, int index, record& tracking) {
13145  (void)L;
13146  (void)index;
13147  (void)tracking;
13148  if constexpr (std::variant_size_v<V> == 0) {
13149  return V();
13150  }
13151  else {
13152  // using T = std::variant_alternative_t<0, V>;
13153  std::abort();
13154  // return V(std::in_place_index<0>, stack::get<T>(L, index, tracking));
13155  }
13156  }
13157 
13158  template <std::size_t I>
13159  static V get_one(std::integral_constant<std::size_t, I>, lua_State* L, int index, record& tracking) {
13160  typedef std::variant_alternative_t<I, V> T;
13161  record temp_tracking = tracking;
13162  if (stack::check<T>(L, index, no_panic, temp_tracking)) {
13163  tracking = temp_tracking;
13164  return V(std::in_place_index<I>, stack::get<T>(L, index));
13165  }
13166  return get_one(std::integral_constant<std::size_t, I + 1>(), L, index, tracking);
13167  }
13168 
13169  static V get(lua_State* L, int index, record& tracking) {
13170  return get_one(std::integral_constant<std::size_t, 0>(), L, index, tracking);
13171  }
13172  };
13173 #endif // variant
13174 
13175 }} // namespace sol::stack
13176 
13177 // end of sol/stack_get_unqualified.hpp
13178 
13179 // beginning of sol/stack_get_qualified.hpp
13180 
13181 namespace sol {
13182 namespace stack {
13183 
13184  // There are no more enable_ifs that can be used here,
13185  // so this is just for posterity, I guess?
13186  // maybe I'll fill this file in later.
13187 
13188 }
13189 } // namespace sol::stack
13190 
13191 // end of sol/stack_get_qualified.hpp
13192 
13193 // end of sol/stack_get.hpp
13194 
13195 // beginning of sol/stack_check_get.hpp
13196 
13197 // beginning of sol/stack_check_get_unqualified.hpp
13198 
13199 #include <cstdlib>
13200 #include <cmath>
13201 #include <optional>
13202 #if SOL_IS_ON(SOL_STD_VARIANT_I_)
13203 #include <variant>
13204 #endif // variant shenanigans (thanks, Mac OSX)
13205 
13206 namespace sol { namespace stack {
13207  template <typename T, typename>
13208  struct unqualified_check_getter {
13209  typedef decltype(stack_detail::unchecked_unqualified_get<T>(nullptr, -1, std::declval<record&>())) R;
13210 
13211  template <typename Optional, typename Handler>
13212  static Optional get_using(lua_State* L, int index, Handler&& handler, record& tracking) {
13213  if constexpr (!meta::meta_detail::is_adl_sol_lua_check_v<T> && !meta::meta_detail::is_adl_sol_lua_get_v<T>) {
13214  if constexpr (is_lua_reference_v<T>) {
13215  // actually check if it's none here, otherwise
13216  // we'll have a none object inside an optional!
13217  bool success = lua_isnoneornil(L, index) == 0 && stack::check<T>(L, index, no_panic);
13218  if (!success) {
13219  // expected type, actual type
13220  tracking.use(static_cast<int>(success));
13221  handler(L, index, type::poly, type_of(L, index), "");
13222  return detail::associated_nullopt_v<Optional>;
13223  }
13224  return stack_detail::unchecked_get<T>(L, index, tracking);
13225  }
13226  else if constexpr ((std::is_integral_v<T> || std::is_same_v<T, lua_Integer>)&&!std::is_same_v<T, bool>) {
13227 #if SOL_LUA_VESION_I_ >= 503
13228  if (lua_isinteger(L, index) != 0) {
13229  tracking.use(1);
13230  return static_cast<T>(lua_tointeger(L, index));
13231  }
13232 #endif
13233  int isnum = 0;
13234  const lua_Number value = lua_tonumberx(L, index, &isnum);
13235  if (isnum != 0) {
13236 #if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_)
13237  const auto integer_value = llround(value);
13238  if (static_cast<lua_Number>(integer_value) == value) {
13239  tracking.use(1);
13240  return static_cast<T>(integer_value);
13241  }
13242 #else
13243  tracking.use(1);
13244  return static_cast<T>(value);
13245 #endif
13246  }
13247  const type t = type_of(L, index);
13248  tracking.use(static_cast<int>(t != type::none));
13249  handler(L, index, type::number, t, "not an integer");
13250  return detail::associated_nullopt_v<Optional>;
13251  }
13252  else if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, lua_Number>) {
13253  int isnum = 0;
13254  lua_Number value = lua_tonumberx(L, index, &isnum);
13255  if (isnum == 0) {
13256  type t = type_of(L, index);
13257  tracking.use(static_cast<int>(t != type::none));
13258  handler(L, index, type::number, t, "not a valid floating point number");
13259  return detail::associated_nullopt_v<Optional>;
13260  }
13261  tracking.use(1);
13262  return static_cast<T>(value);
13263  }
13264  else if constexpr (std::is_enum_v<T> && !meta::any_same_v<T, meta_function, type>) {
13265  int isnum = 0;
13266  lua_Integer value = lua_tointegerx(L, index, &isnum);
13267  if (isnum == 0) {
13268  type t = type_of(L, index);
13269  tracking.use(static_cast<int>(t != type::none));
13270  handler(L, index, type::number, t, "not a valid enumeration value");
13271  return detail::associated_nullopt_v<Optional>;
13272  }
13273  tracking.use(1);
13274  return static_cast<T>(value);
13275  }
13276  else {
13277  if (!unqualified_check<T>(L, index, std::forward<Handler>(handler))) {
13278  tracking.use(static_cast<int>(!lua_isnone(L, index)));
13279  return detail::associated_nullopt_v<Optional>;
13280  }
13281  return stack_detail::unchecked_unqualified_get<T>(L, index, tracking);
13282  }
13283  }
13284  else {
13285  if (!unqualified_check<T>(L, index, std::forward<Handler>(handler))) {
13286  tracking.use(static_cast<int>(!lua_isnone(L, index)));
13287  return detail::associated_nullopt_v<Optional>;
13288  }
13289  return stack_detail::unchecked_unqualified_get<T>(L, index, tracking);
13290  }
13291  }
13292 
13293  template <typename Handler>
13294  static optional<R> get(lua_State* L, int index, Handler&& handler, record& tracking) {
13295  return get_using<optional<R>>(L, index, std::forward<Handler>(handler), tracking);
13296  }
13297  };
13298 
13299 #if SOL_IS_ON(SOL_STD_VARIANT_I_)
13300  template <typename... Tn, typename C>
13301  struct unqualified_check_getter<std::variant<Tn...>, C> {
13302  typedef std::variant<Tn...> V;
13303  typedef std::variant_size<V> V_size;
13304  typedef std::integral_constant<bool, V_size::value == 0> V_is_empty;
13305 
13306  template <typename Handler>
13307  static optional<V> get_empty(std::true_type, lua_State*, int, Handler&&, record&) {
13308  return nullopt;
13309  }
13310 
13311  template <typename Handler>
13312  static optional<V> get_empty(std::false_type, lua_State* L, int index, Handler&& handler, record&) {
13313  // This should never be reached...
13314  // please check your code and understand what you did to bring yourself here
13315  // maybe file a bug report, or 5
13316  handler(
13317  L, index, type::poly, type_of(L, index), "this variant code should never be reached: if it has, you have done something so terribly wrong");
13318  return nullopt;
13319  }
13320 
13321  template <typename Handler>
13322  static optional<V> get_one(std::integral_constant<std::size_t, 0>, lua_State* L, int index, Handler&& handler, record& tracking) {
13323  return get_empty(V_is_empty(), L, index, std::forward<Handler>(handler), tracking);
13324  }
13325 
13326  template <std::size_t I, typename Handler>
13327  static optional<V> get_one(std::integral_constant<std::size_t, I>, lua_State* L, int index, Handler&& handler, record& tracking) {
13328  typedef std::variant_alternative_t<I - 1, V> T;
13329  if (stack::check<T>(L, index, no_panic, tracking)) {
13330  return V(std::in_place_index<I - 1>, stack::get<T>(L, index));
13331  }
13332  return get_one(std::integral_constant<std::size_t, I - 1>(), L, index, std::forward<Handler>(handler), tracking);
13333  }
13334 
13335  template <typename Handler>
13336  static optional<V> get(lua_State* L, int index, Handler&& handler, record& tracking) {
13337  return get_one(std::integral_constant<std::size_t, V_size::value>(), L, index, std::forward<Handler>(handler), tracking);
13338  }
13339  };
13340 #endif // standard variant
13341 }} // namespace sol::stack
13342 
13343 // end of sol/stack_check_get_unqualified.hpp
13344 
13345 // beginning of sol/stack_check_get_qualified.hpp
13346 
13347 namespace sol { namespace stack {
13348  template <typename T, typename C>
13349  struct qualified_check_getter {
13350  typedef decltype(stack_detail::unchecked_get<T>(nullptr, -1, std::declval<record&>())) R;
13351 
13352  template <typename Handler>
13353  static optional<R> get(lua_State* L, int index, Handler&& handler, record& tracking) {
13354  if constexpr (is_lua_reference_v<T>) {
13355  // actually check if it's none here, otherwise
13356  // we'll have a none object inside an optional!
13357  bool success = lua_isnoneornil(L, index) == 0 && stack::check<T>(L, index, no_panic);
13358  if (!success) {
13359  // expected type, actual type
13360  tracking.use(static_cast<int>(success));
13361  handler(L, index, type::poly, type_of(L, index), "");
13362  return nullopt;
13363  }
13364  return stack_detail::unchecked_get<T>(L, index, tracking);
13365  }
13366  else {
13367  if (!check<T>(L, index, std::forward<Handler>(handler))) {
13368  tracking.use(static_cast<int>(!lua_isnone(L, index)));
13369  return nullopt;
13370  }
13371  return stack_detail::unchecked_get<T>(L, index, tracking);
13372  }
13373  }
13374  };
13375 
13376  template <typename T>
13377  struct qualified_getter<T, std::enable_if_t<meta::is_optional_v<T>>> {
13378  static T get(lua_State* L, int index, record& tracking) {
13379  using ValueType = typename meta::unqualified_t<T>::value_type;
13380  if constexpr (is_lua_reference_v<ValueType>) {
13381  // actually check if it's none here, otherwise
13382  // we'll have a none object inside an optional!
13383  bool success = lua_isnoneornil(L, index) == 0 && stack::check<ValueType>(L, index, no_panic);
13384  if (!success) {
13385  // expected type, actual type
13386  tracking.use(static_cast<int>(success));
13387  return {};
13388  }
13389  return stack_detail::unchecked_get<ValueType>(L, index, tracking);
13390  }
13391  else {
13392  if (!check<ValueType>(L, index, &no_panic)) {
13393  tracking.use(static_cast<int>(!lua_isnone(L, index)));
13394  return {};
13395  }
13396  return stack_detail::unchecked_get<ValueType>(L, index, tracking);
13397  }
13398  }
13399  };
13400 
13401 }} // namespace sol::stack
13402 
13403 // end of sol/stack_check_get_qualified.hpp
13404 
13405 // end of sol/stack_check_get.hpp
13406 
13407 // beginning of sol/stack_push.hpp
13408 
13409 #include <memory>
13410 #include <type_traits>
13411 #include <cassert>
13412 #include <limits>
13413 #include <cmath>
13414 #include <string_view>
13415 #if SOL_IS_ON(SOL_STD_VARIANT_I_)
13416 #include <variant>
13417 #endif // Can use variant
13418 
13419 namespace sol { namespace stack {
13420  namespace stack_detail {
13421  template <typename T>
13422  inline bool integer_value_fits(const T& value) {
13423  if constexpr (sizeof(T) < sizeof(lua_Integer) || (std::is_signed_v<T> && sizeof(T) == sizeof(lua_Integer))) {
13424  (void)value;
13425  return true;
13426  }
13427  else {
13428  auto u_min = static_cast<std::intmax_t>((std::numeric_limits<lua_Integer>::min)());
13429  auto u_max = static_cast<std::uintmax_t>((std::numeric_limits<lua_Integer>::max)());
13430  auto t_min = static_cast<std::intmax_t>((std::numeric_limits<T>::min)());
13431  auto t_max = static_cast<std::uintmax_t>((std::numeric_limits<T>::max)());
13432  return (u_min <= t_min || value >= static_cast<T>(u_min)) && (u_max >= t_max || value <= static_cast<T>(u_max));
13433  }
13434  }
13435 
13436  template <typename T>
13437  int msvc_is_ass_with_if_constexpr_push_enum(std::true_type, lua_State* L, const T& value) {
13438  if constexpr (meta::any_same_v<std::underlying_type_t<T>, char /*, char8_t*/, char16_t, char32_t>) {
13439  if constexpr (std::is_signed_v<T>) {
13440  return stack::push(L, static_cast<std::int_least32_t>(value));
13441  }
13442  else {
13443  return stack::push(L, static_cast<std::uint_least32_t>(value));
13444  }
13445  }
13446  else {
13447  return stack::push(L, static_cast<std::underlying_type_t<T>>(value));
13448  }
13449  }
13450 
13451  template <typename T>
13452  int msvc_is_ass_with_if_constexpr_push_enum(std::false_type, lua_State*, const T&) {
13453  return 0;
13454  }
13455  } // namespace stack_detail
13456 
13457  inline int push_environment_of(lua_State* L, int index = -1) {
13458 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13460 #endif // make sure stack doesn't overflow
13461 #if SOL_LUA_VESION_I_ < 502
13462  // Use lua_getfenv
13463  lua_getfenv(L, index);
13464 #else
13465  // Use upvalues as explained in Lua 5.2 and beyond's manual
13466  if (lua_getupvalue(L, index, 1) == nullptr) {
13467  push(L, lua_nil);
13468  return 1;
13469  }
13470 #endif
13471  return 1;
13472  }
13473 
13474  template <typename T>
13475  int push_environment_of(const T& target) {
13476  target.push();
13477  return push_environment_of(target.lua_state(), -1) + 1;
13478  }
13479 
13480  template <typename T>
13481  struct unqualified_pusher<detail::as_value_tag<T>> {
13482  template <typename F, typename... Args>
13483  static int push_fx(lua_State* L, F&& f, Args&&... args) {
13484 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13486 #endif // make sure stack doesn't overflow
13487  // Basically, we store all user-data like this:
13488  // If it's a movable/copyable value (no std::ref(x)), then we store the pointer to the new
13489  // data in the first sizeof(T*) bytes, and then however many bytes it takes to
13490  // do the actual object. Things that are std::ref or plain T* are stored as
13491  // just the sizeof(T*), and nothing else.
13492  T* obj = detail::usertype_allocate<T>(L);
13493  f();
13494  std::allocator<T> alloc {};
13495  std::allocator_traits<std::allocator<T>>::construct(alloc, obj, std::forward<Args>(args)...);
13496  return 1;
13497  }
13498 
13499  template <typename K, typename... Args>
13500  static int push_keyed(lua_State* L, K&& k, Args&&... args) {
13501  stack_detail::undefined_metatable fx(L, &k[0], &stack::stack_detail::set_undefined_methods_on<T>);
13502  return push_fx(L, fx, std::forward<Args>(args)...);
13503  }
13504 
13505  template <typename Arg, typename... Args>
13506  static int push(lua_State* L, Arg&& arg, Args&&... args) {
13507  if constexpr (std::is_same_v<meta::unqualified_t<Arg>, detail::with_function_tag>) {
13508  (void)arg;
13509  return push_fx(L, std::forward<Args>(args)...);
13510  }
13511  else {
13512  return push_keyed(L, usertype_traits<T>::metatable(), std::forward<Arg>(arg), std::forward<Args>(args)...);
13513  }
13514  }
13515 
13516  static int push(lua_State* L) {
13517  return push_keyed(L, usertype_traits<T>::metatable());
13518  }
13519  };
13520 
13521  template <typename T>
13522  struct unqualified_pusher<detail::as_pointer_tag<T>> {
13524 
13525  template <typename F>
13526  static int push_fx(lua_State* L, F&& f, T* obj) {
13527  if (obj == nullptr)
13528  return stack::push(L, lua_nil);
13529 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13531 #endif // make sure stack doesn't overflow
13532  T** pref = detail::usertype_allocate_pointer<T>(L);
13533  f();
13534  *pref = obj;
13535  return 1;
13536  }
13537 
13538  template <typename K>
13539  static int push_keyed(lua_State* L, K&& k, T* obj) {
13540  stack_detail::undefined_metatable fx(L, &k[0], &stack::stack_detail::set_undefined_methods_on<U*>);
13541  return push_fx(L, fx, obj);
13542  }
13543 
13544  template <typename Arg, typename... Args>
13545  static int push(lua_State* L, Arg&& arg, Args&&... args) {
13546  if constexpr (std::is_same_v<meta::unqualified_t<Arg>, detail::with_function_tag>) {
13547  (void)arg;
13548  return push_fx(L, std::forward<Args>(args)...);
13549  }
13550  else {
13551  return push_keyed(L, usertype_traits<U*>::metatable(), std::forward<Arg>(arg), std::forward<Args>(args)...);
13552  }
13553  }
13554  };
13555 
13556  template <>
13557  struct unqualified_pusher<detail::as_reference_tag> {
13558  template <typename T>
13559  static int push(lua_State* L, T&& obj) {
13560  return stack::push(L, detail::ptr(obj));
13561  }
13562  };
13563 
13564  namespace stack_detail {
13565  template <typename T>
13566  struct uu_pusher {
13568  using P = typename u_traits::type;
13569  using Real = typename u_traits::actual_type;
13570 
13571  template <typename Arg, typename... Args>
13572  static int push(lua_State* L, Arg&& arg, Args&&... args) {
13573  if constexpr (std::is_base_of_v<Real, meta::unqualified_t<Arg>>) {
13574  if (u_traits::is_null(arg)) {
13575  return stack::push(L, lua_nil);
13576  }
13577  return push_deep(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
13578  }
13579  else {
13580  return push_deep(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
13581  }
13582  }
13583 
13584  template <typename... Args>
13585  static int push_deep(lua_State* L, Args&&... args) {
13586 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13588 #endif // make sure stack doesn't overflow
13589  P** pref = nullptr;
13590  detail::unique_destructor* fx = nullptr;
13591  detail::unique_tag* id = nullptr;
13592  Real* mem = detail::usertype_unique_allocate<P, Real>(L, pref, fx, id);
13593  if (luaL_newmetatable(L, &usertype_traits<detail::unique_usertype<std::remove_cv_t<P>>>::metatable()[0]) == 1) {
13594  detail::lua_reg_table l {};
13595  int index = 0;
13596  detail::indexed_insert insert_fx(l, index);
13597  detail::insert_default_registrations<P>(insert_fx, detail::property_always_true);
13598  l[index] = { to_string(meta_function::garbage_collect).c_str(), detail::make_destructor<T>() };
13599  luaL_setfuncs(L, l, 0);
13600  }
13601  lua_setmetatable(L, -2);
13602  *fx = detail::usertype_unique_alloc_destroy<P, Real>;
13603  *id = &detail::inheritance<P>::template type_unique_cast<Real>;
13604  detail::default_construct::construct(mem, std::forward<Args>(args)...);
13605  *pref = unique_usertype_traits<T>::get(*mem);
13606  return 1;
13607  }
13608  };
13609  } // namespace stack_detail
13610 
13611  template <typename T>
13612  struct unqualified_pusher<detail::as_unique_tag<T>> {
13613  template <typename... Args>
13614  static int push(lua_State* L, Args&&... args) {
13616  (void)p;
13617  return p.push(L, std::forward<Args>(args)...);
13618  }
13619  };
13620 
13621  template <typename T, typename>
13622  struct unqualified_pusher {
13623  template <typename... Args>
13624  static int push(lua_State* L, Args&&... args) {
13625  using Tu = meta::unqualified_t<T>;
13626  if constexpr (is_lua_reference_v<Tu>) {
13627  using int_arr = int[];
13628  int_arr p { (std::forward<Args>(args).push(L))... };
13629  return p[0];
13630  }
13631  else if constexpr (std::is_same_v<Tu, bool>) {
13632 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13634 #endif // make sure stack doesn't overflow
13635  lua_pushboolean(L, std::forward<Args>(args)...);
13636  return 1;
13637  }
13638  else if constexpr (std::is_integral_v<Tu> || std::is_same_v<Tu, lua_Integer>) {
13639  const Tu& value(std::forward<Args>(args)...);
13640 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13642 #endif // make sure stack doesn't overflow
13643 #if SOL_LUA_VESION_I_ >= 503
13644  if (stack_detail::integer_value_fits<Tu>(value)) {
13645  lua_pushinteger(L, static_cast<lua_Integer>(value));
13646  return 1;
13647  }
13648 #endif // Lua 5.3 and above
13649 #if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_)
13650  if (static_cast<T>(llround(static_cast<lua_Number>(value))) != value) {
13651 #if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
13652  // Is this really worth it?
13653  assert(false && "integer value will be misrepresented in lua");
13654  lua_pushinteger(L, static_cast<lua_Integer>(value));
13655  return 1;
13656 #else
13657  throw error(detail::direct_error, "integer value will be misrepresented in lua");
13658 #endif // No Exceptions
13659  }
13660 #endif // Safe Numerics and Number Precision Check
13661  lua_pushnumber(L, static_cast<lua_Number>(value));
13662  return 1;
13663  }
13664  else if constexpr (std::is_floating_point_v<Tu> || std::is_same_v<Tu, lua_Number>) {
13665 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13667 #endif // make sure stack doesn't overflow
13668  lua_pushnumber(L, std::forward<Args>(args)...);
13669  return 1;
13670  }
13671  else if constexpr (std::is_same_v<Tu, luaL_Stream*>) {
13672  luaL_Stream* source { std::forward<Args>(args)... };
13673  luaL_Stream* stream = static_cast<luaL_Stream*>(lua_newuserdata(L, sizeof(luaL_Stream)));
13674  stream->f = source->f;
13675 #if SOL_IS_ON(SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_)
13676  stream->closef = source->closef;
13677 #endif // LuaJIT and Lua 5.1 and below do not have
13678  return 1;
13679  }
13680  else if constexpr (std::is_same_v<Tu, luaL_Stream>) {
13681  luaL_Stream& source(std::forward<Args>(args)...);
13682  luaL_Stream* stream = static_cast<luaL_Stream*>(lua_newuserdata(L, sizeof(luaL_Stream)));
13683  stream->f = source.f;
13684 #if SOL_IS_ON(SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_)
13685  stream->closef = source.closef;
13686 #endif // LuaJIT and Lua 5.1 and below do not have
13687  return 1;
13688  }
13689  else if constexpr (std::is_enum_v<Tu>) {
13690  return stack_detail::msvc_is_ass_with_if_constexpr_push_enum(std::true_type(), L, std::forward<Args>(args)...);
13691  }
13692  else if constexpr (std::is_pointer_v<Tu>) {
13693  return stack::push<detail::as_pointer_tag<std::remove_pointer_t<T>>>(L, std::forward<Args>(args)...);
13694  }
13695  else if constexpr (is_unique_usertype_v<Tu>) {
13696  return stack::push<detail::as_unique_tag<T>>(L, std::forward<Args>(args)...);
13697  }
13698  else {
13699  return stack::push<detail::as_value_tag<T>>(L, std::forward<Args>(args)...);
13700  }
13701  }
13702  };
13703 
13704  template <typename T>
13705  struct unqualified_pusher<std::reference_wrapper<T>> {
13706  static int push(lua_State* L, const std::reference_wrapper<T>& t) {
13707  return stack::push(L, std::addressof(detail::deref(t.get())));
13708  }
13709  };
13710 
13711  template <typename T>
13712  struct unqualified_pusher<detail::as_table_tag<T>> {
13714 
13715  static int push(lua_State* L, const T& tablecont) {
13716  return push(has_kvp(), std::false_type(), L, tablecont);
13717  }
13718 
13719  static int push(lua_State* L, const T& tablecont, nested_tag_t) {
13720  return push(has_kvp(), std::true_type(), L, tablecont);
13721  }
13722 
13723  static int push(std::true_type, lua_State* L, const T& tablecont) {
13724  return push(has_kvp(), std::true_type(), L, tablecont);
13725  }
13726 
13727  static int push(std::false_type, lua_State* L, const T& tablecont) {
13728  return push(has_kvp(), std::false_type(), L, tablecont);
13729  }
13730 
13731  template <bool is_nested>
13732  static int push(std::true_type, std::integral_constant<bool, is_nested>, lua_State* L, const T& tablecont) {
13733  auto& cont = detail::deref(detail::unwrap(tablecont));
13734  lua_createtable(L, static_cast<int>(cont.size()), 0);
13735  int tableindex = lua_gettop(L);
13736  for (const auto& pair : cont) {
13737  if (is_nested) {
13738  set_field(L, pair.first, as_nested_ref(pair.second), tableindex);
13739  }
13740  else {
13741  set_field(L, pair.first, pair.second, tableindex);
13742  }
13743  }
13744  return 1;
13745  }
13746 
13747  template <bool is_nested>
13748  static int push(std::false_type, std::integral_constant<bool, is_nested>, lua_State* L, const T& tablecont) {
13749  auto& cont = detail::deref(detail::unwrap(tablecont));
13751  int tableindex = lua_gettop(L);
13752  std::size_t index = 1;
13753  for (const auto& i : cont) {
13754 #if SOL_LUA_VESION_I_ >= 503
13755  int p = is_nested ? stack::push(L, as_nested_ref(i)) : stack::push(L, i);
13756  for (int pi = 0; pi < p; ++pi) {
13757  lua_seti(L, tableindex, static_cast<lua_Integer>(index++));
13758  }
13759 #else
13760 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13762 #endif // make sure stack doesn't overflow
13763  lua_pushinteger(L, static_cast<lua_Integer>(index));
13764  int p = is_nested ? stack::push(L, as_nested_ref(i)) : stack::push(L, i);
13765  if (p == 1) {
13766  ++index;
13767  lua_settable(L, tableindex);
13768  }
13769  else {
13770  int firstindex = tableindex + 1 + 1;
13771  for (int pi = 0; pi < p; ++pi) {
13772  stack::push(L, index);
13773 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13775 #endif // make sure stack doesn't overflow
13776  lua_pushvalue(L, firstindex);
13777  lua_settable(L, tableindex);
13778  ++index;
13779  ++firstindex;
13780  }
13781  lua_pop(L, 1 + p);
13782  }
13783 #endif // Lua Version 5.3 and others
13784  }
13785  // TODO: figure out a better way to do this...?
13786  // set_field(L, -1, cont.size());
13787  return 1;
13788  }
13789  };
13790 
13791  template <typename T>
13793  static int push(lua_State* L, const T& v) {
13794  using inner_t = std::remove_pointer_t<meta::unwrap_unqualified_t<T>>;
13795  if constexpr (is_container_v<inner_t>) {
13796  return stack::push<detail::as_table_tag<T>>(L, v);
13797  }
13798  else {
13799  return stack::push(L, v);
13800  }
13801  }
13802  };
13803 
13804  template <typename T>
13806  static int push(lua_State* L, const T& tablecont) {
13807  using Tu = meta::unwrap_unqualified_t<T>;
13808  using inner_t = std::remove_pointer_t<Tu>;
13809  if constexpr (is_container_v<inner_t>) {
13810  return stack::push<detail::as_table_tag<T>>(L, tablecont, nested_tag);
13811  }
13812  else {
13813  return stack::push<Tu>(L, tablecont);
13814  }
13815  }
13816  };
13817 
13818  template <typename T>
13819  struct unqualified_pusher<std::initializer_list<T>> {
13820  static int push(lua_State* L, const std::initializer_list<T>& il) {
13822  // silence annoying VC++ warning
13823  (void)p;
13824  return p.push(L, il);
13825  }
13826  };
13827 
13828  template <>
13830  static int push(lua_State* L, lua_nil_t) {
13831 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13833 #endif // make sure stack doesn't overflow
13834  lua_pushnil(L);
13835  return 1;
13836  }
13837  };
13838 
13839  template <>
13841  static int push(lua_State*, stack_count st) {
13842  return st.count;
13843  }
13844  };
13845 
13846  template <>
13848  static int push(lua_State* L, metatable_key_t) {
13849 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13851 #endif // make sure stack doesn't overflow
13853  return 1;
13854  }
13855  };
13856 
13857  template <>
13858  struct unqualified_pusher<std::remove_pointer_t<lua_CFunction>> {
13859  static int push(lua_State* L, lua_CFunction func, int n = 0) {
13860 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13862 #endif // make sure stack doesn't overflow
13863  lua_pushcclosure(L, func, n);
13864  return 1;
13865  }
13866  };
13867 
13868  template <>
13870  static int push(lua_State* L, lua_CFunction func, int n = 0) {
13871 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13873 #endif // make sure stack doesn't overflow
13874  lua_pushcclosure(L, func, n);
13875  return 1;
13876  }
13877  };
13878 
13879 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
13880  template <>
13881  struct unqualified_pusher<std::remove_pointer_t<detail::lua_CFunction_noexcept>> {
13882  static int push(lua_State* L, detail::lua_CFunction_noexcept func, int n = 0) {
13883 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13885 #endif // make sure stack doesn't overflow
13886  lua_pushcclosure(L, func, n);
13887  return 1;
13888  }
13889  };
13890 
13891  template <>
13893  static int push(lua_State* L, detail::lua_CFunction_noexcept func, int n = 0) {
13894 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13896 #endif // make sure stack doesn't overflow
13897  lua_pushcclosure(L, func, n);
13898  return 1;
13899  }
13900  };
13901 #endif // noexcept function type
13902 
13903  template <>
13905  static int push(lua_State* L, c_closure cc) {
13906 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13908 #endif // make sure stack doesn't overflow
13910  return 1;
13911  }
13912  };
13913 
13914  template <typename Arg, typename... Args>
13915  struct unqualified_pusher<closure<Arg, Args...>> {
13916  template <std::size_t... I, typename T>
13917  static int push(std::index_sequence<I...>, lua_State* L, T&& c) {
13918  using f_tuple = decltype(std::forward<T>(c).upvalues);
13919  int pushcount = multi_push(L, std::get<I>(std::forward<f_tuple>(std::forward<T>(c).upvalues))...);
13920  return stack::push(L, c_closure(c.c_function, pushcount));
13921  }
13922 
13923  template <typename T>
13924  static int push(lua_State* L, T&& c) {
13925  return push(std::make_index_sequence<1 + sizeof...(Args)>(), L, std::forward<T>(c));
13926  }
13927  };
13928 
13929  template <>
13931  static int push(lua_State* L, void* userdata) {
13932 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13934 #endif // make sure stack doesn't overflow
13935  lua_pushlightuserdata(L, userdata);
13936  return 1;
13937  }
13938  };
13939 
13940  template <>
13941  struct unqualified_pusher<const void*> {
13942  static int push(lua_State* L, const void* userdata) {
13943 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13945 #endif // make sure stack doesn't overflow
13946  lua_pushlightuserdata(L, const_cast<void*>(userdata));
13947  return 1;
13948  }
13949  };
13950 
13951  template <>
13954 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13956 #endif // make sure stack doesn't overflow
13957  lua_pushlightuserdata(L, userdata);
13958  return 1;
13959  }
13960  };
13961 
13962  template <typename T>
13964  static int push(lua_State* L, light<T> l) {
13965 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13967 #endif // make sure stack doesn't overflow
13968  lua_pushlightuserdata(L, static_cast<void*>(l.value));
13969  return 1;
13970  }
13971  };
13972 
13973  template <typename T>
13975  template <bool with_meta = true, typename Key, typename... Args>
13976  static int push_with(lua_State* L, Key&& name, Args&&... args) {
13977 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13979 #endif // make sure stack doesn't overflow
13980  // A dumb pusher
13981  T* data = detail::user_allocate<T>(L);
13982  if (with_meta) {
13983  // Make sure we have a plain GC set for this data
13984 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
13986 #endif // make sure stack doesn't overflow
13987  if (luaL_newmetatable(L, name) != 0) {
13988  lua_CFunction cdel = detail::user_alloc_destruct<T>;
13989  lua_pushcclosure(L, cdel, 0);
13990  lua_setfield(L, -2, "__gc");
13991  }
13992  lua_setmetatable(L, -2);
13993  }
13994  std::allocator<T> alloc {};
13995  std::allocator_traits<std::allocator<T>>::construct(alloc, data, std::forward<Args>(args)...);
13996  return 1;
13997  }
13998 
13999  template <typename Arg, typename... Args>
14000  static int push(lua_State* L, Arg&& arg, Args&&... args) {
14001  if constexpr (std::is_same_v<meta::unqualified_t<Arg>, metatable_key_t>) {
14002  const auto name = &arg[0];
14003  return push_with<true>(L, name, std::forward<Args>(args)...);
14004  }
14005  else if constexpr (std::is_same_v<meta::unqualified_t<Arg>, no_metatable_t>) {
14006  (void)arg;
14007  const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
14008  return push_with<false>(L, name, std::forward<Args>(args)...);
14009  }
14010  else {
14011  const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
14012  return push_with(L, name, std::forward<Arg>(arg), std::forward<Args>(args)...);
14013  }
14014  }
14015 
14016  static int push(lua_State* L, const user<T>& u) {
14017  const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
14018  return push_with(L, name, u.value);
14019  }
14020 
14021  static int push(lua_State* L, user<T>&& u) {
14022  const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
14023  return push_with(L, name, std::move(u.value));
14024  }
14025 
14026  static int push(lua_State* L, no_metatable_t, const user<T>& u) {
14027  const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
14028  return push_with<false>(L, name, u.value);
14029  }
14030 
14031  static int push(lua_State* L, no_metatable_t, user<T>&& u) {
14032  const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
14033  return push_with<false>(L, name, std::move(u.value));
14034  }
14035  };
14036 
14037  template <>
14039  static int push(lua_State* L, userdata_value data) {
14040 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
14042 #endif // make sure stack doesn't overflow
14043  void** ud = detail::usertype_allocate_pointer<void>(L);
14044  *ud = data.value;
14045  return 1;
14046  }
14047  };
14048 
14049  template <>
14050  struct unqualified_pusher<const char*> {
14051  static int push_sized(lua_State* L, const char* str, std::size_t len) {
14052 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
14054 #endif // make sure stack doesn't overflow
14055  lua_pushlstring(L, str, len);
14056  return 1;
14057  }
14058 
14059  static int push(lua_State* L, const char* str) {
14060  if (str == nullptr)
14061  return stack::push(L, lua_nil);
14062  return push_sized(L, str, std::char_traits<char>::length(str));
14063  }
14064 
14065  static int push(lua_State* L, const char* strb, const char* stre) {
14066  return push_sized(L, strb, stre - strb);
14067  }
14068 
14069  static int push(lua_State* L, const char* str, std::size_t len) {
14070  return push_sized(L, str, len);
14071  }
14072  };
14073 
14074  template <>
14075  struct unqualified_pusher<char*> {
14076  static int push_sized(lua_State* L, const char* str, std::size_t len) {
14078  (void)p;
14079  return p.push_sized(L, str, len);
14080  }
14081 
14082  static int push(lua_State* L, const char* str) {
14084  (void)p;
14085  return p.push(L, str);
14086  }
14087 
14088  static int push(lua_State* L, const char* strb, const char* stre) {
14090  (void)p;
14091  return p.push(L, strb, stre);
14092  }
14093 
14094  static int push(lua_State* L, const char* str, std::size_t len) {
14096  (void)p;
14097  return p.push(L, str, len);
14098  }
14099  };
14100 
14101  template <size_t N>
14102  struct unqualified_pusher<char[N]> {
14103  static int push(lua_State* L, const char (&str)[N]) {
14104 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
14106 #endif // make sure stack doesn't overflow
14107  lua_pushlstring(L, str, std::char_traits<char>::length(str));
14108  return 1;
14109  }
14110 
14111  static int push(lua_State* L, const char (&str)[N], std::size_t sz) {
14112 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
14114 #endif // make sure stack doesn't overflow
14115  lua_pushlstring(L, str, sz);
14116  return 1;
14117  }
14118  };
14119 
14120  template <>
14121  struct unqualified_pusher<char> {
14122  static int push(lua_State* L, char c) {
14123  const char str[2] = { c, '\0' };
14124  return stack::push(L, static_cast<const char*>(str), 1);
14125  }
14126  };
14127 
14128  template <typename Ch, typename Traits, typename Al>
14129  struct unqualified_pusher<std::basic_string<Ch, Traits, Al>> {
14130  static int push(lua_State* L, const std::basic_string<Ch, Traits, Al>& str) {
14131  if constexpr (!std::is_same_v<Ch, char>) {
14132  return stack::push(L, str.data(), str.size());
14133  }
14134  else {
14135 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
14137 #endif // make sure stack doesn't overflow
14138  lua_pushlstring(L, str.c_str(), str.size());
14139  return 1;
14140  }
14141  }
14142 
14143  static int push(lua_State* L, const std::basic_string<Ch, Traits, Al>& str, std::size_t sz) {
14144  if constexpr (!std::is_same_v<Ch, char>) {
14145  return stack::push(L, str.data(), sz);
14146  }
14147  else {
14148 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
14150 #endif // make sure stack doesn't overflow
14151  lua_pushlstring(L, str.c_str(), sz);
14152  return 1;
14153  }
14154  }
14155  };
14156 
14157  template <typename Ch, typename Traits>
14159  static int push(lua_State* L, const basic_string_view<Ch, Traits>& sv) {
14160  return stack::push(L, sv.data(), sv.length());
14161  }
14162 
14163  static int push(lua_State* L, const basic_string_view<Ch, Traits>& sv, std::size_t n) {
14164  return stack::push(L, sv.data(), n);
14165  }
14166  };
14167 
14168  template <>
14170  static int push(lua_State* L, meta_function m) {
14171 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
14173 #endif // make sure stack doesn't overflow
14174  const std::string& str = to_string(m);
14175  lua_pushlstring(L, str.c_str(), str.size());
14176  return 1;
14177  }
14178  };
14179 
14180  template <>
14182  static int push(lua_State* L, absolute_index ai) {
14183 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
14185 #endif // make sure stack doesn't overflow
14186  lua_pushvalue(L, ai);
14187  return 1;
14188  }
14189  };
14190 
14191  template <>
14193  static int push(lua_State* L, raw_index ri) {
14194 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
14196 #endif // make sure stack doesn't overflow
14197  lua_pushvalue(L, ri);
14198  return 1;
14199  }
14200  };
14201 
14202  template <>
14204  static int push(lua_State* L, ref_index ri) {
14205 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
14207 #endif // make sure stack doesn't overflow
14209  return 1;
14210  }
14211  };
14212 
14213  template <>
14214  struct unqualified_pusher<const wchar_t*> {
14215  static int push(lua_State* L, const wchar_t* wstr) {
14216  return push(L, wstr, std::char_traits<wchar_t>::length(wstr));
14217  }
14218 
14219  static int push(lua_State* L, const wchar_t* wstr, std::size_t sz) {
14220  return push(L, wstr, wstr + sz);
14221  }
14222 
14223  static int push(lua_State* L, const wchar_t* strb, const wchar_t* stre) {
14224  if constexpr (sizeof(wchar_t) == 2) {
14225  const char16_t* sb = reinterpret_cast<const char16_t*>(strb);
14226  const char16_t* se = reinterpret_cast<const char16_t*>(stre);
14227  return stack::push(L, sb, se);
14228  }
14229  else {
14230  const char32_t* sb = reinterpret_cast<const char32_t*>(strb);
14231  const char32_t* se = reinterpret_cast<const char32_t*>(stre);
14232  return stack::push(L, sb, se);
14233  }
14234  }
14235  };
14236 
14237  template <>
14238  struct unqualified_pusher<wchar_t*> {
14239  static int push(lua_State* L, const wchar_t* str) {
14241  (void)p;
14242  return p.push(L, str);
14243  }
14244 
14245  static int push(lua_State* L, const wchar_t* strb, const wchar_t* stre) {
14247  (void)p;
14248  return p.push(L, strb, stre);
14249  }
14250 
14251  static int push(lua_State* L, const wchar_t* str, std::size_t len) {
14253  (void)p;
14254  return p.push(L, str, len);
14255  }
14256  };
14257 
14258  template <>
14259  struct unqualified_pusher<const char16_t*> {
14260  static int convert_into(lua_State* L, char* start, std::size_t, const char16_t* strb, const char16_t* stre) {
14261  char* target = start;
14262  char32_t cp = 0;
14263  for (const char16_t* strtarget = strb; strtarget < stre;) {
14264  auto dr = unicode::utf16_to_code_point(strtarget, stre);
14265  if (dr.error != unicode::error_code::ok) {
14267  }
14268  else {
14269  cp = dr.codepoint;
14270  }
14271  auto er = unicode::code_point_to_utf8(cp);
14272  const char* utf8data = er.code_units.data();
14273  std::memcpy(target, utf8data, er.code_units_size);
14274  target += er.code_units_size;
14275  strtarget = dr.next;
14276  }
14277 
14278  return stack::push(L, start, target);
14279  }
14280 
14281  static int push(lua_State* L, const char16_t* u16str) {
14282  return push(L, u16str, std::char_traits<char16_t>::length(u16str));
14283  }
14284 
14285  static int push(lua_State* L, const char16_t* u16str, std::size_t sz) {
14286  return push(L, u16str, u16str + sz);
14287  }
14288 
14289  static int push(lua_State* L, const char16_t* strb, const char16_t* stre) {
14291  // if our max string space is small enough, use SBO
14292  // right off the bat
14293  std::size_t max_possible_code_units = (stre - strb) * 4;
14294  if (max_possible_code_units <= SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_) {
14295  return convert_into(L, sbo, max_possible_code_units, strb, stre);
14296  }
14297  // otherwise, we must manually count/check size
14298  std::size_t needed_size = 0;
14299  for (const char16_t* strtarget = strb; strtarget < stre;) {
14300  auto dr = unicode::utf16_to_code_point(strtarget, stre);
14301  auto er = unicode::code_point_to_utf8(dr.codepoint);
14302  needed_size += er.code_units_size;
14303  strtarget = dr.next;
14304  }
14306  return convert_into(L, sbo, needed_size, strb, stre);
14307  }
14308  std::string u8str("", 0);
14309  u8str.resize(needed_size);
14310  char* target = const_cast<char*>(u8str.data());
14311  return convert_into(L, target, needed_size, strb, stre);
14312  }
14313  };
14314 
14315  template <>
14316  struct unqualified_pusher<char16_t*> {
14317  static int push(lua_State* L, const char16_t* str) {
14319  (void)p;
14320  return p.push(L, str);
14321  }
14322 
14323  static int push(lua_State* L, const char16_t* strb, const char16_t* stre) {
14325  (void)p;
14326  return p.push(L, strb, stre);
14327  }
14328 
14329  static int push(lua_State* L, const char16_t* str, std::size_t len) {
14331  (void)p;
14332  return p.push(L, str, len);
14333  }
14334  };
14335 
14336  template <>
14337  struct unqualified_pusher<const char32_t*> {
14338  static int convert_into(lua_State* L, char* start, std::size_t, const char32_t* strb, const char32_t* stre) {
14339  char* target = start;
14340  char32_t cp = 0;
14341  for (const char32_t* strtarget = strb; strtarget < stre;) {
14342  auto dr = unicode::utf32_to_code_point(strtarget, stre);
14343  if (dr.error != unicode::error_code::ok) {
14345  }
14346  else {
14347  cp = dr.codepoint;
14348  }
14349  auto er = unicode::code_point_to_utf8(cp);
14350  const char* data = er.code_units.data();
14351  std::memcpy(target, data, er.code_units_size);
14352  target += er.code_units_size;
14353  strtarget = dr.next;
14354  }
14355  return stack::push(L, start, target);
14356  }
14357 
14358  static int push(lua_State* L, const char32_t* u32str) {
14359  return push(L, u32str, u32str + std::char_traits<char32_t>::length(u32str));
14360  }
14361 
14362  static int push(lua_State* L, const char32_t* u32str, std::size_t sz) {
14363  return push(L, u32str, u32str + sz);
14364  }
14365 
14366  static int push(lua_State* L, const char32_t* strb, const char32_t* stre) {
14368  // if our max string space is small enough, use SBO
14369  // right off the bat
14370  std::size_t max_possible_code_units = (stre - strb) * 4;
14371  if (max_possible_code_units <= SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_) {
14372  return convert_into(L, sbo, max_possible_code_units, strb, stre);
14373  }
14374  // otherwise, we must manually count/check size
14375  std::size_t needed_size = 0;
14376  for (const char32_t* strtarget = strb; strtarget < stre;) {
14377  auto dr = unicode::utf32_to_code_point(strtarget, stre);
14378  auto er = unicode::code_point_to_utf8(dr.codepoint);
14379  needed_size += er.code_units_size;
14380  strtarget = dr.next;
14381  }
14383  return convert_into(L, sbo, needed_size, strb, stre);
14384  }
14385  std::string u8str("", 0);
14386  u8str.resize(needed_size);
14387  char* target = const_cast<char*>(u8str.data());
14388  return convert_into(L, target, needed_size, strb, stre);
14389  }
14390  };
14391 
14392  template <>
14393  struct unqualified_pusher<char32_t*> {
14394  static int push(lua_State* L, const char32_t* str) {
14396  (void)p;
14397  return p.push(L, str);
14398  }
14399 
14400  static int push(lua_State* L, const char32_t* strb, const char32_t* stre) {
14402  (void)p;
14403  return p.push(L, strb, stre);
14404  }
14405 
14406  static int push(lua_State* L, const char32_t* str, std::size_t len) {
14408  (void)p;
14409  return p.push(L, str, len);
14410  }
14411  };
14412 
14413  template <size_t N>
14414  struct unqualified_pusher<wchar_t[N]> {
14415  static int push(lua_State* L, const wchar_t (&str)[N]) {
14416  return push(L, str, std::char_traits<wchar_t>::length(str));
14417  }
14418 
14419  static int push(lua_State* L, const wchar_t (&str)[N], std::size_t sz) {
14420  const wchar_t* str_ptr = static_cast<const wchar_t*>(str);
14421  return stack::push<const wchar_t*>(L, str_ptr, str_ptr + sz);
14422  }
14423  };
14424 
14425  template <size_t N>
14426  struct unqualified_pusher<char16_t[N]> {
14427  static int push(lua_State* L, const char16_t (&str)[N]) {
14428  return push(L, str, std::char_traits<char16_t>::length(str));
14429  }
14430 
14431  static int push(lua_State* L, const char16_t (&str)[N], std::size_t sz) {
14432  const char16_t* str_ptr = static_cast<const char16_t*>(str);
14433  return stack::push<const char16_t*>(L, str_ptr, str_ptr + sz);
14434  }
14435  };
14436 
14437  template <size_t N>
14438  struct unqualified_pusher<char32_t[N]> {
14439  static int push(lua_State* L, const char32_t (&str)[N]) {
14440  return push(L, str, std::char_traits<char32_t>::length(str));
14441  }
14442 
14443  static int push(lua_State* L, const char32_t (&str)[N], std::size_t sz) {
14444  const char32_t* str_ptr = static_cast<const char32_t*>(str);
14445  return stack::push<const char32_t*>(L, str_ptr, str_ptr + sz);
14446  }
14447  };
14448 
14449  template <>
14450  struct unqualified_pusher<wchar_t> {
14451  static int push(lua_State* L, wchar_t c) {
14452  const wchar_t str[2] = { c, '\0' };
14453  return stack::push(L, static_cast<const wchar_t*>(str), 1);
14454  }
14455  };
14456 
14457  template <>
14458  struct unqualified_pusher<char16_t> {
14459  static int push(lua_State* L, char16_t c) {
14460  const char16_t str[2] = { c, '\0' };
14461  return stack::push(L, static_cast<const char16_t*>(str), 1);
14462  }
14463  };
14464 
14465  template <>
14466  struct unqualified_pusher<char32_t> {
14467  static int push(lua_State* L, char32_t c) {
14468  const char32_t str[2] = { c, '\0' };
14469  return stack::push(L, static_cast<const char32_t*>(str), 1);
14470  }
14471  };
14472 
14473  template <typename... Args>
14474  struct unqualified_pusher<std::tuple<Args...>> {
14475  template <std::size_t... I, typename T>
14476  static int push(std::index_sequence<I...>, lua_State* L, T&& t) {
14477 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
14478  luaL_checkstack(L, static_cast<int>(sizeof...(I)), detail::not_enough_stack_space_generic);
14479 #endif // make sure stack doesn't overflow
14480  int pushcount = 0;
14481  (void)detail::swallow { 0, (pushcount += stack::push(L, std::get<I>(std::forward<T>(t))), 0)... };
14482  return pushcount;
14483  }
14484 
14485  template <typename T>
14486  static int push(lua_State* L, T&& t) {
14487  return push(std::index_sequence_for<Args...>(), L, std::forward<T>(t));
14488  }
14489  };
14490 
14491  template <typename A, typename B>
14492  struct unqualified_pusher<std::pair<A, B>> {
14493  template <typename T>
14494  static int push(lua_State* L, T&& t) {
14495  int pushcount = stack::push(L, std::get<0>(std::forward<T>(t)));
14496  pushcount += stack::push(L, std::get<1>(std::forward<T>(t)));
14497  return pushcount;
14498  }
14499  };
14500 
14501  template <typename T>
14502  struct unqualified_pusher<T, std::enable_if_t<meta::is_optional_v<T>>> {
14504 
14505  template <typename Optional>
14506  static int push(lua_State* L, Optional&& op) {
14507  using QualifiedValueType = meta::conditional_t<std::is_lvalue_reference_v<Optional>, ValueType&, ValueType&&>;
14508  if (!op) {
14509  return stack::push(L, nullopt);
14510  }
14511  return stack::push(L, static_cast<QualifiedValueType>(op.value()));
14512  }
14513  };
14514 
14515  template <>
14517  static int push(lua_State* L, nullopt_t) {
14518  return stack::push(L, lua_nil);
14519  }
14520  };
14521 
14522  template <>
14523  struct unqualified_pusher<std::nullptr_t> {
14524  static int push(lua_State* L, std::nullptr_t) {
14525  return stack::push(L, lua_nil);
14526  }
14527  };
14528 
14529  template <>
14531  static int push(lua_State*, const this_state&) {
14532  return 0;
14533  }
14534  };
14535 
14536  template <>
14538  static int push(lua_State*, const this_main_state&) {
14539  return 0;
14540  }
14541  };
14542 
14543  template <>
14545  static int push(lua_State* L, const new_table& nt) {
14547  return 1;
14548  }
14549  };
14550 
14551  template <typename Allocator>
14552  struct unqualified_pusher<basic_bytecode<Allocator>> {
14553  template <typename T>
14554  static int push(lua_State* L, T&& bc, const char* bytecode_name) {
14555  const auto first = bc.data();
14556  const auto bcsize = bc.size();
14557  // pushes either the function, or an error
14558  // if it errors, shit goes south, and people can test that upstream
14560  L, reinterpret_cast<const char*>(first), static_cast<std::size_t>(bcsize * (sizeof(*first) / sizeof(const char))), bytecode_name);
14561  return 1;
14562  }
14563 
14564  template <typename T>
14565  static int push(lua_State* L, T&& bc) {
14566  return push(L, std::forward<bc>(bc), "bytecode");
14567  }
14568  };
14569 
14570 #if SOL_IS_ON(SOL_STD_VARIANT_I_)
14571  namespace stack_detail {
14572 
14573  struct push_function {
14575 
14577  }
14578 
14579  template <typename T>
14580  int operator()(T&& value) const {
14581  return stack::push<T>(L, std::forward<T>(value));
14582  }
14583  };
14584 
14585  } // namespace stack_detail
14586 
14587  template <typename... Tn>
14588  struct unqualified_pusher<std::variant<Tn...>> {
14589  static int push(lua_State* L, const std::variant<Tn...>& v) {
14590  return std::visit(stack_detail::push_function(L), v);
14591  }
14592 
14593  static int push(lua_State* L, std::variant<Tn...>&& v) {
14594  return std::visit(stack_detail::push_function(L), std::move(v));
14595  }
14596  };
14597 #endif // Variant because Clang is terrible
14598 
14599 }} // namespace sol::stack
14600 
14601 // end of sol/stack_push.hpp
14602 
14603 // beginning of sol/stack_pop.hpp
14604 
14605 #include <utility>
14606 #include <tuple>
14607 
14608 namespace sol {
14609 namespace stack {
14610  template <typename T, typename>
14611  struct popper {
14612  inline static decltype(auto) pop(lua_State* L) {
14613  if constexpr (is_stack_based_v<meta::unqualified_t<T>>) {
14614  static_assert(!is_stack_based_v<meta::unqualified_t<T>>,
14615  "You cannot pop something that lives solely on the stack: it will not remain on the stack when popped and thusly will go out of "
14616  "scope!");
14617  }
14618  else {
14619  record tracking{};
14620  decltype(auto) r = get<T>(L, -lua_size<T>::value, tracking);
14621  lua_pop(L, tracking.used);
14622  return r;
14623  }
14624  }
14625  };
14626 }
14627 } // namespace sol::stack
14628 
14629 // end of sol/stack_pop.hpp
14630 
14631 // beginning of sol/stack_field.hpp
14632 
14633 namespace sol { namespace stack {
14634  template <typename T, bool global, bool raw, typename>
14635  struct field_getter {
14636  static constexpr int default_table_index = meta::conditional_t < meta::is_c_str_v<T>
14637 #if SOL_LUA_VESION_I_ >= 503
14638  || (std::is_integral_v<T> && !std::is_same_v<T, bool>)
14639 #endif // integer global keys 5.3 or better
14640  || (raw && std::is_void_v<std::remove_pointer_t<T>>),
14641  std::integral_constant<int, -1>, std::integral_constant<int, -2> > ::value;
14642 
14643  template <typename Key>
14644  void get(lua_State* L, Key&& key, int tableindex = default_table_index) {
14645  if constexpr (std::is_same_v<T, update_if_empty_t> || std::is_same_v<T, override_value_t> || std::is_same_v<T, create_if_nil_t>) {
14646  (void)L;
14647  (void)key;
14648  (void)tableindex;
14649  }
14650  else if constexpr (std::is_same_v<T, env_key_t>) {
14651  (void)key;
14652 #if SOL_LUA_VESION_I_ < 502
14653  // Use lua_setfenv
14654  lua_getfenv(L, tableindex);
14655 #else
14656  // Use upvalues as explained in Lua 5.2 and beyond's manual
14657  if (lua_getupvalue(L, tableindex, 1) == nullptr) {
14658  push(L, lua_nil);
14659  }
14660 #endif
14661  }
14662  else if constexpr (std::is_same_v<T, metatable_key_t>) {
14663  (void)key;
14664  if (lua_getmetatable(L, tableindex) == 0)
14665  push(L, lua_nil);
14666  }
14667  else if constexpr (raw) {
14668  if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
14669  lua_rawgeti(L, tableindex, static_cast<lua_Integer>(key));
14670  }
14671 #if SOL_LUA_VESION_I_ >= 502
14672  else if constexpr (std::is_void_v<std::remove_pointer_t<T>>) {
14673  lua_rawgetp(L, tableindex, key);
14674  }
14675 #endif // Lua 5.2.x+
14676  else {
14677  push(L, std::forward<Key>(key));
14678  lua_rawget(L, tableindex);
14679  }
14680  }
14681  else {
14682  if constexpr (meta::is_c_str_v<T>) {
14683  if constexpr (global) {
14684  (void)tableindex;
14685  lua_getglobal(L, &key[0]);
14686  }
14687  else {
14688  lua_getfield(L, tableindex, &key[0]);
14689  }
14690  }
14691 #if SOL_LUA_VESION_I_ >= 503
14692  else if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
14693  lua_geti(L, tableindex, static_cast<lua_Integer>(key));
14694  }
14695 #endif // Lua 5.3.x+
14696  else {
14697  push(L, std::forward<Key>(key));
14698  lua_gettable(L, tableindex);
14699  }
14700  }
14701  }
14702  };
14703 
14704  template <typename... Args, bool b, bool raw, typename C>
14705  struct field_getter<std::tuple<Args...>, b, raw, C> {
14706  template <std::size_t... I, typename Keys>
14707  void apply(std::index_sequence<0, I...>, lua_State* L, Keys&& keys, int tableindex) {
14708  get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)), tableindex);
14709  void(detail::swallow { (get_field<false, raw>(L, std::get<I>(std::forward<Keys>(keys))), 0)... });
14710  reference saved(L, -1);
14711  lua_pop(L, static_cast<int>(sizeof...(I)));
14712  saved.push();
14713  }
14714 
14715  template <typename Keys>
14716  void get(lua_State* L, Keys&& keys) {
14717  apply(std::make_index_sequence<sizeof...(Args)>(), L, std::forward<Keys>(keys), lua_absindex(L, -1));
14718  }
14719 
14720  template <typename Keys>
14721  void get(lua_State* L, Keys&& keys, int tableindex) {
14722  apply(std::make_index_sequence<sizeof...(Args)>(), L, std::forward<Keys>(keys), tableindex);
14723  }
14724  };
14725 
14726  template <typename A, typename B, bool b, bool raw, typename C>
14727  struct field_getter<std::pair<A, B>, b, raw, C> {
14728  template <typename Keys>
14729  void get(lua_State* L, Keys&& keys, int tableindex) {
14730  get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)), tableindex);
14731  get_field<false, raw>(L, std::get<1>(std::forward<Keys>(keys)));
14732  reference saved(L, -1);
14733  lua_pop(L, static_cast<int>(2));
14734  saved.push();
14735  }
14736 
14737  template <typename Keys>
14738  void get(lua_State* L, Keys&& keys) {
14739  get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)));
14740  get_field<false, raw>(L, std::get<1>(std::forward<Keys>(keys)));
14741  reference saved(L, -1);
14742  lua_pop(L, static_cast<int>(2));
14743  saved.push();
14744  }
14745  };
14746 
14747  template <typename T, bool global, bool raw, typename>
14748  struct field_setter {
14749  static constexpr int default_table_index
14750  = meta::conditional_t < (meta::is_c_str_v<T> || meta::is_string_of_v<T, char>) || (std::is_integral_v<T> && !std::is_same_v<T, bool>)
14751  || (std::is_integral_v<T> && !std::is_same_v<T, bool>) || (raw && std::is_void_v<std::remove_pointer_t<T>>),
14752  std::integral_constant<int, -2>, std::integral_constant<int, -3> > ::value;
14753 
14754  template <typename Key, typename Value>
14755  void set(lua_State* L, Key&& key, Value&& value, int tableindex = default_table_index) {
14756  if constexpr (std::is_same_v<T, update_if_empty_t> || std::is_same_v<T, override_value_t>) {
14757  (void)L;
14758  (void)key;
14759  (void)value;
14760  (void)tableindex;
14761  }
14762  else if constexpr (std::is_same_v<T, metatable_key_t>) {
14763  (void)key;
14764  push(L, std::forward<Value>(value));
14765  lua_setmetatable(L, tableindex);
14766  }
14767  else if constexpr (raw) {
14768  if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
14769  push(L, std::forward<Value>(value));
14770  lua_rawseti(L, tableindex, static_cast<lua_Integer>(key));
14771  }
14772 #if SOL_LUA_VESION_I_ >= 502
14773  else if constexpr (std::is_void_v<std::remove_pointer_t<T>>) {
14774  push(L, std::forward<Value>(value));
14775  lua_rawsetp(L, tableindex, std::forward<Key>(key));
14776  }
14777 #endif // Lua 5.2.x
14778  else {
14779  push(L, std::forward<Key>(key));
14780  push(L, std::forward<Value>(value));
14781  lua_rawset(L, tableindex);
14782  }
14783  }
14784  else {
14785  if constexpr (meta::is_c_str_v<T> || meta::is_string_of_v<T, char>) {
14786  if constexpr (global) {
14787  push(L, std::forward<Value>(value));
14788  lua_setglobal(L, &key[0]);
14789  (void)tableindex;
14790  }
14791  else {
14792  push(L, std::forward<Value>(value));
14793  lua_setfield(L, tableindex, &key[0]);
14794  }
14795  }
14796 #if SOL_LUA_VESION_I_ >= 503
14797  else if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
14798  push(L, std::forward<Value>(value));
14799  lua_seti(L, tableindex, static_cast<lua_Integer>(key));
14800  }
14801 #endif // Lua 5.3.x
14802  else {
14803  push(L, std::forward<Key>(key));
14804  push(L, std::forward<Value>(value));
14805  lua_settable(L, tableindex);
14806  }
14807  }
14808  }
14809  };
14810 
14811  template <typename... Args, bool b, bool raw, typename C>
14812  struct field_setter<std::tuple<Args...>, b, raw, C> {
14813  template <bool g, std::size_t I, typename Keys, typename Value>
14814  void apply(std::index_sequence<I>, lua_State* L, Keys&& keys, Value&& value, int tableindex) {
14815  I < 1 ? set_field<g, raw>(L, std::get<I>(std::forward<Keys>(keys)), std::forward<Value>(value), tableindex)
14816  : set_field<g, raw>(L, std::get<I>(std::forward<Keys>(keys)), std::forward<Value>(value));
14817  }
14818 
14819  template <bool g, std::size_t I0, std::size_t I1, std::size_t... I, typename Keys, typename Value>
14820  void apply(std::index_sequence<I0, I1, I...>, lua_State* L, Keys&& keys, Value&& value, int tableindex) {
14821  I0 < 1 ? get_field<g, raw>(L, std::get<I0>(std::forward<Keys>(keys)), tableindex)
14822  : get_field<g, raw>(L, std::get<I0>(std::forward<Keys>(keys)), -1);
14823  apply<false>(std::index_sequence<I1, I...>(), L, std::forward<Keys>(keys), std::forward<Value>(value), -1);
14824  }
14825 
14826  template <bool g, std::size_t I0, std::size_t... I, typename Keys, typename Value>
14827  void top_apply(std::index_sequence<I0, I...>, lua_State* L, Keys&& keys, Value&& value, int tableindex) {
14828  apply<g>(std::index_sequence<I0, I...>(), L, std::forward<Keys>(keys), std::forward<Value>(value), tableindex);
14829  lua_pop(L, static_cast<int>(sizeof...(I)));
14830  }
14831 
14832  template <typename Keys, typename Value>
14833  void set(lua_State* L, Keys&& keys, Value&& value, int tableindex = -3) {
14834  top_apply<b>(std::make_index_sequence<sizeof...(Args)>(), L, std::forward<Keys>(keys), std::forward<Value>(value), tableindex);
14835  }
14836  };
14837 
14838  template <typename A, typename B, bool b, bool raw, typename C>
14839  struct field_setter<std::pair<A, B>, b, raw, C> {
14840  template <typename Keys, typename Value>
14841  void set(lua_State* L, Keys&& keys, Value&& value, int tableindex = -1) {
14842  get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)), tableindex);
14843  set_field<false, raw>(L, std::get<1>(std::forward<Keys>(keys)), std::forward<Value>(value), lua_gettop(L));
14844  lua_pop(L, 1);
14845  }
14846  };
14847 }} // namespace sol::stack
14848 
14849 // end of sol/stack_field.hpp
14850 
14851 // beginning of sol/stack_probe.hpp
14852 
14853 namespace sol {
14854 namespace stack {
14855  template <typename T, typename P, bool b, bool raw, typename>
14856  struct probe_field_getter {
14857  template <typename Key>
14858  probe get(lua_State* L, Key&& key, int tableindex = -2) {
14859  if constexpr(!b) {
14860  if (!maybe_indexable(L, tableindex)) {
14861  return probe(false, 0);
14862  }
14863  }
14864  get_field<b, raw>(L, std::forward<Key>(key), tableindex);
14865  return probe(check<P>(L), 1);
14866  }
14867  };
14868 
14869  template <typename A, typename B, typename P, bool b, bool raw, typename C>
14870  struct probe_field_getter<std::pair<A, B>, P, b, raw, C> {
14871  template <typename Keys>
14872  probe get(lua_State* L, Keys&& keys, int tableindex = -2) {
14873  if (!b && !maybe_indexable(L, tableindex)) {
14874  return probe(false, 0);
14875  }
14876  get_field<b, raw>(L, std::get<0>(keys), tableindex);
14877  if (!maybe_indexable(L)) {
14878  return probe(false, 1);
14879  }
14880  get_field<false, raw>(L, std::get<1>(keys), tableindex);
14881  return probe(check<P>(L), 2);
14882  }
14883  };
14884 
14885  template <typename... Args, typename P, bool b, bool raw, typename C>
14886  struct probe_field_getter<std::tuple<Args...>, P, b, raw, C> {
14887  template <std::size_t I, typename Keys>
14888  probe apply(std::index_sequence<I>, int sofar, lua_State* L, Keys&& keys, int tableindex) {
14889  get_field<(I<1) && b, raw>(L, std::get<I>(keys), tableindex);
14890  return probe(check<P>(L), sofar);
14891  }
14892 
14893  template <std::size_t I, std::size_t I1, std::size_t... In, typename Keys>
14894  probe apply(std::index_sequence<I, I1, In...>, int sofar, lua_State* L, Keys&& keys, int tableindex) {
14895  get_field < I<1 && b, raw>(L, std::get<I>(keys), tableindex);
14896  if (!maybe_indexable(L)) {
14897  return probe(false, sofar);
14898  }
14899  return apply(std::index_sequence<I1, In...>(), sofar + 1, L, std::forward<Keys>(keys), -1);
14900  }
14901 
14902  template <typename Keys>
14903  probe get(lua_State* L, Keys&& keys, int tableindex = -2) {
14904  if constexpr (!b) {
14905  if (!maybe_indexable(L, tableindex)) {
14906  return probe(false, 0);
14907  }
14908  return apply(std::index_sequence_for<Args...>(), 1, L, std::forward<Keys>(keys), tableindex);
14909  }
14910  else {
14911  return apply(std::index_sequence_for<Args...>(), 1, L, std::forward<Keys>(keys), tableindex);
14912  }
14913  }
14914  };
14915 }
14916 } // namespace sol::stack
14917 
14918 // end of sol/stack_probe.hpp
14919 
14920 #include <cstring>
14921 #include <array>
14922 
14923 namespace sol {
14924  namespace detail {
14927 
14929  static const std::string name = "";
14930  return name;
14931  }
14932 
14933  template <std::size_t N>
14934  const char* make_chunk_name(const string_view& code, const std::string& chunkname, char (&basechunkname)[N]) {
14935  if (chunkname.empty()) {
14936  auto it = code.cbegin();
14937  auto e = code.cend();
14938  std::size_t i = 0;
14939  static const std::size_t n = N - 4;
14940  for (i = 0; i < n && it != e; ++i, ++it) {
14941  basechunkname[i] = *it;
14942  }
14943  if (it != e) {
14944  for (std::size_t c = 0; c < 3; ++i, ++c) {
14945  basechunkname[i] = '.';
14946  }
14947  }
14948  basechunkname[i] = '\0';
14949  return &basechunkname[0];
14950  }
14951  else {
14952  return chunkname.c_str();
14953  }
14954  }
14955 
14958  while (lua_next(r.lua_state(), -2)) {
14959  absolute_index key(r.lua_state(), -2);
14960  auto pn = stack::pop_n(r.lua_state(), 1);
14961  stack::set_field<false, true>(r.lua_state(), key, lua_nil, r.stack_index());
14962  }
14963  }
14964 
14965  inline void clear_entries(const reference& registry_reference) {
14966  auto pp = stack::push_pop(registry_reference);
14967  stack_reference ref(registry_reference.lua_state(), -1);
14968  clear_entries(ref);
14969  }
14970  } // namespace detail
14971 
14972  namespace stack {
14973  namespace stack_detail {
14974  template <typename T>
14975  inline int push_as_upvalues(lua_State* L, T& item) {
14976  typedef std::decay_t<T> TValue;
14977  static const std::size_t itemsize = sizeof(TValue);
14978  static const std::size_t voidsize = sizeof(void*);
14979  static const std::size_t voidsizem1 = voidsize - 1;
14980  static const std::size_t data_t_count = (sizeof(TValue) + voidsizem1) / voidsize;
14981  typedef std::array<void*, data_t_count> data_t;
14982 
14983  data_t data { {} };
14984  std::memcpy(&data[0], std::addressof(item), itemsize);
14985  int pushcount = 0;
14986  for (const auto& v : data) {
14987  lua_pushlightuserdata(L, v);
14988  pushcount += 1;
14989  }
14990  return pushcount;
14991  }
14992 
14993  template <typename T>
14994  inline std::pair<T, int> get_as_upvalues(lua_State* L, int index = 2) {
14995  static const std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*);
14996  typedef std::array<void*, data_t_count> data_t;
14997  data_t voiddata { {} };
14998  for (std::size_t i = 0, d = 0; d < sizeof(T); ++i, d += sizeof(void*)) {
14999  voiddata[i] = lua_touserdata(L, upvalue_index(index++));
15000  }
15001  return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index);
15002  }
15003 
15004  template <typename T>
15005  inline std::pair<T, int> get_as_upvalues_using_function(lua_State* L, int function_index = -1) {
15006  static const std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*);
15007  typedef std::array<void*, data_t_count> data_t;
15008  function_index = lua_absindex(L, function_index);
15009  int index = 0;
15010  data_t voiddata { {} };
15011  for (std::size_t d = 0; d < sizeof(T); d += sizeof(void*)) {
15012  // first upvalue is nullptr to respect environment shenanigans
15013  // So +2 instead of +1
15014  const char* upvalue_name = lua_getupvalue(L, function_index, index + 2);
15015  if (upvalue_name == nullptr) {
15016  // We should freak out here...
15017  break;
15018  }
15019  voiddata[index] = lua_touserdata(L, -1);
15020  ++index;
15021  }
15022  lua_pop(L, index);
15023  return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index);
15024  }
15025 
15026  template <typename Fx, typename... Args>
15027  static decltype(auto) eval(types<>, std::index_sequence<>, lua_State*, int, record&, Fx&& fx, Args&&... args) {
15028  return std::forward<Fx>(fx)(std::forward<Args>(args)...);
15029  }
15030 
15031  template <typename Fx, typename Arg, typename... Args, std::size_t I, std::size_t... Is, typename... FxArgs>
15032  static decltype(auto) eval(
15033  types<Arg, Args...>, std::index_sequence<I, Is...>, lua_State* L, int start, record& tracking, Fx&& fx, FxArgs&&... fxargs) {
15034  return eval(types<Args...>(),
15035  std::index_sequence<Is...>(),
15036  L,
15037  start,
15038  tracking,
15039  std::forward<Fx>(fx),
15040  std::forward<FxArgs>(fxargs)...,
15041  stack_detail::unchecked_get<Arg>(L, start + tracking.used, tracking));
15042  }
15043 
15044  template <bool checkargs = detail::default_safe_function_calls, std::size_t... I, typename R, typename... Args, typename Fx, typename... FxArgs>
15045  inline decltype(auto) call(types<R>, types<Args...> ta, std::index_sequence<I...> tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
15046  static_assert(meta::all<meta::is_not_move_only<Args>...>::value,
15047  "One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take "
15048  "a reference and std::move it manually if this was your intention.");
15049  if constexpr (checkargs) {
15050  argument_handler<types<R, Args...>> handler {};
15051  multi_check<Args...>(L, start, handler);
15052  }
15053  record tracking {};
15054  if constexpr (std::is_void_v<R>) {
15055  eval(ta, tai, L, start, tracking, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
15056  }
15057  else {
15058  return eval(ta, tai, L, start, tracking, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
15059  }
15060  }
15061  } // namespace stack_detail
15062 
15063  template <typename T>
15064  int set_ref(lua_State* L, T&& arg, int tableindex = -2) {
15065  push(L, std::forward<T>(arg));
15066  return luaL_ref(L, tableindex);
15067  }
15068 
15069  template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
15070  inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
15071  using args_indices = std::make_index_sequence<sizeof...(Args)>;
15072  if constexpr (std::is_void_v<R>) {
15073  stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
15074  }
15075  else {
15076  return stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
15077  }
15078  }
15079 
15080  template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
15081  inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
15082  if constexpr (std::is_void_v<R>) {
15083  call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
15084  }
15085  else {
15086  return call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
15087  }
15088  }
15089 
15090  template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
15091  inline decltype(auto) call_from_top(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
15092  using expected_count_t = meta::count_for_pack<lua_size, Args...>;
15093  if constexpr (std::is_void_v<R>) {
15094  call<check_args>(tr,
15095  ta,
15096  L,
15097  (std::max)(static_cast<int>(lua_gettop(L) - expected_count_t::value), static_cast<int>(0)),
15098  std::forward<Fx>(fx),
15099  std::forward<FxArgs>(args)...);
15100  }
15101  else {
15102  return call<check_args>(tr,
15103  ta,
15104  L,
15105  (std::max)(static_cast<int>(lua_gettop(L) - expected_count_t::value), static_cast<int>(0)),
15106  std::forward<Fx>(fx),
15107  std::forward<FxArgs>(args)...);
15108  }
15109  }
15110 
15111  template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Ret0, typename... Ret, typename... Args,
15112  typename Fx, typename... FxArgs>
15113  inline int call_into_lua(types<Ret0, Ret...> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
15114  if constexpr (std::is_void_v<Ret0>) {
15115  call<check_args>(tr, ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
15116  if constexpr (clean_stack) {
15117  lua_settop(L, 0);
15118  }
15119  return 0;
15120  }
15121  else {
15122  (void)tr;
15123  decltype(auto) r
15124  = call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
15126  using is_stack = meta::any<is_stack_based<R>, std::is_same<R, absolute_index>, std::is_same<R, ref_index>, std::is_same<R, raw_index>>;
15127  if constexpr (clean_stack && !is_stack::value) {
15128  lua_settop(L, 0);
15129  }
15130  return push_reference(L, std::forward<decltype(r)>(r));
15131  }
15132  }
15133 
15134  template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Fx, typename... FxArgs>
15135  inline int call_lua(lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
15136  using traits_type = lua_bind_traits<meta::unqualified_t<Fx>>;
15137  using args_list = typename traits_type::args_list;
15138  using returns_list = typename traits_type::returns_list;
15139  return call_into_lua<check_args, clean_stack>(returns_list(), args_list(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
15140  }
15141 
15142  inline call_syntax get_call_syntax(lua_State* L, const string_view& key, int index) {
15143  if (lua_gettop(L) < 1) {
15144  return call_syntax::dot;
15145  }
15146  luaL_getmetatable(L, key.data());
15147  auto pn = pop_n(L, 1);
15148  if (lua_compare(L, -1, index, LUA_OPEQ) != 1) {
15149  return call_syntax::dot;
15150  }
15151  return call_syntax::colon;
15152  }
15153 
15154  inline void script(
15155  lua_State* L, lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
15156  detail::typical_chunk_name_t basechunkname = {};
15157  const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
15158  if (lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
15159  lua_error(L);
15160  }
15161  }
15162 
15163  inline void script(
15164  lua_State* L, const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
15165 
15166  detail::typical_chunk_name_t basechunkname = {};
15167  const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
15168  if (luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
15169  lua_error(L);
15170  }
15171  }
15172 
15173  inline void script_file(lua_State* L, const std::string& filename, load_mode mode = load_mode::any) {
15174  if (luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
15175  lua_error(L);
15176  }
15177  }
15178 
15180 #if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_)
15181  if (L == nullptr) {
15182  return;
15183  }
15184 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
15186 #endif // make sure stack doesn't overflow
15187  lua_pushlightuserdata(L, (void*)handler);
15188  auto pn = pop_n(L, 1);
15189  luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON);
15190 #else
15191  (void)L;
15192  (void)handler;
15193 #endif
15194  }
15195 
15197 #if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_)
15198  if (L == nullptr) {
15199  return;
15200  }
15201  luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_OFF);
15202 #else
15203  (void)L;
15204 #endif
15205  }
15206  } // namespace stack
15207 } // namespace sol
15208 
15209 // end of sol/stack.hpp
15210 
15211 // beginning of sol/object.hpp
15212 
15213 // beginning of sol/make_reference.hpp
15214 
15215 namespace sol {
15216 
15217  template <typename R = reference, bool should_pop = !is_stack_based_v<R>, typename T>
15218  R make_reference(lua_State* L, T&& value) {
15219  int backpedal = stack::push(L, std::forward<T>(value));
15220  R r = stack::get<R>(L, -backpedal);
15221  if (should_pop) {
15222  lua_pop(L, backpedal);
15223  }
15224  return r;
15225  }
15226 
15227  template <typename T, typename R = reference, bool should_pop = !is_stack_based_v<R>, typename... Args>
15228  R make_reference(lua_State* L, Args&&... args) {
15229  int backpedal = stack::push<T>(L, std::forward<Args>(args)...);
15230  R r = stack::get<R>(L, -backpedal);
15231  if (should_pop) {
15232  lua_pop(L, backpedal);
15233  }
15234  return r;
15235  }
15236 
15237  template <typename R = reference, bool should_pop = !is_stack_based_v<R>, typename T>
15239  int backpedal = stack::push_userdata(L, std::forward<T>(value));
15240  R r = stack::get<R>(L, -backpedal);
15241  if (should_pop) {
15242  lua_pop(L, backpedal);
15243  }
15244  return r;
15245  }
15246 
15247  template <typename T, typename R = reference, bool should_pop = !is_stack_based_v<R>, typename... Args>
15248  R make_reference_userdata(lua_State* L, Args&&... args) {
15249  int backpedal = stack::push_userdata<T>(L, std::forward<Args>(args)...);
15250  R r = stack::get<R>(L, -backpedal);
15251  if (should_pop) {
15252  lua_pop(L, backpedal);
15253  }
15254  return r;
15255  }
15256 
15257 } // namespace sol
15258 
15259 // end of sol/make_reference.hpp
15260 
15261 // beginning of sol/object_base.hpp
15262 
15263 namespace sol {
15264 
15265  template <typename ref_t>
15266  class basic_object_base : public ref_t {
15267  private:
15268  using base_t = ref_t;
15269 
15270  template <typename T>
15271  decltype(auto) as_stack(std::true_type) const {
15272  return stack::get<T>(base_t::lua_state(), base_t::stack_index());
15273  }
15274 
15275  template <typename T>
15276  decltype(auto) as_stack(std::false_type) const {
15277  base_t::push();
15278  return stack::pop<T>(base_t::lua_state());
15279  }
15280 
15281  template <typename T>
15282  bool is_stack(std::true_type) const {
15283  return stack::check<T>(base_t::lua_state(), base_t::stack_index(), no_panic);
15284  }
15285 
15286  template <typename T>
15287  bool is_stack(std::false_type) const {
15288  int r = base_t::registry_index();
15289  if (r == LUA_REFNIL)
15290  return meta::any_same<meta::unqualified_t<T>, lua_nil_t, nullopt_t, std::nullptr_t>::value ? true : false;
15291  if (r == LUA_NOREF)
15292  return false;
15293  auto pp = stack::push_pop(*this);
15294  return stack::check<T>(base_t::lua_state(), -1, no_panic);
15295  }
15296 
15297  public:
15298  basic_object_base() noexcept = default;
15299  basic_object_base(const basic_object_base&) = default;
15300  basic_object_base(basic_object_base&&) = default;
15301  basic_object_base& operator=(const basic_object_base&) = default;
15302  basic_object_base& operator=(basic_object_base&&) = default;
15304  basic_object_base(T&& arg, Args&&... args)
15305  : base_t(std::forward<T>(arg), std::forward<Args>(args)...) {
15306  }
15307 
15308  template <typename T>
15309  decltype(auto) as() const {
15310  return as_stack<T>(is_stack_based<base_t>());
15311  }
15312 
15313  template <typename T>
15314  bool is() const {
15315  return is_stack<T>(is_stack_based<base_t>());
15316  }
15317  };
15318 } // namespace sol
15319 
15320 // end of sol/object_base.hpp
15321 
15322 namespace sol {
15323 
15324  template <typename base_type>
15325  class basic_object : public basic_object_base<base_type> {
15326  private:
15328 
15329  template <bool invert_and_pop = false>
15330  basic_object(std::integral_constant<bool, invert_and_pop>, lua_State* L, int index = -1) noexcept
15331  : base_t(L, index) {
15332  if (invert_and_pop) {
15333  lua_pop(L, -index);
15334  }
15335  }
15336 
15337  protected:
15339  }
15340  basic_object(detail::no_safety_tag, lua_State* L, int index) : base_t(L, index) {
15341  }
15343  }
15344  basic_object(detail::no_safety_tag, lua_State* L, ref_index index) : base_t(L, index) {
15345  }
15346  template <typename T,
15349  basic_object(detail::no_safety_tag, T&& r) noexcept : base_t(std::forward<T>(r)) {
15350  }
15351 
15352  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
15353  basic_object(detail::no_safety_tag, lua_State* L, T&& r) noexcept : base_t(L, std::forward<T>(r)) {
15354  }
15355 
15356  public:
15357  basic_object() noexcept = default;
15358  template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_object>>, meta::neg<std::is_same<base_type, stack_reference>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
15360  : base_t(std::forward<T>(r)) {
15361  }
15362  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
15364  : base_t(L, std::forward<T>(r)) {
15365  }
15367  : base_t(r) {
15368  }
15369  basic_object(const basic_object&) = default;
15370  basic_object(basic_object&&) = default;
15371  basic_object(const stack_reference& r) noexcept
15372  : basic_object(r.lua_state(), r.stack_index()) {
15373  }
15375  : basic_object(r.lua_state(), r.stack_index()) {
15376  }
15377  template <typename Super>
15378  basic_object(const proxy_base<Super>& r) noexcept
15379  : basic_object(r.operator basic_object()) {
15380  }
15381  template <typename Super>
15383  : basic_object(r.operator basic_object()) {
15384  }
15386  : base_t(L, r) {
15387  }
15388  basic_object(lua_State* L, int index = -1) noexcept
15389  : base_t(L, index) {
15390  }
15392  : base_t(L, index) {
15393  }
15394  basic_object(lua_State* L, raw_index index) noexcept
15395  : base_t(L, index) {
15396  }
15397  basic_object(lua_State* L, ref_index index) noexcept
15398  : base_t(L, index) {
15399  }
15400  template <typename T, typename... Args>
15401  basic_object(lua_State* L, in_place_type_t<T>, Args&&... args) noexcept
15402  : basic_object(std::integral_constant<bool, !is_stack_based<base_t>::value>(), L, -stack::push<T>(L, std::forward<Args>(args)...)) {
15403  }
15404  template <typename T, typename... Args>
15405  basic_object(lua_State* L, in_place_t, T&& arg, Args&&... args) noexcept
15406  : basic_object(L, in_place_type<T>, std::forward<T>(arg), std::forward<Args>(args)...) {
15407  }
15408  basic_object& operator=(const basic_object&) = default;
15409  basic_object& operator=(basic_object&&) = default;
15410  basic_object& operator=(const base_type& b) {
15411  base_t::operator=(b);
15412  return *this;
15413  }
15414  basic_object& operator=(base_type&& b) {
15415  base_t::operator=(std::move(b));
15416  return *this;
15417  }
15418  template <typename Super>
15419  basic_object& operator=(const proxy_base<Super>& r) {
15420  this->operator=(r.operator basic_object());
15421  return *this;
15422  }
15423  template <typename Super>
15424  basic_object& operator=(proxy_base<Super>&& r) {
15425  this->operator=(r.operator basic_object());
15426  return *this;
15427  }
15428  };
15429 
15430  template <typename T>
15431  object make_object(lua_State* L, T&& value) {
15432  return make_reference<object, true>(L, std::forward<T>(value));
15433  }
15434 
15435  template <typename T, typename... Args>
15436  object make_object(lua_State* L, Args&&... args) {
15437  return make_reference<T, object, true>(L, std::forward<Args>(args)...);
15438  }
15439 
15440  template <typename T>
15441  object make_object_userdata(lua_State* L, T&& value) {
15442  return make_reference_userdata<object, true>(L, std::forward<T>(value));
15443  }
15444 
15445  template <typename T, typename... Args>
15446  object make_object_userdata(lua_State* L, Args&&... args) {
15447  return make_reference_userdata<T, object, true>(L, std::forward<Args>(args)...);
15448  }
15449 } // namespace sol
15450 
15451 // end of sol/object.hpp
15452 
15453 // beginning of sol/function.hpp
15454 
15455 // beginning of sol/unsafe_function.hpp
15456 
15457 // beginning of sol/function_result.hpp
15458 
15459 // beginning of sol/protected_function_result.hpp
15460 
15461 // beginning of sol/proxy_base.hpp
15462 
15463 namespace sol {
15464  struct proxy_base_tag {};
15465 
15466  namespace detail {
15467  template <typename T>
15469  std::tuple<meta::conditional_t<std::is_array_v<meta::unqualified_t<T>>, std::remove_reference_t<T>&, meta::unqualified_t<T>>>>;
15470  }
15471 
15472  template <typename Super>
15473  struct proxy_base : proxy_base_tag {
15474  operator std::string() const {
15475  const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
15476  return super.template get<std::string>();
15477  }
15478 
15479  template <typename T, meta::enable<meta::neg<meta::is_string_constructible<T>>, is_proxy_primitive<meta::unqualified_t<T>>> = meta::enabler>
15480  operator T() const {
15481  const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
15482  return super.template get<T>();
15483  }
15484 
15485  template <typename T, meta::enable<meta::neg<meta::is_string_constructible<T>>, meta::neg<is_proxy_primitive<meta::unqualified_t<T>>>> = meta::enabler>
15486  operator T&() const {
15487  const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
15488  return super.template get<T&>();
15489  }
15490 
15492  const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
15493  return super.lua_state();
15494  }
15495  };
15496 } // namespace sol
15497 
15498 // end of sol/proxy_base.hpp
15499 
15500 // beginning of sol/stack_iterator.hpp
15501 
15502 #include <limits>
15503 #include <iterator>
15504 
15505 namespace sol {
15506  template <typename proxy_t, bool is_const>
15510  typedef proxy_t value_type;
15511  typedef std::ptrdiff_t difference_type;
15512  typedef std::random_access_iterator_tag iterator_category;
15514  int index;
15516  proxy_t sp;
15517 
15519  : L(nullptr), index((std::numeric_limits<int>::max)()), stacktop((std::numeric_limits<int>::max)()), sp() {
15520  }
15522  : L(r.L), index(r.index), stacktop(r.stacktop), sp(r.sp) {
15523  }
15524  stack_iterator(lua_State* luastate, int idx, int topidx)
15525  : L(luastate), index(idx), stacktop(topidx), sp(luastate, idx) {
15526  }
15527 
15528  reference operator*() {
15529  return proxy_t(L, index);
15530  }
15531 
15532  reference operator*() const {
15533  return proxy_t(L, index);
15534  }
15535 
15536  pointer operator->() {
15537  sp = proxy_t(L, index);
15538  return &sp;
15539  }
15540 
15541  pointer operator->() const {
15542  const_cast<proxy_t&>(sp) = proxy_t(L, index);
15543  return &sp;
15544  }
15545 
15547  ++index;
15548  return *this;
15549  }
15550 
15552  auto r = *this;
15553  this->operator++();
15554  return r;
15555  }
15556 
15558  --index;
15559  return *this;
15560  }
15561 
15563  auto r = *this;
15564  this->operator--();
15565  return r;
15566  }
15567 
15568  stack_iterator& operator+=(difference_type idx) {
15569  index += static_cast<int>(idx);
15570  return *this;
15571  }
15572 
15573  stack_iterator& operator-=(difference_type idx) {
15574  index -= static_cast<int>(idx);
15575  return *this;
15576  }
15577 
15578  difference_type operator-(const stack_iterator& r) const {
15579  return index - r.index;
15580  }
15581 
15582  stack_iterator operator+(difference_type idx) const {
15583  stack_iterator r = *this;
15584  r += idx;
15585  return r;
15586  }
15587 
15588  reference operator[](difference_type idx) const {
15589  return proxy_t(L, index + static_cast<int>(idx));
15590  }
15591 
15592  bool operator==(const stack_iterator& r) const {
15593  if (stacktop == (std::numeric_limits<int>::max)()) {
15594  return r.index == r.stacktop;
15595  }
15596  else if (r.stacktop == (std::numeric_limits<int>::max)()) {
15597  return index == stacktop;
15598  }
15599  return index == r.index;
15600  }
15601 
15602  bool operator!=(const stack_iterator& r) const {
15603  return !(this->operator==(r));
15604  }
15605 
15606  bool operator<(const stack_iterator& r) const {
15607  return index < r.index;
15608  }
15609 
15610  bool operator>(const stack_iterator& r) const {
15611  return index > r.index;
15612  }
15613 
15614  bool operator<=(const stack_iterator& r) const {
15615  return index <= r.index;
15616  }
15617 
15618  bool operator>=(const stack_iterator& r) const {
15619  return index >= r.index;
15620  }
15621  };
15622 
15623  template <typename proxy_t, bool is_const>
15625  return r + n;
15626  }
15627 } // namespace sol
15628 
15629 // end of sol/stack_iterator.hpp
15630 
15631 // beginning of sol/stack_proxy.hpp
15632 
15633 // beginning of sol/stack_proxy_base.hpp
15634 
15635 namespace sol {
15636  struct stack_proxy_base : public proxy_base<stack_proxy_base> {
15637  private:
15639  int index;
15640 
15641  public:
15643  : L(nullptr), index(0) {
15644  }
15646  : L(L), index(index) {
15647  }
15648 
15649  template <typename T>
15650  decltype(auto) get() const {
15651  return stack::get<T>(L, stack_index());
15652  }
15653 
15654  template <typename T>
15655  bool is() const {
15656  return stack::check<T>(L, stack_index());
15657  }
15658 
15659  template <typename T>
15660  decltype(auto) as() const {
15661  return get<T>();
15662  }
15663 
15664  type get_type() const noexcept {
15665  return type_of(lua_state(), stack_index());
15666  }
15667 
15668  int push() const {
15669  return push(L);
15670  }
15671 
15672  int push(lua_State* Ls) const {
15673  lua_pushvalue(Ls, index);
15674  return 1;
15675  }
15676 
15678  return L;
15679  }
15680  int stack_index() const {
15681  return index;
15682  }
15683  };
15684 
15685  namespace stack {
15686  template <>
15688  static stack_proxy_base get(lua_State* L, int index = -1) {
15689  return stack_proxy_base(L, index);
15690  }
15691  };
15692 
15693  template <>
15695  static int push(lua_State*, const stack_proxy_base& ref) {
15696  return ref.push();
15697  }
15698  };
15699  } // namespace stack
15700 
15701 } // namespace sol
15702 
15703 // end of sol/stack_proxy_base.hpp
15704 
15705 namespace sol {
15706  struct stack_proxy : public stack_proxy_base {
15707  public:
15709  }
15710  stack_proxy(lua_State* L, int index) : stack_proxy_base(L, index) {
15711  }
15712 
15713  template <typename... Ret, typename... Args>
15714  decltype(auto) call(Args&&... args);
15715 
15716  template <typename... Args>
15717  decltype(auto) operator()(Args&&... args) {
15718  return call<>(std::forward<Args>(args)...);
15719  }
15720  };
15721 
15722  namespace stack {
15723  template <>
15725  static stack_proxy get(lua_State* L, int index, record& tracking) {
15726  tracking.use(0);
15727  return stack_proxy(L, index);
15728  }
15729  };
15730 
15731  template <>
15733  static int push(lua_State*, const stack_proxy& ref) {
15734  return ref.push();
15735  }
15736  };
15737  } // namespace stack
15738 } // namespace sol
15739 
15740 // end of sol/stack_proxy.hpp
15741 
15742 #include <cstdint>
15743 
15744 namespace sol {
15745  struct protected_function_result : public proxy_base<protected_function_result> {
15746  private:
15748  int index;
15752 
15753  public:
15757  typedef std::ptrdiff_t difference_type;
15758  typedef std::size_t size_type;
15761  typedef std::reverse_iterator<iterator> reverse_iterator;
15762  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
15763 
15764  protected_function_result() noexcept = default;
15765  protected_function_result(lua_State* Ls, int idx = -1, int retnum = 0, int popped = 0, call_status pferr = call_status::ok) noexcept
15766  : L(Ls), index(idx), returncount(retnum), popcount(popped), err(pferr) {
15767  }
15768 
15769  // We do not want anyone to copy these around willy-nilly
15770  // Will likely break people, but also will probably get rid of quiet bugs that have
15771  // been lurking. (E.g., Vanilla Lua will just quietly discard over-pops and under-pops:
15772  // LuaJIT and other Lua engines will implode and segfault at random later times.)
15774  protected_function_result& operator=(const protected_function_result&) = delete;
15775 
15777  : L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) {
15778  // Must be manual, otherwise destructor will screw us
15779  // return count being 0 is enough to keep things clean
15780  // but we will be thorough
15781  o.abandon();
15782  }
15784  L = o.L;
15785  index = o.index;
15786  returncount = o.returncount;
15787  popcount = o.popcount;
15788  err = o.err;
15789  // Must be manual, otherwise destructor will screw us
15790  // return count being 0 is enough to keep things clean
15791  // but we will be thorough
15792  o.abandon();
15793  return *this;
15794  }
15795 
15797  protected_function_result& operator=(const unsafe_function_result& o) = delete;
15799  protected_function_result& operator=(unsafe_function_result&& o) noexcept;
15800 
15801  call_status status() const noexcept {
15802  return err;
15803  }
15804 
15805  bool valid() const noexcept {
15806  return status() == call_status::ok || status() == call_status::yielded;
15807  }
15808 
15809  template <typename T>
15810  decltype(auto) get(int index_offset = 0) const {
15811  using UT = meta::unqualified_t<T>;
15812  int target = index + index_offset;
15813  if constexpr (meta::is_optional_v<UT>) {
15814  using ValueType = typename UT::value_type;
15815  if constexpr (std::is_same_v<ValueType, error>) {
15816  if (valid()) {
15817  return UT();
15818  }
15819  return UT(error(detail::direct_error, stack::get<std::string>(L, target)));
15820  }
15821  else {
15822  if (!valid()) {
15823  return UT();
15824  }
15825  return stack::get<UT>(L, target);
15826  }
15827  }
15828  else {
15829  if constexpr (std::is_same_v<T, error>) {
15830 #if SOL_IS_ON(SOL_SAFE_PROXIES_I_)
15831  if (valid()) {
15832  type t = type_of(L, target);
15833  type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is an error)");
15834  }
15835 #endif // Check Argument Safety
15836  return error(detail::direct_error, stack::get<std::string>(L, target));
15837  }
15838  else {
15839 #if SOL_IS_ON(SOL_SAFE_PROXIES_I_)
15840  if (!valid()) {
15841  type t = type_of(L, target);
15842  type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is not an error)");
15843  }
15844 #endif // Check Argument Safety
15845  return stack::get<T>(L, target);
15846  }
15847  }
15848  }
15849 
15850  type get_type(int index_offset = 0) const noexcept {
15851  return type_of(L, index + static_cast<int>(index_offset));
15852  }
15853 
15854  stack_proxy operator[](difference_type index_offset) const {
15855  return stack_proxy(L, index + static_cast<int>(index_offset));
15856  }
15857 
15858  iterator begin() {
15859  return iterator(L, index, stack_index() + return_count());
15860  }
15861  iterator end() {
15862  return iterator(L, stack_index() + return_count(), stack_index() + return_count());
15863  }
15864  const_iterator begin() const {
15865  return const_iterator(L, index, stack_index() + return_count());
15866  }
15867  const_iterator end() const {
15868  return const_iterator(L, stack_index() + return_count(), stack_index() + return_count());
15869  }
15870  const_iterator cbegin() const {
15871  return begin();
15872  }
15873  const_iterator cend() const {
15874  return end();
15875  }
15876 
15877  reverse_iterator rbegin() {
15878  return std::reverse_iterator<iterator>(begin());
15879  }
15880  reverse_iterator rend() {
15881  return std::reverse_iterator<iterator>(end());
15882  }
15883  const_reverse_iterator rbegin() const {
15884  return std::reverse_iterator<const_iterator>(begin());
15885  }
15886  const_reverse_iterator rend() const {
15887  return std::reverse_iterator<const_iterator>(end());
15888  }
15889  const_reverse_iterator crbegin() const {
15890  return std::reverse_iterator<const_iterator>(cbegin());
15891  }
15892  const_reverse_iterator crend() const {
15893  return std::reverse_iterator<const_iterator>(cend());
15894  }
15895 
15896  lua_State* lua_state() const noexcept {
15897  return L;
15898  };
15899  int stack_index() const noexcept {
15900  return index;
15901  };
15902  int return_count() const noexcept {
15903  return returncount;
15904  };
15905  int pop_count() const noexcept {
15906  return popcount;
15907  };
15908  void abandon() noexcept {
15909  // L = nullptr;
15910  index = 0;
15911  returncount = 0;
15912  popcount = 0;
15913  err = call_status::runtime;
15914  }
15916  stack::remove(L, index, popcount);
15917  }
15918  };
15919 
15920  namespace stack {
15921  template <>
15923  static int push(lua_State* L, const protected_function_result& pfr) {
15924 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
15926 #endif // make sure stack doesn't overflow
15927  int p = 0;
15928  for (int i = 0; i < pfr.pop_count(); ++i) {
15929  lua_pushvalue(L, i + pfr.stack_index());
15930  ++p;
15931  }
15932  return p;
15933  }
15934  };
15935  } // namespace stack
15936 } // namespace sol
15937 
15938 // end of sol/protected_function_result.hpp
15939 
15940 // beginning of sol/unsafe_function_result.hpp
15941 
15942 #include <cstdint>
15943 
15944 namespace sol {
15945  struct unsafe_function_result : public proxy_base<unsafe_function_result> {
15946  private:
15948  int index;
15950 
15951  public:
15955  typedef std::ptrdiff_t difference_type;
15956  typedef std::size_t size_type;
15959  typedef std::reverse_iterator<iterator> reverse_iterator;
15960  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
15961 
15962  unsafe_function_result() noexcept = default;
15963  unsafe_function_result(lua_State* Ls, int idx = -1, int retnum = 0) noexcept : L(Ls), index(idx), returncount(retnum) {
15964  }
15965 
15966  // We do not want anyone to copy these around willy-nilly
15967  // Will likely break people, but also will probably get rid of quiet bugs that have
15968  // been lurking. (E.g., Vanilla Lua will just quietly discard over-pops and under-pops:
15969  // LuaJIT and other Lua engines will implode and segfault at random later times.)
15971  unsafe_function_result& operator=(const unsafe_function_result&) = delete;
15972 
15973  unsafe_function_result(unsafe_function_result&& o) noexcept : L(o.L), index(o.index), returncount(o.returncount) {
15974  // Must be manual, otherwise destructor will screw us
15975  // return count being 0 is enough to keep things clean
15976  // but will be thorough
15977  o.abandon();
15978  }
15980  L = o.L;
15981  index = o.index;
15982  returncount = o.returncount;
15983  // Must be manual, otherwise destructor will screw us
15984  // return count being 0 is enough to keep things clean
15985  // but will be thorough
15986  o.abandon();
15987  return *this;
15988  }
15989 
15991  unsafe_function_result& operator=(const protected_function_result& o) = delete;
15993  unsafe_function_result& operator=(protected_function_result&& o) noexcept;
15994 
15995  template <typename T>
15996  decltype(auto) get(difference_type index_offset = 0) const {
15997  return stack::get<T>(L, index + static_cast<int>(index_offset));
15998  }
15999 
16000  type get_type(difference_type index_offset = 0) const noexcept {
16001  return type_of(L, index + static_cast<int>(index_offset));
16002  }
16003 
16004  stack_proxy operator[](difference_type index_offset) const {
16005  return stack_proxy(L, index + static_cast<int>(index_offset));
16006  }
16007 
16008  iterator begin() {
16009  return iterator(L, index, stack_index() + return_count());
16010  }
16011  iterator end() {
16012  return iterator(L, stack_index() + return_count(), stack_index() + return_count());
16013  }
16014  const_iterator begin() const {
16015  return const_iterator(L, index, stack_index() + return_count());
16016  }
16017  const_iterator end() const {
16018  return const_iterator(L, stack_index() + return_count(), stack_index() + return_count());
16019  }
16020  const_iterator cbegin() const {
16021  return begin();
16022  }
16023  const_iterator cend() const {
16024  return end();
16025  }
16026 
16027  reverse_iterator rbegin() {
16028  return std::reverse_iterator<iterator>(begin());
16029  }
16030  reverse_iterator rend() {
16031  return std::reverse_iterator<iterator>(end());
16032  }
16033  const_reverse_iterator rbegin() const {
16034  return std::reverse_iterator<const_iterator>(begin());
16035  }
16036  const_reverse_iterator rend() const {
16037  return std::reverse_iterator<const_iterator>(end());
16038  }
16039  const_reverse_iterator crbegin() const {
16040  return std::reverse_iterator<const_iterator>(cbegin());
16041  }
16042  const_reverse_iterator crend() const {
16043  return std::reverse_iterator<const_iterator>(cend());
16044  }
16045 
16046  call_status status() const noexcept {
16047  return call_status::ok;
16048  }
16049 
16050  bool valid() const noexcept {
16051  return status() == call_status::ok || status() == call_status::yielded;
16052  }
16053 
16055  return L;
16056  };
16057  int stack_index() const {
16058  return index;
16059  };
16060  int return_count() const {
16061  return returncount;
16062  };
16063  void abandon() noexcept {
16064  // L = nullptr;
16065  index = 0;
16066  returncount = 0;
16067  }
16069  lua_pop(L, returncount);
16070  }
16071  };
16072 
16073  namespace stack {
16074  template <>
16076  static int push(lua_State* L, const unsafe_function_result& fr) {
16077  int p = 0;
16078  for (int i = 0; i < fr.return_count(); ++i) {
16079  lua_pushvalue(L, i + fr.stack_index());
16080  ++p;
16081  }
16082  return p;
16083  }
16084  };
16085  } // namespace stack
16086 } // namespace sol
16087 
16088 // end of sol/unsafe_function_result.hpp
16089 
16090 #include <cstdint>
16091 
16092 namespace sol {
16093 
16094  namespace detail {
16095  template <>
16096  struct is_speshul<unsafe_function_result> : std::true_type {};
16097  template <>
16098  struct is_speshul<protected_function_result> : std::true_type {};
16099 
16100  template <std::size_t I, typename... Args, typename T>
16102  return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
16103  }
16104 
16105  template <std::size_t I, std::size_t N, typename Arg, typename... Args, typename T, meta::enable<meta::boolean<(N > 0)>> = meta::enabler>
16106  stack_proxy get(types<Arg, Args...>, meta::index_value<N>, meta::index_value<I>, const T& fr) {
16108  }
16109  } // namespace detail
16110 
16111  template <>
16112  struct tie_size<unsafe_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
16113 
16114  template <>
16115  struct tie_size<protected_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
16116 
16117  template <std::size_t I>
16118  stack_proxy get(const unsafe_function_result& fr) {
16119  return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
16120  }
16121 
16122  template <std::size_t I, typename... Args>
16123  stack_proxy get(types<Args...> t, const unsafe_function_result& fr) {
16124  return detail::get(t, meta::index_value<I>(), meta::index_value<0>(), fr);
16125  }
16126 
16127  template <std::size_t I>
16128  stack_proxy get(const protected_function_result& fr) {
16129  return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
16130  }
16131 
16132  template <std::size_t I, typename... Args>
16133  stack_proxy get(types<Args...> t, const protected_function_result& fr) {
16134  return detail::get(t, meta::index_value<I>(), meta::index_value<0>(), fr);
16135  }
16136 } // namespace sol
16137 
16138 // end of sol/function_result.hpp
16139 
16140 // beginning of sol/function_types.hpp
16141 
16142 // beginning of sol/function_types_core.hpp
16143 
16144 // beginning of sol/wrapper.hpp
16145 
16146 namespace sol {
16147 
16148  namespace detail {
16149  template <typename T>
16150  using array_return_type = meta::conditional_t<std::is_array<T>::value, std::add_lvalue_reference_t<T>, T>;
16151  }
16152 
16153  template <typename F, typename = void>
16154  struct wrapper {
16159 
16160  template <typename... Args>
16161  static decltype(auto) call(F& f, Args&&... args) {
16162  return f(std::forward<Args>(args)...);
16163  }
16164 
16165  struct caller {
16166  template <typename... Args>
16167  decltype(auto) operator()(F& fx, Args&&... args) const {
16168  return call(fx, std::forward<Args>(args)...);
16169  }
16170  };
16171  };
16172 
16173  template <typename F>
16174  struct wrapper<F, std::enable_if_t<std::is_function<std::remove_pointer_t<meta::unqualified_t<F>>>::value>> {
16179 
16180  template <F fx, typename... Args>
16181  static decltype(auto) invoke(Args&&... args) {
16182  return fx(std::forward<Args>(args)...);
16183  }
16184 
16185  template <typename... Args>
16186  static decltype(auto) call(F& fx, Args&&... args) {
16187  return fx(std::forward<Args>(args)...);
16188  }
16189 
16190  struct caller {
16191  template <typename... Args>
16192  decltype(auto) operator()(F& fx, Args&&... args) const {
16193  return call(fx, std::forward<Args>(args)...);
16194  }
16195  };
16196 
16197  template <F fx>
16198  struct invoker {
16199  template <typename... Args>
16200  decltype(auto) operator()(Args&&... args) const {
16201  return invoke<fx>(std::forward<Args>(args)...);
16202  }
16203  };
16204  };
16205 
16206  template <typename F>
16207  struct wrapper<F, std::enable_if_t<std::is_member_object_pointer<meta::unqualified_t<F>>::value>> {
16214 
16215  template <F fx>
16216  static auto call(object_type& mem) -> detail::array_return_type<decltype(mem.*fx)> {
16217  return mem.*fx;
16218  }
16219 
16220  template <F fx, typename Arg, typename... Args>
16221  static decltype(auto) invoke(object_type& mem, Arg&& arg, Args&&...) {
16222  return mem.*fx = std::forward<Arg>(arg);
16223  }
16224 
16225  template <typename Fx>
16226  static auto call(Fx&& fx, object_type& mem) -> detail::array_return_type<decltype(mem.*fx)> {
16227  return mem.*fx;
16228  }
16229 
16230  template <typename Fx, typename Arg, typename... Args>
16231  static void call(Fx&& fx, object_type& mem, Arg&& arg, Args&&...) {
16232  using actual_type = meta::unqualified_t<detail::array_return_type<decltype(mem.*fx)>>;
16233  if constexpr (std::is_array_v<actual_type>) {
16234  using std::cbegin;
16235  using std::cend;
16236  auto first = cbegin(arg);
16237  auto last = cend(arg);
16238  for (std::size_t i = 0; first != last; ++i, ++first) {
16239  (mem.*fx)[i] = *first;
16240  }
16241  }
16242  else {
16243  (mem.*fx) = std::forward<Arg>(arg);
16244  }
16245  }
16246 
16247  struct caller {
16248  template <typename Fx, typename... Args>
16249  decltype(auto) operator()(Fx&& fx, object_type& mem, Args&&... args) const {
16250  return call(std::forward<Fx>(fx), mem, std::forward<Args>(args)...);
16251  }
16252  };
16253 
16254  template <F fx>
16255  struct invoker {
16256  template <typename... Args>
16257  decltype(auto) operator()(Args&&... args) const {
16258  return invoke<fx>(std::forward<Args>(args)...);
16259  }
16260  };
16261  };
16262 
16263  template <typename F, typename R, typename O, typename... FArgs>
16265  typedef O object_type;
16268  typedef types<object_type&, FArgs...> free_args_list;
16270 
16271  template <F fx, typename... Args>
16272  static R invoke(O& mem, Args&&... args) {
16273  return (mem.*fx)(std::forward<Args>(args)...);
16274  }
16275 
16276  template <typename Fx, typename... Args>
16277  static R call(Fx&& fx, O& mem, Args&&... args) {
16278  return (mem.*fx)(std::forward<Args>(args)...);
16279  }
16280 
16281  struct caller {
16282  template <typename Fx, typename... Args>
16283  decltype(auto) operator()(Fx&& fx, O& mem, Args&&... args) const {
16284  return call(std::forward<Fx>(fx), mem, std::forward<Args>(args)...);
16285  }
16286  };
16287 
16288  template <F fx>
16289  struct invoker {
16290  template <typename... Args>
16291  decltype(auto) operator()(O& mem, Args&&... args) const {
16292  return invoke<fx>(mem, std::forward<Args>(args)...);
16293  }
16294  };
16295  };
16296 
16297  template <typename R, typename O, typename... Args>
16298  struct wrapper<R (O::*)(Args...)> : public member_function_wrapper<R (O::*)(Args...), R, O, Args...> {};
16299 
16300  template <typename R, typename O, typename... Args>
16301  struct wrapper<R (O::*)(Args...) const> : public member_function_wrapper<R (O::*)(Args...) const, R, O, Args...> {};
16302 
16303  template <typename R, typename O, typename... Args>
16304  struct wrapper<R (O::*)(Args...) const volatile> : public member_function_wrapper<R (O::*)(Args...) const volatile, R, O, Args...> {};
16305 
16306  template <typename R, typename O, typename... Args>
16307  struct wrapper<R (O::*)(Args...)&> : public member_function_wrapper<R (O::*)(Args...)&, R, O, Args...> {};
16308 
16309  template <typename R, typename O, typename... Args>
16310  struct wrapper<R (O::*)(Args...) const&> : public member_function_wrapper<R (O::*)(Args...) const&, R, O, Args...> {};
16311 
16312  template <typename R, typename O, typename... Args>
16313  struct wrapper<R (O::*)(Args...) const volatile&> : public member_function_wrapper<R (O::*)(Args...) const volatile&, R, O, Args...> {};
16314 
16315  template <typename R, typename O, typename... Args>
16316  struct wrapper<R (O::*)(Args..., ...)&> : public member_function_wrapper<R (O::*)(Args..., ...)&, R, O, Args...> {};
16317 
16318  template <typename R, typename O, typename... Args>
16319  struct wrapper<R (O::*)(Args..., ...) const&> : public member_function_wrapper<R (O::*)(Args..., ...) const&, R, O, Args...> {};
16320 
16321  template <typename R, typename O, typename... Args>
16322  struct wrapper<R (O::*)(Args..., ...) const volatile&> : public member_function_wrapper<R (O::*)(Args..., ...) const volatile&, R, O, Args...> {};
16323 
16324  template <typename R, typename O, typename... Args>
16325  struct wrapper<R (O::*)(Args...) &&> : public member_function_wrapper<R (O::*)(Args...)&, R, O, Args...> {};
16326 
16327  template <typename R, typename O, typename... Args>
16328  struct wrapper<R (O::*)(Args...) const&&> : public member_function_wrapper<R (O::*)(Args...) const&, R, O, Args...> {};
16329 
16330  template <typename R, typename O, typename... Args>
16331  struct wrapper<R (O::*)(Args...) const volatile&&> : public member_function_wrapper<R (O::*)(Args...) const volatile&, R, O, Args...> {};
16332 
16333  template <typename R, typename O, typename... Args>
16334  struct wrapper<R (O::*)(Args..., ...) &&> : public member_function_wrapper<R (O::*)(Args..., ...)&, R, O, Args...> {};
16335 
16336  template <typename R, typename O, typename... Args>
16337  struct wrapper<R (O::*)(Args..., ...) const&&> : public member_function_wrapper<R (O::*)(Args..., ...) const&, R, O, Args...> {};
16338 
16339  template <typename R, typename O, typename... Args>
16340  struct wrapper<R (O::*)(Args..., ...) const volatile&&> : public member_function_wrapper<R (O::*)(Args..., ...) const volatile&, R, O, Args...> {};
16341 
16342 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
16343  // noexcept has become a part of a function's type
16344 
16345  template <typename R, typename O, typename... Args>
16346  struct wrapper<R (O::*)(Args...) noexcept> : public member_function_wrapper<R (O::*)(Args...) noexcept, R, O, Args...> {};
16347 
16348  template <typename R, typename O, typename... Args>
16349  struct wrapper<R (O::*)(Args...) const noexcept> : public member_function_wrapper<R (O::*)(Args...) const noexcept, R, O, Args...> {};
16350 
16351  template <typename R, typename O, typename... Args>
16352  struct wrapper<R (O::*)(Args...) const volatile noexcept> : public member_function_wrapper<R (O::*)(Args...) const volatile noexcept, R, O, Args...> {};
16353 
16354  template <typename R, typename O, typename... Args>
16355  struct wrapper<R (O::*)(Args...) & noexcept> : public member_function_wrapper<R (O::*)(Args...) & noexcept, R, O, Args...> {};
16356 
16357  template <typename R, typename O, typename... Args>
16358  struct wrapper<R (O::*)(Args...) const& noexcept> : public member_function_wrapper<R (O::*)(Args...) const& noexcept, R, O, Args...> {};
16359 
16360  template <typename R, typename O, typename... Args>
16361  struct wrapper<R (O::*)(Args...) const volatile& noexcept> : public member_function_wrapper<R (O::*)(Args...) const volatile& noexcept, R, O, Args...> {};
16362 
16363  template <typename R, typename O, typename... Args>
16364  struct wrapper<R (O::*)(Args..., ...) & noexcept> : public member_function_wrapper<R (O::*)(Args..., ...) & noexcept, R, O, Args...> {};
16365 
16366  template <typename R, typename O, typename... Args>
16367  struct wrapper<R (O::*)(Args..., ...) const& noexcept> : public member_function_wrapper<R (O::*)(Args..., ...) const& noexcept, R, O, Args...> {};
16368 
16369  template <typename R, typename O, typename... Args>
16370  struct wrapper<R (O::*)(Args..., ...) const volatile& noexcept>
16371  : public member_function_wrapper<R (O::*)(Args..., ...) const volatile& noexcept, R, O, Args...> {};
16372 
16373  template <typename R, typename O, typename... Args>
16374  struct wrapper<R (O::*)(Args...) && noexcept> : public member_function_wrapper<R (O::*)(Args...) & noexcept, R, O, Args...> {};
16375 
16376  template <typename R, typename O, typename... Args>
16377  struct wrapper<R (O::*)(Args...) const&& noexcept> : public member_function_wrapper<R (O::*)(Args...) const& noexcept, R, O, Args...> {};
16378 
16379  template <typename R, typename O, typename... Args>
16380  struct wrapper<R (O::*)(Args...) const volatile&& noexcept> : public member_function_wrapper<R (O::*)(Args...) const volatile& noexcept, R, O, Args...> {};
16381 
16382  template <typename R, typename O, typename... Args>
16383  struct wrapper<R (O::*)(Args..., ...) && noexcept> : public member_function_wrapper<R (O::*)(Args..., ...) & noexcept, R, O, Args...> {};
16384 
16385  template <typename R, typename O, typename... Args>
16386  struct wrapper<R (O::*)(Args..., ...) const&& noexcept> : public member_function_wrapper<R (O::*)(Args..., ...) const& noexcept, R, O, Args...> {};
16387 
16388  template <typename R, typename O, typename... Args>
16389  struct wrapper<R (O::*)(Args..., ...) const volatile&& noexcept>
16390  : public member_function_wrapper<R (O::*)(Args..., ...) const volatile& noexcept, R, O, Args...> {};
16391 
16392 #endif // noexcept is part of a function's type
16393 
16394 } // namespace sol
16395 
16396 // end of sol/wrapper.hpp
16397 
16398 #include <memory>
16399 
16400 namespace sol {
16401 namespace function_detail {
16402  template <typename Fx, int start = 1, bool is_yielding = false>
16403  int call(lua_State* L) {
16404  Fx& fx = stack::get<user<Fx>>(L, upvalue_index(start));
16405  int nr = fx(L);
16406  if (is_yielding) {
16407  return lua_yield(L, nr);
16408  }
16409  else {
16410  return nr;
16411  }
16412  }
16413 }
16414 } // namespace sol::function_detail
16415 
16416 // end of sol/function_types_core.hpp
16417 
16418 // beginning of sol/function_types_templated.hpp
16419 
16420 // beginning of sol/call.hpp
16421 
16422 // beginning of sol/property.hpp
16423 
16424 #include <type_traits>
16425 #include <utility>
16426 
16427 namespace sol {
16428  namespace detail {
16429  struct no_prop {};
16430  }
16431 
16432  template <typename R, typename W>
16434  private:
16437 
16438  public:
16439  template <typename Rx, typename Wx>
16440  property_wrapper(Rx&& r, Wx&& w)
16441  : read_base_t(std::forward<Rx>(r)), write_base_t(std::forward<Wx>(w)) {
16442  }
16443 
16444  W& write() {
16445  return write_base_t::value();
16446  }
16447 
16448  const W& write() const {
16449  return write_base_t::value();
16450  }
16451 
16452  R& read() {
16453  return read_base_t::value();
16454  }
16455 
16456  const R& read() const {
16457  return read_base_t::value();
16458  }
16459  };
16460 
16461  template <typename F, typename G>
16462  inline decltype(auto) property(F&& f, G&& g) {
16463  typedef lua_bind_traits<meta::unqualified_t<F>> left_traits;
16464  typedef lua_bind_traits<meta::unqualified_t<G>> right_traits;
16465  if constexpr (left_traits::free_arity < right_traits::free_arity) {
16466  return property_wrapper<std::decay_t<F>, std::decay_t<G>>(std::forward<F>(f), std::forward<G>(g));
16467  }
16468  else {
16469  return property_wrapper<std::decay_t<G>, std::decay_t<F>>(std::forward<G>(g), std::forward<F>(f));
16470  }
16471  }
16472 
16473  template <typename F>
16474  inline decltype(auto) property(F&& f) {
16475  typedef lua_bind_traits<meta::unqualified_t<F>> left_traits;
16476  if constexpr (left_traits::free_arity < 2) {
16477  return property_wrapper<std::decay_t<F>, detail::no_prop>(std::forward<F>(f), detail::no_prop());
16478  }
16479  else {
16481  }
16482  }
16483 
16484  template <typename F>
16485  inline decltype(auto) readonly_property(F&& f) {
16486  return property_wrapper<std::decay_t<F>, detail::no_prop>(std::forward<F>(f), detail::no_prop());
16487  }
16488 
16489  template <typename F>
16490  inline decltype(auto) writeonly_property(F&& f) {
16492  }
16493 
16494  template <typename T>
16496  private:
16497  using base_t = detail::ebco<T>;
16498 
16499  public:
16500  using base_t::base_t;
16501 
16502  operator T&() {
16503  return base_t::value();
16504  }
16505  operator const T&() const {
16506  return base_t::value();
16507  }
16508  };
16509 
16510  // Allow someone to make a member variable readonly (const)
16511  template <typename R, typename T>
16512  inline auto readonly(R T::*v) {
16514  }
16515 
16516  template <typename T>
16518  private:
16519  using base_t = detail::ebco<T>;
16520 
16521  public:
16522  using base_t::base_t;
16523  };
16524 
16525  template <typename V>
16526  inline auto var(V&& v) {
16527  typedef std::decay_t<V> T;
16528  return var_wrapper<T>(std::forward<V>(v));
16529  }
16530 
16531  namespace meta {
16532  template <typename T>
16533  struct is_member_object : std::is_member_object_pointer<T> {};
16534 
16535  template <typename T>
16536  struct is_member_object<readonly_wrapper<T>> : std::true_type {};
16537 
16538  template <typename T>
16540  } // namespace meta
16541 
16542 } // namespace sol
16543 
16544 // end of sol/property.hpp
16545 
16546 // beginning of sol/protect.hpp
16547 
16548 #include <utility>
16549 
16550 namespace sol {
16551 
16552  template <typename T>
16553  struct protect_t {
16555 
16556  template <typename Arg, typename... Args, meta::disable<std::is_same<protect_t, meta::unqualified_t<Arg>>> = meta::enabler>
16557  protect_t(Arg&& arg, Args&&... args)
16558  : value(std::forward<Arg>(arg), std::forward<Args>(args)...) {
16559  }
16560 
16561  protect_t(const protect_t&) = default;
16562  protect_t(protect_t&&) = default;
16563  protect_t& operator=(const protect_t&) = default;
16564  protect_t& operator=(protect_t&&) = default;
16565  };
16566 
16567  template <typename T>
16568  auto protect(T&& value) {
16569  return protect_t<std::decay_t<T>>(std::forward<T>(value));
16570  }
16571 
16572 } // namespace sol
16573 
16574 // end of sol/protect.hpp
16575 
16576 namespace sol {
16577  namespace u_detail {
16578 
16579  } // namespace u_detail
16580 
16581  namespace policy_detail {
16582  template <int I, int... In>
16584  if constexpr (sizeof...(In) == 0) {
16585  (void)L;
16586  return;
16587  }
16588  else {
16589  absolute_index ai(L, I);
16590  if (type_of(L, ai) != type::userdata) {
16591  return;
16592  }
16593  lua_createtable(L, static_cast<int>(sizeof...(In)), 0);
16594  stack_reference deps(L, -1);
16595  auto per_dep = [&L, &deps](int i) {
16596 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
16598 #endif // make sure stack doesn't overflow
16599  lua_pushvalue(L, i);
16600  luaL_ref(L, deps.stack_index());
16601  };
16602  (void)per_dep;
16603  (void)detail::swallow{ int(), (per_dep(In), int())... };
16604  lua_setuservalue(L, ai);
16605  }
16606  }
16607 
16608  template <int... In>
16609  inline void handle_policy(returns_self_with<In...>, lua_State* L, int& pushed) {
16610  pushed = stack::push(L, raw_index(1));
16612  }
16613 
16614  inline void handle_policy(const stack_dependencies& sdeps, lua_State* L, int&) {
16615  absolute_index ai(L, sdeps.target);
16616  if (type_of(L, ai) != type::userdata) {
16617  return;
16618  }
16619  lua_createtable(L, static_cast<int>(sdeps.size()), 0);
16620  stack_reference deps(L, -1);
16621 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
16622  luaL_checkstack(L, static_cast<int>(sdeps.size()), detail::not_enough_stack_space_generic);
16623 #endif // make sure stack doesn't overflow
16624  for (std::size_t i = 0; i < sdeps.size(); ++i) {
16625  lua_pushvalue(L, sdeps.stack_indices[i]);
16626  luaL_ref(L, deps.stack_index());
16627  }
16628  lua_setuservalue(L, ai);
16629  }
16630 
16631  template <typename P, meta::disable<std::is_base_of<detail::policy_base_tag, meta::unqualified_t<P>>> = meta::enabler>
16632  inline void handle_policy(P&& p, lua_State* L, int& pushed) {
16633  pushed = std::forward<P>(p)(L, pushed);
16634  }
16635  } // namespace policy_detail
16636 
16637  namespace function_detail {
16639  return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)");
16640  }
16641  } // namespace function_detail
16642 
16643  namespace call_detail {
16644 
16645  template <typename R, typename W>
16646  inline auto& pick(std::true_type, property_wrapper<R, W>& f) {
16647  return f.read();
16648  }
16649 
16650  template <typename R, typename W>
16651  inline auto& pick(std::false_type, property_wrapper<R, W>& f) {
16652  return f.write();
16653  }
16654 
16655  template <typename T, typename List>
16656  struct void_call : void_call<T, meta::function_args_t<List>> {};
16657 
16658  template <typename T, typename... Args>
16659  struct void_call<T, types<Args...>> {
16660  static void call(Args...) {
16661  }
16662  };
16663 
16664  template <typename T, bool checked, bool clean_stack>
16666  T* obj_;
16667 
16668  constructor_match(T* o) : obj_(o) {
16669  }
16670 
16671  template <typename Fx, std::size_t I, typename... R, typename... Args>
16674  return stack::call_into_lua<checked, clean_stack>(r, a, L, start, func, obj_);
16675  }
16676  };
16677 
16678  namespace overload_detail {
16679  template <std::size_t... M, typename Match, typename... Args>
16680  inline int overload_match_arity(types<>, std::index_sequence<>, std::index_sequence<M...>, Match&&, lua_State* L, int, int, Args&&...) {
16681  return luaL_error(L, "sol: no matching function call takes this number of arguments and the specified types");
16682  }
16683 
16684  template <typename Fx, typename... Fxs, std::size_t I, std::size_t... In, std::size_t... M, typename Match, typename... Args>
16685  inline int overload_match_arity(types<Fx, Fxs...>, std::index_sequence<I, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L,
16686  int fxarity, int start, Args&&... args) {
16689  typedef typename traits::free_args_list args_list;
16690  // compile-time eliminate any functions that we know ahead of time are of improper arity
16691  if constexpr (!traits::runtime_variadics_t::value
16694  std::index_sequence<In...>(),
16695  std::index_sequence<M...>(),
16696  std::forward<Match>(matchfx),
16697  L,
16698  fxarity,
16699  start,
16700  std::forward<Args>(args)...);
16701  }
16702  else {
16703  if constexpr (!traits::runtime_variadics_t::value) {
16704  if (traits::free_arity != fxarity) {
16706  std::index_sequence<In...>(),
16707  std::index_sequence<traits::free_arity, M...>(),
16708  std::forward<Match>(matchfx),
16709  L,
16710  fxarity,
16711  start,
16712  std::forward<Args>(args)...);
16713  }
16714  }
16715  stack::record tracking{};
16716  if (!stack::stack_detail::check_types(args_list(), L, start, no_panic, tracking)) {
16718  std::index_sequence<In...>(),
16719  std::index_sequence<M...>(),
16720  std::forward<Match>(matchfx),
16721  L,
16722  fxarity,
16723  start,
16724  std::forward<Args>(args)...);
16725  }
16726  return matchfx(types<Fx>(), meta::index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
16727  }
16728  }
16729 
16730  template <std::size_t... M, typename Match, typename... Args>
16732  types<>, std::index_sequence<>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
16733  return overload_match_arity(types<>(),
16734  std::index_sequence<>(),
16735  std::index_sequence<M...>(),
16736  std::forward<Match>(matchfx),
16737  L,
16738  fxarity,
16739  start,
16740  std::forward<Args>(args)...);
16741  }
16742 
16743  template <typename Fx, std::size_t I, std::size_t... M, typename Match, typename... Args>
16745  types<Fx>, std::index_sequence<I>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
16748  typedef typename traits::free_args_list args_list;
16749  // compile-time eliminate any functions that we know ahead of time are of improper arity
16750  if constexpr (!traits::runtime_variadics_t::value
16752  return overload_match_arity(types<>(),
16753  std::index_sequence<>(),
16754  std::index_sequence<M...>(),
16755  std::forward<Match>(matchfx),
16756  L,
16757  fxarity,
16758  start,
16759  std::forward<Args>(args)...);
16760  }
16761  if constexpr (!traits::runtime_variadics_t::value) {
16762  if (traits::free_arity != fxarity) {
16763  return overload_match_arity(types<>(),
16764  std::index_sequence<>(),
16765  std::index_sequence<traits::free_arity, M...>(),
16766  std::forward<Match>(matchfx),
16767  L,
16768  fxarity,
16769  start,
16770  std::forward<Args>(args)...);
16771  }
16772  }
16773  return matchfx(types<Fx>(), meta::index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
16774  }
16775 
16776  template <typename Fx, typename Fx1, typename... Fxs, std::size_t I, std::size_t I1, std::size_t... In, std::size_t... M, typename Match,
16777  typename... Args>
16778  inline int overload_match_arity_single(types<Fx, Fx1, Fxs...>, std::index_sequence<I, I1, In...>, std::index_sequence<M...>, Match&& matchfx,
16779  lua_State* L, int fxarity, int start, Args&&... args) {
16782  typedef typename traits::free_args_list args_list;
16783  // compile-time eliminate any functions that we know ahead of time are of improper arity
16784  if constexpr (!traits::runtime_variadics_t::value
16787  std::index_sequence<I1, In...>(),
16788  std::index_sequence<M...>(),
16789  std::forward<Match>(matchfx),
16790  L,
16791  fxarity,
16792  start,
16793  std::forward<Args>(args)...);
16794  }
16795  else {
16796  if constexpr (!traits::runtime_variadics_t::value) {
16797  if (traits::free_arity != fxarity) {
16799  std::index_sequence<I1, In...>(),
16800  std::index_sequence<traits::free_arity, M...>(),
16801  std::forward<Match>(matchfx),
16802  L,
16803  fxarity,
16804  start,
16805  std::forward<Args>(args)...);
16806  }
16807  }
16808  stack::record tracking{};
16809  if (!stack::stack_detail::check_types(args_list(), L, start, no_panic, tracking)) {
16811  std::index_sequence<I1, In...>(),
16812  std::index_sequence<M...>(),
16813  std::forward<Match>(matchfx),
16814  L,
16815  fxarity,
16816  start,
16817  std::forward<Args>(args)...);
16818  }
16819  return matchfx(types<Fx>(), meta::index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
16820  }
16821  }
16822  } // namespace overload_detail
16823 
16824  template <typename... Functions, typename Match, typename... Args>
16825  inline int overload_match_arity(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
16827  std::make_index_sequence<sizeof...(Functions)>(),
16828  std::index_sequence<>(),
16829  std::forward<Match>(matchfx),
16830  L,
16831  fxarity,
16832  start,
16833  std::forward<Args>(args)...);
16834  }
16835 
16836  template <typename... Functions, typename Match, typename... Args>
16837  inline int overload_match(Match&& matchfx, lua_State* L, int start, Args&&... args) {
16838  int fxarity = lua_gettop(L) - (start - 1);
16839  return overload_match_arity<Functions...>(std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
16840  }
16841 
16842  template <typename T, typename... TypeLists, typename Match, typename... Args>
16843  inline int construct_match(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
16844  // use same overload resolution matching as all other parts of the framework
16846  std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
16847  }
16848 
16849  template <typename T, bool checked, bool clean_stack, typename... TypeLists>
16851  static const auto& meta = usertype_traits<T>::metatable();
16852  int argcount = lua_gettop(L);
16854  argcount -= static_cast<int>(syntax);
16855 
16856  T* obj = detail::usertype_allocate<T>(L);
16857  reference userdataref(L, -1);
16858  stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
16859  umf();
16860 
16861  // put userdata at the first index
16862  lua_insert(L, 1);
16863  construct_match<T, TypeLists...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, 1 + static_cast<int>(syntax));
16864 
16865  userdataref.push();
16866  return 1;
16867  }
16868 
16869  template <typename T, bool checked, bool clean_stack, typename... TypeLists>
16870  inline int construct(lua_State* L) {
16871  return detail::static_trampoline<&construct_trampolined<T, checked, clean_stack, TypeLists...>>(L);
16872  }
16873 
16874  template <typename F, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename = void>
16876  template <typename Fx, typename... Args>
16877  static int call(lua_State* L, Fx&& f, Args&&... args) {
16878  using uFx = meta::unqualified_t<Fx>;
16879  static constexpr bool is_ref = is_lua_reference_v<uFx>;
16880  if constexpr (is_ref) {
16881  if constexpr (is_index) {
16882  return stack::push(L, std::forward<Fx>(f), std::forward<Args>(args)...);
16883  }
16884  else {
16885  std::forward<Fx>(f) = stack::unqualified_get<F>(L, boost + (is_variable ? 3 : 1));
16886  return 0;
16887  }
16888  }
16889  else {
16890  using wrap = wrapper<uFx>;
16891  using traits_type = typename wrap::traits_type;
16892  using fp_t = typename traits_type::function_pointer_type;
16893  constexpr bool is_function_pointer_convertible
16894  = std::is_class_v<uFx> && std::is_convertible_v<std::decay_t<Fx>, fp_t>;
16895  if constexpr (is_function_pointer_convertible) {
16896  fp_t fx = f;
16898  L, fx, std::forward<Args>(args)...);
16899  }
16900  else {
16901  using returns_list = typename wrap::returns_list;
16902  using args_list = typename wrap::free_args_list;
16903  using caller = typename wrap::caller;
16904  return stack::call_into_lua<checked, clean_stack>(
16905  returns_list(), args_list(), L, boost + 1, caller(), std::forward<Fx>(f), std::forward<Args>(args)...);
16906  }
16907  }
16908  }
16909  };
16910 
16911  template <typename T, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
16912  struct agnostic_lua_call_wrapper<var_wrapper<T>, is_index, is_variable, checked, boost, clean_stack, C> {
16913  template <typename F>
16914  static int call(lua_State* L, F&& f) {
16915  if constexpr (is_index) {
16916  constexpr bool is_stack = is_stack_based_v<meta::unqualified_t<decltype(detail::unwrap(f.value()))>>;
16917  if constexpr (clean_stack && !is_stack) {
16918  lua_settop(L, 0);
16919  }
16920  return stack::push_reference(L, detail::unwrap(f.value()));
16921  }
16922  else {
16923  if constexpr (std::is_const_v<meta::unwrapped_t<T>>) {
16924  (void)f;
16925  return luaL_error(L, "sol: cannot write to a readonly (const) variable");
16926  }
16927  else {
16928  using R = meta::unwrapped_t<T>;
16929  if constexpr (std::is_assignable_v<std::add_lvalue_reference_t<meta::unqualified_t<R>>, R>) {
16930  detail::unwrap(f.value()) = stack::unqualified_get<meta::unwrapped_t<T>>(L, boost + (is_variable ? 3 : 1));
16931  if (clean_stack) {
16932  lua_settop(L, 0);
16933  }
16934  return 0;
16935  }
16936  else {
16937  return luaL_error(L, "sol: cannot write to this variable: copy assignment/constructor not available");
16938  }
16939  }
16940  }
16941  }
16942  };
16943 
16944  template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
16945  struct agnostic_lua_call_wrapper<lua_CFunction_ref, is_index, is_variable, checked, boost, clean_stack, C> {
16946  static int call(lua_State* L, lua_CFunction_ref f) {
16947  return f(L);
16948  }
16949  };
16950 
16951  template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
16952  struct agnostic_lua_call_wrapper<lua_CFunction, is_index, is_variable, checked, boost, clean_stack, C> {
16953  static int call(lua_State* L, lua_CFunction f) {
16954  return f(L);
16955  }
16956  };
16957 
16958 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
16959  template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
16960  struct agnostic_lua_call_wrapper<detail::lua_CFunction_noexcept, is_index, is_variable, checked, boost, clean_stack, C> {
16962  return f(L);
16963  }
16964  };
16965 #endif // noexcept function types
16966 
16967  template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
16968  struct agnostic_lua_call_wrapper<detail::no_prop, is_index, is_variable, checked, boost, clean_stack, C> {
16969  static int call(lua_State* L, const detail::no_prop&) {
16970  return luaL_error(L, is_index ? "sol: cannot read from a writeonly property" : "sol: cannot write to a readonly property");
16971  }
16972  };
16973 
16974  template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
16975  struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, checked, boost, clean_stack, C> {
16976  static int call(lua_State* L, const no_construction&) {
16978  }
16979  };
16980 
16981  template <typename... Args, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
16982  struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, checked, boost, clean_stack, C> {
16983  static int call(lua_State*, const bases<Args...>&) {
16984  // Uh. How did you even call this, lul
16985  return 0;
16986  }
16987  };
16988 
16989  template <typename T, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
16990  struct agnostic_lua_call_wrapper<std::reference_wrapper<T>, is_index, is_variable, checked, boost, clean_stack, C> {
16991  static int call(lua_State* L, std::reference_wrapper<T> f) {
16993  return alcw.call(L, f.get());
16994  }
16995  };
16996 
16997  template <typename T, typename F, bool is_index, bool is_variable, bool checked = detail::default_safe_function_calls, int boost = 0,
16998  bool clean_stack = true, typename = void>
17000  template <typename Fx, typename... Args>
17001  static int call(lua_State* L, Fx&& fx, Args&&... args) {
17002  if constexpr (std::is_member_function_pointer_v<F>) {
17003  using wrap = wrapper<F>;
17004  using object_type = typename wrap::object_type;
17005  if constexpr (sizeof...(Args) < 1) {
17006  using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
17007  static_assert(std::is_base_of_v<object_type, Ta>, "It seems like you might have accidentally bound a class type with a member function method that does not correspond to the class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one class \"T\" but then bind member methods from a complete unrelated class. Check things over!");
17008 #if SOL_IS_ON(SOL_SAFE_USERTYPE_I_)
17009  auto maybeo = stack::check_get<Ta*>(L, 1);
17010  if (!maybeo || maybeo.value() == nullptr) {
17011  return luaL_error(L,
17012  "sol: received nil for 'self' argument (use ':' for accessing member functions, make sure member variables are "
17013  "preceeded by the "
17014  "actual object with '.' syntax)");
17015  }
17016  object_type* o = static_cast<object_type*>(maybeo.value());
17017  return call(L, std::forward<Fx>(fx), *o);
17018 #else
17019  object_type& o = static_cast<object_type&>(*stack::unqualified_get<non_null<Ta*>>(L, 1));
17020  return call(L, std::forward<Fx>(fx), o);
17021 #endif // Safety
17022  }
17023  else {
17024  using returns_list = typename wrap::returns_list;
17025  using args_list = typename wrap::args_list;
17026  using caller = typename wrap::caller;
17027  return stack::call_into_lua<checked, clean_stack>(
17028  returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), std::forward<Fx>(fx), std::forward<Args>(args)...);
17029  }
17030  }
17031  else if constexpr (std::is_member_object_pointer_v<F>) {
17032  using wrap = wrapper<F>;
17033  using object_type = typename wrap::object_type;
17034  if constexpr (is_index) {
17035  if constexpr (sizeof...(Args) < 1) {
17036  using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
17037  static_assert(std::is_base_of_v<object_type, Ta>, "It seems like you might have accidentally bound a class type with a member function method that does not correspond to the class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one class \"T\" but then bind member methods from a complete unrelated class. Check things over!");
17038 #if SOL_IS_ON(SOL_SAFE_USERTYPE_I_)
17039  auto maybeo = stack::check_get<Ta*>(L, 1);
17040  if (!maybeo || maybeo.value() == nullptr) {
17041  if (is_variable) {
17042  return luaL_error(L, "sol: 'self' argument is lua_nil (bad '.' access?)");
17043  }
17044  return luaL_error(L, "sol: 'self' argument is lua_nil (pass 'self' as first argument)");
17045  }
17046  object_type* o = static_cast<object_type*>(maybeo.value());
17047  return call(L, std::forward<Fx>(fx), *o);
17048 #else
17049  object_type& o = static_cast<object_type&>(*stack::get<non_null<Ta*>>(L, 1));
17050  return call(L, std::forward<Fx>(fx), o);
17051 #endif // Safety
17052  }
17053  else {
17054  using returns_list = typename wrap::returns_list;
17055  using caller = typename wrap::caller;
17056  return stack::call_into_lua<checked, clean_stack>(returns_list(),
17057  types<>(),
17058  L,
17059  boost + (is_variable ? 3 : 2),
17060  caller(),
17061  std::forward<Fx>(fx),
17062  std::forward<Args>(args)...);
17063  }
17064  }
17065  else {
17066  using traits_type = lua_bind_traits<F>;
17067  using return_type = typename traits_type::return_type;
17068  constexpr bool ret_is_const = std::is_const_v<std::remove_reference_t<return_type>>;
17069  if constexpr (ret_is_const) {
17070  (void)fx;
17071  (void)detail::swallow{ 0, (static_cast<void>(args), 0)... };
17072  return luaL_error(L, "sol: cannot write to a readonly (const) variable");
17073  }
17074  else {
17075  using u_return_type = meta::unqualified_t<return_type>;
17076  constexpr bool is_assignable = std::is_copy_assignable_v<u_return_type> || std::is_array_v<u_return_type>;
17077  if constexpr (!is_assignable) {
17078  (void)fx;
17079  (void)detail::swallow{ 0, ((void)args, 0)... };
17080  return luaL_error(L, "sol: cannot write to this variable: copy assignment/constructor not available");
17081  }
17082  else {
17083  using args_list = typename wrap::args_list;
17084  using caller = typename wrap::caller;
17085  if constexpr (sizeof...(Args) > 0) {
17086  return stack::call_into_lua<checked, clean_stack>(types<void>(),
17087  args_list(),
17088  L,
17089  boost + (is_variable ? 3 : 2),
17090  caller(),
17091  std::forward<Fx>(fx),
17092  std::forward<Args>(args)...);
17093  }
17094  else {
17095  using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
17096 #if SOL_IS_ON(SOL_SAFE_USERTYPE_I_)
17097  auto maybeo = stack::check_get<Ta*>(L, 1);
17098  if (!maybeo || maybeo.value() == nullptr) {
17099  if (is_variable) {
17100  return luaL_error(L, "sol: received nil for 'self' argument (bad '.' access?)");
17101  }
17102  return luaL_error(L, "sol: received nil for 'self' argument (pass 'self' as first argument)");
17103  }
17104  object_type* po = static_cast<object_type*>(maybeo.value());
17105  object_type& o = *po;
17106 #else
17107  object_type& o = static_cast<object_type&>(*stack::get<non_null<Ta*>>(L, 1));
17108 #endif // Safety
17109 
17110  return stack::call_into_lua<checked, clean_stack>(
17111  types<void>(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), std::forward<Fx>(fx), o);
17112  }
17113  }
17114  }
17115  }
17116  }
17117  else {
17119  return alcw.call(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
17120  }
17121  }
17122  };
17123 
17124  template <typename T, typename F, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
17125  struct lua_call_wrapper<T, readonly_wrapper<F>, is_index, is_variable, checked, boost, clean_stack, C> {
17127  using wrap = wrapper<F>;
17128  using object_type = typename wrap::object_type;
17129 
17130  static int call(lua_State* L, readonly_wrapper<F>&& rw) {
17131  if constexpr (!is_index) {
17132  (void)rw;
17133  return luaL_error(L, "sol: cannot write to a sol::readonly variable");
17134  }
17135  else {
17137  return lcw.call(L, std::move(rw.value()));
17138  }
17139  }
17140 
17141  static int call(lua_State* L, readonly_wrapper<F>&& rw, object_type& o) {
17142  if constexpr (!is_index) {
17143  (void)o;
17144  return call(L, std::move(rw));
17145  }
17146  else {
17148  return lcw.call(L, rw.value(), o);
17149  }
17150  }
17151 
17152  static int call(lua_State* L, const readonly_wrapper<F>& rw) {
17153  if constexpr (!is_index) {
17154  (void)rw;
17155  return luaL_error(L, "sol: cannot write to a sol::readonly variable");
17156  }
17157  else {
17159  return lcw.call(L, rw.value());
17160  }
17161  }
17162 
17163  static int call(lua_State* L, const readonly_wrapper<F>& rw, object_type& o) {
17164  if constexpr (!is_index) {
17165  (void)o;
17166  return call(L, rw);
17167  }
17168  else {
17170  return lcw.call(L, rw.value(), o);
17171  }
17172  }
17173  };
17174 
17175  template <typename T, typename... Args, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
17176  struct lua_call_wrapper<T, constructor_list<Args...>, is_index, is_variable, checked, boost, clean_stack, C> {
17177  typedef constructor_list<Args...> F;
17178 
17179  static int call(lua_State* L, F&) {
17180  const auto& meta = usertype_traits<T>::metatable();
17181  int argcount = lua_gettop(L);
17183  argcount -= static_cast<int>(syntax);
17184 
17185  T* obj = detail::usertype_allocate<T>(L);
17186  reference userdataref(L, -1);
17187  stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
17188  umf();
17189 
17190  // put userdata at the first index
17191  lua_insert(L, 1);
17192  construct_match<T, Args...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, boost + 1 + 1 + static_cast<int>(syntax));
17193 
17194  userdataref.push();
17195  return 1;
17196  }
17197  };
17198 
17199  template <typename T, typename... Cxs, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
17200  struct lua_call_wrapper<T, constructor_wrapper<Cxs...>, is_index, is_variable, checked, boost, clean_stack, C> {
17201  typedef constructor_wrapper<Cxs...> F;
17202 
17203  struct onmatch {
17204  template <typename Fx, std::size_t I, typename... R, typename... Args>
17206  const auto& meta = usertype_traits<T>::metatable();
17207  T* obj = detail::usertype_allocate<T>(L);
17208  reference userdataref(L, -1);
17209  stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
17210  umf();
17211 
17212  auto& func = std::get<I>(f.functions);
17213  // put userdata at the first index
17214  lua_insert(L, 1);
17215  stack::call_into_lua<checked, clean_stack>(r, a, L, boost + 1 + start, func, detail::implicit_wrapper<T>(obj));
17216 
17217  userdataref.push();
17218  return 1;
17219  }
17220  };
17221 
17222  static int call(lua_State* L, F& f) {
17224  int syntaxval = static_cast<int>(syntax);
17225  int argcount = lua_gettop(L) - syntaxval;
17226  return construct_match<T, meta::pop_front_type_t<meta::function_args_t<Cxs>>...>(onmatch(), L, argcount, 1 + syntaxval, f);
17227  }
17228  };
17229 
17230  template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
17231  struct lua_call_wrapper<T, destructor_wrapper<Fx>, is_index, is_variable, checked, boost, clean_stack, C> {
17232 
17233  template <typename F>
17234  static int call(lua_State* L, F&& f) {
17235  if constexpr (std::is_void_v<Fx>) {
17236  return detail::usertype_alloc_destruct<T>(L);
17237  }
17238  else {
17239  using uFx = meta::unqualified_t<Fx>;
17241  return lcw.call(L, std::forward<F>(f).fx);
17242  }
17243  }
17244  };
17245 
17246  template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
17247  struct lua_call_wrapper<T, overload_set<Fs...>, is_index, is_variable, checked, boost, clean_stack, C> {
17248  typedef overload_set<Fs...> F;
17249 
17250  struct on_match {
17251  template <typename Fx, std::size_t I, typename... R, typename... Args>
17253  auto& f = std::get<I>(fx.functions);
17255  }
17256  };
17257 
17258  static int call(lua_State* L, F& fx) {
17259  return overload_match_arity<Fs...>(on_match(), L, lua_gettop(L), 1, fx);
17260  }
17261  };
17262 
17263  template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
17264  struct lua_call_wrapper<T, factory_wrapper<Fs...>, is_index, is_variable, checked, boost, clean_stack, C> {
17265  typedef factory_wrapper<Fs...> F;
17266 
17267  struct on_match {
17268  template <typename Fx, std::size_t I, typename... R, typename... Args>
17270  auto& f = std::get<I>(fx.functions);
17272  }
17273  };
17274 
17275  static int call(lua_State* L, F& fx) {
17276  return overload_match_arity<Fs...>(on_match(), L, lua_gettop(L) - boost, 1 + boost, fx);
17277  }
17278  };
17279 
17280  template <typename T, typename R, typename W, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
17281  struct lua_call_wrapper<T, property_wrapper<R, W>, is_index, is_variable, checked, boost, clean_stack, C> {
17284  typedef wrapper<U> wrap;
17287 
17288  template <typename F, typename... Args>
17289  static int call(lua_State* L, F&& f, Args&&... args) {
17290  constexpr bool is_specialized = meta::any<std::is_same<U, detail::no_prop>,
17294  std::is_member_pointer<U>>::value;
17295  if constexpr (is_specialized) {
17296  if constexpr (is_index) {
17297  decltype(auto) p = f.read();
17298  lua_call_wrapper<T, meta::unqualified_t<decltype(p)>, is_index, is_variable, checked, boost, clean_stack> lcw{};
17299  return lcw.call(L, p, std::forward<Args>(args)...);
17300  }
17301  else {
17302  decltype(auto) p = f.write();
17303  lua_call_wrapper<T, meta::unqualified_t<decltype(p)>, is_index, is_variable, checked, boost, clean_stack> lcw{};
17304  return lcw.call(L, p, std::forward<Args>(args)...);
17305  }
17306  }
17307  else {
17308  constexpr bool non_class_object_type = meta::any<std::is_void<object_type>,
17310  if constexpr (non_class_object_type) {
17311  // The type being void means we don't have any arguments, so it might be a free functions?
17312  using args_list = typename traits_type::free_args_list;
17313  using returns_list = typename wrap::returns_list;
17314  using caller = typename wrap::caller;
17315  if constexpr (is_index) {
17316  decltype(auto) pf = f.read();
17317  return stack::call_into_lua<checked, clean_stack>(
17318  returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), pf);
17319  }
17320  else {
17321  decltype(auto) pf = f.write();
17322  return stack::call_into_lua<checked, clean_stack>(
17323  returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), pf);
17324  }
17325  }
17326  else {
17328  using Ta = T;
17329  using Oa = std::remove_pointer_t<object_type>;
17330 #if SOL_IS_ON(SOL_SAFE_USERTYPE_I_)
17331  auto maybeo = stack::check_get<Ta*>(L, 1);
17332  if (!maybeo || maybeo.value() == nullptr) {
17333  if (is_variable) {
17334  return luaL_error(L, "sol: 'self' argument is lua_nil (bad '.' access?)");
17335  }
17336  return luaL_error(L, "sol: 'self' argument is lua_nil (pass 'self' as first argument)");
17337  }
17338  Oa* o = static_cast<Oa*>(maybeo.value());
17339 #else
17340  Oa* o = static_cast<Oa*>(stack::get<non_null<Ta*>>(L, 1));
17341 #endif // Safety
17342  using returns_list = typename wrap::returns_list;
17343  using caller = typename wrap::caller;
17344  if constexpr (is_index) {
17345  decltype(auto) pf = f.read();
17346  return stack::call_into_lua<checked, clean_stack>(
17347  returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), pf, detail::implicit_wrapper<Oa>(*o));
17348  }
17349  else {
17350  decltype(auto) pf = f.write();
17351  return stack::call_into_lua<checked, clean_stack>(
17352  returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), pf, detail::implicit_wrapper<Oa>(*o));
17353  }
17354  }
17355  }
17356  }
17357  };
17358 
17359  template <typename T, typename V, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
17360  struct lua_call_wrapper<T, protect_t<V>, is_index, is_variable, checked, boost, clean_stack, C> {
17361  typedef protect_t<V> F;
17362 
17363  template <typename... Args>
17364  static int call(lua_State* L, F& fx, Args&&... args) {
17365  return lua_call_wrapper<T, V, is_index, is_variable, true, boost, clean_stack>{}.call(L, fx.value, std::forward<Args>(args)...);
17366  }
17367  };
17368 
17369  template <typename T, typename F, typename... Policies, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
17370  struct lua_call_wrapper<T, policy_wrapper<F, Policies...>, is_index, is_variable, checked, boost, clean_stack, C> {
17371  typedef policy_wrapper<F, Policies...> P;
17372 
17373  template <std::size_t... In>
17374  static int call(std::index_sequence<In...>, lua_State* L, P& fx) {
17376  (void)detail::swallow{ int(), (policy_detail::handle_policy(std::get<In>(fx.policies), L, pushed), int())... };
17377  return pushed;
17378  }
17379 
17380  static int call(lua_State* L, P& fx) {
17381  typedef typename P::indices indices;
17382  return call(indices(), L, fx);
17383  }
17384  };
17385 
17386  template <typename T, typename Y, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
17387  struct lua_call_wrapper<T, yielding_t<Y>, is_index, is_variable, checked, boost, clean_stack, C> {
17388  template <typename F>
17389  static int call(lua_State* L, F&& f) {
17390  return lua_call_wrapper<T, meta::unqualified_t<Y>, is_index, is_variable, checked, boost, clean_stack>{}.call(L, f.func);
17391  }
17392  };
17393 
17394  template <typename T, typename Sig, typename P, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
17395  struct lua_call_wrapper<T, function_arguments<Sig, P>, is_index, is_variable, checked, boost, clean_stack, C> {
17396  static int call(lua_State* L, const function_arguments<Sig, P>& f) {
17397  lua_call_wrapper<T, meta::unqualified_t<P>, is_index, is_variable, checked, boost, clean_stack> lcw{};
17398  return lcw.call(L, std::get<0>(f.arguments));
17399  }
17400 
17402  lua_call_wrapper<T, meta::unqualified_t<P>, is_index, is_variable, checked, boost, clean_stack> lcw{};
17403  return lcw.call(L, std::get<0>(std::move(f.arguments)));
17404  }
17405  };
17406 
17407  template <typename T, bool is_index, bool is_variable, int boost = 0, bool checked = detail::default_safe_function_calls, bool clean_stack = true,
17408  typename Fx, typename... Args>
17409  inline int call_wrapped(lua_State* L, Fx&& fx, Args&&... args) {
17410  using uFx = meta::unqualified_t<Fx>;
17411  if constexpr (meta::is_specialization_of_v<uFx, yielding_t>) {
17412  using real_fx = meta::unqualified_t<decltype(std::forward<Fx>(fx).func)>;
17414  return lcw.call(L, std::forward<Fx>(fx).func, std::forward<Args>(args)...);
17415  }
17416  else {
17418  return lcw.call(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
17419  }
17420  }
17421 
17422  template <typename T, bool is_index, bool is_variable, typename F, int start = 1, bool checked = detail::default_safe_function_calls,
17423  bool clean_stack = true>
17424  inline int call_user(lua_State* L) {
17425  auto& fx = stack::unqualified_get<user<F>>(L, upvalue_index(start));
17426  using uFx = meta::unqualified_t<F>;
17427  int nr = call_wrapped<T, is_index, is_variable, 0, checked, clean_stack>(L, fx);
17428  if constexpr (meta::is_specialization_of_v<uFx, yielding_t>) {
17429  return lua_yield(L, nr);
17430  }
17431  else {
17432  return nr;
17433  }
17434  }
17435 
17436  template <typename T, typename = void>
17437  struct is_var_bind : std::false_type {};
17438 
17439  template <typename T>
17440  struct is_var_bind<T, std::enable_if_t<std::is_member_object_pointer<T>::value>> : std::true_type {};
17441 
17442  template <typename T>
17443  struct is_var_bind<T, std::enable_if_t<is_lua_reference_or_proxy<T>::value>> : std::true_type {};
17444 
17445  template <>
17446  struct is_var_bind<detail::no_prop> : std::true_type {};
17447 
17448  template <typename R, typename W>
17449  struct is_var_bind<property_wrapper<R, W>> : std::true_type {};
17450 
17451  template <typename T>
17452  struct is_var_bind<var_wrapper<T>> : std::true_type {};
17453 
17454  template <typename T>
17455  struct is_var_bind<readonly_wrapper<T>> : is_var_bind<meta::unqualified_t<T>> {};
17456 
17457  template <typename F, typename... Policies>
17458  struct is_var_bind<policy_wrapper<F, Policies...>> : is_var_bind<meta::unqualified_t<F>> {};
17459  } // namespace call_detail
17460 
17461  template <typename T>
17462  struct is_variable_binding : call_detail::is_var_bind<meta::unqualified_t<T>> {};
17463 
17464  template <typename T>
17466 
17467  template <typename T>
17468  struct is_function_binding : meta::neg<is_variable_binding<T>> {};
17469 
17470 } // namespace sol
17471 
17472 // end of sol/call.hpp
17473 
17474 namespace sol {
17475  namespace function_detail {
17476  template <typename F, F fx>
17477  inline int call_wrapper_variable(std::false_type, lua_State* L) {
17478  typedef meta::bind_traits<meta::unqualified_t<F>> traits_type;
17479  typedef typename traits_type::args_list args_list;
17481  return stack::call_into_lua(return_type(), args_list(), L, 1, fx);
17482  }
17483 
17484  template <typename R, typename V, V, typename T>
17485  inline int call_set_assignable(std::false_type, T&&, lua_State* L) {
17486  return luaL_error(L, "cannot write to this type: copy assignment/constructor not available");
17487  }
17488 
17489  template <typename R, typename V, V variable, typename T>
17490  inline int call_set_assignable(std::true_type, lua_State* L, T&& mem) {
17491  (mem.*variable) = stack::get<R>(L, 2);
17492  return 0;
17493  }
17494 
17495  template <typename R, typename V, V, typename T>
17496  inline int call_set_variable(std::false_type, lua_State* L, T&&) {
17497  return luaL_error(L, "cannot write to a const variable");
17498  }
17499 
17500  template <typename R, typename V, V variable, typename T>
17501  inline int call_set_variable(std::true_type, lua_State* L, T&& mem) {
17502  return call_set_assignable<R, V, variable>(std::is_assignable<std::add_lvalue_reference_t<R>, R>(), L, std::forward<T>(mem));
17503  }
17504 
17505  template <typename V, V variable>
17506  inline int call_wrapper_variable(std::true_type, lua_State* L) {
17507  typedef meta::bind_traits<meta::unqualified_t<V>> traits_type;
17508  typedef typename traits_type::object_type T;
17509  typedef typename traits_type::return_type R;
17510  auto& mem = stack::get<T>(L, 1);
17511  switch (lua_gettop(L)) {
17512  case 1: {
17513  decltype(auto) r = (mem.*variable);
17514  stack::push_reference(L, std::forward<decltype(r)>(r));
17515  return 1;
17516  }
17517  case 2:
17518  return call_set_variable<R, V, variable>(meta::neg<std::is_const<R>>(), L, mem);
17519  default:
17520  return luaL_error(L, "incorrect number of arguments to member variable function call");
17521  }
17522  }
17523 
17524  template <typename F, F fx>
17525  inline int call_wrapper_function(std::false_type, lua_State* L) {
17526  return call_wrapper_variable<F, fx>(std::is_member_object_pointer<F>(), L);
17527  }
17528 
17529  template <typename F, F fx>
17530  inline int call_wrapper_function(std::true_type, lua_State* L) {
17531  return call_detail::call_wrapped<void, false, false>(L, fx);
17532  }
17533 
17534  template <typename F, F fx>
17536  return call_wrapper_function<F, fx>(std::is_member_function_pointer<meta::unqualified_t<F>>(), L);
17537  }
17538 
17539  template <typename... Fxs>
17541  template <typename Fx, std::size_t I, typename R, typename... Args>
17543  typedef meta::at_in_pack_t<I, Fxs...> target;
17544  return target::call(L);
17545  }
17546  };
17547 
17548  template <typename F, F fx>
17549  inline int c_call_raw(std::true_type, lua_State* L) {
17550  return fx(L);
17551  }
17552 
17553  template <typename F, F fx>
17554  inline int c_call_raw(std::false_type, lua_State* L) {
17555 #ifdef __clang__
17556  return detail::trampoline(L, function_detail::call_wrapper_entry<F, fx>);
17557 #else
17558  return detail::typed_static_trampoline<decltype(&function_detail::call_wrapper_entry<F, fx>), (&function_detail::call_wrapper_entry<F, fx>)>(L);
17559 #endif // fuck you clang :c
17560  }
17561 
17562  } // namespace function_detail
17563 
17564  template <typename F, F fx>
17565  inline int c_call(lua_State* L) {
17566  typedef meta::unqualified_t<F> Fu;
17567  typedef std::integral_constant<bool,
17569 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
17571 #endif
17572  >
17573  is_raw;
17574  return function_detail::c_call_raw<F, fx>(is_raw(), L);
17575  }
17576 
17577  template <typename F, F f>
17578  struct wrap {
17579  typedef F type;
17580 
17581  static int call(lua_State* L) {
17582  return c_call<type, f>(L);
17583  }
17584  };
17585 
17586  template <typename... Fxs>
17587  inline int c_call(lua_State* L) {
17588  if constexpr (sizeof...(Fxs) < 2) {
17589  using target = meta::at_in_pack_t<0, Fxs...>;
17590  return target::call(L);
17591  }
17592  else {
17594  }
17595  }
17596 
17597 } // namespace sol
17598 
17599 // end of sol/function_types_templated.hpp
17600 
17601 // beginning of sol/function_types_stateless.hpp
17602 
17603 namespace sol { namespace function_detail {
17604  template <typename Function, bool is_yielding>
17606  using function_type = std::remove_pointer_t<std::decay_t<Function>>;
17608 
17609  static int real_call(lua_State* L)
17610 #if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
17611  // MSVC is broken, what a surprise...
17612 #else
17613  noexcept(traits_type::is_noexcept)
17614 #endif
17615  {
17616  auto udata = stack::stack_detail::get_as_upvalues<function_type*>(L);
17617  function_type* fx = udata.first;
17618  return call_detail::call_wrapped<void, true, false>(L, fx);
17619  }
17620 
17621  static int call(lua_State* L) {
17622  int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
17623  if (is_yielding) {
17624  return lua_yield(L, nr);
17625  }
17626  else {
17627  return nr;
17628  }
17629  }
17630 
17632  return call(L);
17633  }
17634  };
17635 
17636  template <typename T, typename Function, bool is_yielding>
17638  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
17640 
17641  static int real_call(lua_State* L)
17642 #if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
17643  // MSVC is broken, what a surprise...
17644 #else
17645  noexcept(traits_type::is_noexcept)
17646 #endif
17647  {
17648  // Layout:
17649  // idx 1...n: verbatim data of member function pointer
17650  // idx n + 1: is the object's void pointer
17651  // We don't need to store the size, because the other side is templated
17652  // with the same member function pointer type
17653  function_type& memfx = stack::get<user<function_type>>(L, upvalue_index(2));
17654  auto& item = *static_cast<T*>(stack::get<void*>(L, upvalue_index(3)));
17655  return call_detail::call_wrapped<T, true, false, -1>(L, memfx, item);
17656  }
17657 
17658  static int call(lua_State* L)
17659 #if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
17660  // MSVC is broken, what a surprise...
17661 #else
17662  noexcept(traits_type::is_noexcept)
17663 #endif
17664  {
17665  int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
17666  if (is_yielding) {
17667  return lua_yield(L, nr);
17668  }
17669  else {
17670  return nr;
17671  }
17672  }
17673 
17675  return call(L);
17676  }
17677  };
17678 
17679  template <typename T, typename Function, bool is_yielding>
17681  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
17683 
17684  static int real_call(lua_State* L)
17685 #if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
17686  // MSVC is broken, what a surprise...
17687 #else
17688  noexcept(traits_type::is_noexcept)
17689 #endif
17690  {
17691  // Layout:
17692  // idx 1...n: verbatim data of member variable pointer
17693  // idx n + 1: is the object's void pointer
17694  // We don't need to store the size, because the other side is templated
17695  // with the same member function pointer type
17696  auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
17697  auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
17698  auto& mem = *objdata.first;
17699  function_type& var = memberdata.first;
17700  switch (lua_gettop(L)) {
17701  case 0:
17702  return call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
17703  case 1:
17704  return call_detail::call_wrapped<T, false, false, -1>(L, var, mem);
17705  default:
17706  return luaL_error(L, "sol: incorrect number of arguments to member variable function");
17707  }
17708  }
17709 
17710  static int call(lua_State* L)
17711 #if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
17712  // MSVC is broken, what a surprise...
17713 #else
17714  noexcept(traits_type::is_noexcept)
17715 #endif
17716  {
17717  int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
17718  if (is_yielding) {
17719  return lua_yield(L, nr);
17720  }
17721  else {
17722  return nr;
17723  }
17724  }
17725 
17727  return call(L);
17728  }
17729  };
17730 
17731  template <typename T, typename Function, bool is_yielding>
17732  struct upvalue_member_variable<T, readonly_wrapper<Function>, is_yielding> {
17733  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
17735 
17736  static int real_call(lua_State* L)
17737 #if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
17738  // MSVC is broken, what a surprise...
17739 #else
17740  noexcept(traits_type::is_noexcept)
17741 #endif
17742  {
17743  // Layout:
17744  // idx 1...n: verbatim data of member variable pointer
17745  // idx n + 1: is the object's void pointer
17746  // We don't need to store the size, because the other side is templated
17747  // with the same member function pointer type
17748  auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
17749  auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
17750  auto& mem = *objdata.first;
17751  function_type& var = memberdata.first;
17752  switch (lua_gettop(L)) {
17753  case 0:
17754  return call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
17755  default:
17756  return luaL_error(L, "sol: incorrect number of arguments to member variable function");
17757  }
17758  }
17759 
17760  static int call(lua_State* L)
17761 #if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
17762  // MSVC is broken, what a surprise...
17763 #else
17764  noexcept(traits_type::is_noexcept)
17765 #endif
17766  {
17767  int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
17768  if (is_yielding) {
17769  return lua_yield(L, nr);
17770  }
17771  else {
17772  return nr;
17773  }
17774  }
17775 
17777  return call(L);
17778  }
17779  };
17780 
17781  template <typename T, typename Function, bool is_yielding>
17783  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
17785 
17786  static int real_call(lua_State* L)
17787 #if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
17788  // MSVC is broken, what a surprise...
17789 #else
17790  noexcept(traits_type::is_noexcept)
17791 #endif
17792  {
17793  // Layout:
17794  // idx 1...n: verbatim data of member variable pointer
17795  function_type& memfx = stack::get<user<function_type>>(L, upvalue_index(2));
17796  return call_detail::call_wrapped<T, false, false>(L, memfx);
17797  }
17798 
17799  static int call(lua_State* L)
17800 #if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
17801  // MSVC is broken, what a surprise...
17802 #else
17803  noexcept(traits_type::is_noexcept)
17804 #endif
17805  {
17806  int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
17807  if (is_yielding) {
17808  return lua_yield(L, nr);
17809  }
17810  else {
17811  return nr;
17812  }
17813  }
17814 
17816  return call(L);
17817  }
17818  };
17819 
17820  template <typename T, typename Function, bool is_yielding>
17822  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
17823 
17824  static int real_call(lua_State* L) noexcept(false) {
17825  // Layout:
17826  // idx 1...n: verbatim data of member variable pointer
17827  auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
17828  function_type& var = memberdata.first;
17829  switch (lua_gettop(L)) {
17830  case 1:
17831  return call_detail::call_wrapped<T, true, false>(L, var);
17832  case 2:
17833  return call_detail::call_wrapped<T, false, false>(L, var);
17834  default:
17835  return luaL_error(L, "sol: incorrect number of arguments to member variable function");
17836  }
17837  }
17838 
17839  static int call(lua_State* L) {
17840  int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
17841  if (is_yielding) {
17842  return lua_yield(L, nr);
17843  }
17844  else {
17845  return nr;
17846  }
17847  }
17848 
17850  return call(L);
17851  }
17852  };
17853 
17854  template <typename T, typename Function, bool is_yielding>
17855  struct upvalue_this_member_variable<T, readonly_wrapper<Function>, is_yielding> {
17856  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
17858 
17859  static int real_call(lua_State* L) noexcept(false) {
17860  // Layout:
17861  // idx 1...n: verbatim data of member variable pointer
17862  auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
17863  function_type& var = memberdata.first;
17864  switch (lua_gettop(L)) {
17865  case 1:
17866  return call_detail::call_wrapped<T, true, false>(L, var);
17867  default:
17868  return luaL_error(L, "sol: incorrect number of arguments to member variable function");
17869  }
17870  }
17871 
17872  static int call(lua_State* L) {
17873  int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
17874  if (is_yielding) {
17875  return lua_yield(L, nr);
17876  }
17877  else {
17878  return nr;
17879  }
17880  }
17881 
17883  return call(L);
17884  }
17885  };
17886 }} // namespace sol::function_detail
17887 
17888 // end of sol/function_types_stateless.hpp
17889 
17890 // beginning of sol/function_types_stateful.hpp
17891 
17892 namespace sol {
17893 namespace function_detail {
17894  template <typename Func, bool is_yielding, bool no_trampoline>
17896  typedef std::decay_t<meta::unwrap_unqualified_t<Func>> function_type;
17897  function_type fx;
17898 
17899  template <typename... Args>
17900  functor_function(function_type f, Args&&... args)
17901  : fx(std::move(f), std::forward<Args>(args)...) {
17902  }
17903 
17904  int call(lua_State* L) {
17905  int nr = call_detail::call_wrapped<void, true, false>(L, fx);
17906  if (is_yielding) {
17907  return lua_yield(L, nr);
17908  }
17909  else {
17910  return nr;
17911  }
17912  }
17913 
17915  if (!no_trampoline) {
17916  auto f = [&](lua_State*) -> int { return this->call(L); };
17917  return detail::trampoline(L, f);
17918  }
17919  else {
17920  return call(L);
17921  }
17922  }
17923  };
17924 
17925  template <typename T, typename Function, bool is_yielding>
17927  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
17930  function_type invocation;
17932 
17933  template <typename... Args>
17934  member_function(function_type f, Args&&... args)
17935  : invocation(std::move(f)), member(std::forward<Args>(args)...) {
17936  }
17937 
17938  int call(lua_State* L) {
17939  int nr = call_detail::call_wrapped<T, true, false, -1>(L, invocation, detail::unwrap(detail::deref(member)));
17940  if (is_yielding) {
17941  return lua_yield(L, nr);
17942  }
17943  else {
17944  return nr;
17945  }
17946  }
17947 
17949  auto f = [&](lua_State*) -> int { return this->call(L); };
17950  return detail::trampoline(L, f);
17951  }
17952  };
17953 
17954  template <typename T, typename Function, bool is_yielding>
17956  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
17959  function_type var;
17961  typedef std::add_lvalue_reference_t<meta::unwrapped_t<std::remove_reference_t<decltype(detail::deref(member))>>> M;
17962 
17963  template <typename... Args>
17964  member_variable(function_type v, Args&&... args)
17965  : var(std::move(v)), member(std::forward<Args>(args)...) {
17966  }
17967 
17968  int call(lua_State* L) {
17969  int nr;
17970  {
17971  M mem = detail::unwrap(detail::deref(member));
17972  switch (lua_gettop(L)) {
17973  case 0:
17974  nr = call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
17975  break;
17976  case 1:
17977  nr = call_detail::call_wrapped<T, false, false, -1>(L, var, mem);
17978  break;
17979  default:
17980  nr = luaL_error(L, "sol: incorrect number of arguments to member variable function");
17981  break;
17982  }
17983  }
17984  if (is_yielding) {
17985  return lua_yield(L, nr);
17986  }
17987  else {
17988  return nr;
17989  }
17990  }
17991 
17993  auto f = [&](lua_State*) -> int { return this->call(L); };
17994  return detail::trampoline(L, f);
17995  }
17996  };
17997 }
17998 } // namespace sol::function_detail
17999 
18000 // end of sol/function_types_stateful.hpp
18001 
18002 // beginning of sol/function_types_overloaded.hpp
18003 
18004 namespace sol {
18005 namespace function_detail {
18006  template <int start_skew, typename... Functions>
18008  typedef std::tuple<Functions...> overload_list;
18009  typedef std::make_index_sequence<sizeof...(Functions)> indices;
18011 
18013  : overloads(std::move(set)) {
18014  }
18015 
18016  overloaded_function(Functions... fxs)
18017  : overloads(fxs...) {
18018  }
18019 
18020  template <typename Fx, std::size_t I, typename... R, typename... Args>
18022  auto& func = std::get<I>(ol);
18023  int nr = call_detail::call_wrapped<void, true, false, start_skew>(L, func);
18024  return nr;
18025  }
18026 
18028  auto mfx = [](auto&&... args) { return call(std::forward<decltype(args)>(args)...); };
18029  return call_detail::overload_match<Functions...>(mfx, L, 1 + start_skew, overloads);
18030  }
18031  };
18032 }
18033 } // namespace sol::function_detail
18034 
18035 // end of sol/function_types_overloaded.hpp
18036 
18037 // beginning of sol/resolve.hpp
18038 
18039 namespace sol {
18040 
18041 #ifndef __clang__
18042  // constexpr is fine for not-clang
18043 
18044  namespace detail {
18045  template <typename R, typename... Args, typename F, typename = std::invoke_result_t<meta::unqualified_t<F>, Args...>>
18046  inline constexpr auto resolve_i(types<R(Args...)>, F &&) -> R (meta::unqualified_t<F>::*)(Args...) {
18047  using Sig = R(Args...);
18048  typedef meta::unqualified_t<F> Fu;
18049  return static_cast<Sig Fu::*>(&Fu::operator());
18050  }
18051 
18052  template <typename F, typename U = meta::unqualified_t<F>>
18053  inline constexpr auto resolve_f(std::true_type, F&& f)
18054  -> decltype(resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
18055  return resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
18056  }
18057 
18058  template <typename F>
18059  inline constexpr void resolve_f(std::false_type, F&&) {
18060  static_assert(
18061  meta::has_deducible_signature<F>::value, "Cannot use no-template-parameter call with an overloaded functor: specify the signature");
18062  }
18063 
18064  template <typename F, typename U = meta::unqualified_t<F>>
18065  inline constexpr auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::has_deducible_signature<U>(), std::forward<F>(f))) {
18066  return resolve_f(meta::has_deducible_signature<U> {}, std::forward<F>(f));
18067  }
18068 
18069  template <typename... Args, typename F, typename R = std::invoke_result_t<F&, Args...>>
18070  inline constexpr auto resolve_i(types<Args...>, F&& f) -> decltype(resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
18071  return resolve_i(types<R(Args...)>(), std::forward<F>(f));
18072  }
18073 
18074  template <typename Sig, typename C>
18075  inline constexpr Sig C::*resolve_v(std::false_type, Sig C::*mem_func_ptr) {
18076  return mem_func_ptr;
18077  }
18078 
18079  template <typename Sig, typename C>
18080  inline constexpr Sig C::*resolve_v(std::true_type, Sig C::*mem_variable_ptr) {
18081  return mem_variable_ptr;
18082  }
18083  } // namespace detail
18084 
18085  template <typename... Args, typename R>
18086  inline constexpr auto resolve(R fun_ptr(Args...)) -> R (*)(Args...) {
18087  return fun_ptr;
18088  }
18089 
18090  template <typename Sig>
18091  inline constexpr Sig* resolve(Sig* fun_ptr) {
18092  return fun_ptr;
18093  }
18094 
18095  template <typename... Args, typename R, typename C>
18096  inline constexpr auto resolve(R (C::*mem_ptr)(Args...)) -> R (C::*)(Args...) {
18097  return mem_ptr;
18098  }
18099 
18100  template <typename Sig, typename C>
18101  inline constexpr Sig C::*resolve(Sig C::*mem_ptr) {
18102  return detail::resolve_v(std::is_member_object_pointer<Sig C::*>(), mem_ptr);
18103  }
18104 
18105  template <typename... Sig, typename F, meta::disable<std::is_function<meta::unqualified_t<F>>> = meta::enabler>
18106  inline constexpr auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
18107  return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
18108  }
18109 #else
18110 
18111  // Clang has distinct problems with constexpr arguments,
18112  // so don't use the constexpr versions inside of clang.
18113 
18114  namespace detail {
18115  template <typename R, typename... Args, typename F, typename = std::invoke_result_t<meta::unqualified_t<F>, Args...>>
18116  inline auto resolve_i(types<R(Args...)>, F &&) -> R (meta::unqualified_t<F>::*)(Args...) {
18117  using Sig = R(Args...);
18118  typedef meta::unqualified_t<F> Fu;
18119  return static_cast<Sig Fu::*>(&Fu::operator());
18120  }
18121 
18122  template <typename F, typename U = meta::unqualified_t<F>>
18123  inline auto resolve_f(std::true_type, F&& f)
18124  -> decltype(resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
18125  return resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
18126  }
18127 
18128  template <typename F>
18129  inline void resolve_f(std::false_type, F&&) {
18130  static_assert(
18131  meta::has_deducible_signature<F>::value, "Cannot use no-template-parameter call with an overloaded functor: specify the signature");
18132  }
18133 
18134  template <typename F, typename U = meta::unqualified_t<F>>
18135  inline auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::has_deducible_signature<U>(), std::forward<F>(f))) {
18136  return resolve_f(meta::has_deducible_signature<U> {}, std::forward<F>(f));
18137  }
18138 
18139  template <typename... Args, typename F, typename R = std::invoke_result_t<F&, Args...>>
18140  inline auto resolve_i(types<Args...>, F&& f) -> decltype(resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
18141  return resolve_i(types<R(Args...)>(), std::forward<F>(f));
18142  }
18143 
18144  template <typename Sig, typename C>
18145  inline Sig C::*resolve_v(std::false_type, Sig C::*mem_func_ptr) {
18146  return mem_func_ptr;
18147  }
18148 
18149  template <typename Sig, typename C>
18150  inline Sig C::*resolve_v(std::true_type, Sig C::*mem_variable_ptr) {
18151  return mem_variable_ptr;
18152  }
18153  } // namespace detail
18154 
18155  template <typename... Args, typename R>
18156  inline auto resolve(R fun_ptr(Args...)) -> R (*)(Args...) {
18157  return fun_ptr;
18158  }
18159 
18160  template <typename Sig>
18161  inline Sig* resolve(Sig* fun_ptr) {
18162  return fun_ptr;
18163  }
18164 
18165  template <typename... Args, typename R, typename C>
18166  inline auto resolve(R (C::*mem_ptr)(Args...)) -> R (C::*)(Args...) {
18167  return mem_ptr;
18168  }
18169 
18170  template <typename Sig, typename C>
18171  inline Sig C::*resolve(Sig C::*mem_ptr) {
18172  return detail::resolve_v(std::is_member_object_pointer<Sig C::*>(), mem_ptr);
18173  }
18174 
18175  template <typename... Sig, typename F>
18176  inline auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
18177  return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
18178  }
18179 
18180 #endif
18181 
18182 } // namespace sol
18183 
18184 // end of sol/resolve.hpp
18185 
18186 namespace sol {
18187  namespace function_detail {
18188  template <typename T>
18190  using type = T;
18191  };
18192 
18193  struct call_indicator { };
18194 
18195  template <bool yielding>
18198  int nr = cf(L);
18199  if constexpr (yielding) {
18200  return lua_yield(L, nr);
18201  }
18202  else {
18203  return nr;
18204  }
18205  }
18206 
18207  template <bool yielding>
18210  int nr = cf(L);
18211  if constexpr (yielding) {
18212  return lua_yield(L, nr);
18213  }
18214  else {
18215  return nr;
18216  }
18217  }
18218 
18220 
18221  template <bool is_yielding, typename Fx, typename... Args>
18222  void select(lua_State* L, Fx&& fx, Args&&... args);
18223 
18224  template <bool is_yielding, bool no_trampoline, typename Fx, typename... Args>
18225  void select_set_fx(lua_State* L, Args&&... args) {
18226  lua_CFunction freefunc = no_trampoline ? detail::static_trampoline<function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>>
18227  : function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>;
18228 
18229  int upvalues = 0;
18230  upvalues += stack::push(L, nullptr);
18231  upvalues += stack::push<user<Fx>>(L, std::forward<Args>(args)...);
18232  stack::push(L, c_closure(freefunc, upvalues));
18233  }
18234 
18235  template <bool is_yielding, typename R, typename... A, typename Fx, typename... Args>
18236  void select_convertible(types<R(A...)>, lua_State* L, Fx&& fx, Args&&... args) {
18237  using dFx = std::decay_t<meta::unwrap_unqualified_t<Fx>>;
18238  using fx_ptr_t = R (*)(A...);
18239  constexpr bool is_convertible = std::is_convertible_v<dFx, fx_ptr_t>;
18240  if constexpr (is_convertible) {
18241  fx_ptr_t fxptr = detail::unwrap(std::forward<Fx>(fx));
18242  select<is_yielding>(L, std::move(fxptr), std::forward<Args>(args)...);
18243  }
18244  else {
18246  select_set_fx<is_yielding, false, F>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
18247  }
18248  }
18249 
18250  template <bool is_yielding, typename Fx, typename... Args>
18251  void select_convertible(types<>, lua_State* L, Fx&& fx, Args&&... args) {
18253  select_convertible<is_yielding>(types<Sig>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
18254  }
18255 
18256  template <bool is_yielding, typename Fx, typename... Args>
18257  void select_member_variable(lua_State* L, Fx&& fx, Args&&... args) {
18258  using uFx = meta::unqualified_t<Fx>;
18259  if constexpr (sizeof...(Args) < 1) {
18260  using C = typename meta::bind_traits<uFx>::object_type;
18262 
18263  int upvalues = 0;
18264  upvalues += stack::push(L, nullptr);
18265  upvalues += stack::stack_detail::push_as_upvalues(L, fx);
18266  stack::push(L, c_closure(freefunc, upvalues));
18267  }
18268  else if constexpr (sizeof...(Args) < 2) {
18269  using Tu = typename meta::meta_detail::unqualified_non_alias<Args...>::type;
18270  constexpr bool is_reference = meta::is_specialization_of_v<Tu, std::reference_wrapper> || std::is_pointer_v<Tu>;
18271  if constexpr (meta::is_specialization_of_v<Tu, function_detail::class_indicator>) {
18273 
18274  int upvalues = 0;
18275  upvalues += stack::push(L, nullptr);
18276  upvalues += stack::stack_detail::push_as_upvalues(L, fx);
18277  stack::push(L, c_closure(freefunc, upvalues));
18278  }
18279  else if constexpr (is_reference) {
18280  typedef std::decay_t<Fx> dFx;
18281  dFx memfxptr(std::forward<Fx>(fx));
18282  auto userptr = detail::ptr(std::forward<Args>(args)...);
18283  lua_CFunction freefunc
18285 
18286  int upvalues = 0;
18287  upvalues += stack::push(L, nullptr);
18288  upvalues += stack::stack_detail::push_as_upvalues(L, memfxptr);
18289  upvalues += stack::push(L, static_cast<void const*>(userptr));
18290  stack::push(L, c_closure(freefunc, upvalues));
18291  }
18292  else {
18293  using clean_fx = std::remove_pointer_t<std::decay_t<Fx>>;
18295  select_set_fx<false, false, F>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
18296  }
18297  }
18298  else {
18299  using C = typename meta::bind_traits<uFx>::object_type;
18300  using clean_fx = std::remove_pointer_t<std::decay_t<Fx>>;
18302  select_set_fx<false, false, F>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
18303  }
18304  }
18305 
18306  template <bool is_yielding, typename Fx, typename T, typename... Args>
18307  void select_member_function_with(lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
18308  using dFx = std::decay_t<Fx>;
18309  using Tu = meta::unqualified_t<T>;
18310  if constexpr (meta::is_specialization_of_v<Tu, function_detail::class_indicator>) {
18311  (void)obj;
18312  using C = typename Tu::type;
18314 
18315  int upvalues = 0;
18316  upvalues += stack::push(L, nullptr);
18317  upvalues += stack::push<user<dFx>>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
18318  stack::push(L, c_closure(freefunc, upvalues));
18319  }
18320  else {
18321  constexpr bool is_reference = meta::is_specialization_of_v<Tu, std::reference_wrapper> || std::is_pointer_v<Tu>;
18322  if constexpr (is_reference) {
18323  auto userptr = detail::ptr(std::forward<T>(obj));
18325 
18326  int upvalues = 0;
18327  upvalues += stack::push(L, nullptr);
18328  upvalues += stack::push<user<dFx>>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
18329  upvalues += stack::push(L, lightuserdata_value(static_cast<void*>(userptr)));
18330  stack::push(L, c_closure(freefunc, upvalues));
18331  }
18332  else {
18334  select_set_fx<false, false, F>(L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
18335  }
18336  }
18337  }
18338 
18339  template <bool is_yielding, typename Fx, typename... Args>
18340  void select_member_function(lua_State* L, Fx&& fx, Args&&... args) {
18341  using dFx = std::decay_t<Fx>;
18342  if constexpr (sizeof...(Args) < 1) {
18343  using C = typename meta::bind_traits<meta::unqualified_t<Fx>>::object_type;
18345 
18346  int upvalues = 0;
18347  upvalues += stack::push(L, nullptr);
18348  upvalues += stack::push<user<dFx>>(L, std::forward<Fx>(fx));
18349  stack::push(L, c_closure(freefunc, upvalues));
18350  }
18351  else {
18352  select_member_function_with<is_yielding>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
18353  }
18354  }
18355 
18356  template <bool is_yielding, typename Fx, typename... Args>
18357  void select(lua_State* L, Fx&& fx, Args&&... args) {
18358  using uFx = meta::unqualified_t<Fx>;
18359  if constexpr (is_lua_reference_v<uFx>) {
18360  // TODO: hoist into lambda in this case for yielding???
18361  stack::push(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
18362  }
18363  else if constexpr (is_lua_c_function_v<uFx>) {
18364  int upvalues = 0;
18365  upvalues += stack::push(L, nullptr);
18366  upvalues += stack::push(L, std::forward<Fx>(fx));
18367 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
18368  if constexpr (std::is_nothrow_invocable_r_v<int, uFx, lua_State*>) {
18369  detail::lua_CFunction_noexcept cf = &lua_c_noexcept_wrapper<is_yielding>;
18370  lua_pushcclosure(L, reinterpret_cast<lua_CFunction>(cf), 2);
18371  }
18372  else {
18373  lua_CFunction cf = &lua_c_wrapper<is_yielding>;
18374  lua_pushcclosure(L, cf, 2);
18375  }
18376 #else
18377  lua_CFunction cf = &function_detail::lua_c_wrapper<is_yielding>;
18378  lua_pushcclosure(L, cf, 2);
18379 #endif
18380  }
18381  else if constexpr (std::is_function_v<std::remove_pointer_t<uFx>>) {
18382  std::decay_t<Fx> target(std::forward<Fx>(fx), std::forward<Args>(args)...);
18384 
18385  int upvalues = 0;
18386  upvalues += stack::push(L, nullptr);
18387  upvalues += stack::stack_detail::push_as_upvalues(L, target);
18388  stack::push(L, c_closure(freefunc, upvalues));
18389  }
18390  else if constexpr (std::is_member_function_pointer_v<uFx>) {
18391  select_member_function<is_yielding>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
18392  }
18393  else if constexpr (meta::is_member_object_v<uFx>) {
18394  select_member_variable<is_yielding>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
18395  }
18396  else {
18397  select_convertible<is_yielding>(types<>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
18398  }
18399  }
18400  } // namespace function_detail
18401 
18402  namespace stack {
18403  template <typename... Sigs>
18405  template <bool is_yielding, typename Arg0, typename... Args>
18406  static int push(lua_State* L, Arg0&& arg0, Args&&... args) {
18408  if constexpr (is_yielding) {
18409  return stack::push<meta::unqualified_t<Arg0>>(L, detail::yield_tag, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
18410  }
18411  else {
18412  return stack::push(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
18413  }
18414  }
18415  else {
18416  function_detail::select<is_yielding>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
18417  return 1;
18418  }
18419  }
18420 
18421  template <typename Arg0, typename... Args>
18422  static int push(lua_State* L, Arg0&& arg0, Args&&... args) {
18423  if constexpr (std::is_same_v<meta::unqualified_t<Arg0>, detail::yield_tag_t>) {
18424  push<true>(L, std::forward<Args>(args)...);
18425  }
18427  push<true>(L, std::forward<Arg0>(arg0).func, std::forward<Args>(args)...);
18428  }
18429  else {
18430  push<false>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
18431  }
18432  return 1;
18433  }
18434  };
18435 
18436  template <typename T>
18438  template <typename... Args>
18439  static int push(lua_State* L, const yielding_t<T>& f, Args&&... args) {
18441  return stack::push<T>(L, detail::yield_tag, f.func, std::forward<Args>(args)...);
18442  }
18443  else {
18444  function_detail::select<true>(L, f.func, std::forward<Args>(args)...);
18445  return 1;
18446  }
18447  }
18448 
18449  template <typename... Args>
18450  static int push(lua_State* L, yielding_t<T>&& f, Args&&... args) {
18452  return stack::push<T>(L, detail::yield_tag, std::move(f.func), std::forward<Args>(args)...);
18453  }
18454  else {
18455  function_detail::select<true>(L, std::move(f.func), std::forward<Args>(args)...);
18456  return 1;
18457  }
18458  }
18459  };
18460 
18461  template <typename T, typename... Args>
18463  template <std::size_t... I, typename FP>
18464  static int push_func(std::index_sequence<I...>, lua_State* L, FP&& fp) {
18465  return stack::push<T>(L, std::get<I>(std::forward<FP>(fp).arguments)...);
18466  }
18467 
18468  static int push(lua_State* L, const function_arguments<T, Args...>& fp) {
18469  return push_func(std::make_index_sequence<sizeof...(Args)>(), L, fp);
18470  }
18471 
18473  return push_func(std::make_index_sequence<sizeof...(Args)>(), L, std::move(fp));
18474  }
18475  };
18476 
18477  template <typename Signature>
18478  struct unqualified_pusher<std::function<Signature>> {
18479  static int push(lua_State* L, detail::yield_tag_t, const std::function<Signature>& fx) {
18480  if (fx) {
18481  function_detail::select<true>(L, fx);
18482  return 1;
18483  }
18484  return stack::push(L, lua_nil);
18485  }
18486 
18487  static int push(lua_State* L, detail::yield_tag_t, std::function<Signature>&& fx) {
18488  if (fx) {
18489  function_detail::select<true>(L, std::move(fx));
18490  return 1;
18491  }
18492  return stack::push(L, lua_nil);
18493  }
18494 
18495  static int push(lua_State* L, const std::function<Signature>& fx) {
18496  if (fx) {
18497  function_detail::select<false>(L, fx);
18498  return 1;
18499  }
18500  return stack::push(L, lua_nil);
18501  }
18502 
18503  static int push(lua_State* L, std::function<Signature>&& fx) {
18504  if (fx) {
18505  function_detail::select<false>(L, std::move(fx));
18506  return 1;
18507  }
18508  return stack::push(L, lua_nil);
18509  }
18510  };
18511 
18512  template <typename Signature>
18513  struct unqualified_pusher<Signature, std::enable_if_t<std::is_member_pointer<Signature>::value>> {
18514  template <typename... Args>
18515  static int push(lua_State* L, Args&&... args) {
18516  function_detail::select<false>(L, std::forward<Args>(args)...);
18517  return 1;
18518  }
18519  };
18520 
18521  template <typename Signature>
18522  struct unqualified_pusher<Signature,
18523  std::enable_if_t<meta::all<std::is_function<std::remove_pointer_t<Signature>>, meta::neg<std::is_same<Signature, lua_CFunction>>,
18524  meta::neg<std::is_same<Signature, std::remove_pointer_t<lua_CFunction>>>
18525 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
18526  ,
18527  meta::neg<std::is_same<Signature, detail::lua_CFunction_noexcept>>,
18528  meta::neg<std::is_same<Signature, std::remove_pointer_t<detail::lua_CFunction_noexcept>>>
18529 #endif // noexcept function types
18530  >::value>> {
18531  template <typename F>
18532  static int push(lua_State* L, F&& f) {
18533  function_detail::select<false>(L, std::forward<F>(f));
18534  return 1;
18535  }
18536  };
18537 
18538  template <typename... Functions>
18539  struct unqualified_pusher<overload_set<Functions...>> {
18541  using F = function_detail::overloaded_function<0, Functions...>;
18542  function_detail::select_set_fx<false, false, F>(L, std::move(set.functions));
18543  return 1;
18544  }
18545 
18546  static int push(lua_State* L, const overload_set<Functions...>& set) {
18547  using F = function_detail::overloaded_function<0, Functions...>;
18548  function_detail::select_set_fx<false, false, F>(L, set.functions);
18549  return 1;
18550  }
18551  };
18552 
18553  template <typename T>
18555  static int push(lua_State* L, protect_t<T>&& pw) {
18556  lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>, 2>;
18557  int upvalues = 0;
18558  upvalues += stack::push(L, nullptr);
18559  upvalues += stack::push<user<protect_t<T>>>(L, std::move(pw.value));
18560  return stack::push(L, c_closure(cf, upvalues));
18561  }
18562 
18563  static int push(lua_State* L, const protect_t<T>& pw) {
18564  lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>, 2>;
18565  int upvalues = 0;
18566  upvalues += stack::push(L, nullptr);
18567  upvalues += stack::push<user<protect_t<T>>>(L, pw.value);
18568  return stack::push(L, c_closure(cf, upvalues));
18569  }
18570  };
18571 
18572  template <typename F, typename G>
18574  static int push(lua_State* L, property_wrapper<F, G>&& pw) {
18575  if constexpr (std::is_void_v<F>) {
18576  return stack::push(L, std::move(pw.write()));
18577  }
18578  else if constexpr (std::is_void_v<G>) {
18579  return stack::push(L, std::move(pw.read()));
18580  }
18581  else {
18582  return stack::push(L, overload(std::move(pw.read()), std::move(pw.write())));
18583  }
18584  }
18585 
18586  static int push(lua_State* L, const property_wrapper<F, G>& pw) {
18587  if constexpr (std::is_void_v<F>) {
18588  return stack::push(L, pw.write);
18589  }
18590  else if constexpr (std::is_void_v<G>) {
18591  return stack::push(L, pw.read);
18592  }
18593  else {
18594  return stack::push(L, overload(pw.read, pw.write));
18595  }
18596  }
18597  };
18598 
18599  template <typename T>
18601  static int push(lua_State* L, var_wrapper<T>&& vw) {
18602  return stack::push(L, std::move(vw.value()));
18603  }
18604  static int push(lua_State* L, const var_wrapper<T>& vw) {
18605  return stack::push(L, vw.value());
18606  }
18607  };
18608 
18609  template <typename... Functions>
18610  struct unqualified_pusher<factory_wrapper<Functions...>> {
18611  static int push(lua_State* L, const factory_wrapper<Functions...>& fw) {
18612  using F = function_detail::overloaded_function<0, Functions...>;
18613  function_detail::select_set_fx<false, false, F>(L, fw.functions);
18614  return 1;
18615  }
18616 
18618  using F = function_detail::overloaded_function<0, Functions...>;
18619  function_detail::select_set_fx<false, false, F>(L, std::move(fw.functions));
18620  return 1;
18621  }
18622 
18624  using F = function_detail::overloaded_function<1, Functions...>;
18625  function_detail::select_set_fx<false, false, F>(L, fw.functions);
18626  return 1;
18627  }
18628 
18630  using F = function_detail::overloaded_function<1, Functions...>;
18631  function_detail::select_set_fx<false, false, F>(L, std::move(fw.functions));
18632  return 1;
18633  }
18634  };
18635 
18636  template <>
18638  static int push(lua_State* L, no_construction) {
18640  return stack::push(L, cf);
18641  }
18642 
18644  return push(L, c);
18645  }
18646  };
18647 
18648  template <typename T>
18649  struct unqualified_pusher<detail::tagged<T, no_construction>> {
18652  return stack::push(L, cf);
18653  }
18654 
18656  return push(L, c);
18657  }
18658  };
18659 
18660  template <typename T, typename... Lists>
18661  struct unqualified_pusher<detail::tagged<T, constructor_list<Lists...>>> {
18664  return stack::push(L, cf);
18665  }
18666 
18669  return stack::push(L, cf);
18670  }
18671  };
18672 
18673  template <typename L0, typename... Lists>
18674  struct unqualified_pusher<constructor_list<L0, Lists...>> {
18675  typedef constructor_list<L0, Lists...> cl_t;
18676  static int push(lua_State* L, cl_t cl) {
18677  typedef typename meta::bind_traits<L0>::return_type T;
18678  return stack::push<detail::tagged<T, cl_t>>(L, cl);
18679  }
18680  };
18681 
18682  template <typename T, typename... Fxs>
18683  struct unqualified_pusher<detail::tagged<T, constructor_wrapper<Fxs...>>> {
18685  return push(L, std::move(c.value()));
18686  }
18687 
18688  static int push(lua_State* L, const detail::tagged<T, const constructor_wrapper<Fxs...>>& c) {
18689  return push(L, c.value());
18690  }
18691 
18693  lua_CFunction cf = call_detail::call_user<T, false, false, constructor_wrapper<Fxs...>, 2>;
18694  int upvalues = 0;
18695  upvalues += stack::push(L, nullptr);
18696  upvalues += stack::push<user<constructor_wrapper<Fxs...>>>(L, std::move(c));
18697  return stack::push(L, c_closure(cf, upvalues));
18698  }
18699 
18700  static int push(lua_State* L, const constructor_wrapper<Fxs...>& c) {
18701  lua_CFunction cf = call_detail::call_user<T, false, false, constructor_wrapper<Fxs...>, 2>;
18702  int upvalues = 0;
18703  upvalues += stack::push(L, nullptr);
18704  upvalues += stack::push<user<constructor_wrapper<Fxs...>>>(L, c);
18705  return stack::push(L, c_closure(cf, upvalues));
18706  }
18707  };
18708 
18709  template <typename F, typename... Fxs>
18712  typedef typename meta::bind_traits<F>::template arg_at<0> arg0;
18714  return stack::push<detail::tagged<T, constructor_wrapper<F, Fxs...>>>(L, c);
18715  }
18716 
18718  typedef typename meta::bind_traits<F>::template arg_at<0> arg0;
18720  return stack::push<detail::tagged<T, constructor_wrapper<F, Fxs...>>>(L, std::move(c));
18721  }
18722  };
18723 
18724  template <typename T>
18725  struct unqualified_pusher<detail::tagged<T, destructor_wrapper<void>>> {
18727  lua_CFunction cf = detail::usertype_alloc_destruct<T>;
18728  return stack::push(L, cf);
18729  }
18730  };
18731 
18732  template <typename T, typename Fx>
18733  struct unqualified_pusher<detail::tagged<T, destructor_wrapper<Fx>>> {
18735  lua_CFunction cf = call_detail::call_user<T, false, false, destructor_wrapper<Fx>, 2>;
18736  int upvalues = 0;
18737  upvalues += stack::push(L, nullptr);
18738  upvalues += stack::push<user<destructor_wrapper<Fx>>>(L, std::move(c));
18739  return stack::push(L, c_closure(cf, upvalues));
18740  }
18741 
18742  static int push(lua_State* L, const destructor_wrapper<Fx>& c) {
18743  lua_CFunction cf = call_detail::call_user<T, false, false, destructor_wrapper<Fx>, 2>;
18744  int upvalues = 0;
18745  upvalues += stack::push(L, nullptr);
18746  upvalues += stack::push<user<destructor_wrapper<Fx>>>(L, c);
18747  return stack::push(L, c_closure(cf, upvalues));
18748  }
18749  };
18750 
18751  template <typename Fx>
18754  lua_CFunction cf = call_detail::call_user<void, false, false, destructor_wrapper<Fx>, 2>;
18755  int upvalues = 0;
18756  upvalues += stack::push(L, nullptr);
18757  upvalues += stack::push<user<destructor_wrapper<Fx>>>(L, std::move(c));
18758  return stack::push(L, c_closure(cf, upvalues));
18759  }
18760 
18761  static int push(lua_State* L, const destructor_wrapper<Fx>& c) {
18762  lua_CFunction cf = call_detail::call_user<void, false, false, destructor_wrapper<Fx>, 2>;
18763  int upvalues = 0;
18764  upvalues += stack::push(L, nullptr);
18765  upvalues += stack::push<user<destructor_wrapper<Fx>>>(L, c);
18766  return stack::push(L, c_closure(cf, upvalues));
18767  }
18768  };
18769 
18770  template <typename F, typename... Policies>
18771  struct unqualified_pusher<policy_wrapper<F, Policies...>> {
18772  using P = policy_wrapper<F, Policies...>;
18773 
18774  static int push(lua_State* L, const P& p) {
18775  lua_CFunction cf = call_detail::call_user<void, false, false, P, 2>;
18776  int upvalues = 0;
18777  upvalues += stack::push(L, nullptr);
18778  upvalues += stack::push<user<P>>(L, p);
18779  return stack::push(L, c_closure(cf, upvalues));
18780  }
18781 
18782  static int push(lua_State* L, P&& p) {
18783  lua_CFunction cf = call_detail::call_user<void, false, false, P, 2>;
18784  int upvalues = 0;
18785  upvalues += stack::push(L, nullptr);
18786  upvalues += stack::push<user<P>>(L, std::move(p));
18787  return stack::push(L, c_closure(cf, upvalues));
18788  }
18789  };
18790 
18791  template <typename T, typename F, typename... Policies>
18792  struct unqualified_pusher<detail::tagged<T, policy_wrapper<F, Policies...>>> {
18793  using P = policy_wrapper<F, Policies...>;
18795 
18796  static int push(lua_State* L, const Tagged& p) {
18797  lua_CFunction cf = call_detail::call_user<T, false, false, P, 2>;
18798  int upvalues = 0;
18799  upvalues += stack::push(L, nullptr);
18800  upvalues += stack::push<user<P>>(L, p.value());
18801  return stack::push(L, c_closure(cf, upvalues));
18802  }
18803 
18804  static int push(lua_State* L, Tagged&& p) {
18805  lua_CFunction cf = call_detail::call_user<T, false, false, P, 2>;
18806  int upvalues = 0;
18807  upvalues += stack::push(L, nullptr);
18808  upvalues += stack::push<user<P>>(L, std::move(p.value()));
18809  return stack::push(L, c_closure(cf, upvalues));
18810  }
18811  };
18812 
18813  template <typename T>
18815  static int push(lua_State* L, push_invoke_t<T>&& pi) {
18816  if constexpr (std::is_invocable_v<std::add_rvalue_reference_t<T>, lua_State*>) {
18817  return stack::push(L, std::move(pi.value())(L));
18818  }
18819  else {
18820  return stack::push(L, std::move(pi.value())());
18821  }
18822  }
18823 
18824  static int push(lua_State* L, const push_invoke_t<T>& pi) {
18825  if constexpr (std::is_invocable_v<const T, lua_State*>) {
18826  return stack::push(L, pi.value()(L));
18827  }
18828  else {
18829  return stack::push(L, pi.value()());
18830  }
18831  }
18832  };
18833 
18834  namespace stack_detail {
18835  template <typename Function, typename Handler>
18836  bool check_function_pointer(lua_State* L, int index, Handler&& handler, record& tracking) noexcept {
18837 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
18838  tracking.use(1);
18839  bool success = lua_iscfunction(L, index) == 1;
18840  if (success) {
18841  // there must be at LEAST 2 upvalues; otherwise, we didn't serialize it.
18842  const char* upvalue_name = lua_getupvalue(L, index, 2);
18843  lua_pop(L, 1);
18844  success = upvalue_name != nullptr;
18845  }
18846  if (!success) {
18847  // expected type, actual type
18848  handler(
18849  L, index, type::function, type_of(L, index), "type must be a Lua C Function gotten from a function pointer serialized by sol2");
18850  }
18851  return success;
18852 #else
18853  return false;
18854 #endif
18855  }
18856 
18857  template <typename Function>
18858  Function* get_function_pointer(lua_State* L, int index, record& tracking) noexcept {
18859 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
18860  tracking.use(1);
18861  auto udata = stack::stack_detail::get_as_upvalues_using_function<Function*>(L, index);
18862  Function* fx = udata.first;
18863  return fx;
18864 #else
18867  "You are attempting to retrieve a function pointer type. "
18868  "This is inherently unsafe in sol2. In order to do this, you must turn on the "
18869  "SOL_GET_FUNCTION_POINTER_UNSAFE configuration macro, as detailed in the documentation. "
18870  "Please be careful!"
18871 #else
18872  "You are attempting to retrieve a function pointer type. "
18873  "You explicitly turned off the ability to do this by defining "
18874  "SOL_GET_FUNCTION_POINTER_UNSAFE or similar to be off. "
18875  "Please reconsider this!"
18876 #endif
18877  );
18878  return nullptr;
18879 #endif
18880  }
18881  } // namespace stack_detail
18882  } // namespace stack
18883 } // namespace sol
18884 
18885 // end of sol/function_types.hpp
18886 
18887 // beginning of sol/dump_handler.hpp
18888 
18889 #include <cstdint>
18890 #include <exception>
18891 
18892 namespace sol {
18893 
18894  class dump_error : public error {
18895  private:
18896  int ec_;
18897 
18898  public:
18899  dump_error(int error_code_) : error("dump returned non-zero error of " + std::to_string(error_code_)), ec_(error_code_) {
18900  }
18901 
18902  int error_code() const {
18903  return ec_;
18904  }
18905  };
18906 
18907  inline int dump_pass_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
18908  (void)L;
18909  (void)writer_function;
18910  (void)userdata;
18911  (void)strip;
18912  return result_code;
18913  }
18914 
18915  inline int dump_panic_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
18916  (void)L;
18917  (void)writer_function;
18918  (void)userdata;
18919  (void)strip;
18920  return luaL_error(L, "a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code);
18921  }
18922 
18923  inline int dump_throw_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
18924 #if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
18925  return dump_panic_on_error(L, result_code, writer_function, userdata, strip);
18926 #else
18927  (void)L;
18928  (void)writer_function;
18929  (void)userdata;
18930  (void)strip;
18931  throw dump_error(result_code);
18932 #endif // no exceptions stuff
18933  }
18934 
18935 } // namespace sol
18936 
18937 // end of sol/dump_handler.hpp
18938 
18939 #include <cstdint>
18940 
18941 namespace sol {
18942  template <typename ref_t, bool aligned = false>
18943  class basic_function : public basic_object<ref_t> {
18944  private:
18945  using base_t = basic_object<ref_t>;
18946 
18947  void luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount) const {
18948  lua_call(lua_state(), static_cast<int>(argcount), static_cast<int>(resultcount));
18949  }
18950 
18951  template <std::size_t... I, typename... Ret>
18952  auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n) const {
18953  luacall(n, lua_size<std::tuple<Ret...>>::value);
18954  return stack::pop<std::tuple<Ret...>>(lua_state());
18955  }
18956 
18957  template <std::size_t I, typename Ret, meta::enable<meta::neg<std::is_void<Ret>>> = meta::enabler>
18958  Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n) const {
18959  luacall(n, lua_size<Ret>::value);
18960  return stack::pop<Ret>(lua_state());
18961  }
18962 
18963  template <std::size_t I>
18964  void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n) const {
18965  luacall(n, 0);
18966  }
18967 
18968  unsafe_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n) const {
18969  int stacksize = lua_gettop(lua_state());
18970  int firstreturn = (std::max)(1, stacksize - static_cast<int>(n));
18971  luacall(n, LUA_MULTRET);
18972  int poststacksize = lua_gettop(lua_state());
18973  int returncount = poststacksize - (firstreturn - 1);
18974  return unsafe_function_result(lua_state(), firstreturn, returncount);
18975  }
18976 
18977  public:
18978  using base_t::lua_state;
18979 
18980  basic_function() = default;
18981  template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_function>>, meta::neg<std::is_same<base_t, stack_reference>>, meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
18982  basic_function(T&& r) noexcept
18983  : base_t(std::forward<T>(r)) {
18984 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
18986  auto pp = stack::push_pop(*this);
18988  stack::check<basic_function>(lua_state(), -1, handler);
18989  }
18990 #endif // Safety
18991  }
18992  basic_function(const basic_function&) = default;
18993  basic_function& operator=(const basic_function&) = default;
18994  basic_function(basic_function&&) = default;
18995  basic_function& operator=(basic_function&&) = default;
18997  : basic_function(r.lua_state(), r.stack_index()) {
18998  }
19000  : basic_function(r.lua_state(), r.stack_index()) {
19001  }
19003  : base_t(n) {
19004  }
19005  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
19007  : base_t(L, std::forward<T>(r)) {
19008 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
19009  auto pp = stack::push_pop(*this);
19011  stack::check<basic_function>(lua_state(), -1, handler);
19012 #endif // Safety
19013  }
19014  basic_function(lua_State* L, int index = -1)
19015  : base_t(L, index) {
19016 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
19018  stack::check<basic_function>(L, index, handler);
19019 #endif // Safety
19020  }
19022  : base_t(L, index) {
19023 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
19024  auto pp = stack::push_pop(*this);
19026  stack::check<basic_function>(lua_state(), -1, handler);
19027 #endif // Safety
19028  }
19029 
19030  template <typename Fx>
19031  int dump(lua_Writer writer, void* userdata, bool strip, Fx&& on_error) const {
19032  this->push();
19033  auto ppn = stack::push_popper_n<false>(this->lua_state(), 1);
19034  int r = lua_dump(this->lua_state(), writer, userdata, strip ? 1 : 0);
19035  if (r != 0) {
19036  return on_error(this->lua_state(), r, writer, userdata, strip);
19037  }
19038  return r;
19039  }
19040 
19041  int dump(lua_Writer writer, void* userdata, bool strip = false) const {
19042  return dump(writer, userdata, strip, &dump_throw_on_error);
19043  }
19044 
19045  template <typename Container = bytecode>
19046  Container dump() const {
19047  Container bc;
19048  (void)dump(static_cast<lua_Writer>(&basic_insert_dump_writer<Container>), static_cast<void*>(&bc), false, &dump_panic_on_error);
19049  return bc;
19050  }
19051 
19052  template <typename Container = bytecode, typename Fx>
19053  Container dump(Fx&& on_error) const {
19054  Container bc;
19055  (void)dump(static_cast<lua_Writer>(&basic_insert_dump_writer<Container>), static_cast<void*>(&bc), false, std::forward<Fx>(on_error));
19056  return bc;
19057  }
19058 
19059  template <typename... Args>
19060  unsafe_function_result operator()(Args&&... args) const {
19061  return call<>(std::forward<Args>(args)...);
19062  }
19063 
19064  template <typename... Ret, typename... Args>
19065  decltype(auto) operator()(types<Ret...>, Args&&... args) const {
19066  return call<Ret...>(std::forward<Args>(args)...);
19067  }
19068 
19069  template <typename... Ret, typename... Args>
19070  decltype(auto) call(Args&&... args) const {
19071  if (!aligned) {
19072  base_t::push();
19073  }
19074  int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
19075  return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), static_cast<std::ptrdiff_t>(pushcount));
19076  }
19077  };
19078 } // namespace sol
19079 
19080 // end of sol/unsafe_function.hpp
19081 
19082 // beginning of sol/protected_function.hpp
19083 
19084 // beginning of sol/protected_handler.hpp
19085 
19086 #include <cstdint>
19087 
19088 namespace sol {
19089  namespace detail {
19090  inline const char(&default_handler_name())[9]{
19091  static const char name[9] = "sol.\xF0\x9F\x94\xA9";
19092  return name;
19093  }
19094 
19095  template <bool b, typename target_t = reference>
19098  const target_t& target;
19100 
19101  protected_handler(std::false_type, const target_t& target)
19102  : target(target), stackindex(0) {
19103  if (b) {
19104  stackindex = lua_gettop(target.lua_state()) + 1;
19105  target.push();
19106  }
19107  }
19108 
19109  protected_handler(std::true_type, const target_t& target)
19110  : target(target), stackindex(0) {
19111  if (b) {
19112  stackindex = target.stack_index();
19113  }
19114  }
19115 
19116  protected_handler(const target_t& target)
19117  : protected_handler(is_stack(), target) {
19118  }
19119 
19120  bool valid() const noexcept {
19121  return b;
19122  }
19123 
19125  if constexpr (!is_stack::value) {
19126  if (stackindex != 0) {
19127  lua_remove(target.lua_state(), stackindex);
19128  }
19129  }
19130  }
19131  };
19132 
19133  template <typename base_t, typename T>
19135  return p;
19136  }
19137 
19138  template <typename Reference, bool is_main_ref = false>
19139  static Reference get_default_handler(lua_State* L) {
19140  if (is_stack_based<Reference>::value || L == nullptr)
19141  return Reference(L, lua_nil);
19142  L = is_main_ref ? main_thread(L, L) : L;
19144  auto pp = stack::pop_n(L, 1);
19145  return Reference(L, -1);
19146  }
19147 
19148  template <typename T>
19149  static void set_default_handler(lua_State* L, const T& ref) {
19150  if (L == nullptr) {
19151  return;
19152  }
19153  if (!ref.valid()) {
19154 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
19156 #endif // make sure stack doesn't overflow
19157  lua_pushnil(L);
19159  }
19160  else {
19161  ref.push(L);
19163  }
19164  }
19165  } // namespace detail
19166 } // namespace sol
19167 
19168 // end of sol/protected_handler.hpp
19169 
19170 #include <cstdint>
19171 #include <algorithm>
19172 
19173 namespace sol {
19174 
19175  namespace detail {
19176  template <bool b, typename handler_t>
19177  inline void handle_protected_exception(lua_State* L, optional<const std::exception&> maybe_ex, const char* error, detail::protected_handler<b, handler_t>& h) {
19178  h.stackindex = 0;
19179  if (b) {
19180  h.target.push();
19181  detail::call_exception_handler(L, maybe_ex, error);
19182  lua_call(L, 1, 1);
19183  }
19184  else {
19185  detail::call_exception_handler(L, maybe_ex, error);
19186  }
19187  }
19188  }
19189 
19190  template <typename ref_t, bool aligned = false, typename handler_t = reference>
19191  class basic_protected_function : public basic_object<ref_t> {
19192  private:
19193  using base_t = basic_object<ref_t>;
19194 
19195  public:
19197 
19198  static handler_t get_default_handler(lua_State* L) {
19200  }
19201 
19202  template <typename T>
19203  static void set_default_handler(const T& ref) {
19204  detail::set_default_handler(ref.lua_state(), ref);
19205  }
19206 
19207  private:
19208  template <bool b>
19209  call_status luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount, detail::protected_handler<b, handler_t>& h) const {
19210  return static_cast<call_status>(lua_pcall(lua_state(), static_cast<int>(argcount), static_cast<int>(resultcount), h.stackindex));
19211  }
19212 
19213  template <std::size_t... I, bool b, typename... Ret>
19214  auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
19215  luacall(n, sizeof...(Ret), h);
19216  return stack::pop<std::tuple<Ret...>>(lua_state());
19217  }
19218 
19219  template <std::size_t I, bool b, typename Ret>
19220  Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
19221  luacall(n, 1, h);
19222  return stack::pop<Ret>(lua_state());
19223  }
19224 
19225  template <std::size_t I, bool b>
19226  void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
19227  luacall(n, 0, h);
19228  }
19229 
19230  template <bool b>
19231  protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
19232  int stacksize = lua_gettop(lua_state());
19233  int poststacksize = stacksize;
19234  int firstreturn = 1;
19235  int returncount = 0;
19237 #if !defined(SOL_NO_EXCEPTIONS) || !SOL_NO_EXCEPTIONS
19238 #if (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !SOL_NO_EXCEPTIONS_SAFE_PROPAGATION) || (defined(SOL_LUAJIT) && SOL_LUAJIT)
19239  try {
19240 #endif // Safe Exception Propagation
19241 #endif // No Exceptions
19242  firstreturn = (std::max)(1, static_cast<int>(stacksize - n - static_cast<int>(h.valid() && !is_stack_handler::value)));
19243  code = luacall(n, LUA_MULTRET, h);
19244  poststacksize = lua_gettop(lua_state()) - static_cast<int>(h.valid() && !is_stack_handler::value);
19245  returncount = poststacksize - (firstreturn - 1);
19246 #ifndef SOL_NO_EXCEPTIONS
19247 #if (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !SOL_NO_EXCEPTIONS_SAFE_PROPAGATION) || (defined(SOL_LUAJIT) && SOL_LUAJIT)
19248  }
19249  // Handle C++ errors thrown from C++ functions bound inside of lua
19250  catch (const char* error) {
19251  detail::handle_protected_exception(lua_state(), optional<const std::exception&>(nullopt), error, h);
19252  firstreturn = lua_gettop(lua_state());
19253  return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
19254  }
19255  catch (const std::string& error) {
19256  detail::handle_protected_exception(lua_state(), optional<const std::exception&>(nullopt), error.c_str(), h);
19257  firstreturn = lua_gettop(lua_state());
19258  return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
19259  }
19260  catch (const std::exception& error) {
19261  detail::handle_protected_exception(lua_state(), optional<const std::exception&>(error), error.what(), h);
19262  firstreturn = lua_gettop(lua_state());
19263  return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
19264  }
19265 #if (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !SOL_NO_EXCEPTIONS_SAFE_PROPAGATION)
19266  // LuaJIT cannot have the catchall when the safe propagation is on
19267  // but LuaJIT will swallow all C++ errors
19268  // if we don't at least catch std::exception ones
19269  catch (...) {
19270  detail::handle_protected_exception(lua_state(), optional<const std::exception&>(nullopt), detail::protected_function_error, h);
19271  firstreturn = lua_gettop(lua_state());
19272  return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
19273  }
19274 #endif // LuaJIT
19275 #else
19276  // do not handle exceptions: they can be propogated into C++ and keep all type information / rich information
19277 #endif // Safe Exception Propagation
19278 #endif // Exceptions vs. No Exceptions
19279  return protected_function_result(lua_state(), firstreturn, returncount, returncount, code);
19280  }
19281 
19282  public:
19283  using base_t::lua_state;
19284 
19285  handler_t error_handler;
19286 
19287  basic_protected_function() = default;
19288  template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_protected_function>>, meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>, meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
19290  : base_t(std::forward<T>(r)), error_handler(get_default_handler(r.lua_state())) {
19291 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
19293  auto pp = stack::push_pop(*this);
19295  stack::check<basic_protected_function>(lua_state(), -1, handler);
19296  }
19297 #endif // Safety
19298  }
19300  basic_protected_function& operator=(const basic_protected_function&) = default;
19302  basic_protected_function& operator=(basic_protected_function&&) = default;
19304  : basic_protected_function(b, get_default_handler(b.lua_state())) {
19305  }
19307  : basic_protected_function(std::move(b), get_default_handler(b.lua_state())) {
19308  }
19310  : base_t(b), error_handler(std::move(eh)) {
19311  }
19313  : base_t(std::move(b)), error_handler(std::move(eh)) {
19314  }
19316  : basic_protected_function(r.lua_state(), r.stack_index(), get_default_handler(r.lua_state())) {
19317  }
19319  : basic_protected_function(r.lua_state(), r.stack_index(), get_default_handler(r.lua_state())) {
19320  }
19322  : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {
19323  }
19325  : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {
19326  }
19327 
19328  template <typename Super>
19330  : basic_protected_function(p, get_default_handler(p.lua_state())) {
19331  }
19332  template <typename Super>
19334  : basic_protected_function(std::move(p), get_default_handler(p.lua_state())) {
19335  }
19336  template <typename Proxy, typename Handler, meta::enable<std::is_base_of<proxy_base_tag, meta::unqualified_t<Proxy>>, meta::neg<is_lua_index<meta::unqualified_t<Handler>>>> = meta::enabler>
19337  basic_protected_function(Proxy&& p, Handler&& eh)
19338  : basic_protected_function(detail::force_cast<base_t>(p), std::forward<Handler>(eh)) {
19339  }
19340 
19341  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
19343  : basic_protected_function(L, std::forward<T>(r), get_default_handler(L)) {
19344  }
19345  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
19346  basic_protected_function(lua_State* L, T&& r, handler_t eh)
19347  : base_t(L, std::forward<T>(r)), error_handler(std::move(eh)) {
19348 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
19349  auto pp = stack::push_pop(*this);
19351  stack::check<basic_protected_function>(lua_state(), -1, handler);
19352 #endif // Safety
19353  }
19354 
19356  : base_t(n), error_handler(n) {
19357  }
19358 
19361  }
19362  basic_protected_function(lua_State* L, int index, handler_t eh)
19363  : base_t(L, index), error_handler(std::move(eh)) {
19364 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
19366  stack::check<basic_protected_function>(L, index, handler);
19367 #endif // Safety
19368  }
19371  }
19373  : base_t(L, index), error_handler(std::move(eh)) {
19374 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
19376  stack::check<basic_protected_function>(L, index, handler);
19377 #endif // Safety
19378  }
19381  }
19383  : base_t(L, index), error_handler(std::move(eh)) {
19384 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
19386  stack::check<basic_protected_function>(L, index, handler);
19387 #endif // Safety
19388  }
19391  }
19393  : base_t(L, index), error_handler(std::move(eh)) {
19394 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
19395  auto pp = stack::push_pop(*this);
19397  stack::check<basic_protected_function>(lua_state(), -1, handler);
19398 #endif // Safety
19399  }
19400 
19401  template <typename Fx>
19402  int dump(lua_Writer writer, void* userdata, bool strip, Fx&& on_error) const {
19403  this->push();
19404  auto ppn = stack::push_popper_n<false>(this->lua_state(), 1);
19405  int r = lua_dump(this->lua_state(), writer, userdata, strip ? 1 : 0);
19406  if (r != 0) {
19407  return on_error(this->lua_state(), r, writer, userdata, strip);
19408  }
19409  return r;
19410  }
19411 
19412  int dump(lua_Writer writer, void* userdata, bool strip = false) const {
19413  return dump(writer, userdata, strip, &dump_pass_on_error);
19414  }
19415 
19416  template <typename Container = bytecode>
19417  Container dump() const {
19418  Container bc;
19419  (void)dump(static_cast<lua_Writer>(&basic_insert_dump_writer<Container>), static_cast<void*>(&bc), false, &dump_throw_on_error);
19420  return bc;
19421  }
19422 
19423  template <typename Container = bytecode, typename Fx>
19424  Container dump(Fx&& on_error) const {
19425  Container bc;
19426  (void)dump(static_cast<lua_Writer>(&basic_insert_dump_writer<Container>), static_cast<void*>(&bc), false, std::forward<Fx>(on_error));
19427  return bc;
19428  }
19429 
19430  template <typename... Args>
19431  protected_function_result operator()(Args&&... args) const {
19432  return call<>(std::forward<Args>(args)...);
19433  }
19434 
19435  template <typename... Ret, typename... Args>
19436  decltype(auto) operator()(types<Ret...>, Args&&... args) const {
19437  return call<Ret...>(std::forward<Args>(args)...);
19438  }
19439 
19440  template <typename... Ret, typename... Args>
19441  decltype(auto) call(Args&&... args) const {
19442  if constexpr (!aligned) {
19443  // we do not expect the function to already be on the stack: push it
19444  if (error_handler.valid()) {
19446  base_t::push();
19447  int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
19448  return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
19449  }
19450  else {
19452  base_t::push();
19453  int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
19454  return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
19455  }
19456  }
19457  else {
19458  // the function is already on the stack at the right location
19459  if (error_handler.valid()) {
19460  // the handler will be pushed onto the stack manually,
19461  // since it's not already on the stack this means we need to push our own
19462  // function on the stack too and swap things to be in-place
19463  if constexpr (!is_stack_handler::value) {
19464  // so, we need to remove the function at the top and then dump the handler out ourselves
19465  base_t::push();
19466  }
19468  if constexpr (!is_stack_handler::value) {
19469  lua_replace(lua_state(), -3);
19470  h.stackindex = lua_absindex(lua_state(), -2);
19471  }
19472  int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
19473  return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
19474  }
19475  else {
19477  int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
19478  return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
19479  }
19480  }
19481  }
19482  };
19483 } // namespace sol
19484 
19485 // end of sol/protected_function.hpp
19486 
19487 #include <functional>
19488 
19489 namespace sol {
19490  template <typename... Ret, typename... Args>
19491  decltype(auto) stack_proxy::call(Args&&... args) {
19492  stack_function sf(this->lua_state(), this->stack_index());
19493  return sf.template call<Ret...>(std::forward<Args>(args)...);
19494  }
19495 
19497  : L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()), popcount(o.return_count()), err(o.status()) {
19498  // Must be manual, otherwise destructor will screw us
19499  // return count being 0 is enough to keep things clean
19500  // but we will be thorough
19501  o.abandon();
19502  }
19503 
19505  L = o.lua_state();
19506  index = o.stack_index();
19507  returncount = o.return_count();
19508  popcount = o.return_count();
19509  err = o.status();
19510  // Must be manual, otherwise destructor will screw us
19511  // return count being 0 is enough to keep things clean
19512  // but we will be thorough
19513  o.abandon();
19514  return *this;
19515  }
19516 
19518  : L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()) {
19519  // Must be manual, otherwise destructor will screw us
19520  // return count being 0 is enough to keep things clean
19521  // but we will be thorough
19522  o.abandon();
19523  }
19525  L = o.lua_state();
19526  index = o.stack_index();
19527  returncount = o.return_count();
19528  // Must be manual, otherwise destructor will screw us
19529  // return count being 0 is enough to keep things clean
19530  // but we will be thorough
19531  o.abandon();
19532  return *this;
19533  }
19534 
19535  namespace detail {
19536  template <typename... R>
19537  struct std_shim {
19539 
19540  std_shim(unsafe_function lua_func) : lua_func_(std::move(lua_func)) {
19541  }
19542 
19543  template <typename... Args>
19544  meta::return_type_t<R...> operator()(Args&&... args) {
19545  return lua_func_.call<R...>(std::forward<Args>(args)...);
19546  }
19547  };
19548 
19549  template <>
19550  struct std_shim<void> {
19552 
19553  std_shim(unsafe_function lua_func) : lua_func_(std::move(lua_func)) {
19554  }
19555 
19556  template <typename... Args>
19557  void operator()(Args&&... args) {
19558  lua_func_.call<void>(std::forward<Args>(args)...);
19559  }
19560  };
19561  } // namespace detail
19562 
19563  namespace stack {
19564  template <typename Signature>
19565  struct unqualified_getter<std::function<Signature>> {
19567  typedef typename fx_t::args_list args_lists;
19569 
19570  template <typename... R>
19571  static std::function<Signature> get_std_func(types<R...>, lua_State* L, int index) {
19572  detail::std_shim<R...> fx(unsafe_function(L, index));
19573  return fx;
19574  }
19575 
19576  static std::function<Signature> get(lua_State* L, int index, record& tracking) {
19577  tracking.use(1);
19578  type t = type_of(L, index);
19579  if (t == type::none || t == type::lua_nil) {
19580  return nullptr;
19581  }
19582  return get_std_func(return_types(), L, index);
19583  }
19584  };
19585 
19586  template <typename Allocator>
19587  struct unqualified_getter<basic_bytecode<Allocator>> {
19588  static basic_bytecode<Allocator> get(lua_State* L, int index, record& tracking) {
19589  tracking.use(1);
19590  stack_function sf(L, index);
19591  return sf.dump(&dump_panic_on_error);
19592  }
19593  };
19594  } // namespace stack
19595 
19596 } // namespace sol
19597 
19598 // end of sol/function.hpp
19599 
19600 // beginning of sol/usertype.hpp
19601 
19602 // beginning of sol/usertype_core.hpp
19603 
19604 // beginning of sol/deprecate.hpp
19605 
19606 #ifndef SOL_DEPRECATED
19607 #ifdef _MSC_VER
19608 #define SOL_DEPRECATED __declspec(deprecated)
19609 #elif __GNUC__
19610 #define SOL_DEPRECATED __attribute__((deprecated))
19611 #else
19612 #define SOL_DEPRECATED [[deprecated]]
19613 #endif // compilers
19614 #endif // SOL_DEPRECATED
19615 
19616 namespace sol {
19617 namespace detail {
19618  template <typename T>
19620  using type = T;
19621  };
19622 }
19623 } // namespace sol::detail
19624 
19625 // end of sol/deprecate.hpp
19626 
19627 // beginning of sol/usertype_container_launch.hpp
19628 
19629 // beginning of sol/usertype_container.hpp
19630 
19631 namespace sol {
19632 
19633  template <typename T>
19635 
19636  namespace container_detail {
19637 
19638  template <typename T>
19640  private:
19641  template <typename C>
19642  static meta::sfinae_yes_t test(decltype(&C::clear));
19643  template <typename C>
19644  static meta::sfinae_no_t test(...);
19645 
19646  public:
19647  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19648  };
19649 
19650  template <typename T>
19652  private:
19653  template <typename C>
19654  static meta::sfinae_yes_t test(decltype(&C::empty));
19655  template <typename C>
19656  static meta::sfinae_no_t test(...);
19657 
19658  public:
19659  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19660  };
19661 
19662  template <typename T>
19664  private:
19665  template <typename C>
19666  static meta::sfinae_yes_t test(
19667  decltype(std::declval<C>().erase_after(std::declval<std::add_rvalue_reference_t<typename C::const_iterator>>()))*);
19668  template <typename C>
19669  static meta::sfinae_no_t test(...);
19670 
19671  public:
19672  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19673  };
19674 
19675  template <typename T, typename = void>
19676  struct has_find_test {
19677  private:
19678  template <typename C>
19679  static meta::sfinae_yes_t test(decltype(std::declval<C>().find(std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
19680  template <typename C>
19681  static meta::sfinae_no_t test(...);
19682 
19683  public:
19684  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19685  };
19686 
19687  template <typename T>
19688  struct has_find_test<T, std::enable_if_t<meta::is_lookup<T>::value>> {
19689  private:
19690  template <typename C>
19691  static meta::sfinae_yes_t test(decltype(std::declval<C>().find(std::declval<std::add_rvalue_reference_t<typename C::key_type>>()))*);
19692  template <typename C>
19693  static meta::sfinae_no_t test(...);
19694 
19695  public:
19696  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19697  };
19698 
19699  template <typename T>
19701  private:
19702  template <typename C>
19703  static meta::sfinae_yes_t test(decltype(std::declval<C>().erase(std::declval<typename C::iterator>()))*);
19704  template <typename C>
19705  static meta::sfinae_no_t test(...);
19706 
19707  public:
19708  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19709  };
19710 
19711  template <typename T>
19713  private:
19714  template <typename C>
19715  static meta::sfinae_yes_t test(decltype(std::declval<C>().erase(std::declval<typename C::key_type>()))*);
19716  template <typename C>
19717  static meta::sfinae_no_t test(...);
19718 
19719  public:
19720  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19721  };
19722 
19723  template <typename T>
19725  private:
19726  template <typename C>
19727  static meta::sfinae_yes_t test(decltype(&C::find));
19728  template <typename C>
19729  static meta::sfinae_no_t test(...);
19730 
19731  public:
19732  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19733  };
19734 
19735  template <typename T>
19737  private:
19738  template <typename C>
19739  static meta::sfinae_yes_t test(decltype(&C::index_of));
19740  template <typename C>
19741  static meta::sfinae_no_t test(...);
19742 
19743  public:
19744  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19745  };
19746 
19747  template <typename T>
19749  private:
19750  template <typename C>
19751  static meta::sfinae_yes_t test(decltype(&C::insert));
19752  template <typename C>
19753  static meta::sfinae_no_t test(...);
19754 
19755  public:
19756  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19757  };
19758 
19759  template <typename T>
19761  private:
19762  template <typename C>
19763  static meta::sfinae_yes_t test(decltype(&C::erase));
19764  template <typename C>
19765  static meta::sfinae_no_t test(...);
19766 
19767  public:
19768  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19769  };
19770 
19771  template <typename T>
19773  private:
19774  template <typename C>
19775  static meta::sfinae_yes_t test(decltype(&C::index_set));
19776  template <typename C>
19777  static meta::sfinae_no_t test(...);
19778 
19779  public:
19780  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19781  };
19782 
19783  template <typename T>
19785  private:
19786  template <typename C>
19787  static meta::sfinae_yes_t test(decltype(&C::index_get));
19788  template <typename C>
19789  static meta::sfinae_no_t test(...);
19790 
19791  public:
19792  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19793  };
19794 
19795  template <typename T>
19797  private:
19798  template <typename C>
19799  static meta::sfinae_yes_t test(decltype(&C::set));
19800  template <typename C>
19801  static meta::sfinae_no_t test(...);
19802 
19803  public:
19804  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19805  };
19806 
19807  template <typename T>
19809  private:
19810  template <typename C>
19811  static meta::sfinae_yes_t test(decltype(&C::get));
19812  template <typename C>
19813  static meta::sfinae_no_t test(...);
19814 
19815  public:
19816  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19817  };
19818 
19819  template <typename T>
19821  private:
19822  template <typename C>
19823  static meta::sfinae_yes_t test(decltype(&C::at));
19824  template <typename C>
19825  static meta::sfinae_no_t test(...);
19826 
19827  public:
19828  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19829  };
19830 
19831  template <typename T>
19833  private:
19834  template <typename C>
19835  static meta::sfinae_yes_t test(decltype(&C::pairs));
19836  template <typename C>
19837  static meta::sfinae_no_t test(...);
19838 
19839  public:
19840  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19841  };
19842 
19843  template <typename T>
19845  private:
19846  template <typename C>
19847  static meta::sfinae_yes_t test(decltype(&C::ipairs));
19848  template <typename C>
19849  static meta::sfinae_no_t test(...);
19850 
19851  public:
19852  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19853  };
19854 
19855  template <typename T>
19857  private:
19858  template <typename C>
19859  static meta::sfinae_yes_t test(decltype(&C::next));
19860  template <typename C>
19861  static meta::sfinae_no_t test(...);
19862 
19863  public:
19864  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19865  };
19866 
19867  template <typename T>
19869  private:
19870  template <typename C>
19871  static meta::sfinae_yes_t test(decltype(&C::add));
19872  template <typename C>
19873  static meta::sfinae_no_t test(...);
19874 
19875  public:
19876  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19877  };
19878 
19879  template <typename T>
19881  private:
19882  template <typename C>
19883  static meta::sfinae_yes_t test(decltype(&C::size));
19884  template <typename C>
19885  static meta::sfinae_no_t test(...);
19886 
19887  public:
19888  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
19889  };
19890 
19891  template <typename T>
19893 
19894  template <typename T>
19896 
19897  template <typename T>
19899 
19900  template <typename T>
19902 
19903  template <typename T>
19905 
19906  template <typename T>
19908 
19909  template <typename T>
19911 
19912  template <typename T>
19914 
19915  template <typename T>
19917 
19918  template <typename T>
19920 
19921  template <typename T>
19923 
19924  template <typename T>
19926 
19927  template <typename T>
19929 
19930  template <typename T>
19932 
19933  template <typename T>
19935 
19936  template <typename T>
19938 
19939  template <typename T>
19941 
19942  template <typename T>
19944 
19945  template <typename T>
19947 
19948  template <typename T>
19950 
19951  template <typename T>
19953 
19954  template <typename T>
19956 
19957  template <typename T>
19959 
19960  template <typename T>
19961  struct is_forced_container<as_container_t<T>> : std::true_type {};
19962 
19963  template <typename T>
19965  typedef T type;
19966  };
19967 
19968  template <typename T>
19970  typedef T type;
19971  };
19972 
19973  template <typename T>
19975 
19976  template <typename T>
19977  decltype(auto) get_key(std::false_type, T&& t) {
19978  return std::forward<T>(t);
19979  }
19980 
19981  template <typename T>
19982  decltype(auto) get_key(std::true_type, T&& t) {
19983  return t.first;
19984  }
19985 
19986  template <typename T>
19987  decltype(auto) get_value(std::false_type, T&& t) {
19988  return std::forward<T>(t);
19989  }
19990 
19991  template <typename T>
19992  decltype(auto) get_value(std::true_type, T&& t) {
19993  return t.second;
19994  }
19995 
19996  template <typename X, typename = void>
19998  private:
19999  typedef std::remove_pointer_t<meta::unwrap_unqualified_t<X>> T;
20000 
20001  public:
20004 
20005  static int at(lua_State* L) {
20006  return luaL_error(L, "sol: cannot call 'at(index)' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20007  }
20008 
20009  static int get(lua_State* L) {
20010  return luaL_error(L, "sol: cannot call 'get(key)' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20011  }
20012 
20013  static int index_get(lua_State* L) {
20014  return luaL_error(L, "sol: cannot call 'container[key]' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20015  }
20016 
20017  static int set(lua_State* L) {
20018  return luaL_error(L, "sol: cannot call 'set(key, value)' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20019  }
20020 
20021  static int index_set(lua_State* L) {
20022  return luaL_error(
20023  L, "sol: cannot call 'container[key] = value' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20024  }
20025 
20026  static int add(lua_State* L) {
20027  return luaL_error(L, "sol: cannot call 'add' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20028  }
20029 
20030  static int insert(lua_State* L) {
20031  return luaL_error(L, "sol: cannot call 'insert' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20032  }
20033 
20034  static int find(lua_State* L) {
20035  return luaL_error(L, "sol: cannot call 'find' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20036  }
20037 
20038  static int index_of(lua_State* L) {
20039  return luaL_error(L, "sol: cannot call 'index_of' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20040  }
20041 
20042  static int size(lua_State* L) {
20043  return luaL_error(L, "sol: cannot call 'end' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20044  }
20045 
20046  static int clear(lua_State* L) {
20047  return luaL_error(L, "sol: cannot call 'clear' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20048  }
20049 
20050  static int empty(lua_State* L) {
20051  return luaL_error(L, "sol: cannot call 'empty' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20052  }
20053 
20054  static int erase(lua_State* L) {
20055  return luaL_error(L, "sol: cannot call 'erase' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20056  }
20057 
20058  static int next(lua_State* L) {
20059  return luaL_error(L, "sol: cannot call 'next' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20060  }
20061 
20062  static int pairs(lua_State* L) {
20063  return luaL_error(L, "sol: cannot call '__pairs/pairs' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20064  }
20065 
20066  static int ipairs(lua_State* L) {
20067  return luaL_error(L, "sol: cannot call '__ipairs' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20068  }
20069 
20070  static iterator begin(lua_State* L, T&) {
20071  luaL_error(L, "sol: cannot call 'being' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20072  return lua_nil;
20073  }
20074 
20075  static iterator end(lua_State* L, T&) {
20076  luaL_error(L, "sol: cannot call 'end' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
20077  return lua_nil;
20078  }
20079  };
20080 
20081  template <typename X>
20083  std::enable_if_t<meta::all<is_forced_container<meta::unqualified_t<X>>, meta::has_value_type<meta::unqualified_t<container_decay_t<X>>>,
20084  meta::has_iterator<meta::unqualified_t<container_decay_t<X>>>>::value>> {
20085  private:
20086  using T = std::remove_pointer_t<meta::unwrap_unqualified_t<container_decay_t<X>>>;
20087 
20088  private:
20094  using iterator = typename T::iterator;
20095  using value_type = typename T::value_type;
20099  typedef typename KV::first_type K;
20100  typedef typename KV::second_type V;
20102  typedef decltype(*std::declval<iterator&>()) iterator_return;
20103  typedef meta::conditional_t<is_associative::value || is_matched_lookup::value, std::add_lvalue_reference_t<V>,
20104  meta::conditional_t<is_lookup::value, V, iterator_return>>
20106  typedef typename meta::iterator_tag<iterator>::type iterator_category;
20107  typedef std::is_same<iterator_category, std::input_iterator_tag> is_input_iterator;
20108  typedef meta::conditional_t<is_input_iterator::value, V, decltype(detail::deref_move_only(std::declval<captured_type>()))> push_type;
20109  typedef std::is_copy_assignable<V> is_copyable;
20110  typedef meta::neg<meta::any<std::is_const<V>, std::is_const<std::remove_reference_t<iterator_return>>, meta::neg<is_copyable>>> is_writable;
20111  typedef meta::unqualified_t<decltype(get_key(is_associative(), std::declval<std::add_lvalue_reference_t<value_type>>()))> key_type;
20112  typedef meta::all<std::is_integral<K>, meta::neg<meta::any<is_associative, is_lookup>>> is_linear_integral;
20113 
20114  struct iter {
20117  std::size_t i;
20118 
20119  iter(T& source, iterator it) : source(source), it(std::move(it)), i(0) {
20120  }
20121 
20122  ~iter() {
20123  }
20124  };
20125 
20126  static auto& get_src(lua_State* L) {
20127 #if SOL_IS_ON(SOL_SAFE_USERTYPE_I_)
20128  auto p = stack::unqualified_check_get<T*>(L, 1);
20129  if (!p) {
20130  luaL_error(L,
20131  "sol: 'self' is not of type '%s' (pass 'self' as first argument with ':' or call on proper type)",
20132  detail::demangle<T>().c_str());
20133  }
20134  if (p.value() == nullptr) {
20135  luaL_error(
20136  L, "sol: 'self' argument is nil (pass 'self' as first argument with ':' or call on a '%s' type)", detail::demangle<T>().c_str());
20137  }
20138  return *p.value();
20139 #else
20140  return stack::unqualified_get<T>(L, 1);
20141 #endif // Safe getting with error
20142  }
20143 
20144  static detail::error_result at_category(std::input_iterator_tag, lua_State* L, T& self, std::ptrdiff_t pos) {
20145  pos += deferred_uc::index_adjustment(L, self);
20146  if (pos < 0) {
20147  return stack::push(L, lua_nil);
20148  }
20149  auto it = deferred_uc::begin(L, self);
20150  auto e = deferred_uc::end(L, self);
20151  if (it == e) {
20152  return stack::push(L, lua_nil);
20153  }
20154  while (pos > 0) {
20155  --pos;
20156  ++it;
20157  if (it == e) {
20158  return stack::push(L, lua_nil);
20159  }
20160  }
20161  return get_associative(is_associative(), L, it);
20162  }
20163 
20164  static detail::error_result at_category(std::random_access_iterator_tag, lua_State* L, T& self, std::ptrdiff_t pos) {
20165  std::ptrdiff_t len = static_cast<std::ptrdiff_t>(size_start(L, self));
20166  pos += deferred_uc::index_adjustment(L, self);
20167  if (pos < 0 || pos >= len) {
20168  return stack::push(L, lua_nil);
20169  }
20170  auto it = std::next(deferred_uc::begin(L, self), pos);
20171  return get_associative(is_associative(), L, it);
20172  }
20173 
20174  static detail::error_result at_start(lua_State* L, T& self, std::ptrdiff_t pos) {
20175  return at_category(iterator_category(), L, self, pos);
20176  }
20177 
20178  template <typename Iter>
20179  static detail::error_result get_associative(std::true_type, lua_State* L, Iter& it) {
20180  decltype(auto) v = *it;
20181  return stack::stack_detail::push_reference<push_type>(L, detail::deref_move_only(v.second));
20182  }
20183 
20184  template <typename Iter>
20185  static detail::error_result get_associative(std::false_type, lua_State* L, Iter& it) {
20186  return stack::stack_detail::push_reference<push_type>(L, detail::deref_move_only(*it));
20187  }
20188 
20189  static detail::error_result get_category(std::input_iterator_tag, lua_State* L, T& self, K& key) {
20190  key += deferred_uc::index_adjustment(L, self);
20191  if (key < 0) {
20192  return stack::push(L, lua_nil);
20193  }
20194  auto it = deferred_uc::begin(L, self);
20195  auto e = deferred_uc::end(L, self);
20196  if (it == e) {
20197  return stack::push(L, lua_nil);
20198  }
20199  while (key > 0) {
20200  --key;
20201  ++it;
20202  if (it == e) {
20203  return stack::push(L, lua_nil);
20204  }
20205  }
20206  return get_associative(is_associative(), L, it);
20207  }
20208 
20209  static detail::error_result get_category(std::random_access_iterator_tag, lua_State* L, T& self, K& key) {
20210  std::ptrdiff_t len = static_cast<std::ptrdiff_t>(size_start(L, self));
20211  key += deferred_uc::index_adjustment(L, self);
20212  if (key < 0 || key >= len) {
20213  return stack::push(L, lua_nil);
20214  }
20215  auto it = std::next(deferred_uc::begin(L, self), key);
20216  return get_associative(is_associative(), L, it);
20217  }
20218 
20219  static detail::error_result get_it(std::true_type, lua_State* L, T& self, K& key) {
20220  return get_category(iterator_category(), L, self, key);
20221  }
20222 
20223  static detail::error_result get_comparative(std::true_type, lua_State* L, T& self, K& key) {
20224  auto fx = [&](const value_type& r) -> bool { return key == get_key(is_associative(), r); };
20225  auto e = deferred_uc::end(L, self);
20226  auto it = std::find_if(deferred_uc::begin(L, self), e, std::ref(fx));
20227  if (it == e) {
20228  return stack::push(L, lua_nil);
20229  }
20230  return get_associative(is_associative(), L, it);
20231  }
20232 
20233  static detail::error_result get_comparative(std::false_type, lua_State*, T&, K&) {
20234  return detail::error_result("cannot get this key on '%s': no suitable way to increment iterator and compare to key value '%s'",
20235  detail::demangle<T>().data(),
20236  detail::demangle<K>().data());
20237  }
20238 
20239  static detail::error_result get_it(std::false_type, lua_State* L, T& self, K& key) {
20240  return get_comparative(meta::supports_op_equal<K, key_type>(), L, self, key);
20241  }
20242 
20243  static detail::error_result set_associative(std::true_type, iterator& it, stack_object value) {
20244  decltype(auto) v = *it;
20245  v.second = value.as<V>();
20246  return {};
20247  }
20248 
20249  static detail::error_result set_associative(std::false_type, iterator& it, stack_object value) {
20250  decltype(auto) v = *it;
20251  v = value.as<V>();
20252  return {};
20253  }
20254 
20255  static detail::error_result set_writable(std::true_type, lua_State*, T&, iterator& it, stack_object value) {
20256  return set_associative(is_associative(), it, std::move(value));
20257  }
20258 
20260  return detail::error_result(
20261  "cannot perform a 'set': '%s's iterator reference is not writable (non-copy-assignable or const)", detail::demangle<T>().data());
20262  }
20263 
20264  static detail::error_result set_category(std::input_iterator_tag, lua_State* L, T& self, stack_object okey, stack_object value) {
20265  decltype(auto) key = okey.as<K>();
20266  key += deferred_uc::index_adjustment(L, self);
20267  auto e = deferred_uc::end(L, self);
20268  auto it = deferred_uc::begin(L, self);
20269  auto backit = it;
20270  for (; key > 0 && it != e; --key, ++it) {
20271  backit = it;
20272  }
20273  if (it == e) {
20274  if (key == 0) {
20275  return add_copyable(is_copyable(), L, self, std::move(value), meta::has_insert_after<T>::value ? backit : it);
20276  }
20277  return detail::error_result("out of bounds (too big) for set on '%s'", detail::demangle<T>().c_str());
20278  }
20279  return set_writable(is_writable(), L, self, it, std::move(value));
20280  }
20281 
20282  static detail::error_result set_category(std::random_access_iterator_tag, lua_State* L, T& self, stack_object okey, stack_object value) {
20283  decltype(auto) key = okey.as<K>();
20284  key += deferred_uc::index_adjustment(L, self);
20285  if (key < 0) {
20286  return detail::error_result("sol: out of bounds (too small) for set on '%s'", detail::demangle<T>().c_str());
20287  }
20288  std::ptrdiff_t len = static_cast<std::ptrdiff_t>(size_start(L, self));
20289  if (key == len) {
20290  return add_copyable(is_copyable(), L, self, std::move(value));
20291  }
20292  else if (key >= len) {
20293  return detail::error_result("sol: out of bounds (too big) for set on '%s'", detail::demangle<T>().c_str());
20294  }
20295  auto it = std::next(deferred_uc::begin(L, self), key);
20296  return set_writable(is_writable(), L, self, it, std::move(value));
20297  }
20298 
20299  static detail::error_result set_comparative(std::true_type, lua_State* L, T& self, stack_object okey, stack_object value) {
20300  decltype(auto) key = okey.as<K>();
20301  if (!is_writable::value) {
20302  return detail::error_result(
20303  "cannot perform a 'set': '%s's iterator reference is not writable (non-copy-assignable or const)", detail::demangle<T>().data());
20304  }
20305  auto fx = [&](const value_type& r) -> bool { return key == get_key(is_associative(), r); };
20306  auto e = deferred_uc::end(L, self);
20307  auto it = std::find_if(deferred_uc::begin(L, self), e, std::ref(fx));
20308  if (it == e) {
20309  return {};
20310  }
20311  return set_writable(is_writable(), L, self, it, std::move(value));
20312  }
20313 
20315  return detail::error_result("cannot set this value on '%s': no suitable way to increment iterator or compare to '%s' key",
20316  detail::demangle<T>().data(),
20317  detail::demangle<K>().data());
20318  }
20319 
20320  template <typename Iter>
20321  static detail::error_result set_associative_insert(std::true_type, lua_State*, T& self, Iter& it, K& key, stack_object value) {
20322  if constexpr (meta::has_insert<T>::value) {
20323  self.insert(it, value_type(key, value.as<V>()));
20324  return {};
20325  }
20326  else {
20327  (void)self;
20328  (void)it;
20329  (void)key;
20330  return detail::error_result(
20331  "cannot call 'set' on '%s': there is no 'insert' function on this associative type", detail::demangle<T>().c_str());
20332  }
20333  }
20334 
20335  template <typename Iter>
20336  static detail::error_result set_associative_insert(std::false_type, lua_State*, T& self, Iter& it, K& key, stack_object) {
20337  if constexpr (meta::has_insert<T>::value) {
20338  self.insert(it, key);
20339  return {};
20340  }
20341  else {
20342  (void)self;
20343  (void)it;
20344  (void)key;
20345  return detail::error_result(
20346  "cannot call 'set' on '%s': there is no 'insert' function on this non-associative type", detail::demangle<T>().c_str());
20347  }
20348  }
20349 
20350  static detail::error_result set_associative_find(std::true_type, lua_State* L, T& self, stack_object okey, stack_object value) {
20351  decltype(auto) key = okey.as<K>();
20352  auto it = self.find(key);
20353  if (it == deferred_uc::end(L, self)) {
20354  return set_associative_insert(is_associative(), L, self, it, key, std::move(value));
20355  }
20356  return set_writable(is_writable(), L, self, it, std::move(value));
20357  }
20358 
20359  static detail::error_result set_associative_find(std::false_type, lua_State* L, T& self, stack_object key, stack_object value) {
20360  return set_comparative(meta::supports_op_equal<K, key_type>(), L, self, std::move(key), std::move(value));
20361  }
20362 
20363  static detail::error_result set_it(std::true_type, lua_State* L, T& self, stack_object key, stack_object value) {
20364  return set_category(iterator_category(), L, self, std::move(key), std::move(value));
20365  }
20366 
20367  static detail::error_result set_it(std::false_type, lua_State* L, T& self, stack_object key, stack_object value) {
20368  return set_associative_find(meta::all<has_find<T>, meta::any<is_associative, is_lookup>>(), L, self, std::move(key), std::move(value));
20369  }
20370 
20371  template <bool idx_of = false>
20372  static detail::error_result find_has_associative_lookup(std::true_type, lua_State* L, T& self) {
20373  if constexpr (!is_ordered::value && idx_of) {
20374  (void)L;
20375  (void)self;
20376  return detail::error_result("cannot perform an 'index_of': '%s's is not an ordered container", detail::demangle<T>().data());
20377  }
20378  else {
20379  decltype(auto) key = stack::unqualified_get<K>(L, 2);
20380  auto it = self.find(key);
20381  if (it == deferred_uc::end(L, self)) {
20382  return stack::push(L, lua_nil);
20383  }
20384  if constexpr (idx_of) {
20385  auto dist = std::distance(deferred_uc::begin(L, self), it);
20386  dist -= deferred_uc::index_adjustment(L, self);
20387  return stack::push(L, dist);
20388  }
20389  else {
20390  return get_associative(is_associative(), L, it);
20391  }
20392  }
20393  }
20394 
20395  template <bool idx_of = false>
20396  static detail::error_result find_has_associative_lookup(std::false_type, lua_State* L, T& self) {
20397  if constexpr (!is_ordered::value && idx_of) {
20398  (void)L;
20399  (void)self;
20400  return detail::error_result("cannot perform an 'index_of': '%s's is not an ordered container", detail::demangle<T>().data());
20401  }
20402  else {
20403  decltype(auto) value = stack::unqualified_get<V>(L, 2);
20404  auto it = self.find(value);
20405  if (it == deferred_uc::end(L, self)) {
20406  return stack::push(L, lua_nil);
20407  }
20408  if constexpr (idx_of) {
20409  auto dist = std::distance(deferred_uc::begin(L, self), it);
20410  dist -= deferred_uc::index_adjustment(L, self);
20411  return stack::push(L, dist);
20412  }
20413  else {
20414  return get_associative(is_associative(), L, it);
20415  }
20416  }
20417  }
20418 
20419  template <bool idx_of = false>
20420  static detail::error_result find_has(std::true_type, lua_State* L, T& self) {
20421  return find_has_associative_lookup<idx_of>(meta::any<is_lookup, is_associative>(), L, self);
20422  }
20423 
20424  template <typename Iter>
20425  static detail::error_result find_associative_lookup(std::true_type, lua_State* L, T&, Iter& it, std::size_t) {
20426  return get_associative(is_associative(), L, it);
20427  }
20428 
20429  template <typename Iter>
20430  static detail::error_result find_associative_lookup(std::false_type, lua_State* L, T& self, Iter&, std::size_t idx) {
20431  idx -= deferred_uc::index_adjustment(L, self);
20432  return stack::push(L, idx);
20433  }
20434 
20435  template <bool = false>
20436  static detail::error_result find_comparative(std::false_type, lua_State*, T&) {
20437  return detail::error_result("cannot call 'find' on '%s': there is no 'find' function and the value_type is not equality comparable",
20438  detail::demangle<T>().c_str());
20439  }
20440 
20441  template <bool idx_of = false>
20442  static detail::error_result find_comparative(std::true_type, lua_State* L, T& self) {
20443  decltype(auto) value = stack::unqualified_get<V>(L, 2);
20444  auto it = deferred_uc::begin(L, self);
20445  auto e = deferred_uc::end(L, self);
20446  std::size_t idx = 0;
20447  for (;; ++it, ++idx) {
20448  if (it == e) {
20449  return stack::push(L, lua_nil);
20450  }
20451  if (value == get_value(is_associative(), *it)) {
20452  break;
20453  }
20454  }
20455  return find_associative_lookup(meta::all<meta::boolean<!idx_of>, meta::any<is_lookup, is_associative>>(), L, self, it, idx);
20456  }
20457 
20458  template <bool idx_of = false>
20459  static detail::error_result find_has(std::false_type, lua_State* L, T& self) {
20460  return find_comparative<idx_of>(meta::supports_op_equal<V>(), L, self);
20461  }
20462 
20463  template <typename Iter>
20464  static detail::error_result add_insert_after(std::false_type, lua_State* L, T& self, stack_object value, Iter&) {
20465  return add_insert_after(std::false_type(), L, self, value);
20466  }
20467 
20469  return detail::error_result("cannot call 'add' on type '%s': no suitable insert/push_back C++ functions", detail::demangle<T>().data());
20470  }
20471 
20472  template <typename Iter>
20473  static detail::error_result add_insert_after(std::true_type, lua_State*, T& self, stack_object value, Iter& pos) {
20474  self.insert_after(pos, value.as<V>());
20475  return {};
20476  }
20477 
20478  static detail::error_result add_insert_after(std::true_type, lua_State* L, T& self, stack_object value) {
20479  auto backit = self.before_begin();
20480  {
20481  auto e = deferred_uc::end(L, self);
20482  for (auto it = deferred_uc::begin(L, self); it != e; ++backit, ++it) {
20483  }
20484  }
20485  return add_insert_after(std::true_type(), L, self, value, backit);
20486  }
20487 
20488  template <typename Iter>
20489  static detail::error_result add_insert(std::true_type, lua_State*, T& self, stack_object value, Iter& pos) {
20490  self.insert(pos, value.as<V>());
20491  return {};
20492  }
20493 
20494  static detail::error_result add_insert(std::true_type, lua_State* L, T& self, stack_object value) {
20495  auto pos = deferred_uc::end(L, self);
20496  return add_insert(std::true_type(), L, self, value, pos);
20497  }
20498 
20499  template <typename Iter>
20500  static detail::error_result add_insert(std::false_type, lua_State* L, T& self, stack_object value, Iter& pos) {
20501  return add_insert_after(meta::has_insert_after<T>(), L, self, std::move(value), pos);
20502  }
20503 
20504  static detail::error_result add_insert(std::false_type, lua_State* L, T& self, stack_object value) {
20505  return add_insert_after(meta::has_insert_after<T>(), L, self, std::move(value));
20506  }
20507 
20508  template <typename Iter>
20509  static detail::error_result add_push_back(std::true_type, lua_State*, T& self, stack_object value, Iter&) {
20510  self.push_back(value.as<V>());
20511  return {};
20512  }
20513 
20514  static detail::error_result add_push_back(std::true_type, lua_State*, T& self, stack_object value) {
20515  self.push_back(value.as<V>());
20516  return {};
20517  }
20518 
20519  template <typename Iter>
20520  static detail::error_result add_push_back(std::false_type, lua_State* L, T& self, stack_object value, Iter& pos) {
20521  return add_insert(meta::has_insert<T>(), L, self, value, pos);
20522  }
20523 
20524  static detail::error_result add_push_back(std::false_type, lua_State* L, T& self, stack_object value) {
20525  return add_insert(meta::has_insert<T>(), L, self, value);
20526  }
20527 
20528  template <typename Iter>
20529  static detail::error_result add_associative(std::true_type, lua_State* L, T& self, stack_object key, Iter& pos) {
20530  if constexpr (meta::has_insert<T>::value) {
20531  self.insert(pos, value_type(key.as<K>(), stack::unqualified_get<V>(L, 3)));
20532  return {};
20533  }
20534  else {
20535  (void)L;
20536  (void)self;
20537  (void)key;
20538  (void)pos;
20539  return detail::error_result(
20540  "cannot call 'insert' on '%s': there is no 'insert' function on this associative type", detail::demangle<T>().c_str());
20541  }
20542  }
20543 
20544  static detail::error_result add_associative(std::true_type, lua_State* L, T& self, stack_object key) {
20545  auto pos = deferred_uc::end(L, self);
20546  return add_associative(std::true_type(), L, self, std::move(key), pos);
20547  }
20548 
20549  template <typename Iter>
20550  static detail::error_result add_associative(std::false_type, lua_State* L, T& self, stack_object value, Iter& pos) {
20551  return add_push_back(meta::has_push_back<T>(), L, self, value, pos);
20552  }
20553 
20554  static detail::error_result add_associative(std::false_type, lua_State* L, T& self, stack_object value) {
20555  return add_push_back(meta::has_push_back<T>(), L, self, value);
20556  }
20557 
20558  template <typename Iter>
20559  static detail::error_result add_copyable(std::true_type, lua_State* L, T& self, stack_object value, Iter& pos) {
20560  return add_associative(is_associative(), L, self, std::move(value), pos);
20561  }
20562 
20563  static detail::error_result add_copyable(std::true_type, lua_State* L, T& self, stack_object value) {
20564  return add_associative(is_associative(), L, self, value);
20565  }
20566 
20567  template <typename Iter>
20568  static detail::error_result add_copyable(std::false_type, lua_State* L, T& self, stack_object value, Iter&) {
20569  return add_copyable(std::false_type(), L, self, std::move(value));
20570  }
20571 
20572  static detail::error_result add_copyable(std::false_type, lua_State*, T&, stack_object) {
20573  return detail::error_result("cannot call 'add' on '%s': value_type is non-copyable", detail::demangle<T>().data());
20574  }
20575 
20576  static detail::error_result insert_lookup(std::true_type, lua_State* L, T& self, stack_object, stack_object value) {
20577  // TODO: should we warn or error about someone calling insert on an ordered / lookup container with no associativity?
20578  return add_copyable(std::true_type(), L, self, std::move(value));
20579  }
20580 
20581  static detail::error_result insert_lookup(std::false_type, lua_State* L, T& self, stack_object where, stack_object value) {
20582  auto it = deferred_uc::begin(L, self);
20583  auto key = where.as<K>();
20584  key += deferred_uc::index_adjustment(L, self);
20585  std::advance(it, key);
20586  self.insert(it, value.as<V>());
20587  return {};
20588  }
20589 
20590  static detail::error_result insert_after_has(std::true_type, lua_State* L, T& self, stack_object where, stack_object value) {
20591  auto key = where.as<K>();
20592  auto backit = self.before_begin();
20593  {
20594  key += deferred_uc::index_adjustment(L, self);
20595  auto e = deferred_uc::end(L, self);
20596  for (auto it = deferred_uc::begin(L, self); key > 0; ++backit, ++it, --key) {
20597  if (backit == e) {
20598  return detail::error_result("sol: out of bounds (too big) for set on '%s'", detail::demangle<T>().c_str());
20599  }
20600  }
20601  }
20602  self.insert_after(backit, value.as<V>());
20603  return {};
20604  }
20605 
20607  return detail::error_result(
20608  "cannot call 'insert' on '%s': no suitable or similar functionality detected on this container", detail::demangle<T>().data());
20609  }
20610 
20611  static detail::error_result insert_has(std::true_type, lua_State* L, T& self, stack_object key, stack_object value) {
20612  return insert_lookup(meta::any<is_associative, is_lookup>(), L, self, std::move(key), std::move(value));
20613  }
20614 
20615  static detail::error_result insert_has(std::false_type, lua_State* L, T& self, stack_object where, stack_object value) {
20616  return insert_after_has(meta::has_insert_after<T>(), L, self, where, value);
20617  }
20618 
20619  static detail::error_result insert_copyable(std::true_type, lua_State* L, T& self, stack_object key, stack_object value) {
20620  return insert_has(meta::has_insert<T>(), L, self, std::move(key), std::move(value));
20621  }
20622 
20624  return detail::error_result("cannot call 'insert' on '%s': value_type is non-copyable", detail::demangle<T>().data());
20625  }
20626 
20627  static detail::error_result erase_integral(std::true_type, lua_State* L, T& self, K& key) {
20628  auto it = deferred_uc::begin(L, self);
20629  key += deferred_uc::index_adjustment(L, self);
20630  std::advance(it, key);
20631  self.erase(it);
20632 
20633  return {};
20634  }
20635 
20636  static detail::error_result erase_integral(std::false_type, lua_State* L, T& self, const K& key) {
20637  auto fx = [&](const value_type& r) -> bool { return key == r; };
20638  auto e = deferred_uc::end(L, self);
20639  auto it = std::find_if(deferred_uc::begin(L, self), e, std::ref(fx));
20640  if (it == e) {
20641  return {};
20642  }
20643  self.erase(it);
20644 
20645  return {};
20646  }
20647 
20648  static detail::error_result erase_associative_lookup(std::true_type, lua_State*, T& self, const K& key) {
20649  self.erase(key);
20650  return {};
20651  }
20652 
20653  static detail::error_result erase_associative_lookup(std::false_type, lua_State* L, T& self, K& key) {
20654  return erase_integral(std::is_integral<K>(), L, self, key);
20655  }
20656 
20657  static detail::error_result erase_after_has(std::true_type, lua_State* L, T& self, K& key) {
20658  auto backit = self.before_begin();
20659  {
20660  key += deferred_uc::index_adjustment(L, self);
20661  auto e = deferred_uc::end(L, self);
20662  for (auto it = deferred_uc::begin(L, self); key > 0; ++backit, ++it, --key) {
20663  if (backit == e) {
20664  return detail::error_result("sol: out of bounds for erase on '%s'", detail::demangle<T>().c_str());
20665  }
20666  }
20667  }
20668  self.erase_after(backit);
20669  return {};
20670  }
20671 
20672  static detail::error_result erase_after_has(std::false_type, lua_State*, T&, const K&) {
20673  return detail::error_result("sol: cannot call erase on '%s'", detail::demangle<T>().c_str());
20674  }
20675 
20676  static detail::error_result erase_key_has(std::true_type, lua_State* L, T& self, K& key) {
20677  return erase_associative_lookup(meta::any<is_associative, is_lookup>(), L, self, key);
20678  }
20679 
20680  static detail::error_result erase_key_has(std::false_type, lua_State* L, T& self, K& key) {
20681  return erase_after_has(has_erase_after<T>(), L, self, key);
20682  }
20683 
20684  static detail::error_result erase_has(std::true_type, lua_State* L, T& self, K& key) {
20685  return erase_associative_lookup(meta::any<is_associative, is_lookup>(), L, self, key);
20686  }
20687 
20688  static detail::error_result erase_has(std::false_type, lua_State* L, T& self, K& key) {
20689  return erase_key_has(has_erase_key<T>(), L, self, key);
20690  }
20691 
20692  static auto size_has(std::false_type, lua_State* L, T& self) {
20693  return std::distance(deferred_uc::begin(L, self), deferred_uc::end(L, self));
20694  }
20695 
20696  static auto size_has(std::true_type, lua_State*, T& self) {
20697  return self.size();
20698  }
20699 
20700  static void clear_has(std::true_type, lua_State*, T& self) {
20701  self.clear();
20702  }
20703 
20704  static void clear_has(std::false_type, lua_State* L, T&) {
20705  luaL_error(L, "sol: cannot call clear on '%s'", detail::demangle<T>().c_str());
20706  }
20707 
20708  static bool empty_has(std::true_type, lua_State*, T& self) {
20709  return self.empty();
20710  }
20711 
20712  static bool empty_has(std::false_type, lua_State* L, T& self) {
20713  return deferred_uc::begin(L, self) == deferred_uc::end(L, self);
20714  }
20715 
20716  static detail::error_result get_associative_find(std::true_type, lua_State* L, T& self, K& key) {
20717  auto it = self.find(key);
20718  if (it == deferred_uc::end(L, self)) {
20719  stack::push(L, lua_nil);
20720  return {};
20721  }
20722  return get_associative(std::true_type(), L, it);
20723  }
20724 
20725  static detail::error_result get_associative_find(std::false_type, lua_State* L, T& self, K& key) {
20726  return get_it(is_linear_integral(), L, self, key);
20727  }
20728 
20729  static detail::error_result get_start(lua_State* L, T& self, K& key) {
20730  return get_associative_find(std::integral_constant < bool, is_associative::value&& has_find<T>::value > (), L, self, key);
20731  }
20732 
20734  return set_it(is_linear_integral(), L, self, std::move(key), std::move(value));
20735  }
20736 
20737  static std::size_t size_start(lua_State* L, T& self) {
20738  return size_has(meta::has_size<T>(), L, self);
20739  }
20740 
20741  static void clear_start(lua_State* L, T& self) {
20742  clear_has(has_clear<T>(), L, self);
20743  }
20744 
20745  static bool empty_start(lua_State* L, T& self) {
20746  return empty_has(has_empty<T>(), L, self);
20747  }
20748 
20749  static detail::error_result erase_start(lua_State* L, T& self, K& key) {
20750  return erase_has(has_erase<T>(), L, self, key);
20751  }
20752 
20753  template <bool ip>
20754  static int next_associative(std::true_type, lua_State* L) {
20755  iter& i = stack::unqualified_get<user<iter>>(L, 1);
20756  auto& source = i.source;
20757  auto& it = i.it;
20758  if (it == deferred_uc::end(L, source)) {
20759  return stack::push(L, lua_nil);
20760  }
20761  int p;
20762  if constexpr (ip) {
20763  ++i.i;
20764  p = stack::push_reference(L, i.i);
20765  }
20766  else {
20767  p = stack::push_reference(L, it->first);
20768  }
20769  p += stack::stack_detail::push_reference<push_type>(L, detail::deref_move_only(it->second));
20770  std::advance(it, 1);
20771  return p;
20772  }
20773 
20774  template <bool>
20775  static int next_associative(std::false_type, lua_State* L) {
20776  iter& i = stack::unqualified_get<user<iter>>(L, 1);
20777  auto& source = i.source;
20778  auto& it = i.it;
20779  next_K k = stack::unqualified_get<next_K>(L, 2);
20780  if (it == deferred_uc::end(L, source)) {
20781  return stack::push(L, lua_nil);
20782  }
20783  int p;
20784  if constexpr (std::is_integral_v<next_K>) {
20785  p = stack::push_reference(L, k + 1);
20786  }
20787  else {
20789  }
20790  p += stack::stack_detail::push_reference<push_type>(L, detail::deref_move_only(*it));
20791  std::advance(it, 1);
20792  return p;
20793  }
20794 
20795  template <bool ip>
20796  static int next_iter(lua_State* L) {
20798  return next_associative<ip>(is_assoc(), L);
20799  }
20800 
20801  template <bool ip>
20802  static int pairs_associative(std::true_type, lua_State* L) {
20803  auto& src = get_src(L);
20804  stack::push(L, next_iter<ip>);
20805  stack::push<user<iter>>(L, src, deferred_uc::begin(L, src));
20806  stack::push(L, lua_nil);
20807  return 3;
20808  }
20809 
20810  template <bool ip>
20811  static int pairs_associative(std::false_type, lua_State* L) {
20812  auto& src = get_src(L);
20813  stack::push(L, next_iter<ip>);
20814  stack::push<user<iter>>(L, src, deferred_uc::begin(L, src));
20815  stack::push(L, 0);
20816  return 3;
20817  }
20818 
20819  public:
20820  static int at(lua_State* L) {
20821  auto& self = get_src(L);
20823  {
20824  std::ptrdiff_t pos = stack::unqualified_get<std::ptrdiff_t>(L, 2);
20825  er = at_start(L, self, pos);
20826  }
20827  return handle_errors(L, er);
20828  }
20829 
20830  static int get(lua_State* L) {
20831  auto& self = get_src(L);
20833  {
20834  decltype(auto) key = stack::unqualified_get<K>(L);
20835  er = get_start(L, self, key);
20836  }
20837  return handle_errors(L, er);
20838  }
20839 
20840  static int index_get(lua_State* L) {
20841  return get(L);
20842  }
20843 
20844  static int set(lua_State* L) {
20846  if constexpr (is_linear_integral::value) {
20847  // for non-associative containers,
20848  // erasure only happens if it is the
20849  // last index in the container
20850  auto key = stack::get<K>(L, 2);
20851  auto self_size = deferred_uc::size(L);
20852  if (key == static_cast<K>(self_size)) {
20853  if (type_of(L, 3) == type::lua_nil) {
20854  return erase(L);
20855  }
20856  }
20857  }
20858  else {
20859  if (type_of(L, 3) == type::lua_nil) {
20860  return erase(L);
20861  }
20862  }
20863  auto& self = get_src(L);
20864  detail::error_result er = set_start(L, self, stack_object(L, raw_index(2)), std::move(value));
20865  return handle_errors(L, er);
20866  }
20867 
20868  static int index_set(lua_State* L) {
20869  return set(L);
20870  }
20871 
20872  static int add(lua_State* L) {
20873  auto& self = get_src(L);
20874  detail::error_result er = add_copyable(is_copyable(), L, self, stack_object(L, raw_index(2)));
20875  return handle_errors(L, er);
20876  }
20877 
20878  static int insert(lua_State* L) {
20879  auto& self = get_src(L);
20880  detail::error_result er = insert_copyable(is_copyable(), L, self, stack_object(L, raw_index(2)), stack_object(L, raw_index(3)));
20881  return handle_errors(L, er);
20882  }
20883 
20884  static int find(lua_State* L) {
20885  auto& self = get_src(L);
20886  detail::error_result er = find_has(has_find<T>(), L, self);
20887  return handle_errors(L, er);
20888  }
20889 
20890  static int index_of(lua_State* L) {
20891  auto& self = get_src(L);
20892  detail::error_result er = find_has<true>(has_find<T>(), L, self);
20893  return handle_errors(L, er);
20894  }
20895 
20896  static iterator begin(lua_State*, T& self) {
20897  if constexpr (meta::has_begin_end_v<T>) {
20898  return self.begin();
20899  }
20900  else {
20901  using std::begin;
20902  return begin(self);
20903  }
20904  }
20905 
20906  static iterator end(lua_State*, T& self) {
20907  if constexpr (meta::has_begin_end_v<T>) {
20908  return self.end();
20909  }
20910  else {
20911  using std::end;
20912  return end(self);
20913  }
20914  }
20915 
20916  static int size(lua_State* L) {
20917  auto& self = get_src(L);
20918  std::size_t r = size_start(L, self);
20919  return stack::push(L, r);
20920  }
20921 
20922  static int clear(lua_State* L) {
20923  auto& self = get_src(L);
20924  clear_start(L, self);
20925  return 0;
20926  }
20927 
20928  static int erase(lua_State* L) {
20929  auto& self = get_src(L);
20931  {
20932  decltype(auto) key = stack::unqualified_get<K>(L, 2);
20933  er = erase_start(L, self, key);
20934  }
20935  return handle_errors(L, er);
20936  }
20937 
20938  static int empty(lua_State* L) {
20939  auto& self = get_src(L);
20940  return stack::push(L, empty_start(L, self));
20941  }
20942 
20943  static std::ptrdiff_t index_adjustment(lua_State*, T&) {
20944  return static_cast<std::ptrdiff_t>((SOL_CONTAINER_START_INDEX_I_) == 0 ? 0 : -(SOL_CONTAINER_START_INDEX_I_));
20945  }
20946 
20947  static int pairs(lua_State* L) {
20949  return pairs_associative<false>(is_assoc(), L);
20950  }
20951 
20952  static int ipairs(lua_State* L) {
20954  return pairs_associative<true>(is_assoc(), L);
20955  }
20956 
20957  static int next(lua_State* L) {
20958  return stack::push(L, next_iter<false>);
20959  }
20960  };
20961 
20962  template <typename X>
20963  struct usertype_container_default<X, std::enable_if_t<std::is_array<std::remove_pointer_t<meta::unwrap_unqualified_t<X>>>::value>> {
20964  private:
20965  typedef std::remove_pointer_t<meta::unwrap_unqualified_t<X>> T;
20967 
20968  public:
20969  typedef std::remove_extent_t<T> value_type;
20970  typedef value_type* iterator;
20971 
20972  private:
20973  struct iter {
20975  iterator it;
20976 
20977  iter(T& source, iterator it) : source(source), it(std::move(it)) {
20978  }
20979  };
20980 
20981  static auto& get_src(lua_State* L) {
20982  auto p = stack::unqualified_check_get<T*>(L, 1);
20983 #if SOL_IS_ON(SOL_SAFE_USERTYPE_I_)
20984  if (!p) {
20985  luaL_error(L,
20986  "sol: 'self' is not of type '%s' (pass 'self' as first argument with ':' or call on proper type)",
20987  detail::demangle<T>().c_str());
20988  }
20989  if (p.value() == nullptr) {
20990  luaL_error(
20991  L, "sol: 'self' argument is nil (pass 'self' as first argument with ':' or call on a '%s' type)", detail::demangle<T>().c_str());
20992  }
20993 #endif // Safe getting with error
20994  return *p.value();
20995  }
20996 
20997  static int find(std::true_type, lua_State* L) {
20998  T& self = get_src(L);
20999  decltype(auto) value = stack::unqualified_get<value_type>(L, 2);
21000  std::size_t N = std::extent<T>::value;
21001  for (std::size_t idx = 0; idx < N; ++idx) {
21002  using v_t = std::add_const_t<decltype(self[idx])>;
21003  v_t v = self[idx];
21004  if (v == value) {
21005  idx -= deferred_uc::index_adjustment(L, self);
21006  return stack::push(L, idx);
21007  }
21008  }
21009  return stack::push(L, lua_nil);
21010  }
21011 
21012  static int find(std::false_type, lua_State* L) {
21013  return luaL_error(L, "sol: cannot call 'find' on '%s': no supported comparison operator for the value type", detail::demangle<T>().c_str());
21014  }
21015 
21016  static int next_iter(lua_State* L) {
21017  iter& i = stack::unqualified_get<user<iter>>(L, 1);
21018  auto& source = i.source;
21019  auto& it = i.it;
21020  std::size_t k = stack::unqualified_get<std::size_t>(L, 2);
21021  if (it == deferred_uc::end(L, source)) {
21022  return 0;
21023  }
21024  int p;
21025  p = stack::push(L, k + 1);
21027  std::advance(it, 1);
21028  return p;
21029  }
21030 
21031  public:
21032  static int clear(lua_State* L) {
21033  return luaL_error(L, "sol: cannot call 'clear' on type '%s': cannot remove all items from a fixed array", detail::demangle<T>().c_str());
21034  }
21035 
21036  static int erase(lua_State* L) {
21037  return luaL_error(L, "sol: cannot call 'erase' on type '%s': cannot remove an item from fixed arrays", detail::demangle<T>().c_str());
21038  }
21039 
21040  static int add(lua_State* L) {
21041  return luaL_error(L, "sol: cannot call 'add' on type '%s': cannot add to fixed arrays", detail::demangle<T>().c_str());
21042  }
21043 
21044  static int insert(lua_State* L) {
21045  return luaL_error(L, "sol: cannot call 'insert' on type '%s': cannot insert new entries into fixed arrays", detail::demangle<T>().c_str());
21046  }
21047 
21048  static int at(lua_State* L) {
21049  return get(L);
21050  }
21051 
21052  static int get(lua_State* L) {
21053  T& self = get_src(L);
21054  std::ptrdiff_t idx = stack::unqualified_get<std::ptrdiff_t>(L, 2);
21055  idx += deferred_uc::index_adjustment(L, self);
21056  if (idx >= static_cast<std::ptrdiff_t>(std::extent<T>::value) || idx < 0) {
21057  return stack::push(L, lua_nil);
21058  }
21059  return stack::push_reference(L, detail::deref_move_only(self[idx]));
21060  }
21061 
21062  static int index_get(lua_State* L) {
21063  return get(L);
21064  }
21065 
21066  static int set(lua_State* L) {
21067  T& self = get_src(L);
21068  std::ptrdiff_t idx = stack::unqualified_get<std::ptrdiff_t>(L, 2);
21069  idx += deferred_uc::index_adjustment(L, self);
21070  if (idx >= static_cast<std::ptrdiff_t>(std::extent<T>::value)) {
21071  return luaL_error(L, "sol: index out of bounds (too big) for set on '%s'", detail::demangle<T>().c_str());
21072  }
21073  if (idx < 0) {
21074  return luaL_error(L, "sol: index out of bounds (too small) for set on '%s'", detail::demangle<T>().c_str());
21075  }
21076  self[idx] = stack::unqualified_get<value_type>(L, 3);
21077  return 0;
21078  }
21079 
21080  static int index_set(lua_State* L) {
21081  return set(L);
21082  }
21083 
21084  static int index_of(lua_State* L) {
21085  return find(L);
21086  }
21087 
21088  static int find(lua_State* L) {
21090  }
21091 
21092  static int size(lua_State* L) {
21094  }
21095 
21096  static int empty(lua_State* L) {
21097  return stack::push(L, std::extent<T>::value > 0);
21098  }
21099 
21100  static int pairs(lua_State* L) {
21101  auto& src = get_src(L);
21102  stack::push(L, next_iter);
21103  stack::push<user<iter>>(L, src, deferred_uc::begin(L, src));
21104  stack::push(L, 0);
21105  return 3;
21106  }
21107 
21108  static int ipairs(lua_State* L) {
21109  return pairs(L);
21110  }
21111 
21112  static int next(lua_State* L) {
21113  return stack::push(L, next_iter);
21114  }
21115 
21116  static std::ptrdiff_t index_adjustment(lua_State*, T&) {
21118  }
21119 
21120  static iterator begin(lua_State*, T& self) {
21121  return std::addressof(self[0]);
21122  }
21123 
21124  static iterator end(lua_State*, T& self) {
21125  return std::addressof(self[0]) + std::extent<T>::value;
21126  }
21127  };
21128 
21129  template <typename X>
21131  } // namespace container_detail
21132 
21133  template <typename T>
21135 
21136 } // namespace sol
21137 
21138 // end of sol/usertype_container.hpp
21139 
21140 #include <unordered_map>
21141 
21142 namespace sol {
21143 
21144  namespace container_detail {
21145  template <typename X>
21146  struct u_c_launch {
21147  using T = std::remove_pointer_t<meta::unqualified_t<X>>;
21150 
21151  static inline int real_index_get_traits(std::true_type, lua_State* L) {
21152  return uc::index_get(L);
21153  }
21154 
21155  static inline int real_index_get_traits(std::false_type, lua_State* L) {
21156  return default_uc::index_get(L);
21157  }
21158 
21159  static inline int real_index_call(lua_State* L) {
21160  static const std::unordered_map<string_view, lua_CFunction> calls {
21161  { "at", &real_at_call },
21162  { "get", &real_get_call },
21163  { "set", &real_set_call },
21164  { "size", &real_length_call },
21165  { "add", &real_add_call },
21166  { "empty", &real_empty_call },
21167  { "insert", &real_insert_call },
21168  { "clear", &real_clear_call },
21169  { "find", &real_find_call },
21170  { "index_of", &real_index_of_call },
21171  { "erase", &real_erase_call },
21172  { "pairs", &pairs_call },
21173  { "next", &next_call },
21174  };
21175  auto maybenameview = stack::unqualified_check_get<string_view>(L, 2);
21176  if (maybenameview) {
21177  const string_view& name = *maybenameview;
21178  auto it = calls.find(name);
21179  if (it != calls.cend()) {
21180  return stack::push(L, it->second);
21181  }
21182  }
21183  return real_index_get_traits(container_detail::has_traits_index_get<uc>(), L);
21184  }
21185 
21186  static inline int real_at_traits(std::true_type, lua_State* L) {
21187  return uc::at(L);
21188  }
21189 
21190  static inline int real_at_traits(std::false_type, lua_State* L) {
21191  return default_uc::at(L);
21192  }
21193 
21194  static inline int real_at_call(lua_State* L) {
21195  return real_at_traits(container_detail::has_traits_at<uc>(), L);
21196  }
21197 
21198  static inline int real_get_traits(std::true_type, lua_State* L) {
21199  return uc::get(L);
21200  }
21201 
21202  static inline int real_get_traits(std::false_type, lua_State* L) {
21203  return default_uc::get(L);
21204  }
21205 
21206  static inline int real_get_call(lua_State* L) {
21207  return real_get_traits(container_detail::has_traits_get<uc>(), L);
21208  }
21209 
21210  static inline int real_set_traits(std::true_type, lua_State* L) {
21211  return uc::set(L);
21212  }
21213 
21214  static inline int real_set_traits(std::false_type, lua_State* L) {
21215  return default_uc::set(L);
21216  }
21217 
21218  static inline int real_set_call(lua_State* L) {
21219  return real_set_traits(container_detail::has_traits_set<uc>(), L);
21220  }
21221 
21222  static inline int real_index_set_traits(std::true_type, lua_State* L) {
21223  return uc::index_set(L);
21224  }
21225 
21226  static inline int real_index_set_traits(std::false_type, lua_State* L) {
21227  return default_uc::index_set(L);
21228  }
21229 
21230  static inline int real_new_index_call(lua_State* L) {
21231  return real_index_set_traits(container_detail::has_traits_index_set<uc>(), L);
21232  }
21233 
21234  static inline int real_pairs_traits(std::true_type, lua_State* L) {
21235  return uc::pairs(L);
21236  }
21237 
21238  static inline int real_pairs_traits(std::false_type, lua_State* L) {
21239  return default_uc::pairs(L);
21240  }
21241 
21242  static inline int real_pairs_call(lua_State* L) {
21243  return real_pairs_traits(container_detail::has_traits_pairs<uc>(), L);
21244  }
21245 
21246  static inline int real_ipairs_traits(std::true_type, lua_State* L) {
21247  return uc::ipairs(L);
21248  }
21249 
21250  static inline int real_ipairs_traits(std::false_type, lua_State* L) {
21251  return default_uc::ipairs(L);
21252  }
21253 
21254  static inline int real_ipairs_call(lua_State* L) {
21255  return real_ipairs_traits(container_detail::has_traits_ipairs<uc>(), L);
21256  }
21257 
21258  static inline int real_next_traits(std::true_type, lua_State* L) {
21259  return uc::next(L);
21260  }
21261 
21262  static inline int real_next_traits(std::false_type, lua_State* L) {
21263  return default_uc::next(L);
21264  }
21265 
21266  static inline int real_next_call(lua_State* L) {
21267  return real_next_traits(container_detail::has_traits_next<uc>(), L);
21268  }
21269 
21270  static inline int real_size_traits(std::true_type, lua_State* L) {
21271  return uc::size(L);
21272  }
21273 
21274  static inline int real_size_traits(std::false_type, lua_State* L) {
21275  return default_uc::size(L);
21276  }
21277 
21278  static inline int real_length_call(lua_State* L) {
21279  return real_size_traits(container_detail::has_traits_size<uc>(), L);
21280  }
21281 
21282  static inline int real_add_traits(std::true_type, lua_State* L) {
21283  return uc::add(L);
21284  }
21285 
21286  static inline int real_add_traits(std::false_type, lua_State* L) {
21287  return default_uc::add(L);
21288  }
21289 
21290  static inline int real_add_call(lua_State* L) {
21291  return real_add_traits(container_detail::has_traits_add<uc>(), L);
21292  }
21293 
21294  static inline int real_insert_traits(std::true_type, lua_State* L) {
21295  return uc::insert(L);
21296  }
21297 
21298  static inline int real_insert_traits(std::false_type, lua_State* L) {
21299  return default_uc::insert(L);
21300  }
21301 
21302  static inline int real_insert_call(lua_State* L) {
21303  return real_insert_traits(container_detail::has_traits_insert<uc>(), L);
21304  }
21305 
21306  static inline int real_clear_traits(std::true_type, lua_State* L) {
21307  return uc::clear(L);
21308  }
21309 
21310  static inline int real_clear_traits(std::false_type, lua_State* L) {
21311  return default_uc::clear(L);
21312  }
21313 
21314  static inline int real_clear_call(lua_State* L) {
21315  return real_clear_traits(container_detail::has_traits_clear<uc>(), L);
21316  }
21317 
21318  static inline int real_empty_traits(std::true_type, lua_State* L) {
21319  return uc::empty(L);
21320  }
21321 
21322  static inline int real_empty_traits(std::false_type, lua_State* L) {
21323  return default_uc::empty(L);
21324  }
21325 
21326  static inline int real_empty_call(lua_State* L) {
21327  return real_empty_traits(container_detail::has_traits_empty<uc>(), L);
21328  }
21329 
21330  static inline int real_erase_traits(std::true_type, lua_State* L) {
21331  return uc::erase(L);
21332  }
21333 
21334  static inline int real_erase_traits(std::false_type, lua_State* L) {
21335  return default_uc::erase(L);
21336  }
21337 
21338  static inline int real_erase_call(lua_State* L) {
21339  return real_erase_traits(container_detail::has_traits_erase<uc>(), L);
21340  }
21341 
21342  static inline int real_find_traits(std::true_type, lua_State* L) {
21343  return uc::find(L);
21344  }
21345 
21346  static inline int real_find_traits(std::false_type, lua_State* L) {
21347  return default_uc::find(L);
21348  }
21349 
21350  static inline int real_find_call(lua_State* L) {
21351  return real_find_traits(container_detail::has_traits_find<uc>(), L);
21352  }
21353 
21354  static inline int real_index_of_call(lua_State* L) {
21356  return uc::index_of(L);
21357  }
21358  else {
21359  return default_uc::index_of(L);
21360  }
21361  }
21362 
21363  static inline int add_call(lua_State* L) {
21364  return detail::typed_static_trampoline<decltype(&real_add_call), (&real_add_call)>(L);
21365  }
21366 
21367  static inline int erase_call(lua_State* L) {
21368  return detail::typed_static_trampoline<decltype(&real_erase_call), (&real_erase_call)>(L);
21369  }
21370 
21371  static inline int insert_call(lua_State* L) {
21372  return detail::typed_static_trampoline<decltype(&real_insert_call), (&real_insert_call)>(L);
21373  }
21374 
21375  static inline int clear_call(lua_State* L) {
21376  return detail::typed_static_trampoline<decltype(&real_clear_call), (&real_clear_call)>(L);
21377  }
21378 
21379  static inline int empty_call(lua_State* L) {
21380  return detail::typed_static_trampoline<decltype(&real_empty_call), (&real_empty_call)>(L);
21381  }
21382 
21383  static inline int find_call(lua_State* L) {
21384  return detail::typed_static_trampoline<decltype(&real_find_call), (&real_find_call)>(L);
21385  }
21386 
21387  static inline int index_of_call(lua_State* L) {
21388  return detail::typed_static_trampoline<decltype(&real_index_of_call), (&real_index_of_call)>(L);
21389  }
21390 
21391  static inline int length_call(lua_State* L) {
21392  return detail::typed_static_trampoline<decltype(&real_length_call), (&real_length_call)>(L);
21393  }
21394 
21395  static inline int pairs_call(lua_State* L) {
21396  return detail::typed_static_trampoline<decltype(&real_pairs_call), (&real_pairs_call)>(L);
21397  }
21398 
21399  static inline int ipairs_call(lua_State* L) {
21400  return detail::typed_static_trampoline<decltype(&real_ipairs_call), (&real_ipairs_call)>(L);
21401  }
21402 
21403  static inline int next_call(lua_State* L) {
21404  return detail::typed_static_trampoline<decltype(&real_next_call), (&real_next_call)>(L);
21405  }
21406 
21407  static inline int at_call(lua_State* L) {
21408  return detail::typed_static_trampoline<decltype(&real_at_call), (&real_at_call)>(L);
21409  }
21410 
21411  static inline int get_call(lua_State* L) {
21412  return detail::typed_static_trampoline<decltype(&real_get_call), (&real_get_call)>(L);
21413  }
21414 
21415  static inline int set_call(lua_State* L) {
21416  return detail::typed_static_trampoline<decltype(&real_set_call), (&real_set_call)>(L);
21417  }
21418 
21419  static inline int index_call(lua_State* L) {
21420  return detail::typed_static_trampoline<decltype(&real_index_call), (&real_index_call)>(L);
21421  }
21422 
21423  static inline int new_index_call(lua_State* L) {
21424  return detail::typed_static_trampoline<decltype(&real_new_index_call), (&real_new_index_call)>(L);
21425  }
21426  };
21427  } // namespace container_detail
21428 
21429  namespace stack {
21430  namespace stack_detail {
21431  template <typename T, bool is_shim = false>
21434 
21436  }
21437 
21438  void operator()() {
21439  using meta_usertype_container
21441  static const char* metakey
21443  static const std::array<luaL_Reg, 20> reg = { {
21444  // clang-format off
21445  { "__pairs", &meta_usertype_container::pairs_call },
21446  { "__ipairs", &meta_usertype_container::ipairs_call },
21447  { "__len", &meta_usertype_container::length_call },
21448  { "__index", &meta_usertype_container::index_call },
21449  { "__newindex", &meta_usertype_container::new_index_call },
21450  { "pairs", &meta_usertype_container::pairs_call },
21451  { "next", &meta_usertype_container::next_call },
21452  { "at", &meta_usertype_container::at_call },
21453  { "get", &meta_usertype_container::get_call },
21454  { "set", &meta_usertype_container::set_call },
21455  { "size", &meta_usertype_container::length_call },
21456  { "empty", &meta_usertype_container::empty_call },
21457  { "clear", &meta_usertype_container::clear_call },
21458  { "insert", &meta_usertype_container::insert_call },
21459  { "add", &meta_usertype_container::add_call },
21460  { "find", &meta_usertype_container::find_call },
21461  { "index_of", &meta_usertype_container::index_of_call },
21462  { "erase", &meta_usertype_container::erase_call },
21463  std::is_pointer<T>::value ? luaL_Reg{ nullptr, nullptr } : luaL_Reg{ "__gc", &detail::usertype_alloc_destruct<T> },
21464  { nullptr, nullptr }
21465  // clang-format on
21466  } };
21467 
21468  if (luaL_newmetatable(L, metakey) == 1) {
21469  luaL_setfuncs(L, reg.data(), 0);
21470  }
21471  lua_setmetatable(L, -2);
21472  }
21473  };
21474  } // namespace stack_detail
21475 
21476  template <typename T>
21479 
21480  static int push_lvalue(std::true_type, lua_State* L, const C& cont) {
21482  return stack::push<detail::as_pointer_tag<const C>>(L, detail::with_function_tag(), fx, detail::ptr(cont));
21483  }
21484 
21485  static int push_lvalue(std::false_type, lua_State* L, const C& cont) {
21487  return stack::push<detail::as_value_tag<C>>(L, detail::with_function_tag(), fx, cont);
21488  }
21489 
21490  static int push_rvalue(std::true_type, lua_State* L, C&& cont) {
21492  return stack::push<detail::as_value_tag<C>>(L, detail::with_function_tag(), fx, std::move(cont));
21493  }
21494 
21495  static int push_rvalue(std::false_type, lua_State* L, const C& cont) {
21496  return push_lvalue(std::is_lvalue_reference<T>(), L, cont);
21497  }
21498 
21499  static int push(lua_State* L, const as_container_t<T>& as_cont) {
21500  return push_lvalue(std::is_lvalue_reference<T>(), L, as_cont.value());
21501  }
21502 
21503  static int push(lua_State* L, as_container_t<T>&& as_cont) {
21504  return push_rvalue(meta::all<std::is_rvalue_reference<T>, meta::neg<std::is_lvalue_reference<T>>>(), L, std::forward<T>(as_cont.value()));
21505  }
21506  };
21507 
21508  template <typename T>
21510  using C = std::add_pointer_t<meta::unqualified_t<std::remove_pointer_t<T>>>;
21511 
21512  static int push(lua_State* L, T* cont) {
21514  return stack::push<detail::as_pointer_tag<T>>(L, detail::with_function_tag(), fx, cont);
21515  }
21516  };
21517 
21518  template <typename T>
21519  struct unqualified_pusher<T, std::enable_if_t<is_container_v<T>>> {
21520  using C = T;
21521 
21522  template <typename... Args>
21523  static int push(lua_State* L, Args&&... args) {
21525  return stack::push<detail::as_value_tag<T>>(L, detail::with_function_tag(), fx, std::forward<Args>(args)...);
21526  }
21527  };
21528 
21529  template <typename T>
21530  struct unqualified_pusher<T*, std::enable_if_t<is_container_v<T>>> {
21531  using C = std::add_pointer_t<meta::unqualified_t<std::remove_pointer_t<T>>>;
21532 
21533  static int push(lua_State* L, T* cont) {
21535  return stack::push<detail::as_pointer_tag<T>>(L, detail::with_function_tag(), fx, cont);
21536  }
21537  };
21538  } // namespace stack
21539 
21540 } // namespace sol
21541 
21542 // end of sol/usertype_container_launch.hpp
21543 
21544 #include <sstream>
21545 #include <type_traits>
21546 
21547 namespace sol {
21548  namespace u_detail {
21549  constexpr const lua_Integer toplevel_magic = static_cast<lua_Integer>(0xCCC2CCC1);
21550 
21551  constexpr const int environment_index = 1;
21552  constexpr const int usertype_storage_index = 2;
21553  constexpr const int usertype_storage_base_index = 3;
21554  constexpr const int exact_function_index = 4;
21555  constexpr const int magic_index = 5;
21556 
21557  constexpr const int simple_usertype_storage_index = 2;
21558  constexpr const int index_function_index = 3;
21559  constexpr const int new_index_function_index = 4;
21560 
21561  constexpr const int base_walking_failed_index = -32467;
21562  constexpr const int lookup_failed_index = -42469;
21563 
21564  enum class submetatable_type {
21565  // must be sequential
21566  value,
21567  reference,
21568  unique,
21570  const_value,
21571  // must be LAST!
21572  named
21573  };
21574 
21576  return s;
21577  }
21578 
21581  }
21582 
21584  return string_view(to_string(mf));
21585  }
21586 
21589  }
21590 
21591  template <typename Arg>
21592  inline std::string make_string(Arg&& arg) {
21594  return std::string(s.data(), s.size());
21595  }
21596 
21597  inline int is_indexer(string_view s) {
21598  if (s == to_string(meta_function::index)) {
21599  return 1;
21600  }
21601  else if (s == to_string(meta_function::new_index)) {
21602  return 2;
21603  }
21604  return 0;
21605  }
21606 
21607  inline int is_indexer(meta_function mf) {
21608  if (mf == meta_function::index) {
21609  return 1;
21610  }
21611  else if (mf == meta_function::new_index) {
21612  return 2;
21613  }
21614  return 0;
21615  }
21616 
21618  return 0;
21619  }
21620  } // namespace u_detail
21621 
21622  namespace detail {
21623 
21624  template <typename T, typename IFx, typename Fx>
21625  inline void insert_default_registrations(IFx&& ifx, Fx&& fx) {
21626  (void)ifx;
21627  (void)fx;
21628  if constexpr (is_automagical<T>::value) {
21629  if (fx(meta_function::less_than)) {
21630  if constexpr (meta::supports_op_less<T>::value) {
21631  lua_CFunction f = &comparsion_operator_wrap<T, std::less<>>;
21632  ifx(meta_function::less_than, f);
21633  }
21634  }
21637  lua_CFunction f = &comparsion_operator_wrap<T, std::less_equal<>>;
21639  }
21640  }
21641  if (fx(meta_function::equal_to)) {
21642  if constexpr (meta::supports_op_equal<T>::value) {
21643  lua_CFunction f = &comparsion_operator_wrap<T, std::equal_to<>>;
21644  ifx(meta_function::equal_to, f);
21645  }
21646  else {
21647  lua_CFunction f = &comparsion_operator_wrap<T, no_comp>;
21648  ifx(meta_function::equal_to, f);
21649  }
21650  }
21651  if (fx(meta_function::pairs)) {
21653  }
21654  if (fx(meta_function::length)) {
21656  auto f = &default_size<T>;
21657  ifx(meta_function::length, f);
21658  }
21659  }
21660  if (fx(meta_function::to_string)) {
21661  if constexpr (is_to_stringable<T>::value) {
21662  auto f = &detail::static_trampoline<&default_to_string<T>>;
21663  ifx(meta_function::to_string, f);
21664  }
21665  }
21666  if (fx(meta_function::call_function)) {
21668  auto f = &c_call<decltype(&T::operator()), &T::operator()>;
21670  }
21671  }
21672  }
21673  }
21674  } // namespace detail
21675 
21676  namespace stack { namespace stack_detail {
21677  template <typename X>
21679  using T = std::remove_pointer_t<X>;
21680 
21681  lua_State* L = t.lua_state();
21682 
21683  t.push();
21684 
21686  int index = 0;
21687  detail::indexed_insert insert_fx(l, index);
21688  detail::insert_default_registrations<T>(insert_fx, detail::property_always_true);
21689  if constexpr (!std::is_pointer_v<X>) {
21690  l[index] = luaL_Reg{ to_string(meta_function::garbage_collect).c_str(), detail::make_destructor<T>() };
21691  }
21692  luaL_setfuncs(L, l, 0);
21693 
21694  // __type table
21695  lua_createtable(L, 0, 2);
21696  const std::string& name = detail::demangle<T>();
21697  lua_pushlstring(L, name.c_str(), name.size());
21698  lua_setfield(L, -2, "name");
21699  lua_CFunction is_func = &detail::is_check<T>;
21700  lua_pushcclosure(L, is_func, 0);
21701  lua_setfield(L, -2, "is");
21703 
21704  t.pop();
21705  }
21706  }} // namespace stack::stack_detail
21707 } // namespace sol
21708 
21709 // end of sol/usertype_core.hpp
21710 
21711 // beginning of sol/usertype_storage.hpp
21712 
21713 #include <bitset>
21714 #include <unordered_map>
21715 
21716 namespace sol { namespace u_detail {
21717 
21718  struct usertype_storage_base;
21719  template <typename T>
21721 
21723  usertype_storage_base& get_usertype_storage_base(lua_State* L, const char* gcmetakey);
21724  template <typename T>
21726  template <typename T>
21728 
21729  using index_call_function = int(lua_State*, void*);
21732 
21737  };
21738 
21741  };
21742 
21743  struct binding_base {
21744  virtual void* data() = 0;
21745  virtual ~binding_base() {
21746  }
21747  };
21748 
21749  template <typename K, typename Fq, typename T = void>
21753 #ifdef __cpp_char8_t
21754  || meta::is_c_str_of_v<uF, char8_t>
21755 #endif
21756  || meta::is_c_str_of_v<uF, char16_t> || meta::is_c_str_of_v<uF, char32_t> || meta::is_c_str_of_v<uF, wchar_t>,
21757  std::add_pointer_t<std::add_const_t<std::remove_all_extents_t<Fq>>>, std::decay_t<Fq>>;
21759 
21760  template <typename... Args>
21761  binding(Args&&... args) : data_(std::forward<Args>(args)...) {
21762  }
21763 
21764  virtual void* data() override {
21765  return static_cast<void*>(std::addressof(data_));
21766  }
21767 
21768  template <bool is_index = true, bool is_variable = false>
21769  static inline int call_with_(lua_State* L, void* target) {
21771  auto& f = *static_cast<F*>(target);
21772  return call_detail::call_wrapped<T, is_index, is_variable, boost>(L, f);
21773  }
21774 
21775  template <bool is_index = true, bool is_variable = false>
21776  static inline int call_(lua_State* L) {
21777  void* f = stack::get<void*>(L, upvalue_index(usertype_storage_index));
21778  return call_with_<is_index, is_variable>(L, f);
21779  }
21780 
21781  template <bool is_index = true, bool is_variable = false>
21782  static inline int call(lua_State* L) {
21783  int r = detail::typed_static_trampoline<decltype(&call_<is_index, is_variable>), (&call_<is_index, is_variable>)>(L);
21784  if constexpr (meta::is_specialization_of_v<uF, yielding_t>) {
21785  return lua_yield(L, r);
21786  }
21787  else {
21788  return r;
21789  }
21790  }
21791 
21792  template <bool is_index = true, bool is_variable = false>
21793  static inline int index_call_with_(lua_State* L, void* target) {
21794  if constexpr (!is_variable) {
21795  if constexpr (is_lua_c_function_v<std::decay_t<F>>) {
21796  auto& f = *static_cast<std::decay_t<F>*>(target);
21797  return stack::push(L, f);
21798  }
21799  else {
21800  // set up upvalues
21801  // for a chained call
21802  int upvalues = 0;
21803  upvalues += stack::push(L, nullptr);
21804  upvalues += stack::push(L, target);
21805  auto cfunc = &call<is_index, is_variable>;
21806  return stack::push(L, c_closure(cfunc, upvalues));
21807  }
21808  }
21809  else {
21811  auto& f = *static_cast<F*>(target);
21812  return call_detail::call_wrapped<T, is_index, is_variable, boost>(L, f);
21813  }
21814  }
21815 
21816  template <bool is_index = true, bool is_variable = false>
21817  static inline int index_call_(lua_State* L) {
21818  void* f = stack::get<void*>(L, upvalue_index(usertype_storage_index));
21819  return index_call_with_<is_index, is_variable>(L, f);
21820  }
21821 
21822  template <bool is_index = true, bool is_variable = false>
21823  static inline int index_call(lua_State* L) {
21824  int r = detail::typed_static_trampoline<decltype(&index_call_<is_index, is_variable>), (&index_call_<is_index, is_variable>)>(L);
21825  if constexpr (meta::is_specialization_of_v<uF, yielding_t>) {
21826  return lua_yield(L, r);
21827  }
21828  else {
21829  return r;
21830  }
21831  }
21832  };
21833 
21834  inline int index_fail(lua_State* L) {
21835  if (lua_getmetatable(L, 1) == 1) {
21836  int metatarget = lua_gettop(L);
21837  stack::get_field<false, true>(L, stack_reference(L, raw_index(2)), metatarget);
21838  return 1;
21839  }
21840  // With runtime extensibility, we can't
21841  // hard-error things. They have to
21842  // return nil, like regular table types
21843  return stack::push(L, lua_nil);
21844  }
21845 
21846  inline int index_target_fail(lua_State* L, void*) {
21847  return index_fail(L);
21848  }
21849 
21850  inline int new_index_fail(lua_State* L) {
21851  return luaL_error(L, "sol: cannot set (new_index) into this object: no defined new_index operation on usertype");
21852  }
21853 
21854  inline int new_index_target_fail(lua_State* L, void*) {
21855  return new_index_fail(L);
21856  }
21857 
21859  bool is_destruction = false;
21860  bool is_index = false;
21861  bool is_new_index = false;
21862  bool is_static_index = false;
21863  bool is_static_new_index = false;
21864  bool poison_indexing = false;
21865  bool is_unqualified_lua_CFunction = false;
21866  bool is_unqualified_lua_reference = false;
21867  std::string* p_key = nullptr;
21868  reference* p_binding_ref = nullptr;
21869  lua_CFunction call_func = nullptr;
21870  index_call_storage* p_ics = nullptr;
21871  usertype_storage_base* p_usb = nullptr;
21872  void* p_derived_usb = nullptr;
21873  lua_CFunction idx_call = nullptr, new_idx_call = nullptr, meta_idx_call = nullptr, meta_new_idx_call = nullptr;
21875 
21876  void operator()(lua_State* L, submetatable_type smt, reference& fast_index_table) {
21877  std::string& key = *p_key;
21878  usertype_storage_base& usb = *p_usb;
21879  index_call_storage& ics = *p_ics;
21880 
21881  if (smt == submetatable_type::named) {
21882  // do not override __call or
21883  // other specific meta functions on named metatable:
21884  // we need that for call construction
21885  // and other amenities
21886  return;
21887  }
21888  int fast_index_table_push = fast_index_table.push();
21889  stack_reference t(L, -fast_index_table_push);
21890  if (poison_indexing) {
21891  (usb.*change_indexing)(L, smt, p_derived_usb, t, idx_call, new_idx_call, meta_idx_call, meta_new_idx_call);
21892  }
21893  if (is_destruction
21894  && (smt == submetatable_type::reference || smt == submetatable_type::const_reference || smt == submetatable_type::named
21895  || smt == submetatable_type::unique)) {
21896  // gc does not apply to us here
21897  // for reference types (raw T*, std::ref)
21898  // for the named metatable itself,
21899  // or for unique_usertypes, which do their own custom destruction
21900  t.pop();
21901  return;
21902  }
21903  if (is_index || is_new_index || is_static_index || is_static_new_index) {
21904  // do not serialize the new_index and index functions here directly
21905  // we control those...
21906  t.pop();
21907  return;
21908  }
21909  if (is_unqualified_lua_CFunction) {
21910  stack::set_field<false, true>(L, key, call_func, t.stack_index());
21911  }
21912  else if (is_unqualified_lua_reference) {
21913  reference& binding_ref = *p_binding_ref;
21914  stack::set_field<false, true>(L, key, binding_ref, t.stack_index());
21915  }
21916  else {
21917  stack::set_field<false, true>(L, key, make_closure(call_func, nullptr, ics.binding_data), t.stack_index());
21918  }
21919  t.pop();
21920  }
21921  };
21922 
21926 
21927  void operator()(lua_State* L, submetatable_type smt, reference& fast_index_table) {
21928  if (smt == submetatable_type::named) {
21929  return;
21930  }
21931  int fast_index_table_push = fast_index_table.push();
21932  stack_reference t(L, -fast_index_table_push);
21933  stack::set_field<false, true>(L, key, value, t.stack_index());
21934  t.pop();
21935  }
21936  };
21937 
21941  lua_CFunction idx_call, new_idx_call, meta_idx_call, meta_new_idx_call;
21945 
21946  void operator()(lua_State* L, submetatable_type smt, reference& fast_index_table) {
21947  int fast_index_table_push = fast_index_table.push();
21948  stack_reference t(L, -fast_index_table_push);
21949  stack::set_field(L, detail::base_class_check_key(), reinterpret_cast<void*>(base_class_check_func), t.stack_index());
21950  stack::set_field(L, detail::base_class_cast_key(), reinterpret_cast<void*>(base_class_cast_func), t.stack_index());
21951  // change indexing, forcefully
21952  (p_usb->*change_indexing)(L, smt, p_derived_usb, t, idx_call, new_idx_call, meta_idx_call, meta_new_idx_call);
21953  t.pop();
21954  }
21955  };
21956 
21959 
21960  binding_data_equals(void* b) : binding_data(b) {
21961  }
21962 
21963  bool operator()(const std::unique_ptr<binding_base>& ptr) const {
21964  return binding_data == ptr->data();
21965  }
21966  };
21967 
21969  public:
21970  std::vector<std::unique_ptr<binding_base>> storage;
21971  std::vector<std::unique_ptr<char[]>> string_keys_storage;
21972  std::unordered_map<string_view, index_call_storage> string_keys;
21973  std::unordered_map<reference, reference, reference_hash, reference_equals> auxiliary_keys;
21987  std::bitset<64> properties;
21988 
21990  : storage()
21991  , string_keys()
21992  , auxiliary_keys()
21993  , value_index_table()
21994  , reference_index_table()
21995  , unique_index_table()
21996  , const_reference_index_table()
21997  , type_table(make_reference(L, create))
21998  , gc_names_table(make_reference(L, create))
21999  , named_metatable(make_reference(L, create))
22000  , base_index()
22001  , static_base_index()
22002  , is_using_index(false)
22003  , is_using_new_index(false)
22004  , properties() {
22005  base_index.binding_data = nullptr;
22006  base_index.index = index_target_fail;
22007  base_index.new_index = new_index_target_fail;
22008  base_index.new_binding_data = nullptr;
22009  static_base_index.binding_data = nullptr;
22010  static_base_index.index = index_target_fail;
22011  static_base_index.new_binding_data = this;
22012  static_base_index.new_index = new_index_target_set;
22013  }
22014 
22015  template <typename Fx>
22016  void for_each_table(lua_State* L, Fx&& fx) {
22017  for (int i = 0; i < 6; ++i) {
22018  submetatable_type smt = static_cast<submetatable_type>(i);
22019  reference* p_fast_index_table = nullptr;
22020  switch (smt) {
22021  case submetatable_type::const_value:
22022  p_fast_index_table = &this->const_value_index_table;
22023  break;
22025  p_fast_index_table = &this->reference_index_table;
22026  break;
22028  p_fast_index_table = &this->unique_index_table;
22029  break;
22030  case submetatable_type::const_reference:
22031  p_fast_index_table = &this->const_reference_index_table;
22032  break;
22033  case submetatable_type::named:
22034  p_fast_index_table = &this->named_index_table;
22035  break;
22037  default:
22038  p_fast_index_table = &this->value_index_table;
22039  break;
22040  }
22041  fx(L, smt, *p_fast_index_table);
22042  }
22043  }
22044 
22046  string_keys_storage.emplace_back(new char[sv.size()]);
22047  std::unique_ptr<char[]>& sv_storage = string_keys_storage.back();
22048  std::memcpy(sv_storage.get(), sv.data(), sv.size());
22049  string_view stored_sv(sv_storage.get(), sv.size());
22050  string_keys.insert_or_assign(std::move(stored_sv), std::move(ics));
22051  }
22052 
22053  template <typename T, typename... Bases>
22055  static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function),
22056  "The size of this data pointer is too small to fit the inheritance checking function: Please file "
22057  "a bug report.");
22058  static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function),
22059  "The size of this data pointer is too small to fit the inheritance checking function: Please file "
22060  "a bug report.");
22061  static_assert(!meta::any_same<T, Bases...>::value, "base classes cannot list the original class as part of the bases");
22062  if constexpr (sizeof...(Bases) < 1) {
22063  return;
22064  }
22065 
22066  (void)detail::swallow { 0, ((weak_derive<Bases>::value = true), 0)... };
22067 
22068  void* derived_this = static_cast<void*>(static_cast<usertype_storage<T>*>(this));
22069 
22070  update_bases_func for_each_fx;
22071  for_each_fx.base_class_check_func = &detail::inheritance<T>::template type_check_with<Bases...>;
22072  for_each_fx.base_class_cast_func = &detail::inheritance<T>::template type_cast_with<Bases...>;
22073  for_each_fx.idx_call = &usertype_storage<T>::template index_call_with_bases<false, Bases...>;
22074  for_each_fx.new_idx_call = &usertype_storage<T>::template index_call_with_bases<true, Bases...>;
22075  for_each_fx.meta_idx_call = &usertype_storage<T>::template meta_index_call_with_bases<false, Bases...>;
22076  for_each_fx.meta_new_idx_call = &usertype_storage<T>::template meta_index_call_with_bases<true, Bases...>;
22077  for_each_fx.p_usb = this;
22078  for_each_fx.p_derived_usb = derived_this;
22079  for_each_fx.change_indexing = &usertype_storage_base::change_indexing;
22080  for_each_fx.p_derived_usb = derived_this;
22081  this->for_each_table(L, for_each_fx);
22082  }
22083 
22084  void clear() {
22085  if (value_index_table.valid()) {
22086  stack::clear(value_index_table);
22087  }
22088  if (reference_index_table.valid()) {
22089  stack::clear(reference_index_table);
22090  }
22091  if (unique_index_table.valid()) {
22092  stack::clear(unique_index_table);
22093  }
22094  if (const_reference_index_table.valid()) {
22095  stack::clear(const_reference_index_table);
22096  }
22097  if (const_value_index_table.valid()) {
22098  stack::clear(const_value_index_table);
22099  }
22100  if (named_index_table.valid()) {
22101  stack::clear(named_index_table);
22102  }
22103  if (type_table.valid()) {
22104  stack::clear(type_table);
22105  }
22106  if (gc_names_table.valid()) {
22107  stack::clear(gc_names_table);
22108  }
22109  if (named_metatable.valid()) {
22110  lua_State* L = named_metatable.lua_state();
22111  auto pp = stack::push_pop(named_metatable);
22112  int named_metatable_index = pp.index_of(named_metatable);
22113  if (lua_getmetatable(L, named_metatable_index) == 1) {
22114  stack::clear(L, absolute_index(L, -1));
22115  }
22116  stack::clear(named_metatable);
22117  }
22118 
22119  value_index_table = lua_nil;
22120  reference_index_table = lua_nil;
22121  unique_index_table = lua_nil;
22122  const_reference_index_table = lua_nil;
22123  const_value_index_table = lua_nil;
22124  named_index_table = lua_nil;
22125  type_table = lua_nil;
22126  gc_names_table = lua_nil;
22127  named_metatable = lua_nil;
22128 
22129  storage.clear();
22130  string_keys.clear();
22131  auxiliary_keys.clear();
22132  }
22133 
22134  template <bool is_new_index, typename Base>
22135  static void base_walk_index(lua_State* L, usertype_storage_base& self, bool& keep_going, int& base_result) {
22136  using bases = typename base<Base>::type;
22137  if (!keep_going) {
22138  return;
22139  }
22140  (void)L;
22141  (void)self;
22142 #if SOL_IS_ON(SOL_USE_UNSAFE_BASE_LOOKUP_I_)
22143  usertype_storage_base& base_storage = get_usertype_storage<Base>(L);
22144  base_result = self_index_call<is_new_index, true>(bases(), L, base_storage);
22145 #else
22146  optional<usertype_storage<Base>&> maybe_base_storage = maybe_get_usertype_storage<Base>(L);
22147  if (static_cast<bool>(maybe_base_storage)) {
22148  base_result = self_index_call<is_new_index, true>(bases(), L, *maybe_base_storage);
22149  keep_going = base_result == base_walking_failed_index;
22150  }
22151 #endif // Fast versus slow, safe base lookup
22152  }
22153 
22154  template <bool is_new_index = false, bool base_walking = false, bool from_named_metatable = false, typename... Bases>
22156  type k_type = stack::get<type>(L, 2);
22157  if (k_type == type::string) {
22158  index_call_storage* target = nullptr;
22159  {
22160  string_view k = stack::get<string_view>(L, 2);
22161  auto it = self.string_keys.find(k);
22162  if (it != self.string_keys.cend()) {
22163  target = &it->second;
22164  }
22165  }
22166  if (target != nullptr) {
22167  // let the target decide what to do
22168  if constexpr (is_new_index) {
22169  return (target->new_index)(L, target->binding_data);
22170  }
22171  else {
22172  return (target->index)(L, target->binding_data);
22173  }
22174  }
22175  }
22176  else if (k_type != type::lua_nil && k_type != type::none) {
22177  reference* target = nullptr;
22178  {
22179  stack_reference k = stack::get<stack_reference>(L, 2);
22180  auto it = self.auxiliary_keys.find(k);
22181  if (it != self.auxiliary_keys.cend()) {
22182  target = &it->second;
22183  }
22184  }
22185  if (target != nullptr) {
22186  if constexpr (is_new_index) {
22187  // set value and return
22188  *target = reference(L, 3);
22189  return 0;
22190  }
22191  else {
22192  // push target to return
22193  // what we found
22194  return stack::push(L, *target);
22195  }
22196  }
22197  }
22198 
22199  // retrieve bases and walk through them.
22200  bool keep_going = true;
22201  int base_result;
22202  (void)keep_going;
22203  (void)base_result;
22204  (void)detail::swallow { 1, (base_walk_index<is_new_index, Bases>(L, self, keep_going, base_result), 1)... };
22205  if constexpr (sizeof...(Bases) > 0) {
22206  if (!keep_going) {
22207  return base_result;
22208  }
22209  }
22210  if constexpr (base_walking) {
22211  // if we're JUST base-walking then don't index-fail, just
22212  // return the false bits
22214  }
22215  else if constexpr (from_named_metatable) {
22216  if constexpr (is_new_index) {
22217  return self.static_base_index.new_index(L, self.static_base_index.new_binding_data);
22218  }
22219  else {
22220  return self.static_base_index.index(L, self.static_base_index.binding_data);
22221  }
22222  }
22223  else {
22224  if constexpr (is_new_index) {
22225  return self.base_index.new_index(L, self.base_index.new_binding_data);
22226  }
22227  else {
22228  return self.base_index.index(L, self.base_index.binding_data);
22229  }
22230  }
22231  }
22232 
22233  void change_indexing(lua_State* L, submetatable_type submetatable, void* derived_this, stack_reference& t, lua_CFunction index,
22234  lua_CFunction new_index, lua_CFunction meta_index, lua_CFunction meta_new_index) {
22235  usertype_storage_base& this_base = *this;
22236  void* base_this = static_cast<void*>(&this_base);
22237 
22238  this->is_using_index |= true;
22239  this->is_using_new_index |= true;
22240  if (submetatable == submetatable_type::named) {
22241  stack::set_field(L, metatable_key, named_index_table, t.stack_index());
22242  stack_reference stack_metametatable(L, -named_metatable.push());
22243  stack::set_field<false, true>(L,
22245  make_closure(meta_index, nullptr, derived_this, base_this, nullptr, toplevel_magic),
22246  stack_metametatable.stack_index());
22247  stack::set_field<false, true>(L,
22249  make_closure(meta_new_index, nullptr, derived_this, base_this, nullptr, toplevel_magic),
22250  stack_metametatable.stack_index());
22251  stack_metametatable.pop();
22252  }
22253  else {
22254  stack::set_field<false, true>(
22255  L, meta_function::index, make_closure(index, nullptr, derived_this, base_this, nullptr, toplevel_magic), t.stack_index());
22256  stack::set_field<false, true>(
22257  L, meta_function::new_index, make_closure(new_index, nullptr, derived_this, base_this, nullptr, toplevel_magic), t.stack_index());
22258  }
22259  }
22260 
22261  template <typename T = void, typename Key, typename Value>
22262  void set(lua_State* L, Key&& key, Value&& value);
22263 
22264  static int new_index_target_set(lua_State* L, void* target) {
22265  usertype_storage_base& self = *static_cast<usertype_storage_base*>(target);
22266  self.set(L, reference(L, raw_index(2)), reference(L, raw_index(3)));
22267  return 0;
22268  }
22269  };
22270 
22271  template <typename T>
22273 
22274  using usertype_storage_base::usertype_storage_base;
22275 
22276  template <bool is_new_index, bool from_named_metatable>
22277  static inline int index_call_(lua_State* L) {
22278  using bases = typename base<T>::type;
22279  usertype_storage_base& self = stack::get<light<usertype_storage_base>>(L, upvalue_index(usertype_storage_index));
22280  return self_index_call<is_new_index, false, from_named_metatable>(bases(), L, self);
22281  }
22282 
22283  template <bool is_new_index, bool from_named_metatable, typename... Bases>
22284  static inline int index_call_with_bases_(lua_State* L) {
22285  using bases = types<Bases...>;
22286  usertype_storage_base& self = stack::get<light<usertype_storage_base>>(L, upvalue_index(usertype_storage_index));
22287  return self_index_call<is_new_index, false, from_named_metatable>(bases(), L, self);
22288  }
22289 
22290  template <bool is_new_index>
22291  static inline int index_call(lua_State* L) {
22292  return detail::static_trampoline<&index_call_<is_new_index, false>>(L);
22293  }
22294 
22295  template <bool is_new_index, typename... Bases>
22296  static inline int index_call_with_bases(lua_State* L) {
22297  return detail::static_trampoline<&index_call_with_bases_<is_new_index, false, Bases...>>(L);
22298  }
22299 
22300  template <bool is_new_index>
22301  static inline int meta_index_call(lua_State* L) {
22302  return detail::static_trampoline<&index_call_<is_new_index, true>>(L);
22303  }
22304 
22305  template <bool is_new_index, typename... Bases>
22306  static inline int meta_index_call_with_bases(lua_State* L) {
22307  return detail::static_trampoline<&index_call_with_bases_<is_new_index, true, Bases...>>(L);
22308  }
22309 
22310  template <typename Key, typename Value>
22311  inline void set(lua_State* L, Key&& key, Value&& value);
22312  };
22313 
22314  template <typename T>
22316  return detail::user_alloc_destruct<usertype_storage<T>>(L);
22317  }
22318 
22319  template <typename T, typename Key, typename Value>
22320  void usertype_storage_base::set(lua_State* L, Key&& key, Value&& value) {
22321  using ValueU = meta::unwrap_unqualified_t<Value>;
22322  using KeyU = meta::unwrap_unqualified_t<Key>;
22323  using Binding = binding<KeyU, ValueU, T>;
22324  using is_var_bind = is_variable_binding<ValueU>;
22325  if constexpr (std::is_same_v<KeyU, call_construction>) {
22326  (void)key;
22327  std::unique_ptr<Binding> p_binding = std::make_unique<Binding>(std::forward<Value>(value));
22328  Binding& b = *p_binding;
22329  this->storage.push_back(std::move(p_binding));
22330 
22331  this->named_index_table.push();
22332  absolute_index metametatable_index(L, -1);
22333  stack::push(L, nullptr);
22334  stack::push(L, b.data());
22335  lua_CFunction target_func = &b.template call<false, false>;
22336  lua_pushcclosure(L, target_func, 2);
22337  lua_setfield(L, metametatable_index, to_string(meta_function::call).c_str());
22338  this->named_index_table.pop();
22339  }
22340  else if constexpr (std::is_same_v<KeyU, base_classes_tag>) {
22341  (void)key;
22342  this->update_bases<T>(L, std::forward<Value>(value));
22343  }
22344  else if constexpr ((meta::is_string_like_or_constructible<KeyU>::value || std::is_same_v<KeyU, meta_function>)) {
22345  std::string s = u_detail::make_string(std::forward<Key>(key));
22346  auto storage_it = this->storage.end();
22347  auto string_it = this->string_keys.find(s);
22348  if (string_it != this->string_keys.cend()) {
22349  const auto& binding_data = string_it->second.binding_data;
22350  storage_it = std::find_if(this->storage.begin(), this->storage.end(), binding_data_equals(binding_data));
22351  this->string_keys.erase(string_it);
22352  }
22353 
22354  std::unique_ptr<Binding> p_binding = std::make_unique<Binding>(std::forward<Value>(value));
22355  Binding& b = *p_binding;
22356  if (storage_it != this->storage.cend()) {
22357  *storage_it = std::move(p_binding);
22358  }
22359  else {
22360  this->storage.push_back(std::move(p_binding));
22361  }
22362 
22363  bool is_index = (s == to_string(meta_function::index));
22364  bool is_new_index = (s == to_string(meta_function::new_index));
22365  bool is_static_index = (s == to_string(meta_function::static_index));
22366  bool is_static_new_index = (s == to_string(meta_function::static_new_index));
22367  bool is_destruction = s == to_string(meta_function::garbage_collect);
22368  bool poison_indexing = (!is_using_index || !is_using_new_index) && (is_var_bind::value || is_index || is_new_index);
22369  void* derived_this = static_cast<void*>(static_cast<usertype_storage<T>*>(this));
22370  index_call_storage ics;
22371  ics.binding_data = b.data();
22372  ics.index = is_index || is_static_index ? &Binding::template call_with_<true, is_var_bind::value>
22373  : &Binding::template index_call_with_<true, is_var_bind::value>;
22374  ics.new_index = is_new_index || is_static_new_index ? &Binding::template call_with_<false, is_var_bind::value>
22375  : &Binding::template index_call_with_<false, is_var_bind::value>;
22376 
22377  string_for_each_metatable_func for_each_fx;
22378  for_each_fx.is_destruction = is_destruction;
22379  for_each_fx.is_index = is_index;
22380  for_each_fx.is_new_index = is_new_index;
22381  for_each_fx.is_static_index = is_static_index;
22382  for_each_fx.is_static_new_index = is_static_new_index;
22383  for_each_fx.poison_indexing = poison_indexing;
22384  for_each_fx.p_key = &s;
22385  for_each_fx.p_ics = &ics;
22386  if constexpr (is_lua_c_function_v<ValueU>) {
22387  for_each_fx.is_unqualified_lua_CFunction = true;
22388  for_each_fx.call_func = *static_cast<lua_CFunction*>(ics.binding_data);
22389  }
22390  else if constexpr (is_lua_reference_or_proxy_v<ValueU>) {
22391  for_each_fx.is_unqualified_lua_reference = true;
22392  for_each_fx.p_binding_ref = static_cast<reference*>(ics.binding_data);
22393  }
22394  else {
22395  for_each_fx.call_func = &b.template call<false, is_var_bind::value>;
22396  }
22397  for_each_fx.p_usb = this;
22398  for_each_fx.p_derived_usb = derived_this;
22399  for_each_fx.idx_call = &usertype_storage<T>::template index_call<false>;
22400  for_each_fx.new_idx_call = &usertype_storage<T>::template index_call<true>;
22401  for_each_fx.meta_idx_call = &usertype_storage<T>::template meta_index_call<false>;
22402  for_each_fx.meta_new_idx_call = &usertype_storage<T>::template meta_index_call<true>;
22403  for_each_fx.change_indexing = &usertype_storage_base::change_indexing;
22404  // set base index and base new_index
22405  // functions here
22406  if (is_index) {
22407  this->base_index.index = ics.index;
22408  this->base_index.binding_data = ics.binding_data;
22409  }
22410  if (is_new_index) {
22411  this->base_index.new_index = ics.new_index;
22412  this->base_index.new_binding_data = ics.binding_data;
22413  }
22414  if (is_static_index) {
22415  this->static_base_index.index = ics.index;
22416  this->static_base_index.binding_data = ics.binding_data;
22417  }
22418  if (is_static_new_index) {
22419  this->static_base_index.new_index = ics.new_index;
22420  this->static_base_index.new_binding_data = ics.binding_data;
22421  }
22422  this->for_each_table(L, for_each_fx);
22423  this->add_entry(s, std::move(ics));
22424  }
22425  else {
22426  // the reference-based implementation might compare poorly and hash
22427  // poorly in some cases...
22428  if constexpr (is_lua_reference_v<KeyU> && is_lua_reference_v<ValueU>) {
22429  if (key.get_type() == type::string) {
22430  stack::push(L, key);
22431  std::string string_key = stack::pop<std::string>(L);
22432  this->set<T>(L, string_key, std::forward<Value>(value));
22433  }
22434  else {
22435  lua_reference_func ref_additions_fx { key, value };
22436 
22437  this->for_each_table(L, ref_additions_fx);
22438  this->auxiliary_keys.insert_or_assign(std::forward<Key>(key), std::forward<Value>(value));
22439  }
22440  }
22441  else {
22442  reference ref_key = make_reference(L, std::forward<Key>(key));
22443  reference ref_value = make_reference(L, std::forward<Value>(value));
22444  lua_reference_func ref_additions_fx { key, value };
22445 
22446  this->for_each_table(L, ref_additions_fx);
22447  this->auxiliary_keys.insert_or_assign(std::move(ref_key), std::move(ref_value));
22448  }
22449  }
22450  }
22451 
22452  template <typename T>
22453  template <typename Key, typename Value>
22454  void usertype_storage<T>::set(lua_State* L, Key&& key, Value&& value) {
22455  static_cast<usertype_storage_base&>(*this).set<T>(L, std::forward<Key>(key), std::forward<Value>(value));
22456  }
22457 
22458  template <typename T>
22460  const char* gcmetakey = &usertype_traits<T>::gc_table()[0];
22461 
22462  // Make sure userdata's memory is properly in lua first,
22463  // otherwise all the light userdata we make later will become invalid
22464  int usertype_storage_push_count = stack::push<user<usertype_storage<T>>>(L, no_metatable, L);
22465  stack_reference usertype_storage_ref(L, -usertype_storage_push_count);
22466 
22467  // create and push onto the stack a table to use as metatable for this GC
22468  // we create a metatable to attach to the regular gc_table
22469  // so that the destructor is called for the usertype storage
22470  int usertype_storage_metatabe_count = stack::push(L, new_table(0, 1));
22471  stack_reference usertype_storage_metatable(L, -usertype_storage_metatabe_count);
22472  // set the destruction routine on the metatable
22473  stack::set_field(L, meta_function::garbage_collect, &destruct_usertype_storage<T>, usertype_storage_metatable.stack_index());
22474  // set the metatable on the usertype storage userdata
22475  stack::set_field(L, metatable_key, usertype_storage_metatable, usertype_storage_ref.stack_index());
22476  usertype_storage_metatable.pop();
22477 
22478  // set the usertype storage and its metatable
22479  // into the global table...
22480  stack::set_field<true>(L, gcmetakey, usertype_storage_ref);
22481  usertype_storage_ref.pop();
22482 
22483  // then retrieve the lua-stored version so we have a well-pinned
22484  // reference that does not die
22485  stack::get_field<true>(L, gcmetakey);
22486  usertype_storage<T>& target_umt = stack::pop<user<usertype_storage<T>>>(L);
22487  return target_umt;
22488  }
22489 
22491  stack::record tracking;
22492  if (!stack::check<user<usertype_storage_base>>(L, index)) {
22493  return nullopt;
22494  }
22495  usertype_storage_base& target_umt = stack::stack_detail::unchecked_unqualified_get<user<usertype_storage_base>>(L, -1, tracking);
22496  return target_umt;
22497  }
22498 
22500  stack::get_field<true>(L, gcmetakey);
22501  auto maybe_storage = maybe_get_usertype_storage_base(L, lua_gettop(L));
22502  lua_pop(L, 1);
22503  return maybe_storage;
22504  }
22505 
22506  inline usertype_storage_base& get_usertype_storage_base(lua_State* L, const char* gcmetakey) {
22507  stack::get_field<true>(L, gcmetakey);
22508  stack::record tracking;
22509  usertype_storage_base& target_umt = stack::stack_detail::unchecked_unqualified_get<user<usertype_storage_base>>(L, -1, tracking);
22510  lua_pop(L, 1);
22511  return target_umt;
22512  }
22513 
22514  template <typename T>
22516  const char* gcmetakey = &usertype_traits<T>::gc_table()[0];
22517  stack::get_field<true>(L, gcmetakey);
22518  int target = lua_gettop(L);
22519  if (!stack::check<user<usertype_storage<T>>>(L, target)) {
22520  return nullopt;
22521  }
22522  usertype_storage<T>& target_umt = stack::pop<user<usertype_storage<T>>>(L);
22523  return target_umt;
22524  }
22525 
22526  template <typename T>
22528  const char* gcmetakey = &usertype_traits<T>::gc_table()[0];
22529  stack::get_field<true>(L, gcmetakey);
22530  usertype_storage<T>& target_umt = stack::pop<user<usertype_storage<T>>>(L);
22531  return target_umt;
22532  }
22533 
22534  template <typename T>
22536  using u_traits = usertype_traits<T>;
22537 #if 0
22538  using u_const_traits = usertype_traits<const T>;
22539  using u_unique_traits = usertype_traits<detail::unique_usertype<T>>;
22540  using u_ref_traits = usertype_traits<T*>;
22541  using u_const_ref_traits = usertype_traits<T const*>;
22542 #endif
22543  using uts = usertype_storage<T>;
22544 
22545  const char* gcmetakey = &u_traits::gc_table()[0];
22546  stack::get_field<true>(L, gcmetakey);
22547  if (!stack::check<user<uts>>(L)) {
22548  lua_pop(L, 1);
22549  return;
22550  }
22551  usertype_storage<T>& target_umt = stack::pop<user<usertype_storage<T>>>(L);
22552  target_umt.clear();
22553 
22554  // get the registry
22555 #if 0
22556  stack_reference registry(L, raw_index(LUA_REGISTRYINDEX));
22557  registry.push();
22558  // eliminate all named entries for this usertype
22559  // in the registry (luaL_newmetatable does
22560  // [name] = new table
22561  // in registry upon creation
22567  registry.pop();
22568 #endif // Registry Cleanout
22569 
22570  stack::set_field<true>(L, gcmetakey, lua_nil);
22571  }
22572 
22573  template <typename T>
22574  inline int register_usertype(lua_State* L, automagic_enrollments enrollments = {}) {
22575  using u_traits = usertype_traits<T>;
22576  using u_const_traits = usertype_traits<const T>;
22577  using u_unique_traits = usertype_traits<detail::unique_usertype<T>>;
22578  using u_ref_traits = usertype_traits<T*>;
22579  using u_const_ref_traits = usertype_traits<T const*>;
22580  using uts = usertype_storage<T>;
22581 
22582  // always have __new_index point to usertype_storage method
22583  // have __index always point to regular fast-lookup
22584  // meta_method table
22585  // if __new_index is invoked, runtime-swap
22586  // to slow __index if necessary
22587  // (no speed penalty because function calls
22588  // are all read-only -- only depend on __index
22589  // to retrieve function and then call happens VIA Lua)
22590 
22591  // __type entry:
22592  // table contains key -> value lookup,
22593  // where key is entry in metatable
22594  // and value is type information as a string as
22595  // best as we can give it
22596 
22597  // name entry:
22598  // string that contains raw class name,
22599  // as defined from C++
22600 
22601  // is entry:
22602  // checks if argument supplied is of type T
22603 
22604  // __storage entry:
22605  // a light userdata pointing to the storage
22606  // mostly to enable this new abstraction
22607  // to not require the type name `T`
22608  // to get at the C++ usertype storage within
22609 
22610  // we then let typical definitions potentially override these intrinsics
22611  // it's the user's fault if they override things or screw them up:
22612  // these names have been reserved and documented since sol3
22613 
22614  // STEP 0: tell the old usertype (if it exists)
22615  // to fuck off
22616  delete_usertype_storage<T>(L);
22617 
22618  // STEP 1: Create backing store for usertype storage
22619  // Pretty much the most important step.
22620  // STEP 2: Create Lua tables used for fast method indexing.
22621  // This is done inside of the storage table's constructor
22622  usertype_storage<T>& storage = create_usertype_storage<T>(L);
22623  usertype_storage_base& base_storage = storage;
22624  void* light_storage = static_cast<void*>(&storage);
22625  void* light_base_storage = static_cast<void*>(&base_storage);
22626 
22627  // STEP 3: set up GC escape hatch table entirely
22628  storage.gc_names_table.push();
22629  stack_reference gnt(L, -1);
22630  stack::set_field(L, submetatable_type::named, &u_traits::gc_table()[0], gnt.stack_index());
22631  stack::set_field(L, submetatable_type::const_value, &u_const_traits::metatable()[0], gnt.stack_index());
22632  stack::set_field(L, submetatable_type::const_reference, &u_const_ref_traits::metatable()[0], gnt.stack_index());
22636  gnt.pop();
22637 
22638  // STEP 4: add some useful information to the type table
22639  stack_reference stacked_type_table(L, -storage.type_table.push());
22640  stack::set_field(L, "name", detail::demangle<T>(), stacked_type_table.stack_index());
22641  stack::set_field(L, "is", &detail::is_check<T>, stacked_type_table.stack_index());
22642  stacked_type_table.pop();
22643 
22644  // STEP 5: create and hook up metatable,
22645  // add intrinsics
22646  // this one is the actual meta-handling table,
22647  // the next one will be the one for
22648  int for_each_backing_metatable_calls = 0;
22649  auto for_each_backing_metatable = [&](lua_State* L, submetatable_type smt, reference& fast_index_table) {
22650  // Pointer types, AKA "references" from C++
22651  const char* metakey = nullptr;
22652  switch (smt) {
22653  case submetatable_type::const_value:
22654  metakey = &u_const_traits::metatable()[0];
22655  break;
22657  metakey = &u_ref_traits::metatable()[0];
22658  break;
22660  metakey = &u_unique_traits::metatable()[0];
22661  break;
22662  case submetatable_type::const_reference:
22663  metakey = &u_const_ref_traits::metatable()[0];
22664  break;
22665  case submetatable_type::named:
22666  metakey = &u_traits::user_metatable()[0];
22667  break;
22669  default:
22670  metakey = &u_traits::metatable()[0];
22671  break;
22672  }
22673 
22674  luaL_newmetatable(L, metakey);
22675  if (smt == submetatable_type::named) {
22676  // the named table itself
22677  // gets the associated name value
22678  storage.named_metatable = reference(L, -1);
22679  lua_pop(L, 1);
22680  // but the thing we perform the methods on
22681  // is still the metatable of the named
22682  // table
22683  lua_createtable(L, 0, 6);
22684  }
22685  stack_reference t(L, -1);
22686  fast_index_table = reference(t);
22687  stack::set_field<false, true>(L, meta_function::type, storage.type_table, t.stack_index());
22688  if constexpr (std::is_destructible_v<T>) {
22689  // destructible: serialize default
22690  // destructor here
22691  switch (smt) {
22692  case submetatable_type::const_reference:
22694  case submetatable_type::named:
22695  break;
22697  stack::set_field<false, true>(L, meta_function::garbage_collect, &detail::unique_destruct<T>, t.stack_index());
22698  break;
22700  case submetatable_type::const_value:
22701  default:
22702  stack::set_field<false, true>(L, meta_function::garbage_collect, detail::make_destructor<T>(), t.stack_index());
22703  break;
22704  }
22705  }
22706  else {
22707  // not destructible: serialize a
22708  // "hey you messed up"
22709  // destructor
22710  switch (smt) {
22711  case submetatable_type::const_reference:
22713  case submetatable_type::named:
22714  break;
22716  stack::set_field<false, true>(L, meta_function::garbage_collect, &detail::cannot_destruct<T>, t.stack_index());
22717  break;
22719  case submetatable_type::const_value:
22720  default:
22721  stack::set_field<false, true>(L, meta_function::garbage_collect, &detail::cannot_destruct<T>, t.stack_index());
22722  break;
22723  }
22724  }
22725 
22726  static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function),
22727  "The size of this data pointer is too small to fit the inheritance checking function: file a bug "
22728  "report.");
22729  static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function),
22730  "The size of this data pointer is too small to fit the inheritance checking function: file a bug "
22731  "report.");
22732  stack::set_field<false, true>(L, detail::base_class_check_key(), reinterpret_cast<void*>(&detail::inheritance<T>::type_check), t.stack_index());
22733  stack::set_field<false, true>(L, detail::base_class_cast_key(), reinterpret_cast<void*>(&detail::inheritance<T>::type_cast), t.stack_index());
22734 
22735  auto prop_fx = detail::properties_enrollment_allowed(for_each_backing_metatable_calls, storage.properties, enrollments);
22736  auto insert_fx = [&L, &t, &storage](meta_function mf, lua_CFunction reg) {
22737  stack::set_field<false, true>(L, mf, reg, t.stack_index());
22738  storage.properties[static_cast<int>(mf)] = true;
22739  };
22740  detail::insert_default_registrations<T>(insert_fx, prop_fx);
22741 
22742  // There are no variables, so serialize the fast function stuff
22743  // be sure to reset the index stuff to the non-fast version
22744  // if the user ever adds something later!
22745  if (smt == submetatable_type::named) {
22746  // add escape hatch storage pointer and gc names
22747  stack::set_field<false, true>(L, meta_function::storage, light_base_storage, t.stack_index());
22748  stack::set_field<false, true>(L, meta_function::gc_names, storage.gc_names_table, t.stack_index());
22749 
22750  // fancy new_indexing when using the named table
22751  {
22752  absolute_index named_metatable_index(L, -storage.named_metatable.push());
22753  stack::set_field<false, true>(L, metatable_key, t, named_metatable_index);
22754  storage.named_metatable.pop();
22755  }
22756  stack_reference stack_metametatable(L, -storage.named_index_table.push());
22757  stack::set_field<false, true>(L,
22759  make_closure(uts::template meta_index_call<false>, nullptr, light_storage, light_base_storage, nullptr, toplevel_magic),
22760  stack_metametatable.stack_index());
22761  stack::set_field<false, true>(L,
22763  make_closure(uts::template meta_index_call<true>, nullptr, light_storage, light_base_storage, nullptr, toplevel_magic),
22764  stack_metametatable.stack_index());
22765  stack_metametatable.pop();
22766  }
22767  else {
22768  // otherwise just plain for index,
22769  // and elaborated for new_index
22770  stack::set_field<false, true>(L, meta_function::index, t, t.stack_index());
22771  stack::set_field<false, true>(L,
22773  make_closure(uts::template index_call<true>, nullptr, light_storage, light_base_storage, nullptr, toplevel_magic),
22774  t.stack_index());
22775  storage.is_using_new_index = true;
22776  }
22777 
22778  ++for_each_backing_metatable_calls;
22779  fast_index_table = reference(L, t);
22780  t.pop();
22781  };
22782 
22783  storage.for_each_table(L, for_each_backing_metatable);
22784 
22785  // can only use set AFTER we initialize all the metatables
22786  if constexpr (std::is_default_constructible_v<T>) {
22787  if (enrollments.default_constructor) {
22788  storage.set(L, meta_function::construct, constructors<T()>());
22789  }
22790  }
22791 
22792  // return the named metatable we want names linked into
22793  storage.named_metatable.push();
22794  return 1;
22795  }
22796 }} // namespace sol::u_detail
22797 
22798 // end of sol/usertype_storage.hpp
22799 
22800 // beginning of sol/usertype_proxy.hpp
22801 
22802 namespace sol {
22803  template <typename Table, typename Key>
22804  struct usertype_proxy : public proxy_base<usertype_proxy<Table, Key>> {
22805  private:
22807 
22808  template <typename T, std::size_t... I>
22809  decltype(auto) tuple_get(std::index_sequence<I...>) const & {
22810  return tbl.template traverse_get<T>(std::get<I>(key)...);
22811  }
22812 
22813  template <typename T, std::size_t... I>
22814  decltype(auto) tuple_get(std::index_sequence<I...>) && {
22815  return tbl.template traverse_get<T>(std::get<I>(std::move(key))...);
22816  }
22817 
22818  template <std::size_t... I, typename T>
22819  void tuple_set(std::index_sequence<I...>, T&& value) & {
22820  if constexpr (sizeof...(I) > 1) {
22821  tbl.traverse_set(std::get<I>(key)..., std::forward<T>(value));
22822  }
22823  else {
22824  tbl.set(std::get<I>(key)..., std::forward<T>(value));
22825  }
22826  }
22827 
22828  template <std::size_t... I, typename T>
22829  void tuple_set(std::index_sequence<I...>, T&& value) && {
22830  if constexpr (sizeof...(I) > 1) {
22831  tbl.traverse_set(std::get<I>(std::move(key))..., std::forward<T>(value));
22832  }
22833  else {
22834  tbl.set(std::get<I>(std::move(key))..., std::forward<T>(value));
22835  }
22836  }
22837 
22838  public:
22841 
22842  template <typename T>
22844  : tbl(table), key(std::forward<T>(k)) {
22845  }
22846 
22847  template <typename T>
22848  usertype_proxy& set(T&& item) & {
22849  using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
22850  tuple_set(idx_seq(), std::forward<T>(item));
22851  return *this;
22852  }
22853 
22854  template <typename T>
22855  usertype_proxy&& set(T&& item) && {
22856  using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
22857  std::move(*this).tuple_set(idx_seq(), std::forward<T>(item));
22858  return std::move(*this);
22859  }
22860 
22861  template <typename T>
22862  usertype_proxy& operator=(T&& other) & {
22863  return set(std::forward<T>(other));
22864  }
22865 
22866  template <typename T>
22867  usertype_proxy&& operator=(T&& other) && {
22868  return std::move(*this).set(std::forward<T>(other));
22869  }
22870 
22871  template <typename T>
22872  usertype_proxy& operator=(std::initializer_list<T> other) & {
22873  return set(std::move(other));
22874  }
22875 
22876  template <typename T>
22877  usertype_proxy&& operator=(std::initializer_list<T> other) && {
22878  return std::move(*this).set(std::move(other));
22879  }
22880 
22881  template <typename T>
22882  decltype(auto) get() const& {
22883  using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
22884  return tuple_get<T>(idx_seq());
22885  }
22886 
22887  template <typename T>
22888  decltype(auto) get() && {
22889  using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
22890  return std::move(*this).template tuple_get<T>(idx_seq());
22891  }
22892 
22893  template <typename K>
22894  decltype(auto) operator[](K&& k) const& {
22895  auto keys = meta::tuplefy(key, std::forward<K>(k));
22897  }
22898 
22899  template <typename K>
22900  decltype(auto) operator[](K&& k) & {
22901  auto keys = meta::tuplefy(key, std::forward<K>(k));
22903  }
22904 
22905  template <typename K>
22906  decltype(auto) operator[](K&& k) && {
22907  auto keys = meta::tuplefy(std::move(key), std::forward<K>(k));
22909  }
22910 
22911  template <typename... Ret, typename... Args>
22912  decltype(auto) call(Args&&... args) {
22913 #if !defined(__clang__) && defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 191200000
22914  // MSVC is ass sometimes
22915  return get<function>().call<Ret...>(std::forward<Args>(args)...);
22916 #else
22917  return get<function>().template call<Ret...>(std::forward<Args>(args)...);
22918 #endif
22919  }
22920 
22921  template <typename... Args>
22922  decltype(auto) operator()(Args&&... args) {
22923  return call<>(std::forward<Args>(args)...);
22924  }
22925 
22926  bool valid() const {
22927  auto pp = stack::push_pop(tbl);
22928  auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(lua_state(), key, lua_gettop(lua_state()));
22929  lua_pop(lua_state(), p.levels);
22930  return p;
22931  }
22932 
22933  int push() const noexcept {
22934  return push(this->lua_state());
22935  }
22936 
22937  int push(lua_State* L) const noexcept {
22938  return get<reference>().push(L);
22939  }
22940 
22941  type get_type() const {
22942  type t = type::none;
22943  auto pp = stack::push_pop(tbl);
22944  auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(lua_state(), key, lua_gettop(lua_state()));
22945  if (p) {
22946  t = type_of(lua_state(), -1);
22947  }
22948  lua_pop(lua_state(), p.levels);
22949  return t;
22950  }
22951 
22953  return tbl.lua_state();
22954  }
22955  };
22956 } // namespace sol
22957 
22958 // end of sol/usertype_proxy.hpp
22959 
22960 // beginning of sol/metatable.hpp
22961 
22962 // beginning of sol/table_core.hpp
22963 
22964 // beginning of sol/table_proxy.hpp
22965 
22966 namespace sol {
22967 
22968  template <typename Table, typename Key>
22969  struct table_proxy : public proxy_base<table_proxy<Table, Key>> {
22970  private:
22972 
22973  template <typename T, std::size_t... I>
22974  decltype(auto) tuple_get(std::index_sequence<I...>) const& {
22975  return tbl.template traverse_get<T>(std::get<I>(key)...);
22976  }
22977 
22978  template <typename T, std::size_t... I>
22979  decltype(auto) tuple_get(std::index_sequence<I...>) && {
22980  return tbl.template traverse_get<T>(std::get<I>(std::move(key))...);
22981  }
22982 
22983  template <std::size_t... I, typename T>
22984  void tuple_set(std::index_sequence<I...>, T&& value) & {
22985  tbl.traverse_set(std::get<I>(key)..., std::forward<T>(value));
22986  }
22987 
22988  template <std::size_t... I, typename T>
22989  void tuple_set(std::index_sequence<I...>, T&& value) && {
22990  tbl.traverse_set(std::get<I>(std::move(key))..., std::forward<T>(value));
22991  }
22992 
22993  auto setup_table(std::true_type) {
22994  auto p = stack::probe_get_field<std::is_same_v<meta::unqualified_t<Table>, global_table>>(lua_state(), key, tbl.stack_index());
22995  lua_pop(lua_state(), p.levels);
22996  return p;
22997  }
22998 
22999  bool is_valid(std::false_type) {
23000  auto pp = stack::push_pop(tbl);
23001  auto p = stack::probe_get_field<std::is_same_v<meta::unqualified_t<Table>, global_table>>(lua_state(), key, lua_gettop(lua_state()));
23002  lua_pop(lua_state(), p.levels);
23003  return p;
23004  }
23005 
23006  public:
23009 
23010  template <typename T>
23011  table_proxy(Table table, T&& k) : tbl(table), key(std::forward<T>(k)) {
23012  }
23013 
23014  template <typename T>
23015  table_proxy& set(T&& item) & {
23016  tuple_set(std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>(), std::forward<T>(item));
23017  return *this;
23018  }
23019 
23020  template <typename T>
23021  table_proxy&& set(T&& item) && {
23022  tuple_set(std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>(), std::forward<T>(item));
23023  return std::move(*this);
23024  }
23025 
23026  template <typename... Args>
23027  table_proxy& set_function(Args&&... args) & {
23028  tbl.set_function(key, std::forward<Args>(args)...);
23029  return *this;
23030  }
23031 
23032  template <typename... Args>
23033  table_proxy&& set_function(Args&&... args) && {
23034  tbl.set_function(std::move(key), std::forward<Args>(args)...);
23035  return std::move(*this);
23036  }
23037 
23038  template <typename T>
23039  table_proxy& operator=(T&& other) & {
23040  using Tu = meta::unwrap_unqualified_t<T>;
23041  if constexpr (!is_lua_reference_or_proxy_v<Tu> && meta::is_callable_v<Tu>) {
23042  return set_function(std::forward<T>(other));
23043  }
23044  else {
23045  return set(std::forward<T>(other));
23046  }
23047  }
23048 
23049  template <typename T>
23050  table_proxy&& operator=(T&& other) && {
23051  using Tu = meta::unwrap_unqualified_t<T>;
23052  if constexpr (!is_lua_reference_or_proxy_v<Tu> && meta::is_callable_v<Tu>) {
23053  return std::move(*this).set_function(std::forward<T>(other));
23054  }
23055  else {
23056  return std::move(*this).set(std::forward<T>(other));
23057  }
23058  }
23059 
23060  template <typename T>
23061  table_proxy& operator=(std::initializer_list<T> other) & {
23062  return set(std::move(other));
23063  }
23064 
23065  template <typename T>
23066  table_proxy&& operator=(std::initializer_list<T> other) && {
23067  return std::move(*this).set(std::move(other));
23068  }
23069 
23070  template <typename T>
23071  decltype(auto) get() const& {
23072  using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
23073  return tuple_get<T>(idx_seq());
23074  }
23075 
23076  template <typename T>
23077  decltype(auto) get() && {
23078  using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
23079  return std::move(*this).template tuple_get<T>(idx_seq());
23080  }
23081 
23082  template <typename T>
23083  decltype(auto) get_or(T&& otherwise) const {
23084  typedef decltype(get<T>()) U;
23085  optional<U> option = get<optional<U>>();
23086  if (option) {
23087  return static_cast<U>(option.value());
23088  }
23089  return static_cast<U>(std::forward<T>(otherwise));
23090  }
23091 
23092  template <typename T, typename D>
23093  decltype(auto) get_or(D&& otherwise) const {
23094  optional<T> option = get<optional<T>>();
23095  if (option) {
23096  return static_cast<T>(option.value());
23097  }
23098  return static_cast<T>(std::forward<D>(otherwise));
23099  }
23100 
23101  template <typename T>
23102  decltype(auto) get_or_create() {
23103  return get_or_create<T>(new_table());
23104  }
23105 
23106  template <typename T, typename Otherwise>
23107  decltype(auto) get_or_create(Otherwise&& other) {
23108  if (!this->valid()) {
23109  this->set(std::forward<Otherwise>(other));
23110  }
23111  return get<T>();
23112  }
23113 
23114  template <typename K>
23115  decltype(auto) operator[](K&& k) const& {
23116  auto keys = meta::tuplefy(key, std::forward<K>(k));
23117  return table_proxy<Table, decltype(keys)>(tbl, std::move(keys));
23118  }
23119 
23120  template <typename K>
23121  decltype(auto) operator[](K&& k) & {
23122  auto keys = meta::tuplefy(key, std::forward<K>(k));
23123  return table_proxy<Table, decltype(keys)>(tbl, std::move(keys));
23124  }
23125 
23126  template <typename K>
23127  decltype(auto) operator[](K&& k) && {
23128  auto keys = meta::tuplefy(std::move(key), std::forward<K>(k));
23129  return table_proxy<Table, decltype(keys)>(tbl, std::move(keys));
23130  }
23131 
23132  template <typename... Ret, typename... Args>
23133  decltype(auto) call(Args&&... args) {
23134  lua_State* L = this->lua_state();
23135  push(L);
23136  int idx = lua_gettop(L);
23137  stack_aligned_function func(L, idx);
23138  return func.call<Ret...>(std::forward<Args>(args)...);
23139  }
23140 
23141  template <typename... Args>
23142  decltype(auto) operator()(Args&&... args) {
23143  return call<>(std::forward<Args>(args)...);
23144  }
23145 
23146  bool valid() const {
23147  auto pp = stack::push_pop(tbl);
23148  auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(lua_state(), key, lua_gettop(lua_state()));
23149  lua_pop(lua_state(), p.levels);
23150  return p;
23151  }
23152 
23153  int push() const noexcept {
23154  return push(this->lua_state());
23155  }
23156 
23157  int push(lua_State* L) const noexcept {
23159  auto pp = stack::push_pop<true>(tbl);
23160  int tableindex = pp.index_of(tbl);
23161  int top_index = lua_gettop(L);
23162  stack::get_field<true>(lua_state(), key, tableindex);
23163  lua_replace(L, top_index + 1);
23164  lua_settop(L, top_index + 1);
23165  }
23166  else {
23167  auto pp = stack::push_pop<false>(tbl);
23168  int tableindex = pp.index_of(tbl);
23169  int aftertableindex = lua_gettop(L);
23170  stack::get_field<false>(lua_state(), key, tableindex);
23171  lua_replace(L, tableindex);
23172  lua_settop(L, aftertableindex + 1);
23173  }
23174  return 1;
23175  }
23176 
23177  type get_type() const {
23178  type t = type::none;
23179  auto pp = stack::push_pop(tbl);
23180  auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(lua_state(), key, lua_gettop(lua_state()));
23181  if (p) {
23182  t = type_of(lua_state(), -1);
23183  }
23184  lua_pop(lua_state(), p.levels);
23185  return t;
23186  }
23187 
23189  return tbl.lua_state();
23190  }
23191 
23193  if (!this->valid()) {
23194  this->set(new_table());
23195  }
23196  return *this;
23197  }
23198  };
23199 
23200  template <typename Table, typename Key, typename T>
23201  inline bool operator==(T&& left, const table_proxy<Table, Key>& right) {
23202  using G = decltype(stack::get<T>(nullptr, 0));
23203  return right.template get<optional<G>>() == left;
23204  }
23205 
23206  template <typename Table, typename Key, typename T>
23207  inline bool operator==(const table_proxy<Table, Key>& right, T&& left) {
23208  using G = decltype(stack::get<T>(nullptr, 0));
23209  return right.template get<optional<G>>() == left;
23210  }
23211 
23212  template <typename Table, typename Key, typename T>
23213  inline bool operator!=(T&& left, const table_proxy<Table, Key>& right) {
23214  using G = decltype(stack::get<T>(nullptr, 0));
23215  return right.template get<optional<G>>() != left;
23216  }
23217 
23218  template <typename Table, typename Key, typename T>
23219  inline bool operator!=(const table_proxy<Table, Key>& right, T&& left) {
23220  using G = decltype(stack::get<T>(nullptr, 0));
23221  return right.template get<optional<G>>() != left;
23222  }
23223 
23224  template <typename Table, typename Key>
23226  return !right.valid();
23227  }
23228 
23229  template <typename Table, typename Key>
23231  return !right.valid();
23232  }
23233 
23234  template <typename Table, typename Key>
23236  return right.valid();
23237  }
23238 
23239  template <typename Table, typename Key>
23241  return right.valid();
23242  }
23243 
23244  template <bool b>
23245  template <typename Super>
23247  basic_reference<b> v = r;
23248  this->operator=(std::move(v));
23249  return *this;
23250  }
23251 
23252  template <bool b>
23253  template <typename Super>
23255  basic_reference<b> v = r;
23256  this->operator=(std::move(v));
23257  return *this;
23258  }
23259 
23260  namespace stack {
23261  template <typename Table, typename Key>
23263  static int push(lua_State* L, const table_proxy<Table, Key>& p) {
23264  return p.push(L);
23265  }
23266  };
23267  } // namespace stack
23268 } // namespace sol
23269 
23270 // end of sol/table_proxy.hpp
23271 
23272 // beginning of sol/table_iterator.hpp
23273 
23274 #include <iterator>
23275 
23276 namespace sol {
23277 
23278  template <typename reference_type>
23280  public:
23281  typedef object key_type;
23282  typedef object mapped_type;
23283  typedef std::pair<object, object> value_type;
23284  typedef std::input_iterator_tag iterator_category;
23285  typedef std::ptrdiff_t difference_type;
23286  typedef value_type* pointer;
23287  typedef value_type& reference;
23288  typedef const value_type& const_reference;
23289 
23290  private:
23291  std::pair<object, object> kvp;
23292  reference_type ref;
23293  int tableidx = 0;
23294  int keyidx = 0;
23295  std::ptrdiff_t idx = 0;
23296 
23297  public:
23298  basic_table_iterator() : keyidx(-1), idx(-1) {
23299  }
23300 
23301  basic_table_iterator(reference_type x) : ref(std::move(x)) {
23302  ref.push();
23303  tableidx = lua_gettop(ref.lua_state());
23304  stack::push(ref.lua_state(), lua_nil);
23305  this->operator++();
23306  if (idx == -1) {
23307  return;
23308  }
23309  --idx;
23310  }
23311 
23313  if (idx == -1)
23314  return *this;
23315 
23316  if (lua_next(ref.lua_state(), tableidx) == 0) {
23317  idx = -1;
23318  keyidx = -1;
23319  return *this;
23320  }
23321  ++idx;
23322  kvp.first = object(ref.lua_state(), -2);
23323  kvp.second = object(ref.lua_state(), -1);
23324  lua_pop(ref.lua_state(), 1);
23325  // leave key on the stack
23326  keyidx = lua_gettop(ref.lua_state());
23327  return *this;
23328  }
23329 
23331  auto saved = *this;
23332  this->operator++();
23333  return saved;
23334  }
23335 
23336  reference operator*() {
23337  return kvp;
23338  }
23339 
23340  const_reference operator*() const {
23341  return kvp;
23342  }
23343 
23345  return idx == right.idx;
23346  }
23347 
23349  return idx != right.idx;
23350  }
23351 
23353  if (keyidx != -1) {
23354  stack::remove(ref.lua_state(), keyidx, 1);
23355  }
23356  if (ref.lua_state() != nullptr && ref.valid()) {
23357  stack::remove(ref.lua_state(), tableidx, 1);
23358  }
23359  }
23360  };
23361 
23362 } // namespace sol
23363 
23364 // end of sol/table_iterator.hpp
23365 
23366 namespace sol {
23367  namespace detail {
23368  template <std::size_t n>
23369  struct clean {
23371  clean(lua_State* luastate) : L(luastate) {
23372  }
23374  lua_pop(L, static_cast<int>(n));
23375  }
23376  };
23377 
23378  struct ref_clean {
23380  int& n;
23381  ref_clean(lua_State* luastate, int& n) : L(luastate), n(n) {
23382  }
23384  lua_pop(L, static_cast<int>(n));
23385  }
23386  };
23387 
23388  inline int fail_on_newindex(lua_State* L) {
23389  return luaL_error(L, "sol: cannot modify the elements of an enumeration table");
23390  }
23391 
23392  } // namespace detail
23393 
23394  template <bool top_level, typename ref_t>
23395  class basic_table_core : public basic_object<ref_t> {
23396  private:
23397  using base_t = basic_object<ref_t>;
23398 
23399  friend class state;
23400  friend class state_view;
23401  template <typename, typename>
23402  friend class basic_usertype;
23403  template <typename>
23404  friend class basic_metatable;
23405 
23406  template <bool raw, typename... Ret, typename... Keys>
23407  decltype(auto) tuple_get(int table_index, Keys&&... keys) const {
23408  if constexpr (sizeof...(Ret) < 2) {
23409  return traverse_get_single_maybe_tuple<raw, Ret...>(table_index, std::forward<Keys>(keys)...);
23410  }
23411  else {
23412  using multi_ret = decltype(stack::pop<std::tuple<Ret...>>(nullptr));
23413  return multi_ret(traverse_get_single_maybe_tuple<raw, Ret>(table_index, std::forward<Keys>(keys))...);
23414  }
23415  }
23416 
23417  template <bool raw, typename Ret, size_t... I, typename Key>
23418  decltype(auto) traverse_get_single_tuple(int table_index, std::index_sequence<I...>, Key&& key) const {
23419  return traverse_get_single<raw, Ret>(table_index, std::get<I>(std::forward<Key>(key))...);
23420  }
23421 
23422  template <bool raw, typename Ret, typename Key>
23423  decltype(auto) traverse_get_single_maybe_tuple(int table_index, Key&& key) const {
23424  if constexpr (meta::is_tuple_v<meta::unqualified_t<Key>>) {
23425  return traverse_get_single_tuple<raw, Ret>(
23426  table_index, std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<Key>>>(), std::forward<Key>(key));
23427  }
23428  else {
23429  return traverse_get_single<raw, Ret>(table_index, std::forward<Key>(key));
23430  }
23431  }
23432 
23433  template <bool raw, typename Ret, typename... Keys>
23434  decltype(auto) traverse_get_single(int table_index, Keys&&... keys) const {
23435  constexpr static bool global = top_level && (meta::count_for_to_pack_v<1, meta::is_c_str, meta::unqualified_t<Keys>...> > 0);
23437  int popcount = 0;
23438  detail::ref_clean c(base_t::lua_state(), popcount);
23439  return traverse_get_deep_optional<global, raw, detail::insert_mode::none, Ret>(popcount, table_index, std::forward<Keys>(keys)...);
23440  }
23441  else {
23442  detail::clean<sizeof...(Keys) - meta::count_for_pack_v<detail::is_insert_mode, meta::unqualified_t<Keys>...>> c(base_t::lua_state());
23443  return traverse_get_deep<global, raw, detail::insert_mode::none, Ret>(table_index, std::forward<Keys>(keys)...);
23444  }
23445  }
23446 
23447  template <bool raw, typename Pairs, std::size_t... I>
23448  void tuple_set(std::index_sequence<I...>, Pairs&& pairs) {
23449  constexpr static bool global = top_level
23450  && (meta::count_even_for_pack_v<meta::is_c_str, meta::unqualified_t<decltype(std::get<I * 2>(std::forward<Pairs>(pairs)))>...> > 0);
23451  auto pp = stack::push_pop<global>(*this);
23452  int table_index = pp.index_of(*this);
23453  lua_State* L = base_t::lua_state();
23454  (void)table_index;
23455  (void)L;
23456  void(detail::swallow { (stack::set_field<(top_level), raw>(
23457  L, std::get<I * 2>(std::forward<Pairs>(pairs)), std::get<I * 2 + 1>(std::forward<Pairs>(pairs)), table_index),
23458  0)... });
23459  }
23460 
23461  template <bool global, bool raw, detail::insert_mode mode, typename T, typename Key, typename... Keys>
23462  decltype(auto) traverse_get_deep(int table_index, Key&& key, Keys&&... keys) const {
23463  if constexpr (std::is_same_v<meta::unqualified_t<Key>, create_if_nil_t>) {
23464  (void)key;
23465  return traverse_get_deep<false, raw, static_cast<detail::insert_mode>(mode | detail::insert_mode::create_if_nil), T>(
23466  table_index, std::forward<Keys>(keys)...);
23467  }
23468  else {
23469  lua_State* L = base_t::lua_state();
23470  stack::get_field<global, raw>(L, std::forward<Key>(key), table_index);
23471  if constexpr (sizeof...(Keys) > 0) {
23472  if constexpr ((mode & detail::insert_mode::create_if_nil) == detail::insert_mode::create_if_nil) {
23473  type t = type_of(L, -1);
23474  if (t == type::lua_nil || t == type::none) {
23475  lua_pop(L, 1);
23476  stack::push(L, new_table(0, 0));
23477  }
23478  }
23479  return traverse_get_deep<false, raw, mode, T>(lua_gettop(L), std::forward<Keys>(keys)...);
23480  }
23481  else {
23482  if constexpr ((mode & detail::insert_mode::create_if_nil) == detail::insert_mode::create_if_nil) {
23483  type t = type_of(L, -1);
23484  if ((t == type::lua_nil || t == type::none) && (is_table_like_v<T>)) {
23485  lua_pop(L, 1);
23486  stack::push(L, new_table(0, 0));
23487  }
23488  }
23489  return stack::get<T>(L);
23490  }
23491  }
23492  }
23493 
23494  template <bool global, bool raw, detail::insert_mode mode, typename T, typename Key, typename... Keys>
23495  decltype(auto) traverse_get_deep_optional(int& popcount, int table_index, Key&& key, Keys&&... keys) const {
23496  if constexpr (std::is_same_v<meta::unqualified_t<Key>, create_if_nil_t>) {
23497  constexpr detail::insert_mode new_mode = static_cast<detail::insert_mode>(mode | detail::insert_mode::create_if_nil);
23498  (void)key;
23499  return traverse_get_deep_optional<global, raw, new_mode, T>(popcount, table_index, std::forward<Keys>(keys)...);
23500  }
23501  else if constexpr (std::is_same_v<meta::unqualified_t<Key>, update_if_empty_t>) {
23502  constexpr detail::insert_mode new_mode = static_cast<detail::insert_mode>(mode | detail::insert_mode::update_if_empty);
23503  (void)key;
23504  return traverse_get_deep_optional<global, raw, new_mode, T>(popcount, table_index, std::forward<Keys>(keys)...);
23505  }
23506  else if constexpr (std::is_same_v<meta::unqualified_t<Key>, override_value_t>) {
23507  constexpr detail::insert_mode new_mode = static_cast<detail::insert_mode>(mode | detail::insert_mode::override_value);
23508  (void)key;
23509  return traverse_get_deep_optional<global, raw, new_mode, T>(popcount, table_index, std::forward<Keys>(keys)...);
23510  }
23511  else {
23512  if constexpr (sizeof...(Keys) > 0) {
23513  lua_State* L = base_t::lua_state();
23514  auto p = stack::probe_get_field<global, raw>(L, std::forward<Key>(key), table_index);
23515  popcount += p.levels;
23516  if (!p.success) {
23517  if constexpr ((mode & detail::insert_mode::create_if_nil) == detail::insert_mode::create_if_nil) {
23518  lua_pop(L, 1);
23519  constexpr bool is_seq = meta::count_for_to_pack_v<1, std::is_integral, Keys...> > 0;
23520  stack::push(L, new_table(static_cast<int>(is_seq), static_cast<int>(!is_seq)));
23521  stack::set_field<global, raw>(L, std::forward<Key>(key), stack_reference(L, -1), table_index);
23522  }
23523  else {
23524  return T(nullopt);
23525  }
23526  }
23527  return traverse_get_deep_optional<false, raw, mode, T>(popcount, lua_gettop(L), std::forward<Keys>(keys)...);
23528  }
23529  else {
23530  using R = decltype(stack::get<T>(nullptr));
23531  using value_type = typename meta::unqualified_t<R>::value_type;
23532  lua_State* L = base_t::lua_state();
23533  auto p = stack::probe_get_field<global, raw, value_type>(L, key, table_index);
23534  popcount += p.levels;
23535  if (!p.success) {
23536  if constexpr ((mode & detail::insert_mode::create_if_nil) == detail::insert_mode::create_if_nil) {
23537  lua_pop(L, 1);
23538  stack::push(L, new_table(0, 0));
23539  stack::set_field<global, raw>(L, std::forward<Key>(key), stack_reference(L, -1), table_index);
23540  if (stack::check<value_type>(L, lua_gettop(L), no_panic)) {
23541  return stack::get<T>(L);
23542  }
23543  }
23544  return R(nullopt);
23545  }
23546  return stack::get<T>(L);
23547  }
23548  }
23549  }
23550 
23551  template <bool global, bool raw, detail::insert_mode mode, typename Key, typename... Keys>
23552  void traverse_set_deep(int table_index, Key&& key, Keys&&... keys) const {
23553  using KeyU = meta::unqualified_t<Key>;
23554  if constexpr (std::is_same_v<KeyU, update_if_empty_t>) {
23555  (void)key;
23556  traverse_set_deep<global, raw, static_cast<detail::insert_mode>(mode | detail::insert_mode::update_if_empty)>(
23557  table_index, std::forward<Keys>(keys)...);
23558  }
23559  else if constexpr (std::is_same_v<KeyU, create_if_nil_t>) {
23560  (void)key;
23561  traverse_set_deep<global, raw, static_cast<detail::insert_mode>(mode | detail::insert_mode::create_if_nil)>(
23562  table_index, std::forward<Keys>(keys)...);
23563  }
23564  else if constexpr (std::is_same_v<KeyU, override_value_t>) {
23565  (void)key;
23566  traverse_set_deep<global, raw, static_cast<detail::insert_mode>(mode | detail::insert_mode::override_value)>(
23567  table_index, std::forward<Keys>(keys)...);
23568  }
23569  else {
23570  lua_State* L = base_t::lua_state();
23571  if constexpr (sizeof...(Keys) == 1) {
23572  if constexpr ((mode & detail::insert_mode::update_if_empty) == detail::insert_mode::update_if_empty) {
23573  auto p = stack::probe_get_field<global, raw>(L, key, table_index);
23574  lua_pop(L, p.levels);
23575  if (!p.success) {
23576  stack::set_field<global, raw>(L, std::forward<Key>(key), std::forward<Keys>(keys)..., table_index);
23577  }
23578  }
23579  else {
23580  stack::set_field<global, raw>(L, std::forward<Key>(key), std::forward<Keys>(keys)..., table_index);
23581  }
23582  }
23583  else {
23584  if constexpr (mode != detail::insert_mode::none) {
23585  stack::get_field<global, raw>(L, key, table_index);
23586  type vt = type_of(L, -1);
23587  if constexpr ((mode & detail::insert_mode::update_if_empty) == detail::insert_mode::update_if_empty
23588  || (mode & detail::insert_mode::create_if_nil) == detail::insert_mode::create_if_nil) {
23589  if (vt == type::lua_nil || vt == type::none) {
23590  constexpr bool is_seq = meta::count_for_to_pack_v<1, std::is_integral, Keys...> > 0;
23591  lua_pop(L, 1);
23592  stack::push(L, new_table(static_cast<int>(is_seq), static_cast<int>(!is_seq)));
23593  stack::set_field<global, raw>(L, std::forward<Key>(key), stack_reference(L, -1), table_index);
23594  }
23595  }
23596  else {
23597  if (vt != type::table) {
23598  constexpr bool is_seq = meta::count_for_to_pack_v<1, std::is_integral, Keys...> > 0;
23599  lua_pop(L, 1);
23600  stack::push(L, new_table(static_cast<int>(is_seq), static_cast<int>(!is_seq)));
23601  stack::set_field<global, raw>(L, std::forward<Key>(key), stack_reference(L, -1), table_index);
23602  }
23603  }
23604  }
23605  else {
23606  stack::get_field<global, raw>(L, std::forward<Key>(key), table_index);
23607  }
23608  traverse_set_deep<false, raw, mode>(lua_gettop(L), std::forward<Keys>(keys)...);
23609  }
23610  }
23611  }
23612 
23613  basic_table_core(lua_State* L, detail::global_tag t) noexcept : base_t(L, t) {
23614  }
23615 
23616  protected:
23618  }
23619  basic_table_core(detail::no_safety_tag, lua_State* L, int index) : base_t(L, index) {
23620  }
23622  }
23623  template <typename T,
23624  meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_table_core>>, meta::neg<std::is_same<ref_t, stack_reference>>,
23625  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
23626  basic_table_core(detail::no_safety_tag, T&& r) noexcept : base_t(std::forward<T>(r)) {
23627  }
23628  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
23629  basic_table_core(detail::no_safety_tag, lua_State* L, T&& r) noexcept : base_t(L, std::forward<T>(r)) {
23630  }
23631 
23632  public:
23635 
23636  using base_t::lua_state;
23637 
23638  basic_table_core() noexcept = default;
23639  basic_table_core(const basic_table_core&) = default;
23640  basic_table_core(basic_table_core&&) = default;
23641  basic_table_core& operator=(const basic_table_core&) = default;
23642  basic_table_core& operator=(basic_table_core&&) = default;
23643  basic_table_core(const stack_reference& r) : basic_table_core(r.lua_state(), r.stack_index()) {
23644  }
23645  basic_table_core(stack_reference&& r) : basic_table_core(r.lua_state(), r.stack_index()) {
23646  }
23647  template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
23648  basic_table_core(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
23649 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
23650  auto pp = stack::push_pop(*this);
23651  int table_index = pp.index_of(*this);
23653  stack::check<basic_table_core>(lua_state(), table_index, handler);
23654 #endif // Safety
23655  }
23656  basic_table_core(lua_State* L, const new_table& nt) : base_t(L, -stack::push(L, nt)) {
23658  lua_pop(L, 1);
23659  }
23660  }
23661  basic_table_core(lua_State* L, int index = -1) : basic_table_core(detail::no_safety, L, index) {
23662 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
23664  stack::check<basic_table_core>(L, index, handler);
23665 #endif // Safety
23666  }
23667  basic_table_core(lua_State* L, ref_index index) : basic_table_core(detail::no_safety, L, index) {
23668 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
23669  auto pp = stack::push_pop(*this);
23670  int table_index = pp.index_of(*this);
23672  stack::check<basic_table_core>(lua_state(), table_index, handler);
23673 #endif // Safety
23674  }
23675  template <typename T,
23676  meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_table_core>>, meta::neg<std::is_same<ref_t, stack_reference>>,
23677  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
23678  basic_table_core(T&& r) noexcept : basic_table_core(detail::no_safety, std::forward<T>(r)) {
23679 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
23681  auto pp = stack::push_pop(*this);
23682  int table_index = pp.index_of(*this);
23684  stack::check<basic_table_core>(lua_state(), table_index, handler);
23685  }
23686 #endif // Safety
23687  }
23689  }
23690 
23691  iterator begin() const {
23692  if (this->get_type() == type::table) {
23693  return iterator(*this);
23694  }
23695  return iterator();
23696  }
23697 
23698  iterator end() const {
23699  return iterator();
23700  }
23701 
23703  return begin();
23704  }
23705 
23707  return end();
23708  }
23709 
23710  void clear() {
23711  auto pp = stack::push_pop<false>(*this);
23712  int table_index = pp.index_of(*this);
23713  stack::clear(lua_state(), table_index);
23714  }
23715 
23716  template <typename... Ret, typename... Keys>
23717  decltype(auto) get(Keys&&... keys) const {
23718  static_assert(sizeof...(Keys) == sizeof...(Ret), "number of keys and number of return types do not match");
23720  auto pp = stack::push_pop<global>(*this);
23721  int table_index = pp.index_of(*this);
23722  return tuple_get<false, Ret...>(table_index, std::forward<Keys>(keys)...);
23723  }
23724 
23725  template <typename T, typename Key>
23726  decltype(auto) get_or(Key&& key, T&& otherwise) const {
23727  typedef decltype(get<T>("")) U;
23728  optional<U> option = get<optional<U>>(std::forward<Key>(key));
23729  if (option) {
23730  return static_cast<U>(option.value());
23731  }
23732  return static_cast<U>(std::forward<T>(otherwise));
23733  }
23734 
23735  template <typename T, typename Key, typename D>
23736  decltype(auto) get_or(Key&& key, D&& otherwise) const {
23737  optional<T> option = get<optional<T>>(std::forward<Key>(key));
23738  if (option) {
23739  return static_cast<T>(option.value());
23740  }
23741  return static_cast<T>(std::forward<D>(otherwise));
23742  }
23743 
23744  template <typename T, typename... Keys>
23745  decltype(auto) traverse_get(Keys&&... keys) const {
23746  static_assert(sizeof...(Keys) > 0, "must pass at least 1 key to get");
23747  constexpr static bool global = top_level && (meta::count_for_to_pack_v<1, meta::is_c_str, meta::unqualified_t<Keys>...> > 0);
23748  auto pp = stack::push_pop<global>(*this);
23749  int table_index = pp.index_of(*this);
23750  return traverse_get_single<false, T>(table_index, std::forward<Keys>(keys)...);
23751  }
23752 
23753  template <typename... Keys>
23754  basic_table_core& traverse_set(Keys&&... keys) {
23755  static_assert(sizeof...(Keys) > 1, "must pass at least 1 key and 1 value to set");
23756  constexpr static bool global
23757  = top_level && (meta::count_when_for_to_pack_v<detail::is_not_insert_mode, 1, meta::is_c_str, meta::unqualified_t<Keys>...> > 0);
23758  auto pp = stack::push_pop<global>(*this);
23759  int table_index = pp.index_of(*this);
23760  lua_State* L = base_t::lua_state();
23761  auto pn = stack::pop_n(L, static_cast<int>(sizeof...(Keys) - 2 - meta::count_for_pack_v<detail::is_insert_mode, meta::unqualified_t<Keys>...>));
23762  traverse_set_deep<top_level, false, detail::insert_mode::none>(table_index, std::forward<Keys>(keys)...);
23763  return *this;
23764  }
23765 
23766  template <typename... Args>
23767  basic_table_core& set(Args&&... args) {
23768  if constexpr (sizeof...(Args) == 2) {
23769  traverse_set(std::forward<Args>(args)...);
23770  }
23771  else {
23772  tuple_set<false>(std::make_index_sequence<sizeof...(Args) / 2>(), std::forward_as_tuple(std::forward<Args>(args)...));
23773  }
23774  return *this;
23775  }
23776 
23777  template <typename... Ret, typename... Keys>
23778  decltype(auto) raw_get(Keys&&... keys) const {
23779  static_assert(sizeof...(Keys) == sizeof...(Ret), "number of keys and number of return types do not match");
23780  constexpr static bool global = top_level && (meta::count_for_to_pack_v<1, meta::is_c_str, meta::unqualified_t<Keys>...> > 0);
23781  auto pp = stack::push_pop<global>(*this);
23782  int table_index = pp.index_of(*this);
23783  return tuple_get<true, Ret...>(table_index, std::forward<Keys>(keys)...);
23784  }
23785 
23786  template <typename T, typename Key>
23787  decltype(auto) raw_get_or(Key&& key, T&& otherwise) const {
23788  typedef decltype(raw_get<T>("")) U;
23789  optional<U> option = raw_get<optional<U>>(std::forward<Key>(key));
23790  if (option) {
23791  return static_cast<U>(option.value());
23792  }
23793  return static_cast<U>(std::forward<T>(otherwise));
23794  }
23795 
23796  template <typename T, typename Key, typename D>
23797  decltype(auto) raw_get_or(Key&& key, D&& otherwise) const {
23798  optional<T> option = raw_get<optional<T>>(std::forward<Key>(key));
23799  if (option) {
23800  return static_cast<T>(option.value());
23801  }
23802  return static_cast<T>(std::forward<D>(otherwise));
23803  }
23804 
23805  template <typename T, typename... Keys>
23806  decltype(auto) traverse_raw_get(Keys&&... keys) const {
23807  constexpr static bool global = top_level && (meta::count_for_to_pack_v<1, meta::is_c_str, meta::unqualified_t<Keys>...> > 0);
23808  auto pp = stack::push_pop<global>(*this);
23809  int table_index = pp.index_of(*this);
23810  return traverse_get_single<true, T>(table_index, std::forward<Keys>(keys)...);
23811  }
23812 
23813  template <typename... Keys>
23814  basic_table_core& traverse_raw_set(Keys&&... keys) {
23815  constexpr static bool global = top_level && (meta::count_for_to_pack_v<1, meta::is_c_str, meta::unqualified_t<Keys>...> > 0);
23816  auto pp = stack::push_pop<global>(*this);
23817  lua_State* L = base_t::lua_state();
23818  auto pn = stack::pop_n(L, static_cast<int>(sizeof...(Keys) - 2 - meta::count_for_pack_v<detail::is_insert_mode, meta::unqualified_t<Keys>...>));
23819  traverse_set_deep<top_level, true, false>(std::forward<Keys>(keys)...);
23820  return *this;
23821  }
23822 
23823  template <typename... Args>
23824  basic_table_core& raw_set(Args&&... args) {
23825  tuple_set<true>(std::make_index_sequence<sizeof...(Args) / 2>(), std::forward_as_tuple(std::forward<Args>(args)...));
23826  return *this;
23827  }
23828 
23829  template <typename Class, typename Key>
23830  usertype<Class> new_usertype(Key&& key);
23831 
23832  template <typename Class, typename Key>
23833  usertype<Class> new_usertype(Key&& key, automagic_enrollments enrollment);
23834 
23835  template <typename Class, typename Key, typename Arg, typename... Args,
23836  typename = std::enable_if_t<!std::is_same_v<meta::unqualified_t<Arg>, automagic_enrollments>>>
23837  usertype<Class> new_usertype(Key&& key, Arg&& arg, Args&&... args);
23838 
23839  template <bool read_only = true, typename... Args>
23840  table new_enum(const string_view& name, Args&&... args) {
23841  table target = create_with(std::forward<Args>(args)...);
23842  if (read_only) {
23844  table shim = create_named(name, metatable_key, x);
23845  return shim;
23846  }
23847  else {
23848  set(name, target);
23849  return target;
23850  }
23851  }
23852 
23853  template <typename T, bool read_only = true>
23854  table new_enum(const string_view& name, std::initializer_list<std::pair<string_view, T>> items) {
23855  table target = create(static_cast<int>(items.size()), static_cast<int>(0));
23856  for (const auto& kvp : items) {
23857  target.set(kvp.first, kvp.second);
23858  }
23859  if constexpr (read_only) {
23861  table shim = create_named(name, metatable_key, x);
23862  return shim;
23863  }
23864  else {
23865  set(name, target);
23866  return target;
23867  }
23868  }
23869 
23870  template <typename Key = object, typename Value = object, typename Fx>
23871  void for_each(Fx&& fx) const {
23872  lua_State* L = base_t::lua_state();
23873  if constexpr (std::is_invocable_v<Fx, Key, Value>) {
23874  auto pp = stack::push_pop(*this);
23875  int table_index = pp.index_of(*this);
23876  stack::push(L, lua_nil);
23877  while (lua_next(L, table_index)) {
23878  Key key(L, -2);
23879  Value value(L, -1);
23880  auto pn = stack::pop_n(L, 1);
23881  fx(key, value);
23882  }
23883  }
23884  else {
23885  auto pp = stack::push_pop(*this);
23886  int table_index = pp.index_of(*this);
23887  stack::push(L, lua_nil);
23888  while (lua_next(L, table_index)) {
23889  Key key(L, -2);
23890  Value value(L, -1);
23891  auto pn = stack::pop_n(L, 1);
23892  std::pair<Key&, Value&> keyvalue(key, value);
23893  fx(keyvalue);
23894  }
23895  }
23896  }
23897 
23898  size_t size() const {
23899  auto pp = stack::push_pop(*this);
23900  int table_index = pp.index_of(*this);
23901  lua_State* L = base_t::lua_state();
23902  lua_len(L, table_index);
23903  return stack::pop<size_t>(L);
23904  }
23905 
23906  bool empty() const {
23907  return cbegin() == cend();
23908  }
23909 
23910  template <typename T>
23911  auto operator[](T&& key) & {
23912  return table_proxy<basic_table_core&, detail::proxy_key_t<T>>(*this, std::forward<T>(key));
23913  }
23914 
23915  template <typename T>
23916  auto operator[](T&& key) const& {
23917  return table_proxy<const basic_table_core&, detail::proxy_key_t<T>>(*this, std::forward<T>(key));
23918  }
23919 
23920  template <typename T>
23921  auto operator[](T&& key) && {
23922  return table_proxy<basic_table_core, detail::proxy_key_t<T>>(std::move(*this), std::forward<T>(key));
23923  }
23924 
23925  template <typename Sig, typename Key, typename... Args>
23926  basic_table_core& set_function(Key&& key, Args&&... args) {
23927  set_fx(types<Sig>(), std::forward<Key>(key), std::forward<Args>(args)...);
23928  return *this;
23929  }
23930 
23931  template <typename Key, typename... Args>
23932  basic_table_core& set_function(Key&& key, Args&&... args) {
23933  set_fx(types<>(), std::forward<Key>(key), std::forward<Args>(args)...);
23934  return *this;
23935  }
23936 
23937  template <typename... Args>
23938  basic_table_core& add(Args&&... args) {
23939  auto pp = stack::push_pop(*this);
23940  int table_index = pp.index_of(*this);
23941  lua_State* L = base_t::lua_state();
23942  (void)detail::swallow { 0, (stack::set_ref(L, std::forward<Args>(args), table_index), 0)... };
23943  return *this;
23944  }
23945 
23946  private:
23947  template <typename R, typename... Args, typename Fx, typename Key, typename = std::invoke_result_t<Fx, Args...>>
23948  void set_fx(types<R(Args...)>, Key&& key, Fx&& fx) {
23949  set_resolved_function<R(Args...)>(std::forward<Key>(key), std::forward<Fx>(fx));
23950  }
23951 
23952  template <typename Fx, typename Key, meta::enable<meta::is_specialization_of<meta::unqualified_t<Fx>, overload_set>> = meta::enabler>
23953  void set_fx(types<>, Key&& key, Fx&& fx) {
23954  set(std::forward<Key>(key), std::forward<Fx>(fx));
23955  }
23956 
23957  template <typename Fx, typename Key, typename... Args,
23959  void set_fx(types<>, Key&& key, Fx&& fx, Args&&... args) {
23960  set(std::forward<Key>(key), as_function_reference(std::forward<Fx>(fx), std::forward<Args>(args)...));
23961  }
23962 
23963  template <typename... Sig, typename... Args, typename Key>
23964  void set_resolved_function(Key&& key, Args&&... args) {
23965  set(std::forward<Key>(key), as_function_reference<function_sig<Sig...>>(std::forward<Args>(args)...));
23966  }
23967 
23968  public:
23969  static inline table create(lua_State* L, int narr = 0, int nrec = 0) {
23970  lua_createtable(L, narr, nrec);
23971  table result(L);
23972  lua_pop(L, 1);
23973  return result;
23974  }
23975 
23976  template <typename Key, typename Value, typename... Args>
23977  static inline table create(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
23978  lua_createtable(L, narr, nrec);
23979  table result(L);
23980  result.set(std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
23981  lua_pop(L, 1);
23982  return result;
23983  }
23984 
23985  template <typename... Args>
23986  static inline table create_with(lua_State* L, Args&&... args) {
23987  static_assert(sizeof...(Args) % 2 == 0, "You must have an even number of arguments for a key, value ... list.");
23988  constexpr int narr = static_cast<int>(meta::count_odd_for_pack_v<std::is_integral, Args...>);
23989  return create(L, narr, static_cast<int>((sizeof...(Args) / 2) - narr), std::forward<Args>(args)...);
23990  }
23991 
23992  table create(int narr = 0, int nrec = 0) {
23993  return create(base_t::lua_state(), narr, nrec);
23994  }
23995 
23996  template <typename Key, typename Value, typename... Args>
23997  table create(int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
23998  return create(base_t::lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
23999  }
24000 
24001  template <typename Name>
24002  table create(Name&& name, int narr = 0, int nrec = 0) {
24003  table x = create(base_t::lua_state(), narr, nrec);
24004  this->set(std::forward<Name>(name), x);
24005  return x;
24006  }
24007 
24008  template <typename Name, typename Key, typename Value, typename... Args>
24009  table create(Name&& name, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
24010  table x = create(base_t::lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
24011  this->set(std::forward<Name>(name), x);
24012  return x;
24013  }
24014 
24015  template <typename... Args>
24016  table create_with(Args&&... args) {
24017  return create_with(base_t::lua_state(), std::forward<Args>(args)...);
24018  }
24019 
24020  template <typename Name, typename... Args>
24021  table create_named(Name&& name, Args&&... args) {
24022  static const int narr = static_cast<int>(meta::count_even_for_pack_v<std::is_integral, Args...>);
24023  return create(std::forward<Name>(name), narr, (sizeof...(Args) / 2) - narr, std::forward<Args>(args)...);
24024  }
24025  };
24026 } // namespace sol
24027 
24028 // end of sol/table_core.hpp
24029 
24030 namespace sol {
24031 
24032  template <typename base_type>
24033  class basic_metatable : public basic_table<base_type> {
24035  friend class state;
24036  friend class state_view;
24037 
24038  protected:
24040  }
24041  basic_metatable(detail::no_safety_tag, lua_State* L, int index) : base_t(L, index) {
24042  }
24044  }
24045  template <typename T,
24046  meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_metatable>>, meta::neg<std::is_same<base_type, stack_reference>>,
24047  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
24048  basic_metatable(detail::no_safety_tag, T&& r) noexcept : base_t(std::forward<T>(r)) {
24049  }
24050  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
24051  basic_metatable(detail::no_safety_tag, lua_State* L, T&& r) noexcept : base_t(L, std::forward<T>(r)) {
24052  }
24053 
24054  public:
24055  using base_t::lua_state;
24056 
24057  basic_metatable() noexcept = default;
24058  basic_metatable(const basic_metatable&) = default;
24059  basic_metatable(basic_metatable&&) = default;
24060  basic_metatable& operator=(const basic_metatable&) = default;
24061  basic_metatable& operator=(basic_metatable&&) = default;
24062  basic_metatable(const stack_reference& r) : basic_metatable(r.lua_state(), r.stack_index()) {
24063  }
24064  basic_metatable(stack_reference&& r) : basic_metatable(r.lua_state(), r.stack_index()) {
24065  }
24066  template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
24067  basic_metatable(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
24068 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
24069  auto pp = stack::push_pop(*this);
24071  stack::check<basic_metatable>(lua_state(), -1, handler);
24072 #endif // Safety
24073  }
24074  basic_metatable(lua_State* L, int index = -1) : basic_metatable(detail::no_safety, L, index) {
24075 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
24077  stack::check<basic_metatable>(L, index, handler);
24078 #endif // Safety
24079  }
24080  basic_metatable(lua_State* L, ref_index index) : basic_metatable(detail::no_safety, L, index) {
24081 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
24082  auto pp = stack::push_pop(*this);
24084  stack::check<basic_metatable>(lua_state(), -1, handler);
24085 #endif // Safety
24086  }
24087  template <typename T,
24088  meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_metatable>>, meta::neg<std::is_same<base_type, stack_reference>>,
24089  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
24090  basic_metatable(T&& r) noexcept : basic_metatable(detail::no_safety, std::forward<T>(r)) {
24091 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
24093  auto pp = stack::push_pop(*this);
24095  stack::check<basic_metatable>(base_t::lua_state(), -1, handler);
24096  }
24097 #endif // Safety
24098  }
24100  }
24101 
24102  template <typename Key, typename Value>
24103  void set(Key&& key, Value&& value);
24104 
24105  void unregister() {
24106  using ustorage_base = u_detail::usertype_storage_base;
24107 
24108  lua_State* L = this->lua_state();
24109 
24110  auto pp = stack::push_pop(*this);
24111  int top = lua_gettop(L);
24112 
24113  stack_reference mt(L, -1);
24115  if (type_of(L, -1) != type::table) {
24116  return;
24117  }
24118  stack_reference gc_names_table(L, -1);
24120  if (type_of(L, -1) != type::lightuserdata) {
24121  return;
24122  }
24123  ustorage_base& base_storage = *static_cast<ustorage_base*>(stack::get<void*>(L, -1));
24124  std::array<string_view, 6> registry_traits;
24125  for (std::size_t i = 0; i < registry_traits.size(); ++i) {
24127  stack::get_field<false, true>(L, smt, gc_names_table.stack_index());
24128  registry_traits[i] = stack::get<string_view>(L, -1);
24129  }
24130 
24131  // get the registry
24133  registry.push();
24134  // eliminate all named entries for this usertype
24135  // in the registry (luaL_newmetatable does
24136  // [name] = new table
24137  // in registry upon creation)
24138  for (std::size_t i = 0; i < registry_traits.size(); ++i) {
24140  const string_view& gcmetakey = registry_traits[i];
24142  // use .data() to make it treat it like a c string,
24143  // which it is...
24144  stack::set_field<true>(L, gcmetakey.data(), lua_nil);
24145  }
24146  else {
24147  // do not change the values in the registry: they need to be present
24148  // no matter what, for safety's sake
24149  //stack::set_field(L, gcmetakey, lua_nil, registry.stack_index());
24150  }
24151  }
24152 
24153  // destroy all storage and tables
24154  base_storage.clear();
24155 
24156  // 6 strings from gc_names table,
24157  // + 1 registry,
24158  // + 1 gc_names table
24159  // + 1 light userdata of storage
24160  // + 1 registry
24161  // 10 total, 4 left since popping off 6 gc_names tables
24162  lua_settop(L, top);
24163  }
24164  };
24165 
24166 } // namespace sol
24167 
24168 // end of sol/metatable.hpp
24169 
24170 namespace sol {
24171 
24172  template <typename T, typename base_type>
24173  class basic_usertype : private basic_metatable<base_type> {
24174  private:
24177 
24178  template <typename>
24179  friend class basic_metatable;
24180 
24181  template <bool, typename>
24182  friend class basic_table_core;
24183 
24184  template <std::size_t... I, typename... Args>
24185  void tuple_set(std::index_sequence<I...>, std::tuple<Args...>&& args) {
24186  (void)args;
24187  (void)detail::swallow{ 0,
24188  (this->set(std::get<I * 2>(std::move(args)), std::get<I * 2 + 1>(std::move(args))), 0)... };
24189  }
24190 
24191  public:
24192  using base_t::base_t;
24193 
24194  using base_t::pop;
24195  using base_t::push;
24196  using base_t::lua_state;
24197  using base_t::get;
24198  using base_t::set_function;
24199  using base_t::traverse_set;
24200  using base_t::traverse_get;
24201  using base_t::unregister;
24202 
24203  template <typename Key, typename Value>
24204  void set(Key&& key, Value&& value) {
24205  optional<u_detail::usertype_storage<T>&> maybe_uts = u_detail::maybe_get_usertype_storage<T>(this->lua_state());
24206  if (maybe_uts) {
24207  u_detail::usertype_storage<T>& uts = *maybe_uts;
24208  uts.set(this->lua_state(), std::forward<Key>(key), std::forward<Value>(value));
24209  }
24210  else {
24211  using ValueU = meta::unqualified_t<Value>;
24212  // cannot get metatable: try regular table set?
24213  if constexpr (detail::is_non_factory_constructor_v<ValueU> || detail::is_policy_v<ValueU>) {
24214  // tag constructors so we don't get destroyed by lack of info
24215  table_base_t::set(std::forward<Key>(key), detail::tagged<T, Value>(std::forward<Value>(value)));
24216  }
24217  else {
24218  table_base_t::set(std::forward<Key>(key), std::forward<Value>(value));
24219  }
24220  }
24221  }
24222 
24223  template <typename Key>
24225  return usertype_proxy<basic_usertype&, std::decay_t<Key>>(*this, std::forward<Key>(key));
24226  }
24227 
24228  template <typename Key>
24230  return usertype_proxy<const basic_usertype&, std::decay_t<Key>>(*this, std::forward<Key>(key));
24231  }
24232  };
24233 
24234 } // namespace sol
24235 
24236 // end of sol/usertype.hpp
24237 
24238 // beginning of sol/table.hpp
24239 
24240 // beginning of sol/lua_table.hpp
24241 
24242 namespace sol {
24243 
24244  template <typename ref_t>
24245  struct basic_lua_table : basic_table_core<false, ref_t> {
24246  private:
24248 
24249  friend class state;
24250  friend class state_view;
24251 
24252  public:
24253  using base_t::lua_state;
24254 
24255  basic_lua_table() noexcept = default;
24256  basic_lua_table(const basic_lua_table&) = default;
24257  basic_lua_table(basic_lua_table&&) = default;
24258  basic_lua_table& operator=(const basic_lua_table&) = default;
24259  basic_lua_table& operator=(basic_lua_table&&) = default;
24260  basic_lua_table(const stack_reference& r) : basic_lua_table(r.lua_state(), r.stack_index()) {
24261  }
24262  basic_lua_table(stack_reference&& r) : basic_lua_table(r.lua_state(), r.stack_index()) {
24263  }
24264  template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
24265  basic_lua_table(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
24266 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
24267  auto pp = stack::push_pop(*this);
24269  stack::check<basic_lua_table>(lua_state(), -1, handler);
24270 #endif // Safety
24271  }
24272  basic_lua_table(lua_State* L, const new_table& nt) : base_t(L, nt) {
24274  lua_pop(L, 1);
24275  }
24276  }
24277  basic_lua_table(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
24278 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
24280  stack::check<basic_lua_table>(L, index, handler);
24281 #endif // Safety
24282  }
24283  basic_lua_table(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
24284 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
24285  auto pp = stack::push_pop(*this);
24287  stack::check<basic_lua_table>(lua_state(), -1, handler);
24288 #endif // Safety
24289  }
24290  template <typename T,
24291  meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_lua_table>>, meta::neg<std::is_same<ref_t, stack_reference>>,
24292  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
24293  basic_lua_table(T&& r) noexcept : basic_lua_table(detail::no_safety, std::forward<T>(r)) {
24294 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
24296  auto pp = stack::push_pop(*this);
24298  stack::check<basic_lua_table>(lua_state(), -1, handler);
24299  }
24300 #endif // Safety
24301  }
24303  }
24304  };
24305 
24306 }
24307 
24308 // end of sol/lua_table.hpp
24309 
24310 namespace sol {
24311  typedef table_core<false> table;
24312 
24313  template <bool is_global, typename base_type>
24314  template <typename Class, typename Key>
24316  automagic_enrollments enrollments;
24317  return this->new_usertype<Class>(std::forward<Key>(key), std::move(enrollments));
24318  }
24319 
24320  template <bool is_global, typename base_type>
24321  template <typename Class, typename Key>
24323  int mt_index = u_detail::register_usertype<Class>(this->lua_state(), std::move(enrollments));
24324  usertype<Class> mt(this->lua_state(), -mt_index);
24325  lua_pop(this->lua_state(), 1);
24326  set(std::forward<Key>(key), mt);
24327  return mt;
24328  }
24329 
24330  template <bool is_global, typename base_type>
24331  template <typename Class, typename Key, typename Arg, typename... Args, typename>
24333  automagic_enrollments enrollments;
24334  enrollments.default_constructor = !detail::any_is_constructor_v<Arg, Args...>;
24335  enrollments.destructor = !detail::any_is_destructor_v<Arg, Args...>;
24336  usertype<Class> ut = this->new_usertype<Class>(std::forward<Key>(key), std::move(enrollments));
24337  static_assert(sizeof...(Args) % 2 == static_cast<std::size_t>(!detail::any_is_constructor_v<Arg>),
24338  "you must pass an even number of arguments to new_usertype after first passing a constructor");
24339  if constexpr (detail::any_is_constructor_v<Arg>) {
24340  ut.set(meta_function::construct, std::forward<Arg>(arg));
24341  ut.tuple_set(std::make_index_sequence<(sizeof...(Args)) / 2>(), std::forward_as_tuple(std::forward<Args>(args)...));
24342  }
24343  else {
24344  ut.tuple_set(std::make_index_sequence<(sizeof...(Args) + 1) / 2>(), std::forward_as_tuple(std::forward<Arg>(arg), std::forward<Args>(args)...));
24345  }
24346  return ut;
24347  }
24348 
24349  template <typename base_type>
24350  template <typename Key, typename Value>
24351  void basic_metatable<base_type>::set(Key&& key, Value&& value) {
24352  this->push();
24353  lua_State* L = this->lua_state();
24354  int target = lua_gettop(L);
24356  lua_pop(L, 1);
24357  if (maybe_uts) {
24358  u_detail::usertype_storage_base& uts = *maybe_uts;
24359  uts.set(L, std::forward<Key>(key), std::forward<Value>(value));
24360  }
24361  else {
24362  base_t::set(std::forward<Key>(key), std::forward<Value>(value));
24363  }
24364  }
24365 
24366  namespace stack {
24367  template <>
24369  static table get(lua_State* L, int index = -1) {
24370  if (lua_getmetatable(L, index) == 0) {
24371  return table(L, ref_index(LUA_REFNIL));
24372  }
24373  return table(L, -1);
24374  }
24375  };
24376  } // namespace stack
24377 } // namespace sol
24378 
24379 // end of sol/table.hpp
24380 
24381 // beginning of sol/state.hpp
24382 
24383 // beginning of sol/state_view.hpp
24384 
24385 // beginning of sol/environment.hpp
24386 
24387 namespace sol {
24388 
24389  template <typename base_type>
24390  struct basic_environment : basic_table<base_type> {
24391  private:
24393 
24394  public:
24395  using base_t::lua_state;
24396 
24397  basic_environment() noexcept = default;
24398  basic_environment(const basic_environment&) = default;
24399  basic_environment(basic_environment&&) = default;
24400  basic_environment& operator=(const basic_environment&) = default;
24401  basic_environment& operator=(basic_environment&&) = default;
24402  basic_environment(const stack_reference& r) : basic_environment(r.lua_state(), r.stack_index()) {
24403  }
24404  basic_environment(stack_reference&& r) : basic_environment(r.lua_state(), r.stack_index()) {
24405  }
24406 
24407  basic_environment(lua_State* L, new_table nt) : base_t(L, std::move(nt)) {
24408  }
24409  template <bool b>
24411  stack_table mt(L, new_table(0, 1));
24412  mt.set(meta_function::index, fallback);
24413  this->set(metatable_key, mt);
24414  mt.pop();
24415  }
24416 
24417  basic_environment(env_key_t, const stack_reference& extraction_target)
24418  : base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
24419 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
24421  stack::check<env_key_t>(this->lua_state(), -1, handler);
24422 #endif // Safety
24423  lua_pop(this->lua_state(), 2);
24424  }
24425  template <bool b>
24427  : base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
24428 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
24430  stack::check<env_key_t>(this->lua_state(), -1, handler);
24431 #endif // Safety
24432  lua_pop(this->lua_state(), 2);
24433  }
24434  basic_environment(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
24435 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
24437  stack::check<basic_environment>(L, index, handler);
24438 #endif // Safety
24439  }
24440  basic_environment(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
24441 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
24442  auto pp = stack::push_pop(*this);
24444  stack::check<basic_environment>(L, -1, handler);
24445 #endif // Safety
24446  }
24447  template <typename T,
24448  meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_environment>>, meta::neg<std::is_same<base_type, stack_reference>>,
24449  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
24450  basic_environment(T&& r) noexcept : base_t(detail::no_safety, std::forward<T>(r)) {
24451 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
24453  auto pp = stack::push_pop(*this);
24455  stack::check<basic_environment>(lua_state(), -1, handler);
24456  }
24457 #endif // Safety
24458  }
24459  basic_environment(lua_nil_t r) noexcept : base_t(detail::no_safety, r) {
24460  }
24461 
24462  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
24463  basic_environment(lua_State* L, T&& r) noexcept : base_t(detail::no_safety, L, std::forward<T>(r)) {
24464 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
24466  auto pp = stack::push_pop(*this);
24468  stack::check<basic_environment>(lua_state(), -1, handler);
24469  }
24470 #endif // Safety
24471  }
24472 
24473  template <typename T>
24474  void set_on(const T& target) const {
24475  lua_State* L = target.lua_state();
24476  auto pp = stack::push_pop(target);
24477 #if SOL_LUA_VESION_I_ < 502
24478  // Use lua_setfenv
24479  this->push();
24480  lua_setfenv(L, -2);
24481 #else
24482  // Use upvalues as explained in Lua 5.2 and beyond's manual
24483  this->push();
24484  const char* name = lua_setupvalue(L, -2, 1);
24485  if (name == nullptr) {
24486  this->pop();
24487  }
24488 #endif
24489  }
24490  };
24491 
24492  template <typename T, typename E>
24493  void set_environment(const basic_environment<E>& env, const T& target) {
24494  env.set_on(target);
24495  }
24496 
24497  template <typename E = reference, typename T>
24499  lua_State* L = target.lua_state();
24500  auto pp = stack::pop_n(L, stack::push_environment_of(target));
24501  return basic_environment<E>(L, -1);
24502  }
24503 
24506 
24508  }
24510  }
24511  this_environment(const this_environment&) = default;
24512  this_environment(this_environment&&) = default;
24513  this_environment& operator=(const this_environment&) = default;
24514  this_environment& operator=(this_environment&&) = default;
24515 
24516  explicit operator bool() const {
24517  return static_cast<bool>(env);
24518  }
24519 
24520  operator optional<environment> &() {
24521  return env;
24522  }
24523 
24524  operator const optional<environment> &() const {
24525  return env;
24526  }
24527 
24528  operator environment&() {
24529  return env.value();
24530  }
24531 
24532  operator const environment&() const {
24533  return env.value();
24534  }
24535  };
24536 
24537  namespace stack {
24538  template <>
24540  static environment get(lua_State* L, int index, record& tracking) {
24541  tracking.use(1);
24542  return get_environment(stack_reference(L, raw_index(index)));
24543  }
24544  };
24545 
24546  template <>
24548  static this_environment get(lua_State* L, int, record& tracking) {
24549  tracking.use(0);
24550  lua_Debug info;
24551  // Level 0 means current function (this C function, which may or may not be useful for us?)
24552  // Level 1 means next call frame up the stack. (Can be nothing if function called directly from C++ with lua_p/call)
24553  int pre_stack_size = lua_gettop(L);
24554  if (lua_getstack(L, 1, &info) != 1) {
24555  if (lua_getstack(L, 0, &info) != 1) {
24556  lua_settop(L, pre_stack_size);
24557  return this_environment();
24558  }
24559  }
24560  if (lua_getinfo(L, "f", &info) == 0) {
24561  lua_settop(L, pre_stack_size);
24562  return this_environment();
24563  }
24564 
24565  stack_reference f(L, -1);
24566  environment env(env_key, f);
24567  if (!env.valid()) {
24568  lua_settop(L, pre_stack_size);
24569  return this_environment();
24570  }
24571  return this_environment(std::move(env));
24572  }
24573  };
24574  } // namespace stack
24575 } // namespace sol
24576 
24577 // end of sol/environment.hpp
24578 
24579 // beginning of sol/load_result.hpp
24580 
24581 #include <cstdint>
24582 
24583 namespace sol {
24584  struct load_result : public proxy_base<load_result> {
24585  private:
24587  int index;
24591 
24592  public:
24593  load_result() noexcept = default;
24594  load_result(lua_State* Ls, int stackindex = -1, int retnum = 0, int popnum = 0, load_status lerr = load_status::ok) noexcept
24595  : L(Ls), index(stackindex), returncount(retnum), popcount(popnum), err(lerr) {
24596  }
24597 
24598  // We do not want anyone to copy these around willy-nilly
24599  // Will likely break people, but also will probably get rid of quiet bugs that have
24600  // been lurking. (E.g., Vanilla Lua will just quietly discard over-pops and under-pops:
24601  // LuaJIT and other Lua engines will implode and segfault at random later times.)
24602  load_result(const load_result&) = delete;
24603  load_result& operator=(const load_result&) = delete;
24604 
24605  load_result(load_result&& o) noexcept : L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) {
24606  // Must be manual, otherwise destructor will screw us
24607  // return count being 0 is enough to keep things clean
24608  // but we will be thorough
24609  o.L = nullptr;
24610  o.index = 0;
24611  o.returncount = 0;
24612  o.popcount = 0;
24613  o.err = load_status::syntax;
24614  }
24616  L = o.L;
24617  index = o.index;
24618  returncount = o.returncount;
24619  popcount = o.popcount;
24620  err = o.err;
24621  // Must be manual, otherwise destructor will screw us
24622  // return count being 0 is enough to keep things clean
24623  // but we will be thorough
24624  o.L = nullptr;
24625  o.index = 0;
24626  o.returncount = 0;
24627  o.popcount = 0;
24628  o.err = load_status::syntax;
24629  return *this;
24630  }
24631 
24632  load_status status() const noexcept {
24633  return err;
24634  }
24635 
24636  bool valid() const noexcept {
24637  return status() == load_status::ok;
24638  }
24639 
24640  template <typename T>
24641  T get() const {
24642  using UT = meta::unqualified_t<T>;
24643  if constexpr (meta::is_optional_v<UT>) {
24644  using ValueType = typename UT::value_type;
24645  if constexpr (std::is_same_v<ValueType, error>) {
24646  if (valid()) {
24647  return UT(nullopt);
24648  }
24649  return error(detail::direct_error, stack::get<std::string>(L, index));
24650  }
24651  else {
24652  if (!valid()) {
24653  return UT(nullopt);
24654  }
24655  return stack::get<UT>(L, index);
24656  }
24657  }
24658  else {
24659  if constexpr (std::is_same_v<T, error>) {
24660 #if SOL_IS_ON(SOL_SAFE_PROXIES_I_)
24661  if (valid()) {
24662  type_panic_c_str(L, index, type_of(L, index), type::none, "expecting an error type (a string, from Lua)");
24663  }
24664 #endif // Check proxy type's safety
24665  return error(detail::direct_error, stack::get<std::string>(L, index));
24666  }
24667  else {
24668 #if SOL_IS_ON(SOL_SAFE_PROXIES_I_)
24669  if (!valid()) {
24670  type_panic_c_str(L, index, type_of(L, index), type::none);
24671  }
24672 #endif // Check proxy type's safety
24673  return stack::get<T>(L, index);
24674  }
24675  }
24676  }
24677 
24678  template <typename... Ret, typename... Args>
24679  decltype(auto) call(Args&&... args) {
24680 #if !defined(__clang__) && defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 191200000
24681  // MSVC is ass sometimes
24682  return get<protected_function>().call<Ret...>(std::forward<Args>(args)...);
24683 #else
24684  return get<protected_function>().template call<Ret...>(std::forward<Args>(args)...);
24685 #endif
24686  }
24687 
24688  template <typename... Args>
24689  decltype(auto) operator()(Args&&... args) {
24690  return call<>(std::forward<Args>(args)...);
24691  }
24692 
24693  lua_State* lua_state() const noexcept {
24694  return L;
24695  };
24696  int stack_index() const noexcept {
24697  return index;
24698  };
24699 
24701  stack::remove(L, index, popcount);
24702  }
24703  };
24704 } // namespace sol
24705 
24706 // end of sol/load_result.hpp
24707 
24708 // beginning of sol/state_handling.hpp
24709 
24710 // beginning of sol/lua_value.hpp
24711 
24712 namespace sol {
24713  struct lua_value {
24714  public:
24715  struct arr : detail::ebco<std::initializer_list<lua_value>> {
24716  private:
24718 
24719  public:
24720  using base_t::base_t;
24721  };
24722 
24723  private:
24724  template <typename T>
24726  = meta::any<meta::is_specialization_of<T, std::initializer_list>, std::is_same<T, reference>, std::is_same<T, arr>>;
24727 
24728  template <typename T>
24730 
24732 #if SOL_IS_ON(SOL_USE_THREAD_LOCAL_I_)
24733  static thread_local lua_State* L = nullptr;
24734 #else
24735  static lua_State* L = nullptr;
24736 #endif
24737  return L;
24738  }
24739 
24741 
24742  public:
24743  static void set_lua_state(lua_State* L) {
24744  thread_local_lua_state() = L;
24745  }
24746 
24747  template <typename T, meta::disable<is_reference_or_lua_value_init_list<meta::unqualified_t<T>>> = meta::enabler>
24748  lua_value(lua_State* L_, T&& value) : lua_value(((set_lua_state(L_)), std::forward<T>(value))) {
24749  }
24750 
24751  template <typename T, meta::disable<is_lua_value_single_constructible<meta::unqualified_t<T>>> = meta::enabler>
24752  lua_value(T&& value) : ref_value(make_reference(thread_local_lua_state(), std::forward<T>(value))) {
24753  }
24754 
24755  lua_value(lua_State* L_, std::initializer_list<std::pair<lua_value, lua_value>> il)
24756  : lua_value([&L_, &il]() {
24757  set_lua_state(L_);
24758  return std::move(il);
24759  }()) {
24760  }
24761 
24762  lua_value(std::initializer_list<std::pair<lua_value, lua_value>> il) : ref_value(make_reference(thread_local_lua_state(), std::move(il))) {
24763  }
24764 
24766  : lua_value([&L_, &il]() {
24767  set_lua_state(L_);
24768  return std::move(il);
24769  }()) {
24770  }
24771 
24772  lua_value(arr il) : ref_value(make_reference(thread_local_lua_state(), std::move(il.value()))) {
24773  }
24774 
24776  : lua_value([&L_, &r]() {
24777  set_lua_state(L_);
24778  return std::move(r);
24779  }()) {
24780  }
24781 
24782  lua_value(reference r) : ref_value(std::move(r)) {
24783  }
24784 
24785  lua_value(const lua_value&) noexcept = default;
24786  lua_value(lua_value&&) = default;
24787  lua_value& operator=(const lua_value&) = default;
24788  lua_value& operator=(lua_value&&) = default;
24789 
24790  const reference& value() const& {
24791  return ref_value;
24792  }
24793 
24795  return ref_value;
24796  }
24797 
24798  reference&& value() && {
24799  return std::move(ref_value);
24800  }
24801 
24802  template <typename T>
24803  decltype(auto) as() const {
24804  ref_value.push();
24805  return stack::pop<T>(ref_value.lua_state());
24806  }
24807 
24808  template <typename T>
24809  bool is() const {
24810  int r = ref_value.registry_index();
24811  if (r == LUA_REFNIL)
24812  return meta::any_same<meta::unqualified_t<T>, lua_nil_t, nullopt_t, std::nullptr_t>::value ? true : false;
24813  if (r == LUA_NOREF)
24814  return false;
24815  auto pp = stack::push_pop(ref_value);
24816  return stack::check<T>(ref_value.lua_state(), -1, no_panic);
24817  }
24818  };
24819 
24820  using array_value = typename lua_value::arr;
24821 
24822  namespace stack {
24823  template <>
24825  static int push(lua_State* L, const lua_value& lv) {
24826  return stack::push(L, lv.value());
24827  }
24828 
24829  static int push(lua_State* L, lua_value&& lv) {
24830  return stack::push(L, std::move(lv).value());
24831  }
24832  };
24833 
24834  template <>
24836  static lua_value get(lua_State* L, int index, record& tracking) {
24837  return lua_value(L, stack::get<reference>(L, index, tracking));
24838  }
24839  };
24840  } // namespace stack
24841 } // namespace sol
24842 
24843 // end of sol/lua_value.hpp
24844 
24845 #if SOL_IS_ON(SOL_PRINT_ERRORS_I_)
24846 #include <iostream>
24847 #endif
24848 
24849 namespace sol {
24851 #if SOL_LUA_VESION_I_ < 502
24852  if (L == nullptr) {
24853  lua_pushnil(L);
24855  return;
24856  }
24857  lua_pushthread(L);
24859 #else
24860  (void)L;
24861 #endif
24862  }
24863 
24864  inline int default_at_panic(lua_State* L) {
24865 #if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
24866  (void)L;
24867  return -1;
24868 #else
24869  size_t messagesize;
24870  const char* message = lua_tolstring(L, -1, &messagesize);
24871  if (message) {
24872  std::string err(message, messagesize);
24873  lua_settop(L, 0);
24874 #if SOL_IS_ON(SOL_PRINT_ERRORS_I_)
24875  std::cerr << "[sol3] An error occurred and panic has been invoked: ";
24876  std::cerr << err;
24877  std::cerr << std::endl;
24878 #endif
24879  throw error(err);
24880  }
24881  lua_settop(L, 0);
24882  throw error(std::string("An unexpected error occurred and panic has been invoked"));
24883 #endif // Printing Errors
24884  }
24885 
24887  std::string msg = "An unknown error has triggered the default error handler";
24888  optional<string_view> maybetopmsg = stack::unqualified_check_get<string_view>(L, 1, no_panic);
24889  if (maybetopmsg) {
24890  const string_view& topmsg = maybetopmsg.value();
24891  msg.assign(topmsg.data(), topmsg.size());
24892  }
24893  luaL_traceback(L, L, msg.c_str(), 1);
24894  optional<string_view> maybetraceback = stack::unqualified_check_get<string_view>(L, -1, no_panic);
24895  if (maybetraceback) {
24896  const string_view& traceback = maybetraceback.value();
24897  msg.assign(traceback.data(), traceback.size());
24898  }
24899 #if SOL_IS_ON(SOL_PRINT_ERRORS_I_)
24900  // std::cerr << "[sol3] An error occurred and was caught in traceback: ";
24901  // std::cerr << msg;
24902  // std::cerr << std::endl;
24903 #endif // Printing
24904  return stack::push(L, msg);
24905  }
24906 
24907  inline void set_default_state(lua_State* L, lua_CFunction panic_function = &default_at_panic,
24910  lua_atpanic(L, panic_function);
24911  protected_function::set_default_handler(object(L, in_place, traceback_function));
24916  }
24917 
24918  inline std::size_t total_memory_used(lua_State* L) {
24919  std::size_t kb = lua_gc(L, LUA_GCCOUNT, 0);
24920  kb *= 1024;
24921  kb += lua_gc(L, LUA_GCCOUNTB, 0);
24922  return kb;
24923  }
24924 
24926  return result;
24927  }
24928 
24930  type t = type_of(L, result.stack_index());
24931  std::string err = "sol: ";
24932  err += to_string(result.status());
24933  err += " error";
24934 #if SOL_IS_ON(SOL_EXCEPTIONS_I_)
24935  std::exception_ptr eptr = std::current_exception();
24936  if (eptr) {
24937  err += " with a ";
24938  try {
24939  std::rethrow_exception(eptr);
24940  }
24941  catch (const std::exception& ex) {
24942  err += "std::exception -- ";
24943  err.append(ex.what());
24944  }
24945  catch (const std::string& message) {
24946  err += "thrown message -- ";
24947  err.append(message);
24948  }
24949  catch (const char* message) {
24950  err += "thrown message -- ";
24951  err.append(message);
24952  }
24953  catch (...) {
24954  err.append("thrown but unknown type, cannot serialize into error message");
24955  }
24956  }
24957 #endif // serialize exception information if possible
24958  if (t == type::string) {
24959  err += ": ";
24960  string_view serr = stack::unqualified_get<string_view>(L, result.stack_index());
24961  err.append(serr.data(), serr.size());
24962  }
24963 #if SOL_IS_ON(SOL_PRINT_ERRORS_I_)
24964  std::cerr << "[sol3] An error occurred and has been passed to an error handler: ";
24965  std::cerr << err;
24966  std::cerr << std::endl;
24967 #endif
24968  // replacing information of stack error into pfr
24969  int target = result.stack_index();
24970  if (result.pop_count() > 0) {
24971  stack::remove(L, target, result.pop_count());
24972  }
24973  stack::push(L, err);
24974  int top = lua_gettop(L);
24975  int towards = top - target;
24976  if (towards != 0) {
24977  lua_rotate(L, top, towards);
24978  }
24979 #if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
24980  return result;
24981 #else
24982  // just throw our error
24983  throw error(detail::direct_error, err);
24984 #endif // If exceptions are allowed
24985  }
24986 
24988 #if SOL_IS_ON(SOL_DEFAULT_PASS_ON_ERROR_I_)
24989  return script_pass_on_error(L, std::move(pfr));
24990 #else
24991  return script_throw_on_error(L, std::move(pfr));
24992 #endif
24993  }
24994 
24995  namespace stack {
24998  sol::error err = stack::get<sol::error>(L, -p);
24999  lua_pop(L, p);
25000  return err;
25001  }
25002  } // namespace stack
25003 } // namespace sol
25004 
25005 // end of sol/state_handling.hpp
25006 
25007 #include <memory>
25008 #include <cstddef>
25009 
25010 namespace sol {
25011 
25012  class state_view {
25013  private:
25017 
25019  auto loaded = reg.traverse_get<optional<object>>("_LOADED", key);
25020  bool is53mod = loaded && !(loaded->is<bool>() && !loaded->as<bool>());
25021  if (is53mod)
25022  return loaded;
25023 #if SOL_LUA_VESION_I_ <= 501
25024  auto loaded51 = global.traverse_get<optional<object>>("package", "loaded", key);
25025  bool is51mod = loaded51 && !(loaded51->is<bool>() && !loaded51->as<bool>());
25026  if (is51mod)
25027  return loaded51;
25028 #endif
25029  return nullopt;
25030  }
25031 
25032  template <typename T>
25033  void ensure_package(const std::string& key, T&& sr) {
25034 #if SOL_LUA_VESION_I_ <= 501
25035  auto pkg = global["package"];
25036  if (!pkg.valid()) {
25037  pkg = create_table_with("loaded", create_table_with(key, sr));
25038  }
25039  else {
25040  auto ld = pkg["loaded"];
25041  if (!ld.valid()) {
25042  ld = create_table_with(key, sr);
25043  }
25044  else {
25045  ld[key] = sr;
25046  }
25047  }
25048 #endif
25049  auto loaded = reg["_LOADED"];
25050  if (!loaded.valid()) {
25051  loaded = create_table_with(key, sr);
25052  }
25053  else {
25054  loaded[key] = sr;
25055  }
25056  }
25057 
25058  template <typename Fx>
25059  object require_core(const std::string& key, Fx&& action, bool create_global = true) {
25060  optional<object> loaded = is_loaded_package(key);
25061  if (loaded && loaded->valid())
25062  return std::move(*loaded);
25063  action();
25064  stack_reference sr(L, -1);
25065  if (create_global)
25066  set(key, sr);
25067  ensure_package(key, sr);
25068  return stack::pop<object>(L);
25069  }
25070 
25071  public:
25074 
25075  state_view(lua_State* Ls) : L(Ls), reg(Ls, LUA_REGISTRYINDEX), global(Ls, detail::global_) {
25076  }
25077 
25079  }
25080 
25082  return L;
25083  }
25084 
25085  template <typename... Args>
25086  void open_libraries(Args&&... args) {
25087  static_assert(meta::all_same<lib, meta::unqualified_t<Args>...>::value, "all types must be libraries");
25088  if constexpr (sizeof...(args) == 0) {
25089  luaL_openlibs(L);
25090  return;
25091  }
25092  else {
25093  lib libraries[1 + sizeof...(args)] = { lib::count, std::forward<Args>(args)... };
25094 
25095  for (auto&& library : libraries) {
25096  switch (library) {
25097 #if SOL_LUA_VESION_I_ <= 501 && defined(SOL_LUAJIT)
25098  case lib::coroutine:
25099 #endif // luajit opens coroutine base stuff
25100  case lib::base:
25101  luaL_requiref(L, "base", luaopen_base, 1);
25102  lua_pop(L, 1);
25103  break;
25104  case lib::package:
25105  luaL_requiref(L, "package", luaopen_package, 1);
25106  lua_pop(L, 1);
25107  break;
25108 #if !defined(SOL_LUAJIT)
25109  case lib::coroutine:
25110 #if SOL_LUA_VESION_I_ > 501
25111  luaL_requiref(L, "coroutine", luaopen_coroutine, 1);
25112  lua_pop(L, 1);
25113 #endif // Lua 5.2+ only
25114  break;
25115 #endif // Not LuaJIT - comes builtin
25116  case lib::string:
25117  luaL_requiref(L, "string", luaopen_string, 1);
25118  lua_pop(L, 1);
25119  break;
25120  case lib::table:
25121  luaL_requiref(L, "table", luaopen_table, 1);
25122  lua_pop(L, 1);
25123  break;
25124  case lib::math:
25125  luaL_requiref(L, "math", luaopen_math, 1);
25126  lua_pop(L, 1);
25127  break;
25128  case lib::bit32:
25129 #ifdef SOL_LUAJIT
25130  luaL_requiref(L, "bit32", luaopen_bit, 1);
25131  lua_pop(L, 1);
25132 #elif (SOL_LUA_VESION_I_ == 502) || defined(LUA_COMPAT_BITLIB) || defined(LUA_COMPAT_5_2)
25133  luaL_requiref(L, "bit32", luaopen_bit32, 1);
25134  lua_pop(L, 1);
25135 #else
25136 #endif // Lua 5.2 only (deprecated in 5.3 (503)) (Can be turned on with Compat flags)
25137  break;
25138  case lib::io:
25139  luaL_requiref(L, "io", luaopen_io, 1);
25140  lua_pop(L, 1);
25141  break;
25142  case lib::os:
25143  luaL_requiref(L, "os", luaopen_os, 1);
25144  lua_pop(L, 1);
25145  break;
25146  case lib::debug:
25147  luaL_requiref(L, "debug", luaopen_debug, 1);
25148  lua_pop(L, 1);
25149  break;
25150  case lib::utf8:
25151 #if SOL_LUA_VESION_I_ > 502 && !defined(SOL_LUAJIT)
25152  luaL_requiref(L, "utf8", luaopen_utf8, 1);
25153  lua_pop(L, 1);
25154 #endif // Lua 5.3+ only
25155  break;
25156  case lib::ffi:
25157 #ifdef SOL_LUAJIT
25158  luaL_requiref(L, "ffi", luaopen_ffi, 1);
25159  lua_pop(L, 1);
25160 #endif // LuaJIT only
25161  break;
25162  case lib::jit:
25163 #ifdef SOL_LUAJIT
25164  luaL_requiref(L, "jit", luaopen_jit, 0);
25165  lua_pop(L, 1);
25166 #endif // LuaJIT Only
25167  break;
25168  case lib::count:
25169  default:
25170  break;
25171  }
25172  }
25173  }
25174  }
25175 
25176  object require(const std::string& key, lua_CFunction open_function, bool create_global = true) {
25177  luaL_requiref(L, key.c_str(), open_function, create_global ? 1 : 0);
25178  return stack::pop<object>(L);
25179  }
25180 
25181  object require_script(const std::string& key, const string_view& code, bool create_global = true,
25182  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25183  auto action = [this, &code, &chunkname, &mode]() { stack::script(L, code, chunkname, mode); };
25184  return require_core(key, action, create_global);
25185  }
25186 
25187  object require_file(const std::string& key, const std::string& filename, bool create_global = true, load_mode mode = load_mode::any) {
25188  auto action = [this, &filename, &mode]() { stack::script_file(L, filename, mode); };
25189  return require_core(key, action, create_global);
25190  }
25191 
25193  optional<table> maybe_package = this->global["package"];
25194  if (!maybe_package) {
25195  // package lib wasn't opened
25196  // open package lib
25197  return;
25198  }
25199  table& package = *maybe_package;
25200  // yay for version differences...
25201  // one day Lua 5.1 will die a peaceful death
25202  // and its old bones will find blissful rest
25203  auto loaders_proxy = package
25204 #if SOL_LUA_VESION_I_ < 502
25205  ["loaders"]
25206 #else
25207  ["searchers"]
25208 #endif
25209  ;
25210  if (!loaders_proxy.valid()) {
25211  // nothing to clear
25212  return;
25213  }
25214  // we need to create the table for loaders
25215  // table does not exist, so create and move forward
25216  loaders_proxy = new_table(1, 0);
25217  }
25218 
25219  template <typename Fx>
25220  void add_package_loader(Fx&& fx, bool clear_all_package_loaders = false) {
25221  optional<table> maybe_package = this->global["package"];
25222  if (!maybe_package) {
25223  // package lib wasn't opened
25224  // open package lib
25225  return;
25226  }
25227  table& package = *maybe_package;
25228  // yay for version differences...
25229  // one day Lua 5.1 will die a peaceful death
25230  // and its old bones will find blissful rest
25231  auto loaders_proxy = package
25232 #if SOL_LUA_VESION_I_ < 502
25233  ["loaders"]
25234 #else
25235  ["searchers"]
25236 #endif
25237  ;
25238  bool make_new_table = clear_all_package_loaders || !loaders_proxy.valid();
25239  if (make_new_table) {
25240  // we need to create the table for loaders
25241  // table does not exist, so create and move forward
25242  loaders_proxy = new_table(1, 0);
25243  }
25244  optional<table> maybe_loaders = loaders_proxy;
25245  if (!maybe_loaders) {
25246  // loaders/searches
25247  // thing exists in package, but it
25248  // ain't a table or a table-alike...!
25249  return;
25250  }
25251  table loaders = loaders_proxy;
25252  loaders.add(std::forward<Fx>(fx));
25253  }
25254 
25255  template <typename E>
25257  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25258  detail::typical_chunk_name_t basechunkname = {};
25259  const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
25260  load_status x = static_cast<load_status>(lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()));
25261  if (x != load_status::ok) {
25262  return protected_function_result(L, absolute_index(L, -1), 0, 1, static_cast<call_status>(x));
25263  }
25265  set_environment(env, pf);
25266  return pf();
25267  }
25268 
25270  lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25271  detail::typical_chunk_name_t basechunkname = {};
25272  const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
25273  load_status x = static_cast<load_status>(lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()));
25274  if (x != load_status::ok) {
25275  return protected_function_result(L, absolute_index(L, -1), 0, 1, static_cast<call_status>(x));
25276  }
25278  return pf();
25279  }
25280 
25281  template <typename E>
25283  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25284  detail::typical_chunk_name_t basechunkname = {};
25285  const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
25286  load_status x = static_cast<load_status>(luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str()));
25287  if (x != load_status::ok) {
25288  return protected_function_result(L, absolute_index(L, -1), 0, 1, static_cast<call_status>(x));
25289  }
25291  set_environment(env, pf);
25292  return pf();
25293  }
25294 
25296  const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25297  detail::typical_chunk_name_t basechunkname = {};
25298  const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
25299  load_status x = static_cast<load_status>(luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str()));
25300  if (x != load_status::ok) {
25301  return protected_function_result(L, absolute_index(L, -1), 0, 1, static_cast<call_status>(x));
25302  }
25304  return pf();
25305  }
25306 
25307  template <typename E>
25309  load_status x = static_cast<load_status>(luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str()));
25310  if (x != load_status::ok) {
25311  return protected_function_result(L, absolute_index(L, -1), 0, 1, static_cast<call_status>(x));
25312  }
25314  set_environment(env, pf);
25315  return pf();
25316  }
25317 
25319  load_status x = static_cast<load_status>(luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str()));
25320  if (x != load_status::ok) {
25321  return protected_function_result(L, absolute_index(L, -1), 0, 1, static_cast<call_status>(x));
25322  }
25324  return pf();
25325  }
25326 
25327  template <typename Fx,
25331  lua_Reader reader, void* data, Fx&& on_error, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25332  protected_function_result pfr = do_reader(reader, data, chunkname, mode);
25333  if (!pfr.valid()) {
25334  return on_error(L, std::move(pfr));
25335  }
25336  return pfr;
25337  }
25338 
25340  lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25341  return safe_script(reader, data, script_default_on_error, chunkname, mode);
25342  }
25343 
25344  template <typename Fx,
25345  meta::disable_any<meta::is_string_constructible<meta::unqualified_t<Fx>>,
25346  meta::is_specialization_of<meta::unqualified_t<Fx>, basic_environment>> = meta::enabler>
25348  const string_view& code, Fx&& on_error, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25349  protected_function_result pfr = do_string(code, chunkname, mode);
25350  if (!pfr.valid()) {
25351  return on_error(L, std::move(pfr));
25352  }
25353  return pfr;
25354  }
25355 
25356  template <typename Fx, typename E>
25358  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25359  protected_function_result pfr = do_string(code, env, chunkname, mode);
25360  if (!pfr.valid()) {
25361  return on_error(L, std::move(pfr));
25362  }
25363  return pfr;
25364  }
25365 
25366  template <typename E>
25368  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25369  return safe_script(code, env, script_default_on_error, chunkname, mode);
25370  }
25371 
25373  const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25374  return safe_script(code, script_default_on_error, chunkname, mode);
25375  }
25376 
25377  template <typename Fx,
25378  meta::disable_any<meta::is_string_constructible<meta::unqualified_t<Fx>>,
25379  meta::is_specialization_of<meta::unqualified_t<Fx>, basic_environment>> = meta::enabler>
25381  protected_function_result pfr = do_file(filename, mode);
25382  if (!pfr.valid()) {
25383  return on_error(L, std::move(pfr));
25384  }
25385  return pfr;
25386  }
25387 
25388  template <typename Fx, typename E>
25390  const std::string& filename, const basic_environment<E>& env, Fx&& on_error, load_mode mode = load_mode::any) {
25391  protected_function_result pfr = do_file(filename, env, mode);
25392  if (!pfr.valid()) {
25393  return on_error(L, std::move(pfr));
25394  }
25395  return pfr;
25396  }
25397 
25398  template <typename E>
25400  return safe_script_file(filename, env, script_default_on_error, mode);
25401  }
25402 
25404  return safe_script_file(filename, script_default_on_error, mode);
25405  }
25406 
25407  template <typename E>
25409  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25410  detail::typical_chunk_name_t basechunkname = {};
25411  const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
25412  int index = lua_gettop(L);
25413  if (lua_load(L, reader, data, chunknametarget, to_string(mode).c_str())) {
25414  lua_error(L);
25415  }
25416  set_environment(env, stack_reference(L, raw_index(index + 1)));
25417  if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
25418  lua_error(L);
25419  }
25420  int postindex = lua_gettop(L);
25421  int returns = postindex - index;
25422  return unsafe_function_result(L, (std::max)(postindex - (returns - 1), 1), returns);
25423  }
25424 
25426  lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25427  int index = lua_gettop(L);
25428  stack::script(L, reader, data, chunkname, mode);
25429  int postindex = lua_gettop(L);
25430  int returns = postindex - index;
25431  return unsafe_function_result(L, (std::max)(postindex - (returns - 1), 1), returns);
25432  }
25433 
25434  template <typename E>
25436  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25437  detail::typical_chunk_name_t basechunkname = {};
25438  const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
25439  int index = lua_gettop(L);
25440  if (luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str())) {
25441  lua_error(L);
25442  }
25443  set_environment(env, stack_reference(L, raw_index(index + 1)));
25444  if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
25445  lua_error(L);
25446  }
25447  int postindex = lua_gettop(L);
25448  int returns = postindex - index;
25449  return unsafe_function_result(L, (std::max)(postindex - (returns - 1), 1), returns);
25450  }
25451 
25453  const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25454  int index = lua_gettop(L);
25455  stack::script(L, code, chunkname, mode);
25456  int postindex = lua_gettop(L);
25457  int returns = postindex - index;
25458  return unsafe_function_result(L, (std::max)(postindex - (returns - 1), 1), returns);
25459  }
25460 
25461  template <typename E>
25463  int index = lua_gettop(L);
25464  if (luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str())) {
25465  lua_error(L);
25466  }
25467  set_environment(env, stack_reference(L, raw_index(index + 1)));
25468  if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
25469  lua_error(L);
25470  }
25471  int postindex = lua_gettop(L);
25472  int returns = postindex - index;
25473  return unsafe_function_result(L, (std::max)(postindex - (returns - 1), 1), returns);
25474  }
25475 
25477  int index = lua_gettop(L);
25478  stack::script_file(L, filename, mode);
25479  int postindex = lua_gettop(L);
25480  int returns = postindex - index;
25481  return unsafe_function_result(L, (std::max)(postindex - (returns - 1), 1), returns);
25482  }
25483 
25484  template <typename Fx,
25485  meta::disable_any<meta::is_string_constructible<meta::unqualified_t<Fx>>,
25486  meta::is_specialization_of<meta::unqualified_t<Fx>, basic_environment>> = meta::enabler>
25488  const string_view& code, Fx&& on_error, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25489  return safe_script(code, std::forward<Fx>(on_error), chunkname, mode);
25490  }
25491 
25492  template <typename Fx,
25493  meta::disable_any<meta::is_string_constructible<meta::unqualified_t<Fx>>,
25494  meta::is_specialization_of<meta::unqualified_t<Fx>, basic_environment>> = meta::enabler>
25496  return safe_script_file(filename, std::forward<Fx>(on_error), mode);
25497  }
25498 
25499  template <typename Fx, typename E>
25500  protected_function_result script(const string_view& code, const basic_environment<E>& env, Fx&& on_error,
25501  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25502  return safe_script(code, env, std::forward<Fx>(on_error), chunkname, mode);
25503  }
25504 
25505  template <typename Fx, typename E>
25507  return safe_script_file(filename, env, std::forward<Fx>(on_error), mode);
25508  }
25509 
25511  const string_view& code, const environment& env, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25512  return safe_script(code, env, script_default_on_error, chunkname, mode);
25513  }
25514 
25516  return safe_script_file(filename, env, script_default_on_error, mode);
25517  }
25518 
25519 #if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_)
25521  lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25522  return safe_script(reader, data, chunkname, mode);
25523  }
25524 
25526  const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25527  return safe_script(code, chunkname, mode);
25528  }
25529 
25531  return safe_script_file(filename, mode);
25532  }
25533 #else
25535  return unsafe_script(code, chunkname, mode);
25536  }
25537 
25539  return unsafe_script_file(filename, mode);
25540  }
25541 #endif
25543  detail::typical_chunk_name_t basechunkname = {};
25544  const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
25545  load_status x = static_cast<load_status>(luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str()));
25546  return load_result(L, absolute_index(L, -1), 1, 1, x);
25547  }
25548 
25549  load_result load_buffer(const char* buff, size_t size, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25550  return load(string_view(buff, size), chunkname, mode);
25551  }
25552 
25554  const std::byte* buff, size_t size, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25555  return load(string_view(reinterpret_cast<const char*>(buff), size), chunkname, mode);
25556  }
25557 
25559  load_status x = static_cast<load_status>(luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str()));
25560  return load_result(L, absolute_index(L, -1), 1, 1, x);
25561  }
25562 
25563  load_result load(lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
25564  detail::typical_chunk_name_t basechunkname = {};
25565  const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
25566  load_status x = static_cast<load_status>(lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()));
25567  return load_result(L, absolute_index(L, -1), 1, 1, x);
25568  }
25569 
25570  iterator begin() const {
25571  return global.begin();
25572  }
25573 
25574  iterator end() const {
25575  return global.end();
25576  }
25577 
25579  return global.cbegin();
25580  }
25581 
25583  return global.cend();
25584  }
25585 
25587  // if we return a reference
25588  // we'll be screwed a bit
25589  return global;
25590  }
25591 
25593  return global;
25594  }
25595 
25596  table registry() const {
25597  return reg;
25598  }
25599 
25600  std::size_t memory_used() const {
25601  return total_memory_used(lua_state());
25602  }
25603 
25604  int stack_top() const {
25605  return stack::top(L);
25606  }
25607 
25608  int stack_clear() {
25609  int s = stack_top();
25610  lua_pop(L, s);
25611  return s;
25612  }
25613 
25614  bool supports_gc_mode(gc_mode mode) const noexcept {
25615 #if SOL_LUA_VESION_I_ >= 504
25616  // supports all modes
25617  (void)mode;
25618  return true;
25619 #endif
25620  return mode == gc_mode::default_value;
25621  }
25622 
25623  bool is_gc_on() const {
25624 #if SOL_LUA_VESION_I_ >= 502
25625  return lua_gc(lua_state(), LUA_GCISRUNNING, 0) == 1;
25626 #else
25627  // You cannot turn it off in Lua 5.1
25628  return true;
25629 #endif
25630  }
25631 
25633  lua_gc(lua_state(), LUA_GCCOLLECT, 0);
25634  }
25635 
25636  void collect_gc() {
25637  collect_garbage();
25638  }
25639 
25640  bool step_gc(int step_size_kilobytes) {
25641  // THOUGHT: std::chrono-alikes to map "kilobyte size" here...?
25642  // Make it harder to give MB or KB to a B parameter...?
25643  // Probably overkill for now.
25644 #if SOL_LUA_VESION_I_ >= 504
25645  // The manual implies that this function is almost always successful...
25646  // is it?? It could depend on the GC mode...
25647  return lua_gc(lua_state(), LUA_GCSTEP, step_size_kilobytes) != 0;
25648 #else
25649  return lua_gc(lua_state(), LUA_GCSTEP, step_size_kilobytes) == 1;
25650 #endif
25651  }
25652 
25653  void restart_gc() {
25654  lua_gc(lua_state(), LUA_GCRESTART, 0);
25655  }
25656 
25657  void stop_gc() {
25658  lua_gc(lua_state(), LUA_GCSTOP, 0);
25659  }
25660 
25661  // Returns the old GC mode. Check support using the supports_gc_mode function.
25662  gc_mode change_gc_mode_incremental(int pause, int step_multiplier, int step_byte_size) {
25663  // "What the fuck does any of this mean??"
25664  // http://www.lua.org/manual/5.4/manual.html#2.5.1
25665 
25666  // THOUGHT: std::chrono-alikes to map "byte size" here...?
25667  // Make it harder to give MB or KB to a B parameter...?
25668  // Probably overkill for now.
25669 #if SOL_LUA_VESION_I_ >= 504
25670  int old_mode = lua_gc(lua_state(), LUA_GCINC, pause, step_multiplier, step_byte_size);
25671  if (old_mode == LUA_GCGEN) {
25672  return gc_mode::generational;
25673  }
25674  else if (old_mode == LUA_GCINC) {
25675  return gc_mode::incremental;
25676  }
25677 #else
25678  lua_gc(lua_state(), LUA_GCSETPAUSE, pause);
25679  lua_gc(lua_state(), LUA_GCSETSTEPMUL, step_multiplier);
25680  (void)step_byte_size; // means nothing in older versions
25681 #endif
25682  return gc_mode::default_value;
25683  }
25684 
25685  // Returns the old GC mode. Check support using the supports_gc_mode function.
25686  gc_mode change_gc_mode_generational(int minor_multiplier, int major_multiplier) {
25687 #if SOL_LUA_VESION_I_ >= 504
25688  // "What does this shit mean?"
25689  // http://www.lua.org/manual/5.4/manual.html#2.5.2
25690  int old_mode = lua_gc(lua_state(), LUA_GCGEN, minor_multiplier, major_multiplier);
25691  if (old_mode == LUA_GCGEN) {
25692  return gc_mode::generational;
25693  }
25694  else if (old_mode == LUA_GCINC) {
25695  return gc_mode::incremental;
25696  }
25697 #endif
25698  return gc_mode::default_value;
25699  }
25700 
25701  operator lua_State*() const {
25702  return lua_state();
25703  }
25704 
25706  lua_atpanic(lua_state(), panic);
25707  }
25708 
25710  set_default_exception_handler(lua_state(), handler);
25711  }
25712 
25713  template <typename... Args, typename... Keys>
25714  decltype(auto) get(Keys&&... keys) const {
25715  return global.get<Args...>(std::forward<Keys>(keys)...);
25716  }
25717 
25718  template <typename T, typename Key>
25719  decltype(auto) get_or(Key&& key, T&& otherwise) const {
25720  return global.get_or(std::forward<Key>(key), std::forward<T>(otherwise));
25721  }
25722 
25723  template <typename T, typename Key, typename D>
25724  decltype(auto) get_or(Key&& key, D&& otherwise) const {
25725  return global.get_or<T>(std::forward<Key>(key), std::forward<D>(otherwise));
25726  }
25727 
25728  template <typename... Args>
25729  state_view& set(Args&&... args) {
25730  global.set(std::forward<Args>(args)...);
25731  return *this;
25732  }
25733 
25734  template <typename T, typename... Keys>
25735  decltype(auto) traverse_get(Keys&&... keys) const {
25736  return global.traverse_get<T>(std::forward<Keys>(keys)...);
25737  }
25738 
25739  template <typename... Args>
25740  state_view& traverse_set(Args&&... args) {
25741  global.traverse_set(std::forward<Args>(args)...);
25742  return *this;
25743  }
25744 
25745  template <typename Class, typename... Args>
25746  usertype<Class> new_usertype(const std::string& name, Args&&... args) {
25747  return global.new_usertype<Class>(name, std::forward<Args>(args)...);
25748  }
25749 
25750  template <bool read_only = true, typename... Args>
25751  state_view& new_enum(const string_view& name, Args&&... args) {
25752  global.new_enum<read_only>(name, std::forward<Args>(args)...);
25753  return *this;
25754  }
25755 
25756  template <typename T, bool read_only = true>
25757  state_view& new_enum(const string_view& name, std::initializer_list<std::pair<string_view, T>> items) {
25758  global.new_enum<T, read_only>(name, std::move(items));
25759  return *this;
25760  }
25761 
25762  template <typename Fx>
25763  void for_each(Fx&& fx) {
25764  global.for_each(std::forward<Fx>(fx));
25765  }
25766 
25767  template <typename T>
25769  return global[std::forward<T>(key)];
25770  }
25771 
25772  template <typename T>
25774  return global[std::forward<T>(key)];
25775  }
25776 
25777  template <typename Sig, typename... Args, typename Key>
25778  state_view& set_function(Key&& key, Args&&... args) {
25779  global.set_function<Sig>(std::forward<Key>(key), std::forward<Args>(args)...);
25780  return *this;
25781  }
25782 
25783  template <typename... Args, typename Key>
25784  state_view& set_function(Key&& key, Args&&... args) {
25785  global.set_function(std::forward<Key>(key), std::forward<Args>(args)...);
25786  return *this;
25787  }
25788 
25789  template <typename Name>
25790  table create_table(Name&& name, int narr = 0, int nrec = 0) {
25791  return global.create(std::forward<Name>(name), narr, nrec);
25792  }
25793 
25794  template <typename Name, typename Key, typename Value, typename... Args>
25795  table create_table(Name&& name, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
25796  return global.create(std::forward<Name>(name), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
25797  }
25798 
25799  template <typename Name, typename... Args>
25800  table create_named_table(Name&& name, Args&&... args) {
25801  table x = global.create_with(std::forward<Args>(args)...);
25802  global.set(std::forward<Name>(name), x);
25803  return x;
25804  }
25805 
25806  table create_table(int narr = 0, int nrec = 0) {
25807  return create_table(lua_state(), narr, nrec);
25808  }
25809 
25810  template <typename Key, typename Value, typename... Args>
25811  table create_table(int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
25812  return create_table(lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
25813  }
25814 
25815  template <typename... Args>
25816  table create_table_with(Args&&... args) {
25817  return create_table_with(lua_state(), std::forward<Args>(args)...);
25818  }
25819 
25820  static inline table create_table(lua_State* L, int narr = 0, int nrec = 0) {
25821  return global_table::create(L, narr, nrec);
25822  }
25823 
25824  template <typename Key, typename Value, typename... Args>
25825  static inline table create_table(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
25826  return global_table::create(L, narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
25827  }
25828 
25829  template <typename... Args>
25830  static inline table create_table_with(lua_State* L, Args&&... args) {
25831  return global_table::create_with(L, std::forward<Args>(args)...);
25832  }
25833  };
25834 } // namespace sol
25835 
25836 // end of sol/state_view.hpp
25837 
25838 // beginning of sol/thread.hpp
25839 
25840 namespace sol {
25843 
25845  : L(Ls) {
25846  }
25847 
25848  lua_State* lua_state() const noexcept {
25849  return L;
25850  }
25851  operator lua_State*() const noexcept {
25852  return lua_state();
25853  }
25854  lua_State* operator->() const noexcept {
25855  return lua_state();
25856  }
25857  };
25858 
25859  namespace stack {
25860  template <>
25863  lua_pushthread(lts.L);
25864  return 1;
25865  }
25866  };
25867 
25868  template <>
25870  lua_thread_state get(lua_State* L, int index, record& tracking) {
25871  tracking.use(1);
25872  lua_thread_state lts( lua_tothread(L, index) );
25873  return lts;
25874  }
25875  };
25876 
25877  template <>
25879  template <typename Handler>
25880  optional<lua_thread_state> get(lua_State* L, int index, Handler&& handler, record& tracking) {
25881  lua_thread_state lts( lua_tothread(L, index) );
25882  if (lts.lua_state() == nullptr) {
25883  handler(L, index, type::thread, type_of(L, index), "value is not a valid thread type");
25884  return nullopt;
25885  }
25886  tracking.use(1);
25887  return lts;
25888  }
25889  };
25890  } // namespace stack
25891 
25892  template <typename ref_t>
25893  class basic_thread : public basic_object<ref_t> {
25894  private:
25895  using base_t = basic_object<ref_t>;
25896 
25897  public:
25898  using base_t::lua_state;
25899 
25900  basic_thread() noexcept = default;
25901  basic_thread(const basic_thread&) = default;
25902  basic_thread(basic_thread&&) = default;
25903  template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_thread>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
25904  basic_thread(T&& r)
25905  : base_t(std::forward<T>(r)) {
25906 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
25907  auto pp = stack::push_pop(*this);
25909  stack::check<basic_thread>(lua_state(), -1, handler);
25910 #endif // Safety
25911  }
25913  : basic_thread(r.lua_state(), r.stack_index()){};
25915  : basic_thread(r.lua_state(), r.stack_index()){};
25916  basic_thread& operator=(const basic_thread&) = default;
25917  basic_thread& operator=(basic_thread&&) = default;
25918  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
25920  : base_t(L, std::forward<T>(r)) {
25921 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
25922  auto pp = stack::push_pop(*this);
25924  stack::check<basic_thread>(lua_state(), -1, handler);
25925 #endif // Safety
25926  }
25927  basic_thread(lua_State* L, int index = -1)
25928  : base_t(L, index) {
25929 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
25931  stack::check<basic_thread>(L, index, handler);
25932 #endif // Safety
25933  }
25935  : base_t(L, index) {
25936 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
25937  auto pp = stack::push_pop(*this);
25939  stack::check<basic_thread>(lua_state(), -1, handler);
25940 #endif // Safety
25941  }
25942  basic_thread(lua_State* L, lua_State* actualthread)
25943  : basic_thread(L, lua_thread_state{ actualthread }) {
25944  }
25946  : basic_thread(L, lua_thread_state{ actualthread.L }) {
25947  }
25949  : base_t(L, -stack::push(L, actualthread)) {
25950 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
25952  stack::check<basic_thread>(lua_state(), -1, handler);
25953 #endif // Safety
25955  lua_pop(lua_state(), 1);
25956  }
25957  }
25958 
25959  state_view state() const {
25960  return state_view(this->thread_state());
25961  }
25962 
25963  bool is_main_thread() const {
25964  return stack::is_main_thread(this->thread_state());
25965  }
25966 
25968  auto pp = stack::push_pop(*this);
25969  lua_State* lthread = lua_tothread(lua_state(), -1);
25970  return lthread;
25971  }
25972 
25974  lua_State* lthread = thread_state();
25975  auto lstat = static_cast<thread_status>(lua_status(lthread));
25976  if (lstat == thread_status::ok) {
25977  lua_Debug ar;
25978  if (lua_getstack(lthread, 0, &ar) > 0)
25979  return thread_status::ok;
25980  else if (lua_gettop(lthread) == 0)
25981  return thread_status::dead;
25982  else
25983  return thread_status::yielded;
25984  }
25985  return lstat;
25986  }
25987 
25989  return create(lua_state());
25990  }
25991 
25993  lua_newthread(L);
25994  basic_thread result(L);
25996  lua_pop(L, 1);
25997  }
25998  return result;
25999  }
26000  };
26001 
26004 } // namespace sol
26005 
26006 // end of sol/thread.hpp
26007 
26008 namespace sol {
26009 
26010  class state : private std::unique_ptr<lua_State, detail::state_deleter>, public state_view {
26011  private:
26012  typedef std::unique_ptr<lua_State, detail::state_deleter> unique_base;
26013 
26014  public:
26016  : unique_base(luaL_newstate()), state_view(unique_base::get()) {
26018  }
26019 
26020  state(lua_CFunction panic, lua_Alloc alfunc, void* alpointer = nullptr)
26021  : unique_base(lua_newstate(alfunc, alpointer)), state_view(unique_base::get()) {
26023  }
26024 
26025  state(const state&) = delete;
26026  state(state&&) = default;
26027  state& operator=(const state&) = delete;
26028  state& operator=(state&& that) {
26029  state_view::operator=(std::move(that));
26030  unique_base::operator=(std::move(that));
26031  return *this;
26032  }
26033 
26034  using state_view::get;
26035 
26037  }
26038  };
26039 } // namespace sol
26040 
26041 // end of sol/state.hpp
26042 
26043 // beginning of sol/coroutine.hpp
26044 
26045 namespace sol {
26046  template <typename ref_t>
26047  class basic_coroutine : public basic_object<ref_t> {
26048  private:
26049  using base_t = basic_object<ref_t>;
26050 
26051  public:
26053  handler_t error_handler;
26054 
26055  private:
26057 
26058  void luacall(std::ptrdiff_t argcount, std::ptrdiff_t) {
26059 #if SOL_LUA_VESION_I_ >= 504
26060  int nresults;
26061  stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount), &nresults));
26062 #else
26063  stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount)));
26064 #endif
26065  }
26066 
26067  template <std::size_t... I, typename... Ret>
26068  auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n) {
26069  luacall(n, sizeof...(Ret));
26070  return stack::pop<std::tuple<Ret...>>(lua_state());
26071  }
26072 
26073  template <std::size_t I, typename Ret>
26074  Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n) {
26075  luacall(n, 1);
26076  return stack::pop<Ret>(lua_state());
26077  }
26078 
26079  template <std::size_t I>
26080  void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n) {
26081  luacall(n, 0);
26082  }
26083 
26084  protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n) {
26085  int firstreturn = 1;
26086  luacall(n, LUA_MULTRET);
26087  int poststacksize = lua_gettop(this->lua_state());
26088  int returncount = poststacksize - (firstreturn - 1);
26089  if (error()) {
26090  if (error_handler.valid()) {
26091  string_view err = stack::get<string_view>(this->lua_state(), poststacksize);
26092  error_handler.push();
26093  stack::push(this->lua_state(), err);
26094  lua_call(lua_state(), 1, 1);
26095  }
26096  return protected_function_result(this->lua_state(), lua_absindex(this->lua_state(), -1), 1, returncount, status());
26097  }
26098  return protected_function_result(this->lua_state(), firstreturn, returncount, returncount, status());
26099  }
26100 
26101  public:
26102  using base_t::lua_state;
26103 
26104  basic_coroutine() = default;
26105  template <typename T,
26108  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26109  basic_coroutine(T&& r) noexcept
26110  : base_t(std::forward<T>(r)), error_handler(detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
26111 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
26113  auto pp = stack::push_pop(*this);
26115  stack::check<basic_coroutine>(lua_state(), -1, handler);
26116  }
26117 #endif // Safety
26118  }
26119  basic_coroutine(const basic_coroutine&) = default;
26120  basic_coroutine& operator=(const basic_coroutine&) = default;
26121  basic_coroutine(basic_coroutine&&) = default;
26122  basic_coroutine& operator=(basic_coroutine&&) = default;
26124  : basic_coroutine(b, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(b.lua_state())) {
26125  }
26127  : basic_coroutine(std::move(b), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(b.lua_state())) {
26128  }
26129  basic_coroutine(const basic_function<base_t>& b, handler_t eh) : base_t(b), error_handler(std::move(eh)) {
26130  }
26131  basic_coroutine(basic_function<base_t>&& b, handler_t eh) : base_t(std::move(b)), error_handler(std::move(eh)) {
26132  }
26134  : basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
26135  }
26137  : basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
26138  }
26139  basic_coroutine(const stack_reference& r, handler_t eh) : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
26140  }
26141  basic_coroutine(stack_reference&& r, handler_t eh) : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
26142  }
26143 
26144  template <typename Super>
26146  : basic_coroutine(p, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) {
26147  }
26148  template <typename Super>
26150  : basic_coroutine(std::move(p), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) {
26151  }
26152  template <typename Proxy, typename Handler,
26154  basic_coroutine(Proxy&& p, Handler&& eh) : basic_coroutine(detail::force_cast<base_t>(p), std::forward<Handler>(eh)) {
26155  }
26156 
26157  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26159  : basic_coroutine(L, std::forward<T>(r), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
26160  }
26161  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26162  basic_coroutine(lua_State* L, T&& r, handler_t eh) : base_t(L, std::forward<T>(r)), error_handler(std::move(eh)) {
26163 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
26164  auto pp = stack::push_pop(*this);
26166  stack::check<basic_coroutine>(lua_state(), -1, handler);
26167 #endif // Safety
26168  }
26169 
26170  basic_coroutine(lua_nil_t n) : base_t(n), error_handler(n) {
26171  }
26172 
26173  basic_coroutine(lua_State* L, int index = -1)
26174  : basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
26175  }
26176  basic_coroutine(lua_State* L, int index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
26177 #ifdef SOL_SAFE_REFERENCES
26179  stack::check<basic_coroutine>(L, index, handler);
26180 #endif // Safety
26181  }
26183  : basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
26184  }
26185  basic_coroutine(lua_State* L, absolute_index index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
26186 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
26188  stack::check<basic_coroutine>(L, index, handler);
26189 #endif // Safety
26190  }
26192  : basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
26193  }
26194  basic_coroutine(lua_State* L, raw_index index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
26195 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
26197  stack::check<basic_coroutine>(L, index, handler);
26198 #endif // Safety
26199  }
26201  : basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
26202  }
26203  basic_coroutine(lua_State* L, ref_index index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
26204 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
26205  auto pp = stack::push_pop(*this);
26207  stack::check<basic_coroutine>(lua_state(), -1, handler);
26208 #endif // Safety
26209  }
26210 
26211  call_status status() const noexcept {
26212  return stats;
26213  }
26214 
26215  bool error() const noexcept {
26216  call_status cs = status();
26217  return cs != call_status::ok && cs != call_status::yielded;
26218  }
26219 
26220  bool runnable() const noexcept {
26221  return base_t::valid() && (status() == call_status::yielded);
26222  }
26223 
26224  explicit operator bool() const noexcept {
26225  return runnable();
26226  }
26227 
26228  template <typename... Args>
26230  return call<>(std::forward<Args>(args)...);
26231  }
26232 
26233  template <typename... Ret, typename... Args>
26234  decltype(auto) operator()(types<Ret...>, Args&&... args) {
26235  return call<Ret...>(std::forward<Args>(args)...);
26236  }
26237 
26238  template <typename... Ret, typename... Args>
26239  decltype(auto) call(Args&&... args) {
26240  // some users screw up coroutine.create
26241  // and try to use it with sol::coroutine without ever calling the first resume in Lua
26242  // this makes the stack incompatible with other kinds of stacks: protect against this
26243  // make sure coroutines don't screw us over
26244  base_t::push();
26245  int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
26246  return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount);
26247  }
26248  };
26249 } // namespace sol
26250 
26251 // end of sol/coroutine.hpp
26252 
26253 // beginning of sol/userdata.hpp
26254 
26255 namespace sol {
26256  template <typename base_type>
26257  class basic_userdata : public basic_table<base_type> {
26258  private:
26259  using base_t = basic_table<base_type>;
26260 
26261  public:
26262  using base_t::lua_state;
26263 
26264  basic_userdata() noexcept = default;
26265  template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_userdata>>, meta::neg<std::is_same<base_t, stack_reference>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26266  basic_userdata(T&& r) noexcept
26267  : base_t(std::forward<T>(r)) {
26268 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
26270  auto pp = stack::push_pop(*this);
26271  type_assert(lua_state(), -1, type::userdata);
26272  }
26273 #endif // Safety
26274  }
26275  basic_userdata(const basic_userdata&) = default;
26276  basic_userdata(basic_userdata&&) = default;
26277  basic_userdata& operator=(const basic_userdata&) = default;
26278  basic_userdata& operator=(basic_userdata&&) = default;
26280  : basic_userdata(r.lua_state(), r.stack_index()) {
26281  }
26283  : basic_userdata(r.lua_state(), r.stack_index()) {
26284  }
26285  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26287  : base_t(L, std::forward<T>(r)) {
26288 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
26289  auto pp = stack::push_pop(*this);
26291  stack::check<basic_userdata>(L, -1, handler);
26292 #endif // Safety
26293  }
26294  basic_userdata(lua_State* L, int index = -1)
26295  : base_t(detail::no_safety, L, index) {
26296 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
26298  stack::check<basic_userdata>(L, index, handler);
26299 #endif // Safety
26300  }
26302  : base_t(detail::no_safety, L, index) {
26303 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
26304  auto pp = stack::push_pop(*this);
26306  stack::check<basic_userdata>(L, -1, handler);
26307 #endif // Safety
26308  }
26309  };
26310 
26311  template <typename base_type>
26312  class basic_lightuserdata : public basic_object_base<base_type> {
26314 
26315  public:
26316  using base_t::lua_state;
26317 
26318  basic_lightuserdata() noexcept = default;
26319  template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_lightuserdata>>, meta::neg<std::is_same<base_t, stack_reference>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26320  basic_lightuserdata(T&& r) noexcept
26321  : base_t(std::forward<T>(r)) {
26322 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
26324  auto pp = stack::push_pop(*this);
26325  type_assert(lua_state(), -1, type::lightuserdata);
26326  }
26327 #endif // Safety
26328  }
26329  basic_lightuserdata(const basic_lightuserdata&) = default;
26331  basic_lightuserdata& operator=(const basic_lightuserdata&) = default;
26332  basic_lightuserdata& operator=(basic_lightuserdata&&) = default;
26334  : basic_lightuserdata(r.lua_state(), r.stack_index()) {
26335  }
26337  : basic_lightuserdata(r.lua_state(), r.stack_index()) {
26338  }
26339  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26341  : basic_lightuserdata(L, std::forward<T>(r)) {
26342 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
26343  auto pp = stack::push_pop(*this);
26345  stack::check<basic_lightuserdata>(lua_state(), -1, handler);
26346 #endif // Safety
26347  }
26348  basic_lightuserdata(lua_State* L, int index = -1)
26349  : base_t(L, index) {
26350 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
26352  stack::check<basic_lightuserdata>(L, index, handler);
26353 #endif // Safety
26354  }
26356  : base_t(L, index) {
26357 #if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
26358  auto pp = stack::push_pop(*this);
26360  stack::check<basic_lightuserdata>(lua_state(), index, handler);
26361 #endif // Safety
26362  }
26363  };
26364 
26365 } // namespace sol
26366 
26367 // end of sol/userdata.hpp
26368 
26369 // beginning of sol/as_args.hpp
26370 
26371 namespace sol {
26372  template <typename T>
26373  struct as_args_t {
26374  T src;
26375  };
26376 
26377  template <typename Source>
26378  auto as_args(Source&& source) {
26379  return as_args_t<Source> { std::forward<Source>(source) };
26380  }
26381 
26382  namespace stack {
26383  template <typename T>
26385  int push(lua_State* L, const as_args_t<T>& e) {
26386  int p = 0;
26387  for (const auto& i : e.src) {
26388  p += stack::push(L, i);
26389  }
26390  return p;
26391  }
26392  };
26393  } // namespace stack
26394 } // namespace sol
26395 
26396 // end of sol/as_args.hpp
26397 
26398 // beginning of sol/variadic_args.hpp
26399 
26400 #include <limits>
26401 #include <iterator>
26402 
26403 namespace sol {
26404  struct variadic_args {
26405  private:
26407  int index;
26409 
26410  public:
26414  typedef std::ptrdiff_t difference_type;
26415  typedef std::size_t size_type;
26418  typedef std::reverse_iterator<iterator> reverse_iterator;
26419  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
26420 
26421  variadic_args() = default;
26422  variadic_args(lua_State* luastate, int stackindex = -1)
26423  : L(luastate), index(lua_absindex(luastate, stackindex)), stacktop(lua_gettop(luastate)) {
26424  }
26425  variadic_args(lua_State* luastate, int stackindex, int lastindex)
26426  : L(luastate), index(lua_absindex(luastate, stackindex)), stacktop(lastindex) {
26427  }
26428  variadic_args(const variadic_args&) = default;
26429  variadic_args& operator=(const variadic_args&) = default;
26431  : L(o.L), index(o.index), stacktop(o.stacktop) {
26432  // Must be manual, otherwise destructor will screw us
26433  // return count being 0 is enough to keep things clean
26434  // but will be thorough
26435  o.L = nullptr;
26436  o.index = 0;
26437  o.stacktop = 0;
26438  }
26440  L = o.L;
26441  index = o.index;
26442  stacktop = o.stacktop;
26443  // Must be manual, otherwise destructor will screw us
26444  // return count being 0 is enough to keep things clean
26445  // but will be thorough
26446  o.L = nullptr;
26447  o.index = 0;
26448  o.stacktop = 0;
26449  return *this;
26450  }
26451 
26452  iterator begin() {
26453  return iterator(L, index, stacktop + 1);
26454  }
26455  iterator end() {
26456  return iterator(L, stacktop + 1, stacktop + 1);
26457  }
26458  const_iterator begin() const {
26459  return const_iterator(L, index, stacktop + 1);
26460  }
26461  const_iterator end() const {
26462  return const_iterator(L, stacktop + 1, stacktop + 1);
26463  }
26464  const_iterator cbegin() const {
26465  return begin();
26466  }
26467  const_iterator cend() const {
26468  return end();
26469  }
26470 
26471  reverse_iterator rbegin() {
26472  return std::reverse_iterator<iterator>(begin());
26473  }
26474  reverse_iterator rend() {
26475  return std::reverse_iterator<iterator>(end());
26476  }
26477  const_reverse_iterator rbegin() const {
26478  return std::reverse_iterator<const_iterator>(begin());
26479  }
26480  const_reverse_iterator rend() const {
26481  return std::reverse_iterator<const_iterator>(end());
26482  }
26483  const_reverse_iterator crbegin() const {
26484  return std::reverse_iterator<const_iterator>(cbegin());
26485  }
26486  const_reverse_iterator crend() const {
26487  return std::reverse_iterator<const_iterator>(cend());
26488  }
26489 
26490  int push() const {
26491  return push(L);
26492  }
26493 
26494  int push(lua_State* target) const {
26495  int pushcount = 0;
26496  for (int i = index; i <= stacktop; ++i) {
26497  lua_pushvalue(L, i);
26498  pushcount += 1;
26499  }
26500  if (target != L) {
26501  lua_xmove(L, target, pushcount);
26502  }
26503  return pushcount;
26504  }
26505 
26506  template <typename T>
26507  decltype(auto) get(difference_type index_offset = 0) const {
26508  return stack::get<T>(L, index + static_cast<int>(index_offset));
26509  }
26510 
26511  type get_type(difference_type index_offset = 0) const noexcept {
26512  return type_of(L, index + static_cast<int>(index_offset));
26513  }
26514 
26515  stack_proxy operator[](difference_type index_offset) const {
26516  return stack_proxy(L, index + static_cast<int>(index_offset));
26517  }
26518 
26520  return L;
26521  };
26522  int stack_index() const {
26523  return index;
26524  };
26525  int leftover_count() const {
26526  return stacktop - (index - 1);
26527  }
26528  std::size_t size() const {
26529  return static_cast<std::size_t>(leftover_count());
26530  }
26531  int top() const {
26532  return stacktop;
26533  }
26534  };
26535 
26536  namespace stack {
26537  template <>
26539  static variadic_args get(lua_State* L, int index, record& tracking) {
26540  tracking.last = 0;
26541  return variadic_args(L, index);
26542  }
26543  };
26544 
26545  template <>
26547  static int push(lua_State* L, const variadic_args& ref) {
26548  return ref.push(L);
26549  }
26550  };
26551  } // namespace stack
26552 } // namespace sol
26553 
26554 // end of sol/variadic_args.hpp
26555 
26556 // beginning of sol/variadic_results.hpp
26557 
26558 // beginning of sol/as_returns.hpp
26559 
26560 namespace sol {
26561  template <typename T>
26562  struct as_returns_t {
26563  T src;
26564  };
26565 
26566  template <typename Source>
26567  auto as_returns(Source&& source) {
26568  return as_returns_t<std::decay_t<Source>>{ std::forward<Source>(source) };
26569  }
26570 
26571  namespace stack {
26572  template <typename T>
26574  int push(lua_State* L, const as_returns_t<T>& e) {
26575  auto& src = detail::unwrap(e.src);
26576  int p = 0;
26577  for (const auto& i : src) {
26578  p += stack::push(L, i);
26579  }
26580  return p;
26581  }
26582  };
26583  } // namespace stack
26584 } // namespace sol
26585 
26586 // end of sol/as_returns.hpp
26587 
26588 #include <vector>
26589 
26590 namespace sol {
26591 
26592  template <typename Al = typename std::allocator<object>>
26593  struct basic_variadic_results : public std::vector<object, Al> {
26594  private:
26595  using base_t = std::vector<object, Al>;
26596 
26597  public:
26598  basic_variadic_results() : base_t() {
26599  }
26600 
26602  this->reserve(fr.return_count());
26603  this->insert(this->cend(), fr.begin(), fr.end());
26604  }
26605 
26607  this->reserve(fr.return_count());
26608  this->insert(this->cend(), fr.begin(), fr.end());
26609  }
26610 
26611  template <typename Arg0, typename... Args,
26613  std::is_same<meta::unqualified_t<Arg0>, protected_function_result>> = meta::enabler>
26614  basic_variadic_results(Arg0&& arg0, Args&&... args) : base_t(std::forward<Arg0>(arg0), std::forward<Args>(args)...) {
26615  }
26616 
26617  basic_variadic_results(const basic_variadic_results&) = default;
26618  basic_variadic_results(basic_variadic_results&&) = default;
26619  };
26620 
26622  private:
26624 
26625  public:
26626  using base_t::base_t;
26627  };
26628 
26629  template <typename Al>
26630  struct is_container<basic_variadic_results<Al>> : std::false_type { };
26631 
26632  template <>
26633  struct is_container<variadic_results> : std::false_type { };
26634 
26635  namespace stack {
26636  template <typename Al>
26639  int p = 0;
26640  for (const auto& i : e) {
26641  p += stack::push(L, i);
26642  }
26643  return p;
26644  }
26645  };
26646 
26647  template <>
26648  struct unqualified_pusher<variadic_results> {
26649  int push(lua_State* L, const variadic_results& r) {
26650  using base_t = basic_variadic_results<>;
26651  return stack::push(L, static_cast<const base_t&>(r));
26652  }
26653  };
26654  } // namespace stack
26655 
26656 } // namespace sol
26657 
26658 // end of sol/variadic_results.hpp
26659 
26660 #if SOL_IS_ON(SOL_COMPILER_GCC_I_)
26661 #pragma GCC diagnostic pop
26662 #elif SOL_IS_ON(SOL_COMPILER_VCXX_I_)
26663 #pragma warning(pop)
26664 #endif // g++
26665 
26666 #if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE_I_)
26667 #undef check
26668 #pragma pop_macro("check")
26669 #endif // Unreal Engine 4 Bullshit
26670 
26671 #endif // SOL_HPP
26672 // end of sol/sol.hpp
26673 
26674 #endif // SOL_SINGLE_INCLUDE_HPP
static int get_call(lua_State *L)
Definition: sol.hpp:21411
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs)&
disjunction
Definition: sol.hpp:5925
const char * what
Definition: lua.h:473
std::size_t code_units_size
Definition: sol.hpp:11895
#define luaL_addsize(B, s)
Definition: lauxlib.h:186
static int push(lua_State *L, detail::tagged< T, no_construction >)
Definition: sol.hpp:18650
basic_function(T &&r) noexcept
Definition: sol.hpp:18982
LUA_API int lua_isstring(lua_State *L, int idx)
Definition: lapi.c:292
basic_userdata(lua_State *L, int index=-1)
Definition: sol.hpp:26294
stack_iterator & operator-=(difference_type idx)
Definition: sol.hpp:15573
LUA_API const char * lua_getupvalue(lua_State *L, int funcindex, int n)
Definition: lapi.c:1352
auto unqualified_get(lua_State *L, int index, record &tracking) -> decltype(stack_detail::unchecked_unqualified_get< T >(L, index, tracking))
Definition: sol.hpp:10866
std::integral_constant< bool, meta::count_for< is_variadic_arguments, typename base_t::args_list >::value!=0 > runtime_variadics_t
Definition: sol.hpp:7762
closure c_closure
Definition: sol.hpp:6798
static int push(lua_State *L, const T &tablecont)
Definition: sol.hpp:13806
const_reference operator*() const
Definition: sol.hpp:23340
table create(Name &&name, int narr=0, int nrec=0)
Definition: sol.hpp:24002
static int push(lua_State *L, detail::yield_tag_t, const std::function< Signature > &fx)
Definition: sol.hpp:18479
void set_on(const T &target) const
Definition: sol.hpp:24474
void select_member_variable(lua_State *L, Fx &&fx, Args &&...args)
Definition: sol.hpp:18257
reverse_iterator rend()
Definition: sol.hpp:26474
void operator()(meta_function mf, lua_CFunction f)
Definition: sol.hpp:10277
constexpr const char * not_a_number
Definition: sol.hpp:8569
protected_function_result safe_script(const string_view &code, const basic_environment< E > &env, Fx &&on_error, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25357
object require(const std::string &key, lua_CFunction open_function, bool create_global=true)
Definition: sol.hpp:25176
lua_CFunction c_function
Definition: sol.hpp:6792
lua_State * copy_assign(lua_State *L, lua_State *rL, const stateless_reference &r)
Definition: sol.hpp:9108
error(detail::direct_error_tag, const std::string &str)
Definition: sol.hpp:3890
static int real_insert_traits(std::true_type, lua_State *L)
Definition: sol.hpp:21294
#define lua_isnoneornil(L, n)
Definition: lua.h:379
Definition: lua.h:469
LUA_API void lua_xmove(lua_State *from, lua_State *to, int n)
Definition: lapi.c:120
T & unwrap(std::reference_wrapper< T > arg)
Definition: sol.hpp:1561
detail::inheritance_cast_function base_class_cast_func
Definition: sol.hpp:21940
FILE * f
Definition: lauxlib.h:221
meta::boolean< has_find_test< T >::value > has_find
Definition: sol.hpp:19898
static int real_empty_traits(std::false_type, lua_State *L)
Definition: sol.hpp:21322
basic_coroutine(proxy_base< Super > &&p)
Definition: sol.hpp:26149
constexpr const char * not_enough_stack_space_generic
Definition: sol.hpp:8581
bool valid() const noexcept
Definition: sol.hpp:8862
constexpr std::in_place_t in_place
Definition: sol.hpp:3919
const reference & value() const &
Definition: sol.hpp:24790
std::unordered_map< string_view, index_call_storage > string_keys
Definition: sol.hpp:21972
typename std::remove_const< T >::type remove_const_t
Definition: sol.hpp:4025
static int real_set_traits(std::false_type, lua_State *L)
Definition: sol.hpp:21214
state & operator=(state &&that)
Definition: sol.hpp:26028
lua_State * lua_state() const noexcept
Definition: sol.hpp:25848
static int push(std::index_sequence< I... >, lua_State *L, T &&c)
Definition: sol.hpp:13917
int stack_index() const
Definition: sol.hpp:16057
std::size_t size() const
Definition: sol.hpp:6386
stack_iterator(lua_State *luastate, int idx, int topidx)
Definition: sol.hpp:15524
reference operator*()
Definition: sol.hpp:15528
static int push(lua_State *L, const variadic_args &ref)
Definition: sol.hpp:26547
static table create_with(lua_State *L, Args &&...args)
Definition: sol.hpp:23986
ebco & operator=(T &&v)
Definition: sol.hpp:6446
static int push(std::false_type, lua_State *L, const T &tablecont)
Definition: sol.hpp:13727
basic_function(lua_State *L, ref_index index)
Definition: sol.hpp:19021
int operator()(lua_State *L, int index, type expected, type actual, string_view message) const noexcept(false)
Definition: sol.hpp:8653
nested< T > as_nested_ref(T &&container)
Definition: sol.hpp:6913
static int push(lua_State *L, overload_set< Functions... > &&set)
Definition: sol.hpp:18540
bool check_usertype(lua_State *L, int index=-lua_size< meta::unqualified_t< T >>::value)
Definition: sol.hpp:10771
static int index_call_with_bases(lua_State *L)
Definition: sol.hpp:22296
static int panic(lua_State *L)
Definition: lauxlib.c:999
#define LUA_TTHREAD
Definition: lua.h:73
type get_type(difference_type index_offset=0) const noexcept
Definition: sol.hpp:26511
int default_at_panic(lua_State *L)
Definition: sol.hpp:24864
constexpr Sig C::* resolve_v(std::true_type, Sig C::*mem_variable_ptr)
Definition: sol.hpp:18080
lua_State * lua_state() const noexcept
Definition: sol.hpp:8858
constexpr optional< typename std::decay< U >::type > conjunction(U &&u) const
Definition: sol.hpp:4883
const auto call_constructor
Definition: sol.hpp:6299
LUA_API int lua_dump(lua_State *L, lua_Writer writer, void *data, int strip)
Definition: lapi.c:1078
bool operator!=(const stack_iterator &r) const
Definition: sol.hpp:15602
void swap(optional &rhs) noexcept
Definition: sol.hpp:6068
LUALIB_API int luaL_ref(lua_State *L, int t)
Definition: lauxlib.c:646
static int real_next_traits(std::false_type, lua_State *L)
Definition: sol.hpp:21262
#define lua_pushcfunction(L, f)
Definition: lua.h:370
static int push(lua_State *L, const wchar_t *strb, const wchar_t *stre)
Definition: sol.hpp:14245
constexpr const T * operator->() const
Definition: sol.hpp:5193
static int real_ipairs_call(lua_State *L)
Definition: sol.hpp:21254
basic_reference(basic_reference &&o) noexcept
Definition: sol.hpp:9429
LUA_API int lua_isinteger(lua_State *L, int idx)
Definition: lapi.c:279
bool runnable() const noexcept
Definition: sol.hpp:26220
static int real_size_traits(std::false_type, lua_State *L)
Definition: sol.hpp:21274
basic_table_core(detail::no_safety_tag, lua_State *L, int index)
Definition: sol.hpp:23619
void move_assign(basic_reference< r_main_only > &&r)
Definition: sol.hpp:9295
static R apply(std::index_sequence< I, Ix... >, lua_State *L, int index, record &tracking, Args &&...args)
Definition: sol.hpp:13119
static decltype(auto) pop(lua_State *L)
Definition: sol.hpp:14612
static int push(lua_State *L, const char16_t *str, std::size_t len)
Definition: sol.hpp:14329
push_invoke_t(Arg &&arg)
Definition: sol.hpp:6994
stack_proxy * pointer
Definition: sol.hpp:15954
void tuple_set(std::index_sequence< I... >, T &&value)&&
Definition: sol.hpp:22989
basic_object(std::integral_constant< bool, invert_and_pop >, lua_State *L, int index=-1) noexcept
Definition: sol.hpp:15330
LUA_API int lua_rawget(lua_State *L, int idx)
Definition: lapi.c:698
enum MQTTPropertyCodes value
const auto direct_error
Definition: sol.hpp:3854
std::string short_demangle_from_type_name(std::string realname)
Definition: sol.hpp:8203
meta::conditional_t< meta::is_c_str_of_v< uF, char >||meta::is_c_str_of_v< uF, char16_t >||meta::is_c_str_of_v< uF, char32_t >||meta::is_c_str_of_v< uF, wchar_t >, std::add_pointer_t< std::add_const_t< std::remove_all_extents_t< Fq >>>, std::decay_t< Fq >> F
Definition: sol.hpp:21757
basic_lua_table(lua_State *L, ref_index index)
Definition: sol.hpp:24283
constexpr const Char * data() const
Definition: core.h:388
int overload_match_arity(Match &&matchfx, lua_State *L, int fxarity, int start, Args &&...args)
Definition: sol.hpp:16825
void_tuple_element_t< i, args_tuple > arg_at
Definition: sol.hpp:1510
void accumulate_and_mark(const std::string &n, std::string &aux_message, int &marker)
Definition: sol.hpp:8585
binding(Args &&...args)
Definition: sol.hpp:21761
std::array< C, 4 > code_units
Definition: sol.hpp:11896
base_list< Args... > bases
Definition: sol.hpp:8399
optional< T > SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) const &
Definition: sol.hpp:5800
int dump(lua_Writer writer, void *userdata, bool strip, Fx &&on_error) const
Definition: sol.hpp:19402
static int push(lua_State *L, const char *strb, const char *stre)
Definition: sol.hpp:14088
static const std::string & gc_table()
Definition: sol.hpp:8286
optional< usertype_storage< T > & > maybe_get_usertype_storage(lua_State *L)
Definition: sol.hpp:22515
basic_thread(lua_State *L, int index=-1)
Definition: sol.hpp:25927
static bool check(lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:11744
const_reverse_iterator crend() const
Definition: sol.hpp:16042
#define LUA_GCSETSTEPMUL
Definition: lua.h:326
stack_reference argument_type
Definition: sol.hpp:8910
basic_reference(lua_State *oL, const basic_reference<!main_only > &o) noexcept
Definition: sol.hpp:9329
as_container_t(T &value)
Definition: sol.hpp:6963
static heap_info state
Definition: Heap.c:58
int success(int count)
Definition: test6.c:567
void tuple_set(std::index_sequence< I... >, std::tuple< Args... > &&args)
Definition: sol.hpp:24185
basic_reference< true > main_reference
Definition: forward.hpp:611
const_iterator cend() const
Definition: sol.hpp:25582
static int push(lua_State *L, constructor_wrapper< Fxs... > &&c)
Definition: sol.hpp:18692
static auto call(object_type &mem) -> detail::array_return_type< decltype(mem.*fx)>
Definition: sol.hpp:16216
properties_enrollment_allowed(int &times, std::bitset< 64 > &props, automagic_enrollments &enroll)
Definition: sol.hpp:10242
stack_reference(lua_State *L, absolute_index i) noexcept
Definition: sol.hpp:8806
lua_State * lua_state() const
Definition: sol.hpp:15491
constexpr bool is_adl_sol_lua_interop_check_v
Definition: sol.hpp:10389
int & operator[](std::size_t i)
Definition: sol.hpp:6378
static int push(lua_State *L, char32_t c)
Definition: sol.hpp:14467
optional_copy_base(const optional_copy_base &rhs)
Definition: sol.hpp:4346
constexpr auto associated_nullopt_v
Definition: sol.hpp:6205
record() noexcept
Definition: sol.hpp:10336
protected_function_result safe_script(lua_Reader reader, void *data, Fx &&on_error, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25330
index_call_function * index
Definition: sol.hpp:21734
type get_type(lua_State *L) const noexcept
Definition: sol.hpp:9247
std::size_t result_type
Definition: sol.hpp:8911
state(lua_CFunction panic, lua_Alloc alfunc, void *alpointer=nullptr)
Definition: sol.hpp:26020
basic_protected_function(proxy_base< Super > &&p)
Definition: sol.hpp:19333
basic_object(lua_State *L, in_place_type_t< T >, Args &&...args) noexcept
Definition: sol.hpp:15401
T * ptr(T *val)
Definition: sol.hpp:1598
void for_each_table(lua_State *L, Fx &&fx)
Definition: sol.hpp:22016
detail::enable_if_t< std::is_constructible< T, U && >::value &&!std::is_same< detail::decay_t< U >, in_place_t >::value &&!std::is_same< optional< T >, detail::decay_t< U >>::value > enable_forward_value
Definition: sol.hpp:4144
int push() const noexcept
Definition: sol.hpp:8834
traits_type::args_list args_list
Definition: sol.hpp:16267
bool is() const
Definition: sol.hpp:24809
const std::array< std::string, 37 > & meta_function_names()
Definition: sol.hpp:7320
std::integral_constant< bool, std::is_same_v< T, override_value_t >||std::is_same_v< T, update_if_empty_t >||std::is_same_v< T, create_if_nil_t >> is_insert_mode
Definition: sol.hpp:7042
as_table_t(Arg &&arg)
Definition: sol.hpp:6837
std::remove_pointer_t< free_function_pointer_type > signature_type
Definition: sol.hpp:1063
lightuserdata_value(void *data)
Definition: sol.hpp:6705
static int real_add_call(lua_State *L)
Definition: sol.hpp:21290
static bool check(lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:11699
int dump(lua_Writer writer, void *userdata, bool strip=false) const
Definition: sol.hpp:19041
optional< object > is_loaded_package(const std::string &key)
Definition: sol.hpp:25018
Definition: lobject.h:712
int member_default_to_string(std::false_type, lua_State *L)
Definition: sol.hpp:11057
basic_thread(lua_State *L, T &&r)
Definition: sol.hpp:25919
int multi_push_reference(lua_State *L, T &&t, Args &&...args)
Definition: sol.hpp:10692
typename invoke_result< F, Us... >::type invoke_result_t
Definition: sol.hpp:4102
basic_object(detail::no_safety_tag, lua_State *L, T &&r) noexcept
Definition: sol.hpp:15353
const void * pointer() const noexcept
Definition: sol.hpp:8850
types type
Definition: sol.hpp:801
optional_move_base(optional_move_base &&rhs) noexcept(std::is_nothrow_move_constructible< T >::value)
Definition: sol.hpp:4376
member_function(function_type f, Args &&...args)
Definition: sol.hpp:17934
static void set_default_handler(const T &ref)
Definition: sol.hpp:19203
protected_function_result operator()(Args &&...args) const
Definition: sol.hpp:19431
ebco & operator=(const T &v)
Definition: sol.hpp:6442
basic_protected_function(lua_State *L, absolute_index index)
Definition: sol.hpp:19369
constexpr std::size_t count_for_to_pack_v
Definition: sol.hpp:1811
void luajit_exception_off(lua_State *L)
Definition: sol.hpp:15196
basic_protected_function(lua_State *L, raw_index index)
Definition: sol.hpp:19379
static int call(lua_State *L) noexcept(traits_type::is_noexcept)
Definition: sol.hpp:17710
#define SOL_FILE_ID_SIZE_I_
Definition: sol.hpp:427
stack_iterator< proxy_t, is_const > operator+(typename stack_iterator< proxy_t, is_const >::difference_type n, const stack_iterator< proxy_t, is_const > &r)
Definition: sol.hpp:15624
this_main_state(lua_State *Ls)
Definition: sol.hpp:7070
meta::boolean< has_traits_insert_test< T >::value > has_traits_insert
Definition: sol.hpp:19952
load_status status() const noexcept
Definition: sol.hpp:24632
basic_reference(lua_State *L, lua_nil_t) noexcept
Definition: sol.hpp:9417
constexpr auto optional_map_impl(Opt &&opt, F &&f) -> optional< Ret >
Definition: sol.hpp:5528
#define lua_isnone(L, n)
Definition: lua.h:378
const_reverse_iterator rend() const
Definition: sol.hpp:16036
static int push(lua_State *L, std::function< Signature > &&fx)
Definition: sol.hpp:18503
static int push(lua_State *L, const std::function< Signature > &fx)
Definition: sol.hpp:18495
constexpr std::in_place_type_t< T > in_place_type
Definition: sol.hpp:3925
LUA_API void lua_pushnil(lua_State *L)
Definition: lapi.c:473
basic_lightuserdata< reference > lightuserdata
Definition: forward.hpp:719
static int push(lua_State *L, const char *str)
Definition: sol.hpp:14059
LUA_API int lua_isnumber(lua_State *L, int idx)
Definition: lapi.c:285
static int real_get_traits(std::false_type, lua_State *L)
Definition: sol.hpp:21202
constexpr const char * not_enough_stack_space_environment
Definition: sol.hpp:10410
static int index_of_call(lua_State *L)
Definition: sol.hpp:21387
thread_status status() const
Definition: sol.hpp:25973
protected_handler(const target_t &target)
Definition: sol.hpp:19116
stateless_stack_reference(lua_State *, raw_index i) noexcept
Definition: sol.hpp:8744
static int push(lua_State *L, const wchar_t *wstr, std::size_t sz)
Definition: sol.hpp:14219
static int push(lua_State *L, lua_nil_t)
Definition: sol.hpp:13830
difference_type operator-(const stack_iterator &r) const
Definition: sol.hpp:15578
as_container_t(Arg0 &&arg0, Arg1 &&arg1, Args &&...args)
Definition: sol.hpp:6941
basic_lua_table< reference > lua_table
Definition: forward.hpp:645
SOL_TL_OPTIONAL_11_CONSTEXPR T & operator*()
Definition: sol.hpp:6090
const bool default_safe_function_calls
Definition: sol.hpp:2287
push_popper_n(lua_State *, int)
Definition: sol.hpp:8987
meta::boolean< has_traits_index_of_test< T >::value > has_traits_index_of
Definition: sol.hpp:19949
bool valid() const noexcept
Definition: sol.hpp:9509
bool attempt_alloc_unique(lua_State *L, std::size_t ptr_align, std::size_t ptr_size, std::size_t real_align, std::size_t real_size, std::size_t allocated_size, void *&pointer_adjusted, void *&dx_adjusted, void *&id_adjusted, void *&data_adjusted)
Definition: sol.hpp:9961
void invoke(types< void >, std::index_sequence< I >, std::ptrdiff_t n)
Definition: sol.hpp:26080
constexpr bool operator!=(const optional< T > &lhs, const optional< U > &rhs)
relop
Definition: sol.hpp:5324
MQTTProperties props
Definition: paho_c_pub.c:54
LUA_KCONTEXT lua_KContext
Definition: lua.h:100
constexpr bool is_table_v
Definition: sol.hpp:7779
bool operator()(const basic_reference< lb > &lhs, const lua_nil_t &rhs) const
Definition: sol.hpp:9591
std::tuple_element_t< N, std::remove_reference_t< Tuple >> tuple_element_t
Definition: sol.hpp:997
static int push(lua_State *L, Arg &&arg, Args &&...args)
Definition: sol.hpp:13506
LUA_API const void * lua_topointer(lua_State *L, int idx)
Definition: lapi.c:451
stack_iterator< stack_proxy, true > const_iterator
Definition: sol.hpp:15958
basic_coroutine(lua_State *L, int index=-1)
Definition: sol.hpp:26173
constexpr const char * not_enough_stack_space_integral
Definition: sol.hpp:8577
reverse_iterator rbegin()
Definition: sol.hpp:15877
reference ref_value
Definition: sol.hpp:24740
basic_table_iterator(reference_type x)
Definition: sol.hpp:23301
const void * pointer(lua_State *L) const noexcept
Definition: sol.hpp:9240
void operator()(Args &&...args)
Definition: sol.hpp:19557
basic_object< reference > object
Definition: forward.hpp:717
static constexpr char32_t decode(unsigned char b0, unsigned char b1, unsigned char b2)
Definition: sol.hpp:11957
int top() const
Definition: sol.hpp:26531
table create(Name &&name, int narr, int nrec, Key &&key, Value &&value, Args &&...args)
Definition: sol.hpp:24009
#define LUA_TUSERDATA
Definition: lua.h:72
optional< T > or_else(F &&f) const &&
Definition: sol.hpp:5807
basic_thread< stack_reference > stack_thread
Definition: forward.hpp:729
overloaded_function(overload_list set)
Definition: sol.hpp:18012
state_view & new_enum(const string_view &name, std::initializer_list< std::pair< string_view, T >> items)
Definition: sol.hpp:25757
basic_object(const stack_reference &r) noexcept
Definition: sol.hpp:15371
int adl_default_to_string(std::false_type, lua_State *L)
Definition: sol.hpp:11072
LUA_API int lua_rawgeti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.c:710
iterator end()
Definition: sol.hpp:26455
T && value()&&
Definition: sol.hpp:6463
constexpr optional(detail::enable_if_t< std::is_constructible< T, Args... >::value, in_place_t >, Args &&...args)
Definition: sol.hpp:4990
basic_lua_table< stack_reference > stack_lua_table
Definition: forward.hpp:646
int comparsion_operator_wrap(lua_State *L)
Definition: sol.hpp:11100
reference & value()&
Definition: sol.hpp:24794
int push(lua_State *L) const noexcept
Definition: sol.hpp:8758
static int real_index_set_traits(std::true_type, lua_State *L)
Definition: sol.hpp:21222
constexpr const char * not_enough_stack_space_meta_function_name
Definition: sol.hpp:8579
meta::tuple_types< typename fx_t::return_type > return_types
Definition: sol.hpp:19568
stack_iterator< stack_proxy, false > iterator
Definition: sol.hpp:15759
static int push(lua_State *L, const T &tablecont)
Definition: sol.hpp:13715
int lua_c_wrapper(lua_State *L)
Definition: sol.hpp:18196
stack_guard(lua_State *L, int top, std::function< void(int, int)> fx=detail::stack_fail)
Definition: sol.hpp:9724
std::integral_constant< bool, std::is_arithmetic< T >::value||std::is_pointer< T >::value||std::is_array< T >::value > is_builtin_type
Definition: sol.hpp:942
lua_State * main_thread(lua_State *L, lua_State *backup_if_unsupported=nullptr)
Definition: sol.hpp:9057
types< object_type &, FArgs... > free_args_list
Definition: sol.hpp:16268
auto optional_map_impl(Opt &&opt, F &&f) -> optional< monostate >
Definition: sol.hpp:5535
protected_function_result do_reader(lua_Reader reader, void *data, const basic_environment< E > &env, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25256
basic_coroutine(basic_function< base_t > &&b, handler_t eh)
Definition: sol.hpp:26131
meta::boolean< has_traits_set_test< T >::value > has_traits_set
Definition: sol.hpp:19916
lua_State * lua_state() const
Definition: sol.hpp:23188
protected_function_result safe_script(const string_view &code, Fx &&on_error, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25347
meta::function_args_t< function_type > args_lists
Definition: sol.hpp:17929
bool operator()(const std::unique_ptr< binding_base > &ptr) const
Definition: sol.hpp:21963
#define nullptr
Definition: backward.hpp:386
std_shim(unsafe_function lua_func)
Definition: sol.hpp:19553
decltype(auto) traverse_get(Keys &&...keys) const
Definition: sol.hpp:23745
void select_set_fx(lua_State *L, Args &&...args)
Definition: sol.hpp:18225
int destruct_usertype_storage(lua_State *L)
Definition: sol.hpp:22315
optional_move_assign_base & operator=(optional_move_assign_base &&rhs) noexcept(std::is_nothrow_move_constructible< T >::value &&std::is_nothrow_move_assignable< T >::value)
Definition: sol.hpp:4433
basic_table_core(detail::no_safety_tag, lua_State *L, ref_index index)
Definition: sol.hpp:23621
void operator()(T &&obj, Args &&...args) const
Definition: sol.hpp:6226
const_reverse_iterator rbegin() const
Definition: sol.hpp:15883
constexpr bool operator>=(const optional< T > &lhs, const optional< U > &rhs)
relop
Definition: sol.hpp:5344
iterator end() const
Definition: sol.hpp:23698
static int push(lua_State *L, const char16_t *strb, const char16_t *stre)
Definition: sol.hpp:14323
lu_byte right
Definition: lparser.c:1229
stack_iterator operator+(difference_type idx) const
Definition: sol.hpp:15582
int dump_throw_on_error(lua_State *L, int result_code, lua_Writer writer_function, void *userdata, bool strip)
Definition: sol.hpp:18923
int is_indexer(call_construction)
Definition: sol.hpp:21617
protected_function_result script_file(const std::string &filename, const basic_environment< E > &env, Fx &&on_error, load_mode mode=load_mode::any)
Definition: sol.hpp:25506
void abandon() noexcept
Definition: sol.hpp:15908
static int push(lua_State *L, user< T > &&u)
Definition: sol.hpp:14021
lib
Definition: sol.hpp:7102
reference argument_type
Definition: sol.hpp:9612
basic_coroutine(lua_nil_t n)
Definition: sol.hpp:26170
detail::invoke_result_t< U > map_or_else(F &&f, U &&u)&
Maps the stored value with f if there is one, otherwise calls u and returns the result.
Definition: sol.hpp:4851
usertype_storage_base * p_usb
Definition: sol.hpp:21942
static int insert_call(lua_State *L)
Definition: sol.hpp:21371
int lua_cfunction_trampoline(lua_State *L, lua_CFunction f)
Definition: sol.hpp:7981
int operator()(lua_State *L, int index, type expected, type actual, string_view message) const noexcept(false)
Definition: sol.hpp:8669
#define LUA_MULTRET
Definition: lua.h:36
static constexpr bool is_overlong(char32_t u, std::size_t bytes)
Definition: sol.hpp:11942
typename std::conditional< B, T, F >::type conditional_t
Definition: core.h:253
static void push_back_at_end(std::false_type, types< V > t, lua_State *L, T &cont, std::size_t idx)
Definition: sol.hpp:12393
detail::enable_if_t< std::is_constructible< T, Other >::value &&std::is_assignable< T &, Other >::value &&!std::is_constructible< T, optional< U > & >::value &&!std::is_constructible< T, optional< U > && >::value &&!std::is_constructible< T, const optional< U > & >::value &&!std::is_constructible< T, const optional< U > && >::value &&!std::is_convertible< optional< U > &, T >::value &&!std::is_convertible< optional< U > &&, T >::value &&!std::is_convertible< const optional< U > &, T >::value &&!std::is_convertible< const optional< U > &&, T >::value &&!std::is_assignable< T &, optional< U > & >::value &&!std::is_assignable< T &, optional< U > && >::value &&!std::is_assignable< T &, const optional< U > & >::value &&!std::is_assignable< T &, const optional< U > && >::value > enable_assign_from_other
Definition: sol.hpp:4165
std::initializer_list< int > swallow
Definition: sol.hpp:954
meta::boolean< has_traits_size_test< T >::value > has_traits_size
Definition: sol.hpp:19937
auto as_args(Source &&source)
Definition: sol.hpp:26378
handler_t error_handler
Definition: sol.hpp:26053
static int push(lua_State *L, T *cont)
Definition: sol.hpp:21512
int stack_index() const noexcept
Definition: sol.hpp:8770
basic_environment< main_reference > main_environment
Definition: forward.hpp:663
const T & value() const &
Definition: sol.hpp:7008
decltype(auto) get_key(std::true_type, T &&t)
Definition: sol.hpp:19982
std::remove_cv< std::remove_reference_t< T >> unqualified
Definition: sol.hpp:880
value_type * pointer
Definition: sol.hpp:23286
meta::boolean< has_traits_index_set_test< T >::value > has_traits_index_set
Definition: sol.hpp:19922
constexpr T & value_or(U &&u) const
Definition: sol.hpp:6139
stack_table_core< true > stack_global_table
Definition: forward.hpp:641
lua_bind_traits< meta::unqualified_t< F > > traits_type
Definition: sol.hpp:16155
LUA_API int lua_resume(lua_State *L, lua_State *from, int nargs, int *nresults)
Definition: ldo.c:661
static int push(lua_State *L, factory_wrapper< Functions... > &&fw)
Definition: sol.hpp:18617
LUA_API int lua_setmetatable(lua_State *L, int objindex)
Definition: lapi.c:901
std::tuple< decltype(stack::get< Tn >nullptr, 0))... > R
Definition: sol.hpp:13110
member_variable(function_type v, Args &&...args)
Definition: sol.hpp:17964
meta::conditional_t< is_const, const proxy_t, proxy_t > reference
Definition: sol.hpp:15508
const char * format_string
Definition: sol.hpp:3858
pointer operator->()
Definition: sol.hpp:15536
static table create(lua_State *L, int narr=0, int nrec=0)
Definition: sol.hpp:23969
static bool type_unique_cast_bases(types<>, void *, void *, const string_view &)
Definition: sol.hpp:8473
LUAMOD_API int luaopen_debug(lua_State *L)
Definition: ldblib.c:473
meta::boolean< has_erase_key_test< T >::value > has_erase_key
Definition: sol.hpp:19904
static const char * get(lua_State *L, int index, record &tracking)
Definition: sol.hpp:12804
int stack_index() const noexcept
Definition: sol.hpp:24696
bool valid() const
Definition: sol.hpp:22926
type get_type() const
Definition: sol.hpp:22941
LUA_API int lua_toboolean(lua_State *L, int idx)
Definition: lapi.c:375
auto as_returns(Source &&source)
Definition: sol.hpp:26567
static int ipairs_call(lua_State *L)
Definition: sol.hpp:21399
static int push_keyed(lua_State *L, K &&k, T *obj)
Definition: sol.hpp:13539
LUA_API void lua_rawsetp(lua_State *L, int idx, const void *p)
Definition: lapi.c:882
error(std::string &&str)
Definition: sol.hpp:3888
std::enable_if_t<!value, T > disable_if_t
Definition: sol.hpp:1723
bool check_types(types< Args... >, lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:10843
static int push(lua_State *, const this_state &)
Definition: sol.hpp:14531
static int push(lua_State *L, const detail::tagged< T, const constructor_wrapper< Fxs... >> &c)
Definition: sol.hpp:18688
constexpr auto bytecode_dump_writer
Definition: sol.hpp:3833
LUAMOD_API int luaopen_os(lua_State *L)
Definition: loslib.c:426
stateless_stack_reference(raw_index i) noexcept
Definition: sol.hpp:8748
reverse_iterator rend()
Definition: sol.hpp:16030
void select(lua_State *L, Fx &&fx, Args &&...args)
Definition: sol.hpp:18357
U map_or(F &&f, U &&u) const &
map_or
Definition: sol.hpp:4829
SOL_TL_OPTIONAL_11_CONSTEXPR T & get()&
Definition: sol.hpp:4315
basic_thread(lua_State *L, ref_index index)
Definition: sol.hpp:25934
void tuple_set(std::index_sequence< I... >, T &&value)&&
Definition: sol.hpp:22829
decltype(auto) unqualified_interop_get(lua_State *L, int index, void *unadjusted_pointer, record &tracking)
Definition: sol.hpp:10468
load_status err
Definition: sol.hpp:24590
MQTTClient d
Definition: test10.c:1656
lua_value(arr il)
Definition: sol.hpp:24772
decoded_result< It > utf32_to_code_point(It it, It last)
Definition: sol.hpp:12150
const char * name
Definition: lua.h:471
LUA_API void lua_rawset(lua_State *L, int idx)
Definition: lapi.c:877
detail::inheritance_check_function base_class_check_func
Definition: sol.hpp:21939
void deref() const noexcept
Definition: sol.hpp:9332
std::remove_pointer_t< std::decay_t< Function > > function_type
Definition: sol.hpp:17638
static int push(lua_State *L, raw_index ri)
Definition: sol.hpp:14193
SOL_TL_OPTIONAL_11_CONSTEXPR T && value()&&
Definition: sol.hpp:5265
int push(lua_State *L, const as_returns_t< T > &e)
Definition: sol.hpp:26574
void * align_user(void *ptr)
Definition: sol.hpp:9888
bool is_stack(std::true_type) const
Definition: sol.hpp:15282
void *(* pf)(int, unsigned char, char *, size_t)
Definition: MQTTPacket.h:32
static int push(lua_State *L, wchar_t c)
Definition: sol.hpp:14451
basic_reference(lua_State *L, detail::global_tag) noexcept
Definition: sol.hpp:9322
const char * name
Definition: lauxlib.h:38
type get_type() const
Definition: sol.hpp:23177
error(detail::direct_error_tag, std::string &&str)
Definition: sol.hpp:3892
LUA_API void * lua_touserdata(lua_State *L, int idx)
Definition: lapi.c:432
basic_protected_function(lua_State *L, raw_index index, handler_t eh)
Definition: sol.hpp:19382
basic_reference(basic_reference<!main_only > &&o) noexcept
Definition: sol.hpp:9437
#define LUA_OPUNM
Definition: lua.h:217
type
Definition: sol.hpp:7176
static const std::string & name()
Definition: sol.hpp:8266
int(* lua_Writer)(lua_State *L, const void *p, size_t sz, void *ud)
Definition: lua.h:119
meta::unqualified_t< T > Tu
Definition: sol.hpp:9011
static constexpr char32_t decode(unsigned char b0, unsigned char b1, unsigned char b2, unsigned char b3)
Definition: sol.hpp:11960
constexpr override_value_t override_value
Definition: sol.hpp:7031
basic_coroutine(lua_State *L, int index, handler_t eh)
Definition: sol.hpp:26176
optional< usertype_storage_base & > maybe_get_usertype_storage_base(lua_State *L, const char *gcmetakey)
Definition: sol.hpp:22499
#define LUA_GCSTEP
Definition: lua.h:324
LUA_API void lua_seti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.c:843
int default_to_string(lua_State *L)
Definition: sol.hpp:11089
int upvalues
Definition: sol.hpp:6793
std::integral_constant< bool,!std::is_array_v< T > &&(std::is_pointer_v< T >||is_detected_v< meta_detail::is_explicitly_dereferenceable_test, T >)> is_pointer_like
Definition: sol.hpp:1547
static int push(lua_State *L, no_construction c, function_detail::call_indicator)
Definition: sol.hpp:18643
bool is_gc_on() const
Definition: sol.hpp:25623
int typed_static_trampoline(lua_State *L)
Definition: sol.hpp:8067
void reset() noexcept
Destroys the stored value if one exists, making the optional empty.
Definition: sol.hpp:5304
LUALIB_API int luaL_callmeta(lua_State *L, int obj, const char *event)
Definition: lauxlib.c:839
stack_unsafe_function stack_function
Definition: forward.hpp:690
basic_table_iterator & operator++()
Definition: sol.hpp:23312
static int real_ipairs_traits(std::true_type, lua_State *L)
Definition: sol.hpp:21246
static int real_index_call(lua_State *L)
Definition: sol.hpp:21159
void tuple_set(std::index_sequence< I... >, T &&value)&
Definition: sol.hpp:22819
variadic_args(lua_State *luastate, int stackindex=-1)
Definition: sol.hpp:26422
stack_iterator operator++(int)
Definition: sol.hpp:15551
static iterator begin(lua_State *L, T &)
Definition: sol.hpp:20070
global_table & globals()
Definition: sol.hpp:25592
void pop(lua_State *L, int n=1) const noexcept
Definition: sol.hpp:9501
protected_function_result safe_function_result
Definition: forward.hpp:697
meta::bind_traits< Signature > base_t
Definition: sol.hpp:7759
constexpr bool operator>(const optional< T > &lhs, const optional< U > &rhs)
relop
Definition: sol.hpp:5334
static int real_size_traits(std::true_type, lua_State *L)
Definition: sol.hpp:21270
T * usertype_allocate(lua_State *L)
Definition: sol.hpp:9998
functor_function(function_type f, Args &&...args)
Definition: sol.hpp:17900
void copy_assign(const basic_reference< r_main_only > &r)
Definition: sol.hpp:9271
static int push(lua_State *L, const char32_t(&str)[N])
Definition: sol.hpp:14439
detail::enable_if_t<!std::is_same< optional< T >, detail::decay_t< U >>::value &&!detail::conjunction< std::is_scalar< T >, std::is_same< T, detail::decay_t< U >>>::value &&std::is_constructible< T, U >::value &&std::is_assignable< T &, U >::value > enable_assign_forward
Definition: sol.hpp:4156
constexpr auto resolve_i(types< R(Args...)>, F &&) -> R(meta::unqualified_t< F >::*)(Args...)
Definition: sol.hpp:18046
typename lua_value::arr array_value
Definition: sol.hpp:24820
std::input_iterator_tag iterator_category
Definition: sol.hpp:23284
Container dump(Fx &&on_error) const
Definition: sol.hpp:19053
typename at_in_pack< I, Args... >::type at_in_pack_t
Definition: sol.hpp:1765
static decltype(auto) get(lua_State *L, int index, record &tracking)
Definition: sol.hpp:12251
basic_reference & operator=(const basic_reference &r) noexcept
Definition: sol.hpp:9448
constexpr const T & operator*() const &
Definition: sol.hpp:5213
int push_as_upvalues(lua_State *L, T &item)
Definition: sol.hpp:14975
basic_reference(const stack_reference &r) noexcept
Definition: sol.hpp:9348
#define LUA_NOREF
Definition: lauxlib.h:85
lua_State * lua_state() const
Definition: sol.hpp:22952
static int push(lua_State *L, const char32_t *str)
Definition: sol.hpp:14394
meta_function meta_method
Definition: sol.hpp:7318
static basic_thread create(lua_State *L)
Definition: sol.hpp:25992
reference_type ref
Definition: sol.hpp:23292
error_result(int results)
Definition: sol.hpp:3864
constexpr detail::invoke_result_t< F, const T && > and_then(F &&f) const &&
Definition: sol.hpp:4650
void clear_entries(const reference &registry_reference)
Definition: sol.hpp:14965
#define LUA_ERRFILE
Definition: lauxlib.h:26
lu_byte left
Definition: lparser.c:1228
usertype_storage< T > & create_usertype_storage(lua_State *L)
Definition: sol.hpp:22459
type get_type() const noexcept
Definition: sol.hpp:15664
auto make_string_view(base_classes_tag)
Definition: sol.hpp:21587
void script(lua_State *L, const string_view &code, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:15163
void * align_usertype_unique_tag(void *ptr)
Definition: sol.hpp:9843
int push(lua_State *L, const basic_variadic_results< Al > &e)
Definition: sol.hpp:26638
static table create_table(lua_State *L, int narr, int nrec, Key &&key, Value &&value, Args &&...args)
Definition: sol.hpp:25825
#define SOL_IS_DEFAULT_OFF(OP_SYMBOL)
Definition: sol.hpp:50
static int call(lua_State *L)
Definition: sol.hpp:21782
bool is_main_thread() const
Definition: sol.hpp:25963
state_view & traverse_set(Args &&...args)
Definition: sol.hpp:25740
state_view & new_enum(const string_view &name, Args &&...args)
Definition: sol.hpp:25751
std::false_type sfinae_no_t
Definition: sol.hpp:874
LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
Definition: lapi.c:837
static int writer(lua_State *L, const void *b, size_t size, void *ud)
Definition: lstrlib.c:221
basic_lightuserdata(lua_State *L, int index=-1)
Definition: sol.hpp:26348
static int push(lua_State *L, char c)
Definition: sol.hpp:14122
constexpr bool all_v
Definition: sol.hpp:1713
constexpr const char * not_enough_stack_space_string
Definition: sol.hpp:10406
basic_reference(lua_State *L, const stack_reference &r) noexcept
Definition: sol.hpp:9390
push_invoke_t(Arg0 &&arg0, Arg1 &&arg1, Args &&...args)
Definition: sol.hpp:6997
#define lua_remove(L, idx)
Definition: lua.h:391
protected_function_result safe_script_file(const std::string &filename, load_mode mode=load_mode::any)
Definition: sol.hpp:25403
has_empty< T > has_traits_empty
Definition: sol.hpp:19943
int no_construction_error(lua_State *L)
Definition: sol.hpp:16638
T const & value() const &
Definition: sol.hpp:6277
LUA_API int lua_compare(lua_State *L, int index1, int index2, int op)
Definition: lapi.c:327
void luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount) const
Definition: sol.hpp:18947
static int push(lua_State *L, const std::initializer_list< T > &il)
Definition: sol.hpp:13820
std::unique_ptr< lua_State, detail::state_deleter > unique_base
Definition: sol.hpp:26012
basic_environment< stack_reference > stack_environment
Definition: forward.hpp:664
int call_wrapper_function(std::true_type, lua_State *L)
Definition: sol.hpp:17530
int basic_insert_dump_writer(lua_State *, const void *memory, size_t memory_size, void *userdata)
Definition: sol.hpp:3814
constexpr const char * not_a_number_integral
Definition: sol.hpp:8571
basic_object(lua_State *L, absolute_index index) noexcept
Definition: sol.hpp:15391
static int push(lua_State *L, no_construction)
Definition: sol.hpp:18638
lua_reg_table & l
Definition: sol.hpp:10272
as_table_t< meta::unqualified_t< T > > as_table(T &&container)
Definition: sol.hpp:6908
optional< T > SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) const &
Definition: sol.hpp:4787
Container dump() const
Definition: sol.hpp:19417
basic_coroutine(lua_State *L, ref_index index)
Definition: sol.hpp:26200
basic_coroutine(T &&r) noexcept
Definition: sol.hpp:26109
LUA_API lua_Integer lua_tointegerx(lua_State *L, int idx, int *pisnum)
Definition: lapi.c:365
typename bind_traits< Signature >::return_type function_return_t
Definition: sol.hpp:1525
static int push(lua_State *L, const yielding_t< T > &f, Args &&...args)
Definition: sol.hpp:18439
std::add_lvalue_reference_t< meta::unwrapped_t< std::remove_reference_t< decltype(detail::deref(member))> > > M
Definition: sol.hpp:17961
int push() const
Definition: sol.hpp:15668
void abandon(lua_State *=nullptr)
Definition: sol.hpp:8789
static int push(lua_State *L, yielding_t< T > &&f, Args &&...args)
Definition: sol.hpp:18450
protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n, detail::protected_handler< b, handler_t > &h) const
Definition: sol.hpp:19231
std::integral_constant< bool, is_userdata_v< T >||is_table_v< T >||meta::is_specialization_of_v< T, basic_environment >> is_environment
Definition: sol.hpp:7811
protected_function_result safe_script(lua_Reader reader, void *data, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25339
static int index_call_with_(lua_State *L, void *target)
Definition: sol.hpp:21793
int operator()(T &&value) const
Definition: sol.hpp:14580
std::tuple< Functions... > functions
Definition: sol.hpp:6303
encoded_result< char16_t > code_point_to_utf16(char32_t codepoint)
Definition: sol.hpp:12013
void insert_default_registrations(IFx &&ifx, Fx &&fx)
Definition: sol.hpp:21625
#define lua_tointeger(L, i)
Definition: lua.h:362
SOL_TL_OPTIONAL_11_CONSTEXPR T * operator->()
Definition: sol.hpp:6082
void collect_garbage()
Definition: sol.hpp:25632
#define SOL_TL_OPTIONAL_11_CONSTEXPR
Definition: sol.hpp:4006
T && value()&&
Definition: sol.hpp:6886
decltype(auto) deref(T &&item)
Definition: sol.hpp:1566
static int push(lua_State *L, const function_arguments< T, Args... > &fp)
Definition: sol.hpp:18468
static int push_fx(lua_State *L, F &&f, Args &&...args)
Definition: sol.hpp:13483
bool operator()(const basic_reference< lb > &lhs, const basic_reference< rb > &rhs) const
Definition: sol.hpp:9596
reference operator*() const
Definition: sol.hpp:15532
static int call_with_(lua_State *L, void *target)
Definition: sol.hpp:21769
constexpr const T & operator*() const
Definition: sol.hpp:6096
basic_protected_function(const basic_function< base_t > &b)
Definition: sol.hpp:19303
static bool check(lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:11690
constexpr const char * not_enough_stack_space_integral
Definition: sol.hpp:10405
static int push_sized(lua_State *L, const char *str, std::size_t len)
Definition: sol.hpp:14076
typename detail::tuple_types_< Args... >::type tuple_types
Definition: sol.hpp:973
LUA_API lua_State * lua_newstate(lua_Alloc f, void *ud)
Definition: lstate.c:385
static int push_lvalue(std::true_type, lua_State *L, const C &cont)
Definition: sol.hpp:21480
static int real_new_index_call(lua_State *L)
Definition: sol.hpp:21230
static int push(lua_State *L, no_metatable_t, const user< T > &u)
Definition: sol.hpp:14026
int stack_index() const
Definition: sol.hpp:15680
Ret invoke(types< Ret >, std::index_sequence< I >, std::ptrdiff_t n)
Definition: sol.hpp:26074
fallback_uintptr uintptr_t
Definition: format.h:314
U map_or(F &&f, U &&u) const &
map_or
Definition: sol.hpp:5842
int push(lua_State *Ls) const
Definition: sol.hpp:15672
probe get(lua_State *L, Key &&key, int tableindex=-2)
Definition: sol.hpp:14858
int dump(lua_Writer writer, void *userdata, bool strip, Fx &&on_error) const
Definition: sol.hpp:19031
static int push(lua_State *L, lightuserdata_value userdata)
Definition: sol.hpp:13953
LUAMOD_API int luaopen_package(lua_State *L)
Definition: loadlib.c:736
int trampoline(lua_State *L, Fx &&f, Args &&...args)
Definition: sol.hpp:8028
basic_object(lua_State *L, in_place_t, T &&arg, Args &&...args) noexcept
Definition: sol.hpp:15405
constexpr bool is_lua_c_function_v
Definition: sol.hpp:7889
void script(lua_State *L, lua_Reader reader, void *data, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:15154
basic_protected_function(const stack_reference &r)
Definition: sol.hpp:19315
load_result load(const string_view &code, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25542
std::unique_ptr< T, Dx > make_unique_deleter(Args &&...args)
Definition: sol.hpp:6258
call_status luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount, detail::protected_handler< b, handler_t > &h) const
Definition: sol.hpp:19209
T && value()&&
Definition: sol.hpp:7004
int operator()(types< Fx >, meta::index_value< I >, types< R >, types< Args... >, lua_State *L, int, int) const
Definition: sol.hpp:17542
const_reverse_iterator crend() const
Definition: sol.hpp:26486
typename voider< Ts... >::type void_t
Definition: sol.hpp:4111
gc_mode
Definition: sol.hpp:7170
static int real_pairs_traits(std::true_type, lua_State *L)
Definition: sol.hpp:21234
stack_proxy value_type
Definition: sol.hpp:26412
#define LUA_TLIGHTUSERDATA
Definition: lua.h:67
int push() const noexcept
Definition: sol.hpp:23153
void operator()(lua_State *L, submetatable_type smt, reference &fast_index_table)
Definition: sol.hpp:21927
meta::conditional_t< is_matched_lookup::value, std::pair< value_type, value_type >, meta::conditional_t< is_associative::value||is_lookup::value, value_type, std::pair< std::ptrdiff_t, value_type > > > KV
Definition: sol.hpp:20098
ebco(const T &v)
Definition: sol.hpp:6440
static int real_set_traits(std::true_type, lua_State *L)
Definition: sol.hpp:21210
static int push(lua_State *L, const user< T > &u)
Definition: sol.hpp:14016
static int real_empty_call(lua_State *L)
Definition: sol.hpp:21326
static int real_ipairs_traits(std::false_type, lua_State *L)
Definition: sol.hpp:21250
decoded_result< It > utf16_to_code_point(It it, It last)
Definition: sol.hpp:12112
yielding_t(Arg0 &&arg0, Arg1 &&arg1, Args &&...args)
Definition: sol.hpp:6639
typename identity< T >::type identity_t
Definition: sol.hpp:939
int multi_push_reference(lua_State *)
Definition: sol.hpp:10686
#define LUA_FILEHANDLE
Definition: lauxlib.h:217
std::string associated_type_name(lua_State *L, int index, type t)
Definition: sol.hpp:8594
auto as_function(Args &&...args)
Definition: sol.hpp:6814
load_status
Definition: sol.hpp:7162
LUA_API int lua_error(lua_State *L)
Definition: lapi.c:1205
LUALIB_API int luaL_loadbufferx(lua_State *L, const char *buff, size_t size, const char *name, const char *mode)
Definition: lauxlib.c:806
stack_iterator< stack_proxy, false > iterator
Definition: sol.hpp:26416
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs)&&
disjunction
Definition: sol.hpp:4922
#define luaL_getmetatable(L, n)
Definition: lauxlib.h:149
basic_variadic_results(unsafe_function_result fr)
Definition: sol.hpp:26601
basic_metatable< stack_reference > stack_metatable
Definition: forward.hpp:658
void * align_usertype_pointer(void *ptr)
Definition: sol.hpp:9805
#define G(L)
Definition: lstate.h:332
std::string short_demangle_once()
Definition: sol.hpp:8242
basic_environment(env_key_t, const basic_reference< b > &extraction_target)
Definition: sol.hpp:24426
basic_lua_table(lua_State *L, T &&r)
Definition: sol.hpp:24265
Definition: json.hpp:4042
bool check_types(lua_State *, int, Handler &&, record &)
Definition: sol.hpp:10831
decltype(&inheritance< void >::type_unique_cast< void >) inheritance_unique_cast_function
Definition: sol.hpp:8556
optional_copy_assign_base & operator=(const optional_copy_assign_base &rhs)
Definition: sol.hpp:4404
basic_function< stack_reference, false > stack_unsafe_function
Definition: forward.hpp:674
decltype(auto) call(Args &&...args)
error get_traceback_or_errors(lua_State *L)
Definition: sol.hpp:24996
static constexpr bool is_invalid(unsigned char b)
Definition: sol.hpp:11934
stack_iterator(const stack_iterator< proxy_t, true > &r)
Definition: sol.hpp:15521
int(lua_State *, int, type, type, const char *) check_handler_type
Definition: forward.hpp:804
const value_type & const_reference
Definition: sol.hpp:23288
types< Args... > type
Definition: sol.hpp:966
#define lua_tonumber(L, i)
Definition: lua.h:361
int pop_count() const noexcept
Definition: sol.hpp:15905
static int push_rvalue(std::true_type, lua_State *L, C &&cont)
Definition: sol.hpp:21490
SOL_TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept
Definition: sol.hpp:4233
static lua_State *& thread_local_lua_state()
Definition: sol.hpp:24731
basic_reference & operator=(basic_reference<!main_only > &&r) noexcept
Definition: sol.hpp:9453
std::string make_string(Arg &&arg)
Definition: sol.hpp:21592
basic_lightuserdata(lua_State *L, ref_index index)
Definition: sol.hpp:26355
value_type & reference
Definition: sol.hpp:23287
void modify_unique_usertype(const stack_reference &obj, F &&f)
Definition: sol.hpp:11004
basic_lua_table(T &&r) noexcept
Definition: sol.hpp:24293
static void push_back_at_end(std::true_type, types< V >, lua_State *L, T &cont, std::size_t)
Definition: sol.hpp:12388
basic_coroutine(const basic_function< base_t > &b, handler_t eh)
Definition: sol.hpp:26129
lua_State * lua_state() const
Definition: sol.hpp:25081
int copy(lua_State *L) const noexcept
Definition: sol.hpp:9340
basic_reference & operator=(const basic_reference<!main_only > &r) noexcept
Definition: sol.hpp:9458
void restart_gc()
Definition: sol.hpp:25653
char short_src[LUA_IDSIZE]
Definition: lua.h:485
LUAMOD_API int luaopen_coroutine(lua_State *L)
Definition: lcorolib.c:203
auto initializers(Functions &&...functions)
Definition: sol.hpp:6311
unsigned int bool
Definition: MQTTPacket.h:31
basic_table_core(lua_State *L, ref_index index)
Definition: sol.hpp:23667
bool is() const
Definition: sol.hpp:15314
protected_function_result do_string(const string_view &code, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25295
static void insert_at_end(std::true_type, types< V >, lua_State *L, T &cont, std::size_t)
Definition: sol.hpp:12398
LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname)
Definition: lauxlib.c:311
state_view(this_state Ls)
Definition: sol.hpp:25078
static int at_call(lua_State *L)
Definition: sol.hpp:21407
unsafe_function_result & operator=(unsafe_function_result &&o) noexcept
Definition: sol.hpp:15979
bool error() const noexcept
Definition: sol.hpp:26215
boolean<!T::value > neg
Definition: sol.hpp:1695
decltype(auto) call_from_top(types< R > tr, types< Args... > ta, lua_State *L, Fx &&fx, FxArgs &&...args)
Definition: sol.hpp:15091
Container dump(Fx &&on_error) const
Definition: sol.hpp:19424
void clear_package_loaders()
Definition: sol.hpp:25192
const_reverse_iterator crbegin() const
Definition: sol.hpp:26483
bool operator!=(const basic_table_iterator &right) const
Definition: sol.hpp:23348
U value
Definition: sol.hpp:6747
static int push(lua_State *L, const wchar_t *str)
Definition: sol.hpp:14239
#define LUA_TFUNCTION
Definition: lua.h:71
const char * namewhat
Definition: lua.h:472
constexpr const char * not_enough_stack_space_meta_function_name
Definition: sol.hpp:10407
void(*)(stack_reference) undefined_method_func
Definition: sol.hpp:2299
static int call(lua_State *L) noexcept(traits_type::is_noexcept)
Definition: sol.hpp:17760
int(* lua_CFunction_noexcept)(lua_State *L) noexcept
Definition: sol.hpp:6571
static int real_pairs_call(lua_State *L)
Definition: sol.hpp:21242
lua_State * lua_state() const noexcept
Definition: sol.hpp:15896
#define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_
Definition: sol.hpp:413
meta::all< has_key_type< T >, has_key_value_pair< T >, has_mapped_type< T >> is_associative
Definition: sol.hpp:2164
struct void())
static bool check(lua_State *L, int index, type index_type, Handler &&handler, record &tracking)
Definition: sol.hpp:11219
constexpr bool is_userdata_v
Definition: sol.hpp:7808
void convert(const char *strb, const char *stre, F &&f)
Definition: sol.hpp:12205
T && value()&&
Definition: sol.hpp:6281
reference && value()&&
Definition: sol.hpp:24798
const W & write() const
Definition: sol.hpp:16448
lua_value(lua_State *L_, reference r)
Definition: sol.hpp:24775
std::remove_pointer_t< std::decay_t< Function > > function_type
Definition: sol.hpp:17783
optional & operator=(U &&u)
Definition: sol.hpp:5087
static int convert_into(lua_State *L, char *start, std::size_t, const char32_t *strb, const char32_t *stre)
Definition: sol.hpp:14338
basic_reference(const basic_reference<!main_only > &o) noexcept
Definition: sol.hpp:9433
meta::boolean< has_traits_at_test< T >::value > has_traits_at
Definition: sol.hpp:19913
optional(optional< U > &&rhs)
Definition: sol.hpp:5044
std::tuple< Args... > args_tuple
Definition: sol.hpp:1055
basic_environment(lua_State *L, int index=-1)
Definition: sol.hpp:24434
basic_coroutine(lua_State *L, ref_index index, handler_t eh)
Definition: sol.hpp:26203
meta::bind_traits< function_type >::args_list args_lists
Definition: sol.hpp:17958
char[SOL_ID_SIZE_I_] typical_chunk_name_t
Definition: sol.hpp:14925
int handle_errors(lua_State *L, const error_result &er)
Definition: sol.hpp:3872
stateless_reference(lua_State *L, int index=-1) noexcept
Definition: sol.hpp:9190
stateless_reference(lua_State *L, ref_index index) noexcept
Definition: sol.hpp:9198
LUA_API const char * lua_pushstring(lua_State *L, const char *s)
Definition: lapi.c:514
lua_bind_traits< F > traits_type
Definition: sol.hpp:16266
S get_into(lua_State *L, int index, record &tracking)
Definition: sol.hpp:12229
bool valid() const noexcept
Definition: sol.hpp:24636
bool operator()(const lua_nil_t &lhs, const basic_reference< rb > &rhs) const
Definition: sol.hpp:9586
std::true_type can_swap(int) noexcept(noexcept(swap(std::declval< T & >(), std::declval< U & >())))
decltype(auto) get_value(std::true_type, T &&t)
Definition: sol.hpp:19992
lua_CFunction meta_new_idx_call
Definition: sol.hpp:21941
basic_metatable(lua_State *L, ref_index index)
Definition: sol.hpp:24080
std::ptrdiff_t difference_type
Definition: sol.hpp:15955
pointer operator->() const
Definition: sol.hpp:15541
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:4680
std::reverse_iterator< iterator > reverse_iterator
Definition: sol.hpp:15959
variadic_args(lua_State *luastate, int stackindex, int lastindex)
Definition: sol.hpp:26425
void script_file(lua_State *L, const std::string &filename, load_mode mode=load_mode::any)
Definition: sol.hpp:15173
stateless_reference(stack_reference &&r) noexcept
Definition: sol.hpp:9147
basic_userdata(stack_reference &&r)
Definition: sol.hpp:26282
static bool check(types< U >, lua_State *L, int index, type indextype, Handler &&handler, record &tracking)
Definition: sol.hpp:11619
stateless_reference(const stack_reference &r) noexcept
Definition: sol.hpp:9145
SOL_TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U &&...u)
Definition: sol.hpp:4237
static int push(lua_State *L, c_closure cc)
Definition: sol.hpp:13905
meta::boolean< has_traits_pairs_test< T >::value > has_traits_pairs
Definition: sol.hpp:19925
protected_function_result safe_script_file(const std::string &filename, Fx &&on_error, load_mode mode=load_mode::any)
Definition: sol.hpp:25380
int new_index_target_fail(lua_State *L, void *)
Definition: sol.hpp:21854
bool operator()(A &&, B &&) const
Definition: sol.hpp:11040
const auto base_classes
Definition: sol.hpp:8402
#define LUA_SIGNATURE
Definition: lua.h:33
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: sol.hpp:15762
void set(lua_State *L, Key &&key, Value &&value, int tableindex=default_table_index)
Definition: sol.hpp:14755
const_reverse_iterator rend() const
Definition: sol.hpp:15886
unsafe_function lua_func_
Definition: sol.hpp:19538
#define SOL_ID_SIZE_I_
Definition: sol.hpp:419
static T & get(lua_State *L, int index, record &tracking)
Definition: sol.hpp:13068
LUALIB_API void luaL_buffinit(lua_State *L, luaL_Buffer *B)
Definition: lauxlib.c:620
detail::proxy_key_t< Key > key_type
Definition: sol.hpp:22806
constexpr bool neg_v
Definition: sol.hpp:1698
usertype_storage< T > & get_usertype_storage(lua_State *L)
Definition: sol.hpp:22527
static bool check(lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:11613
lua_State * pick_main_thread(lua_State *L, lua_State *backup_if_unsupported=nullptr)
Definition: sol.hpp:9084
decltype(auto) base_class_new_index_propogation_key()
Definition: sol.hpp:8424
virtual const char * what() const noexceptoverride
Definition: sol.hpp:3900
basic_metatable(const stack_reference &r)
Definition: sol.hpp:24062
bool property_always_true(meta_function)
Definition: sol.hpp:10233
static int push(std::true_type, lua_State *L, const T &tablecont)
Definition: sol.hpp:13723
static int call(lua_State *L)
Definition: sol.hpp:17581
typename std::conditional< B, T, F >::type conditional_t
Definition: sol.hpp:4033
int call_exception_handler(lua_State *L, optional< const std::exception & > maybe_ex, string_view what)
Definition: sol.hpp:7937
basic_coroutine(stack_reference &&r, handler_t eh)
Definition: sol.hpp:26141
const char * what() const noexcept
Definition: sol.hpp:4536
probe(bool s, int l)
Definition: sol.hpp:10324
LUA_API lua_Number lua_tonumberx(lua_State *L, int idx, int *pisnum)
Definition: lapi.c:355
constexpr type lua_type_of_v
Definition: sol.hpp:7649
LUAMOD_API int luaopen_io(lua_State *L)
Definition: liolib.c:812
decltype(auto) get(Keys &&...keys) const
Definition: sol.hpp:25714
tie_t & operator=(T &&value)
Definition: sol.hpp:9677
void clear(stack_reference &r)
Definition: sol.hpp:10589
int registry_index() const noexcept
Definition: sol.hpp:9232
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) const &&
Definition: sol.hpp:5889
stack_proxy get(const unsafe_function_result &fr)
Definition: sol.hpp:16118
std::add_pointer_t< meta::unqualified_t< std::remove_pointer_t< T >>> C
Definition: sol.hpp:21510
table_proxy & operator=(T &&other)&
Definition: sol.hpp:23039
constexpr const char * not_enough_stack_space_generic
Definition: sol.hpp:10409
static int index_call(lua_State *L)
Definition: sol.hpp:22291
T & value()&
Definition: sol.hpp:6843
meta::neg< is_insert_mode< T >> is_not_insert_mode
Definition: sol.hpp:7045
basic_object_base< base_type > base_t
Definition: sol.hpp:26313
int new_index_fail(lua_State *L)
Definition: sol.hpp:21850
std::enable_if_t< any< Args... >::value, enable_t > enable_any
Definition: sol.hpp:1732
static int push(lua_State *L, const char32_t(&str)[N], std::size_t sz)
Definition: sol.hpp:14443
std::ptrdiff_t difference_type
Definition: sol.hpp:15757
const_iterator cbegin() const
Definition: sol.hpp:26464
stack_proxy(lua_State *L, int index)
Definition: sol.hpp:15710
static void destroy(T &&obj)
Definition: sol.hpp:6233
basic_environment(lua_State *L, new_table t, const basic_reference< b > &fallback)
Definition: sol.hpp:24410
static R apply(std::index_sequence<>, lua_State *, int, record &, Args &&...args)
Definition: sol.hpp:13113
change_indexing_mem_func change_indexing
Definition: sol.hpp:21874
basic_userdata< main_reference > main_userdata
Definition: forward.hpp:723
LUALIB_API void luaL_addlstring(luaL_Buffer *B, const char *s, size_t l)
Definition: lauxlib.c:570
LUA_API int lua_geti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.c:661
basic_protected_function(const proxy_base< Super > &p)
Definition: sol.hpp:19329
base< T >::type bases_t
Definition: sol.hpp:8431
static int push(lua_State *L, protect_t< T > &&pw)
Definition: sol.hpp:18555
static int push(lua_State *L, const factory_wrapper< Functions... > &fw, function_detail::call_indicator)
Definition: sol.hpp:18623
basic_coroutine(lua_State *L, T &&r)
Definition: sol.hpp:26158
basic_lua_table(stack_reference &&r)
Definition: sol.hpp:24262
basic_lua_table(lua_nil_t r) noexcept
Definition: sol.hpp:24302
basic_thread< reference > thread
Definition: forward.hpp:720
std::true_type on_always
Definition: sol.hpp:1783
table create_table(Name &&name, int narr, int nrec, Key &&key, Value &&value, Args &&...args)
Definition: sol.hpp:25795
bool valid(lua_State *L) const noexcept
Definition: sol.hpp:8784
constexpr bool is_specialization_of_v
Definition: sol.hpp:931
typename unwrapped< T >::type unwrapped_t
Definition: sol.hpp:1649
static int set_call(lua_State *L)
Definition: sol.hpp:21415
int call_lua(lua_State *L, int start, Fx &&fx, FxArgs &&...fxargs)
Definition: sol.hpp:15135
traits_type::args_list args_list
Definition: sol.hpp:16156
detail::invoke_result_t< U > map_or_else(F &&f, U &&u)&
Maps the stored value with f if there is one, otherwise calls u and returns the result.
Definition: sol.hpp:5864
this_state(lua_State *Ls)
Definition: sol.hpp:7051
type get_type(int index_offset=0) const noexcept
Definition: sol.hpp:15850
decltype(sol_lua_interop_get(types< T >(), static_cast< lua_State * >(nullptr),-1, static_cast< void * >(nullptr), std::declval< stack::record & >())) adl_sol_lua_interop_get_test_t
Definition: sol.hpp:10360
basic_environment(stack_reference &&r)
Definition: sol.hpp:24404
basic_userdata< stack_reference > stack_userdata
Definition: forward.hpp:727
static int push(lua_State *L, char16_t c)
Definition: sol.hpp:14459
constexpr optional(const T &u)
Definition: sol.hpp:5020
decltype(auto) unqualified_get(lua_State *L, int index=-lua_size< meta::unqualified_t< T >>::value)
Definition: sol.hpp:10885
stateless_reference(lua_State *L, const stack_reference &r) noexcept
Definition: sol.hpp:9174
static int push_rvalue(std::false_type, lua_State *L, const C &cont)
Definition: sol.hpp:21495
#define lua_pop(L, n)
Definition: lua.h:364
static int push(lua_State *L, Args &&...args)
Definition: sol.hpp:13614
auto factories(Functions &&...functions)
Definition: sol.hpp:6325
constexpr bool is_lua_reference_v
Definition: sol.hpp:7381
protected_function_result script_file(const std::string &filename, const environment &env, load_mode mode=load_mode::any)
Definition: sol.hpp:25515
basic_protected_function(basic_function< base_t > &&b, handler_t eh)
Definition: sol.hpp:19312
void operator()(lua_State *L, submetatable_type smt, reference &fast_index_table)
Definition: sol.hpp:21876
meta::boolean<(TI::value%2)==1 > on_odd
Definition: sol.hpp:1780
basic_object(detail::no_safety_tag, lua_State *L, ref_index index)
Definition: sol.hpp:15344
change_indexing_mem_func change_indexing
Definition: sol.hpp:21944
LUA_API void lua_pushvalue(lua_State *L, int idx)
Definition: lapi.c:246
#define luaL_loadbuffer(L, s, sz, n)
Definition: lauxlib.h:153
int index_target_fail(lua_State *L, void *)
Definition: sol.hpp:21846
fp operator*(fp x, fp y)
Definition: format-inl.h:1187
lua_State * L
Definition: sol.hpp:7068
static int real_empty_traits(std::true_type, lua_State *L)
Definition: sol.hpp:21318
LUA_API int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar)
Definition: ldebug.c:386
stack_aligned_safe_function stack_aligned_protected_function
Definition: forward.hpp:681
basic_lua_table(lua_State *L, int index=-1)
Definition: sol.hpp:24277
const destructor_wrapper< void > default_destructor
Definition: sol.hpp:6340
std::make_index_sequence< sizeof...(Args)> indices
Definition: forward.hpp:768
int stack_index() const
Definition: sol.hpp:26522
lua_State * L
Definition: sol.hpp:25014
protected_function_result script_default_on_error(lua_State *L, protected_function_result pfr)
Definition: sol.hpp:24987
usertype< Class > new_usertype(const std::string &name, Args &&...args)
Definition: sol.hpp:25746
lua_State * luastate
Definition: sol.hpp:9268
LUALIB_API int luaL_execresult(lua_State *L, int stat)
Definition: lauxlib.c:285
std::integral_constant< bool, B > boolean
Definition: sol.hpp:1689
LUA_API int lua_rawgetp(lua_State *L, int idx, const void *p)
Definition: lapi.c:718
constexpr bool any_same_v
Definition: sol.hpp:1686
void set_undefined_methods_on(stack_reference)
Definition: sol.hpp:21678
int is_check(lua_State *L)
Definition: sol.hpp:11046
auto policies(F &&f, Args &&...args)
Definition: sol.hpp:6409
static int push(lua_State *L, detail::tagged< T, constructor_wrapper< Fxs... >> &&c)
Definition: sol.hpp:18684
#define LUA_RIDX_MAINTHREAD
Definition: lua.h:84
decltype(auto) call(Args &&...args) const
Definition: sol.hpp:19070
Definition: lobject.h:47
std::true_type sfinae_yes_t
Definition: sol.hpp:873
basic_string_view< char > string_view
Definition: core.h:432
basic_environment(lua_nil_t r) noexcept
Definition: sol.hpp:24459
int push(lua_State *L) const noexcept
Definition: sol.hpp:9482
unsafe_function_result operator()(Args &&...args) const
Definition: sol.hpp:19060
void set_fx(types<>, Key &&key, Fx &&fx, Args &&...args)
Definition: sol.hpp:23959
basic_protected_function(lua_State *L, absolute_index index, handler_t eh)
Definition: sol.hpp:19372
static bool max_size_check(std::true_type, T &cont, std::size_t idx)
Definition: sol.hpp:12412
int operator()(types< Fx >, meta::index_value< I >, types< R... >, types< Args... >, lua_State *L, int, int, F &fx)
Definition: sol.hpp:17252
void get_field(lua_State *L, Key &&key)
Definition: sol.hpp:10933
unsafe_function_result(unsafe_function_result &&o) noexcept
Definition: sol.hpp:15973
static int push(lua_State *, const this_main_state &)
Definition: sol.hpp:14538
static table create_table(lua_State *L, int narr=0, int nrec=0)
Definition: sol.hpp:25820
#define LUA_OPLT
Definition: lua.h:223
static int push(lua_State *L, detail::tagged< T, constructor_list< Lists... >>)
Definition: sol.hpp:18662
void * align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
Definition: sol.hpp:9785
static int real_next_call(lua_State *L)
Definition: sol.hpp:21266
static int push(lua_State *L, no_construction c, function_detail::call_indicator)
Definition: sol.hpp:18655
constexpr optional< typename std::decay< U >::type > conjunction(U &&u) const
Definition: sol.hpp:5896
traits_type::returns_list returns_list
Definition: sol.hpp:16158
basic_metatable(detail::no_safety_tag, lua_nil_t n)
Definition: sol.hpp:24039
protected_function_result() noexcept=default
lua_CFunction func
Definition: lauxlib.h:39
constexpr void resolve_f(std::false_type, F &&)
Definition: sol.hpp:18059
static int push(lua_State *L, const wchar_t *wstr)
Definition: sol.hpp:14215
bool valid() const noexcept
Definition: sol.hpp:15805
basic_environment(T &&r) noexcept
Definition: sol.hpp:24450
static int push(lua_State *L, meta_function m)
Definition: sol.hpp:14170
int operator()(types< Fx >, meta::index_value< I >, types< R... >, types< Args... >, lua_State *L, int, int, F &fx)
Definition: sol.hpp:17269
static int push(lua_State *L, const overload_set< Functions... > &set)
Definition: sol.hpp:18546
load_result & operator=(load_result &&o) noexcept
Definition: sol.hpp:24615
meta::boolean< has_clear_test< T >::value > has_clear
Definition: sol.hpp:19892
void for_each(Fx &&fx)
Definition: sol.hpp:25763
LUA_API void lua_settop(lua_State *L, int idx)
Definition: lapi.c:173
int registry_index() const noexcept
Definition: sol.hpp:8733
LUA_API int lua_getmetatable(lua_State *L, int objindex)
Definition: lapi.c:741
constexpr optional< Ret > make_optional(U &&v)
Definition: sol.hpp:5487
int set_ref(lua_State *L, T &&arg, int tableindex=-2)
Definition: sol.hpp:15064
static int push(lua_State *L, const char *strb, const char *stre)
Definition: sol.hpp:14065
#define LUA_GCSTOP
Definition: lua.h:319
static int push(lua_State *L, const protected_function_result &pfr)
Definition: sol.hpp:15923
object require_script(const std::string &key, const string_view &code, bool create_global=true, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25181
int index_of(const Tu &)
Definition: sol.hpp:9000
global_table global
Definition: sol.hpp:25016
basic_object(lua_nil_t r)
Definition: sol.hpp:15366
luaL_Reg[64] lua_reg_table
Definition: sol.hpp:9763
basic_object & operator=(const proxy_base< Super > &r)
Definition: sol.hpp:15419
static const std::string & qualified_name()
Definition: sol.hpp:8270
table create_with(Args &&...args)
Definition: sol.hpp:24016
bool operator<=(const stack_iterator &r) const
Definition: sol.hpp:15614
const yield_tag_t yield_tag
Definition: sol.hpp:6595
basic_table_core & add(Args &&...args)
Definition: sol.hpp:23938
static int real_call(lua_State *L) noexcept(traits_type::is_noexcept)
Definition: sol.hpp:17684
lua_value(lua_State *L_, std::initializer_list< std::pair< lua_value, lua_value >> il)
Definition: sol.hpp:24755
static int length_call(lua_State *L)
Definition: sol.hpp:21391
const type_panic_t type_panic
Definition: sol.hpp:8650
basic_reference & operator=(basic_reference &&r) noexcept
Definition: sol.hpp:9443
LUA_API void lua_setglobal(lua_State *L, const char *name)
Definition: lapi.c:813
LUA_API int lua_getglobal(lua_State *L, const char *name)
Definition: lapi.c:632
load_result load(lua_Reader reader, void *data, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25563
#define lua_upvalueindex(i)
Definition: lua.h:45
LUAMOD_API int luaopen_table(lua_State *L)
Definition: ltablib.c:424
constexpr std::size_t count_odd_for_pack_v
Definition: sol.hpp:1829
gc_mode change_gc_mode_incremental(int pause, int step_multiplier, int step_byte_size)
Definition: sol.hpp:25662
void type_error(lua_State *L, int expected, int actual) noexcept(false)
Definition: sol.hpp:8688
constexpr bool is_transparent_argument_v
Definition: sol.hpp:7393
static int push(lua_State *L, const destructor_wrapper< Fx > &c)
Definition: sol.hpp:18761
void handle_policy(static_stack_dependencies< I, In... >, lua_State *L, int &)
Definition: sol.hpp:16583
stack_iterator operator--(int)
Definition: sol.hpp:15562
static bool check(lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:11196
#define lua_pcall(L, n, r, f)
Definition: lua.h:287
static int push(std::false_type, std::integral_constant< bool, is_nested >, lua_State *L, const T &tablecont)
Definition: sol.hpp:13748
const T & value() const &
Definition: sol.hpp:6890
static int push(lua_State *L, as_container_t< T > &&as_cont)
Definition: sol.hpp:21503
typename u_traits::actual_type Real
Definition: sol.hpp:13569
static char32_t combine_surrogates(char16_t lead, char16_t trail)
Definition: sol.hpp:11972
std::enable_if_t< neg< all< Args... >>::value, enable_t > disable
Definition: sol.hpp:1729
LUA_INTEGER lua_Integer
Definition: lua.h:94
object require_file(const std::string &key, const std::string &filename, bool create_global=true, load_mode mode=load_mode::any)
Definition: sol.hpp:25187
static int push(lua_State *L, const as_container_t< T > &as_cont)
Definition: sol.hpp:21499
const no_metatable_t no_metatable
Definition: sol.hpp:6622
probe apply(std::index_sequence< I, I1, In... >, int sofar, lua_State *L, Keys &&keys, int tableindex)
Definition: sol.hpp:14894
constexpr detail::invoke_result_t< F, const T & > and_then(F &&f) const &
Definition: sol.hpp:5653
#define LUA_TSTRING
Definition: lua.h:69
static int push(lua_State *L, const char(&str)[N], std::size_t sz)
Definition: sol.hpp:14111
basic_environment(lua_State *L, ref_index index)
Definition: sol.hpp:24440
decltype(auto) unchecked_unqualified_get(lua_State *L, int index, record &tracking)
Definition: sol.hpp:10443
static constexpr bool is_surrogate(char32_t u)
Definition: sol.hpp:11918
lua_State * thread_state() const
Definition: sol.hpp:25967
LUALIB_API void luaL_openlibs(lua_State *L)
Definition: linit.c:57
int construct_match(Match &&matchfx, lua_State *L, int fxarity, int start, Args &&...args)
Definition: sol.hpp:16843
bool xmovable(lua_State *leftL, lua_State *rightL)
Definition: sol.hpp:8717
bool maybe_indexable(lua_State *L, int index=-1)
Definition: sol.hpp:10538
decltype(auto) writeonly_property(F &&f)
Definition: sol.hpp:16490
constexpr bool is_detected_v
Definition: sol.hpp:900
void reserve(std::basic_string< T, Tr, Al > &str, std::size_t hint)
Definition: sol.hpp:10229
bool check_stack(int modification=0) const
Definition: sol.hpp:9726
constexpr bool is_tuple_v
Definition: sol.hpp:962
const_iterator cbegin() const
Definition: sol.hpp:16020
std::in_place_index_t< I > in_place_index_t
Definition: sol.hpp:3928
auto invoke(types< Ret... >, std::index_sequence< I... >, std::ptrdiff_t n, detail::protected_handler< b, handler_t > &h) const
Definition: sol.hpp:19214
T ** usertype_allocate_pointer(lua_State *L)
Definition: sol.hpp:9905
ref_index(int idx)
Definition: sol.hpp:6688
basic_coroutine(const proxy_base< Super > &p)
Definition: sol.hpp:26145
static int push(lua_State *L, const char16_t(&str)[N], std::size_t sz)
Definition: sol.hpp:14431
lua_State * operator->() const noexcept
Definition: sol.hpp:7058
optional< T > or_else(F &&f)&&
Definition: sol.hpp:5773
main_unsafe_function main_function
Definition: forward.hpp:689
std::pair< T, int > get_as_upvalues(lua_State *L, int index=2)
Definition: sol.hpp:14994
const T & value() const &
Definition: sol.hpp:6546
int oss_default_to_string(std::false_type, lua_State *L)
Definition: sol.hpp:11084
constexpr std::size_t count_for_pack_v
Definition: sol.hpp:1799
basic_protected_function(basic_function< base_t > &&b)
Definition: sol.hpp:19306
dump_error(int error_code_)
Definition: sol.hpp:18899
static int clear_call(lua_State *L)
Definition: sol.hpp:21375
auto destructor(Fx &&fx)
Definition: sol.hpp:6343
meta::boolean< is_string_like_v< T >||is_string_constructible_v< T >> is_string_like_or_constructible
Definition: sol.hpp:2227
basic_protected_function(lua_State *L, int index, handler_t eh)
Definition: sol.hpp:19362
constexpr optional disjunction(const optional &rhs) const &
disjunction
Definition: sol.hpp:5908
basic_metatable(detail::no_safety_tag, lua_State *L, ref_index index)
Definition: sol.hpp:24043
void for_each(Fx &&fx) const
Definition: sol.hpp:23871
int push(lua_State *target) const
Definition: sol.hpp:26494
basic_environment(env_key_t, const stack_reference &extraction_target)
Definition: sol.hpp:24417
LUA_API int lua_getstack(lua_State *L, int level, lua_Debug *ar)
Definition: ldebug.c:164
stateless_stack_reference(lua_nil_t) noexcept
Definition: sol.hpp:8739
reference operator[](difference_type idx) const
Definition: sol.hpp:15588
basic_table_core(lua_State *L, int index=-1)
Definition: sol.hpp:23661
#define LUA_GCISRUNNING
Definition: lua.h:327
constexpr bool is_unique_usertype_v
Definition: sol.hpp:8363
static bool is_null(const actual_type &p)
Definition: sol.hpp:8334
static void * type_cast_bases(types< Base, Args... >, T *data, const string_view &ti)
Definition: sol.hpp:8456
unsafe_function_result & operator=(const unsafe_function_result &)=delete
LUAMOD_API int luaopen_base(lua_State *L)
Definition: lbaselib.c:515
LUALIB_API void * luaL_testudata(lua_State *L, int ud, const char *tname)
Definition: lauxlib.c:330
std::remove_pointer_t< std::decay_t< Function > > function_type
Definition: sol.hpp:17681
decltype(auto) base_class_cast_key()
Definition: sol.hpp:8414
void set_fx(types< R(Args...)>, Key &&key, Fx &&fx)
Definition: sol.hpp:23948
optional & operator=(const optional< U > &rhs)
Definition: sol.hpp:5104
LUA_API int lua_status(lua_State *L)
Definition: lapi.c:1093
const_iterator end() const
Definition: sol.hpp:15867
bool interop_check(lua_State *L, int index, type index_type, Handler &&handler, record &tracking)
Definition: sol.hpp:10510
basic_reference & operator=(const lua_nil_t &) noexcept
Definition: sol.hpp:9463
closure(lua_CFunction f, int upvalue_count=0)
Definition: sol.hpp:6794
basic_protected_function(const basic_function< base_t > &b, handler_t eh)
Definition: sol.hpp:19309
const_iterator begin() const
Definition: sol.hpp:16014
probe probe_get_field(lua_State *L, Key &&key, int tableindex)
Definition: sol.hpp:10958
call_syntax
Definition: sol.hpp:7133
constexpr bool any_v
Definition: sol.hpp:1716
std::random_access_iterator_tag iterator_category
Definition: sol.hpp:15512
const_iterator cend() const
Definition: sol.hpp:15873
int push(lua_State *L) const noexcept
Definition: sol.hpp:9220
int cannot_destruct(lua_State *L)
Definition: sol.hpp:10211
static int push(lua_State *L, const char16_t *u16str)
Definition: sol.hpp:14281
static auto get(U &&value)
Definition: sol.hpp:8317
load_result(load_result &&o) noexcept
Definition: sol.hpp:24605
int push(lua_State *L, T &&t, Args &&...args)
Definition: sol.hpp:10594
constructor_wrapper(Arg &&arg, Args &&...args)
Definition: sol.hpp:6305
static table create(lua_State *L, int narr, int nrec, Key &&key, Value &&value, Args &&...args)
Definition: sol.hpp:23977
table_proxy(Table table, T &&k)
Definition: sol.hpp:23011
int overload_match(Match &&matchfx, lua_State *L, int start, Args &&...args)
Definition: sol.hpp:16837
void top_apply(std::index_sequence< I0, I... >, lua_State *L, Keys &&keys, Value &&value, int tableindex)
Definition: sol.hpp:14827
table_proxy & set_function(Args &&...args)&
Definition: sol.hpp:23027
static int push(lua_State *L, lua_value &&lv)
Definition: sol.hpp:24829
decltype(auto) get_usertype(lua_State *L, int index=-lua_size< meta::unqualified_t< T >>::value)
Definition: sol.hpp:10922
optional< T > SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F &&f)&&
Definition: sol.hpp:4770
basic_environment< reference > environment
Definition: forward.hpp:662
bool supports_gc_mode(gc_mode mode) const noexcept
Definition: sol.hpp:25614
static bool check(lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:11707
int(* lua_CFunction)(lua_State *L)
Definition: lua.h:106
std::u16string_view u16string_view
Definition: sol.hpp:1619
protected_function_result script_throw_on_error(lua_State *L, protected_function_result result)
Definition: sol.hpp:24929
std::tuple< Policies... > policies
Definition: sol.hpp:6396
static int push(lua_State *L, const unsafe_function_result &fr)
Definition: sol.hpp:16076
#define l_inspectstat(stat, what)
Definition: lauxlib.c:278
static T * get_no_lua_nil_from(lua_State *L, void *udata, int index, record &)
Definition: sol.hpp:13018
variadic_args & operator=(variadic_args &&o)
Definition: sol.hpp:26439
basic_object(T &&r)
Definition: sol.hpp:15359
bool check_metatable(lua_State *L, int index=-2)
Definition: sol.hpp:11189
const_iterator end() const
Definition: sol.hpp:26461
unsafe_function_result() noexcept=default
static int real_erase_call(lua_State *L)
Definition: sol.hpp:21338
#define LUA_TNONE
Definition: lua.h:63
bool unqualified_interop_check(lua_State *L, int index, type index_type, Handler &&handler, record &tracking)
Definition: sol.hpp:10494
overload_set(Arg &&arg, Args &&...args)
Definition: sol.hpp:11836
static std::function< Signature > get_std_func(types< R... >, lua_State *L, int index)
Definition: sol.hpp:19571
table create_named_table(Name &&name, Args &&...args)
Definition: sol.hpp:25800
decltype(auto) interop_get(lua_State *L, int index, void *unadjusted_pointer, record &tracking)
Definition: sol.hpp:10484
void add_package_loader(Fx &&fx, bool clear_all_package_loaders=false)
Definition: sol.hpp:25220
size_t size() const
Definition: sol.hpp:23898
static bool is_null(const actual_type &p)
Definition: sol.hpp:8350
constexpr bool is_optional_v
Definition: sol.hpp:6188
protected_handler(std::false_type, const target_t &target)
Definition: sol.hpp:19101
int type_panic_c_str(lua_State *L, int index, type expected, type actual, const char *message=nullptr) noexcept(false)
Definition: sol.hpp:8636
state_view state() const
Definition: sol.hpp:25959
meta::boolean< has_traits_ipairs_test< T >::value > has_traits_ipairs
Definition: sol.hpp:19928
stateless_reference(lua_nil_t) noexcept
Definition: sol.hpp:9143
static void insert_at_end(std::false_type, types< V >, lua_State *L, T &cont, std::size_t idx)
Definition: sol.hpp:12404
int operator()(lua_State *L, int index, type expected, type actual) const noexcept(false)
Definition: sol.hpp:8642
LUA_API lua_CFunction lua_atpanic(lua_State *L, lua_CFunction panicf)
Definition: lapi.c:136
#define lua_newuserdata(L, s)
Definition: lua.h:411
int push_reference(lua_State *L, Arg &&arg, Args &&...args)
Definition: sol.hpp:10653
basic_table_core(stack_reference &&r)
Definition: sol.hpp:23645
int register_usertype(lua_State *L, automagic_enrollments enrollments={})
Definition: sol.hpp:22574
static int push(lua_State *L, const std::reference_wrapper< T > &t)
Definition: sol.hpp:13706
void set_field(lua_State *L, Key &&key, Value &&value)
Definition: sol.hpp:10973
basic_object(stack_reference &&r) noexcept
Definition: sol.hpp:15374
optional< T > or_else(F &&f) const &
Definition: sol.hpp:4777
constexpr std::size_t count_even_for_pack_v
Definition: sol.hpp:1823
constexpr detail::invoke_result_t< F, const T & > and_then(F &&f) const &
Definition: sol.hpp:4639
global_table globals() const
Definition: sol.hpp:25586
LUA_API void lua_settable(lua_State *L, int idx)
Definition: lapi.c:821
basic_function(lua_nil_t n)
Definition: sol.hpp:19002
basic_protected_function(T &&r) noexcept
Definition: sol.hpp:19289
static int push(lua_State *L, const wchar_t(&str)[N], std::size_t sz)
Definition: sol.hpp:14419
void handle_policy(P &&p, lua_State *L, int &pushed)
Definition: sol.hpp:16632
static int index_call(lua_State *L)
Definition: sol.hpp:21419
basic_object & operator=(proxy_base< Super > &&r)
Definition: sol.hpp:15424
int call_set_assignable(std::true_type, lua_State *L, T &&mem)
Definition: sol.hpp:17490
index_call_function * new_index
Definition: sol.hpp:21735
#define LUA_YIELD
Definition: lua.h:50
bool impl_check_metatable(lua_State *L, int index, const std::string &metakey, bool poptable)
Definition: sol.hpp:11175
const void * pointer(lua_State *L) const noexcept
Definition: sol.hpp:8774
constexpr in_place_index_t< I > in_place_index
Definition: sol.hpp:3930
U map_or(F &&f, U &&u)&&
map_or
Definition: sol.hpp:4823
auto operator[](T &&key)&
Definition: sol.hpp:23911
unsafe_function_result script(const string_view &code, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25534
typename global_table::iterator iterator
Definition: sol.hpp:25072
void set(lua_State *L, Key &&key, Value &&value)
Definition: sol.hpp:22320
auto push_invoke(Fx &&fx)
Definition: sol.hpp:7026
#define LUA_TNIL
Definition: lua.h:65
int push(lua_State *L) const noexcept
Definition: sol.hpp:22937
#define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T)
Definition: sol.hpp:3994
stack_proxy get(types< Args... >, meta::index_value< 0 >, meta::index_value< I >, const T &fr)
Definition: sol.hpp:16101
void ensure_package(const std::string &key, T &&sr)
Definition: sol.hpp:25033
static int index_call(lua_State *L)
Definition: sol.hpp:21823
auto invoke(types< Ret... >, std::index_sequence< I... >, std::ptrdiff_t n)
Definition: sol.hpp:26068
#define SOL_GET_FUNCTION_POINTER_UNSAFE_I_
Definition: sol.hpp:579
bool operator()(const stack_reference &lhs, const stack_reference &rhs) const
Definition: sol.hpp:8904
typename T::template rebind_base< Rebind > is_base_rebindable_test
Definition: sol.hpp:8367
#define lua_setuservalue(L, idx)
Definition: lua.h:413
lua_State * L
Definition: sol.hpp:24586
#define SOL_DEPRECATED
Definition: sol.hpp:19612
function_arguments(Arg &&arg, Args &&...args)
Definition: sol.hpp:6809
basic_object(lua_State *L, ref_index index) noexcept
Definition: sol.hpp:15397
void luacall(std::ptrdiff_t argcount, std::ptrdiff_t)
Definition: sol.hpp:26058
decltype(auto) property(F &&f, G &&g)
Definition: sol.hpp:16462
void *(* lua_Alloc)(void *ud, void *ptr, size_t osize, size_t nsize)
Definition: lua.h:125
encoded_result< char > code_point_to_utf8(char32_t codepoint)
Definition: sol.hpp:11979
stack_proxy reference_type
Definition: sol.hpp:26411
const_reverse_iterator rend() const
Definition: sol.hpp:26480
decltype(auto) get_or(Key &&key, T &&otherwise) const
Definition: sol.hpp:23726
T const & value() const &
Definition: sol.hpp:6459
void select_member_function(lua_State *L, Fx &&fx, Args &&...args)
Definition: sol.hpp:18340
constexpr detail::invoke_result_t< F, const T & > and_then(F &&f) const &&
Definition: sol.hpp:5664
static int real_next_traits(std::true_type, lua_State *L)
Definition: sol.hpp:21258
basic_protected_function(lua_State *L, T &&r)
Definition: sol.hpp:19342
static constexpr char32_t decode(unsigned char b0, unsigned char b1)
Definition: sol.hpp:11954
basic_coroutine< main_reference > main_coroutine
Definition: forward.hpp:725
call_status status() const noexcept
Definition: sol.hpp:26211
#define min(A, B)
Definition: Log.c:64
basic_object(lua_State *L, lua_nil_t r) noexcept
Definition: sol.hpp:15385
int usertype_alloc_destruct(lua_State *L)
Definition: sol.hpp:10172
protected_function_result script(const string_view &code, const basic_environment< E > &env, Fx &&on_error, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25500
optional< T > SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F &&f)&
Calls f if the optional is empty std::invoke_result_t<F> must be void or convertible to optional<T>...
Definition: sol.hpp:4743
void use(int count) noexcept
Definition: sol.hpp:10338
std::remove_pointer_t< lua_CFunction > lua_CFunction_ref
Definition: sol.hpp:6648
constexpr const char * not_enough_stack_space_floating
Definition: sol.hpp:8576
#define max(A, B)
Definition: Socket.h:88
meta::conditional_t< std::is_void< T >::value, args_list, types< first_type, Args... > > free_args_list
Definition: sol.hpp:1060
Definition: chrono.h:284
const_iterator end() const
Definition: sol.hpp:16017
meta::is_detected< detail::is_base_rebindable_test, T > is_base_rebindable_non_void
Definition: sol.hpp:8386
T && value()&&
Definition: sol.hpp:6847
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)
Definition: format.h:2881
static int real_call(lua_State *L) noexcept(traits_type::is_noexcept)
Definition: sol.hpp:17641
encoded_result< char32_t > code_point_to_utf32(char32_t codepoint)
Definition: sol.hpp:12035
meta::tuple_types< return_type > returns_list
Definition: sol.hpp:1505
optional & operator=(nullopt_t) noexcept
Definition: sol.hpp:5062
basic_reference(lua_State *L, basic_reference< r_main_only > &&r) noexcept
Definition: sol.hpp:9371
int SOL_INTERNAL_UNSPECIALIZED_MARKER_
Definition: sol.hpp:7645
const_reverse_iterator rbegin() const
Definition: sol.hpp:26477
static int push(lua_State *L, const property_wrapper< F, G > &pw)
Definition: sol.hpp:18586
bool empty() const
Definition: sol.hpp:23906
LUALIB_API void luaL_pushresult(luaL_Buffer *B)
Definition: lauxlib.c:584
decltype(auto) base_class_check_key()
Definition: sol.hpp:8409
constexpr const int simple_usertype_storage_index
Definition: sol.hpp:21557
call_status
Definition: sol.hpp:7141
unsafe_function_result unsafe_script(lua_Reader reader, void *data, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25425
LUA_API void lua_pushboolean(lua_State *L, int b)
Definition: lapi.c:581
basic_variadic_results(Arg0 &&arg0, Args &&...args)
Definition: sol.hpp:26614
lua_State * lua_state() const
Definition: sol.hpp:16054
decltype(auto) deref_move_only(T &&item)
Definition: sol.hpp:1577
detail::enable_if_t< std::is_constructible< T, Other >::value &&!std::is_constructible< T, optional< U > & >::value &&!std::is_constructible< T, optional< U > && >::value &&!std::is_constructible< T, const optional< U > & >::value &&!std::is_constructible< T, const optional< U > && >::value &&!std::is_convertible< optional< U > &, T >::value &&!std::is_convertible< optional< U > &&, T >::value &&!std::is_convertible< const optional< U > &, T >::value &&!std::is_convertible< const optional< U > &&, T >::value > enable_from_other
Definition: sol.hpp:4151
LUA_API int lua_iscfunction(lua_State *L, int idx)
Definition: lapi.c:273
lua_State * lua_state() const
Definition: sol.hpp:26519
protected_function_result do_reader(lua_Reader reader, void *data, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25269
static int real_index_get_traits(std::false_type, lua_State *L)
Definition: sol.hpp:21155
void abandon(lua_State *=nullptr)
Definition: sol.hpp:9254
bool valid() const
Definition: sol.hpp:23146
lua_thread_state(lua_State *Ls)
Definition: sol.hpp:25844
#define lua_pushglobaltable(L)
Definition: lua.h:383
decltype(auto) base_class_index_propogation_key()
Definition: sol.hpp:8419
basic_string_view< wchar_t > wstring_view
Definition: core.h:433
constexpr const int new_index_function_index
Definition: sol.hpp:21559
basic_metatable(detail::no_safety_tag, lua_State *L, T &&r) noexcept
Definition: sol.hpp:24051
int unique_destruct(lua_State *L)
Definition: sol.hpp:10183
std::wstring_view wstring_view
Definition: sol.hpp:1618
static int push(lua_State *L, const push_invoke_t< T > &pi)
Definition: sol.hpp:18824
constexpr bool is_non_factory_constructor_v
Definition: sol.hpp:7849
static int push(lua_State *L, Arg &&arg, Args &&...args)
Definition: sol.hpp:13545
optional take() const &
take
Definition: sol.hpp:5955
static constexpr bool is_trail_surrogate(char32_t u)
Definition: sol.hpp:11915
static int index_call_(lua_State *L)
Definition: sol.hpp:22277
static int push(lua_State *L, const char *str, std::size_t len)
Definition: sol.hpp:14094
auto var(V &&v)
Definition: sol.hpp:16526
basic_object(lua_State *L, T &&r)
Definition: sol.hpp:15363
static int meta_index_call_with_bases(lua_State *L)
Definition: sol.hpp:22306
table_proxy< global_table &, detail::proxy_key_t< T > > operator[](T &&key)
Definition: sol.hpp:25768
lua_value(std::initializer_list< std::pair< lua_value, lua_value >> il)
Definition: sol.hpp:24762
protected_function_result safe_script_file(const std::string &filename, const basic_environment< E > &env, load_mode mode=load_mode::any)
Definition: sol.hpp:25399
std::remove_pointer_t< std::decay_t< Function >> function_type
Definition: sol.hpp:17606
basic_lightuserdata< main_reference > main_lightuserdata
Definition: forward.hpp:724
lua_value(lua_State *L_, T &&value)
Definition: sol.hpp:24748
static int push(lua_State *L, const char32_t *u32str)
Definition: sol.hpp:14358
usertype_proxy && operator=(std::initializer_list< T > other)&&
Definition: sol.hpp:22877
std::string what_reason
Definition: sol.hpp:3883
basic_coroutine(const stack_reference &r)
Definition: sol.hpp:26133
int return_count() const noexcept
Definition: sol.hpp:15902
unsafe_function_result script_file(const std::string &filename, load_mode mode=load_mode::any)
Definition: sol.hpp:25538
basic_object(proxy_base< Super > &&r) noexcept
Definition: sol.hpp:15382
LUA_API void lua_rawseti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.c:889
protected_function_result script(const string_view &code, Fx &&on_error, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25487
bool operator==(const basic_table_iterator &right) const
Definition: sol.hpp:23344
static int push(lua_State *L, Arg &&arg, Args &&...args)
Definition: sol.hpp:13572
basic_protected_function(lua_State *L, T &&r, handler_t eh)
Definition: sol.hpp:19346
typename std::decay< T >::type decay_t
Definition: sol.hpp:4029
std::size_t size() const
Definition: sol.hpp:26528
void set(lua_State *L, Key &&key, Value &&value)
Definition: sol.hpp:22454
lua_State * operator->() const noexcept
Definition: sol.hpp:7077
static decltype(auto) eval(types< Arg, Args... >, std::index_sequence< I, Is... >, lua_State *L, int start, record &tracking, Fx &&fx, FxArgs &&...fxargs)
Definition: sol.hpp:15032
meta::unqualified_t< T > Tu
Definition: sol.hpp:8993
#define COMPAT53_API
Definition: sol.hpp:2486
basic_object(const proxy_base< Super > &r) noexcept
Definition: sol.hpp:15378
meta::boolean< meta_detail::has_size_test< T >::value > has_size
Definition: sol.hpp:2161
stack_proxy operator[](difference_type index_offset) const
Definition: sol.hpp:26515
bool operator()(meta_function mf) const
Definition: sol.hpp:10246
static int push(lua_State *L, userdata_value data)
Definition: sol.hpp:14039
std::vector< object, typename std::allocator< object > > base_t
Definition: sol.hpp:26595
constexpr bool is_container_v
Definition: sol.hpp:7414
static int meta_index_call(lua_State *L)
Definition: sol.hpp:22301
constexpr bool is_base_rebindable_non_void_v
Definition: sol.hpp:8389
int call_into_lua(types< Ret0, Ret... > tr, types< Args... > ta, lua_State *L, int start, Fx &&fx, FxArgs &&...fxargs)
Definition: sol.hpp:15113
decltype(auto) tuplefy(X &&...x)
Definition: sol.hpp:2267
static int push(lua_State *L, const basic_string_view< Ch, Traits > &sv, std::size_t n)
Definition: sol.hpp:14163
protected_handler(std::true_type, const target_t &target)
Definition: sol.hpp:19109
stack_iterator< stack_proxy, true > const_iterator
Definition: sol.hpp:15760
static int call(lua_State *L) noexcept(traits_type::is_noexcept)
Definition: sol.hpp:17658
stateless_reference(int raw_ref_index) noexcept
Definition: sol.hpp:9138
#define LUA_TNUMBER
Definition: lua.h:68
static int push(lua_State *, const stack_proxy &ref)
Definition: sol.hpp:15733
basic_protected_function< stack_reference, true, stack_reference > stack_aligned_stack_handler_function
Definition: forward.hpp:693
stack_iterator< stack_proxy, true > const_iterator
Definition: sol.hpp:26417
basic_lightuserdata(lua_State *L, T &&r)
Definition: sol.hpp:26340
lua_State * L
Definition: sol.hpp:23370
const_iterator begin() const
Definition: sol.hpp:15864
LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname)
Definition: lauxlib.c:245
optional take() const &
take
Definition: sol.hpp:4942
constexpr bool any_is_constructor_v
Definition: sol.hpp:7870
stateless_reference(lua_State *, lua_nil_t) noexcept
Definition: sol.hpp:9202
R make_reference_userdata(lua_State *L, T &&value)
Definition: sol.hpp:15238
std::array< int, 64 > stack_indices
Definition: sol.hpp:6369
bool is_indeterminate_call_failure(call_status c)
Definition: sol.hpp:7229
decltype(sol_lua_check_get(types< T >(), static_cast< lua_State * >(nullptr),-1, no_panic, std::declval< stack::record & >())) adl_sol_lua_check_get_test_t
Definition: sol.hpp:10371
void swap(optional &rhs) noexcept(std::is_nothrow_move_constructible< T >::value &&detail::is_nothrow_swappable< T >::value)
Definition: sol.hpp:5172
decltype(std::declval< T >().operator*()) is_explicitly_dereferenceable_test
Definition: sol.hpp:1543
stateless_stack_reference(absolute_index i) noexcept
Definition: sol.hpp:8746
typename std::remove_reference< T >::type remove_reference_t
Definition: core.h:256
iterator begin() const
Definition: sol.hpp:25570
static int real_length_call(lua_State *L)
Definition: sol.hpp:21278
static int type_unique_cast_with(void *source_data, void *target_data, const string_view &ti, const string_view &rebind_ti)
Definition: sol.hpp:8524
lua_State * move_assign(lua_State *L, lua_State *rL, stateless_reference &&r)
Definition: sol.hpp:9116
constexpr const char * not_enough_stack_space
Definition: sol.hpp:10403
int push() const noexcept
Definition: sol.hpp:9478
static int push(lua_State *L, const char(&str)[N])
Definition: sol.hpp:14103
void stop_gc()
Definition: sol.hpp:25657
stack_reference(lua_State *L, const stack_reference &r) noexcept
Definition: sol.hpp:8812
static int find_call(lua_State *L)
Definition: sol.hpp:21383
static bool is_null(U &&)
Definition: sol.hpp:8312
typename meta_detail::is_detected< Trait, void, Args... >::type is_detected
Definition: sol.hpp:897
basic_protected_function< main_reference, false, reference > main_safe_function
Definition: forward.hpp:673
key_type key
Definition: sol.hpp:23008
std::vector< std::unique_ptr< char[]> > string_keys_storage
Definition: sol.hpp:21971
LUA_API void lua_close(lua_State *L)
Definition: lstate.c:441
table_proxy && set_function(Args &&...args)&&
Definition: sol.hpp:23033
static const std::string & metatable()
Definition: sol.hpp:8274
basic_protected_function(stack_reference &&r, handler_t eh)
Definition: sol.hpp:19324
bool valid() const noexcept
Definition: sol.hpp:16050
probe apply(std::index_sequence< I >, int sofar, lua_State *L, Keys &&keys, int tableindex)
Definition: sol.hpp:14888
const void * pointer() const noexcept
Definition: sol.hpp:9513
basic_metatable(stack_reference &&r)
Definition: sol.hpp:24064
bool operator()(const stack_reference &lhs, const basic_reference< rb > &rhs) const
Definition: sol.hpp:9606
std::reference_wrapper< T > value_
Definition: sol.hpp:6960
enable_if_t<!returns_void< T &&, U... >::value > disable_if_ret_void
Definition: sol.hpp:4140
typename bind_traits< Signature >::signature_type function_signature_t
Definition: sol.hpp:1522
optional take()&
Definition: sol.hpp:5948
stateless_stack_reference(lua_State *L, int i) noexcept
Definition: sol.hpp:8740
static int push(lua_State *L, T &&bc, const char *bytecode_name)
Definition: sol.hpp:14554
static int push(lua_State *L, property_wrapper< F, G > &&pw)
Definition: sol.hpp:18574
static int real_index_of_call(lua_State *L)
Definition: sol.hpp:21354
void align_one(std::size_t a, std::size_t s, void *&target_alignment)
Definition: sol.hpp:9790
variadic_args(variadic_args &&o)
Definition: sol.hpp:26430
push_invoke_t(T &value)
Definition: sol.hpp:7017
constexpr bool any_is_destructor_v
Definition: sol.hpp:7882
void add_entry(string_view sv, index_call_storage ics)
Definition: sol.hpp:22045
basic_coroutine(basic_function< base_t > &&b)
Definition: sol.hpp:26126
constexpr const char * not_enough_stack_space_environment
Definition: sol.hpp:8582
int error_code() const
Definition: sol.hpp:18902
std::false_type uses_std(...)
basic_object_base< base_type > base_t
Definition: sol.hpp:15327
std::tuple< std::add_lvalue_reference_t< Tn >... > base_t
Definition: sol.hpp:9643
void pop(lua_State *L, int n=1) const noexcept
Definition: sol.hpp:9228
int call_wrapper_variable(std::true_type, lua_State *L)
Definition: sol.hpp:17506
basic_coroutine< reference > coroutine
Definition: forward.hpp:721
as_table_t(Arg0 &&arg0, Arg1 &&arg1, Args &&...args)
Definition: sol.hpp:6840
void apply(std::index_sequence< 0, I... >, lua_State *L, Keys &&keys, int tableindex)
Definition: sol.hpp:14707
typename unqualified< T >::type unqualified_t
Definition: sol.hpp:883
static int push(lua_State *L, constructor_list< Lists... >)
Definition: sol.hpp:18667
Container dump() const
Definition: sol.hpp:19046
constexpr optional() noexcept=default
meta::boolean< has_erase_after_test< T >::value > has_erase_after
Definition: sol.hpp:19907
constexpr optional(const optional< U > &rhs)
Definition: sol.hpp:6009
static auto call(Fx &&fx, object_type &mem) -> detail::array_return_type< decltype(mem.*fx)>
Definition: sol.hpp:16226
LUA_API int lua_gc(lua_State *L, int what,...)
Definition: lapi.c:1101
table_core< false > table
Definition: forward.hpp:636
bool operator==(const stack_iterator &r) const
Definition: sol.hpp:15592
void raw_set_field(lua_State *L, Key &&key, Value &&value, int tableindex)
Definition: sol.hpp:10988
static int push(lua_State *L, const void *userdata)
Definition: sol.hpp:13942
std::tuple< Functions... > functions
Definition: sol.hpp:6317
push_popper_n(lua_State *luastate, int x)
Definition: sol.hpp:8974
std::array< const char *, 4 > args_strings
Definition: sol.hpp:3859
void * align_usertype_unique_destructor(void *ptr)
Definition: sol.hpp:9821
detail::enable_if_t< std::is_constructible< T, std::initializer_list< U > &, Args &&... >::value, T & > emplace(std::initializer_list< U > il, Args &&...args)
Definition: sol.hpp:5160
SOL_TL_OPTIONAL_11_CONSTEXPR T & operator*()&
Definition: sol.hpp:5207
LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx)
Definition: lapi.c:414
static R invoke(O &mem, Args &&...args)
Definition: sol.hpp:16272
basic_table_core & set(Args &&...args)
Definition: sol.hpp:23767
LUA_API void lua_arith(lua_State *L, int op)
Definition: lapi.c:311
table registry() const
Definition: sol.hpp:25596
as_table_t< T > as_table_ref(T &&container)
Definition: sol.hpp:6903
LUA_API int lua_pushthread(lua_State *L)
Definition: lapi.c:600
void pop(lua_State *L, int n=1) const noexcept
Definition: sol.hpp:8766
upvalue_index(int idx)
Definition: sol.hpp:6658
std::string type_name(lua_State *L, type t)
Definition: sol.hpp:7372
basic_object(lua_State *L, raw_index index) noexcept
Definition: sol.hpp:15394
const std::string & default_chunk_name()
Definition: sol.hpp:14928
load_result load_file(const std::string &filename, load_mode mode=load_mode::any)
Definition: sol.hpp:25558
basic_reference(const basic_reference &o) noexcept
Definition: sol.hpp:9426
int(*)(lua_State *, optional< const std::exception & >, string_view) exception_handler_function
Definition: sol.hpp:7918
static int call(lua_State *L) noexcept(traits_type::is_noexcept)
Definition: sol.hpp:17799
#define SOL_TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T)
Definition: sol.hpp:3995
auto operator[](T &&key) const &
Definition: sol.hpp:23916
auto make_light(T &l)
Definition: sol.hpp:6740
std::enable_if_t< neg< any< Args... >>::value, enable_t > disable_any
Definition: sol.hpp:1735
absolute_index(lua_State *L, int idx)
Definition: sol.hpp:6678
int dump_pass_on_error(lua_State *L, int result_code, lua_Writer writer_function, void *userdata, bool strip)
Definition: sol.hpp:18907
static int real_add_traits(std::true_type, lua_State *L)
Definition: sol.hpp:21282
#define lua_newtable(L)
Definition: lua.h:366
static int push(lua_State *L, const std::basic_string< Ch, Traits, Al > &str, std::size_t sz)
Definition: sol.hpp:14143
static int push_with(lua_State *L, Key &&name, Args &&...args)
Definition: sol.hpp:13976
void set_resolved_function(Key &&key, Args &&...args)
Definition: sol.hpp:23964
void set_default_exception_handler(lua_State *L, exception_handler_function exf=&detail::default_exception_handler)
Definition: sol.hpp:8077
int push_type_panic_string(lua_State *L, int index, type expected, type actual, string_view message, string_view aux_message) noexcept
Definition: sol.hpp:8619
basic_function(stack_reference &&r)
Definition: sol.hpp:18999
basic_protected_function< stack_reference, true, reference > stack_aligned_safe_function
Definition: forward.hpp:677
int push_userdata(lua_State *L, T &&t, Args &&...args)
Definition: sol.hpp:10633
int dummy
Definition: lstrlib.c:1347
void change_indexing(lua_State *L, submetatable_type submetatable, void *derived_this, stack_reference &t, lua_CFunction index, lua_CFunction new_index, lua_CFunction meta_index, lua_CFunction meta_new_index)
Definition: sol.hpp:22233
static int push(lua_State *L, no_metatable_t, user< T > &&u)
Definition: sol.hpp:14031
usertype_proxy< basic_usertype &, std::decay_t< Key > > operator[](Key &&key)
Definition: sol.hpp:24224
static int push(lua_State *L, const char16_t(&str)[N])
Definition: sol.hpp:14427
static int push(lua_State *L, const new_table &nt)
Definition: sol.hpp:14545
basic_lightuserdata(stack_reference &&r)
Definition: sol.hpp:26336
SOL_TL_OPTIONAL_11_CONSTEXPR T * operator->()
Definition: sol.hpp:5199
void open_libraries(Args &&...args)
Definition: sol.hpp:25086
stack_proxy get(types< Args... > t, const protected_function_result &fr)
Definition: sol.hpp:16133
basic_coroutine(Proxy &&p, Handler &&eh)
Definition: sol.hpp:26154
std::tuple< Ps... > arguments
Definition: sol.hpp:6807
int overload_match_arity_single(types< Fx, Fx1, Fxs... >, std::index_sequence< I, I1, In... >, std::index_sequence< M... >, Match &&matchfx, lua_State *L, int fxarity, int start, Args &&...args)
Definition: sol.hpp:16778
stack_proxy operator[](difference_type index_offset) const
Definition: sol.hpp:16004
LUA_API lua_State * lua_tothread(lua_State *L, int idx)
Definition: lapi.c:438
#define lua_pushliteral(L, s)
Definition: lua.h:381
LUAMOD_API int() luaopen_utf8(lua_State *L)
Definition: lutf8lib.c:283
meta::is_detected< detail::is_base_rebindable_test, T > is_base_rebindable
Definition: sol.hpp:8371
static int push(lua_State *L, destructor_wrapper< Fx > &&c)
Definition: sol.hpp:18753
static int push(lua_State *L, const char32_t *str, std::size_t len)
Definition: sol.hpp:14406
static optional< V > get_one(std::integral_constant< std::size_t, 0 >, lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:13322
const_reverse_iterator rbegin() const
Definition: sol.hpp:16033
static int erase_call(lua_State *L)
Definition: sol.hpp:21367
std::vector< std::byte, Allocator > base_t
Definition: sol.hpp:3755
LUA_API size_t lua_stringtonumber(lua_State *L, const char *s)
Definition: lapi.c:347
static int push(lua_State *L, metatable_key_t)
Definition: sol.hpp:13848
LUA_API const char * lua_tolstring(lua_State *L, int idx, size_t *len)
Definition: lapi.c:381
basic_reference< false > reference
Definition: forward.hpp:610
static optional< V > get_empty(std::true_type, lua_State *, int, Handler &&, record &)
Definition: sol.hpp:13307
LUALIB_API lua_Integer luaL_len(lua_State *L, int idx)
Definition: lauxlib.c:849
void invoke(types< void >, std::index_sequence< I >, std::ptrdiff_t n, detail::protected_handler< b, handler_t > &h) const
Definition: sol.hpp:19226
void deref(lua_State *L) const noexcept
Definition: sol.hpp:9258
meta::boolean< has_traits_erase_test< T >::value > has_traits_erase
Definition: sol.hpp:19955
static const std::string & user_metatable()
Definition: sol.hpp:8278
LUALIB_API void luaL_unref(lua_State *L, int t, int ref)
Definition: lauxlib.c:667
static optional< V > get_one(std::integral_constant< std::size_t, I >, lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:13327
std::size_t total_memory_used(lua_State *L)
Definition: sol.hpp:24918
static int push(std::true_type, std::integral_constant< bool, is_nested >, lua_State *L, const T &tablecont)
Definition: sol.hpp:13732
std::integral_constant< bool, V_size::value==0 > V_is_empty
Definition: sol.hpp:11718
stateless_reference & operator=(stateless_reference &&o) noexcept
Definition: sol.hpp:9214
constexpr std::array< string_view, 9 > removals
Definition: sol.hpp:8108
detail::inheritance_unique_cast_function unique_tag
Definition: sol.hpp:9766
meta::conditional_t< is_const, const proxy_t *, proxy_t * > pointer
Definition: sol.hpp:15509
std::ptrdiff_t difference_type
Definition: sol.hpp:23285
static int push(lua_State *L, const destructor_wrapper< Fx > &c)
Definition: sol.hpp:18742
std::size_t size_type
Definition: sol.hpp:26415
const int & operator[](std::size_t i) const
Definition: sol.hpp:6382
error_result(const char *fmt, const char *msg)
Definition: sol.hpp:3867
std::hash< std::string_view > string_view_hash
Definition: sol.hpp:1621
basic_environment(lua_State *L, T &&r) noexcept
Definition: sol.hpp:24463
static int push_deep(lua_State *L, Args &&...args)
Definition: sol.hpp:13585
const_iterator cend() const
Definition: sol.hpp:16023
stack_proxy reference_type
Definition: sol.hpp:15952
protected_function_result script(const string_view &code, const environment &env, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25510
table_proxy && operator=(T &&other)&&
Definition: sol.hpp:23050
basic_protected_function(lua_nil_t n)
Definition: sol.hpp:19355
bool multi_check(lua_State *L, int index)
Definition: sol.hpp:10861
U map_or(F &&f, U &&u)&
Maps the stored value with f if there is one, otherwise returns u.
Definition: sol.hpp:4817
decltype(auto) as() const
Definition: sol.hpp:15309
std::size_t memory_used() const
Definition: sol.hpp:25600
basic_thread(const stack_reference &r)
Definition: sol.hpp:25912
static int push(std::index_sequence< I... >, lua_State *L, T &&t)
Definition: sol.hpp:14476
#define lua_isboolean(L, n)
Definition: lua.h:376
void set_exception_handler(exception_handler_function handler)
Definition: sol.hpp:25709
std::reverse_iterator< iterator > reverse_iterator
Definition: sol.hpp:15761
basic_object(lua_State *L, detail::global_tag t)
Definition: sol.hpp:15342
static void base_walk_index(lua_State *L, usertype_storage_base &self, bool &keep_going, int &base_result)
Definition: sol.hpp:22135
int registry_index() const noexcept
Definition: sol.hpp:9505
decltype(auto) readonly_property(F &&f)
Definition: sol.hpp:16485
basic_environment< E > get_environment(const T &target)
Definition: sol.hpp:24498
basic_table_core(lua_State *L, T &&r)
Definition: sol.hpp:23648
basic_object< stack_reference > stack_object
Definition: forward.hpp:726
static int push(lua_State *L, const constructor_wrapper< F, Fxs... > &c)
Definition: sol.hpp:18711
usertype_proxy && operator=(T &&other)&&
Definition: sol.hpp:22867
static int push(lua_State *L, const T &v)
Definition: sol.hpp:13793
std::integral_constant< bool, is_table_v< T >||is_environment_v< T >||is_userdata_v< T >> is_table_like
Definition: sol.hpp:7817
void update_bases(lua_State *L, bases< Bases... >)
Definition: sol.hpp:22054
static int next_call(lua_State *L)
Definition: sol.hpp:21403
main_table_core< false > main_table
Definition: forward.hpp:638
meta::conditional_t< std::is_void< T >::value, R(*)(Args...), R(*)(first_type, Args...)> free_function_pointer_type
Definition: sol.hpp:1062
stack_dependencies(int stack_target, Args &&...args)
Definition: sol.hpp:6373
constexpr bool is_adl_sol_lua_push_v
Definition: sol.hpp:10395
meta::tuple_types< R > returns_list
Definition: sol.hpp:16269
constexpr bool is_base_rebindable_v
Definition: sol.hpp:8374
light(L &x)
Definition: sol.hpp:6725
std::string demangle_once()
Definition: sol.hpp:8198
stateless_reference(lua_State *L, detail::global_tag) noexcept
Definition: sol.hpp:9130
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs)&
disjunction
Definition: sol.hpp:4912
std::add_pointer_t< meta::unqualified_t< std::remove_pointer_t< T >>> C
Definition: sol.hpp:21531
stack_proxy_base(lua_State *L, int index)
Definition: sol.hpp:15645
static int real_insert_traits(std::false_type, lua_State *L)
Definition: sol.hpp:21298
constexpr const char * not_enough_stack_space_string
Definition: sol.hpp:8578
int static_trampoline_noexcept(lua_State *L) noexcept
Definition: sol.hpp:8017
state_view & set_function(Key &&key, Args &&...args)
Definition: sol.hpp:25784
stack_iterator & operator++()
Definition: sol.hpp:15546
table_core< true > global_table
Definition: forward.hpp:637
struct sol::detail::global_tag global_
LUALIB_API void luaL_checkstack(lua_State *L, int space, const char *msg)
Definition: lauxlib.c:380
LUA_API int lua_next(lua_State *L, int idx)
Definition: lapi.c:1220
static int push(lua_State *L, lua_CFunction func, int n=0)
Definition: sol.hpp:13859
push_popper_at push_pop_at(T &&x)
Definition: sol.hpp:9045
T * ptr(T &val)
Definition: sol.hpp:1588
main_safe_function main_protected_function
Definition: forward.hpp:679
static int push(lua_State *L, const wchar_t *strb, const wchar_t *stre)
Definition: sol.hpp:14223
#define LUA_ERRERR
Definition: lua.h:54
#define luaL_checkversion(L)
Definition: lauxlib.h:46
meta::bind_traits< function_type >::return_type return_type
Definition: sol.hpp:17957
reference operator*()
Definition: sol.hpp:23336
basic_protected_function< stack_reference, false, reference > stack_safe_function
Definition: forward.hpp:675
LUALIB_API const char * luaL_tolstring(lua_State *L, int idx, size_t *len)
Definition: lauxlib.c:861
static int push_keyed(lua_State *L, K &&k, Args &&...args)
Definition: sol.hpp:13500
bool is_main_thread(lua_State *L)
Definition: sol.hpp:10547
static int real_erase_traits(std::false_type, lua_State *L)
Definition: sol.hpp:21334
const_iterator cend() const
Definition: sol.hpp:26467
const_iterator cbegin() const
Definition: sol.hpp:23702
basic_table< base_type > base_t
Definition: sol.hpp:24392
basic_protected_function(Proxy &&p, Handler &&eh)
Definition: sol.hpp:19337
tagged(Arg &&arg, Args &&...args)
Definition: sol.hpp:6269
decoded_result< It > utf8_to_code_point(It it, It last)
Definition: sol.hpp:12044
basic_userdata(lua_State *L, ref_index index)
Definition: sol.hpp:26301
static int push(lua_State *L, lua_CFunction func, int n=0)
Definition: sol.hpp:13870
protected_function_result do_file(const std::string &filename, const basic_environment< E > &env, load_mode mode=load_mode::any)
Definition: sol.hpp:25308
protected_function_result script_file(const std::string &filename, Fx &&on_error, load_mode mode=load_mode::any)
Definition: sol.hpp:25495
static R call(Fx &&fx, O &mem, Args &&...args)
Definition: sol.hpp:16277
stack_reference(lua_State *L, int i) noexcept
Definition: sol.hpp:8804
#define lua_isnil(L, n)
Definition: lua.h:375
void operator()(const unicode::encoded_result< ErCh > er)
Definition: sol.hpp:12198
LUALIB_API void luaL_traceback(lua_State *L, lua_State *L1, const char *msg, int level)
Definition: lauxlib.c:131
safe_function protected_function
Definition: forward.hpp:678
SOL_TL_OPTIONAL_11_CONSTEXPR T & value()
Definition: sol.hpp:6115
static int pairs_call(lua_State *L)
Definition: sol.hpp:21395
undefined_metatable(lua_State *l, const char *k, undefined_method_func umf)
Definition: sol.hpp:10526
basic_protected_function(lua_State *L, ref_index index, handler_t eh)
Definition: sol.hpp:19392
decltype(&inheritance< void >::type_check) inheritance_check_function
Definition: sol.hpp:8554
stack_iterator< stack_proxy, false > iterator
Definition: sol.hpp:15957
load_result load_buffer(const std::byte *buff, size_t size, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25553
decltype(auto) unqualified_check_get(lua_State *L, int index=-lua_size< meta::unqualified_t< T >>::value)
Definition: sol.hpp:10799
basic_usertype< T, stack_reference > stack_usertype
Definition: forward.hpp:653
optional< environment > env
Definition: sol.hpp:24505
protected_function_result(protected_function_result &&o) noexcept
Definition: sol.hpp:15776
protected_function_result do_string(const string_view &code, const basic_environment< E > &env, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25282
LUA_API void lua_concat(lua_State *L, int n)
Definition: lapi.c:1253
lua_CFunction closef
Definition: lauxlib.h:222
const char * name
basic_coroutine(lua_State *L, raw_index index)
Definition: sol.hpp:26191
basic_usertype< T, reference > usertype
Definition: forward.hpp:651
decltype(auto) get(Keys &&...keys) const
Definition: sol.hpp:23717
basic_reference(lua_State *L, const basic_reference< r_main_only > &r) noexcept
Definition: sol.hpp:9353
usertype_proxy(Table table, T &&k)
Definition: sol.hpp:22843
void set_environment(const basic_environment< E > &env, const T &target)
Definition: sol.hpp:24493
constexpr create_if_nil_t create_if_nil
Definition: sol.hpp:7035
neg< is_move_only< T >> is_not_move_only
Definition: sol.hpp:2252
static bool max_size_check(std::false_type, T &, std::size_t)
Definition: sol.hpp:12408
constexpr const int base_walking_failed_index
Definition: sol.hpp:21561
constexpr const T * operator->() const
Definition: sol.hpp:6076
const char *(* lua_Reader)(lua_State *L, void *ud, size_t *sz)
Definition: lua.h:117
static V get_one(std::integral_constant< std::size_t, std::variant_size_v< V >>, lua_State *L, int index, record &tracking)
Definition: sol.hpp:13144
basic_reference(lua_nil_t) noexcept
Definition: sol.hpp:9346
bool operator()(const lua_nil_t &lhs, const stack_reference &rhs) const
Definition: sol.hpp:8896
constexpr const char * not_a_number_or_number_string_integral
Definition: sol.hpp:8573
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: sol.hpp:15960
std::nullopt_t nullopt_t
A tag type to represent an empty optional.
Definition: sol.hpp:4520
const_reverse_iterator crend() const
Definition: sol.hpp:15892
static int push_func(std::index_sequence< I... >, lua_State *L, FP &&fp)
Definition: sol.hpp:18464
constexpr auto invoke(Fn &&f, Args &&...args) noexcept(noexcept(std::forward< Fn >(f)(std::forward< Args >(args)...))) -> decltype(std::forward< Fn >(f)(std::forward< Args >(args)...))
Definition: sol.hpp:4084
static int real_find_traits(std::true_type, lua_State *L)
Definition: sol.hpp:21342
std::integral_constant< bool, V_size::value==0 > V_is_empty
Definition: sol.hpp:13304
stack_iterator & operator--()
Definition: sol.hpp:15557
lua_State * L
Definition: sol.hpp:7049
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs)&&
disjunction
Definition: sol.hpp:5935
closure< Args... > make_closure(lua_CFunction f, Args &&...args)
Definition: sol.hpp:6801
meta::boolean< meta_detail::has_max_size_test< T >::value > has_max_size
Definition: sol.hpp:2152
detail::proxy_key_t< Key > key_type
Definition: sol.hpp:22971
static void check(LexState *ls, int c)
Definition: lparser.c:107
unqualified< tuple_element_t< N, Tuple >> unqualified_tuple_element
Definition: sol.hpp:1000
ref_clean(lua_State *luastate, int &n)
Definition: sol.hpp:23381
basic_coroutine(lua_State *L, absolute_index index, handler_t eh)
Definition: sol.hpp:26185
detail::named_arg< Char, T > arg(const Char *name, const T &arg)
Definition: core.h:1656
void traverse_set_deep(int table_index, Key &&key, Keys &&...keys) const
Definition: sol.hpp:23552
constexpr optional() noexcept
Definition: sol.hpp:5981
auto invoke(types< Ret... >, std::index_sequence< I... >, std::ptrdiff_t n) const
Definition: sol.hpp:18952
const T & value() const &
Definition: sol.hpp:6952
yielding_t< std::decay_t< F > > yielding(F &&f)
Definition: sol.hpp:6644
U map_or(F &&f, U &&u) const &&
map_or
Definition: sol.hpp:4836
void coroutine_create_guard(lua_State *L)
Definition: sol.hpp:10553
LUALIB_API void luaL_requiref(lua_State *L, const char *modname, lua_CFunction openf, int glb)
Definition: lauxlib.c:945
void operator()(const unicode::encoded_result< Ch > er)
Definition: sol.hpp:12186
constexpr bool is_lua_reference_or_proxy_v
Definition: sol.hpp:7387
optional & operator=(nullopt_t) noexcept
Definition: sol.hpp:6018
meta::conditional_t< meta::is_specialization_of_v< meta::unqualified_t< T >, std::tuple >, T, std::tuple< meta::conditional_t< std::is_array_v< meta::unqualified_t< T >>, std::remove_reference_t< T > &, meta::unqualified_t< T >>>> proxy_key_t
Definition: sol.hpp:15469
static int codepoint(lua_State *L)
Definition: lutf8lib.c:122
bool operator()(const stack_reference &lhs, const lua_nil_t &rhs) const
Definition: sol.hpp:8900
stack_count(int cnt)
Definition: sol.hpp:6699
#define LUA_OPLE
Definition: lua.h:224
const unchecked_t unchecked
Definition: sol.hpp:869
table new_enum(const string_view &name, std::initializer_list< std::pair< string_view, T >> items)
Definition: sol.hpp:23854
reverse_iterator rbegin()
Definition: sol.hpp:16027
static int push(lua_State *L, T &&t)
Definition: sol.hpp:14494
lua_State * lua_state() const
Definition: sol.hpp:15677
static void * type_cast_with(void *voiddata, const string_view &ti)
Definition: sol.hpp:8467
bool check_function_pointer(lua_State *L, int index, Handler &&handler, record &tracking) noexcept
Definition: sol.hpp:18836
SOL_TL_OPTIONAL_11_CONSTEXPR T && operator*()&&
Definition: sol.hpp:5218
static int push(lua_State *L, Args &&...args)
Definition: sol.hpp:13624
const T & move(const T &v)
Definition: backward.hpp:394
SOL_TL_OPTIONAL_11_CONSTEXPR T value_or(U &&u)&&
value_or
Definition: sol.hpp:5298
bool valid() const noexcept
Definition: sol.hpp:19120
traits_type::args_list free_args_list
Definition: sol.hpp:16157
static int push(lua_State *L, constructor_wrapper< F, Fxs... > &&c)
Definition: sol.hpp:18717
object make_object(lua_State *L, T &&value)
Definition: sol.hpp:15431
basic_table_core(lua_State *L, const new_table &nt)
Definition: sol.hpp:23656
static optional< R > get(lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:13294
optional< T > or_else(F &&f)&&
Definition: sol.hpp:4760
basic_table_core & set_function(Key &&key, Args &&...args)
Definition: sol.hpp:23926
static void * type_cast(void *voiddata, const string_view &ti)
Definition: sol.hpp:8461
SOL_TL_OPTIONAL_11_CONSTEXPR optional(detail::enable_if_t< std::is_constructible< T, std::initializer_list< U > &, Args &&... >::value, in_place_t >, std::initializer_list< U > il, Args &&...args)
Definition: sol.hpp:4997
const_iterator cend() const
Definition: sol.hpp:23706
push_popper_n< top_level > pop_n(lua_State *L, int x)
Definition: sol.hpp:9052
static int empty_call(lua_State *L)
Definition: sol.hpp:21379
static handler_t get_default_handler(lua_State *L)
Definition: sol.hpp:19198
const metatable_key_t metatable_key
Definition: sol.hpp:6616
basic_metatable< reference > metatable
Definition: forward.hpp:657
state(lua_CFunction panic=default_at_panic)
Definition: sol.hpp:26015
constexpr bool is_environment_v
Definition: sol.hpp:7814
basic_table_core & traverse_raw_set(Keys &&...keys)
Definition: sol.hpp:23814
static bool check(lua_State *L, int index, type indextype, Handler &&handler, record &tracking)
Definition: sol.hpp:11681
const T & value() const &
Definition: sol.hpp:6851
LUAMOD_API int luaopen_string(lua_State *L)
Definition: lstrlib.c:1800
#define LUA_GCCOLLECT
Definition: lua.h:321
static int real_call(lua_State *L) noexcept(traits_type::is_noexcept)
Definition: sol.hpp:17786
static int push(lua_State *L, const wchar_t *str, std::size_t len)
Definition: sol.hpp:14251
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs)&&
disjunction
Definition: sol.hpp:4900
int operator()(types< Fx >, meta::index_value< I >, types< R... > r, types< Args... > a, lua_State *L, int, int start, F &f)
Definition: sol.hpp:17205
std::index_sequence_for< Policies... > indices
Definition: sol.hpp:6393
optional< T > or_else(F &&f) const &&
Definition: sol.hpp:4794
LUA_API int lua_absindex(lua_State *L, int idx)
Definition: lapi.c:161
light(void *x)
Definition: sol.hpp:6729
basic_function(lua_State *L, int index=-1)
Definition: sol.hpp:19014
LUA_API int lua_type(lua_State *L, int idx)
Definition: lapi.c:260
basic_function(const stack_reference &r)
Definition: sol.hpp:18996
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
Definition: lapi.c:728
optional< T > or_else(F &&f) const &
Definition: sol.hpp:5790
basic_object(lua_State *L, int index=-1) noexcept
Definition: sol.hpp:15388
static int push(lua_State *, const stack_proxy_base &ref)
Definition: sol.hpp:15695
#define assert(a, b, c, d)
lua_CFunction make_destructor()
Definition: sol.hpp:11034
void select_convertible(types<>, lua_State *L, Fx &&fx, Args &&...args)
Definition: sol.hpp:18251
static int real_call(lua_State *L) noexcept(traits_type::is_noexcept)
Definition: sol.hpp:17609
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) const &
Definition: sol.hpp:4867
iterator begin()
Definition: sol.hpp:26452
decltype(auto) pop(lua_State *L)
Definition: sol.hpp:10928
basic_protected_function(const stack_reference &r, handler_t eh)
Definition: sol.hpp:19321
#define LUA_GCCOUNT
Definition: lua.h:322
std::tuple< Functions... > functions
Definition: sol.hpp:11834
conditional_t< std::is_void< U >::value, monostate, U > fixup_void
Definition: sol.hpp:4123
auto meta_registry_key(T &&key)
Definition: sol.hpp:6777
protect_t(Arg &&arg, Args &&...args)
Definition: sol.hpp:16557
static int add_call(lua_State *L)
Definition: sol.hpp:21363
const char(& default_handler_name())[9]
Definition: sol.hpp:19090
std::size_t result_type
Definition: sol.hpp:9613
void set(Key &&key, Value &&value)
Definition: sol.hpp:24204
int no_panic(lua_State *, int, type, type, const char *=nullptr) noexcept
Definition: sol.hpp:8684
static int push(lua_State *L, std::variant< Tn... > &&v)
Definition: sol.hpp:14593
static int push(lua_State *L, const factory_wrapper< Functions... > &fw)
Definition: sol.hpp:18611
static int push(lua_State *L, var_wrapper< T > &&vw)
Definition: sol.hpp:18601
int return_count() const
Definition: sol.hpp:16060
void set_default_state(lua_State *L, lua_CFunction panic_function=&default_at_panic, lua_CFunction traceback_function=c_call< decltype(&default_traceback_error_handler),&default_traceback_error_handler >, exception_handler_function exf=detail::default_exception_handler)
Definition: sol.hpp:24907
#define LUA_GCINC
Definition: lua.h:329
constexpr const int usertype_storage_base_index
Definition: sol.hpp:21553
static int push(lua_State *L, void *userdata)
Definition: sol.hpp:13931
protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n)
Definition: sol.hpp:26084
constexpr bool is_adl_sol_lua_get_v
Definition: sol.hpp:10380
meta::boolean< has_traits_index_get_test< T >::value > has_traits_index_get
Definition: sol.hpp:19919
stateless_stack_reference(lua_State *, absolute_index i) noexcept
Definition: sol.hpp:8742
automagic_enrollments & enrollments
Definition: sol.hpp:10240
constexpr std::in_place_t in_place_of
Definition: sol.hpp:3920
#define lua_yield(L, n)
Definition: lua.h:305
#define lua_replace(L, idx)
Definition: lua.h:393
unsafe_function_result unsafe_script(lua_Reader reader, void *data, const basic_environment< E > &env, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25408
int push(lua_State *Ls) const noexcept
Definition: sol.hpp:8838
constexpr bool is_lightuserdata_v
Definition: sol.hpp:7802
lua_bind_traits< function_type > traits_type
Definition: sol.hpp:17784
basic_object(detail::no_safety_tag, T &&r) noexcept
Definition: sol.hpp:15349
lua_State * lua_state() const noexcept
Definition: sol.hpp:7081
static int real_index_set_traits(std::false_type, lua_State *L)
Definition: sol.hpp:21226
typename bind_traits< Signature >::args_list function_args_t
Definition: sol.hpp:1519
#define LUA_ERRSYNTAX
Definition: lua.h:52
basic_function< base_t > force_cast(T &p)
Definition: sol.hpp:19134
basic_protected_function(lua_State *L, int index=-1)
Definition: sol.hpp:19359
std::is_void< decltype(test< F >(0))> type
Definition: sol.hpp:1023
constexpr optional(nullopt_t) noexcept
ctor_empty
Definition: sol.hpp:5985
void operator()(lua_State *L, submetatable_type smt, reference &fast_index_table)
Definition: sol.hpp:21946
new_index_call_storage static_base_index
Definition: sol.hpp:21984
basic_table_core< false, base_type > basic_table
Definition: forward.hpp:635
meta::boolean< has_traits_next_test< T >::value > has_traits_next
Definition: sol.hpp:19931
basic_reference(lua_State *L, ref_index index) noexcept
Definition: sol.hpp:9413
LUAMOD_API int luaopen_math(lua_State *L)
Definition: lmathlib.c:750
typename strip< T >::type strip_t
Definition: sol.hpp:10429
meta::return_type_t< R... > operator()(Args &&...args)
Definition: sol.hpp:19544
#define lua_tostring(L, i)
Definition: lua.h:386
basic_table_core< b, reference > table_core
Definition: forward.hpp:629
R make_reference(lua_State *L, T &&value)
Definition: sol.hpp:15218
LUA_API void lua_copy(lua_State *L, int fromidx, int toidx)
Definition: lapi.c:231
void set_extra(std::false_type, std::index_sequence< I... >, T &&target)
Definition: sol.hpp:9667
int top(lua_State *L)
Definition: sol.hpp:10543
void delete_usertype_storage(lua_State *L)
Definition: sol.hpp:22535
static int push(lua_State *L, detail::yield_tag_t, std::function< Signature > &&fx)
Definition: sol.hpp:18487
const R & read() const
Definition: sol.hpp:16456
int push(lua_State *L, Arg &&arg, Args &&...args)
Definition: sol.hpp:10614
int push(lua_State *, lua_thread_state lts)
Definition: sol.hpp:25862
void set_panic(lua_CFunction panic)
Definition: sol.hpp:25705
::std::size_t operator()(const ::sol::optional< T > &o) const
Definition: sol.hpp:6159
void set_extra(std::true_type, std::index_sequence< I... >, T &&target)
Definition: sol.hpp:9660
meta::boolean<(TI::value%2)==0 > on_even
Definition: sol.hpp:1777
static int push(lua_State *, stack_count st)
Definition: sol.hpp:13841
static int push(lua_State *L, const char32_t *strb, const char32_t *stre)
Definition: sol.hpp:14400
typename return_type< Args... >::type return_type_t
Definition: sol.hpp:1847
LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction fn, int n)
Definition: lapi.c:555
SOL_TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t< F, T && > and_then(F &&f)&&
Definition: sol.hpp:4629
void stack_fail(int, int)
Definition: sol.hpp:9706
lua_value(lua_State *L_, arr il)
Definition: sol.hpp:24765
constexpr optional(U &&u)
Definition: sol.hpp:6003
unsafe_function_result unsafe_script_file(const std::string &filename, load_mode mode=load_mode::any)
Definition: sol.hpp:25476
char[SOL_FILE_ID_SIZE_I_] typical_file_chunk_name_t
Definition: sol.hpp:14926
meta::boolean< has_empty_test< T >::value > has_empty
Definition: sol.hpp:19895
MQTTClient c
Definition: test10.c:1656
protected_function_result safe_script(const string_view &code, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25372
void usertype_unique_alloc_destroy(void *memory)
Definition: sol.hpp:10203
closure(lua_CFunction f, Upvalues...targetupvalues)
Definition: sol.hpp:6786
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) const &&
Definition: sol.hpp:4876
optional & operator=(const optional< U > &rhs)
Definition: sol.hpp:6045
optional take()&&
take
Definition: sol.hpp:4949
const char(& default_exception_handler_name())[11]
Definition: sol.hpp:7921
void swap(optional< T > &lhs, optional< T > &rhs) noexcept(noexcept(lhs.swap(rhs)))
template <class t>=""> swap(optional<T> &lhs, optional<T> &rhs);
Definition: sol.hpp:5478
U map_or(F &&f, U &&u)&
Maps the stored value with f if there is one, otherwise returns u.
Definition: sol.hpp:5830
typename conditional< B >::template type< T, U > conditional_t
Definition: sol.hpp:918
stack_safe_function stack_protected_function
Definition: forward.hpp:680
#define LUA_MINSTACK
Definition: lua.h:80
static bool is_one(std::integral_constant< std::size_t, 0 >, lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:11721
stack_proxy operator[](difference_type index_offset) const
Definition: sol.hpp:15854
nested(Arg &&arg)
Definition: sol.hpp:6876
optional< T > SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F &&f)&
Calls f if the optional is empty std::invoke_result_t<F> must be void or convertible to optional<T>...
Definition: sol.hpp:5756
int dump_panic_on_error(lua_State *L, int result_code, lua_Writer writer_function, void *userdata, bool strip)
Definition: sol.hpp:18915
is_stack_based< target_t > is_stack
Definition: sol.hpp:19097
static optional< V > get_empty(std::false_type, lua_State *L, int index, Handler &&handler, record &)
Definition: sol.hpp:13312
result_type operator()(const basic_reference< lb > &lhs) const
Definition: sol.hpp:9616
SOL_TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U &&...u)
Definition: sol.hpp:4263
LUALIB_API int luaL_error(lua_State *L, const char *fmt,...)
Definition: lauxlib.c:234
std::remove_pointer_t< std::decay_t< Function > > function_type
Definition: sol.hpp:17956
auto & pick(std::false_type, property_wrapper< R, W > &f)
Definition: sol.hpp:16651
std::ptrdiff_t difference_type
Definition: sol.hpp:15511
std::ptrdiff_t difference_type
Definition: sol.hpp:26414
int stack_top() const
Definition: sol.hpp:25604
int push_reference(lua_State *L, Arg &&arg, Args &&...args)
Definition: sol.hpp:10670
#define LUA_ERRMEM
Definition: lua.h:53
static int push(lua_State *L, factory_wrapper< Functions... > &&fw, function_detail::call_indicator)
Definition: sol.hpp:18629
basic_coroutine(lua_State *L, T &&r, handler_t eh)
Definition: sol.hpp:26162
int static_trampoline(lua_State *L)
Definition: sol.hpp:8011
constexpr bool is_adl_sol_lua_push_exact_v
Definition: sol.hpp:10398
std::pair< object, object > value_type
Definition: sol.hpp:23283
SOL_TL_OPTIONAL_11_CONSTEXPR const T & value() const
Definition: sol.hpp:6126
basic_lightuserdata(const stack_reference &r)
Definition: sol.hpp:26333
std_shim(unsafe_function lua_func)
Definition: sol.hpp:19540
std::reverse_iterator< iterator > reverse_iterator
Definition: sol.hpp:26418
unqualified_t< tuple_element_t< N, Tuple >> unqualified_tuple_element_t
Definition: sol.hpp:1003
basic_thread create()
Definition: sol.hpp:25988
void * align_usertype_unique(void *ptr)
Definition: sol.hpp:9865
const auto no_constructor
Definition: sol.hpp:6296
basic_variadic_results(protected_function_result fr)
Definition: sol.hpp:26606
std::function< void(int, int)> on_mismatch
Definition: sol.hpp:9720
constexpr const char * protected_function_error
Definition: sol.hpp:8583
basic_coroutine(const basic_function< base_t > &b)
Definition: sol.hpp:26123
meta::boolean< meta_detail::has_insert_test< T >::value > has_insert
Definition: sol.hpp:2155
basic_thread(lua_State *L, this_state actualthread)
Definition: sol.hpp:25945
static table create_table_with(lua_State *L, Args &&...args)
Definition: sol.hpp:25830
static bool check(lua_State *, int, type, Handler &&, record &)
Definition: sol.hpp:11211
policy_wrapper(Fx &&fx, Args &&...args)
Definition: sol.hpp:6399
#define lua_call(L, n, r)
Definition: lua.h:283
LUA_API void lua_rotate(lua_State *L, int idx, int n)
Definition: lapi.c:217
LUA_API int lua_load(lua_State *L, lua_Reader reader, void *data, const char *chunkname, const char *mode)
Definition: lapi.c:1054
typename u_traits::type P
Definition: sol.hpp:13568
void type_assert(lua_State *L, int index, type expected, type actual) noexcept(false)
Definition: sol.hpp:8696
property_wrapper(Rx &&r, Wx &&w)
Definition: sol.hpp:16440
std::tuple_element< N, std::remove_reference_t< Tuple >> tuple_element
Definition: sol.hpp:994
LUALIB_API void luaL_addvalue(luaL_Buffer *B)
Definition: lauxlib.c:609
constexpr const int index_function_index
Definition: sol.hpp:21558
basic_coroutine(stack_reference &&r)
Definition: sol.hpp:26136
stack_reference(lua_State *L, raw_index i) noexcept
Definition: sol.hpp:8808
constexpr bool is_stack_table_v
Definition: sol.hpp:7789
static_stack_dependencies<-1, 1 > self_dependency
Definition: sol.hpp:6362
type get_type(difference_type index_offset=0) const noexcept
Definition: sol.hpp:16000
basic_table_core(detail::no_safety_tag, lua_State *L, T &&r) noexcept
Definition: sol.hpp:23629
void collect_gc()
Definition: sol.hpp:25636
basic_userdata< reference > userdata
Definition: forward.hpp:718
int default_size(lua_State *L)
Definition: sol.hpp:11094
clean(lua_State *luastate)
Definition: sol.hpp:23371
lua_State * lua_state() const noexcept
Definition: sol.hpp:7062
lua_State * lua_state() const noexcept
Definition: sol.hpp:9525
table create(int narr=0, int nrec=0)
Definition: sol.hpp:23992
iterator const_iterator
Definition: sol.hpp:23634
void reset() noexcept
Destroys the stored value if one exists, making the optional empty.
Definition: sol.hpp:6145
void get(lua_State *L, Key &&key, int tableindex=default_table_index)
Definition: sol.hpp:14644
static constexpr bool is_lead_surrogate(char32_t u)
Definition: sol.hpp:11912
destructor_wrapper(Function f)
Definition: sol.hpp:6332
auto as_function_reference(Args &&...args)
Definition: sol.hpp:6819
basic_environment(lua_State *L, new_table nt)
Definition: sol.hpp:24407
static int real_set_call(lua_State *L)
Definition: sol.hpp:21218
std::integral_constant< std::size_t, I > index_value
Definition: sol.hpp:903
int c_trampoline(lua_State *L, lua_CFunction f)
Definition: sol.hpp:8061
int call_set_variable(std::true_type, lua_State *L, T &&mem)
Definition: sol.hpp:17501
bool operator>=(const stack_iterator &r) const
Definition: sol.hpp:15618
LUA_API lua_State * lua_newthread(lua_State *L)
Definition: lstate.c:321
lua_bind_traits< function_type > traits_type
Definition: sol.hpp:17682
void operator()(T *p) const
Definition: sol.hpp:6246
bool is_valid(std::false_type)
Definition: sol.hpp:22999
std::reference_wrapper< T > value_
Definition: sol.hpp:7015
static bool type_check(const string_view &ti)
Definition: sol.hpp:8442
result_type operator()(const argument_type &lhs) const
Definition: sol.hpp:8913
static int push(lua_State *L, const char32_t *u32str, std::size_t sz)
Definition: sol.hpp:14362
userdata_value(void *data)
Definition: sol.hpp:6714
auto unwrap(T &&item) -> decltype(std::forward< T >(item))
Definition: sol.hpp:1556
basic_object & operator=(base_type &&b)
Definition: sol.hpp:15414
std::enable_if_t< all< Args... >::value, enable_t > enable
Definition: sol.hpp:1726
static iterator end(lua_State *L, T &)
Definition: sol.hpp:20075
as_container_t(Arg &&arg)
Definition: sol.hpp:6938
static int push(lua_State *L, detail::lua_CFunction_noexcept func, int n=0)
Definition: sol.hpp:13893
static int real_call(lua_State *L) noexcept(false)
Definition: sol.hpp:17824
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs)&
Definition: sol.hpp:5903
const_iterator cbegin() const
Definition: sol.hpp:15870
basic_protected_function< reference, false, reference > safe_function
Definition: forward.hpp:671
typename global_table::const_iterator const_iterator
Definition: sol.hpp:25073
table create_table(int narr=0, int nrec=0)
Definition: sol.hpp:25806
std::size_t len
Definition: sol.hpp:6370
bases base_classes_tag
Definition: sol.hpp:8401
table create_table_with(Args &&...args)
Definition: sol.hpp:25816
nested< meta::unqualified_t< T > > as_nested(T &&container)
Definition: sol.hpp:6918
basic_table_core(T &&r) noexcept
Definition: sol.hpp:23678
constexpr const char * not_enough_stack_space_floating
Definition: sol.hpp:10404
LUALIB_API int luaL_getsubtable(lua_State *L, int idx, const char *fname)
Definition: lauxlib.c:925
basic_thread(stack_reference &&r)
Definition: sol.hpp:25914
T * user_allocate(lua_State *L)
Definition: sol.hpp:10137
returns_self_with returns_self
Definition: sol.hpp:6365
constexpr const char * not_enough_stack_space_userdata
Definition: sol.hpp:8580
int construct_trampolined(lua_State *L)
Definition: sol.hpp:16850
constexpr const char * not_a_number_or_number_string
Definition: sol.hpp:8570
constexpr bool has_value() const noexcept
Definition: sol.hpp:5231
static int real_get_call(lua_State *L)
Definition: sol.hpp:21206
static Reference get_default_handler(lua_State *L)
Definition: sol.hpp:19139
void set(Key &&key, Value &&value)
Definition: sol.hpp:24351
static bool check(lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:11227
void(usertype_storage_base::*)(lua_State *, submetatable_type, void *, stack_reference &, lua_CFunction, lua_CFunction, lua_CFunction, lua_CFunction) change_indexing_mem_func
Definition: sol.hpp:21731
L * value
Definition: sol.hpp:6723
constexpr const int usertype_storage_index
Definition: sol.hpp:21552
static int push(lua_State *L, destructor_wrapper< void >)
Definition: sol.hpp:18726
static int push(lua_State *L, Arg &&arg, Args &&...args)
Definition: sol.hpp:14000
int operator()(types< Fx >, meta::index_value< I >, types< R... > r, types< Args... > a, lua_State *L, int, int start) const
Definition: sol.hpp:16672
void invoke(types< void >, std::index_sequence< I >, std::ptrdiff_t n) const
Definition: sol.hpp:18964
#define LUA_GCGEN
Definition: lua.h:328
stack_proxy * pointer
Definition: sol.hpp:26413
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
Definition: lapi.c:489
static void construct(T &&obj, Args &&...args)
Definition: sol.hpp:6219
#define LUA_GCSETPAUSE
Definition: lua.h:325
static bool is_one(std::integral_constant< std::size_t, I >, lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:11733
usertype_proxy & operator=(T &&other)&
Definition: sol.hpp:22862
basic_thread(lua_State *L, lua_State *actualthread)
Definition: sol.hpp:25942
static int get_size_hint(const std::forward_list< V, Al > &)
Definition: sol.hpp:10437
int call_wrapped(lua_State *L, Fx &&fx, Args &&...args)
Definition: sol.hpp:17409
void abandon() noexcept
Definition: sol.hpp:16063
void tuple_set(std::index_sequence< I... >, T &&value)&
Definition: sol.hpp:22984
static int push(lua_State *L, const T &tablecont, nested_tag_t)
Definition: sol.hpp:13719
probe probe_raw_get_field(lua_State *L, Key &&key, int tableindex)
Definition: sol.hpp:10968
reference handler_t
Definition: sol.hpp:26052
call_status status() const noexcept
Definition: sol.hpp:16046
#define LUA_REGISTRYINDEX
Definition: lua.h:44
static int push(lua_State *L, destructor_wrapper< Fx > &&c)
Definition: sol.hpp:18734
int operator()(lua_State *L, int index, type expected, type actual, string_view message) const noexcept(false)
Definition: sol.hpp:8645
const_iterator begin() const
Definition: sol.hpp:26458
state_view(lua_State *Ls)
Definition: sol.hpp:25075
static constexpr bool is_continuation(unsigned char b)
Definition: sol.hpp:11938
static int push(lua_State *L, push_invoke_t< T > &&pi)
Definition: sol.hpp:18815
gc_mode change_gc_mode_generational(int minor_multiplier, int major_multiplier)
Definition: sol.hpp:25686
constexpr const int magic_index
Definition: sol.hpp:21555
basic_metatable(lua_nil_t r) noexcept
Definition: sol.hpp:24099
LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
Definition: lapi.c:592
decltype(sol_lua_get(types< T >(), static_cast< lua_State * >(nullptr),-1, std::declval< stack::record & >())) adl_sol_lua_get_test_t
Definition: sol.hpp:10356
static int call(lua_State *L, Fx &&fx, Args &&...args)
Definition: sol.hpp:17001
basic_protected_function(lua_State *L, ref_index index)
Definition: sol.hpp:19389
static T * get_no_lua_nil(lua_State *L, int index, record &tracking)
Definition: sol.hpp:13003
static int real_at_call(lua_State *L)
Definition: sol.hpp:21194
basic_lightuserdata< stack_reference > stack_lightuserdata
Definition: forward.hpp:728
decltype(*std::declval< T >()) is_dereferenceable_test
Definition: sol.hpp:1540
static optional< R > get(lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:13353
static int push_lvalue(std::false_type, lua_State *L, const C &cont)
Definition: sol.hpp:21485
meta::conditional_t< std::is_void< T >::value, R(Args...), R(first_type, Args...)> free_function_type
Definition: sol.hpp:1061
SOL_TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t< F, T & > and_then(F &&f)&
Definition: sol.hpp:5633
stateless_reference(lua_State *L, stateless_reference &&r) noexcept
Definition: sol.hpp:9161
fmt::detail::null strerror_r(int, char *,...)
Definition: format-inl.h:32
type get_type(lua_State *L) const noexcept
Definition: sol.hpp:8779
int c_call(lua_State *L)
Definition: sol.hpp:17565
auto readonly(R T::*v)
Definition: sol.hpp:16512
void tuple_set(std::index_sequence< I... >, Pairs &&pairs)
Definition: sol.hpp:23448
basic_table_core & traverse_set(Keys &&...keys)
Definition: sol.hpp:23754
#define LUAL_BUFFERSIZE
Definition: ltests.h:122
static int index_call_with_bases_(lua_State *L)
Definition: sol.hpp:22284
#define SOL_CONTAINER_START_INDEX_I_
Definition: sol.hpp:515
std::in_place_t in_place_t
Definition: sol.hpp:3918
void apply(std::index_sequence< I0, I1, I... >, lua_State *L, Keys &&keys, Value &&value, int tableindex)
Definition: sol.hpp:14820
static int real_clear_traits(std::true_type, lua_State *L)
Definition: sol.hpp:21306
constexpr optional disjunction(optional &&rhs) const &
disjunction
Definition: sol.hpp:5930
load_result load_buffer(const char *buff, size_t size, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25549
auto setup_table(std::true_type)
Definition: sol.hpp:22993
void(*)(void *) unique_destructor
Definition: sol.hpp:9765
struct sol::detail::no_safety_tag no_safety
void set_fx(types<>, Key &&key, Fx &&fx)
Definition: sol.hpp:23953
#define LUA_GCCOUNTB
Definition: lua.h:323
static int push(lua_State *L, nullopt_t)
Definition: sol.hpp:14517
static int push(lua_State *L, const char *str, std::size_t len)
Definition: sol.hpp:14069
basic_object(detail::no_safety_tag, lua_State *L, int index)
Definition: sol.hpp:15340
#define LUA_OK
Definition: lua.h:49
static int push(lua_State *L, detail::lua_CFunction_noexcept func, int n=0)
Definition: sol.hpp:13882
#define lua_istable(L, n)
Definition: lua.h:373
LUALIB_API lua_State * luaL_newstate(void)
Definition: lauxlib.c:1037
std::tuple< Functions... > overload_list
Definition: sol.hpp:18008
type get_type() const noexcept
Definition: sol.hpp:9521
user(U &&x)
Definition: sol.hpp:6749
LUA_API void lua_len(lua_State *L, int idx)
Definition: lapi.c:1267
static int index_call_(lua_State *L)
Definition: sol.hpp:21817
basic_metatable(detail::no_safety_tag, lua_State *L, int index)
Definition: sol.hpp:24041
LUALIB_API int luaL_loadfilex(lua_State *L, const char *filename, const char *mode)
Definition: lauxlib.c:754
static int new_index_call(lua_State *L)
Definition: sol.hpp:21423
int construct(lua_State *L)
Definition: sol.hpp:16870
constexpr const int exact_function_index
Definition: sol.hpp:21554
auto make_user(T &&u)
Definition: sol.hpp:6763
const new_table create
Definition: sol.hpp:7100
const_reverse_iterator crbegin() const
Definition: sol.hpp:15889
unsafe_function lua_func_
Definition: sol.hpp:19551
static int call(lua_State *L, Fx &&f, Args &&...args)
Definition: sol.hpp:16877
void raw_get_field(lua_State *L, Key &&key, int tableindex)
Definition: sol.hpp:10948
T & value()&
Definition: sol.hpp:6455
has_clear< T > has_traits_clear
Definition: sol.hpp:19940
int stack_index() const noexcept
Definition: sol.hpp:15899
int operator()(lua_State *L, int index, type expected, type actual, string_view message) const noexcept(false)
Definition: sol.hpp:8661
const target_t & target
Definition: sol.hpp:19098
static bool type_check_with(const string_view &ti)
Definition: sol.hpp:8447
int multi_push(lua_State *L, T &&t, Args &&...args)
Definition: sol.hpp:10680
std::decay_t< meta::unwrap_unqualified_t< Func > > function_type
Definition: sol.hpp:17896
static int real_at_traits(std::true_type, lua_State *L)
Definition: sol.hpp:21186
LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
Definition: lauxlib.c:324
int copy(lua_State *L) const noexcept
Definition: sol.hpp:9101
Function * get_function_pointer(lua_State *, int, record &) noexcept
Definition: sol.hpp:18858
decltype(&inheritance< void >::type_cast) inheritance_cast_function
Definition: sol.hpp:8555
basic_metatable(T &&r) noexcept
Definition: sol.hpp:24090
typename std::enable_if< B, T >::type enable_if_t
Definition: core.h:251
void operator()(lua_State *L) const
Definition: sol.hpp:6252
void select_member_function_with(lua_State *L, Fx &&fx, T &&obj, Args &&...args)
Definition: sol.hpp:18307
fmt::detail::null strerror_s(char *, size_t,...)
Definition: format-inl.h:33
optional & operator=(U &&u)
Definition: sol.hpp:6034
int call_user(lua_State *L)
Definition: sol.hpp:17424
int push(lua_State *L, const variadic_results &r)
Definition: sol.hpp:26649
constexpr bool is_lua_primitive_v
Definition: sol.hpp:7691
main_table_core< true > main_global_table
Definition: forward.hpp:639
table_proxy & force()
Definition: sol.hpp:23192
LUA_API const char * lua_pushfstring(lua_State *L, const char *fmt,...)
Definition: lapi.c:542
const char(& default_main_thread_name())[9]
Definition: sol.hpp:8926
constexpr bool is_policy_v
Definition: sol.hpp:6418
table create_named(Name &&name, Args &&...args)
Definition: sol.hpp:24021
void construct(Args &&...args) noexcept
Definition: sol.hpp:4289
usertype_proxy< const basic_usertype &, std::decay_t< Key > > operator[](Key &&key) const
Definition: sol.hpp:24229
reverse_iterator rend()
Definition: sol.hpp:15880
static int push(lua_State *L, std::nullptr_t)
Definition: sol.hpp:14524
basic_function(lua_State *L, T &&r)
Definition: sol.hpp:19006
unsafe_function_result function_result
Definition: forward.hpp:701
static void * type_cast_bases(types<>, T *, const string_view &)
Definition: sol.hpp:8451
optional & operator=(optional< U > &&rhs)
Definition: sol.hpp:5128
protected_function_result do_file(const std::string &filename, load_mode mode=load_mode::any)
Definition: sol.hpp:25318
LUA_API const char * lua_setupvalue(lua_State *L, int funcindex, int n)
Definition: lapi.c:1366
lua_bind_traits< function_type > traits_type
Definition: sol.hpp:17639
#define lua_insert(L, idx)
Definition: lua.h:389
meta_function
Definition: sol.hpp:7276
string_view as_string_view() const
Definition: sol.hpp:3808
type type_of(lua_State *L, int index)
Definition: sol.hpp:7368
void register_main_thread(lua_State *L)
Definition: sol.hpp:24850
unsafe_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n) const
Definition: sol.hpp:18968
static int push(lua_State *L, Arg0 &&arg0, Args &&...args)
Definition: sol.hpp:18406
basic_coroutine(lua_State *L, absolute_index index)
Definition: sol.hpp:26182
call_syntax get_call_syntax(lua_State *L, const string_view &key, int index)
Definition: sol.hpp:15142
int dump(lua_Writer writer, void *userdata, bool strip=false) const
Definition: sol.hpp:19412
stack_reference(lua_State *L, lua_nil_t) noexcept
Definition: sol.hpp:8802
int default_traceback_error_handler(lua_State *L)
Definition: sol.hpp:24886
static int real_erase_traits(std::true_type, lua_State *L)
Definition: sol.hpp:21330
constexpr bool is_adl_sol_lua_interop_get_v
Definition: sol.hpp:10383
basic_metatable(lua_State *L, T &&r)
Definition: sol.hpp:24067
static void set_default_handler(lua_State *L, const T &ref)
Definition: sol.hpp:19149
#define lua_str2number(s, p)
Definition: luaconf.h:480
int map_hint
Definition: sol.hpp:7088
int sequence_hint
Definition: sol.hpp:7087
void handle_protected_exception(lua_State *L, optional< const std::exception & > maybe_ex, const char *error, detail::protected_handler< b, handler_t > &h)
Definition: sol.hpp:19177
LUA_API const char * lua_pushlstring(lua_State *L, const char *s, size_t len)
Definition: lapi.c:502
static int push(lua_State *L, const constructor_wrapper< Fxs... > &c)
Definition: sol.hpp:18700
void clear(lua_State *L, int table_index)
Definition: sol.hpp:10569
stateless_reference(stateless_reference &&o) noexcept
Definition: sol.hpp:9210
static int push_fx(lua_State *L, F &&f, T *obj)
Definition: sol.hpp:13526
static constexpr char32_t replacement
Definition: sol.hpp:11970
constexpr update_if_empty_t update_if_empty
Definition: sol.hpp:7033
LUALIB_API char * luaL_prepbuffsize(luaL_Buffer *B, size_t sz)
Definition: lauxlib.c:565
ebco(Arg &&arg, Args &&...args)
Definition: sol.hpp:6453
T & emplace(Args &&...args) noexcept
Definition: sol.hpp:6055
SOL_TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t< F, T & > and_then(F &&f)&&
Definition: sol.hpp:5643
static int real_find_call(lua_State *L)
Definition: sol.hpp:21350
basic_reference(stack_reference &&r) noexcept
Definition: sol.hpp:9350
reverse_iterator rbegin()
Definition: sol.hpp:26471
basic_table_core(detail::no_safety_tag, lua_nil_t n)
Definition: sol.hpp:23617
lua_State * L
Definition: sol.hpp:15638
std::in_place_type_t< T > in_place_type_t
Definition: sol.hpp:3923
lua_State * L
Definition: sol.hpp:9718
types type
Definition: sol.hpp:806
void set_field(lua_State *L, Key &&key, Value &&value, int tableindex)
Definition: sol.hpp:10978
constexpr bool is_adl_sol_lua_check_v
Definition: sol.hpp:10386
auto operator[](T &&key)&&
Definition: sol.hpp:23921
static int real_index_get_traits(std::true_type, lua_State *L)
Definition: sol.hpp:21151
T && value()&&
Definition: sol.hpp:6948
basic_table_iterator< ref_t > iterator
Definition: sol.hpp:23633
meta::function_return_t< function_type > return_type
Definition: sol.hpp:17928
std::remove_pointer_t< meta::unwrap_unqualified_t< X > > T
Definition: sol.hpp:19999
bool is() const
Definition: sol.hpp:15655
static constexpr int sequence_length(unsigned char b)
Definition: sol.hpp:11947
static int push(lua_State *L, const lua_value &lv)
Definition: sol.hpp:24825
int push_environment_of(lua_State *L, int index=-1)
Definition: sol.hpp:13457
T & value()&
Definition: sol.hpp:6882
U map_or(F &&f, U &&u)&&
map_or
Definition: sol.hpp:5836
decltype(auto) unchecked_get(lua_State *L, int index, record &tracking)
Definition: sol.hpp:10456
lua_State * operator->() const noexcept
Definition: sol.hpp:25854
typename container_decay< meta::unqualified_t< T >>::type container_decay_t
Definition: sol.hpp:19974
void operator()(T &&obj) const
Definition: sol.hpp:6239
meta::boolean< meta_detail::has_push_back_test< T >::value > has_push_back
Definition: sol.hpp:2149
SOL_TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t< F, T & > and_then(F &&f)&
Definition: sol.hpp:4619
usertype_storage_base & get_usertype_storage_base(lua_State *L, const char *gcmetakey)
Definition: sol.hpp:22506
usertype< Class > new_usertype(Key &&key)
Definition: sol.hpp:24315
void get_field(lua_State *L, Key &&key, int tableindex)
Definition: sol.hpp:10938
detail::invoke_result_t< U > map_or_else(F &&f, U &&u)&&
Definition: sol.hpp:5872
meta::boolean< has_traits_add_test< T >::value > has_traits_add
Definition: sol.hpp:19934
load_mode
Definition: sol.hpp:7135
static int push(lua_State *L, const char *str)
Definition: sol.hpp:14082
void luajit_exception_handler(lua_State *L, int(*handler)(lua_State *, lua_CFunction)=detail::c_trampoline)
Definition: sol.hpp:15179
static int type_unique_cast_bases(types< Base, Args... >, void *source_data, void *target_data, const string_view &ti)
Definition: sol.hpp:8478
constexpr bool is_adl_sol_lua_check_get_v
Definition: sol.hpp:10392
#define LUA_GCRESTART
Definition: lua.h:320
optional take()&
Definition: sol.hpp:4935
raw_index(int i)
Definition: sol.hpp:6668
void remove(lua_State *L, int rawindex, int count)
Definition: sol.hpp:8933
table new_enum(const string_view &name, Args &&...args)
Definition: sol.hpp:23840
stack_guard(lua_State *L)
Definition: sol.hpp:9722
basic_protected_function(stack_reference &&r)
Definition: sol.hpp:19318
constexpr int lua_size_v
Definition: sol.hpp:7663
const_iterator cbegin() const
Definition: sol.hpp:25578
object make_object_userdata(lua_State *L, T &&value)
Definition: sol.hpp:15441
int push_reference(lua_State *L, T &&t, Args &&...args)
Definition: sol.hpp:10665
decltype(sol_lua_interop_check(types< T >(), static_cast< lua_State * >(nullptr),-1, type::none, no_panic, std::declval< stack::record & >())) adl_sol_lua_interop_check_test_t
Definition: sol.hpp:10367
SOL_TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept
Definition: sol.hpp:4259
int user_alloc_destruct(lua_State *L)
Definition: sol.hpp:10193
int currentline
Definition: lua.h:476
basic_function< stack_reference, true > stack_aligned_unsafe_function
Definition: forward.hpp:676
optional(const optional< U > &rhs)
Definition: sol.hpp:5027
basic_table_core(detail::no_safety_tag, T &&r) noexcept
Definition: sol.hpp:23626
def decode(buffer)
Definition: MQTTV5.py:247
basic_table_core< b, main_reference > main_table_core
Definition: forward.hpp:631
std::remove_pointer_t< std::decay_t< Function > > function_type
Definition: sol.hpp:17822
int(lua_State *, void *) index_call_function
Definition: sol.hpp:21729
unsafe_function_result unsafe_script_file(const std::string &filename, const basic_environment< E > &env, load_mode mode=load_mode::any)
Definition: sol.hpp:25462
bool attempt_alloc(lua_State *L, std::size_t ptr_align, std::size_t ptr_size, std::size_t value_align, std::size_t value_size, std::size_t allocated_size, void *&pointer_adjusted, void *&data_adjusted)
Definition: sol.hpp:9942
lua_State * L
Definition: sol.hpp:26406
std::tuple< Upvalues... > upvalues
Definition: sol.hpp:6785
constexpr bool is_pointer_like_v
Definition: sol.hpp:1550
basic_coroutine(const stack_reference &r, handler_t eh)
Definition: sol.hpp:26139
constexpr const lua_Integer toplevel_magic
Definition: sol.hpp:21549
basic_reference(lua_State *L, detail::global_tag, detail::global_tag) noexcept
Definition: sol.hpp:9326
dictionary data
Definition: mqtt_test.py:22
bool check(lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:10725
optional take()&&
take
Definition: sol.hpp:5962
meta::boolean< has_traits_get_test< T >::value > has_traits_get
Definition: sol.hpp:19910
static int push(lua_State *L, absolute_index ai)
Definition: sol.hpp:14182
LUA_API int lua_getfield(lua_State *L, int idx, const char *k)
Definition: lapi.c:655
const env_key_t env_key
Definition: sol.hpp:6619
const auto default_constructor
Definition: sol.hpp:6293
int call_wrapper_entry(lua_State *L) noexcept(meta::bind_traits< F >::is_noexcept)
Definition: sol.hpp:17535
stack_iterator & operator+=(difference_type idx)
Definition: sol.hpp:15568
typename unwrap_unqualified< T >::type unwrap_unqualified_t
Definition: sol.hpp:1655
light(L *x)
Definition: sol.hpp:6727
static int real_add_traits(std::false_type, lua_State *L)
Definition: sol.hpp:21286
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.hpp:2780
void pop(lua_State *Ls, int n=1) const noexcept
Definition: sol.hpp:8846
basic_coroutine< stack_reference > stack_coroutine
Definition: forward.hpp:730
basic_function< main_reference, false > main_unsafe_function
Definition: forward.hpp:672
static int new_index_target_set(lua_State *L, void *target)
Definition: sol.hpp:22264
bool multi_check(lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:10850
constexpr optional disjunction(optional &&rhs) const &
disjunction
Definition: sol.hpp:4917
int push() const
Definition: sol.hpp:26490
static decltype(auto) get(lua_State *L, int index, record &tracking)
Definition: sol.hpp:12311
LUALIB_API int luaL_getmetafield(lua_State *L, int obj, const char *event)
Definition: lauxlib.c:823
bool operator<(const stack_iterator &r) const
Definition: sol.hpp:15606
~basic_reference() noexcept
Definition: sol.hpp:9420
int copy() const noexcept
Definition: sol.hpp:9336
int lua_c_noexcept_wrapper(lua_State *L) noexcept
Definition: sol.hpp:18208
meta::boolean< meta_detail::has_insert_after_test< T >::value > has_insert_after
Definition: sol.hpp:2158
constexpr bool is_table_like_v
Definition: sol.hpp:7820
yielding_t(Arg &&arg)
Definition: sol.hpp:6636
constexpr const char * not_enough_stack_space_userdata
Definition: sol.hpp:10408
std::unordered_map< reference, reference, reference_hash, reference_equals > auxiliary_keys
Definition: sol.hpp:21973
constexpr const int environment_index
Definition: sol.hpp:21551
int push(lua_State *L) const noexcept
Definition: sol.hpp:23157
constexpr Sig C::* resolve_v(std::false_type, Sig C::*mem_func_ptr)
Definition: sol.hpp:18075
protected_function_result safe_script(const string_view &code, const basic_environment< E > &env, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25367
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: sol.hpp:26419
static int push(lua_State *L, const char16_t *str)
Definition: sol.hpp:14317
table_proxy< const global_table &, detail::proxy_key_t< T > > operator[](T &&key) const
Definition: sol.hpp:25773
decltype(sol_lua_check(types< T >(), static_cast< lua_State * >(nullptr),-1, no_panic, std::declval< stack::record & >())) adl_sol_lua_check_test_t
Definition: sol.hpp:10363
basic_object< main_reference > main_object
Definition: forward.hpp:722
constexpr nested_tag_t nested_tag
Definition: sol.hpp:6900
void void_t
Definition: sol.hpp:877
basic_reference(lua_State *L, int index=-1) noexcept
Definition: sol.hpp:9405
unsafe_function_result unsafe_script(const string_view &code, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25452
union Value Value
constexpr bool is_constructor_v
Definition: sol.hpp:7864
table_proxy & operator=(std::initializer_list< T > other)&
Definition: sol.hpp:23061
static int push_sized(lua_State *L, const char *str, std::size_t len)
Definition: sol.hpp:14051
basic_thread(lua_State *L, lua_thread_state actualthread)
Definition: sol.hpp:25948
constexpr auto resolve(R fun_ptr(Args...)) -> R(*)(Args...)
Definition: sol.hpp:18086
LUALIB_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup)
Definition: lauxlib.c:904
std::size_t aligned_space_for(void *alignment=nullptr)
Definition: sol.hpp:9797
void pop() const noexcept
Definition: sol.hpp:9497
typename void_tuple_element< I, T >::type void_tuple_element_t
Definition: sol.hpp:1041
typename std::enable_if< E, T >::type enable_if_t
Definition: sol.hpp:4031
protected_function_result script_pass_on_error(lua_State *, protected_function_result result)
Definition: sol.hpp:24925
basic_function< reference, false > unsafe_function
Definition: forward.hpp:670
constexpr const auto enabler
Definition: sol.hpp:1720
lua_State * L
Definition: sol.hpp:25842
meta::boolean< has_erase_test< T >::value > has_erase
Definition: sol.hpp:19901
lua_CFunction c_function
Definition: sol.hpp:6784
static const char * libraries[]
Definition: MQTTVersion.c:56
this_environment(environment e)
Definition: sol.hpp:24509
decltype(sol_lua_push(static_cast< lua_State * >(nullptr), std::declval< Args >()...)) adl_sol_lua_push_test_t
Definition: sol.hpp:10374
static int push(lua_State *L, const char32_t *strb, const char32_t *stre)
Definition: sol.hpp:14366
static int push(lua_State *L, Arg0 &&arg0, Args &&...args)
Definition: sol.hpp:18422
#define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)
Definition: sol.hpp:3993
const std::string & short_demangle()
Definition: sol.hpp:8254
bool integer_value_fits(const T &value)
Definition: sol.hpp:13422
int index_fail(lua_State *L)
Definition: sol.hpp:21834
T & emplace(Args &&...args)
Definition: sol.hpp:5149
static int push(lua_State *L, const basic_string_view< Ch, Traits > &sv)
Definition: sol.hpp:14159
basic_object_base(T &&arg, Args &&...args)
Definition: sol.hpp:15304
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) const &
Definition: sol.hpp:5880
Used to represent an optional with no data; essentially a bool.
Definition: sol.hpp:4013
proxy_t value_type
Definition: sol.hpp:15510
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs)&
Definition: sol.hpp:4890
new_index_call_storage base_index
Definition: sol.hpp:21983
protected_function_result safe_script_file(const std::string &filename, const basic_environment< E > &env, Fx &&on_error, load_mode mode=load_mode::any)
Definition: sol.hpp:25389
lua_value(T &&value)
Definition: sol.hpp:24752
table create(int narr, int nrec, Key &&key, Value &&value, Args &&...args)
Definition: sol.hpp:23997
static int real_find_traits(std::false_type, lua_State *L)
Definition: sol.hpp:21346
SOL_TL_OPTIONAL_11_CONSTEXPR T & value()&
Definition: sol.hpp:5244
SOL_TL_OPTIONAL_11_CONSTEXPR const T & value() const &
Definition: sol.hpp:5255
bool operator>(const stack_iterator &r) const
Definition: sol.hpp:15610
bool less_than_or_equal_to_operator
Definition: sol.hpp:7898
LUA_API void lua_pushnumber(lua_State *L, lua_Number n)
Definition: lapi.c:481
enable_if_t< returns_void< T &&, U... >::value > enable_if_ret_void
Definition: sol.hpp:4137
#define LUA_TTABLE
Definition: lua.h:70
typename pop_front_type< Arg >::type pop_front_type_t
Definition: sol.hpp:979
constexpr T value_or(U &&u) const &
Definition: sol.hpp:5291
static int real_clear_traits(std::false_type, lua_State *L)
Definition: sol.hpp:21310
meta::conditional_t< std::is_void< void >::value, int, void > & first_type
Definition: sol.hpp:1046
Real * usertype_unique_allocate(lua_State *L, T **&pref, unique_destructor *&dx, unique_tag *&id)
Definition: sol.hpp:10063
LUA_API int lua_rawequal(lua_State *L, int index1, int index2)
Definition: lapi.c:304
lua_State * L
Definition: sol.hpp:15513
int default_exception_handler(lua_State *L, optional< const std::exception & >, string_view what)
Definition: sol.hpp:7927
T nested_type
Definition: sol.hpp:6866
bool is_stack(std::false_type) const
Definition: sol.hpp:15287
decltype(auto) overload(Args &&...args)
Definition: sol.hpp:11846
thread_status
Definition: sol.hpp:7152
static int push(lua_State *L, const char16_t *u16str, std::size_t sz)
Definition: sol.hpp:14285
static int push(lua_State *L, const table_proxy< Table, Key > &p)
Definition: sol.hpp:23263
int SOL_INTERNAL_UNSPECIALIZED_MARKER_
Definition: sol.hpp:7653
basic_metatable(lua_State *L, int index=-1)
Definition: sol.hpp:24074
protected_function_result operator()(Args &&...args)
Definition: sol.hpp:26229
constexpr bool operator==(const optional< T > &lhs, const optional< U > &rhs)
Compares two optional objects.
Definition: sol.hpp:5319
std::pair< object, object > kvp
Definition: sol.hpp:23291
const_reverse_iterator crbegin() const
Definition: sol.hpp:16039
static int call_(lua_State *L)
Definition: sol.hpp:21776
basic_table_core< b, stack_reference > stack_table_core
Definition: forward.hpp:633
call_status status() const noexcept
Definition: sol.hpp:15801
const nullopt_t nullopt((nullopt_t::init()))
static bool check(lua_State *L, int index, Handler &&handler, record &tracking)
Definition: sol.hpp:11763
static int push(lua_State *L, ref_index ri)
Definition: sol.hpp:14204
meta::conditional_t< std::is_array_v< R >, std::add_lvalue_reference_t< R >, R > return_type
Definition: sol.hpp:1494
int push_environment_of(const T &target)
Definition: sol.hpp:13475
stateless_reference(lua_State *L, const stateless_reference &r) noexcept
Definition: sol.hpp:9149
lua_State * lua_state() const noexcept
Definition: sol.hpp:24693
detail::invoke_result_t< U > map_or_else(F &&f, U &&u)&&
Definition: sol.hpp:4859
unsafe_function_result unsafe_script(const string_view &code, const basic_environment< E > &env, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:25435
static int real_insert_call(lua_State *L)
Definition: sol.hpp:21302
static int real_clear_call(lua_State *L)
Definition: sol.hpp:21314
static int real_pairs_traits(std::false_type, lua_State *L)
Definition: sol.hpp:21238
void pop() const noexcept
Definition: sol.hpp:8842
constexpr bool has_internal_marker_v
Definition: sol.hpp:7679
decltype(sol_lua_push(types< T >(), static_cast< lua_State * >(nullptr), std::declval< Args >()...)) adl_sol_lua_push_exact_test_t
Definition: sol.hpp:10377
LUA_NUMBER lua_Number
Definition: lua.h:90
constexpr auto invoke(Fn &&f, Args &&...args) noexcept(noexcept(std::mem_fn(f)(std::forward< Args >(args)...))) -> decltype(std::mem_fn(f)(std::forward< Args >(args)...))
Definition: sol.hpp:4078
indexed_insert(lua_reg_table &cont, int &idx)
Definition: sol.hpp:10275
basic_table_iterator operator++(int)
Definition: sol.hpp:23330
#define LUA_ERRRUN
Definition: lua.h:51
meta::boolean< has_traits_find_test< T >::value > has_traits_find
Definition: sol.hpp:19946
Ret invoke(types< Ret >, std::index_sequence< I >, std::ptrdiff_t n, detail::protected_handler< b, handler_t > &h) const
Definition: sol.hpp:19220
optional< T > SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F &&f)&&
Definition: sol.hpp:5783
constexpr bool boolean_v
Definition: sol.hpp:1692
static constexpr std::size_t size()
Definition: sol.hpp:794
#define LUA_TBOOLEAN
Definition: lua.h:66
static int push(lua_State *L, const char16_t *strb, const char16_t *stre)
Definition: sol.hpp:14289
basic_table_core(lua_State *L, detail::global_tag t) noexcept
Definition: sol.hpp:23613
iterator begin() const
Definition: sol.hpp:23691
void modify_unique_usertype_as(const stack_reference &obj, F &&f)
Definition: sol.hpp:10993
basic_table_core(lua_nil_t r) noexcept
Definition: sol.hpp:23688
protected_function_result & operator=(protected_function_result &&o) noexcept
Definition: sol.hpp:15783
struct TValue TValue
int push_userdata(lua_State *L, Arg &&arg, Args &&...args)
Definition: sol.hpp:10642
#define LUA_OPEQ
Definition: lua.h:222
void apply(std::index_sequence< I >, lua_State *L, Keys &&keys, Value &&value, int tableindex)
Definition: sol.hpp:14814
static int call(types< Fx >, meta::index_value< I >, types< R... >, types< Args... >, lua_State *L, int, int, overload_list &ol)
Definition: sol.hpp:18021
stack_aligned_unsafe_function stack_aligned_function
Definition: forward.hpp:691
table create_table(Name &&name, int narr=0, int nrec=0)
Definition: sol.hpp:25790
push_popper< top_level, T > push_pop(T &&x)
Definition: sol.hpp:9040
typename std::remove_reference< T >::type remove_reference_t
Definition: sol.hpp:4027
static int push(lua_State *L, const var_wrapper< T > &vw)
Definition: sol.hpp:18604
static int push(lua_State *L, const std::basic_string< Ch, Traits, Al > &str)
Definition: sol.hpp:14130
static int type_unique_cast(void *source_data, void *target_data, const string_view &ti, const string_view &rebind_ti)
Definition: sol.hpp:8495
basic_metatable(detail::no_safety_tag, T &&r) noexcept
Definition: sol.hpp:24048
std::vector< std::unique_ptr< binding_base > > storage
Definition: sol.hpp:21970
int push(lua_State *L, const as_args_t< T > &e)
Definition: sol.hpp:26385
static int push(lua_State *L, const protect_t< T > &pw)
Definition: sol.hpp:18563
int leftover_count() const
Definition: sol.hpp:26525
Definition: format.h:3618
int c_call_raw(std::false_type, lua_State *L)
Definition: sol.hpp:17554
object require_core(const std::string &key, Fx &&action, bool create_global=true)
Definition: sol.hpp:25059
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs)&&
disjunction
Definition: sol.hpp:5913
const char * make_chunk_name(const string_view &code, const std::string &chunkname, char(&basechunkname)[N])
Definition: sol.hpp:14934
static int push(lua_State *L, const wchar_t(&str)[N])
Definition: sol.hpp:14415
#define LUA_REFNIL
Definition: lauxlib.h:86
static int push(lua_State *L, function_arguments< T, Args... > &&fp)
Definition: sol.hpp:18472
bool operator()(const basic_reference< lb > &lhs, const stack_reference &rhs) const
Definition: sol.hpp:9601
bool valid(lua_State *) const noexcept
Definition: sol.hpp:9236
state_view & set_function(Key &&key, Args &&...args)
Definition: sol.hpp:25778
lua_value(reference r)
Definition: sol.hpp:24782
static const std::string & user_gc_metatable()
Definition: sol.hpp:8282
Definition: forward.hpp:603
int type_panic_string(lua_State *L, int index, type expected, type actual, string_view message="") noexcept(false)
Definition: sol.hpp:8631
optional< usertype_storage_base & > maybe_get_usertype_storage_base(lua_State *L, int index)
Definition: sol.hpp:22490
static int push(lua_State *L, light< T > l)
Definition: sol.hpp:13964
U map_or(F &&f, U &&u) const &&
map_or
Definition: sol.hpp:5849
char unique[50]
Definition: test9.c:41
constexpr optional disjunction(const optional &rhs) const &
disjunction
Definition: sol.hpp:4895
LUA_API int lua_checkstack(lua_State *L, int n)
Definition: lapi.c:98
static V get_one(std::integral_constant< std::size_t, I >, lua_State *L, int index, record &tracking)
Definition: sol.hpp:13159
constexpr const int lookup_failed_index
Definition: sol.hpp:21562
meta::conditional_t< std::is_array< T >::value, std::add_lvalue_reference_t< T >, T > array_return_type
Definition: sol.hpp:16150
int stack_clear()
Definition: sol.hpp:25608
table_proxy && operator=(std::initializer_list< T > other)&&
Definition: sol.hpp:23066
const std::string & demangle()
Definition: sol.hpp:8248
basic_lua_table(lua_State *L, const new_table &nt)
Definition: sol.hpp:24272
tie_t< std::remove_reference_t< Tn >... > tie(Tn &&...argn)
Definition: sol.hpp:9689
constexpr bool is_stack_based_v
Definition: sol.hpp:7712
basic_object & operator=(const base_type &b)
Definition: sol.hpp:15410
int stack_index() const noexcept
Definition: sol.hpp:9126
LUA_API int lua_gettable(lua_State *L, int idx)
Definition: lapi.c:640
int len
Definition: utf-8.c:46
factory_wrapper(Arg &&arg, Args &&...args)
Definition: sol.hpp:6319
basic_coroutine(lua_State *L, raw_index index, handler_t eh)
Definition: sol.hpp:26194
static int real_at_traits(std::false_type, lua_State *L)
Definition: sol.hpp:21190
constexpr bool has_value() const noexcept
Definition: sol.hpp:6102
protected_function_result & operator=(const protected_function_result &)=delete
type get_type() const noexcept
Definition: sol.hpp:8854
auto protect(T &&value)
Definition: sol.hpp:16568
constexpr bool is_member_object_v
Definition: sol.hpp:16539
Ret invoke(types< Ret >, std::index_sequence< I >, std::ptrdiff_t n) const
Definition: sol.hpp:18958
int fail_on_newindex(lua_State *L)
Definition: sol.hpp:23388
static int self_index_call(types< Bases... >, lua_State *L, usertype_storage_base &self)
Definition: sol.hpp:22155
usertype_proxy & operator=(std::initializer_list< T > other)&
Definition: sol.hpp:22872
meta::unqualified_t< Fq > uF
Definition: sol.hpp:21751
std::make_index_sequence< sizeof...(Functions)> indices
Definition: sol.hpp:18009
bool step_gc(int step_size_kilobytes)
Definition: sol.hpp:25640
lu_byte status
Definition: lstate.h:308
static int real_call(lua_State *L) noexcept(traits_type::is_noexcept)
Definition: sol.hpp:17736
std::u32string_view u32string_view
Definition: sol.hpp:1620
basic_userdata(lua_State *L, T &&r)
Definition: sol.hpp:26286
int linedefined
Definition: lua.h:477
error(const std::string &str)
Definition: sol.hpp:3886
LUA_API int lua_gettop(lua_State *L)
Definition: lapi.c:168
stack_table_core< false > stack_table
Definition: forward.hpp:640
std::remove_pointer_t< std::decay_t< Function > > function_type
Definition: sol.hpp:17927
push_popper_at(lua_State *luastate, int index=-1, int count=1)
Definition: sol.hpp:8963
std::pair< T, int > get_as_upvalues_using_function(lua_State *L, int function_index=-1)
Definition: sol.hpp:15005
std::ptrdiff_t idx
Definition: sol.hpp:23295
basic_table_core & set_function(Key &&key, Args &&...args)
Definition: sol.hpp:23932
constexpr auto resolve_i(types< Args... >, F &&f) -> decltype(resolve_i(types< R(Args...)>(), std::forward< F >(f)))
Definition: sol.hpp:18070
int msvc_is_ass_with_if_constexpr_push_enum(std::false_type, lua_State *, const T &)
Definition: sol.hpp:13452
decltype(auto) check_get(lua_State *L, int index=-lua_size< meta::unqualified_t< T >>::value)
Definition: sol.hpp:10823
static bool type_check_bases(types< Base, Args... >, const string_view &ti)
Definition: sol.hpp:8438
static int convert_into(lua_State *L, char *start, std::size_t, const char16_t *strb, const char16_t *stre)
Definition: sol.hpp:14260
int push() const noexcept
Definition: sol.hpp:22933
table create_table(int narr, int nrec, Key &&key, Value &&value, Args &&...args)
Definition: sol.hpp:25811
iterator end() const
Definition: sol.hpp:25574
basic_object(detail::no_safety_tag, lua_nil_t n)
Definition: sol.hpp:15338
nested(Arg0 &&arg0, Arg1 &&arg1, Args &&...args)
Definition: sol.hpp:6879
virtual void * data() override
Definition: sol.hpp:21764
std::string_view string_view
Definition: sol.hpp:1617
basic_table_core & raw_set(Args &&...args)
Definition: sol.hpp:23824
static void set_lua_state(lua_State *L)
Definition: sol.hpp:24743
auto as_container(T &&value)
Definition: sol.hpp:6976
new_table(int sequence_hint, int map_hint=0)
Definition: sol.hpp:7096
basic_userdata(const stack_reference &r)
Definition: sol.hpp:26279
static int push(lua_State *L, const std::variant< Tn... > &v)
Definition: sol.hpp:14589
static int real_get_traits(std::true_type, lua_State *L)
Definition: sol.hpp:21198
LUA_API const char * lua_typename(lua_State *L, int t)
Definition: lapi.c:266
static bool type_check_bases(types<>, const string_view &)
Definition: sol.hpp:8433
basic_table< base_type > base_t
Definition: sol.hpp:24034
bool unqualified_check(lua_State *L, int index=-lua_size< meta::unqualified_t< T >>::value)
Definition: sol.hpp:10719


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 04:02:47