Libsaki
Core library of Pancake Mahjong
sol.hpp
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 2022-06-25 08:14:19.151876 UTC
24 // This header was generated with sol v3.3.0 (revision eba86625)
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 #define SOL_VERSION_MAJOR 3
38 #define SOL_VERSION_MINOR 2
39 #define SOL_VERSION_PATCH 3
40 #define SOL_VERSION_STRING "3.2.3"
41 #define SOL_VERSION ((SOL_VERSION_MAJOR * 100000) + (SOL_VERSION_MINOR * 100) + (SOL_VERSION_PATCH))
42 
43 #define SOL_TOKEN_TO_STRING_POST_EXPANSION_I_(_TOKEN) #_TOKEN
44 #define SOL_TOKEN_TO_STRING_I_(_TOKEN) SOL_TOKEN_TO_STRING_POST_EXPANSION_I_(_TOKEN)
45 
46 #define SOL_CONCAT_TOKENS_POST_EXPANSION_I_(_LEFT, _RIGHT) _LEFT##_RIGHT
47 #define SOL_CONCAT_TOKENS_I_(_LEFT, _RIGHT) SOL_CONCAT_TOKENS_POST_EXPANSION_I_(_LEFT, _RIGHT)
48 
49 #define SOL_RAW_IS_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) != 0)
50 #define SOL_RAW_IS_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3) == 0)
51 #define SOL_RAW_IS_DEFAULT_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) > 3)
52 #define SOL_RAW_IS_DEFAULT_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3 OP_SYMBOL 3) < 0)
53 
54 #define SOL_IS_ON(OP_SYMBOL) SOL_RAW_IS_ON(OP_SYMBOL ## _I_)
55 #define SOL_IS_OFF(OP_SYMBOL) SOL_RAW_IS_OFF(OP_SYMBOL ## _I_)
56 #define SOL_IS_DEFAULT_ON(OP_SYMBOL) SOL_RAW_IS_DEFAULT_ON(OP_SYMBOL ## _I_)
57 #define SOL_IS_DEFAULT_OFF(OP_SYMBOL) SOL_RAW_IS_DEFAULT_OFF(OP_SYMBOL ## _I_)
58 
59 #define SOL_ON |
60 #define SOL_OFF ^
61 #define SOL_DEFAULT_ON +
62 #define SOL_DEFAULT_OFF -
63 
64 #if defined(SOL_BUILD_CXX_MODE)
65  #if (SOL_BUILD_CXX_MODE != 0)
66  #define SOL_BUILD_CXX_MODE_I_ SOL_ON
67  #else
68  #define SOL_BUILD_CXX_MODE_I_ SOL_OFF
69  #endif
70 #elif defined(__cplusplus)
71  #define SOL_BUILD_CXX_MODE_I_ SOL_DEFAULT_ON
72 #else
73  #define SOL_BUILD_CXX_MODE_I_ SOL_DEFAULT_OFF
74 #endif
75 
76 #if defined(SOL_BUILD_C_MODE)
77  #if (SOL_BUILD_C_MODE != 0)
78  #define SOL_BUILD_C_MODE_I_ SOL_ON
79  #else
80  #define SOL_BUILD_C_MODE_I_ SOL_OFF
81  #endif
82 #elif defined(__STDC__)
83  #define SOL_BUILD_C_MODE_I_ SOL_DEFAULT_ON
84 #else
85  #define SOL_BUILD_C_MODE_I_ SOL_DEFAULT_OFF
86 #endif
87 
88 #if SOL_IS_ON(SOL_BUILD_C_MODE)
89  #include <stddef.h>
90  #include <stdint.h>
91  #include <limits.h>
92 #else
93  #include <cstddef>
94  #include <cstdint>
95  #include <climits>
96 #endif
97 
98 #if defined(SOL_COMPILER_VCXX)
99  #if defined(SOL_COMPILER_VCXX != 0)
100  #define SOL_COMPILER_VCXX_I_ SOL_ON
101  #else
102  #define SOL_COMPILER_VCXX_I_ SOL_OFF
103  #endif
104 #elif defined(_MSC_VER)
105  #define SOL_COMPILER_VCXX_I_ SOL_DEFAULT_ON
106 #else
107  #define SOL_COMPILER_VCXX_I_ SOL_DEFAULT_OFF
108 #endif
109 
110 #if defined(SOL_COMPILER_GCC)
111  #if defined(SOL_COMPILER_GCC != 0)
112  #define SOL_COMPILER_GCC_I_ SOL_ON
113  #else
114  #define SOL_COMPILER_GCC_I_ SOL_OFF
115  #endif
116 #elif defined(__GNUC__)
117  #define SOL_COMPILER_GCC_I_ SOL_DEFAULT_ON
118 #else
119  #define SOL_COMPILER_GCC_I_ SOL_DEFAULT_OFF
120 #endif
121 
122 #if defined(SOL_COMPILER_CLANG)
123  #if defined(SOL_COMPILER_CLANG != 0)
124  #define SOL_COMPILER_CLANG_I_ SOL_ON
125  #else
126  #define SOL_COMPILER_CLANG_I_ SOL_OFF
127  #endif
128 #elif defined(__clang__)
129  #define SOL_COMPILER_CLANG_I_ SOL_DEFAULT_ON
130 #else
131  #define SOL_COMPILER_CLANG_I_ SOL_DEFAULT_OFF
132 #endif
133 
134 #if defined(SOL_COMPILER_EDG)
135  #if defined(SOL_COMPILER_EDG != 0)
136  #define SOL_COMPILER_EDG_I_ SOL_ON
137  #else
138  #define SOL_COMPILER_EDG_I_ SOL_OFF
139  #endif
140 #else
141  #define SOL_COMPILER_EDG_I_ SOL_DEFAULT_OFF
142 #endif
143 
144 #if defined(SOL_COMPILER_MINGW)
145  #if (SOL_COMPILER_MINGW != 0)
146  #define SOL_COMPILER_MINGW_I_ SOL_ON
147  #else
148  #define SOL_COMPILER_MINGW_I_ SOL_OFF
149  #endif
150 #elif defined(__MINGW32__)
151  #define SOL_COMPILER_MINGW_I_ SOL_DEFAULT_ON
152 #else
153  #define SOL_COMPILER_MINGW_I_ SOL_DEFAULT_OFF
154 #endif
155 
156 #if SIZE_MAX <= 0xFFFFULL
157  #define SOL_PLATFORM_X16_I_ SOL_ON
158  #define SOL_PLATFORM_X86_I_ SOL_OFF
159  #define SOL_PLATFORM_X64_I_ SOL_OFF
160 #elif SIZE_MAX <= 0xFFFFFFFFULL
161  #define SOL_PLATFORM_X16_I_ SOL_OFF
162  #define SOL_PLATFORM_X86_I_ SOL_ON
163  #define SOL_PLATFORM_X64_I_ SOL_OFF
164 #else
165  #define SOL_PLATFORM_X16_I_ SOL_OFF
166  #define SOL_PLATFORM_X86_I_ SOL_OFF
167  #define SOL_PLATFORM_X64_I_ SOL_ON
168 #endif
169 
170 #define SOL_PLATFORM_ARM32_I_ SOL_OFF
171 #define SOL_PLATFORM_ARM64_I_ SOL_OFF
172 
173 #if defined(SOL_PLATFORM_WINDOWS)
174  #if (SOL_PLATFORM_WINDOWS != 0)
175  #define SOL_PLATFORM_WINDOWS_I_ SOL_ON
176  #else
177  #define SOL_PLATFORM_WINDOWS_I_ SOL_OFF
178  #endif
179 #elif defined(_WIN32)
180  #define SOL_PLATFORM_WINDOWS_I_ SOL_DEFAULT_ON
181 #else
182  #define SOL_PLATFORM_WINDOWS_I_ SOL_DEFAULT_OFF
183 #endif
184 
185 #if defined(SOL_PLATFORM_CYGWIN)
186  #if (SOL_PLATFORM_CYGWIN != 0)
187  #define SOL_PLATFORM_CYGWIN_I_ SOL_ON
188  #else
189  #define SOL_PLATFORM_CYGWIN_I_ SOL_ON
190  #endif
191 #elif defined(__CYGWIN__)
192  #define SOL_PLATFORM_CYGWIN_I_ SOL_DEFAULT_ON
193 #else
194  #define SOL_PLATFORM_CYGWIN_I_ SOL_DEFAULT_OFF
195 #endif
196 
197 #if defined(SOL_PLATFORM_APPLE)
198  #if (SOL_PLATFORM_APPLE != 0)
199  #define SOL_PLATFORM_APPLE_I_ SOL_ON
200  #else
201  #define SOL_PLATFORM_APPLE_I_ SOL_OFF
202  #endif
203 #elif defined(__APPLE__)
204  #define SOL_PLATFORM_APPLE_I_ SOL_DEFAULT_ON
205 #else
206  #define SOL_PLATFORM_APPLE_I_ SOL_DEFAULT_OFF
207 #endif
208 
209 #if defined(SOL_PLATFORM_UNIX)
210  #if (SOL_PLATFORM_UNIX != 0)
211  #define SOL_PLATFORM_UNIXLIKE_I_ SOL_ON
212  #else
213  #define SOL_PLATFORM_UNIXLIKE_I_ SOL_OFF
214  #endif
215 #elif defined(__unix__)
216  #define SOL_PLATFORM_UNIXLIKE_I_ SOL_DEFAUKT_ON
217 #else
218  #define SOL_PLATFORM_UNIXLIKE_I_ SOL_DEFAULT_OFF
219 #endif
220 
221 #if defined(SOL_PLATFORM_LINUX)
222  #if (SOL_PLATFORM_LINUX != 0)
223  #define SOL_PLATFORM_LINUXLIKE_I_ SOL_ON
224  #else
225  #define SOL_PLATFORM_LINUXLIKE_I_ SOL_OFF
226  #endif
227 #elif defined(__LINUX__)
228  #define SOL_PLATFORM_LINUXLIKE_I_ SOL_DEFAUKT_ON
229 #else
230  #define SOL_PLATFORM_LINUXLIKE_I_ SOL_DEFAULT_OFF
231 #endif
232 
233 #define SOL_PLATFORM_APPLE_IPHONE_I_ SOL_OFF
234 #define SOL_PLATFORM_BSDLIKE_I_ SOL_OFF
235 
236 #if defined(SOL_IN_DEBUG_DETECTED)
237  #if SOL_IN_DEBUG_DETECTED != 0
238  #define SOL_DEBUG_BUILD_I_ SOL_ON
239  #else
240  #define SOL_DEBUG_BUILD_I_ SOL_OFF
241  #endif
242 #elif !defined(NDEBUG)
243  #if SOL_IS_ON(SOL_COMPILER_VCXX) && defined(_DEBUG)
244  #define SOL_DEBUG_BUILD_I_ SOL_ON
245  #elif (SOL_IS_ON(SOL_COMPILER_CLANG) || SOL_IS_ON(SOL_COMPILER_GCC)) && !defined(__OPTIMIZE__)
246  #define SOL_DEBUG_BUILD_I_ SOL_ON
247  #else
248  #define SOL_DEBUG_BUILD_I_ SOL_OFF
249  #endif
250 #else
251  #define SOL_DEBUG_BUILD_I_ SOL_DEFAULT_OFF
252 #endif // We are in a debug mode of some sort
253 
254 #if defined(SOL_NO_EXCEPTIONS)
255  #if (SOL_NO_EXCEPTIONS != 0)
256  #define SOL_EXCEPTIONS_I_ SOL_OFF
257  #else
258  #define SOL_EXCEPTIONS_I_ SOL_ON
259  #endif
260 #elif SOL_IS_ON(SOL_COMPILER_VCXX)
261  #if !defined(_CPPUNWIND)
262  #define SOL_EXCEPTIONS_I_ SOL_OFF
263  #else
264  #define SOL_EXCEPTIONS_I_ SOL_ON
265  #endif
266 #elif SOL_IS_ON(SOL_COMPILER_CLANG) || SOL_IS_ON(SOL_COMPILER_GCC)
267  #if !defined(__EXCEPTIONS)
268  #define SOL_EXCEPTIONS_I_ SOL_OFF
269  #else
270  #define SOL_EXCEPTIONS_I_ SOL_ON
271  #endif
272 #else
273  #define SOL_EXCEPTIONS_I_ SOL_DEFAULT_ON
274 #endif
275 
276 #if defined(SOL_NO_RTTI)
277  #if (SOL_NO_RTTI != 0)
278  #define SOL_RTTI_I_ SOL_OFF
279  #else
280  #define SOL_RTTI_I_ SOL_ON
281  #endif
282 #elif SOL_IS_ON(SOL_COMPILER_VCXX)
283  #if !defined(_CPPRTTI)
284  #define SOL_RTTI_I_ SOL_OFF
285  #else
286  #define SOL_RTTI_I_ SOL_ON
287  #endif
288 #elif SOL_IS_ON(SOL_COMPILER_CLANG) || SOL_IS_ON(SOL_COMPILER_GCC)
289  #if !defined(__GXX_RTTI)
290  #define SOL_RTTI_I_ SOL_OFF
291  #else
292  #define SOL_RTTI_I_ SOL_ON
293  #endif
294 #else
295  #define SOL_RTTI_I_ SOL_DEFAULT_ON
296 #endif
297 
298 #if defined(SOL_NO_THREAD_LOCAL)
299  #if SOL_NO_THREAD_LOCAL != 0
300  #define SOL_USE_THREAD_LOCAL_I_ SOL_OFF
301  #else
302  #define SOL_USE_THREAD_LOCAL_I_ SOL_ON
303  #endif
304 #else
305  #define SOL_USE_THREAD_LOCAL_I_ SOL_DEFAULT_ON
306 #endif // thread_local keyword is bjorked on some platforms
307 
308 #if defined(SOL_ALL_SAFETIES_ON)
309  #if SOL_ALL_SAFETIES_ON != 0
310  #define SOL_ALL_SAFETIES_ON_I_ SOL_ON
311  #else
312  #define SOL_ALL_SAFETIES_ON_I_ SOL_OFF
313  #endif
314 #else
315  #define SOL_ALL_SAFETIES_ON_I_ SOL_DEFAULT_OFF
316 #endif
317 
318 #if defined(SOL_SAFE_GETTER)
319  #if SOL_SAFE_GETTER != 0
320  #define SOL_SAFE_GETTER_I_ SOL_ON
321  #else
322  #define SOL_SAFE_GETTER_I_ SOL_OFF
323  #endif
324 #else
325  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
326  #define SOL_SAFE_GETTER_I_ SOL_ON
327  #elif SOL_IS_ON(SOL_DEBUG_BUILD)
328  #define SOL_SAFE_GETTER_I_ SOL_DEFAULT_ON
329  #else
330  #define SOL_SAFE_GETTER_I_ SOL_DEFAULT_OFF
331  #endif
332 #endif
333 
334 #if defined(SOL_SAFE_USERTYPE)
335  #if SOL_SAFE_USERTYPE != 0
336  #define SOL_SAFE_USERTYPE_I_ SOL_ON
337  #else
338  #define SOL_SAFE_USERTYPE_I_ SOL_OFF
339  #endif
340 #else
341  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
342  #define SOL_SAFE_USERTYPE_I_ SOL_ON
343  #elif SOL_IS_ON(SOL_DEBUG_BUILD)
344  #define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_ON
345  #else
346  #define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_OFF
347  #endif
348 #endif
349 
350 #if defined(SOL_SAFE_REFERENCES)
351  #if SOL_SAFE_REFERENCES != 0
352  #define SOL_SAFE_REFERENCES_I_ SOL_ON
353  #else
354  #define SOL_SAFE_REFERENCES_I_ SOL_OFF
355  #endif
356 #else
357  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
358  #define SOL_SAFE_REFERENCES_I_ SOL_ON
359  #elif SOL_IS_ON(SOL_DEBUG_BUILD)
360  #define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_ON
361  #else
362  #define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_OFF
363  #endif
364 #endif
365 
366 #if defined(SOL_SAFE_FUNCTIONS)
367  #if SOL_SAFE_FUNCTIONS != 0
368  #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON
369  #else
370  #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_OFF
371  #endif
372 #elif defined (SOL_SAFE_FUNCTION_OBJECTS)
373  #if SOL_SAFE_FUNCTION_OBJECTS != 0
374  #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON
375  #else
376  #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_OFF
377  #endif
378 #else
379  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
380  #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON
381  #elif SOL_IS_ON(SOL_DEBUG_BUILD)
382  #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_ON
383  #else
384  #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_OFF
385  #endif
386 #endif
387 
388 #if defined(SOL_SAFE_FUNCTION_CALLS)
389  #if SOL_SAFE_FUNCTION_CALLS != 0
390  #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON
391  #else
392  #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_OFF
393  #endif
394 #else
395  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
396  #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON
397  #elif SOL_IS_ON(SOL_DEBUG_BUILD)
398  #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_ON
399  #else
400  #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_OFF
401  #endif
402 #endif
403 
404 #if defined(SOL_SAFE_PROXIES)
405  #if SOL_SAFE_PROXIES != 0
406  #define SOL_SAFE_PROXIES_I_ SOL_ON
407  #else
408  #define SOL_SAFE_PROXIES_I_ SOL_OFF
409  #endif
410 #else
411  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
412  #define SOL_SAFE_PROXIES_I_ SOL_ON
413  #elif SOL_IS_ON(SOL_DEBUG_BUILD)
414  #define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_ON
415  #else
416  #define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_OFF
417  #endif
418 #endif
419 
420 #if defined(SOL_SAFE_NUMERICS)
421  #if SOL_SAFE_NUMERICS != 0
422  #define SOL_SAFE_NUMERICS_I_ SOL_ON
423  #else
424  #define SOL_SAFE_NUMERICS_I_ SOL_OFF
425  #endif
426 #else
427  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
428  #define SOL_SAFE_NUMERICS_I_ SOL_ON
429  #elif SOL_IS_ON(SOL_DEBUG_BUILD)
430  #define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_ON
431  #else
432  #define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_OFF
433  #endif
434 #endif
435 
436 #if defined(SOL_ALL_INTEGER_VALUES_FIT)
437  #if (SOL_ALL_INTEGER_VALUES_FIT != 0)
438  #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_ON
439  #else
440  #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_OFF
441  #endif
442 #elif !SOL_IS_DEFAULT_OFF(SOL_SAFE_NUMERICS) && SOL_IS_OFF(SOL_SAFE_NUMERICS)
443  // if numerics is intentionally turned off, flip this on
444  #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_DEFAULT_ON
445 #else
446  // default to off
447  #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_DEFAULT_OFF
448 #endif
449 
450 #if defined(SOL_SAFE_STACK_CHECK)
451  #if SOL_SAFE_STACK_CHECK != 0
452  #define SOL_SAFE_STACK_CHECK_I_ SOL_ON
453  #else
454  #define SOL_SAFE_STACK_CHECK_I_ SOL_OFF
455  #endif
456 #else
457  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
458  #define SOL_SAFE_STACK_CHECK_I_ SOL_ON
459  #elif SOL_IS_ON(SOL_DEBUG_BUILD)
460  #define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_ON
461  #else
462  #define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_OFF
463  #endif
464 #endif
465 
466 #if defined(SOL_NO_CHECK_NUMBER_PRECISION)
467  #if SOL_NO_CHECK_NUMBER_PRECISION != 0
468  #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_OFF
469  #else
470  #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON
471  #endif
472 #elif defined(SOL_NO_CHECKING_NUMBER_PRECISION)
473  #if SOL_NO_CHECKING_NUMBER_PRECISION != 0
474  #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_OFF
475  #else
476  #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON
477  #endif
478 #else
479  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
480  #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON
481  #elif SOL_IS_ON(SOL_SAFE_NUMERICS)
482  #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON
483  #elif SOL_IS_ON(SOL_DEBUG_BUILD)
484  #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_ON
485  #else
486  #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_OFF
487  #endif
488 #endif
489 
490 #if defined(SOL_STRINGS_ARE_NUMBERS)
491  #if (SOL_STRINGS_ARE_NUMBERS != 0)
492  #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_ON
493  #else
494  #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_OFF
495  #endif
496 #else
497  #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_DEFAULT_OFF
498 #endif
499 
500 #if defined(SOL_ENABLE_INTEROP)
501  #if SOL_ENABLE_INTEROP != 0
502  #define SOL_USE_INTEROP_I_ SOL_ON
503  #else
504  #define SOL_USE_INTEROP_I_ SOL_OFF
505  #endif
506 #elif defined(SOL_USE_INTEROP)
507  #if SOL_USE_INTEROP != 0
508  #define SOL_USE_INTEROP_I_ SOL_ON
509  #else
510  #define SOL_USE_INTEROP_I_ SOL_OFF
511  #endif
512 #else
513  #define SOL_USE_INTEROP_I_ SOL_DEFAULT_OFF
514 #endif
515 
516 #if defined(SOL_NO_NIL)
517  #if (SOL_NO_NIL != 0)
518  #define SOL_NIL_I_ SOL_OFF
519  #else
520  #define SOL_NIL_I_ SOL_ON
521  #endif
522 #elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) || defined(__OBJC__) || defined(nil)
523  #define SOL_NIL_I_ SOL_DEFAULT_OFF
524 #else
525  #define SOL_NIL_I_ SOL_DEFAULT_ON
526 #endif
527 
528 #if defined(SOL_USERTYPE_TYPE_BINDING_INFO)
529  #if (SOL_USERTYPE_TYPE_BINDING_INFO != 0)
530  #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_ON
531  #else
532  #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_OFF
533  #endif
534 #else
535  #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_DEFAULT_ON
536 #endif // We should generate a my_type.__type table with lots of class information for usertypes
537 
538 #if defined(SOL_AUTOMAGICAL_TYPES_BY_DEFAULT)
539  #if (SOL_AUTOMAGICAL_TYPES_BY_DEFAULT != 0)
540  #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON
541  #else
542  #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF
543  #endif
544 #elif defined(SOL_DEFAULT_AUTOMAGICAL_USERTYPES)
545  #if (SOL_DEFAULT_AUTOMAGICAL_USERTYPES != 0)
546  #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON
547  #else
548  #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF
549  #endif
550 #else
551  #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_DEFAULT_ON
552 #endif // make is_automagical on/off by default
553 
554 #if defined(SOL_STD_VARIANT)
555  #if (SOL_STD_VARIANT != 0)
556  #define SOL_STD_VARIANT_I_ SOL_ON
557  #else
558  #define SOL_STD_VARIANT_I_ SOL_OFF
559  #endif
560 #else
561  #if SOL_IS_ON(SOL_COMPILER_CLANG) && SOL_IS_ON(SOL_PLATFORM_APPLE)
562  #if defined(__has_include)
563  #if __has_include(<variant>)
564  #define SOL_STD_VARIANT_I_ SOL_DEFAULT_ON
565  #else
566  #define SOL_STD_VARIANT_I_ SOL_DEFAULT_OFF
567  #endif
568  #else
569  #define SOL_STD_VARIANT_I_ SOL_DEFAULT_OFF
570  #endif
571  #else
572  #define SOL_STD_VARIANT_I_ SOL_DEFAULT_ON
573  #endif
574 #endif // make is_automagical on/off by default
575 
576 #if defined(SOL_NOEXCEPT_FUNCTION_TYPE)
577  #if (SOL_NOEXCEPT_FUNCTION_TYPE != 0)
578  #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON
579  #else
580  #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF
581  #endif
582 #else
583  #if defined(__cpp_noexcept_function_type)
584  #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON
585  #elif SOL_IS_ON(SOL_COMPILER_VCXX) && (defined(_MSVC_LANG) && (_MSVC_LANG < 201403L))
586  // There is a bug in the VC++ compiler??
587  // on /std:c++latest under x86 conditions (VS 15.5.2),
588  // compiler errors are tossed for noexcept markings being on function types
589  // that are identical in every other way to their non-noexcept marked types function types...
590  // VS 2019: There is absolutely a bug.
591  #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF
592  #else
593  #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_DEFAULT_ON
594  #endif
595 #endif // noexcept is part of a function's type
596 
597 #if defined(SOL_STACK_STRING_OPTIMIZATION_SIZE) && SOL_STACK_STRING_OPTIMIZATION_SIZE > 0
598  #define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ SOL_STACK_STRING_OPTIMIZATION_SIZE
599 #else
600  #define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ 1024
601 #endif
602 
603 #if defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0
604  #define SOL_ID_SIZE_I_ SOL_ID_SIZE
605 #else
606  #define SOL_ID_SIZE_I_ 512
607 #endif
608 
609 #if defined(LUA_IDSIZE) && LUA_IDSIZE > 0
610  #define SOL_FILE_ID_SIZE_I_ LUA_IDSIZE
611 #elif defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0
612  #define SOL_FILE_ID_SIZE_I_ SOL_FILE_ID_SIZE
613 #else
614  #define SOL_FILE_ID_SIZE_I_ 2048
615 #endif
616 
617 #if defined(SOL_PRINT_ERRORS)
618  #if (SOL_PRINT_ERRORS != 0)
619  #define SOL_PRINT_ERRORS_I_ SOL_ON
620  #else
621  #define SOL_PRINT_ERRORS_I_ SOL_OFF
622  #endif
623 #else
624  #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
625  #define SOL_PRINT_ERRORS_I_ SOL_ON
626  #elif SOL_IS_ON(SOL_DEBUG_BUILD)
627  #define SOL_PRINT_ERRORS_I_ SOL_DEFAULT_ON
628  #else
629  #define SOL_PRINT_ERRORS_I_ SOL_OFF
630  #endif
631 #endif
632 
633 #if defined(SOL_DEFAULT_PASS_ON_ERROR)
634  #if (SOL_DEFAULT_PASS_ON_ERROR != 0)
635  #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_ON
636  #else
637  #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_OFF
638  #endif
639 #else
640  #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_DEFAULT_OFF
641 #endif
642 
643 #if defined(SOL_USING_CXX_LUA)
644  #if (SOL_USING_CXX_LUA != 0)
645  #define SOL_USE_CXX_LUA_I_ SOL_ON
646  #else
647  #define SOL_USE_CXX_LUA_I_ SOL_OFF
648  #endif
649 #elif defined(SOL_USE_CXX_LUA)
650  #if (SOL_USE_CXX_LUA != 0)
651  #define SOL_USE_CXX_LUA_I_ SOL_ON
652  #else
653  #define SOL_USE_CXX_LUA_I_ SOL_OFF
654  #endif
655 #else
656  #define SOL_USE_CXX_LUA_I_ SOL_DEFAULT_OFF
657 #endif
658 
659 #if defined(SOL_USING_CXX_LUAJIT)
660  #if (SOL_USING_CXX_LUA != 0)
661  #define SOL_USE_CXX_LUAJIT_I_ SOL_ON
662  #else
663  #define SOL_USE_CXX_LUAJIT_I_ SOL_OFF
664  #endif
665 #elif defined(SOL_USE_CXX_LUAJIT)
666  #if (SOL_USE_CXX_LUA != 0)
667  #define SOL_USE_CXX_LUAJIT_I_ SOL_ON
668  #else
669  #define SOL_USE_CXX_LUAJIT_I_ SOL_OFF
670  #endif
671 #else
672  #define SOL_USE_CXX_LUAJIT_I_ SOL_DEFAULT_OFF
673 #endif
674 
675 #if defined(SOL_NO_LUA_HPP)
676  #if (SOL_NO_LUA_HPP != 0)
677  #define SOL_USE_LUA_HPP_I_ SOL_OFF
678  #else
679  #define SOL_USE_LUA_HPP_I_ SOL_ON
680  #endif
681 #elif defined(SOL_USING_CXX_LUA)
682  #define SOL_USE_LUA_HPP_I_ SOL_OFF
683 #elif defined(__has_include)
684  #if __has_include(<lua.hpp>)
685  #define SOL_USE_LUA_HPP_I_ SOL_ON
686  #else
687  #define SOL_USE_LUA_HPP_I_ SOL_OFF
688  #endif
689 #else
690  #define SOL_USE_LUA_HPP_I_ SOL_DEFAULT_ON
691 #endif
692 
693 #if defined(SOL_CONTAINERS_START)
694  #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START
695 #elif defined(SOL_CONTAINERS_START_INDEX)
696  #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START_INDEX
697 #elif defined(SOL_CONTAINER_START_INDEX)
698  #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINER_START_INDEX
699 #else
700  #define SOL_CONTAINER_START_INDEX_I_ 1
701 #endif
702 
703 #if defined (SOL_NO_MEMORY_ALIGNMENT)
704  #if (SOL_NO_MEMORY_ALIGNMENT != 0)
705  #define SOL_ALIGN_MEMORY_I_ SOL_OFF
706  #else
707  #define SOL_ALIGN_MEMORY_I_ SOL_ON
708  #endif
709 #else
710  #define SOL_ALIGN_MEMORY_I_ SOL_DEFAULT_ON
711 #endif
712 
713 #if defined(SOL_USE_BOOST)
714  #if (SOL_USE_BOOST != 0)
715  #define SOL_USE_BOOST_I_ SOL_ON
716  #else
717  #define SOL_USE_BOOST_I_ SOL_OFF
718  #endif
719 #else
720  #define SOL_USE_BOOST_I_ SOL_DEFAULT_OFF
721 #endif
722 
723 #if defined(SOL_USE_UNSAFE_BASE_LOOKUP)
724  #if (SOL_USE_UNSAFE_BASE_LOOKUP != 0)
725  #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_ON
726  #else
727  #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_OFF
728  #endif
729 #else
730  #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_DEFAULT_OFF
731 #endif
732 
733 #if defined(SOL_INSIDE_UNREAL)
734  #if (SOL_INSIDE_UNREAL != 0)
735  #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_ON
736  #else
737  #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_OFF
738  #endif
739 #else
740  #if defined(UE_BUILD_DEBUG) || defined(UE_BUILD_DEVELOPMENT) || defined(UE_BUILD_TEST) || defined(UE_BUILD_SHIPPING) || defined(UE_SERVER)
741  #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_DEFAULT_ON
742  #else
743  #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_DEFAULT_OFF
744  #endif
745 #endif
746 
747 #if defined(SOL_NO_COMPAT)
748  #if (SOL_NO_COMPAT != 0)
749  #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_OFF
750  #else
751  #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_ON
752  #endif
753 #else
754  #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_DEFAULT_ON
755 #endif
756 
757 #if defined(SOL_GET_FUNCTION_POINTER_UNSAFE)
758  #if (SOL_GET_FUNCTION_POINTER_UNSAFE != 0)
759  #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_ON
760  #else
761  #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_OFF
762  #endif
763 #else
764  #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_DEFAULT_OFF
765 #endif
766 
767 #if defined(SOL_FUNCTION_CALL_VALUE_SEMANTICS)
768  #if (SOL_FUNCTION_CALL_VALUE_SEMANTICS != 0)
769  #define SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_ SOL_ON
770  #else
771  #define SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_ SOL_OFF
772  #endif
773 #else
774  #define SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_ SOL_DEFAULT_OFF
775 #endif
776 
777 #if defined(SOL_MINGW_CCTYPE_IS_POISONED)
778  #if (SOL_MINGW_CCTYPE_IS_POISONED != 0)
779  #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_ON
780  #else
781  #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_OFF
782  #endif
783 #elif SOL_IS_ON(SOL_COMPILER_MINGW) && defined(__GNUC__) && (__GNUC__ < 6)
784  // MinGW is off its rocker in some places...
785  #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_DEFAULT_ON
786 #else
787  #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_DEFAULT_OFF
788 #endif
789 
790 #if defined(SOL_CHAR8_T)
791  #if (SOL_CHAR8_T != 0)
792  #define SOL_CHAR8_T_I_ SOL_ON
793  #else
794  #define SOL_CHAR8_T_I_ SOL_OFF
795  #endif
796 #else
797  #if defined(__cpp_char8_t)
798  #define SOL_CHAR8_T_I_ SOL_DEFAULT_ON
799  #else
800  #define SOL_CHAR8_T_I_ SOL_DEFAULT_OFF
801  #endif
802 #endif
803 
804 #if SOL_IS_ON(SOL_USE_BOOST)
805  #include <boost/version.hpp>
806 
807  #if BOOST_VERSION >= 107500 // Since Boost 1.75.0 boost::none is constexpr
808  #define SOL_BOOST_NONE_CONSTEXPR_I_ constexpr
809  #else
810  #define SOL_BOOST_NONE_CONSTEXPR_I_ const
811  #endif // BOOST_VERSION
812 #else
813  // assume boost isn't using a garbage version
814  #define SOL_BOOST_NONE_CONSTEXPR_I_ constexpr
815 #endif
816 
817 #if defined(SOL2_CI)
818  #if (SOL2_CI != 0)
819  #define SOL2_CI_I_ SOL_ON
820  #else
821  #define SOL2_CI_I_ SOL_OFF
822  #endif
823 #else
824  #define SOL2_CI_I_ SOL_DEFAULT_OFF
825 #endif
826 
827 #if defined(SOL_C_ASSERT)
828  #define SOL_USER_C_ASSERT_I_ SOL_ON
829 #else
830  #define SOL_USER_C_ASSERT_I_ SOL_DEFAULT_OFF
831 #endif
832 
833 #if defined(SOL_M_ASSERT)
834  #define SOL_USER_M_ASSERT_I_ SOL_ON
835 #else
836  #define SOL_USER_M_ASSERT_I_ SOL_DEFAULT_OFF
837 #endif
838 
839 // beginning of sol/prologue.hpp
840 
841 #if defined(SOL_PROLOGUE_I_)
842  #error "[sol2] Library Prologue was already included in translation unit and not properly ended with an epilogue."
843 #endif
844 
845 #define SOL_PROLOGUE_I_ 1
846 
847 #if SOL_IS_ON(SOL_BUILD_CXX_MODE)
848  #define _FWD(...) static_cast<decltype( __VA_ARGS__ )&&>( __VA_ARGS__ )
849 
850  #if SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
851  #define _MOVE(...) static_cast<__typeof( __VA_ARGS__ )&&>( __VA_ARGS__ )
852  #else
853  #include <type_traits>
854 
855  #define _MOVE(...) static_cast<::std::remove_reference_t<( __VA_ARGS__ )>&&>( __VA_OPT__(,) )
856  #endif
857 #endif
858 
859 // end of sol/prologue.hpp
860 
861 // beginning of sol/epilogue.hpp
862 
863 #if !defined(SOL_PROLOGUE_I_)
864  #error "[sol2] Library Prologue is missing from this translation unit."
865 #else
866  #undef SOL_PROLOGUE_I_
867 #endif
868 
869 #if SOL_IS_ON(SOL_BUILD_CXX_MODE)
870  #undef _FWD
871  #undef _MOVE
872 #endif
873 
874 // end of sol/epilogue.hpp
875 
876 // beginning of sol/detail/build_version.hpp
877 
878 #if defined(SOL_DLL)
879  #if (SOL_DLL != 0)
880  #define SOL_DLL_I_ SOL_ON
881  #else
882  #define SOL_DLL_I_ SOL_OFF
883  #endif
884 #elif SOL_IS_ON(SOL_COMPILER_VCXX) && (defined(DLL_) || defined(_DLL))
885  #define SOL_DLL_I_ SOL_DEFAULT_ON
886 #else
887  #define SOL_DLL_I_ SOL_DEFAULT_OFF
888 #endif // DLL definition
889 
890 #if defined(SOL_HEADER_ONLY)
891  #if (SOL_HEADER_ONLY != 0)
892  #define SOL_HEADER_ONLY_I_ SOL_ON
893  #else
894  #define SOL_HEADER_ONLY_I_ SOL_OFF
895  #endif
896 #else
897  #define SOL_HEADER_ONLY_I_ SOL_DEFAULT_OFF
898 #endif // Header only library
899 
900 #if defined(SOL_BUILD)
901  #if (SOL_BUILD != 0)
902  #define SOL_BUILD_I_ SOL_ON
903  #else
904  #define SOL_BUILD_I_ SOL_OFF
905  #endif
906 #elif SOL_IS_ON(SOL_HEADER_ONLY)
907  #define SOL_BUILD_I_ SOL_DEFAULT_OFF
908 #else
909  #define SOL_BUILD_I_ SOL_DEFAULT_ON
910 #endif
911 
912 #if defined(SOL_UNITY_BUILD)
913  #if (SOL_UNITY_BUILD != 0)
914  #define SOL_UNITY_BUILD_I_ SOL_ON
915  #else
916  #define SOL_UNITY_BUILD_I_ SOL_OFF
917  #endif
918 #else
919  #define SOL_UNITY_BUILD_I_ SOL_DEFAULT_OFF
920 #endif // Header only library
921 
922 #if defined(SOL_C_FUNCTION_LINKAGE)
923  #define SOL_C_FUNCTION_LINKAGE_I_ SOL_C_FUNCTION_LINKAGE
924 #else
925  #if SOL_IS_ON(SOL_BUILD_CXX_MODE)
926  // C++
927  #define SOL_C_FUNCTION_LINKAGE_I_ extern "C"
928  #else
929  // normal
930  #define SOL_C_FUNCTION_LINKAGE_I_
931  #endif // C++ or not
932 #endif // Linkage specification for C functions
933 
934 #if defined(SOL_API_LINKAGE)
935  #define SOL_API_LINKAGE_I_ SOL_API_LINKAGE
936 #else
937  #if SOL_IS_ON(SOL_DLL)
938  #if SOL_IS_ON(SOL_COMPILER_VCXX) || SOL_IS_ON(SOL_PLATFORM_WINDOWS) || SOL_IS_ON(SOL_PLATFORM_CYGWIN)
939  // MSVC Compiler; or, Windows, or Cygwin platforms
940  #if SOL_IS_ON(SOL_BUILD)
941  // Building the library
942  #if SOL_IS_ON(SOL_COMPILER_GCC)
943  // Using GCC
944  #define SOL_API_LINKAGE_I_ __attribute__((dllexport))
945  #else
946  // Using Clang, MSVC, etc...
947  #define SOL_API_LINKAGE_I_ __declspec(dllexport)
948  #endif
949  #else
950  #if SOL_IS_ON(SOL_COMPILER_GCC)
951  #define SOL_API_LINKAGE_I_ __attribute__((dllimport))
952  #else
953  #define SOL_API_LINKAGE_I_ __declspec(dllimport)
954  #endif
955  #endif
956  #else
957  // extern if building normally on non-MSVC
958  #define SOL_API_LINKAGE_I_ extern
959  #endif
960  #elif SOL_IS_ON(SOL_UNITY_BUILD)
961  // Built-in library, like how stb typical works
962  #if SOL_IS_ON(SOL_HEADER_ONLY)
963  // Header only, so functions are defined "inline"
964  #define SOL_API_LINKAGE_I_ inline
965  #else
966  // Not header only, so seperately compiled files
967  #define SOL_API_LINKAGE_I_ extern
968  #endif
969  #else
970  // Normal static library
971  #if SOL_IS_ON(SOL_BUILD_CXX_MODE)
972  #define SOL_API_LINKAGE_I_
973  #else
974  #define SOL_API_LINKAGE_I_ extern
975  #endif
976  #endif // DLL or not
977 #endif // Build definitions
978 
979 #if defined(SOL_PUBLIC_FUNC_DECL)
980  #define SOL_PUBLIC_FUNC_DECL_I_ SOL_PUBLIC_FUNC_DECL
981 #else
982  #define SOL_PUBLIC_FUNC_DECL_I_ SOL_API_LINKAGE_I_
983 #endif
984 
985 #if defined(SOL_INTERNAL_FUNC_DECL_)
986  #define SOL_INTERNAL_FUNC_DECL_I_ SOL_INTERNAL_FUNC_DECL_
987 #else
988  #define SOL_INTERNAL_FUNC_DECL_I_ SOL_API_LINKAGE_I_
989 #endif
990 
991 #if defined(SOL_PUBLIC_FUNC_DEF)
992  #define SOL_PUBLIC_FUNC_DEF_I_ SOL_PUBLIC_FUNC_DEF
993 #else
994  #define SOL_PUBLIC_FUNC_DEF_I_ SOL_API_LINKAGE_I_
995 #endif
996 
997 #if defined(SOL_INTERNAL_FUNC_DEF)
998  #define SOL_INTERNAL_FUNC_DEF_I_ SOL_INTERNAL_FUNC_DEF
999 #else
1000  #define SOL_INTERNAL_FUNC_DEF_I_ SOL_API_LINKAGE_I_
1001 #endif
1002 
1003 #if defined(SOL_FUNC_DECL)
1004  #define SOL_FUNC_DECL_I_ SOL_FUNC_DECL
1005 #elif SOL_IS_ON(SOL_HEADER_ONLY)
1006  #define SOL_FUNC_DECL_I_
1007 #elif SOL_IS_ON(SOL_DLL)
1008  #if SOL_IS_ON(SOL_COMPILER_VCXX)
1009  #if SOL_IS_ON(SOL_BUILD)
1010  #define SOL_FUNC_DECL_I_ extern __declspec(dllexport)
1011  #else
1012  #define SOL_FUNC_DECL_I_ extern __declspec(dllimport)
1013  #endif
1014  #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
1015  #define SOL_FUNC_DECL_I_ extern __attribute__((visibility("default")))
1016  #else
1017  #define SOL_FUNC_DECL_I_ extern
1018  #endif
1019 #endif
1020 
1021 #if defined(SOL_FUNC_DEFN)
1022  #define SOL_FUNC_DEFN_I_ SOL_FUNC_DEFN
1023 #elif SOL_IS_ON(SOL_HEADER_ONLY)
1024  #define SOL_FUNC_DEFN_I_ inline
1025 #elif SOL_IS_ON(SOL_DLL)
1026  #if SOL_IS_ON(SOL_COMPILER_VCXX)
1027  #if SOL_IS_ON(SOL_BUILD)
1028  #define SOL_FUNC_DEFN_I_ __declspec(dllexport)
1029  #else
1030  #define SOL_FUNC_DEFN_I_ __declspec(dllimport)
1031  #endif
1032  #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
1033  #define SOL_FUNC_DEFN_I_ __attribute__((visibility("default")))
1034  #else
1035  #define SOL_FUNC_DEFN_I_
1036  #endif
1037 #endif
1038 
1039 #if defined(SOL_HIDDEN_FUNC_DECL)
1040  #define SOL_HIDDEN_FUNC_DECL_I_ SOL_HIDDEN_FUNC_DECL
1041 #elif SOL_IS_ON(SOL_HEADER_ONLY)
1042  #define SOL_HIDDEN_FUNC_DECL_I_
1043 #elif SOL_IS_ON(SOL_DLL)
1044  #if SOL_IS_ON(SOL_COMPILER_VCXX)
1045  #if SOL_IS_ON(SOL_BUILD)
1046  #define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllexport)
1047  #else
1048  #define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllimport)
1049  #endif
1050  #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
1051  #define SOL_HIDDEN_FUNC_DECL_I_ extern __attribute__((visibility("default")))
1052  #else
1053  #define SOL_HIDDEN_FUNC_DECL_I_ extern
1054  #endif
1055 #endif
1056 
1057 #if defined(SOL_HIDDEN_FUNC_DEFN)
1058  #define SOL_HIDDEN_FUNC_DEFN_I_ SOL_HIDDEN_FUNC_DEFN
1059 #elif SOL_IS_ON(SOL_HEADER_ONLY)
1060  #define SOL_HIDDEN_FUNC_DEFN_I_ inline
1061 #elif SOL_IS_ON(SOL_DLL)
1062  #if SOL_IS_ON(SOL_COMPILER_VCXX)
1063  #if SOL_IS_ON(SOL_BUILD)
1064  #define SOL_HIDDEN_FUNC_DEFN_I_
1065  #else
1066  #define SOL_HIDDEN_FUNC_DEFN_I_
1067  #endif
1068  #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
1069  #define SOL_HIDDEN_FUNC_DEFN_I_ __attribute__((visibility("hidden")))
1070  #else
1071  #define SOL_HIDDEN_FUNC_DEFN_I_
1072  #endif
1073 #endif
1074 
1075 // end of sol/detail/build_version.hpp
1076 
1077 // end of sol/version.hpp
1078 
1079 #if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE)
1080 #ifdef check
1081 #pragma push_macro("check")
1082 #undef check
1083 #endif
1084 #endif // Unreal Engine 4 Bullshit
1085 
1086 #if SOL_IS_ON(SOL_COMPILER_GCC)
1087 #pragma GCC diagnostic push
1088 #pragma GCC diagnostic ignored "-Wshadow"
1089 #pragma GCC diagnostic ignored "-Wconversion"
1090 #if __GNUC__ > 6
1091 #pragma GCC diagnostic ignored "-Wnoexcept-type"
1092 #endif
1093 #elif SOL_IS_ON(SOL_COMPILER_CLANG)
1094 #elif SOL_IS_ON(SOL_COMPILER_VCXX)
1095 #pragma warning(push)
1096 #pragma warning(disable : 4505) // unreferenced local function has been removed GEE THANKS
1097 #endif // clang++ vs. g++ vs. VC++
1098 
1099 // beginning of sol/forward.hpp
1100 
1101 #ifndef SOL_FORWARD_HPP
1102 #define SOL_FORWARD_HPP
1103 
1104 #include <utility>
1105 #include <type_traits>
1106 #include <string_view>
1107 
1108 #if SOL_IS_ON(SOL_USE_CXX_LUA) || SOL_IS_ON(SOL_USE_CXX_LUAJIT)
1109 struct lua_State;
1110 #else
1111 extern "C" {
1112 struct lua_State;
1113 }
1114 #endif // C++ Mangling for Lua vs. Not
1115 
1116 namespace sol {
1117 
1118  enum class type;
1119 
1120  class stateless_reference;
1121  template <bool b>
1126  class stack_reference;
1127 
1128  template <typename A>
1130 
1131  struct lua_value;
1132 
1133  struct proxy_base_tag;
1134  template <typename>
1135  struct proxy_base;
1136  template <typename, typename>
1137  struct table_proxy;
1138 
1139  template <bool, typename>
1141  template <bool b>
1143  template <bool b>
1145  template <bool b>
1147  template <typename base_type>
1149  using table = table_core<false>;
1155 
1156  template <typename>
1160 
1161  template <typename T, typename base_type>
1163  template <typename T>
1165  template <typename T>
1167 
1168  template <typename base_type>
1172 
1173  template <typename base_t>
1178 
1179  template <typename T, bool>
1181  template <typename T, bool, typename H>
1195 #if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS)
1196  using function = protected_function;
1200 #else
1201  using function = unsafe_function;
1205 #endif
1207 
1208  struct unsafe_function_result;
1211 #if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS)
1213 #else
1215 #endif
1216 
1217  template <typename base_t>
1219  template <typename base_t>
1221  template <typename base_t>
1223  template <typename base_t>
1225  template <typename base_t>
1227  template <typename base_t>
1229  template <typename base_t>
1231 
1232  using object = basic_object<reference>;
1247 
1248  struct stack_proxy_base;
1249  struct stack_proxy;
1250  struct variadic_args;
1251  struct variadic_results;
1252  struct stack_count;
1253  struct this_state;
1254  struct this_main_state;
1255  struct this_environment;
1256 
1257  class state_view;
1258  class state;
1259 
1260  template <typename T>
1261  struct as_table_t;
1262  template <typename T>
1264  template <typename T>
1265  struct nested;
1266  template <typename T>
1267  struct light;
1268  template <typename T>
1269  struct user;
1270  template <typename T>
1271  struct as_args_t;
1272  template <typename T>
1273  struct protect_t;
1274  template <typename F, typename... Policies>
1276 
1277  template <typename T>
1279  template <typename T>
1281 
1282  template <typename... Args>
1283  struct types {
1284  typedef std::make_index_sequence<sizeof...(Args)> indices;
1285  static constexpr std::size_t size() {
1286  return sizeof...(Args);
1287  }
1288  };
1289 
1290  template <typename T>
1291  struct derive : std::false_type {
1292  typedef types<> type;
1293  };
1294 
1295  template <typename T>
1296  struct base : std::false_type {
1297  typedef types<> type;
1298  };
1299 
1300  template <typename T>
1301  struct weak_derive {
1302  static bool value;
1303  };
1304 
1305  template <typename T>
1306  bool weak_derive<T>::value = false;
1307 
1308  namespace stack {
1309  struct record;
1310  }
1311 
1312 #if SOL_IS_OFF(SOL_USE_BOOST)
1313  template <class T>
1314  class optional;
1315 
1316  template <class T>
1317  class optional<T&>;
1318 #endif
1319 
1320  using check_handler_type = int(lua_State*, int, type, type, const char*);
1321 
1322 } // namespace sol
1323 
1324 #define SOL_BASE_CLASSES(T, ...) \
1325  namespace sol { \
1326  template <> \
1327  struct base<T> : std::true_type { \
1328  typedef ::sol::types<__VA_ARGS__> type; \
1329  }; \
1330  } \
1331  void a_sol3_detail_function_decl_please_no_collide()
1332 #define SOL_DERIVED_CLASSES(T, ...) \
1333  namespace sol { \
1334  template <> \
1335  struct derive<T> : std::true_type { \
1336  typedef ::sol::types<__VA_ARGS__> type; \
1337  }; \
1338  } \
1339  void a_sol3_detail_function_decl_please_no_collide()
1340 
1341 #endif // SOL_FORWARD_HPP
1342 // end of sol/forward.hpp
1343 
1344 // beginning of sol/forward_detail.hpp
1345 
1346 #ifndef SOL_FORWARD_DETAIL_HPP
1347 #define SOL_FORWARD_DETAIL_HPP
1348 
1349 // beginning of sol/traits.hpp
1350 
1351 // beginning of sol/tuple.hpp
1352 
1353 // beginning of sol/base_traits.hpp
1354 
1355 #include <type_traits>
1356 
1357 namespace sol {
1358  namespace detail {
1359  struct unchecked_t { };
1360  const unchecked_t unchecked = unchecked_t {};
1361  } // namespace detail
1362 
1363  namespace meta {
1364  using sfinae_yes_t = std::true_type;
1365  using sfinae_no_t = std::false_type;
1366 
1367  template <typename...>
1368  using void_t = void;
1369 
1370  template <typename T>
1371  using unqualified = std::remove_cv<std::remove_reference_t<T>>;
1372 
1373  template <typename T>
1374  using unqualified_t = typename unqualified<T>::type;
1375 
1376  namespace meta_detail {
1377  template <typename T>
1378  struct unqualified_non_alias : unqualified<T> { };
1379 
1380  template <template <class...> class Test, class, class... Args>
1381  struct is_detected : std::false_type { };
1382 
1383  template <template <class...> class Test, class... Args>
1384  struct is_detected<Test, void_t<Test<Args...>>, Args...> : std::true_type { };
1385  } // namespace meta_detail
1386 
1387  template <template <class...> class Trait, class... Args>
1388  using is_detected = typename meta_detail::is_detected<Trait, void, Args...>::type;
1389 
1390  template <template <class...> class Trait, class... Args>
1391  constexpr inline bool is_detected_v = is_detected<Trait, Args...>::value;
1392 
1393  template <std::size_t I>
1394  using index_value = std::integral_constant<std::size_t, I>;
1395 
1396  template <bool>
1397  struct conditional {
1398  template <typename T, typename U>
1399  using type = T;
1400  };
1401 
1402  template <>
1403  struct conditional<false> {
1404  template <typename T, typename U>
1405  using type = U;
1406  };
1407 
1408  template <bool B, typename T, typename U>
1409  using conditional_t = typename conditional<B>::template type<T, U>;
1410 
1411  namespace meta_detail {
1412  template <typename T, template <typename...> class Templ>
1413  struct is_specialization_of : std::false_type { };
1414  template <typename... T, template <typename...> class Templ>
1415  struct is_specialization_of<Templ<T...>, Templ> : std::true_type { };
1416  } // namespace meta_detail
1417 
1418  template <typename T, template <typename...> class Templ>
1420 
1421  template <typename T, template <typename...> class Templ>
1422  inline constexpr bool is_specialization_of_v = is_specialization_of<std::remove_cv_t<T>, Templ>::value;
1423 
1424  template <typename T>
1425  struct identity {
1426  typedef T type;
1427  };
1428 
1429  template <typename T>
1430  using identity_t = typename identity<T>::type;
1431 
1432  template <typename T>
1433  using is_builtin_type = std::integral_constant<bool, std::is_arithmetic<T>::value || std::is_pointer<T>::value || std::is_array<T>::value>;
1434 
1435  namespace meta_detail {
1436  template <typename T, typename = void>
1437  struct has_internal_marker_impl : std::false_type { };
1438  template <typename T>
1439  struct has_internal_marker_impl<T, void_t<typename T::SOL_INTERNAL_UNSPECIALIZED_MARKER_>> : std::true_type { };
1440 
1441  template <typename T>
1443 
1444  template <typename T>
1445  constexpr inline bool has_internal_marker_v = has_internal_marker<T>::value;
1446  } // namespace meta_detail
1447 
1448  } // namespace meta
1449 } // namespace sol
1450 
1451 // end of sol/base_traits.hpp
1452 
1453 #include <tuple>
1454 #include <cstddef>
1455 
1456 namespace sol {
1457  namespace detail {
1458  using swallow = std::initializer_list<int>;
1459  } // namespace detail
1460 
1461  namespace meta {
1462  template <typename T>
1464 
1465  template <typename T>
1466  constexpr inline bool is_tuple_v = is_tuple<T>::value;
1467 
1468  namespace detail {
1469  template <typename... Args>
1470  struct tuple_types_ {
1471  typedef types<Args...> type;
1472  };
1473 
1474  template <typename... Args>
1475  struct tuple_types_<std::tuple<Args...>> {
1476  typedef types<Args...> type;
1477  };
1478  } // namespace detail
1479 
1480  template <typename... Args>
1481  using tuple_types = typename detail::tuple_types_<Args...>::type;
1482 
1483  template <typename Arg>
1485 
1486  template <typename Arg>
1487  using pop_front_type_t = typename pop_front_type<Arg>::type;
1488 
1489  template <typename... Args>
1490  struct pop_front_type<types<Args...>> {
1491  typedef void front_type;
1492  typedef types<Args...> type;
1493  };
1494 
1495  template <typename Arg, typename... Args>
1496  struct pop_front_type<types<Arg, Args...>> {
1497  typedef Arg front_type;
1498  typedef types<Args...> type;
1499  };
1500 
1501  template <std::size_t N, typename Tuple>
1502  using tuple_element = std::tuple_element<N, std::remove_reference_t<Tuple>>;
1503 
1504  template <std::size_t N, typename Tuple>
1505  using tuple_element_t = std::tuple_element_t<N, std::remove_reference_t<Tuple>>;
1506 
1507  template <std::size_t N, typename Tuple>
1508  using unqualified_tuple_element = unqualified<tuple_element_t<N, Tuple>>;
1509 
1510  template <std::size_t N, typename Tuple>
1511  using unqualified_tuple_element_t = unqualified_t<tuple_element_t<N, Tuple>>;
1512 
1513  } // namespace meta
1514 } // namespace sol
1515 
1516 // end of sol/tuple.hpp
1517 
1518 // beginning of sol/bind_traits.hpp
1519 
1520 namespace sol { namespace meta {
1521  namespace meta_detail {
1522  template <typename F>
1523  using detect_deducible_signature = decltype(&F::operator());
1524  } // namespace meta_detail
1525 
1526  template <typename F>
1527  using call_operator_deducible = typename is_detected<meta_detail::detect_deducible_signature, F>::type;
1528 
1529  template <typename F>
1530  constexpr inline bool call_operator_deducible_v = call_operator_deducible<F>::value;
1531 
1532  namespace meta_detail {
1533 
1534  template <std::size_t I, typename T>
1535  struct void_tuple_element : meta::tuple_element<I, T> { };
1536 
1537  template <std::size_t I>
1538  struct void_tuple_element<I, std::tuple<>> {
1539  typedef void type;
1540  };
1541 
1542  template <std::size_t I, typename T>
1543  using void_tuple_element_t = typename void_tuple_element<I, T>::type;
1544 
1545  template <bool it_is_noexcept, bool has_c_variadic, typename T, typename R, typename... Args>
1546  struct basic_traits {
1547  private:
1548  using first_type = meta::conditional_t<std::is_void<T>::value, int, T>&;
1549 
1550  public:
1551  inline static constexpr const bool is_noexcept = it_is_noexcept;
1552  inline static constexpr bool is_member_function = std::is_void<T>::value;
1553  inline static constexpr bool has_c_var_arg = has_c_variadic;
1554  inline static constexpr std::size_t arity = sizeof...(Args);
1555  inline static constexpr std::size_t free_arity = sizeof...(Args) + static_cast<std::size_t>(!std::is_void<T>::value);
1556  typedef types<Args...> args_list;
1557  typedef std::tuple<Args...> args_tuple;
1558  typedef T object_type;
1559  typedef R return_type;
1560  typedef tuple_types<R> returns_list;
1561  typedef R(function_type)(Args...);
1562  typedef meta::conditional_t<std::is_void<T>::value, args_list, types<first_type, Args...>> free_args_list;
1563  typedef meta::conditional_t<std::is_void<T>::value, R(Args...), R(first_type, Args...)> free_function_type;
1564  typedef meta::conditional_t<std::is_void<T>::value, R (*)(Args...), R (*)(first_type, Args...)> free_function_pointer_type;
1565  typedef std::remove_pointer_t<free_function_pointer_type> signature_type;
1566  template <std::size_t i>
1567  using arg_at = void_tuple_element_t<i, args_tuple>;
1568  };
1569 
1570  template <typename Signature, bool b = call_operator_deducible<Signature>::value>
1571  struct fx_traits : public basic_traits<false, false, void, void> { };
1572 
1573  // Free Functions
1574  template <typename R, typename... Args>
1575  struct fx_traits<R(Args...), false> : public basic_traits<false, false, void, R, Args...> {
1576  typedef R (*function_pointer_type)(Args...);
1577  };
1578 
1579  template <typename R, typename... Args>
1580  struct fx_traits<R (*)(Args...), false> : public basic_traits<false, false, void, R, Args...> {
1581  typedef R (*function_pointer_type)(Args...);
1582  };
1583 
1584  template <typename R, typename... Args>
1585  struct fx_traits<R(Args..., ...), false> : public basic_traits<false, true, void, R, Args...> {
1586  typedef R (*function_pointer_type)(Args..., ...);
1587  };
1588 
1589  template <typename R, typename... Args>
1590  struct fx_traits<R (*)(Args..., ...), false> : public basic_traits<false, true, void, R, Args...> {
1591  typedef R (*function_pointer_type)(Args..., ...);
1592  };
1593 
1594  // Member Functions
1595  /* C-Style Variadics */
1596  template <typename T, typename R, typename... Args>
1597  struct fx_traits<R (T::*)(Args...), false> : public basic_traits<false, false, T, R, Args...> {
1598  typedef R (T::*function_pointer_type)(Args...);
1599  };
1600 
1601  template <typename T, typename R, typename... Args>
1602  struct fx_traits<R (T::*)(Args..., ...), false> : public basic_traits<false, true, T, R, Args...> {
1603  typedef R (T::*function_pointer_type)(Args..., ...);
1604  };
1605 
1606  /* Const Volatile */
1607  template <typename T, typename R, typename... Args>
1608  struct fx_traits<R (T::*)(Args...) const, false> : public basic_traits<false, false, T, R, Args...> {
1609  typedef R (T::*function_pointer_type)(Args...) const;
1610  };
1611 
1612  template <typename T, typename R, typename... Args>
1613  struct fx_traits<R (T::*)(Args..., ...) const, false> : public basic_traits<false, true, T, R, Args...> {
1614  typedef R (T::*function_pointer_type)(Args..., ...) const;
1615  };
1616 
1617  template <typename T, typename R, typename... Args>
1618  struct fx_traits<R (T::*)(Args...) const volatile, false> : public basic_traits<false, false, T, R, Args...> {
1619  typedef R (T::*function_pointer_type)(Args...) const volatile;
1620  };
1621 
1622  template <typename T, typename R, typename... Args>
1623  struct fx_traits<R (T::*)(Args..., ...) const volatile, false> : public basic_traits<false, true, T, R, Args...> {
1624  typedef R (T::*function_pointer_type)(Args..., ...) const volatile;
1625  };
1626 
1627  /* Member Function Qualifiers */
1628  template <typename T, typename R, typename... Args>
1629  struct fx_traits<R (T::*)(Args...)&, false> : public basic_traits<false, false, T, R, Args...> {
1630  typedef R (T::*function_pointer_type)(Args...) &;
1631  };
1632 
1633  template <typename T, typename R, typename... Args>
1634  struct fx_traits<R (T::*)(Args..., ...)&, false> : public basic_traits<false, true, T, R, Args...> {
1635  typedef R (T::*function_pointer_type)(Args..., ...) &;
1636  };
1637 
1638  template <typename T, typename R, typename... Args>
1639  struct fx_traits<R (T::*)(Args...) const&, false> : public basic_traits<false, false, T, R, Args...> {
1640  typedef R (T::*function_pointer_type)(Args...) const&;
1641  };
1642 
1643  template <typename T, typename R, typename... Args>
1644  struct fx_traits<R (T::*)(Args..., ...) const&, false> : public basic_traits<false, true, T, R, Args...> {
1645  typedef R (T::*function_pointer_type)(Args..., ...) const&;
1646  };
1647 
1648  template <typename T, typename R, typename... Args>
1649  struct fx_traits<R (T::*)(Args...) const volatile&, false> : public basic_traits<false, false, T, R, Args...> {
1650  typedef R (T::*function_pointer_type)(Args...) const volatile&;
1651  };
1652 
1653  template <typename T, typename R, typename... Args>
1654  struct fx_traits<R (T::*)(Args..., ...) const volatile&, false> : public basic_traits<false, true, T, R, Args...> {
1655  typedef R (T::*function_pointer_type)(Args..., ...) const volatile&;
1656  };
1657 
1658  template <typename T, typename R, typename... Args>
1659  struct fx_traits<R (T::*)(Args...)&&, false> : public basic_traits<false, false, T, R, Args...> {
1660  typedef R (T::*function_pointer_type)(Args...) &&;
1661  };
1662 
1663  template <typename T, typename R, typename... Args>
1664  struct fx_traits<R (T::*)(Args..., ...)&&, false> : public basic_traits<false, true, T, R, Args...> {
1665  typedef R (T::*function_pointer_type)(Args..., ...) &&;
1666  };
1667 
1668  template <typename T, typename R, typename... Args>
1669  struct fx_traits<R (T::*)(Args...) const&&, false> : public basic_traits<false, false, T, R, Args...> {
1670  typedef R (T::*function_pointer_type)(Args...) const&&;
1671  };
1672 
1673  template <typename T, typename R, typename... Args>
1674  struct fx_traits<R (T::*)(Args..., ...) const&&, false> : public basic_traits<false, true, T, R, Args...> {
1675  typedef R (T::*function_pointer_type)(Args..., ...) const&&;
1676  };
1677 
1678  template <typename T, typename R, typename... Args>
1679  struct fx_traits<R (T::*)(Args...) const volatile&&, false> : public basic_traits<false, false, T, R, Args...> {
1680  typedef R (T::*function_pointer_type)(Args...) const volatile&&;
1681  };
1682 
1683  template <typename T, typename R, typename... Args>
1684  struct fx_traits<R (T::*)(Args..., ...) const volatile&&, false> : public basic_traits<false, true, T, R, Args...> {
1685  typedef R (T::*function_pointer_type)(Args..., ...) const volatile&&;
1686  };
1687 
1688 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
1689 
1690  template <typename R, typename... Args>
1691  struct fx_traits<R(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {
1692  typedef R (*function_pointer_type)(Args...) noexcept;
1693  };
1694 
1695  template <typename R, typename... Args>
1696  struct fx_traits<R (*)(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {
1697  typedef R (*function_pointer_type)(Args...) noexcept;
1698  };
1699 
1700  template <typename R, typename... Args>
1701  struct fx_traits<R(Args..., ...) noexcept, false> : public basic_traits<true, true, void, R, Args...> {
1702  typedef R (*function_pointer_type)(Args..., ...) noexcept;
1703  };
1704 
1705  template <typename R, typename... Args>
1706  struct fx_traits<R (*)(Args..., ...) noexcept, false> : public basic_traits<true, true, void, R, Args...> {
1707  typedef R (*function_pointer_type)(Args..., ...) noexcept;
1708  };
1709 
1710  template <typename T, typename R, typename... Args>
1711  struct fx_traits<R (T::*)(Args...) noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1712  typedef R (T::*function_pointer_type)(Args...) noexcept;
1713  };
1714 
1715  template <typename T, typename R, typename... Args>
1716  struct fx_traits<R (T::*)(Args..., ...) noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1717  typedef R (T::*function_pointer_type)(Args..., ...) noexcept;
1718  };
1719 
1720  /* Const Volatile */
1721  template <typename T, typename R, typename... Args>
1722  struct fx_traits<R (T::*)(Args...) const noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1723  typedef R (T::*function_pointer_type)(Args...) const noexcept;
1724  };
1725 
1726  template <typename T, typename R, typename... Args>
1727  struct fx_traits<R (T::*)(Args..., ...) const noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1728  typedef R (T::*function_pointer_type)(Args..., ...) const noexcept;
1729  };
1730 
1731  template <typename T, typename R, typename... Args>
1732  struct fx_traits<R (T::*)(Args...) const volatile noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1733  typedef R (T::*function_pointer_type)(Args...) const volatile noexcept;
1734  };
1735 
1736  template <typename T, typename R, typename... Args>
1737  struct fx_traits<R (T::*)(Args..., ...) const volatile noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1738  typedef R (T::*function_pointer_type)(Args..., ...) const volatile noexcept;
1739  };
1740 
1741  template <typename T, typename R, typename... Args>
1742  struct fx_traits<R (T::*)(Args...)& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1743  typedef R (T::*function_pointer_type)(Args...) & noexcept;
1744  };
1745 
1746  template <typename T, typename R, typename... Args>
1747  struct fx_traits<R (T::*)(Args..., ...)& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1748  typedef R (T::*function_pointer_type)(Args..., ...) & noexcept;
1749  };
1750 
1751  template <typename T, typename R, typename... Args>
1752  struct fx_traits<R (T::*)(Args...) const& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1753  typedef R (T::*function_pointer_type)(Args...) const& noexcept;
1754  };
1755 
1756  template <typename T, typename R, typename... Args>
1757  struct fx_traits<R (T::*)(Args..., ...) const& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1758  typedef R (T::*function_pointer_type)(Args..., ...) const& noexcept;
1759  };
1760 
1761  template <typename T, typename R, typename... Args>
1762  struct fx_traits<R (T::*)(Args...) const volatile& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1763  typedef R (T::*function_pointer_type)(Args...) const volatile& noexcept;
1764  };
1765 
1766  template <typename T, typename R, typename... Args>
1767  struct fx_traits<R (T::*)(Args..., ...) const volatile& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1768  typedef R (T::*function_pointer_type)(Args..., ...) const volatile& noexcept;
1769  };
1770 
1771  template <typename T, typename R, typename... Args>
1772  struct fx_traits<R (T::*)(Args...)&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1773  typedef R (T::*function_pointer_type)(Args...) && noexcept;
1774  };
1775 
1776  template <typename T, typename R, typename... Args>
1777  struct fx_traits<R (T::*)(Args..., ...)&& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1778  typedef R (T::*function_pointer_type)(Args..., ...) && noexcept;
1779  };
1780 
1781  template <typename T, typename R, typename... Args>
1782  struct fx_traits<R (T::*)(Args...) const&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1783  typedef R (T::*function_pointer_type)(Args...) const&& noexcept;
1784  };
1785 
1786  template <typename T, typename R, typename... Args>
1787  struct fx_traits<R (T::*)(Args..., ...) const&& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1788  typedef R (T::*function_pointer_type)(Args..., ...) const&& noexcept;
1789  };
1790 
1791  template <typename T, typename R, typename... Args>
1792  struct fx_traits<R (T::*)(Args...) const volatile&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1793  typedef R (T::*function_pointer_type)(Args...) const volatile&& noexcept;
1794  };
1795 
1796  template <typename T, typename R, typename... Args>
1797  struct fx_traits<R (T::*)(Args..., ...) const volatile&& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1798  typedef R (T::*function_pointer_type)(Args..., ...) const volatile&& noexcept;
1799  };
1800 
1801 #endif // noexcept is part of a function's type
1802 
1803 #if SOL_IS_ON(SOL_COMPILER_VCXX) && SOL_IS_ON(SOL_PLATFORM_X86)
1804  template <typename R, typename... Args>
1805  struct fx_traits<R __stdcall(Args...), false> : public basic_traits<false, false, void, R, Args...> {
1806  typedef R(__stdcall* function_pointer_type)(Args...);
1807  };
1808 
1809  template <typename R, typename... Args>
1810  struct fx_traits<R(__stdcall*)(Args...), false> : public basic_traits<false, false, void, R, Args...> {
1811  typedef R(__stdcall* function_pointer_type)(Args...);
1812  };
1813 
1814  template <typename T, typename R, typename... Args>
1815  struct fx_traits<R (__stdcall T::*)(Args...), false> : public basic_traits<false, false, T, R, Args...> {
1816  typedef R (__stdcall T::*function_pointer_type)(Args...);
1817  };
1818 
1819  /* Const Volatile */
1820  template <typename T, typename R, typename... Args>
1821  struct fx_traits<R (__stdcall T::*)(Args...) const, false> : public basic_traits<false, false, T, R, Args...> {
1822  typedef R (__stdcall T::*function_pointer_type)(Args...) const;
1823  };
1824 
1825  template <typename T, typename R, typename... Args>
1826  struct fx_traits<R (__stdcall T::*)(Args...) const volatile, false> : public basic_traits<false, false, T, R, Args...> {
1827  typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile;
1828  };
1829 
1830  /* Member Function Qualifiers */
1831  template <typename T, typename R, typename... Args>
1832  struct fx_traits<R (__stdcall T::*)(Args...)&, false> : public basic_traits<false, false, T, R, Args...> {
1833  typedef R (__stdcall T::*function_pointer_type)(Args...) &;
1834  };
1835 
1836  template <typename T, typename R, typename... Args>
1837  struct fx_traits<R (__stdcall T::*)(Args...) const&, false> : public basic_traits<false, false, T, R, Args...> {
1838  typedef R (__stdcall T::*function_pointer_type)(Args...) const&;
1839  };
1840 
1841  template <typename T, typename R, typename... Args>
1842  struct fx_traits<R (__stdcall T::*)(Args...) const volatile&, false> : public basic_traits<false, false, T, R, Args...> {
1843  typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&;
1844  };
1845 
1846  template <typename T, typename R, typename... Args>
1847  struct fx_traits<R (__stdcall T::*)(Args...)&&, false> : public basic_traits<false, false, T, R, Args...> {
1848  typedef R (__stdcall T::*function_pointer_type)(Args...) &&;
1849  };
1850 
1851  template <typename T, typename R, typename... Args>
1852  struct fx_traits<R (__stdcall T::*)(Args...) const&&, false> : public basic_traits<false, false, T, R, Args...> {
1853  typedef R (__stdcall T::*function_pointer_type)(Args...) const&&;
1854  };
1855 
1856  template <typename T, typename R, typename... Args>
1857  struct fx_traits<R (__stdcall T::*)(Args...) const volatile&&, false> : public basic_traits<false, false, T, R, Args...> {
1858  typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&&;
1859  };
1860 
1861 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
1862 
1863  template <typename R, typename... Args>
1864  struct fx_traits<R __stdcall(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {
1865  typedef R(__stdcall* function_pointer_type)(Args...) noexcept;
1866  };
1867 
1868  template <typename R, typename... Args>
1869  struct fx_traits<R(__stdcall*)(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {
1870  typedef R(__stdcall* function_pointer_type)(Args...) noexcept;
1871  };
1872 
1873  /* __stdcall cannot be applied to functions with varargs*/
1874  /*template <typename R, typename... Args>
1875  struct fx_traits<__stdcall R(Args..., ...) noexcept, false> : public basic_traits<true, true, void, R, Args...> {
1876  typedef R(__stdcall* function_pointer_type)(Args..., ...) noexcept;
1877  };
1878 
1879  template <typename R, typename... Args>
1880  struct fx_traits<R (__stdcall *)(Args..., ...) noexcept, false> : public basic_traits<true, true, void, R, Args...> {
1881  typedef R(__stdcall* function_pointer_type)(Args..., ...) noexcept;
1882  };*/
1883 
1884  template <typename T, typename R, typename... Args>
1885  struct fx_traits<R (__stdcall T::*)(Args...) noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1886  typedef R (__stdcall T::*function_pointer_type)(Args...) noexcept;
1887  };
1888 
1889  /* __stdcall does not work with varargs */
1890  /*template <typename T, typename R, typename... Args>
1891  struct fx_traits<R (__stdcall T::*)(Args..., ...) noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1892  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) noexcept;
1893  };*/
1894 
1895  /* Const Volatile */
1896  template <typename T, typename R, typename... Args>
1897  struct fx_traits<R (__stdcall T::*)(Args...) const noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1898  typedef R (__stdcall T::*function_pointer_type)(Args...) const noexcept;
1899  };
1900 
1901  /* __stdcall does not work with varargs */
1902  /*template <typename T, typename R, typename... Args>
1903  struct fx_traits<R (__stdcall T::*)(Args..., ...) const noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1904  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const noexcept;
1905  };*/
1906 
1907  template <typename T, typename R, typename... Args>
1908  struct fx_traits<R (__stdcall T::*)(Args...) const volatile noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1909  typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile noexcept;
1910  };
1911 
1912  /* __stdcall does not work with varargs */
1913  /*template <typename T, typename R, typename... Args>
1914  struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1915  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const volatile noexcept;
1916  };*/
1917 
1918  template <typename T, typename R, typename... Args>
1919  struct fx_traits<R (__stdcall T::*)(Args...)& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1920  typedef R (__stdcall T::*function_pointer_type)(Args...) & noexcept;
1921  };
1922 
1923  /* __stdcall does not work with varargs */
1924  /*template <typename T, typename R, typename... Args>
1925  struct fx_traits<R (__stdcall T::*)(Args..., ...) & noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1926  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) & noexcept;
1927  };*/
1928 
1929  template <typename T, typename R, typename... Args>
1930  struct fx_traits<R (__stdcall T::*)(Args...) const& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1931  typedef R (__stdcall T::*function_pointer_type)(Args...) const& noexcept;
1932  };
1933 
1934  /* __stdcall does not work with varargs */
1935  /*template <typename T, typename R, typename... Args>
1936  struct fx_traits<R (__stdcall T::*)(Args..., ...) const& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1937  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const& noexcept;
1938  };*/
1939 
1940  template <typename T, typename R, typename... Args>
1941  struct fx_traits<R (__stdcall T::*)(Args...) const volatile& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1942  typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile& noexcept;
1943  };
1944 
1945  /* __stdcall does not work with varargs */
1946  /*template <typename T, typename R, typename... Args>
1947  struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1948  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const volatile& noexcept;
1949  };*/
1950 
1951  template <typename T, typename R, typename... Args>
1952  struct fx_traits<R (__stdcall T::*)(Args...)&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1953  typedef R (__stdcall T::*function_pointer_type)(Args...) && noexcept;
1954  };
1955 
1956  /* __stdcall does not work with varargs */
1957  /*template <typename T, typename R, typename... Args>
1958  struct fx_traits<R (__stdcall T::*)(Args..., ...) && noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1959  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) && noexcept;
1960  };*/
1961 
1962  template <typename T, typename R, typename... Args>
1963  struct fx_traits<R (__stdcall T::*)(Args...) const&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1964  typedef R (__stdcall T::*function_pointer_type)(Args...) const&& noexcept;
1965  };
1966 
1967  /* __stdcall does not work with varargs */
1968  /*template <typename T, typename R, typename... Args>
1969  struct fx_traits<R (__stdcall T::*)(Args..., ...) const&& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1970  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const&& noexcept;
1971  };*/
1972 
1973  template <typename T, typename R, typename... Args>
1974  struct fx_traits<R (__stdcall T::*)(Args...) const volatile&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
1975  typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&& noexcept;
1976  };
1977 
1978  /* __stdcall does not work with varargs */
1979  /*template <typename T, typename R, typename... Args>
1980  struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile&& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
1981  typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const volatile&& noexcept;
1982  };*/
1983 #endif // noexcept is part of a function's type
1984 #endif // __stdcall x86 VC++ bug
1985 
1986  template <typename Signature>
1987  struct fx_traits<Signature, true> : public fx_traits<typename fx_traits<decltype(&Signature::operator())>::function_type, false> { };
1988 
1989  template <typename Signature, bool b = std::is_member_object_pointer<Signature>::value>
1990  struct callable_traits : public fx_traits<std::decay_t<Signature>> { };
1991 
1992  template <typename R, typename T>
1993  struct callable_traits<R(T::*), true> {
1994  typedef meta::conditional_t<std::is_array_v<R>, std::add_lvalue_reference_t<R>, R> return_type;
1995  typedef return_type Arg;
1996  typedef T object_type;
1997  using signature_type = R(T::*);
1998  inline static constexpr bool is_noexcept = false;
1999  inline static constexpr bool is_member_function = false;
2000  inline static constexpr std::size_t arity = 1;
2001  inline static constexpr std::size_t free_arity = 2;
2002  typedef std::tuple<Arg> args_tuple;
2003  typedef types<Arg> args_list;
2004  typedef types<T, Arg> free_args_list;
2005  typedef meta::tuple_types<return_type> returns_list;
2006  typedef return_type(function_type)(T&, return_type);
2007  typedef return_type (*function_pointer_type)(T&, Arg);
2008  typedef return_type (*free_function_pointer_type)(T&, Arg);
2009  template <std::size_t i>
2010  using arg_at = void_tuple_element_t<i, args_tuple>;
2011  };
2012 
2013  } // namespace meta_detail
2014 
2015  template <typename Signature>
2017 
2018  namespace meta_detail {
2019  template <typename, bool>
2020  struct is_probably_stateless_lambda : std::false_type { };
2021 
2022  template <typename T>
2023  struct is_probably_stateless_lambda<T, true> : std::is_convertible<T, typename bind_traits<T>::function_type*>::type { };
2024  } // namespace meta_detail
2025 
2026  template <typename T>
2027  using is_probably_stateless_lambda = typename meta_detail::is_probably_stateless_lambda<T, std::is_empty_v<T> && call_operator_deducible_v<T>>::type;
2028 
2029  template <typename T>
2030  inline constexpr bool is_probably_stateless_lambda_v = is_probably_stateless_lambda<T>::value;
2031 
2032  template <typename Signature>
2033  using function_args_t = typename bind_traits<Signature>::args_list;
2034 
2035  template <typename Signature>
2036  using function_signature_t = typename bind_traits<Signature>::signature_type;
2037 
2038  template <typename Signature>
2039  using function_return_t = typename bind_traits<Signature>::return_type;
2040 }} // namespace sol::meta
2041 
2042 // end of sol/bind_traits.hpp
2043 
2044 // beginning of sol/pointer_like.hpp
2045 
2046 #include <utility>
2047 #include <type_traits>
2048 #include <memory>
2049 
2050 namespace sol {
2051 
2052  namespace meta {
2053  namespace meta_detail {
2054  template <typename T>
2055  using is_dereferenceable_test = decltype(*std::declval<T>());
2056 
2057  template <typename T>
2058  using is_explicitly_dereferenceable_test = decltype(std::declval<T>().operator*());
2059  } // namespace meta_detail
2060 
2061  template <typename T>
2062  using is_pointer_like = std::integral_constant<bool,
2063  !std::is_array_v<T> && (std::is_pointer_v<T> || is_detected_v<meta_detail::is_explicitly_dereferenceable_test, T>)>;
2064 
2065  template <typename T>
2066  constexpr inline bool is_pointer_like_v = is_pointer_like<T>::value;
2067  } // namespace meta
2068 
2069  namespace detail {
2070 
2071  template <typename T>
2072  auto unwrap(T&& item) -> decltype(std::forward<T>(item)) {
2073  return std::forward<T>(item);
2074  }
2075 
2076  template <typename T>
2077  T& unwrap(std::reference_wrapper<T> arg) {
2078  return arg.get();
2079  }
2080 
2081  template <typename T>
2082  inline decltype(auto) deref(T&& item) {
2083  using Tu = meta::unqualified_t<T>;
2084  if constexpr (meta::is_pointer_like_v<Tu>) {
2085  return *std::forward<T>(item);
2086  }
2087  else {
2088  return std::forward<T>(item);
2089  }
2090  }
2091 
2092  template <typename T>
2093  inline decltype(auto) deref_move_only(T&& item) {
2094  using Tu = meta::unqualified_t<T>;
2095  if constexpr (meta::is_pointer_like_v<Tu> && !std::is_pointer_v<Tu> && !std::is_copy_constructible_v<Tu>) {
2096  return *std::forward<T>(item);
2097  }
2098  else {
2099  return std::forward<T>(item);
2100  }
2101  }
2102 
2103  template <typename T>
2104  inline T* ptr(T& val) {
2105  return std::addressof(val);
2106  }
2107 
2108  template <typename T>
2109  inline T* ptr(std::reference_wrapper<T> val) {
2110  return std::addressof(val.get());
2111  }
2112 
2113  template <typename T>
2114  inline T* ptr(T* val) {
2115  return val;
2116  }
2117  } // namespace detail
2118 } // namespace sol
2119 
2120 // end of sol/pointer_like.hpp
2121 
2122 // beginning of sol/string_view.hpp
2123 
2124 #include <cstddef>
2125 #include <string>
2126 #include <string_view>
2127 #include <functional>
2128 
2129 namespace sol {
2130  template <typename C, typename T = std::char_traits<C>>
2131  using basic_string_view = std::basic_string_view<C, T>;
2132 
2133  typedef std::string_view string_view;
2134  typedef std::wstring_view wstring_view;
2135  typedef std::u16string_view u16string_view;
2136  typedef std::u32string_view u32string_view;
2137  typedef std::hash<std::string_view> string_view_hash;
2138 } // namespace sol
2139 
2140 // end of sol/string_view.hpp
2141 
2142 #include <type_traits>
2143 #include <cstdint>
2144 #include <memory>
2145 #include <functional>
2146 #include <array>
2147 #include <iterator>
2148 #include <iosfwd>
2149 #if SOL_IS_ON(SOL_STD_VARIANT)
2150 #include <variant>
2151 #endif // variant is weird on XCode, thanks XCode
2152 
2153 namespace sol { namespace meta {
2154  template <typename T>
2155  struct unwrapped {
2156  typedef T type;
2157  };
2158 
2159  template <typename T>
2160  struct unwrapped<std::reference_wrapper<T>> {
2161  typedef T type;
2162  };
2163 
2164  template <typename T>
2165  using unwrapped_t = typename unwrapped<T>::type;
2166 
2167  template <typename T>
2168  struct unwrap_unqualified : unwrapped<unqualified_t<T>> { };
2169 
2170  template <typename T>
2171  using unwrap_unqualified_t = typename unwrap_unqualified<T>::type;
2172 
2173  template <typename T>
2175 
2176  template <typename R, typename T>
2177  struct remove_member_pointer<R T::*> {
2178  typedef R type;
2179  };
2180 
2181  template <typename R, typename T>
2182  struct remove_member_pointer<R T::*const> {
2183  typedef R type;
2184  };
2185 
2186  template <typename T>
2188 
2189  template <typename T, typename...>
2190  struct all_same : std::true_type { };
2191 
2192  template <typename T, typename U, typename... Args>
2193  struct all_same<T, U, Args...> : std::integral_constant<bool, std::is_same<T, U>::value && all_same<T, Args...>::value> { };
2194 
2195  template <typename T, typename...>
2196  struct any_same : std::false_type { };
2197 
2198  template <typename T, typename U, typename... Args>
2199  struct any_same<T, U, Args...> : std::integral_constant<bool, std::is_same<T, U>::value || any_same<T, Args...>::value> { };
2200 
2201  template <typename T, typename... Args>
2202  constexpr inline bool any_same_v = any_same<T, Args...>::value;
2203 
2204  template <bool B>
2205  using boolean = std::integral_constant<bool, B>;
2206 
2207  template <bool B>
2208  constexpr inline bool boolean_v = boolean<B>::value;
2209 
2210  template <typename T>
2211  using neg = boolean<!T::value>;
2212 
2213  template <typename T>
2214  constexpr inline bool neg_v = neg<T>::value;
2215 
2216  template <typename... Args>
2217  struct all : boolean<true> { };
2218 
2219  template <typename T, typename... Args>
2220  struct all<T, Args...> : std::conditional_t<T::value, all<Args...>, boolean<false>> { };
2221 
2222  template <typename... Args>
2223  struct any : boolean<false> { };
2224 
2225  template <typename T, typename... Args>
2226  struct any<T, Args...> : std::conditional_t<T::value, boolean<true>, any<Args...>> { };
2227 
2228  template <typename... Args>
2229  constexpr inline bool all_v = all<Args...>::value;
2230 
2231  template <typename... Args>
2232  constexpr inline bool any_v = any<Args...>::value;
2233 
2234  enum class enable_t { _ };
2235 
2236  constexpr const auto enabler = enable_t::_;
2237 
2238  template <bool value, typename T = void>
2239  using disable_if_t = std::enable_if_t<!value, T>;
2240 
2241  template <typename... Args>
2242  using enable = std::enable_if_t<all<Args...>::value, enable_t>;
2243 
2244  template <typename... Args>
2245  using disable = std::enable_if_t<neg<all<Args...>>::value, enable_t>;
2246 
2247  template <typename... Args>
2248  using enable_any = std::enable_if_t<any<Args...>::value, enable_t>;
2249 
2250  template <typename... Args>
2251  using disable_any = std::enable_if_t<neg<any<Args...>>::value, enable_t>;
2252 
2253  template <typename V, typename... Vs>
2254  struct find_in_pack_v : boolean<false> { };
2255 
2256  template <typename V, typename Vs1, typename... Vs>
2257  struct find_in_pack_v<V, Vs1, Vs...> : any<boolean<(V::value == Vs1::value)>, find_in_pack_v<V, Vs...>> { };
2258 
2259  namespace meta_detail {
2260  template <std::size_t I, typename T, typename... Args>
2261  struct index_in_pack : std::integral_constant<std::size_t, SIZE_MAX> { };
2262 
2263  template <std::size_t I, typename T, typename T1, typename... Args>
2264  struct index_in_pack<I, T, T1, Args...>
2265  : conditional_t<std::is_same<T, T1>::value, std::integral_constant<std::ptrdiff_t, I>, index_in_pack<I + 1, T, Args...>> { };
2266  } // namespace meta_detail
2267 
2268  template <typename T, typename... Args>
2269  struct index_in_pack : meta_detail::index_in_pack<0, T, Args...> { };
2270 
2271  template <typename T, typename List>
2272  struct index_in : meta_detail::index_in_pack<0, T, List> { };
2273 
2274  template <typename T, typename... Args>
2275  struct index_in<T, types<Args...>> : meta_detail::index_in_pack<0, T, Args...> { };
2276 
2277  template <std::size_t I, typename... Args>
2278  struct at_in_pack { };
2279 
2280  template <std::size_t I, typename... Args>
2281  using at_in_pack_t = typename at_in_pack<I, Args...>::type;
2282 
2283  template <std::size_t I, typename Arg, typename... Args>
2284  struct at_in_pack<I, Arg, Args...> : std::conditional<I == 0, Arg, at_in_pack_t<I - 1, Args...>> { };
2285 
2286  template <typename Arg, typename... Args>
2287  struct at_in_pack<0, Arg, Args...> {
2288  typedef Arg type;
2289  };
2290 
2291  namespace meta_detail {
2292  template <typename, typename TI>
2293  using on_even = meta::boolean<(TI::value % 2) == 0>;
2294 
2295  template <typename, typename TI>
2296  using on_odd = meta::boolean<(TI::value % 2) == 1>;
2297 
2298  template <typename, typename>
2299  using on_always = std::true_type;
2300 
2301  template <template <typename...> class When, std::size_t Limit, std::size_t I, template <typename...> class Pred, typename... Ts>
2302  struct count_when_for_pack : std::integral_constant<std::size_t, 0> { };
2303  template <template <typename...> class When, std::size_t Limit, std::size_t I, template <typename...> class Pred, typename T, typename... Ts>
2304  struct count_when_for_pack<When, Limit, I, Pred, T, Ts...> : conditional_t < sizeof...(Ts)
2305  == 0
2306  || Limit<2, std::integral_constant<std::size_t, I + static_cast<std::size_t>(Limit != 0 && Pred<T>::value)>,
2307  count_when_for_pack<When, Limit - static_cast<std::size_t>(When<T, std::integral_constant<std::size_t, I>>::value),
2308  I + static_cast<std::size_t>(When<T, std::integral_constant<std::size_t, I>>::value&& Pred<T>::value), Pred, Ts...>> { };
2309  } // namespace meta_detail
2310 
2311  template <template <typename...> class Pred, typename... Ts>
2312  struct count_for_pack : meta_detail::count_when_for_pack<meta_detail::on_always, sizeof...(Ts), 0, Pred, Ts...> { };
2313 
2314  template <template <typename...> class Pred, typename... Ts>
2315  inline constexpr std::size_t count_for_pack_v = count_for_pack<Pred, Ts...>::value;
2316 
2317  template <template <typename...> class Pred, typename List>
2318  struct count_for;
2319 
2320  template <template <typename...> class Pred, typename... Args>
2321  struct count_for<Pred, types<Args...>> : count_for_pack<Pred, Args...> { };
2322 
2323  template <std::size_t Limit, template <typename...> class Pred, typename... Ts>
2324  struct count_for_to_pack : meta_detail::count_when_for_pack<meta_detail::on_always, Limit, 0, Pred, Ts...> { };
2325 
2326  template <std::size_t Limit, template <typename...> class Pred, typename... Ts>
2327  inline constexpr std::size_t count_for_to_pack_v = count_for_to_pack<Limit, Pred, Ts...>::value;
2328 
2329  template <template <typename...> class When, std::size_t Limit, template <typename...> class Pred, typename... Ts>
2330  struct count_when_for_to_pack : meta_detail::count_when_for_pack<When, Limit, 0, Pred, Ts...> { };
2331 
2332  template <template <typename...> class When, std::size_t Limit, template <typename...> class Pred, typename... Ts>
2333  inline constexpr std::size_t count_when_for_to_pack_v = count_when_for_to_pack<When, Limit, Pred, Ts...>::value;
2334 
2335  template <template <typename...> class Pred, typename... Ts>
2336  using count_even_for_pack = count_when_for_to_pack<meta_detail::on_even, sizeof...(Ts), Pred, Ts...>;
2337 
2338  template <template <typename...> class Pred, typename... Ts>
2339  inline constexpr std::size_t count_even_for_pack_v = count_even_for_pack<Pred, Ts...>::value;
2340 
2341  template <template <typename...> class Pred, typename... Ts>
2342  using count_odd_for_pack = count_when_for_to_pack<meta_detail::on_odd, sizeof...(Ts), Pred, Ts...>;
2343 
2344  template <template <typename...> class Pred, typename... Ts>
2345  inline constexpr std::size_t count_odd_for_pack_v = count_odd_for_pack<Pred, Ts...>::value;
2346 
2347  template <typename... Args>
2348  struct return_type {
2349  typedef std::tuple<Args...> type;
2350  };
2351 
2352  template <typename T>
2353  struct return_type<T> {
2354  typedef T type;
2355  };
2356 
2357  template <>
2358  struct return_type<> {
2359  typedef void type;
2360  };
2361 
2362  template <typename... Args>
2363  using return_type_t = typename return_type<Args...>::type;
2364 
2365  namespace meta_detail {
2366  template <typename>
2367  struct always_true : std::true_type { };
2368  struct is_invokable_tester {
2369  template <typename Fun, typename... Args>
2370  static always_true<decltype(std::declval<Fun>()(std::declval<Args>()...))> test(int);
2371  template <typename...>
2372  static std::false_type test(...);
2373  };
2374  } // namespace meta_detail
2375 
2376  template <typename T>
2377  struct is_invokable;
2378  template <typename Fun, typename... Args>
2379  struct is_invokable<Fun(Args...)> : decltype(meta_detail::is_invokable_tester::test<Fun, Args...>(0)) { };
2380 
2381  namespace meta_detail {
2382 
2383  template <typename T, typename = void>
2384  struct is_invocable : std::is_function<std::remove_pointer_t<T>> { };
2385 
2386  template <typename T>
2387  struct is_invocable<T,
2388  std::enable_if_t<std::is_final<unqualified_t<T>>::value && std::is_class<unqualified_t<T>>::value
2389  && std::is_same<decltype(void(&T::operator())), void>::value>> { };
2390 
2391  template <typename T>
2392  struct is_invocable<T,
2393  std::enable_if_t<!std::is_final<unqualified_t<T>>::value && std::is_class<unqualified_t<T>>::value
2394  && std::is_destructible<unqualified_t<T>>::value>> {
2395  struct F {
2396  void operator()() {};
2397  };
2398  struct Derived : T, F { };
2399  template <typename U, U>
2400  struct Check;
2401 
2402  template <typename V>
2403  static sfinae_no_t test(Check<void (F::*)(), &V::operator()>*);
2404 
2405  template <typename>
2406  static sfinae_yes_t test(...);
2407 
2408  static constexpr bool value = std::is_same_v<decltype(test<Derived>(0)), sfinae_yes_t>;
2409  };
2410 
2411  template <typename T>
2412  struct is_invocable<T,
2413  std::enable_if_t<!std::is_final<unqualified_t<T>>::value && std::is_class<unqualified_t<T>>::value
2414  && !std::is_destructible<unqualified_t<T>>::value>> {
2415  struct F {
2416  void operator()() {};
2417  };
2418  struct Derived : T, F {
2419  ~Derived() = delete;
2420  };
2421  template <typename U, U>
2422  struct Check;
2423 
2424  template <typename V>
2425  static sfinae_no_t test(Check<void (F::*)(), &V::operator()>*);
2426 
2427  template <typename>
2428  static sfinae_yes_t test(...);
2429 
2430  static constexpr bool value = std::is_same_v<decltype(test<Derived>(0)), sfinae_yes_t>;
2431  };
2432 
2433  struct has_begin_end_impl {
2434  template <typename T, typename U = unqualified_t<T>, typename B = decltype(std::declval<U&>().begin()),
2435  typename E = decltype(std::declval<U&>().end())>
2436  static std::true_type test(int);
2437 
2438  template <typename...>
2439  static std::false_type test(...);
2440  };
2441 
2442  struct has_key_type_impl {
2443  template <typename T, typename U = unqualified_t<T>, typename V = typename U::key_type>
2444  static std::true_type test(int);
2445 
2446  template <typename...>
2447  static std::false_type test(...);
2448  };
2449 
2450  struct has_key_comp_impl {
2451  template <typename T, typename V = decltype(std::declval<unqualified_t<T>>().key_comp())>
2452  static std::true_type test(int);
2453 
2454  template <typename...>
2455  static std::false_type test(...);
2456  };
2457 
2458  struct has_load_factor_impl {
2459  template <typename T, typename V = decltype(std::declval<unqualified_t<T>>().load_factor())>
2460  static std::true_type test(int);
2461 
2462  template <typename...>
2463  static std::false_type test(...);
2464  };
2465 
2466  struct has_mapped_type_impl {
2467  template <typename T, typename V = typename unqualified_t<T>::mapped_type>
2468  static std::true_type test(int);
2469 
2470  template <typename...>
2471  static std::false_type test(...);
2472  };
2473 
2474  struct has_value_type_impl {
2475  template <typename T, typename V = typename unqualified_t<T>::value_type>
2476  static std::true_type test(int);
2477 
2478  template <typename...>
2479  static std::false_type test(...);
2480  };
2481 
2482  struct has_iterator_impl {
2483  template <typename T, typename V = typename unqualified_t<T>::iterator>
2484  static std::true_type test(int);
2485 
2486  template <typename...>
2487  static std::false_type test(...);
2488  };
2489 
2490  struct has_key_value_pair_impl {
2491  template <typename T, typename U = unqualified_t<T>, typename V = typename U::value_type, typename F = decltype(std::declval<V&>().first),
2492  typename S = decltype(std::declval<V&>().second)>
2493  static std::true_type test(int);
2494 
2495  template <typename...>
2496  static std::false_type test(...);
2497  };
2498 
2499  template <typename T>
2500  struct has_push_back_test {
2501  private:
2502  template <typename C>
2503  static sfinae_yes_t test(decltype(std::declval<C>().push_back(std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
2504  template <typename C>
2505  static sfinae_no_t test(...);
2506 
2507  public:
2508  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
2509  };
2510 
2511  template <typename T>
2512  struct has_insert_with_iterator_test {
2513  private:
2514  template <typename C>
2515  static sfinae_yes_t test(decltype(std::declval<C>().insert(
2516  std::declval<std::add_rvalue_reference_t<typename C::iterator>>(), std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
2517  template <typename C>
2518  static sfinae_no_t test(...);
2519 
2520  public:
2521  static constexpr bool value = !std::is_same_v<decltype(test<T>(0)), sfinae_no_t>;
2522  };
2523 
2524  template <typename T>
2525  struct has_insert_test {
2526  private:
2527  template <typename C>
2528  static sfinae_yes_t test(decltype(std::declval<C>().insert(std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
2529  template <typename C>
2530  static sfinae_no_t test(...);
2531 
2532  public:
2533  static constexpr bool value = !std::is_same_v<decltype(test<T>(0)), sfinae_no_t>;
2534  };
2535 
2536  template <typename T>
2537  struct has_insert_after_test {
2538  private:
2539  template <typename C>
2540  static sfinae_yes_t test(decltype(std::declval<C>().insert_after(std::declval<std::add_rvalue_reference_t<typename C::const_iterator>>(),
2541  std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
2542  template <typename C>
2543  static sfinae_no_t test(...);
2544 
2545  public:
2546  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
2547  };
2548 
2549  template <typename T>
2550  struct has_size_test {
2551  private:
2552  template <typename C>
2553  static sfinae_yes_t test(decltype(std::declval<C>().size())*);
2554  template <typename C>
2555  static sfinae_no_t test(...);
2556 
2557  public:
2558  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
2559  };
2560 
2561  template <typename T>
2562  struct has_max_size_test {
2563  private:
2564  template <typename C>
2565  static sfinae_yes_t test(decltype(std::declval<C>().max_size())*);
2566  template <typename C>
2567  static sfinae_no_t test(...);
2568 
2569  public:
2570  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
2571  };
2572 
2573  template <typename T>
2574  struct has_to_string_test {
2575  private:
2576  template <typename C>
2577  static sfinae_yes_t test(decltype(std::declval<C>().to_string())*);
2578  template <typename C>
2579  static sfinae_no_t test(...);
2580 
2581  public:
2582  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
2583  };
2584 
2585  template <typename T, typename U, typename = void>
2586  class supports_op_less_test : public std::false_type { };
2587  template <typename T, typename U>
2588  class supports_op_less_test<T, U, void_t<decltype(std::declval<T&>() < std::declval<U&>())>>
2589  : public std::integral_constant<bool,
2590 #if SOL_IS_ON(SOL_STD_VARIANT)
2591  !is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>
2592 #else
2593  true
2594 #endif
2595  > {
2596  };
2597 
2598  template <typename T, typename U, typename = void>
2599  class supports_op_equal_test : public std::false_type { };
2600  template <typename T, typename U>
2601  class supports_op_equal_test<T, U, void_t<decltype(std::declval<T&>() == std::declval<U&>())>>
2602  : public std::integral_constant<bool,
2603 #if SOL_IS_ON(SOL_STD_VARIANT)
2604  !is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>
2605 #else
2606  true
2607 #endif
2608  > {
2609  };
2610 
2611  template <typename T, typename U, typename = void>
2612  class supports_op_less_equal_test : public std::false_type { };
2613  template <typename T, typename U>
2614  class supports_op_less_equal_test<T, U, void_t<decltype(std::declval<T&>() <= std::declval<U&>())>>
2615  : public std::integral_constant<bool,
2616 #if SOL_IS_ON(SOL_STD_VARIANT)
2617  !is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>
2618 #else
2619  true
2620 #endif
2621  > {
2622  };
2623 
2624  template <typename T, typename U, typename = void>
2625  class supports_op_left_shift_test : public std::false_type { };
2626  template <typename T, typename U>
2627  class supports_op_left_shift_test<T, U, void_t<decltype(std::declval<T&>() << std::declval<U&>())>> : public std::true_type { };
2628 
2629  template <typename T, typename = void>
2630  class supports_adl_to_string_test : public std::false_type { };
2631  template <typename T>
2632  class supports_adl_to_string_test<T, void_t<decltype(to_string(std::declval<const T&>()))>> : public std::true_type { };
2633 
2634  template <typename T, bool b>
2635  struct is_matched_lookup_impl : std::false_type { };
2636  template <typename T>
2637  struct is_matched_lookup_impl<T, true> : std::is_same<typename T::key_type, typename T::value_type> { };
2638 
2639  template <typename T>
2640  using non_void_t = meta::conditional_t<std::is_void_v<T>, ::sol::detail::unchecked_t, T>;
2641  } // namespace meta_detail
2642 
2643  template <typename T, typename U = T>
2644  class supports_op_less : public meta_detail::supports_op_less_test<T, U> { };
2645 
2646  template <typename T, typename U = T>
2647  class supports_op_equal : public meta_detail::supports_op_equal_test<T, U> { };
2648 
2649  template <typename T, typename U = T>
2650  class supports_op_less_equal : public meta_detail::supports_op_less_equal_test<T, U> { };
2651 
2652  template <typename T, typename U = T>
2653  class supports_op_left_shift : public meta_detail::supports_op_left_shift_test<T, U> { };
2654 
2655  template <typename T>
2656  class supports_adl_to_string : public meta_detail::supports_adl_to_string_test<T> { };
2657 
2658  template <typename T>
2659  class supports_to_string_member : public meta::boolean<meta_detail::has_to_string_test<meta_detail::non_void_t<T>>::value> { };
2660 
2661  template <typename T>
2662  using is_invocable = boolean<meta_detail::is_invocable<T>::value>;
2663 
2664  template <typename T>
2665  constexpr inline bool is_invocable_v = is_invocable<T>::value;
2666 
2667  template <typename T>
2668  struct has_begin_end : decltype(meta_detail::has_begin_end_impl::test<T>(0)) { };
2669 
2670  template <typename T>
2671  constexpr inline bool has_begin_end_v = has_begin_end<T>::value;
2672 
2673  template <typename T>
2674  struct has_key_value_pair : decltype(meta_detail::has_key_value_pair_impl::test<T>(0)) { };
2675 
2676  template <typename T>
2677  struct has_key_type : decltype(meta_detail::has_key_type_impl::test<T>(0)) { };
2678 
2679  template <typename T>
2680  struct has_key_comp : decltype(meta_detail::has_key_comp_impl::test<T>(0)) { };
2681 
2682  template <typename T>
2683  struct has_load_factor : decltype(meta_detail::has_load_factor_impl::test<T>(0)) { };
2684 
2685  template <typename T>
2686  struct has_mapped_type : decltype(meta_detail::has_mapped_type_impl::test<T>(0)) { };
2687 
2688  template <typename T>
2689  struct has_iterator : decltype(meta_detail::has_iterator_impl::test<T>(0)) { };
2690 
2691  template <typename T>
2692  struct has_value_type : decltype(meta_detail::has_value_type_impl::test<T>(0)) { };
2693 
2694  template <typename T>
2695  using has_push_back = meta::boolean<meta_detail::has_push_back_test<T>::value>;
2696 
2697  template <typename T>
2698  using has_max_size = meta::boolean<meta_detail::has_max_size_test<T>::value>;
2699 
2700  template <typename T>
2701  using has_insert = meta::boolean<meta_detail::has_insert_test<T>::value>;
2702 
2703  template <typename T>
2704  using has_insert_with_iterator = meta::boolean<meta_detail::has_insert_with_iterator_test<T>::value>;
2705 
2706  template <typename T>
2707  using has_insert_after = meta::boolean<meta_detail::has_insert_after_test<T>::value>;
2708 
2709  template <typename T>
2710  using has_size = meta::boolean<meta_detail::has_size_test<T>::value>;
2711 
2712  template <typename T>
2713  using is_associative = meta::all<has_key_type<T>, has_key_value_pair<T>, has_mapped_type<T>>;
2714 
2715  template <typename T>
2716  using is_lookup = meta::all<has_key_type<T>, has_value_type<T>>;
2717 
2718  template <typename T>
2719  using is_ordered = meta::all<has_key_comp<T>, meta::neg<has_load_factor<T>>>;
2720 
2721  template <typename T>
2722  using is_matched_lookup = meta_detail::is_matched_lookup_impl<T, is_lookup<T>::value>;
2723 
2724  template <typename T>
2725  using is_initializer_list = meta::is_specialization_of<T, std::initializer_list>;
2726 
2727  template <typename T>
2728  constexpr inline bool is_initializer_list_v = is_initializer_list<T>::value;
2729 
2730  template <typename T, typename CharT = char>
2731  using is_string_literal_array_of = boolean<std::is_array_v<T> && std::is_same_v<std::remove_all_extents_t<T>, CharT>>;
2732 
2733  template <typename T, typename CharT = char>
2734  constexpr inline bool is_string_literal_array_of_v = is_string_literal_array_of<T, CharT>::value;
2735 
2736  template <typename T>
2737  using is_string_literal_array = boolean<std::is_array_v<T> && any_same_v<std::remove_all_extents_t<T>, char,
2738 #if SOL_IS_ON(SOL_CHAR8_T)
2739  char8_t,
2740 #endif
2741  char16_t, char32_t, wchar_t>>;
2742 
2743  template <typename T>
2744  constexpr inline bool is_string_literal_array_v = is_string_literal_array<T>::value;
2745 
2746  template <typename T, typename CharT>
2747  struct is_string_of : std::false_type { };
2748 
2749  template <typename CharT, typename CharTargetT, typename TraitsT, typename AllocT>
2750  struct is_string_of<std::basic_string<CharT, TraitsT, AllocT>, CharTargetT> : std::is_same<CharT, CharTargetT> { };
2751 
2752  template <typename T, typename CharT>
2753  constexpr inline bool is_string_of_v = is_string_of<T, CharT>::value;
2754 
2755  template <typename T, typename CharT>
2756  struct is_string_view_of : std::false_type { };
2757 
2758  template <typename CharT, typename CharTargetT, typename TraitsT>
2759  struct is_string_view_of<std::basic_string_view<CharT, TraitsT>, CharTargetT> : std::is_same<CharT, CharTargetT> { };
2760 
2761  template <typename T, typename CharT>
2762  constexpr inline bool is_string_view_of_v = is_string_view_of<T, CharT>::value;
2763 
2764  template <typename T>
2765  using is_string_like
2766  = 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>>;
2767 
2768  template <typename T>
2769  constexpr inline bool is_string_like_v = is_string_like<T>::value;
2770 
2771  template <typename T, typename CharT = char>
2772  using is_string_constructible = meta::boolean<
2773  is_string_literal_array_of_v<T,
2774  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> || std::is_null_pointer_v<T>>;
2775 
2776  template <typename T, typename CharT = char>
2777  constexpr inline bool is_string_constructible_v = is_string_constructible<T, CharT>::value;
2778 
2779  template <typename T>
2780  using is_string_like_or_constructible = meta::boolean<is_string_like_v<T> || is_string_constructible_v<T>>;
2781 
2782  template <typename T>
2783  struct is_pair : std::false_type { };
2784 
2785  template <typename T1, typename T2>
2786  struct is_pair<std::pair<T1, T2>> : std::true_type { };
2787 
2788  template <typename T, typename Char>
2789  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_literal_array_of<T, Char>>;
2790 
2791  template <typename T, typename Char>
2792  constexpr inline bool is_c_str_of_v = is_c_str_of<T, Char>::value;
2793 
2794  template <typename T>
2795  using is_c_str = is_c_str_of<T, char>;
2796 
2797  template <typename T>
2798  constexpr inline bool is_c_str_v = is_c_str<T>::value;
2799 
2800  template <typename T, typename Char>
2801  using is_c_str_or_string_of = any<is_c_str_of<T, Char>, is_string_of<T, Char>>;
2802 
2803  template <typename T, typename Char>
2804  constexpr inline bool is_c_str_or_string_of_v = is_c_str_or_string_of<T, Char>::value;
2805 
2806  template <typename T>
2807  using is_c_str_or_string = is_c_str_or_string_of<T, char>;
2808 
2809  template <typename T>
2810  constexpr inline bool is_c_str_or_string_v = is_c_str_or_string<T>::value;
2811 
2812  template <typename T>
2813  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>>> { };
2814 
2815  template <typename T>
2816  using is_not_move_only = neg<is_move_only<T>>;
2817 
2818  namespace meta_detail {
2819  template <typename T>
2820  decltype(auto) force_tuple(T&& x) {
2821  if constexpr (meta::is_specialization_of_v<meta::unqualified_t<T>, std::tuple>) {
2822  return std::forward<T>(x);
2823  }
2824  else {
2825  return std::tuple<T>(std::forward<T>(x));
2826  }
2827  }
2828  } // namespace meta_detail
2829 
2830  template <typename... X>
2831  decltype(auto) tuplefy(X&&... x) {
2832  return std::tuple_cat(meta_detail::force_tuple(std::forward<X>(x))...);
2833  }
2834 
2835  template <typename T, typename = void>
2836  struct iterator_tag {
2837  using type = std::input_iterator_tag;
2838  };
2839 
2840  template <typename T>
2841  struct iterator_tag<T, conditional_t<false, typename std::iterator_traits<T>::iterator_category, void>> {
2842  using type = typename std::iterator_traits<T>::iterator_category;
2843  };
2844 
2845 }} // namespace sol::meta
2846 
2847 // end of sol/traits.hpp
2848 
2849 namespace sol {
2850  namespace detail {
2851  const bool default_safe_function_calls =
2852 #if SOL_IS_ON(SOL_SAFE_FUNCTION_CALLS)
2853  true;
2854 #else
2855  false;
2856 #endif
2857  } // namespace detail
2858 
2859  namespace meta { namespace meta_detail {
2860  }} // namespace meta::meta_detail
2861 
2862  namespace stack { namespace stack_detail {
2863  using undefined_method_func = void (*)(stack_reference);
2864 
2865  template <typename T>
2866  void set_undefined_methods_on(stack_reference);
2867 
2868  struct undefined_metatable;
2869  }} // namespace stack::stack_detail
2870 } // namespace sol
2871 
2872 #endif // SOL_FORWARD_DETAIL_HPP
2873 // end of sol/forward_detail.hpp
2874 
2875 // beginning of sol/assert.hpp
2876 
2877 #if SOL_IS_ON(SOL2_CI)
2878 
2879 struct pre_main {
2880  pre_main() {
2881 #ifdef _MSC_VER
2882  _set_abort_behavior(0, _WRITE_ABORT_MSG);
2883 #endif
2884  }
2885 } inline sol2_ci_dont_lock_ci_please = {};
2886 
2887 #endif // Prevent lockup when doing Continuous Integration
2888 
2889 #if SOL_IS_ON(SOL_USER_C_ASSERT)
2890  #define sol_c_assert(...) SOL_C_ASSERT(__VA_ARGS__)
2891 #else
2892  #if SOL_IS_ON(SOL_DEBUG_BUILD)
2893  #include <exception>
2894  #include <iostream>
2895  #include <cstdlib>
2896 
2897  #define sol_c_assert(...) \
2898  do { \
2899  if (!(__VA_ARGS__)) { \
2900  std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << std::endl; \
2901  std::terminate(); \
2902  } \
2903  } while (false)
2904  #else
2905  #define sol_c_assert(...) \
2906  do { \
2907  if (false) { \
2908  (void)(__VA_ARGS__); \
2909  } \
2910  } while (false)
2911  #endif
2912 #endif
2913 
2914 #if SOL_IS_ON(SOL_USER_M_ASSERT)
2915  #define sol_m_assert(message, ...) SOL_M_ASSERT(message, __VA_ARGS__)
2916 #else
2917  #if SOL_IS_ON(SOL_DEBUG_BUILD)
2918  #include <exception>
2919  #include <iostream>
2920  #include <cstdlib>
2921 
2922  #define sol_m_assert(message, ...) \
2923  do { \
2924  if (!(__VA_ARGS__)) { \
2925  std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << ": " << message << std::endl; \
2926  std::terminate(); \
2927  } \
2928  } while (false)
2929  #else
2930  #define sol_m_assert(message, ...) \
2931  do { \
2932  if (false) { \
2933  (void)(__VA_ARGS__); \
2934  (void)sizeof(message); \
2935  } \
2936  } while (false)
2937  #endif
2938 #endif
2939 
2940 // end of sol/assert.hpp
2941 
2942 // beginning of sol/bytecode.hpp
2943 
2944 // beginning of sol/compatibility.hpp
2945 
2946 // beginning of sol/compatibility/lua_version.hpp
2947 
2948 #if SOL_IS_ON(SOL_USE_CXX_LUA)
2949  #include <lua.h>
2950  #include <lualib.h>
2951  #include <lauxlib.h>
2952 #elif SOL_IS_ON(SOL_USE_LUA_HPP)
2953  #include <lua.hpp>
2954 #else
2955  extern "C" {
2956  #include <lua.h>
2957  #include <lauxlib.h>
2958  #include <lualib.h>
2959  }
2960 #endif // C++ Mangling for Lua vs. Not
2961 
2962 #if defined(SOL_LUAJIT)
2963  #if (SOL_LUAJIT != 0)
2964  #define SOL_USE_LUAJIT_I_ SOL_ON
2965  #else
2966  #define SOL_USE_LUAJIT_I_ SOL_OFF
2967  #endif
2968 #elif defined(LUAJIT_VERSION)
2969  #define SOL_USE_LUAJIT_I_ SOL_ON
2970 #else
2971  #define SOL_USE_LUAJIT_I_ SOL_DEFAULT_OFF
2972 #endif // luajit
2973 
2974 #if SOL_IS_ON(SOL_USE_CXX_LUAJIT)
2975  #include <luajit.h>
2976 #elif SOL_IS_ON(SOL_USE_LUAJIT)
2977  extern "C" {
2978  #include <luajit.h>
2979  }
2980 #endif // C++ LuaJIT ... whatever that means
2981 
2982 #if defined(SOL_LUAJIT_VERSION)
2983  #define SOL_LUAJIT_VERSION_I_ SOL_LUAJIT_VERSION
2984 #elif SOL_IS_ON(SOL_USE_LUAJIT)
2985  #define SOL_LUAJIT_VERSION_I_ LUAJIT_VERSION_NUM
2986 #else
2987  #define SOL_LUAJIT_VERSION_I_ 0
2988 #endif
2989 
2990 #if defined(SOL_LUAJIT_FFI_DISABLED)
2991  #define SOL_LUAJIT_FFI_DISABLED_I_ SOL_ON
2992 #elif defined(LUAJIT_DISABLE_FFI)
2993  #define SOL_LUAJIT_FFI_DISABLED_I_ SOL_ON
2994 #else
2995  #define SOL_LUAJIT_FFI_DISABLED_I_ SOL_DEFAULT_OFF
2996 #endif
2997 
2998 #if defined(MOONJIT_VERSION)
2999  #define SOL_USE_MOONJIT_I_ SOL_ON
3000 #else
3001  #define SOL_USE_MOONJIT_I_ SOL_OFF
3002 #endif
3003 
3004 #if !defined(SOL_LUA_VERSION)
3005  #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 502
3006  #define SOL_LUA_VERSION LUA_VERSION_NUM
3007  #elif defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
3008  #define SOL_LUA_VERSION LUA_VERSION_NUM
3009  #elif !defined(LUA_VERSION_NUM) || !(LUA_VERSION_NUM)
3010  // Definitely 5.0
3011  #define SOL_LUA_VERSION 500
3012  #else
3013  // ??? Not sure, assume latest?
3014  #define SOL_LUA_VERSION 504
3015  #endif // Lua Version 503, 502, 501 || luajit, 500
3016 #endif // SOL_LUA_VERSION
3017 
3018 #if defined(SOL_LUA_VERSION)
3019  #define SOL_LUA_VERSION_I_ SOL_LUA_VERSION
3020 #else
3021  #define SOL_LUA_VERSION_I_ 504
3022 #endif
3023 
3024 #if defined(SOL_EXCEPTIONS_ALWAYS_UNSAFE)
3025  #if (SOL_EXCEPTIONS_ALWAYS_UNSAFE != 0)
3026  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF
3027  #else
3028  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_ON
3029  #endif
3030 #elif defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
3031  #if (SOL_EXCEPTIONS_SAFE_PROPAGATION != 0)
3032  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_ON
3033  #else
3034  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF
3035  #endif
3036 #elif SOL_LUAJIT_VERSION_I_ >= 20100
3037  // LuaJIT 2.1.0-beta3 and better have exception support locked in for all platforms (mostly)
3038  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
3039 #elif SOL_LUAJIT_VERSION_I_ >= 20000
3040  // LuaJIT 2.0.x have exception support only on x64 builds
3041  #if SOL_IS_ON(SOL_PLATFORM_X64)
3042  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
3043  #else
3044  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF
3045  #endif
3046 #else
3047  // otherwise, there is no exception safety for
3048  // shoving exceptions through Lua and errors should
3049  // always be serialized
3050  #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_OFF
3051 #endif
3052 
3053 #if defined(SOL_EXCEPTIONS_CATCH_ALL)
3054  #if (SOL_EXCEPTIONS_CATCH_ALL != 0)
3055  #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_ON
3056  #else
3057  #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_OFF
3058  #endif
3059 #else
3060  #if SOL_IS_ON(SOL_USE_LUAJIT)
3061  #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
3062  #elif SOL_IS_ON(SOL_USE_CXX_LUAJIT)
3063  #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
3064  #elif SOL_IS_ON(SOL_USE_CXX_LUA)
3065  #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
3066  #else
3067  #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_ON
3068  #endif
3069 #endif
3070 
3071 #if defined(SOL_LUAJIT_USE_EXCEPTION_TRAMPOLINE)
3072  #if (SOL_LUAJIT_USE_EXCEPTION_TRAMPOLINE != 0)
3073  #define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_ON
3074  #else
3075  #define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_OFF
3076  #endif
3077 #else
3078  #if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS) && SOL_IS_ON(SOL_USE_LUAJIT)
3079  #define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_ON
3080  #else
3081  #define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_DEFAULT_OFF
3082  #endif
3083 #endif
3084 
3085 #if defined(SOL_LUAL_STREAM_HAS_CLOSE_FUNCTION)
3086  #if (SOL_LUAL_STREAM_HAS_CLOSE_FUNCTION != 0)
3087  #define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_ON
3088  #else
3089  #define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_OFF
3090  #endif
3091 #else
3092  #if SOL_IS_OFF(SOL_USE_LUAJIT) && (SOL_LUA_VERSION > 501)
3093  #define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_ON
3094  #else
3095  #define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_DEFAULT_OFF
3096  #endif
3097 #endif
3098 
3099 #if defined (SOL_LUA_BIT32_LIB)
3100  #if SOL_LUA_BIT32_LIB != 0
3101  #define SOL_LUA_BIT32_LIB_I_ SOL_ON
3102  #else
3103  #define SOL_LUA_BIT32_LIB_I_ SOL_OFF
3104  #endif
3105 #else
3106  // Lua 5.2 only (deprecated in 5.3 (503)) (Can be turned on with Compat flags)
3107  // Lua 5.2, or other versions of Lua with the compat flag, or Lua that is not 5.2 with the specific define (5.4.1 either removed it entirely or broke it)
3108  #if (SOL_LUA_VERSION_I_ == 502) || (defined(LUA_COMPAT_BITLIB) && (LUA_COMPAT_BITLIB != 0)) || (SOL_LUA_VERSION_I_ < 504 && (defined(LUA_COMPAT_5_2) && (LUA_COMPAT_5_2 != 0)))
3109  #define SOL_LUA_BIT32_LIB_I_ SOL_ON
3110  #else
3111  #define SOL_LUA_BIT32_LIB_I_ SOL_DEFAULT_OFF
3112  #endif
3113 #endif
3114 
3115 #if defined (SOL_LUA_NIL_IN_TABLES)
3116  #if SOL_LUA_NIL_IN_TABLES != 0
3117  #define SOL_LUA_NIL_IN_TABLES_I_ SOL_ON
3118  #else
3119  #define SOL_LUA_NIL_IN_TABLES_I_ SOL_OFF
3120  #endif
3121 #else
3122  #if defined(LUA_NILINTABLE) && (LUA_NILINTABLE != 0)
3123  #define SOL_LUA_NIL_IN_TABLES_I_ SOL_DEFAULT_ON
3124  #else
3125  #define SOL_LUA_NIL_IN_TABLES_I_ SOL_DEFAULT_OFF
3126  #endif
3127 #endif
3128 
3129 // end of sol/compatibility/lua_version.hpp
3130 
3131 #if SOL_IS_ON(SOL_USE_COMPATIBILITY_LAYER)
3132 
3133 #if SOL_IS_ON(SOL_USE_CXX_LUA) || SOL_IS_ON(SOL_USE_CXX_LUAJIT)
3134 #ifndef COMPAT53_LUA_CPP
3135 #define COMPAT53_LUA_CPP 1
3136 #endif // Build Lua Compat layer as C++
3137 #endif
3138 #ifndef COMPAT53_INCLUDE_SOURCE
3139 #define COMPAT53_INCLUDE_SOURCE 1
3140 #endif // Build Compat Layer Inline
3141 
3142 // beginning of sol/compatibility/compat-5.3.h
3143 
3144 #ifndef KEPLER_PROJECT_COMPAT53_H_
3145 #define KEPLER_PROJECT_COMPAT53_H_
3146 
3147 #include <stddef.h>
3148 #include <limits.h>
3149 #include <string.h>
3150 #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
3151 extern "C" {
3152 #endif
3153 #include <lua.h>
3154 #include <lauxlib.h>
3155 #include <lualib.h>
3156 #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
3157 }
3158 #endif
3159 
3160 #ifndef COMPAT53_PREFIX
3161 /* we chose this name because many other lua bindings / libs have
3162 * their own compatibility layer, and that use the compat53 declaration
3163 * frequently, causing all kinds of linker / compiler issues
3164 */
3165 # define COMPAT53_PREFIX kp_compat53
3166 #endif // COMPAT53_PREFIX
3167 
3168 #ifndef COMPAT53_API
3169 # if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE
3170 # if defined(__GNUC__) || defined(__clang__)
3171 # define COMPAT53_API __attribute__((__unused__)) static inline
3172 # else
3173 # define COMPAT53_API static inline
3174 # endif /* Clang/GCC */
3175 # else /* COMPAT53_INCLUDE_SOURCE */
3176 /* we are not including source, so everything is extern */
3177 # define COMPAT53_API extern
3178 # endif /* COMPAT53_INCLUDE_SOURCE */
3179 #endif /* COMPAT53_PREFIX */
3180 
3181 #define COMPAT53_CONCAT_HELPER(a, b) a##b
3182 #define COMPAT53_CONCAT(a, b) COMPAT53_CONCAT_HELPER(a, b)
3183 
3184 /* declarations for Lua 5.1 */
3185 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
3186 
3187 /* XXX not implemented:
3188 * lua_arith (new operators)
3189 * lua_upvalueid
3190 * lua_upvaluejoin
3191 * lua_version
3192 * lua_yieldk
3193 */
3194 
3195 #ifndef LUA_OK
3196 # define LUA_OK 0
3197 #endif
3198 #ifndef LUA_OPADD
3199 # define LUA_OPADD 0
3200 #endif
3201 #ifndef LUA_OPSUB
3202 # define LUA_OPSUB 1
3203 #endif
3204 #ifndef LUA_OPMUL
3205 # define LUA_OPMUL 2
3206 #endif
3207 #ifndef LUA_OPDIV
3208 # define LUA_OPDIV 3
3209 #endif
3210 #ifndef LUA_OPMOD
3211 # define LUA_OPMOD 4
3212 #endif
3213 #ifndef LUA_OPPOW
3214 # define LUA_OPPOW 5
3215 #endif
3216 #ifndef LUA_OPUNM
3217 # define LUA_OPUNM 6
3218 #endif
3219 #ifndef LUA_OPEQ
3220 # define LUA_OPEQ 0
3221 #endif
3222 #ifndef LUA_OPLT
3223 # define LUA_OPLT 1
3224 #endif
3225 #ifndef LUA_OPLE
3226 # define LUA_OPLE 2
3227 #endif
3228 
3229 /* LuaJIT/Lua 5.1 does not have the updated
3230 * error codes for thread status/function returns (but some patched versions do)
3231 * define it only if it's not found
3232 */
3233 #if !defined(LUA_ERRGCMM)
3234 /* Use + 2 because in some versions of Lua (Lua 5.1)
3235 * LUA_ERRFILE is defined as (LUA_ERRERR+1)
3236 * so we need to avoid it (LuaJIT might have something at this
3237 * integer value too)
3238 */
3239 # define LUA_ERRGCMM (LUA_ERRERR + 2)
3240 #endif /* LUA_ERRGCMM define */
3241 
3242 #if !defined(MOONJIT_VERSION)
3243 typedef size_t lua_Unsigned;
3244 #endif
3245 
3246 typedef struct luaL_Buffer_53 {
3247  luaL_Buffer b; /* make incorrect code crash! */
3248  char *ptr;
3249  size_t nelems;
3250  size_t capacity;
3251  lua_State *L2;
3252 } luaL_Buffer_53;
3253 #define luaL_Buffer luaL_Buffer_53
3254 
3255 /* In PUC-Rio 5.1, userdata is a simple FILE*
3256 * In LuaJIT, it's a struct where the first member is a FILE*
3257 * We can't support the `closef` member
3258 */
3259 typedef struct luaL_Stream {
3260  FILE *f;
3261 } luaL_Stream;
3262 
3263 #define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex)
3264 COMPAT53_API int lua_absindex(lua_State *L, int i);
3265 
3266 #define lua_arith COMPAT53_CONCAT(COMPAT53_PREFIX, _arith)
3267 COMPAT53_API void lua_arith(lua_State *L, int op);
3268 
3269 #define lua_compare COMPAT53_CONCAT(COMPAT53_PREFIX, _compare)
3270 COMPAT53_API int lua_compare(lua_State *L, int idx1, int idx2, int op);
3271 
3272 #define lua_copy COMPAT53_CONCAT(COMPAT53_PREFIX, _copy)
3273 COMPAT53_API void lua_copy(lua_State *L, int from, int to);
3274 
3275 #define lua_getuservalue(L, i) \
3276  (lua_getfenv((L), (i)), lua_type((L), -1))
3277 #define lua_setuservalue(L, i) \
3278  (luaL_checktype((L), -1, LUA_TTABLE), lua_setfenv((L), (i)))
3279 
3280 #define lua_len COMPAT53_CONCAT(COMPAT53_PREFIX, _len)
3281 COMPAT53_API void lua_len(lua_State *L, int i);
3282 
3283 #define lua_pushstring(L, s) \
3284  (lua_pushstring((L), (s)), lua_tostring((L), -1))
3285 
3286 #define lua_pushlstring(L, s, len) \
3287  ((((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len))), lua_tostring((L), -1))
3288 
3289 #ifndef luaL_newlibtable
3290 # define luaL_newlibtable(L, l) \
3291  (lua_createtable((L), 0, sizeof((l))/sizeof(*(l))-1))
3292 #endif
3293 #ifndef luaL_newlib
3294 # define luaL_newlib(L, l) \
3295  (luaL_newlibtable((L), (l)), luaL_register((L), NULL, (l)))
3296 #endif
3297 
3298 #ifndef lua_pushglobaltable
3299 # define lua_pushglobaltable(L) \
3300  lua_pushvalue((L), LUA_GLOBALSINDEX)
3301 #endif
3302 #define lua_rawgetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawgetp)
3303 COMPAT53_API int lua_rawgetp(lua_State *L, int i, const void *p);
3304 
3305 #define lua_rawsetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawsetp)
3306 COMPAT53_API void lua_rawsetp(lua_State *L, int i, const void *p);
3307 
3308 #define lua_rawlen(L, i) lua_objlen((L), (i))
3309 
3310 #define lua_tointeger(L, i) lua_tointegerx((L), (i), NULL)
3311 
3312 #define lua_tonumberx COMPAT53_CONCAT(COMPAT53_PREFIX, _tonumberx)
3313 COMPAT53_API lua_Number lua_tonumberx(lua_State *L, int i, int *isnum);
3314 
3315 #define luaL_checkversion COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkversion)
3316 COMPAT53_API void luaL_checkversion(lua_State *L);
3317 
3318 #define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
3319 COMPAT53_API int lua_load(lua_State *L, lua_Reader reader, void *data, const char* source, const char* mode);
3320 
3321 #define luaL_loadfilex COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadfilex)
3322 COMPAT53_API int luaL_loadfilex(lua_State *L, const char *filename, const char *mode);
3323 
3324 #define luaL_loadbufferx COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadbufferx)
3325 COMPAT53_API int luaL_loadbufferx(lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
3326 
3327 #define luaL_checkstack COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkstack_53)
3328 COMPAT53_API void luaL_checkstack(lua_State *L, int sp, const char *msg);
3329 
3330 #define luaL_getsubtable COMPAT53_CONCAT(COMPAT53_PREFIX, L_getsubtable)
3331 COMPAT53_API int luaL_getsubtable(lua_State* L, int i, const char *name);
3332 
3333 #define luaL_len COMPAT53_CONCAT(COMPAT53_PREFIX, L_len)
3334 COMPAT53_API lua_Integer luaL_len(lua_State *L, int i);
3335 
3336 #define luaL_setfuncs COMPAT53_CONCAT(COMPAT53_PREFIX, L_setfuncs)
3337 COMPAT53_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup);
3338 
3339 #define luaL_setmetatable COMPAT53_CONCAT(COMPAT53_PREFIX, L_setmetatable)
3340 COMPAT53_API void luaL_setmetatable(lua_State *L, const char *tname);
3341 
3342 #define luaL_testudata COMPAT53_CONCAT(COMPAT53_PREFIX, L_testudata)
3343 COMPAT53_API void *luaL_testudata(lua_State *L, int i, const char *tname);
3344 
3345 #define luaL_traceback COMPAT53_CONCAT(COMPAT53_PREFIX, L_traceback)
3346 COMPAT53_API void luaL_traceback(lua_State *L, lua_State *L1, const char *msg, int level);
3347 
3348 #define luaL_fileresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_fileresult)
3349 COMPAT53_API int luaL_fileresult(lua_State *L, int stat, const char *fname);
3350 
3351 #define luaL_execresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_execresult)
3352 COMPAT53_API int luaL_execresult(lua_State *L, int stat);
3353 
3354 #define lua_callk(L, na, nr, ctx, cont) \
3355  ((void)(ctx), (void)(cont), lua_call((L), (na), (nr)))
3356 #define lua_pcallk(L, na, nr, err, ctx, cont) \
3357  ((void)(ctx), (void)(cont), lua_pcall((L), (na), (nr), (err)))
3358 
3359 #define lua_resume(L, from, nargs) \
3360  ((void)(from), lua_resume((L), (nargs)))
3361 
3362 #define luaL_buffinit COMPAT53_CONCAT(COMPAT53_PREFIX, _buffinit_53)
3363 COMPAT53_API void luaL_buffinit(lua_State *L, luaL_Buffer_53 *B);
3364 
3365 #define luaL_prepbuffsize COMPAT53_CONCAT(COMPAT53_PREFIX, _prepbufsize_53)
3366 COMPAT53_API char *luaL_prepbuffsize(luaL_Buffer_53 *B, size_t s);
3367 
3368 #define luaL_addlstring COMPAT53_CONCAT(COMPAT53_PREFIX, _addlstring_53)
3369 COMPAT53_API void luaL_addlstring(luaL_Buffer_53 *B, const char *s, size_t l);
3370 
3371 #define luaL_addvalue COMPAT53_CONCAT(COMPAT53_PREFIX, _addvalue_53)
3372 COMPAT53_API void luaL_addvalue(luaL_Buffer_53 *B);
3373 
3374 #define luaL_pushresult COMPAT53_CONCAT(COMPAT53_PREFIX, _pushresult_53)
3375 COMPAT53_API void luaL_pushresult(luaL_Buffer_53 *B);
3376 
3377 #undef luaL_buffinitsize
3378 #define luaL_buffinitsize(L, B, s) \
3379  (luaL_buffinit((L), (B)), luaL_prepbuffsize((B), (s)))
3380 
3381 #undef luaL_prepbuffer
3382 #define luaL_prepbuffer(B) \
3383  luaL_prepbuffsize((B), LUAL_BUFFERSIZE)
3384 
3385 #undef luaL_addchar
3386 #define luaL_addchar(B, c) \
3387  ((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize((B), 1)), \
3388  ((B)->ptr[(B)->nelems++] = (c)))
3389 
3390 #undef luaL_addsize
3391 #define luaL_addsize(B, s) \
3392  ((B)->nelems += (s))
3393 
3394 #undef luaL_addstring
3395 #define luaL_addstring(B, s) \
3396  luaL_addlstring((B), (s), strlen((s)))
3397 
3398 #undef luaL_pushresultsize
3399 #define luaL_pushresultsize(B, s) \
3400  (luaL_addsize((B), (s)), luaL_pushresult((B)))
3401 
3402 #if defined(LUA_COMPAT_APIINTCASTS)
3403 #define lua_pushunsigned(L, n) \
3404  lua_pushinteger((L), (lua_Integer)(n))
3405 #define lua_tounsignedx(L, i, is) \
3406  ((lua_Unsigned)lua_tointegerx((L), (i), (is)))
3407 #define lua_tounsigned(L, i) \
3408  lua_tounsignedx((L), (i), NULL)
3409 #define luaL_checkunsigned(L, a) \
3410  ((lua_Unsigned)luaL_checkinteger((L), (a)))
3411 #define luaL_optunsigned(L, a, d) \
3412  ((lua_Unsigned)luaL_optinteger((L), (a), (lua_Integer)(d)))
3413 #endif
3414 
3415 #endif /* Lua 5.1 only */
3416 
3417 /* declarations for Lua 5.1 and 5.2 */
3418 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 502
3419 
3420 typedef int lua_KContext;
3421 
3422 typedef int(*lua_KFunction)(lua_State *L, int status, lua_KContext ctx);
3423 
3424 #define lua_dump(L, w, d, s) \
3425  ((void)(s), lua_dump((L), (w), (d)))
3426 
3427 #define lua_getfield(L, i, k) \
3428  (lua_getfield((L), (i), (k)), lua_type((L), -1))
3429 
3430 #define lua_gettable(L, i) \
3431  (lua_gettable((L), (i)), lua_type((L), -1))
3432 
3433 #define lua_geti COMPAT53_CONCAT(COMPAT53_PREFIX, _geti)
3434 COMPAT53_API int lua_geti(lua_State *L, int index, lua_Integer i);
3435 
3436 #define lua_isinteger COMPAT53_CONCAT(COMPAT53_PREFIX, _isinteger)
3437 COMPAT53_API int lua_isinteger(lua_State *L, int index);
3438 
3439 #define lua_tointegerx COMPAT53_CONCAT(COMPAT53_PREFIX, _tointegerx_53)
3440 COMPAT53_API lua_Integer lua_tointegerx(lua_State *L, int i, int *isnum);
3441 
3442 #define lua_numbertointeger(n, p) \
3443  ((*(p) = (lua_Integer)(n)), 1)
3444 
3445 #define lua_rawget(L, i) \
3446  (lua_rawget((L), (i)), lua_type((L), -1))
3447 
3448 #define lua_rawgeti(L, i, n) \
3449  (lua_rawgeti((L), (i), (n)), lua_type((L), -1))
3450 
3451 #define lua_rotate COMPAT53_CONCAT(COMPAT53_PREFIX, _rotate)
3452 COMPAT53_API void lua_rotate(lua_State *L, int idx, int n);
3453 
3454 #define lua_seti COMPAT53_CONCAT(COMPAT53_PREFIX, _seti)
3455 COMPAT53_API void lua_seti(lua_State *L, int index, lua_Integer i);
3456 
3457 #define lua_stringtonumber COMPAT53_CONCAT(COMPAT53_PREFIX, _stringtonumber)
3458 COMPAT53_API size_t lua_stringtonumber(lua_State *L, const char *s);
3459 
3460 #define luaL_tolstring COMPAT53_CONCAT(COMPAT53_PREFIX, L_tolstring)
3461 COMPAT53_API const char *luaL_tolstring(lua_State *L, int idx, size_t *len);
3462 
3463 #define luaL_getmetafield(L, o, e) \
3464  (luaL_getmetafield((L), (o), (e)) ? lua_type((L), -1) : LUA_TNIL)
3465 
3466 #define luaL_newmetatable(L, tn) \
3467  (luaL_newmetatable((L), (tn)) ? (lua_pushstring((L), (tn)), lua_setfield((L), -2, "__name"), 1) : 0)
3468 
3469 #define luaL_requiref COMPAT53_CONCAT(COMPAT53_PREFIX, L_requiref_53)
3470 COMPAT53_API void luaL_requiref(lua_State *L, const char *modname,
3471  lua_CFunction openf, int glb);
3472 
3473 #endif /* Lua 5.1 and Lua 5.2 */
3474 
3475 /* declarations for Lua 5.2 */
3476 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 502
3477 
3478 /* XXX not implemented:
3479 * lua_isyieldable
3480 * lua_getextraspace
3481 * lua_arith (new operators)
3482 * lua_pushfstring (new formats)
3483 */
3484 
3485 #define lua_getglobal(L, n) \
3486  (lua_getglobal((L), (n)), lua_type((L), -1))
3487 
3488 #define lua_getuservalue(L, i) \
3489  (lua_getuservalue((L), (i)), lua_type((L), -1))
3490 
3491 #define lua_pushlstring(L, s, len) \
3492  (((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len)))
3493 
3494 #define lua_rawgetp(L, i, p) \
3495  (lua_rawgetp((L), (i), (p)), lua_type((L), -1))
3496 
3497 #define LUA_KFUNCTION(_name) \
3498  static int (_name)(lua_State *L, int status, lua_KContext ctx); \
3499  static int (_name ## _52)(lua_State *L) { \
3500  lua_KContext ctx; \
3501  int status = lua_getctx(L, &ctx); \
3502  return (_name)(L, status, ctx); \
3503  } \
3504  static int (_name)(lua_State *L, int status, lua_KContext ctx)
3505 
3506 #define lua_pcallk(L, na, nr, err, ctx, cont) \
3507  lua_pcallk((L), (na), (nr), (err), (ctx), cont ## _52)
3508 
3509 #define lua_callk(L, na, nr, ctx, cont) \
3510  lua_callk((L), (na), (nr), (ctx), cont ## _52)
3511 
3512 #define lua_yieldk(L, nr, ctx, cont) \
3513  lua_yieldk((L), (nr), (ctx), cont ## _52)
3514 
3515 #ifdef lua_call
3516 # undef lua_call
3517 # define lua_call(L, na, nr) \
3518  (lua_callk)((L), (na), (nr), 0, NULL)
3519 #endif
3520 
3521 #ifdef lua_pcall
3522 # undef lua_pcall
3523 # define lua_pcall(L, na, nr, err) \
3524  (lua_pcallk)((L), (na), (nr), (err), 0, NULL)
3525 #endif
3526 
3527 #ifdef lua_yield
3528 # undef lua_yield
3529 # define lua_yield(L, nr) \
3530  (lua_yieldk)((L), (nr), 0, NULL)
3531 #endif
3532 
3533 #endif /* Lua 5.2 only */
3534 
3535 /* other Lua versions */
3536 #if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 || LUA_VERSION_NUM > 504
3537 
3538 # error "unsupported Lua version (i.e. not Lua 5.1, 5.2, 5.3, or 5.4)"
3539 
3540 #endif /* other Lua versions except 5.1, 5.2, 5.3, and 5.4 */
3541 
3542 /* helper macro for defining continuation functions (for every version
3543 * *except* Lua 5.2) */
3544 #ifndef LUA_KFUNCTION
3545 #define LUA_KFUNCTION(_name) \
3546  static int (_name)(lua_State *L, int status, lua_KContext ctx)
3547 #endif
3548 
3549 #if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE == 1
3550 // beginning of sol/compatibility/compat-5.3.c.h
3551 
3552 #include <stddef.h>
3553 #include <stdlib.h>
3554 #include <string.h>
3555 #include <ctype.h>
3556 #include <errno.h>
3557 #include <stdio.h>
3558 
3559 /* don't compile it again if it already is included via compat53.h */
3560 #ifndef KEPLER_PROJECT_COMPAT53_C_
3561 #define KEPLER_PROJECT_COMPAT53_C_
3562 
3563 /* definitions for Lua 5.1 only */
3564 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
3565 
3566 #ifndef COMPAT53_FOPEN_NO_LOCK
3567 #if defined(_MSC_VER)
3568 #define COMPAT53_FOPEN_NO_LOCK 1
3569 #else /* otherwise */
3570 #define COMPAT53_FOPEN_NO_LOCK 0
3571 #endif /* VC++ only so far */
3572 #endif /* No-lock fopen_s usage if possible */
3573 
3574 #if defined(_MSC_VER) && COMPAT53_FOPEN_NO_LOCK
3575 #include <share.h>
3576 #endif /* VC++ _fsopen for share-allowed file read */
3577 
3578 #ifndef COMPAT53_HAVE_STRERROR_R
3579 #if defined(__GLIBC__) || defined(_POSIX_VERSION) || defined(__APPLE__) || (!defined(__MINGW32__) && defined(__GNUC__) && (__GNUC__ < 6))
3580 #define COMPAT53_HAVE_STRERROR_R 1
3581 #else /* none of the defines matched: define to 0 */
3582 #define COMPAT53_HAVE_STRERROR_R 0
3583 #endif /* have strerror_r of some form */
3584 #endif /* strerror_r */
3585 
3586 #ifndef COMPAT53_HAVE_STRERROR_S
3587 #if defined(_MSC_VER) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || (defined(__STDC_LIB_EXT1__) && __STDC_LIB_EXT1__)
3588 #define COMPAT53_HAVE_STRERROR_S 1
3589 #else /* not VC++ or C11 */
3590 #define COMPAT53_HAVE_STRERROR_S 0
3591 #endif /* strerror_s from VC++ or C11 */
3592 #endif /* strerror_s */
3593 
3594 #ifndef COMPAT53_LUA_FILE_BUFFER_SIZE
3595 #define COMPAT53_LUA_FILE_BUFFER_SIZE 4096
3596 #endif /* Lua File Buffer Size */
3597 
3598 static char* compat53_strerror(int en, char* buff, size_t sz) {
3599 #if COMPAT53_HAVE_STRERROR_R
3600  /* use strerror_r here, because it's available on these specific platforms */
3601  if (sz > 0) {
3602  buff[0] = '\0';
3603  /* we don't care whether the GNU version or the XSI version is used: */
3604  if (strerror_r(en, buff, sz)) {
3605  /* Yes, we really DO want to ignore the return value!
3606  * GCC makes that extra hard, not even a (void) cast will do. */
3607  }
3608  if (buff[0] == '\0') {
3609  /* Buffer is unchanged, so we probably have called GNU strerror_r which
3610  * returned a static constant string. Chances are that strerror will
3611  * return the same static constant string and therefore be thread-safe. */
3612  return strerror(en);
3613  }
3614  }
3615  return buff; /* sz is 0 *or* strerror_r wrote into the buffer */
3616 #elif COMPAT53_HAVE_STRERROR_S
3617  /* for MSVC and other C11 implementations, use strerror_s since it's
3618  * provided by default by the libraries */
3619  strerror_s(buff, sz, en);
3620  return buff;
3621 #else
3622  /* fallback, but strerror is not guaranteed to be threadsafe due to modifying
3623  * errno itself and some impls not locking a static buffer for it ... but most
3624  * known systems have threadsafe errno: this might only change if the locale
3625  * is changed out from under someone while this function is being called */
3626  (void)buff;
3627  (void)sz;
3628  return strerror(en);
3629 #endif
3630 }
3631 
3632 COMPAT53_API int lua_absindex(lua_State* L, int i) {
3633  if (i < 0 && i > LUA_REGISTRYINDEX)
3634  i += lua_gettop(L) + 1;
3635  return i;
3636 }
3637 
3638 static void compat53_call_lua(lua_State* L, char const code[], size_t len, int nargs, int nret) {
3639  lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)code);
3640  if (lua_type(L, -1) != LUA_TFUNCTION) {
3641  lua_pop(L, 1);
3642  if (luaL_loadbuffer(L, code, len, "=none"))
3643  lua_error(L);
3644  lua_pushvalue(L, -1);
3645  lua_rawsetp(L, LUA_REGISTRYINDEX, (void*)code);
3646  }
3647  lua_insert(L, -nargs - 1);
3648  lua_call(L, nargs, nret);
3649 }
3650 
3651 COMPAT53_API void lua_arith(lua_State* L, int op) {
3652  static const char compat53_arith_code[]
3653  = "local op,a,b=...\n"
3654  "if op==0 then return a+b\n"
3655  "elseif op==1 then return a-b\n"
3656  "elseif op==2 then return a*b\n"
3657  "elseif op==3 then return a/b\n"
3658  "elseif op==4 then return a%b\n"
3659  "elseif op==5 then return a^b\n"
3660  "elseif op==6 then return -a\n"
3661  "end\n";
3662 
3663  if (op < LUA_OPADD || op > LUA_OPUNM)
3664  luaL_error(L, "invalid 'op' argument for lua_arith");
3665  luaL_checkstack(L, 5, "not enough stack slots");
3666  if (op == LUA_OPUNM)
3667  lua_pushvalue(L, -1);
3668  lua_pushnumber(L, op);
3669  lua_insert(L, -3);
3670  compat53_call_lua(L, compat53_arith_code, sizeof(compat53_arith_code) - 1, 3, 1);
3671 }
3672 
3673 COMPAT53_API int lua_compare(lua_State* L, int idx1, int idx2, int op) {
3674  static const char compat53_compare_code[]
3675  = "local a,b=...\n"
3676  "return a<=b\n";
3677 
3678  int result = 0;
3679  switch (op) {
3680  case LUA_OPEQ:
3681  return lua_equal(L, idx1, idx2);
3682  case LUA_OPLT:
3683  return lua_lessthan(L, idx1, idx2);
3684  case LUA_OPLE:
3685  luaL_checkstack(L, 5, "not enough stack slots");
3686  idx1 = lua_absindex(L, idx1);
3687  idx2 = lua_absindex(L, idx2);
3688  lua_pushvalue(L, idx1);
3689  lua_pushvalue(L, idx2);
3690  compat53_call_lua(L, compat53_compare_code, sizeof(compat53_compare_code) - 1, 2, 1);
3691  result = lua_toboolean(L, -1);
3692  lua_pop(L, 1);
3693  return result;
3694  default:
3695  luaL_error(L, "invalid 'op' argument for lua_compare");
3696  }
3697  return 0;
3698 }
3699 
3700 COMPAT53_API void lua_copy(lua_State* L, int from, int to) {
3701  int abs_to = lua_absindex(L, to);
3702  luaL_checkstack(L, 1, "not enough stack slots");
3703  lua_pushvalue(L, from);
3704  lua_replace(L, abs_to);
3705 }
3706 
3707 COMPAT53_API void lua_len(lua_State* L, int i) {
3708  switch (lua_type(L, i)) {
3709  case LUA_TSTRING:
3710  lua_pushnumber(L, (lua_Number)lua_objlen(L, i));
3711  break;
3712  case LUA_TTABLE:
3713  if (!luaL_callmeta(L, i, "__len"))
3714  lua_pushnumber(L, (lua_Number)lua_objlen(L, i));
3715  break;
3716  case LUA_TUSERDATA:
3717  if (luaL_callmeta(L, i, "__len"))
3718  break;
3719  /* FALLTHROUGH */
3720  default:
3721  luaL_error(L, "attempt to get length of a %s value", lua_typename(L, lua_type(L, i)));
3722  }
3723 }
3724 
3725 COMPAT53_API int lua_rawgetp(lua_State* L, int i, const void* p) {
3726  int abs_i = lua_absindex(L, i);
3727  lua_pushlightuserdata(L, (void*)p);
3728  lua_rawget(L, abs_i);
3729  return lua_type(L, -1);
3730 }
3731 
3732 COMPAT53_API void lua_rawsetp(lua_State* L, int i, const void* p) {
3733  int abs_i = lua_absindex(L, i);
3734  luaL_checkstack(L, 1, "not enough stack slots");
3735  lua_pushlightuserdata(L, (void*)p);
3736  lua_insert(L, -2);
3737  lua_rawset(L, abs_i);
3738 }
3739 
3740 COMPAT53_API lua_Number lua_tonumberx(lua_State* L, int i, int* isnum) {
3741  lua_Number n = lua_tonumber(L, i);
3742  if (isnum != NULL) {
3743  *isnum = (n != 0 || lua_isnumber(L, i));
3744  }
3745  return n;
3746 }
3747 
3748 COMPAT53_API void luaL_checkversion(lua_State* L) {
3749  (void)L;
3750 }
3751 
3752 COMPAT53_API void luaL_checkstack(lua_State* L, int sp, const char* msg) {
3753  if (!lua_checkstack(L, sp + LUA_MINSTACK)) {
3754  if (msg != NULL)
3755  luaL_error(L, "stack overflow (%s)", msg);
3756  else {
3757  lua_pushliteral(L, "stack overflow");
3758  lua_error(L);
3759  }
3760  }
3761 }
3762 
3763 COMPAT53_API int luaL_getsubtable(lua_State* L, int i, const char* name) {
3764  int abs_i = lua_absindex(L, i);
3765  luaL_checkstack(L, 3, "not enough stack slots");
3766  lua_pushstring(L, name);
3767  lua_gettable(L, abs_i);
3768  if (lua_istable(L, -1))
3769  return 1;
3770  lua_pop(L, 1);
3771  lua_newtable(L);
3772  lua_pushstring(L, name);
3773  lua_pushvalue(L, -2);
3774  lua_settable(L, abs_i);
3775  return 0;
3776 }
3777 
3778 COMPAT53_API lua_Integer luaL_len(lua_State* L, int i) {
3779  lua_Integer res = 0;
3780  int isnum = 0;
3781  luaL_checkstack(L, 1, "not enough stack slots");
3782  lua_len(L, i);
3783  res = lua_tointegerx(L, -1, &isnum);
3784  lua_pop(L, 1);
3785  if (!isnum)
3786  luaL_error(L, "object length is not an integer");
3787  return res;
3788 }
3789 
3790 COMPAT53_API void luaL_setfuncs(lua_State* L, const luaL_Reg* l, int nup) {
3791  luaL_checkstack(L, nup + 1, "too many upvalues");
3792  for (; l->name != NULL; l++) { /* fill the table with given functions */
3793  int i;
3794  lua_pushstring(L, l->name);
3795  for (i = 0; i < nup; i++) /* copy upvalues to the top */
3796  lua_pushvalue(L, -(nup + 1));
3797  lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
3798  lua_settable(L, -(nup + 3)); /* table must be below the upvalues, the name and the closure */
3799  }
3800  lua_pop(L, nup); /* remove upvalues */
3801 }
3802 
3803 COMPAT53_API void luaL_setmetatable(lua_State* L, const char* tname) {
3804  luaL_checkstack(L, 1, "not enough stack slots");
3805  luaL_getmetatable(L, tname);
3806  lua_setmetatable(L, -2);
3807 }
3808 
3809 COMPAT53_API void* luaL_testudata(lua_State* L, int i, const char* tname) {
3810  void* p = lua_touserdata(L, i);
3811  luaL_checkstack(L, 2, "not enough stack slots");
3812  if (p == NULL || !lua_getmetatable(L, i))
3813  return NULL;
3814  else {
3815  int res = 0;
3816  luaL_getmetatable(L, tname);
3817  res = lua_rawequal(L, -1, -2);
3818  lua_pop(L, 2);
3819  if (!res)
3820  p = NULL;
3821  }
3822  return p;
3823 }
3824 
3825 static int compat53_countlevels(lua_State* L) {
3826  lua_Debug ar;
3827  int li = 1, le = 1;
3828  /* find an upper bound */
3829  while (lua_getstack(L, le, &ar)) {
3830  li = le;
3831  le *= 2;
3832  }
3833  /* do a binary search */
3834  while (li < le) {
3835  int m = (li + le) / 2;
3836  if (lua_getstack(L, m, &ar))
3837  li = m + 1;
3838  else
3839  le = m;
3840  }
3841  return le - 1;
3842 }
3843 
3844 static int compat53_findfield(lua_State* L, int objidx, int level) {
3845  if (level == 0 || !lua_istable(L, -1))
3846  return 0; /* not found */
3847  lua_pushnil(L); /* start 'next' loop */
3848  while (lua_next(L, -2)) { /* for each pair in table */
3849  if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */
3850  if (lua_rawequal(L, objidx, -1)) { /* found object? */
3851  lua_pop(L, 1); /* remove value (but keep name) */
3852  return 1;
3853  }
3854  else if (compat53_findfield(L, objidx, level - 1)) { /* try recursively */
3855  lua_remove(L, -2); /* remove table (but keep name) */
3856  lua_pushliteral(L, ".");
3857  lua_insert(L, -2); /* place '.' between the two names */
3858  lua_concat(L, 3);
3859  return 1;
3860  }
3861  }
3862  lua_pop(L, 1); /* remove value */
3863  }
3864  return 0; /* not found */
3865 }
3866 
3867 static int compat53_pushglobalfuncname(lua_State* L, lua_Debug* ar) {
3868  int top = lua_gettop(L);
3869  lua_getinfo(L, "f", ar); /* push function */
3870  lua_pushvalue(L, LUA_GLOBALSINDEX);
3871  if (compat53_findfield(L, top + 1, 2)) {
3872  lua_copy(L, -1, top + 1); /* move name to proper place */
3873  lua_pop(L, 2); /* remove pushed values */
3874  return 1;
3875  }
3876  else {
3877  lua_settop(L, top); /* remove function and global table */
3878  return 0;
3879  }
3880 }
3881 
3882 static void compat53_pushfuncname(lua_State* L, lua_Debug* ar) {
3883  if (*ar->namewhat != '\0') /* is there a name? */
3884  lua_pushfstring(L, "function " LUA_QS, ar->name);
3885  else if (*ar->what == 'm') /* main? */
3886  lua_pushliteral(L, "main chunk");
3887  else if (*ar->what == 'C') {
3888  if (compat53_pushglobalfuncname(L, ar)) {
3889  lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
3890  lua_remove(L, -2); /* remove name */
3891  }
3892  else
3893  lua_pushliteral(L, "?");
3894  }
3895  else
3896  lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
3897 }
3898 
3899 #define COMPAT53_LEVELS1 12 /* size of the first part of the stack */
3900 #define COMPAT53_LEVELS2 10 /* size of the second part of the stack */
3901 
3902 COMPAT53_API void luaL_traceback(lua_State* L, lua_State* L1, const char* msg, int level) {
3903  lua_Debug ar;
3904  int top = lua_gettop(L);
3905  int numlevels = compat53_countlevels(L1);
3906  int mark = (numlevels > COMPAT53_LEVELS1 + COMPAT53_LEVELS2) ? COMPAT53_LEVELS1 : 0;
3907  if (msg)
3908  lua_pushfstring(L, "%s\n", msg);
3909  lua_pushliteral(L, "stack traceback:");
3910  while (lua_getstack(L1, level++, &ar)) {
3911  if (level == mark) { /* too many levels? */
3912  lua_pushliteral(L, "\n\t..."); /* add a '...' */
3913  level = numlevels - COMPAT53_LEVELS2; /* and skip to last ones */
3914  }
3915  else {
3916  lua_getinfo(L1, "Slnt", &ar);
3917  lua_pushfstring(L, "\n\t%s:", ar.short_src);
3918  if (ar.currentline > 0)
3919  lua_pushfstring(L, "%d:", ar.currentline);
3920  lua_pushliteral(L, " in ");
3921  compat53_pushfuncname(L, &ar);
3922  lua_concat(L, lua_gettop(L) - top);
3923  }
3924  }
3925  lua_concat(L, lua_gettop(L) - top);
3926 }
3927 
3928 COMPAT53_API int luaL_fileresult(lua_State* L, int stat, const char* fname) {
3929  const char* serr = NULL;
3930  int en = errno; /* calls to Lua API may change this value */
3931  char buf[512] = { 0 };
3932  if (stat) {
3933  lua_pushboolean(L, 1);
3934  return 1;
3935  }
3936  else {
3937  lua_pushnil(L);
3938  serr = compat53_strerror(en, buf, sizeof(buf));
3939  if (fname)
3940  lua_pushfstring(L, "%s: %s", fname, serr);
3941  else
3942  lua_pushstring(L, serr);
3943  lua_pushnumber(L, (lua_Number)en);
3944  return 3;
3945  }
3946 }
3947 
3948 static int compat53_checkmode(lua_State* L, const char* mode, const char* modename, int err) {
3949  if (mode && strchr(mode, modename[0]) == NULL) {
3950  lua_pushfstring(L, "attempt to load a %s chunk (mode is '%s')", modename, mode);
3951  return err;
3952  }
3953  return LUA_OK;
3954 }
3955 
3956 typedef struct {
3957  lua_Reader reader;
3958  void* ud;
3959  int has_peeked_data;
3960  const char* peeked_data;
3961  size_t peeked_data_size;
3962 } compat53_reader_data;
3963 
3964 static const char* compat53_reader(lua_State* L, void* ud, size_t* size) {
3965  compat53_reader_data* data = (compat53_reader_data*)ud;
3966  if (data->has_peeked_data) {
3967  data->has_peeked_data = 0;
3968  *size = data->peeked_data_size;
3969  return data->peeked_data;
3970  }
3971  else
3972  return data->reader(L, data->ud, size);
3973 }
3974 
3975 COMPAT53_API int lua_load(lua_State* L, lua_Reader reader, void* data, const char* source, const char* mode) {
3976  int status = LUA_OK;
3977  compat53_reader_data compat53_data = { reader, data, 1, 0, 0 };
3978  compat53_data.peeked_data = reader(L, data, &(compat53_data.peeked_data_size));
3979  if (compat53_data.peeked_data && compat53_data.peeked_data_size && compat53_data.peeked_data[0] == LUA_SIGNATURE[0]) /* binary file? */
3980  status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX);
3981  else
3982  status = compat53_checkmode(L, mode, "text", LUA_ERRSYNTAX);
3983  if (status != LUA_OK)
3984  return status;
3985  /* we need to call the original 5.1 version of lua_load! */
3986 #undef lua_load
3987  return lua_load(L, compat53_reader, &compat53_data, source);
3988 #define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
3989 }
3990 
3991 typedef struct {
3992  int n; /* number of pre-read characters */
3993  FILE* f; /* file being read */
3994  char buff[COMPAT53_LUA_FILE_BUFFER_SIZE]; /* area for reading file */
3995 } compat53_LoadF;
3996 
3997 static const char* compat53_getF(lua_State* L, void* ud, size_t* size) {
3998  compat53_LoadF* lf = (compat53_LoadF*)ud;
3999  (void)L; /* not used */
4000  if (lf->n > 0) { /* are there pre-read characters to be read? */
4001  *size = lf->n; /* return them (chars already in buffer) */
4002  lf->n = 0; /* no more pre-read characters */
4003  }
4004  else { /* read a block from file */
4005  /* 'fread' can return > 0 *and* set the EOF flag. If next call to
4006  'compat53_getF' called 'fread', it might still wait for user input.
4007  The next check avoids this problem. */
4008  if (feof(lf->f))
4009  return NULL;
4010  *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */
4011  }
4012  return lf->buff;
4013 }
4014 
4015 static int compat53_errfile(lua_State* L, const char* what, int fnameindex) {
4016  char buf[512] = { 0 };
4017  const char* serr = compat53_strerror(errno, buf, sizeof(buf));
4018  const char* filename = lua_tostring(L, fnameindex) + 1;
4019  lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
4020  lua_remove(L, fnameindex);
4021  return LUA_ERRFILE;
4022 }
4023 
4024 static int compat53_skipBOM(compat53_LoadF* lf) {
4025  const char* p = "\xEF\xBB\xBF"; /* UTF-8 BOM mark */
4026  int c;
4027  lf->n = 0;
4028  do {
4029  c = getc(lf->f);
4030  if (c == EOF || c != *(const unsigned char*)p++)
4031  return c;
4032  lf->buff[lf->n++] = (char)c; /* to be read by the parser */
4033  } while (*p != '\0');
4034  lf->n = 0; /* prefix matched; discard it */
4035  return getc(lf->f); /* return next character */
4036 }
4037 
4038 /*
4039 ** reads the first character of file 'f' and skips an optional BOM mark
4040 ** in its beginning plus its first line if it starts with '#'. Returns
4041 ** true if it skipped the first line. In any case, '*cp' has the
4042 ** first "valid" character of the file (after the optional BOM and
4043 ** a first-line comment).
4044 */
4045 static int compat53_skipcomment(compat53_LoadF* lf, int* cp) {
4046  int c = *cp = compat53_skipBOM(lf);
4047  if (c == '#') { /* first line is a comment (Unix exec. file)? */
4048  do { /* skip first line */
4049  c = getc(lf->f);
4050  } while (c != EOF && c != '\n');
4051  *cp = getc(lf->f); /* skip end-of-line, if present */
4052  return 1; /* there was a comment */
4053  }
4054  else
4055  return 0; /* no comment */
4056 }
4057 
4058 COMPAT53_API int luaL_loadfilex(lua_State* L, const char* filename, const char* mode) {
4059  compat53_LoadF lf;
4060  int status, readstatus;
4061  int c;
4062  int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
4063  if (filename == NULL) {
4064  lua_pushliteral(L, "=stdin");
4065  lf.f = stdin;
4066  }
4067  else {
4068  lua_pushfstring(L, "@%s", filename);
4069 #if defined(_MSC_VER)
4070  /* This code is here to stop a deprecation error that stops builds
4071  * if a certain macro is defined. While normally not caring would
4072  * be best, some header-only libraries and builds can't afford to
4073  * dictate this to the user. A quick check shows that fopen_s this
4074  * goes back to VS 2005, and _fsopen goes back to VS 2003 .NET,
4075  * possibly even before that so we don't need to do any version
4076  * number checks, since this has been there since forever. */
4077 
4078  /* TO USER: if you want the behavior of typical fopen_s/fopen,
4079  * which does lock the file on VC++, define the macro used below to 0 */
4080 #if COMPAT53_FOPEN_NO_LOCK
4081  lf.f = _fsopen(filename, "r", _SH_DENYNO); /* do not lock the file in any way */
4082  if (lf.f == NULL)
4083  return compat53_errfile(L, "open", fnameindex);
4084 #else /* use default locking version */
4085  if (fopen_s(&lf.f, filename, "r") != 0)
4086  return compat53_errfile(L, "open", fnameindex);
4087 #endif /* Locking vs. No-locking fopen variants */
4088 #else
4089  lf.f = fopen(filename, "r"); /* default stdlib doesn't forcefully lock files here */
4090  if (lf.f == NULL)
4091  return compat53_errfile(L, "open", fnameindex);
4092 #endif
4093  }
4094  if (compat53_skipcomment(&lf, &c)) /* read initial portion */
4095  lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */
4096  if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
4097 #if defined(_MSC_VER)
4098  if (freopen_s(&lf.f, filename, "rb", lf.f) != 0)
4099  return compat53_errfile(L, "reopen", fnameindex);
4100 #else
4101  lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
4102  if (lf.f == NULL)
4103  return compat53_errfile(L, "reopen", fnameindex);
4104 #endif
4105  compat53_skipcomment(&lf, &c); /* re-read initial portion */
4106  }
4107  if (c != EOF)
4108  lf.buff[lf.n++] = (char)c; /* 'c' is the first character of the stream */
4109  status = lua_load(L, &compat53_getF, &lf, lua_tostring(L, -1), mode);
4110  readstatus = ferror(lf.f);
4111  if (filename)
4112  fclose(lf.f); /* close file (even in case of errors) */
4113  if (readstatus) {
4114  lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
4115  return compat53_errfile(L, "read", fnameindex);
4116  }
4117  lua_remove(L, fnameindex);
4118  return status;
4119 }
4120 
4121 COMPAT53_API int luaL_loadbufferx(lua_State* L, const char* buff, size_t sz, const char* name, const char* mode) {
4122  int status = LUA_OK;
4123  if (sz > 0 && buff[0] == LUA_SIGNATURE[0]) {
4124  status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX);
4125  }
4126  else {
4127  status = compat53_checkmode(L, mode, "text", LUA_ERRSYNTAX);
4128  }
4129  if (status != LUA_OK)
4130  return status;
4131  return luaL_loadbuffer(L, buff, sz, name);
4132 }
4133 
4134 #if !defined(l_inspectstat) \
4135  && (defined(unix) || defined(__unix) || defined(__unix__) || defined(__TOS_AIX__) || defined(_SYSTYPE_BSD) || (defined(__APPLE__) && defined(__MACH__)))
4136 /* some form of unix; check feature macros in unistd.h for details */
4137 #include <unistd.h>
4138 /* check posix version; the relevant include files and macros probably
4139  * were available before 2001, but I'm not sure */
4140 #if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
4141 #include <sys/wait.h>
4142 #define l_inspectstat(stat, what) \
4143  if (WIFEXITED(stat)) { \
4144  stat = WEXITSTATUS(stat); \
4145  } \
4146  else if (WIFSIGNALED(stat)) { \
4147  stat = WTERMSIG(stat); \
4148  what = "signal"; \
4149  }
4150 #endif
4151 #endif
4152 
4153 /* provide default (no-op) version */
4154 #if !defined(l_inspectstat)
4155 #define l_inspectstat(stat, what) ((void)0)
4156 #endif
4157 
4158 COMPAT53_API int luaL_execresult(lua_State* L, int stat) {
4159  const char* what = "exit";
4160  if (stat == -1)
4161  return luaL_fileresult(L, 0, NULL);
4162  else {
4163  l_inspectstat(stat, what);
4164  if (*what == 'e' && stat == 0)
4165  lua_pushboolean(L, 1);
4166  else
4167  lua_pushnil(L);
4168  lua_pushstring(L, what);
4169  lua_pushinteger(L, stat);
4170  return 3;
4171  }
4172 }
4173 
4174 COMPAT53_API void luaL_buffinit(lua_State* L, luaL_Buffer_53* B) {
4175  /* make it crash if used via pointer to a 5.1-style luaL_Buffer */
4176  B->b.p = NULL;
4177  B->b.L = NULL;
4178  B->b.lvl = 0;
4179  /* reuse the buffer from the 5.1-style luaL_Buffer though! */
4180  B->ptr = B->b.buffer;
4181  B->capacity = LUAL_BUFFERSIZE;
4182  B->nelems = 0;
4183  B->L2 = L;
4184 }
4185 
4186 COMPAT53_API char* luaL_prepbuffsize(luaL_Buffer_53* B, size_t s) {
4187  if (B->capacity - B->nelems < s) { /* needs to grow */
4188  char* newptr = NULL;
4189  size_t newcap = B->capacity * 2;
4190  if (newcap - B->nelems < s)
4191  newcap = B->nelems + s;
4192  if (newcap < B->capacity) /* overflow */
4193  luaL_error(B->L2, "buffer too large");
4194 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 504
4195  newptr = (char*)lua_newuserdatauv(B->L2, newcap, 0);
4196 #else
4197  newptr = (char*)lua_newuserdata(B->L2, newcap);
4198 #endif
4199  memcpy(newptr, B->ptr, B->nelems);
4200  if (B->ptr != B->b.buffer)
4201  lua_replace(B->L2, -2); /* remove old buffer */
4202  B->ptr = newptr;
4203  B->capacity = newcap;
4204  }
4205  return B->ptr + B->nelems;
4206 }
4207 
4208 COMPAT53_API void luaL_addlstring(luaL_Buffer_53* B, const char* s, size_t l) {
4209  memcpy(luaL_prepbuffsize(B, l), s, l);
4210  luaL_addsize(B, l);
4211 }
4212 
4213 COMPAT53_API void luaL_addvalue(luaL_Buffer_53* B) {
4214  size_t len = 0;
4215  const char* s = lua_tolstring(B->L2, -1, &len);
4216  if (!s)
4217  luaL_error(B->L2, "cannot convert value to string");
4218  if (B->ptr != B->b.buffer)
4219  lua_insert(B->L2, -2); /* userdata buffer must be at stack top */
4220  luaL_addlstring(B, s, len);
4221  lua_remove(B->L2, B->ptr != B->b.buffer ? -2 : -1);
4222 }
4223 
4224 void luaL_pushresult(luaL_Buffer_53* B) {
4225  lua_pushlstring(B->L2, B->ptr, B->nelems);
4226  if (B->ptr != B->b.buffer)
4227  lua_replace(B->L2, -2); /* remove userdata buffer */
4228 }
4229 
4230 #endif /* Lua 5.1 */
4231 
4232 /* definitions for Lua 5.1 and Lua 5.2 */
4233 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 502
4234 
4235 COMPAT53_API int lua_geti(lua_State* L, int index, lua_Integer i) {
4236  index = lua_absindex(L, index);
4237  lua_pushinteger(L, i);
4238  lua_gettable(L, index);
4239  return lua_type(L, -1);
4240 }
4241 
4242 COMPAT53_API int lua_isinteger(lua_State* L, int index) {
4243  if (lua_type(L, index) == LUA_TNUMBER) {
4244  lua_Number n = lua_tonumber(L, index);
4245  lua_Integer i = lua_tointeger(L, index);
4246  if (i == n)
4247  return 1;
4248  }
4249  return 0;
4250 }
4251 
4252 COMPAT53_API lua_Integer lua_tointegerx(lua_State* L, int i, int* isnum) {
4253  int ok = 0;
4254  lua_Number n = lua_tonumberx(L, i, &ok);
4255  if (ok) {
4256  if (n == (lua_Integer)n) {
4257  if (isnum)
4258  *isnum = 1;
4259  return (lua_Integer)n;
4260  }
4261  }
4262  if (isnum)
4263  *isnum = 0;
4264  return 0;
4265 }
4266 
4267 static void compat53_reverse(lua_State* L, int a, int b) {
4268  for (; a < b; ++a, --b) {
4269  lua_pushvalue(L, a);
4270  lua_pushvalue(L, b);
4271  lua_replace(L, a);
4272  lua_replace(L, b);
4273  }
4274 }
4275 
4276 COMPAT53_API void lua_rotate(lua_State* L, int idx, int n) {
4277  int n_elems = 0;
4278  idx = lua_absindex(L, idx);
4279  n_elems = lua_gettop(L) - idx + 1;
4280  if (n < 0)
4281  n += n_elems;
4282  if (n > 0 && n < n_elems) {
4283  luaL_checkstack(L, 2, "not enough stack slots available");
4284  n = n_elems - n;
4285  compat53_reverse(L, idx, idx + n - 1);
4286  compat53_reverse(L, idx + n, idx + n_elems - 1);
4287  compat53_reverse(L, idx, idx + n_elems - 1);
4288  }
4289 }
4290 
4291 COMPAT53_API void lua_seti(lua_State* L, int index, lua_Integer i) {
4292  luaL_checkstack(L, 1, "not enough stack slots available");
4293  index = lua_absindex(L, index);
4294  lua_pushinteger(L, i);
4295  lua_insert(L, -2);
4296  lua_settable(L, index);
4297 }
4298 
4299 #if !defined(lua_str2number)
4300 #define lua_str2number(s, p) strtod((s), (p))
4301 #endif
4302 
4303 COMPAT53_API size_t lua_stringtonumber(lua_State* L, const char* s) {
4304  char* endptr;
4305  lua_Number n = lua_str2number(s, &endptr);
4306  if (endptr != s) {
4307  while (*endptr != '\0' && isspace((unsigned char)*endptr))
4308  ++endptr;
4309  if (*endptr == '\0') {
4310  lua_pushnumber(L, n);
4311  return endptr - s + 1;
4312  }
4313  }
4314  return 0;
4315 }
4316 
4317 COMPAT53_API const char* luaL_tolstring(lua_State* L, int idx, size_t* len) {
4318  if (!luaL_callmeta(L, idx, "__tostring")) {
4319  int t = lua_type(L, idx), tt = 0;
4320  char const* name = NULL;
4321  switch (t) {
4322  case LUA_TNIL:
4323  lua_pushliteral(L, "nil");
4324  break;
4325  case LUA_TSTRING:
4326  case LUA_TNUMBER:
4327  lua_pushvalue(L, idx);
4328  break;
4329  case LUA_TBOOLEAN:
4330  if (lua_toboolean(L, idx))
4331  lua_pushliteral(L, "true");
4332  else
4333  lua_pushliteral(L, "false");
4334  break;
4335  default:
4336  tt = luaL_getmetafield(L, idx, "__name");
4337  name = (tt == LUA_TSTRING) ? lua_tostring(L, -1) : lua_typename(L, t);
4338  lua_pushfstring(L, "%s: %p", name, lua_topointer(L, idx));
4339  if (tt != LUA_TNIL)
4340  lua_replace(L, -2);
4341  break;
4342  }
4343  }
4344  else {
4345  if (!lua_isstring(L, -1))
4346  luaL_error(L, "'__tostring' must return a string");
4347  }
4348  return lua_tolstring(L, -1, len);
4349 }
4350 
4351 COMPAT53_API void luaL_requiref(lua_State* L, const char* modname, lua_CFunction openf, int glb) {
4352  luaL_checkstack(L, 3, "not enough stack slots available");
4353  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
4354  if (lua_getfield(L, -1, modname) == LUA_TNIL) {
4355  lua_pop(L, 1);
4356  lua_pushcfunction(L, openf);
4357  lua_pushstring(L, modname);
4358  lua_call(L, 1, 1);
4359  lua_pushvalue(L, -1);
4360  lua_setfield(L, -3, modname);
4361  }
4362  if (glb) {
4363  lua_pushvalue(L, -1);
4364  lua_setglobal(L, modname);
4365  }
4366  lua_replace(L, -2);
4367 }
4368 
4369 #endif /* Lua 5.1 and 5.2 */
4370 
4371 #endif /* KEPLER_PROJECT_COMPAT53_C_ */
4372 
4373 /*********************************************************************
4374  * This file contains parts of Lua 5.2's and Lua 5.3's source code:
4375  *
4376  * Copyright (C) 1994-2014 Lua.org, PUC-Rio.
4377  *
4378  * Permission is hereby granted, free of charge, to any person obtaining
4379  * a copy of this software and associated documentation files (the
4380  * "Software"), to deal in the Software without restriction, including
4381  * without limitation the rights to use, copy, modify, merge, publish,
4382  * distribute, sublicense, and/or sell copies of the Software, and to
4383  * permit persons to whom the Software is furnished to do so, subject to
4384  * the following conditions:
4385  *
4386  * The above copyright notice and this permission notice shall be
4387  * included in all copies or substantial portions of the Software.
4388  *
4389  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
4390  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
4391  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
4392  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
4393  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
4394  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
4395  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4396  *********************************************************************/
4397 // end of sol/compatibility/compat-5.3.c.h
4398 
4399 #endif
4400 
4401 #endif /* KEPLER_PROJECT_COMPAT53_H_ */
4402 
4403 // end of sol/compatibility/compat-5.3.h
4404 
4405 // beginning of sol/compatibility/compat-5.4.h
4406 
4407 #ifndef NOT_KEPLER_PROJECT_COMPAT54_H_
4408 #define NOT_KEPLER_PROJECT_COMPAT54_H_
4409 
4410 #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
4411 extern "C" {
4412 #endif
4413 #include <lua.h>
4414 #include <lauxlib.h>
4415 #include <lualib.h>
4416 #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
4417 }
4418 #endif
4419 
4420 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 504
4421 
4422 #if !defined(LUA_ERRGCMM)
4423 /* So Lua 5.4 actually removes this, which breaks sol2...
4424  man, this API is quite unstable...!
4425 */
4426 # define LUA_ERRGCMM (LUA_ERRERR + 2)
4427 #endif /* LUA_ERRGCMM define */
4428 
4429 #endif // Lua 5.4 only
4430 
4431 #endif // NOT_KEPLER_PROJECT_COMPAT54_H_// end of sol/compatibility/compat-5.4.h
4432 
4433 #endif
4434 
4435 // end of sol/compatibility.hpp
4436 
4437 #include <vector>
4438 #include <cstdint>
4439 #include <cstddef>
4440 
4441 namespace sol {
4442 
4443  template <typename Allocator = std::allocator<std::byte>>
4444  class basic_bytecode : private std::vector<std::byte, Allocator> {
4445  private:
4446  using base_t = std::vector<std::byte, Allocator>;
4447 
4448  public:
4449  using typename base_t::allocator_type;
4450  using typename base_t::const_iterator;
4451  using typename base_t::const_pointer;
4452  using typename base_t::const_reference;
4453  using typename base_t::const_reverse_iterator;
4454  using typename base_t::difference_type;
4455  using typename base_t::iterator;
4456  using typename base_t::pointer;
4457  using typename base_t::reference;
4458  using typename base_t::reverse_iterator;
4459  using typename base_t::size_type;
4460  using typename base_t::value_type;
4461 
4462  using base_t::base_t;
4463  using base_t::operator=;
4464 
4465  using base_t::data;
4466  using base_t::empty;
4467  using base_t::max_size;
4468  using base_t::size;
4469 
4470  using base_t::at;
4471  using base_t::operator[];
4472  using base_t::back;
4473  using base_t::front;
4474 
4475  using base_t::begin;
4476  using base_t::cbegin;
4477  using base_t::cend;
4478  using base_t::end;
4479 
4480  using base_t::crbegin;
4481  using base_t::crend;
4482  using base_t::rbegin;
4483  using base_t::rend;
4484 
4485  using base_t::get_allocator;
4486  using base_t::swap;
4487 
4488  using base_t::clear;
4489  using base_t::emplace;
4490  using base_t::emplace_back;
4491  using base_t::erase;
4492  using base_t::insert;
4493  using base_t::pop_back;
4494  using base_t::push_back;
4495  using base_t::reserve;
4496  using base_t::resize;
4497  using base_t::shrink_to_fit;
4498 
4499  string_view as_string_view() const {
4500  return string_view(reinterpret_cast<const char*>(this->data()), this->size());
4501  }
4502  };
4503 
4504  template <typename Container>
4505  inline int basic_insert_dump_writer(lua_State*, const void* memory, size_t memory_size, void* userdata_pointer) {
4506  using storage_t = Container;
4507  const std::byte* p_code = static_cast<const std::byte*>(memory);
4508  storage_t& bc = *static_cast<storage_t*>(userdata_pointer);
4509 #if SOL_IS_OFF(SOL_EXCEPTIONS)
4510  bc.insert(bc.cend(), p_code, p_code + memory_size);
4511 #else
4512  try {
4513  bc.insert(bc.cend(), p_code, p_code + memory_size);
4514  }
4515  catch (...) {
4516  return -1;
4517  }
4518 #endif
4519  return 0;
4520  }
4521 
4522  using bytecode = basic_bytecode<>;
4523 
4524  constexpr inline auto bytecode_dump_writer = &basic_insert_dump_writer<bytecode>;
4525 
4526 } // namespace sol
4527 
4528 // end of sol/bytecode.hpp
4529 
4530 // beginning of sol/stack.hpp
4531 
4532 // beginning of sol/trampoline.hpp
4533 
4534 // beginning of sol/types.hpp
4535 
4536 // beginning of sol/error.hpp
4537 
4538 #include <stdexcept>
4539 #include <string>
4540 #include <array>
4541 
4542 namespace sol {
4543  namespace detail {
4544  struct direct_error_tag { };
4545  const auto direct_error = direct_error_tag {};
4546 
4547  struct error_result {
4548  int results;
4549  const char* format_string;
4550  std::array<const char*, 4> argument_strings;
4551 
4552  error_result() : results(0), format_string(nullptr) {
4553  }
4554 
4555  error_result(int results_) : results(results_), format_string(nullptr) {
4556  }
4557 
4558  error_result(const char* format_string_, const char* first_message_) : results(0), format_string(format_string_), argument_strings() {
4559  argument_strings[0] = first_message_;
4560  }
4561  };
4562 
4563  inline int handle_errors(lua_State* L, const error_result& er) {
4564  if (er.format_string == nullptr) {
4565  return er.results;
4566  }
4567  return luaL_error(L, er.format_string, er.argument_strings[0], er.argument_strings[1], er.argument_strings[2], er.argument_strings[3]);
4568  }
4569  } // namespace detail
4570 
4571  class error : public std::runtime_error {
4572  private:
4573  // Because VC++ is upsetting, most of the time!
4574  std::string what_reason;
4575 
4576  public:
4577  error(const std::string& str) : error(detail::direct_error, "lua: error: " + str) {
4578  }
4579  error(std::string&& str) : error(detail::direct_error, "lua: error: " + std::move(str)) {
4580  }
4581  error(detail::direct_error_tag, const std::string& str) : std::runtime_error(""), what_reason(str) {
4582  }
4583  error(detail::direct_error_tag, std::string&& str) : std::runtime_error(""), what_reason(std::move(str)) {
4584  }
4585 
4586  error(const error& e) = default;
4587  error(error&& e) = default;
4588  error& operator=(const error& e) = default;
4589  error& operator=(error&& e) = default;
4590 
4591  virtual const char* what() const noexcept override {
4592  return what_reason.c_str();
4593  }
4594  };
4595 
4596 } // namespace sol
4597 
4598 // end of sol/error.hpp
4599 
4600 // beginning of sol/optional.hpp
4601 
4602 // beginning of sol/in_place.hpp
4603 
4604 #include <cstddef>
4605 #include <utility>
4606 
4607 namespace sol {
4608 
4609  using in_place_t = std::in_place_t;
4610  constexpr std::in_place_t in_place {};
4611  constexpr std::in_place_t in_place_of {};
4612 
4613  template <typename T>
4614  using in_place_type_t = std::in_place_type_t<T>;
4615  template <typename T>
4616  constexpr std::in_place_type_t<T> in_place_type {};
4617 
4618  template <size_t I>
4619  using in_place_index_t = std::in_place_index_t<I>;
4620  template <size_t I>
4621  constexpr in_place_index_t<I> in_place_index {};
4622 
4623 } // namespace sol
4624 
4625 // end of sol/in_place.hpp
4626 
4627 #if SOL_IS_ON(SOL_USE_BOOST)
4628 #include <boost/optional.hpp>
4629 #else
4630 // beginning of sol/optional_implementation.hpp
4631 
4632 #define SOL_TL_OPTIONAL_VERSION_MAJOR 0
4633 #define SOL_TL_OPTIONAL_VERSION_MINOR 5
4634 
4635 #include <exception>
4636 #include <functional>
4637 #include <new>
4638 #include <type_traits>
4639 #include <utility>
4640 #include <cstdlib>
4641 #include <optional>
4642 
4643 #if (defined(_MSC_VER) && _MSC_VER == 1900)
4644 #define SOL_TL_OPTIONAL_MSVC2015
4645 #endif
4646 
4647 #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && !defined(__clang__))
4648 #define SOL_TL_OPTIONAL_GCC49
4649 #endif
4650 
4651 #if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && !defined(__clang__))
4652 #define SOL_TL_OPTIONAL_GCC54
4653 #endif
4654 
4655 #if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && !defined(__clang__))
4656 #define SOL_TL_OPTIONAL_GCC55
4657 #endif
4658 
4659 #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && !defined(__clang__))
4660 #define SOL_TL_OPTIONAL_NO_CONSTRR
4661 
4662 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) std::has_trivial_copy_constructor<T>::value
4663 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::has_trivial_copy_assign<T>::value
4664 
4665 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
4666 
4667 #elif (defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__))
4668 #ifndef SOL_TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
4669 #define SOL_TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
4670 namespace sol { namespace detail {
4671  template <class T>
4672  struct is_trivially_copy_constructible : std::is_trivially_copy_constructible<T> { };
4673 #ifdef _GLIBCXX_VECTOR
4674  template <class T, class A>
4675  struct is_trivially_copy_constructible<std::vector<T, A>> : std::is_trivially_copy_constructible<T> { };
4676 #endif
4677 }} // namespace sol::detail
4678 #endif
4679 
4680 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) sol::detail::is_trivially_copy_constructible<T>::value
4681 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::is_trivially_copy_assignable<T>::value
4682 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
4683 #else
4684 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) std::is_trivially_copy_constructible<T>::value
4685 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::is_trivially_copy_assignable<T>::value
4686 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
4687 #endif
4688 
4689 #if __cplusplus > 201103L
4690 #define SOL_TL_OPTIONAL_CXX14
4691 #endif
4692 
4693 #if (__cplusplus == 201103L || defined(SOL_TL_OPTIONAL_MSVC2015) || defined(SOL_TL_OPTIONAL_GCC49))
4694 #define SOL_TL_OPTIONAL_11_CONSTEXPR
4695 #else
4696 #define SOL_TL_OPTIONAL_11_CONSTEXPR constexpr
4698 #endif
4699 
4700 namespace sol {
4701 #ifndef SOL_TL_MONOSTATE_INPLACE_MUTEX
4702 #define SOL_TL_MONOSTATE_INPLACE_MUTEX
4703  class monostate { };
4705 #endif
4706 
4707  template <class T>
4708  class optional;
4709 
4711  namespace detail {
4712 #ifndef SOL_TL_TRAITS_MUTEX
4713 #define SOL_TL_TRAITS_MUTEX
4714  // C++14-style aliases for brevity
4715  template <class T>
4716  using remove_const_t = typename std::remove_const<T>::type;
4717  template <class T>
4718  using remove_reference_t = typename std::remove_reference<T>::type;
4719  template <class T>
4720  using decay_t = typename std::decay<T>::type;
4721  template <bool E, class T = void>
4722  using enable_if_t = typename std::enable_if<E, T>::type;
4723  template <bool B, class T, class F>
4724  using conditional_t = typename std::conditional<B, T, F>::type;
4725 
4726  // std::conjunction from C++17
4727  template <class...>
4728  struct conjunction : std::true_type { };
4729  template <class B>
4730  struct conjunction<B> : B { };
4731  template <class B, class... Bs>
4732  struct conjunction<B, Bs...> : std::conditional<bool(B::value), conjunction<Bs...>, B>::type { };
4733 
4734 #if defined(_LIBCPP_VERSION) && __cplusplus == 201103L
4735 #define SOL_TL_OPTIONAL_LIBCXX_MEM_FN_WORKAROUND
4736 #endif
4737 
4738 #ifdef SOL_TL_OPTIONAL_LIBCXX_MEM_FN_WORKAROUND
4739  template <class T>
4740  struct is_pointer_to_non_const_member_func : std::false_type { };
4741  template <class T, class Ret, class... Args>
4742  struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...)> : std::true_type { };
4743  template <class T, class Ret, class... Args>
4744  struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...)&> : std::true_type { };
4745  template <class T, class Ret, class... Args>
4746  struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) &&> : std::true_type { };
4747  template <class T, class Ret, class... Args>
4748  struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile> : std::true_type { };
4749  template <class T, class Ret, class... Args>
4750  struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile&> : std::true_type { };
4751  template <class T, class Ret, class... Args>
4752  struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile&&> : std::true_type { };
4753 
4754  template <class T>
4755  struct is_const_or_const_ref : std::false_type { };
4756  template <class T>
4757  struct is_const_or_const_ref<T const&> : std::true_type { };
4758  template <class T>
4759  struct is_const_or_const_ref<T const> : std::true_type { };
4760 #endif
4761 
4762  // std::invoke from C++17
4763  // https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround
4764  template <typename Fn, typename... Args,
4765 #ifdef SOL_TL_OPTIONAL_LIBCXX_MEM_FN_WORKAROUND
4766  typename = enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value && is_const_or_const_ref<Args...>::value)>,
4767 #endif
4768  typename = enable_if_t<std::is_member_pointer<decay_t<Fn>>::value>, int = 0>
4769  constexpr auto invoke(Fn&& f, Args&&... args) noexcept(noexcept(std::mem_fn(f)(std::forward<Args>(args)...)))
4770  -> decltype(std::mem_fn(f)(std::forward<Args>(args)...)) {
4771  return std::mem_fn(f)(std::forward<Args>(args)...);
4772  }
4773 
4774  template <typename Fn, typename... Args, typename = enable_if_t<!std::is_member_pointer<decay_t<Fn>>::value>>
4775  constexpr auto invoke(Fn&& f, Args&&... args) noexcept(noexcept(std::forward<Fn>(f)(std::forward<Args>(args)...)))
4776  -> decltype(std::forward<Fn>(f)(std::forward<Args>(args)...)) {
4777  return std::forward<Fn>(f)(std::forward<Args>(args)...);
4778  }
4779 
4780  // std::invoke_result from C++17
4781  template <class F, class, class... Us>
4783 
4784  template <class F, class... Us>
4785  struct invoke_result_impl<F, decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...), void()), Us...> {
4786  using type = decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...));
4787  };
4788 
4789  template <class F, class... Us>
4790  using invoke_result = invoke_result_impl<F, void, Us...>;
4791 
4792  template <class F, class... Us>
4793  using invoke_result_t = typename invoke_result<F, Us...>::type;
4794 #endif
4795 
4796  // std::void_t from C++17
4797  template <class...>
4798  struct voider {
4799  using type = void;
4800  };
4801  template <class... Ts>
4802  using void_t = typename voider<Ts...>::type;
4803 
4804  // Trait for checking if a type is a sol::optional
4805  template <class T>
4806  struct is_optional_impl : std::false_type { };
4807  template <class T>
4808  struct is_optional_impl<optional<T>> : std::true_type { };
4809  template <class T>
4811 
4812  // Change void to sol::monostate
4813  template <class U>
4814  using fixup_void = conditional_t<std::is_void<U>::value, monostate, U>;
4815 
4816  template <class F, class U, class = invoke_result_t<F, U>>
4818 
4819  // Check if invoking F for some Us returns void
4820  template <class F, class = void, class... U>
4822  template <class F, class... U>
4823  struct returns_void_impl<F, void_t<invoke_result_t<F, U...>>, U...> : std::is_void<invoke_result_t<F, U...>> { };
4824  template <class F, class... U>
4825  using returns_void = returns_void_impl<F, void, U...>;
4826 
4827  template <class T, class... U>
4828  using enable_if_ret_void = enable_if_t<returns_void<T&&, U...>::value>;
4829 
4830  template <class T, class... U>
4831  using disable_if_ret_void = enable_if_t<!returns_void<T&&, U...>::value>;
4832 
4833  template <class T, class U>
4834  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
4835  && !std::is_same<optional<T>, detail::decay_t<U>>::value>;
4836 
4837  template <class T, class U, class Other>
4838  using enable_from_other = detail::enable_if_t<std::is_constructible<T, Other>::value && !std::is_constructible<T, optional<U>&>::value
4839  && !std::is_constructible<T, optional<U>&&>::value && !std::is_constructible<T, const optional<U>&>::value
4840  && !std::is_constructible<T, const optional<U>&&>::value && !std::is_convertible<optional<U>&, T>::value
4841  && !std::is_convertible<optional<U>&&, T>::value && !std::is_convertible<const optional<U>&, T>::value
4842  && !std::is_convertible<const optional<U>&&, T>::value>;
4843 
4844  template <class T, class U>
4845  using enable_assign_forward = detail::enable_if_t<!std::is_same<optional<T>, detail::decay_t<U>>::value
4846  && !detail::conjunction<std::is_scalar<T>, std::is_same<T, detail::decay_t<U>>>::value && std::is_constructible<T, U>::value
4847  && std::is_assignable<T&, U>::value>;
4848 
4849  template <class T, class U, class Other>
4850  using enable_assign_from_other = detail::enable_if_t<std::is_constructible<T, Other>::value && std::is_assignable<T&, Other>::value
4851  && !std::is_constructible<T, optional<U>&>::value && !std::is_constructible<T, optional<U>&&>::value
4852  && !std::is_constructible<T, const optional<U>&>::value && !std::is_constructible<T, const optional<U>&&>::value
4853  && !std::is_convertible<optional<U>&, T>::value && !std::is_convertible<optional<U>&&, T>::value
4854  && !std::is_convertible<const optional<U>&, T>::value && !std::is_convertible<const optional<U>&&, T>::value
4855  && !std::is_assignable<T&, optional<U>&>::value && !std::is_assignable<T&, optional<U>&&>::value
4856  && !std::is_assignable<T&, const optional<U>&>::value && !std::is_assignable<T&, const optional<U>&&>::value>;
4857 
4858 #ifdef _MSC_VER
4859  // TODO make a version which works with MSVC
4860  template <class T, class U = T>
4861  struct is_swappable : std::true_type { };
4862 
4863  template <class T, class U = T>
4864  struct is_nothrow_swappable : std::true_type { };
4865 #else
4866  // https://stackoverflow.com/questions/26744589/what-is-a-proper-way-to-implement-is-swappable-to-test-for-the-swappable-concept
4867  namespace swap_adl_tests {
4868  // if swap ADL finds this then it would call std::swap otherwise (same
4869  // signature)
4870  struct tag { };
4871 
4872  template <class T>
4873  tag swap(T&, T&);
4874  template <class T, std::size_t N>
4875  tag swap(T (&a)[N], T (&b)[N]);
4876 
4877  // helper functions to test if an unqualified swap is possible, and if it
4878  // becomes std::swap
4879  template <class, class>
4880  std::false_type can_swap(...) noexcept(false);
4881  template <class T, class U, class = decltype(swap(std::declval<T&>(), std::declval<U&>()))>
4882  std::true_type can_swap(int) noexcept(noexcept(swap(std::declval<T&>(), std::declval<U&>())));
4883 
4884  template <class, class>
4885  std::false_type uses_std(...);
4886  template <class T, class U>
4887  std::is_same<decltype(swap(std::declval<T&>(), std::declval<U&>())), tag> uses_std(int);
4888 
4889  template <class T>
4891  : std::integral_constant<bool, std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_assignable<T>::value> { };
4892 
4893  template <class T, std::size_t N>
4895 
4896  template <class T, class U>
4897  struct is_adl_swap_noexcept : std::integral_constant<bool, noexcept(can_swap<T, U>(0))> { };
4898  } // namespace swap_adl_tests
4899 
4900  template <class T, class U = T>
4901  struct is_swappable : std::integral_constant<bool,
4902  decltype(detail::swap_adl_tests::can_swap<T, U>(0))::value
4903  && (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value
4904  || (std::is_move_assignable<T>::value && std::is_move_constructible<T>::value))> { };
4905 
4906  template <class T, std::size_t N>
4907  struct is_swappable<T[N], T[N]> : std::integral_constant<bool,
4908  decltype(detail::swap_adl_tests::can_swap<T[N], T[N]>(0))::value
4909  && (!decltype(detail::swap_adl_tests::uses_std<T[N], T[N]>(0))::value || is_swappable<T, T>::value)> { };
4910 
4911  template <class T, class U = T>
4913  : std::integral_constant<bool,
4914  is_swappable<T, U>::value
4915  && ((decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value&& detail::swap_adl_tests::is_std_swap_noexcept<T>::value)
4916  || (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value&& detail::swap_adl_tests::is_adl_swap_noexcept<T, U>::value))> { };
4917 #endif
4918 
4919  // The storage base manages the actual storage, and correctly propagates
4920  // trivial destroyion from T. This case is for when T is not trivially
4921  // destructible.
4922  template <class T, bool = ::std::is_trivially_destructible<T>::value>
4924  SOL_TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept : m_dummy(), m_has_value(false) {
4925  }
4926 
4927  template <class... U>
4928  SOL_TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U&&... u) : m_value(std::forward<U>(u)...), m_has_value(true) {
4929  }
4930 
4931  ~optional_storage_base() {
4932  if (m_has_value) {
4933  m_value.~T();
4934  m_has_value = false;
4935  }
4936  }
4937 
4938  struct dummy { };
4939  union {
4940  dummy m_dummy;
4941  T m_value;
4942  };
4943 
4944  bool m_has_value;
4945  };
4946 
4947  // This case is for when T is trivially destructible.
4948  template <class T>
4949  struct optional_storage_base<T, true> {
4950  SOL_TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept : m_dummy(), m_has_value(false) {
4951  }
4952 
4953  template <class... U>
4954  SOL_TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U&&... u) : m_value(std::forward<U>(u)...), m_has_value(true) {
4955  }
4956 
4957  // No destructor, so this class is trivially destructible
4958 
4959  struct dummy { };
4960  union {
4961  dummy m_dummy;
4962  T m_value;
4963  };
4964 
4965  bool m_has_value = false;
4966  };
4967 
4968  // This base class provides some handy member functions which can be used in
4969  // further derived classes
4970  template <class T>
4973 
4974  void hard_reset() noexcept {
4975  get().~T();
4976  this->m_has_value = false;
4977  }
4978 
4979  template <class... Args>
4980  void construct(Args&&... args) noexcept {
4981  new (std::addressof(this->m_value)) T(std::forward<Args>(args)...);
4982  this->m_has_value = true;
4983  }
4984 
4985  template <class Opt>
4986  void assign(Opt&& rhs) {
4987  if (this->has_value()) {
4988  if (rhs.has_value()) {
4989  this->m_value = std::forward<Opt>(rhs).get();
4990  }
4991  else {
4992  this->m_value.~T();
4993  this->m_has_value = false;
4994  }
4995  }
4996 
4997  else if (rhs.has_value()) {
4998  construct(std::forward<Opt>(rhs).get());
4999  }
5000  }
5001 
5002  bool has_value() const {
5003  return this->m_has_value;
5004  }
5005 
5006  SOL_TL_OPTIONAL_11_CONSTEXPR T& get() & {
5007  return this->m_value;
5008  }
5009  SOL_TL_OPTIONAL_11_CONSTEXPR const T& get() const& {
5010  return this->m_value;
5011  }
5012  SOL_TL_OPTIONAL_11_CONSTEXPR T&& get() && {
5013  return std::move(this->m_value);
5014  }
5015 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5016  constexpr const T&& get() const&& {
5017  return std::move(this->m_value);
5018  }
5019 #endif
5020  };
5021 
5022  // This class manages conditionally having a trivial copy constructor
5023  // This specialization is for when T is trivially copy constructible
5024  template <class T, bool = SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)>
5027  };
5028 
5029  // This specialization is for when T is not trivially copy constructible
5030  template <class T>
5033 
5034  using base_t::base_t;
5035 
5036  optional_copy_base() = default;
5037  optional_copy_base(const optional_copy_base& rhs) : base_t() {
5038  if (rhs.has_value()) {
5039  this->construct(rhs.get());
5040  }
5041  else {
5042  this->m_has_value = false;
5043  }
5044  }
5045 
5046  optional_copy_base(optional_copy_base&& rhs) = default;
5047  optional_copy_base& operator=(const optional_copy_base& rhs) = default;
5048  optional_copy_base& operator=(optional_copy_base&& rhs) = default;
5049  };
5050 
5051 #ifndef SOL_TL_OPTIONAL_GCC49
5052  template <class T, bool = std::is_trivially_move_constructible<T>::value>
5055  };
5056 #else
5057  template <class T, bool = false>
5058  struct optional_move_base;
5059 #endif
5060  template <class T>
5061  struct optional_move_base<T, false> : optional_copy_base<T> {
5063 
5064  optional_move_base() = default;
5065  optional_move_base(const optional_move_base& rhs) = default;
5066 
5067  optional_move_base(optional_move_base&& rhs) noexcept(std::is_nothrow_move_constructible<T>::value) {
5068  if (rhs.has_value()) {
5069  this->construct(std::move(rhs.get()));
5070  }
5071  else {
5072  this->m_has_value = false;
5073  }
5074  }
5075  optional_move_base& operator=(const optional_move_base& rhs) = default;
5076  optional_move_base& operator=(optional_move_base&& rhs) = default;
5077  };
5078 
5079  // This class manages conditionally having a trivial copy assignment operator
5080  template <class T,
5081  bool = SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) && SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)
5082  && SOL_TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T)>
5085  };
5086 
5087  template <class T>
5090 
5091  optional_copy_assign_base() = default;
5093 
5095  optional_copy_assign_base& operator=(const optional_copy_assign_base& rhs) {
5096  this->assign(rhs);
5097  return *this;
5098  }
5099  optional_copy_assign_base& operator=(optional_copy_assign_base&& rhs) = default;
5100  };
5101 
5102 #ifndef SOL_TL_OPTIONAL_GCC49
5103  template <class T,
5104  bool = std::is_trivially_destructible<T>::value&& std::is_trivially_move_constructible<T>::value&& std::is_trivially_move_assignable<T>::value>
5107  };
5108 #else
5109  template <class T, bool = false>
5111 #endif
5112 
5113  template <class T>
5116 
5117  optional_move_assign_base() = default;
5119 
5121 
5122  optional_move_assign_base& operator=(const optional_move_assign_base& rhs) = default;
5123 
5124  optional_move_assign_base& operator=(optional_move_assign_base&& rhs) noexcept(
5125  std::is_nothrow_move_constructible<T>::value&& std::is_nothrow_move_assignable<T>::value) {
5126  this->assign(std::move(rhs));
5127  return *this;
5128  }
5129  };
5130 
5131  // optional_delete_ctor_base will conditionally delete copy and move
5132  // constructors depending on whether T is copy/move constructible
5133  template <class T, bool EnableCopy = std::is_copy_constructible<T>::value, bool EnableMove = std::is_move_constructible<T>::value>
5135  optional_delete_ctor_base() = default;
5138  optional_delete_ctor_base& operator=(const optional_delete_ctor_base&) = default;
5139  optional_delete_ctor_base& operator=(optional_delete_ctor_base&&) noexcept = default;
5140  };
5141 
5142  template <class T>
5143  struct optional_delete_ctor_base<T, true, false> {
5144  optional_delete_ctor_base() = default;
5147  optional_delete_ctor_base& operator=(const optional_delete_ctor_base&) = default;
5148  optional_delete_ctor_base& operator=(optional_delete_ctor_base&&) noexcept = default;
5149  };
5150 
5151  template <class T>
5152  struct optional_delete_ctor_base<T, false, true> {
5153  optional_delete_ctor_base() = default;
5156  optional_delete_ctor_base& operator=(const optional_delete_ctor_base&) = default;
5157  optional_delete_ctor_base& operator=(optional_delete_ctor_base&&) noexcept = default;
5158  };
5159 
5160  template <class T>
5161  struct optional_delete_ctor_base<T, false, false> {
5162  optional_delete_ctor_base() = default;
5165  optional_delete_ctor_base& operator=(const optional_delete_ctor_base&) = default;
5166  optional_delete_ctor_base& operator=(optional_delete_ctor_base&&) noexcept = default;
5167  };
5168 
5169  // optional_delete_assign_base will conditionally delete copy and move
5170  // constructors depending on whether T is copy/move constructible + assignable
5171  template <class T, bool EnableCopy = (std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value),
5172  bool EnableMove = (std::is_move_constructible<T>::value && std::is_move_assignable<T>::value)>
5174  optional_delete_assign_base() = default;
5177  optional_delete_assign_base& operator=(const optional_delete_assign_base&) = default;
5178  optional_delete_assign_base& operator=(optional_delete_assign_base&&) noexcept = default;
5179  };
5180 
5181  template <class T>
5182  struct optional_delete_assign_base<T, true, false> {
5183  optional_delete_assign_base() = default;
5186  optional_delete_assign_base& operator=(const optional_delete_assign_base&) = default;
5187  optional_delete_assign_base& operator=(optional_delete_assign_base&&) noexcept = delete;
5188  };
5189 
5190  template <class T>
5191  struct optional_delete_assign_base<T, false, true> {
5192  optional_delete_assign_base() = default;
5195  optional_delete_assign_base& operator=(const optional_delete_assign_base&) = delete;
5196  optional_delete_assign_base& operator=(optional_delete_assign_base&&) noexcept = default;
5197  };
5198 
5199  template <class T>
5200  struct optional_delete_assign_base<T, false, false> {
5201  optional_delete_assign_base() = default;
5204  optional_delete_assign_base& operator=(const optional_delete_assign_base&) = delete;
5205  optional_delete_assign_base& operator=(optional_delete_assign_base&&) noexcept = delete;
5206  };
5207 
5208  } // namespace detail
5209 
5211  using nullopt_t = std::nullopt_t;
5212 
5222  using std::nullopt;
5223 
5225  class bad_optional_access : public std::exception {
5226  public:
5228  bad_optional_access() = default;
5230  const char* what() const noexcept override {
5231  return "Optional has no value";
5232  }
5233  };
5234 
5241  template <class T>
5242  class optional : private detail::optional_move_assign_base<T>,
5246 
5247  static_assert(!std::is_same<T, in_place_t>::value, "instantiation of optional with in_place_t is ill-formed");
5248  static_assert(!std::is_same<detail::decay_t<T>, nullopt_t>::value, "instantiation of optional with nullopt_t is ill-formed");
5249 
5250  public:
5251 #if defined(SOL_TL_OPTIONAL_CXX14) && !defined(SOL_TL_OPTIONAL_GCC49) && !defined(SOL_TL_OPTIONAL_GCC54) && !defined(SOL_TL_OPTIONAL_GCC55)
5252  template <class F>
5263  SOL_TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f) & {
5264  using result = detail::invoke_result_t<F, T&>;
5265  static_assert(detail::is_optional<result>::value, "F must return an optional");
5266 
5267  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
5268  }
5269 
5272  template <class F>
5273  SOL_TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f) && {
5274  using result = detail::invoke_result_t<F, T&&>;
5275  static_assert(detail::is_optional<result>::value, "F must return an optional");
5276 
5277  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : result(nullopt);
5278  }
5279 
5282  template <class F>
5283  constexpr auto and_then(F&& f) const& {
5284  using result = detail::invoke_result_t<F, const T&>;
5285  static_assert(detail::is_optional<result>::value, "F must return an optional");
5286 
5287  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
5288  }
5289 
5290 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5291  template <class F>
5294  constexpr auto and_then(F&& f) const&& {
5295  using result = detail::invoke_result_t<F, const T&&>;
5296  static_assert(detail::is_optional<result>::value, "F must return an optional");
5297 
5298  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : result(nullopt);
5299  }
5300 #endif
5301 #else
5302  template <class F>
5313  SOL_TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T&> and_then(F&& f) & {
5314  using result = detail::invoke_result_t<F, T&>;
5315  static_assert(detail::is_optional<result>::value, "F must return an optional");
5316 
5317  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
5318  }
5319 
5322  template <class F>
5323  SOL_TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T&&> and_then(F&& f) && {
5324  using result = detail::invoke_result_t<F, T&&>;
5325  static_assert(detail::is_optional<result>::value, "F must return an optional");
5326 
5327  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : result(nullopt);
5328  }
5329 
5332  template <class F>
5333  constexpr detail::invoke_result_t<F, const T&> and_then(F&& f) const& {
5334  using result = detail::invoke_result_t<F, const T&>;
5335  static_assert(detail::is_optional<result>::value, "F must return an optional");
5336 
5337  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
5338  }
5339 
5340 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5341  template <class F>
5344  constexpr detail::invoke_result_t<F, const T&&> and_then(F&& f) const&& {
5345  using result = detail::invoke_result_t<F, const T&&>;
5346  static_assert(detail::is_optional<result>::value, "F must return an optional");
5347 
5348  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : result(nullopt);
5349  }
5350 #endif
5351 #endif
5352 
5353 #if defined(SOL_TL_OPTIONAL_CXX14) && !defined(SOL_TL_OPTIONAL_GCC49) && !defined(SOL_TL_OPTIONAL_GCC54) && !defined(SOL_TL_OPTIONAL_GCC55)
5354  template <class F>
5364  SOL_TL_OPTIONAL_11_CONSTEXPR auto map(F&& f) & {
5365  return optional_map_impl(*this, std::forward<F>(f));
5366  }
5367 
5370  template <class F>
5371  SOL_TL_OPTIONAL_11_CONSTEXPR auto map(F&& f) && {
5372  return optional_map_impl(std::move(*this), std::forward<F>(f));
5373  }
5374 
5377  template <class F>
5378  constexpr auto map(F&& f) const& {
5379  return optional_map_impl(*this, std::forward<F>(f));
5380  }
5381 
5384  template <class F>
5385  constexpr auto map(F&& f) const&& {
5386  return optional_map_impl(std::move(*this), std::forward<F>(f));
5387  }
5388 #else
5389  template <class F>
5399  SOL_TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval<optional&>(), std::declval<F&&>())) map(F&& f) & {
5400  return optional_map_impl(*this, std::forward<F>(f));
5401  }
5402 
5405  template <class F>
5406  SOL_TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval<optional&&>(), std::declval<F&&>())) map(F&& f) && {
5407  return optional_map_impl(std::move(*this), std::forward<F>(f));
5408  }
5409 
5412  template <class F>
5413  constexpr decltype(optional_map_impl(std::declval<const optional&>(), std::declval<F&&>())) map(F&& f) const& {
5414  return optional_map_impl(*this, std::forward<F>(f));
5415  }
5416 
5417 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5418  template <class F>
5421  constexpr decltype(optional_map_impl(std::declval<const optional&&>(), std::declval<F&&>())) map(F&& f) const&& {
5422  return optional_map_impl(std::move(*this), std::forward<F>(f));
5423  }
5424 #endif
5425 #endif
5426 
5436  template <class F, detail::enable_if_ret_void<F>* = nullptr>
5437  optional<T> SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) & {
5438  if (has_value())
5439  return *this;
5440 
5441  std::forward<F>(f)();
5442  return nullopt;
5443  }
5444 
5446  template <class F, detail::disable_if_ret_void<F>* = nullptr>
5447  optional<T> SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) & {
5448  return has_value() ? *this : std::forward<F>(f)();
5449  }
5450 
5453  template <class F, detail::enable_if_ret_void<F>* = nullptr>
5454  optional<T> or_else(F&& f) && {
5455  if (has_value())
5456  return std::move(*this);
5457 
5458  std::forward<F>(f)();
5459  return nullopt;
5460  }
5461 
5463  template <class F, detail::disable_if_ret_void<F>* = nullptr>
5464  optional<T> SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) && {
5465  return has_value() ? std::move(*this) : std::forward<F>(f)();
5466  }
5467 
5470  template <class F, detail::enable_if_ret_void<F>* = nullptr>
5471  optional<T> or_else(F&& f) const& {
5472  if (has_value())
5473  return *this;
5474 
5475  std::forward<F>(f)();
5476  return nullopt;
5477  }
5478 
5480  template <class F, detail::disable_if_ret_void<F>* = nullptr>
5481  optional<T> SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) const& {
5482  return has_value() ? *this : std::forward<F>(f)();
5483  }
5484 
5485 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5486  template <class F, detail::enable_if_ret_void<F>* = nullptr>
5488  optional<T> or_else(F&& f) const&& {
5489  if (has_value())
5490  return std::move(*this);
5491 
5492  std::forward<F>(f)();
5493  return nullopt;
5494  }
5495 
5497  template <class F, detail::disable_if_ret_void<F>* = nullptr>
5498  optional<T> or_else(F&& f) const&& {
5499  return has_value() ? std::move(*this) : std::forward<F>(f)();
5500  }
5501 #endif
5502 
5510  template <class F, class U>
5511  U map_or(F&& f, U&& u) & {
5512  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u);
5513  }
5514 
5516  template <class F, class U>
5517  U map_or(F&& f, U&& u) && {
5518  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u);
5519  }
5520 
5522  template <class F, class U>
5523  U map_or(F&& f, U&& u) const& {
5524  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u);
5525  }
5526 
5527 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5528  template <class F, class U>
5530  U map_or(F&& f, U&& u) const&& {
5531  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u);
5532  }
5533 #endif
5534 
5544  template <class F, class U>
5545  detail::invoke_result_t<U> map_or_else(F&& f, U&& u) & {
5546  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u)();
5547  }
5548 
5552  template <class F, class U>
5553  detail::invoke_result_t<U> map_or_else(F&& f, U&& u) && {
5554  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u)();
5555  }
5556 
5560  template <class F, class U>
5561  detail::invoke_result_t<U> map_or_else(F&& f, U&& u) const& {
5562  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u)();
5563  }
5564 
5565 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5566  template <class F, class U>
5570  detail::invoke_result_t<U> map_or_else(F&& f, U&& u) const&& {
5571  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u)();
5572  }
5573 #endif
5574 
5576  template <class U>
5578  using result = optional<detail::decay_t<U>>;
5579  return has_value() ? result { u } : result { nullopt };
5580  }
5581 
5584  SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional& rhs) & {
5585  return has_value() ? *this : rhs;
5586  }
5587 
5589  constexpr optional disjunction(const optional& rhs) const& {
5590  return has_value() ? *this : rhs;
5591  }
5592 
5594  SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional& rhs) && {
5595  return has_value() ? std::move(*this) : rhs;
5596  }
5597 
5598 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5599  constexpr optional disjunction(const optional& rhs) const&& {
5601  return has_value() ? std::move(*this) : rhs;
5602  }
5603 #endif
5604 
5606  SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional&& rhs) & {
5607  return has_value() ? *this : std::move(rhs);
5608  }
5609 
5611  constexpr optional disjunction(optional&& rhs) const& {
5612  return has_value() ? *this : std::move(rhs);
5613  }
5614 
5616  SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional&& rhs) && {
5617  return has_value() ? std::move(*this) : std::move(rhs);
5618  }
5619 
5620 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5621  constexpr optional disjunction(optional&& rhs) const&& {
5623  return has_value() ? std::move(*this) : std::move(rhs);
5624  }
5625 #endif
5626 
5630  optional ret = *this;
5631  reset();
5632  return ret;
5633  }
5634 
5636  optional take() const& {
5637  optional ret = *this;
5638  reset();
5639  return ret;
5640  }
5641 
5644  optional ret = std::move(*this);
5645  reset();
5646  return ret;
5647  }
5648 
5649 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5650  optional take() const&& {
5652  optional ret = std::move(*this);
5653  reset();
5654  return ret;
5655  }
5656 #endif
5657 
5658  using value_type = T;
5659 
5662  constexpr optional() noexcept = default;
5663 
5665  constexpr optional(nullopt_t) noexcept {
5666  }
5667 
5672  SOL_TL_OPTIONAL_11_CONSTEXPR optional(const optional& rhs) = default;
5673 
5678  SOL_TL_OPTIONAL_11_CONSTEXPR optional(optional&& rhs) = default;
5679 
5683  template <class... Args>
5684  constexpr explicit optional(detail::enable_if_t<std::is_constructible<T, Args...>::value, in_place_t>, Args&&... args)
5685  : base(in_place, std::forward<Args>(args)...) {
5686  }
5687 
5690  template <class U, class... Args>
5691  SOL_TL_OPTIONAL_11_CONSTEXPR explicit optional(detail::enable_if_t<std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value, in_place_t>,
5692  std::initializer_list<U> il, Args&&... args) {
5693  this->construct(il, std::forward<Args>(args)...);
5694  }
5695 
5696 #if 0 // SOL_MODIFICATION
5697  template <class U = T, detail::enable_if_t<std::is_convertible<U&&, T>::value>* = nullptr, detail::enable_forward_value<T, U>* = nullptr>
5700  constexpr optional(U&& u) : base(in_place, std::forward<U>(u)) {
5701  }
5702 
5704  template <class U = T, detail::enable_if_t<!std::is_convertible<U&&, T>::value>* = nullptr, detail::enable_forward_value<T, U>* = nullptr>
5705  constexpr explicit optional(U&& u) : base(in_place, std::forward<U>(u)) {
5706  }
5707 #else
5708  constexpr optional(T&& u) : base(in_place, std::move(u)) {
5711  }
5712 
5714  constexpr optional(const T& u) : base(in_place, u) {
5715  }
5716 #endif // sol2 modification
5717 
5720  template <class U, detail::enable_from_other<T, U, const U&>* = nullptr, detail::enable_if_t<std::is_convertible<const U&, T>::value>* = nullptr>
5721  optional(const optional<U>& rhs) {
5722  if (rhs.has_value()) {
5723  this->construct(*rhs);
5724  }
5725  }
5726 
5728  template <class U, detail::enable_from_other<T, U, const U&>* = nullptr, detail::enable_if_t<!std::is_convertible<const U&, T>::value>* = nullptr>
5729  explicit optional(const optional<U>& rhs) {
5730  if (rhs.has_value()) {
5731  this->construct(*rhs);
5732  }
5733  }
5734 
5737  template <class U, detail::enable_from_other<T, U, U&&>* = nullptr, detail::enable_if_t<std::is_convertible<U&&, T>::value>* = nullptr>
5739  if (rhs.has_value()) {
5740  this->construct(std::move(*rhs));
5741  }
5742  }
5743 
5745  template <class U, detail::enable_from_other<T, U, U&&>* = nullptr, detail::enable_if_t<!std::is_convertible<U&&, T>::value>* = nullptr>
5746  explicit optional(optional<U>&& rhs) {
5747  this->construct(std::move(*rhs));
5748  }
5749 
5751  ~optional() = default;
5752 
5756  optional& operator=(nullopt_t) noexcept {
5757  if (has_value()) {
5758  this->m_value.~T();
5759  this->m_has_value = false;
5760  }
5761 
5762  return *this;
5763  }
5764 
5769  optional& operator=(const optional& rhs) = default;
5770 
5775  optional& operator=(optional&& rhs) = default;
5776 
5780  template <class U = T, detail::enable_assign_forward<T, U>* = nullptr>
5781  optional& operator=(U&& u) {
5782  if (has_value()) {
5783  this->m_value = std::forward<U>(u);
5784  }
5785  else {
5786  this->construct(std::forward<U>(u));
5787  }
5788 
5789  return *this;
5790  }
5791 
5797  template <class U, detail::enable_assign_from_other<T, U, const U&>* = nullptr>
5798  optional& operator=(const optional<U>& rhs) {
5799  if (has_value()) {
5800  if (rhs.has_value()) {
5801  this->m_value = *rhs;
5802  }
5803  else {
5804  this->hard_reset();
5805  }
5806  }
5807 
5808  if (rhs.has_value()) {
5809  this->construct(*rhs);
5810  }
5811 
5812  return *this;
5813  }
5814 
5815  // TODO check exception guarantee
5821  template <class U, detail::enable_assign_from_other<T, U, U>* = nullptr>
5822  optional& operator=(optional<U>&& rhs) {
5823  if (has_value()) {
5824  if (rhs.has_value()) {
5825  this->m_value = std::move(*rhs);
5826  }
5827  else {
5828  this->hard_reset();
5829  }
5830  }
5831 
5832  if (rhs.has_value()) {
5833  this->construct(std::move(*rhs));
5834  }
5835 
5836  return *this;
5837  }
5838 
5842  template <class... Args>
5843  T& emplace(Args&&... args) {
5844  static_assert(std::is_constructible<T, Args&&...>::value, "T must be constructible with Args");
5845 
5846  *this = nullopt;
5847  this->construct(std::forward<Args>(args)...);
5848  return value();
5849  }
5850 
5853  template <class U, class... Args>
5854  detail::enable_if_t<std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value, T&> emplace(std::initializer_list<U> il, Args&&... args) {
5855  *this = nullopt;
5856  this->construct(il, std::forward<Args>(args)...);
5857  return value();
5858  }
5859 
5866  void swap(optional& rhs) noexcept(std::is_nothrow_move_constructible<T>::value&& detail::is_nothrow_swappable<T>::value) {
5867  if (has_value()) {
5868  if (rhs.has_value()) {
5869  using std::swap;
5870  swap(**this, *rhs);
5871  }
5872  else {
5873  new (std::addressof(rhs.m_value)) T(std::move(this->m_value));
5874  this->m_value.T::~T();
5875  }
5876  }
5877  else if (rhs.has_value()) {
5878  new (std::addressof(this->m_value)) T(std::move(rhs.m_value));
5879  rhs.m_value.T::~T();
5880  }
5881  }
5882 
5887  constexpr const T* operator->() const {
5888  return std::addressof(this->m_value);
5889  }
5890 
5893  SOL_TL_OPTIONAL_11_CONSTEXPR T* operator->() {
5894  return std::addressof(this->m_value);
5895  }
5896 
5901  SOL_TL_OPTIONAL_11_CONSTEXPR T& operator*() & {
5902  return this->m_value;
5903  }
5904 
5907  constexpr const T& operator*() const& {
5908  return this->m_value;
5909  }
5910 
5912  SOL_TL_OPTIONAL_11_CONSTEXPR T&& operator*() && {
5913  return std::move(this->m_value);
5914  }
5915 
5916 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5917  constexpr const T&& operator*() const&& {
5919  return std::move(this->m_value);
5920  }
5921 #endif
5922 
5925  constexpr bool has_value() const noexcept {
5926  return this->m_has_value;
5927  }
5928 
5930  constexpr explicit operator bool() const noexcept {
5931  return this->m_has_value;
5932  }
5933 
5938  SOL_TL_OPTIONAL_11_CONSTEXPR T& value() & {
5939  if (has_value())
5940  return this->m_value;
5941 #if SOL_IS_OFF(SOL_EXCEPTIONS)
5942  std::abort();
5943 #else
5944  throw bad_optional_access();
5945 #endif // No exceptions allowed
5946  }
5949  SOL_TL_OPTIONAL_11_CONSTEXPR const T& value() const& {
5950  if (has_value())
5951  return this->m_value;
5952 #if SOL_IS_OFF(SOL_EXCEPTIONS)
5953  std::abort();
5954 #else
5955  throw bad_optional_access();
5956 #endif // No exceptions allowed
5957  }
5959  SOL_TL_OPTIONAL_11_CONSTEXPR T&& value() && {
5960  if (has_value())
5961  return std::move(this->m_value);
5962 #if SOL_IS_OFF(SOL_EXCEPTIONS)
5963  std::abort();
5964 #else
5965  throw bad_optional_access();
5966 #endif // No exceptions allowed
5967  }
5968 
5969 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5970  SOL_TL_OPTIONAL_11_CONSTEXPR const T&& value() const&& {
5972  if (has_value())
5973  return std::move(this->m_value);
5974 #if SOL_IS_OFF(SOL_EXCEPTIONS)
5975  std::abort();
5976 #else
5977  throw bad_optional_access();
5978 #endif // No exceptions allowed
5979  }
5980 #endif
5981 
5984  template <class U>
5985  constexpr T value_or(U&& u) const& {
5986  static_assert(std::is_copy_constructible<T>::value && std::is_convertible<U&&, T>::value, "T must be copy constructible and convertible from U");
5987  return has_value() ? **this : static_cast<T>(std::forward<U>(u));
5988  }
5989 
5991  template <class U>
5992  SOL_TL_OPTIONAL_11_CONSTEXPR T value_or(U&& u) && {
5993  static_assert(std::is_move_constructible<T>::value && std::is_convertible<U&&, T>::value, "T must be move constructible and convertible from U");
5994  return has_value() ? **this : static_cast<T>(std::forward<U>(u));
5995  }
5996 
5998  void reset() noexcept {
5999  if (has_value()) {
6000  this->m_value.~T();
6001  this->m_has_value = false;
6002  }
6003  }
6004  }; // namespace sol
6005 
6012  template <class T, class U>
6013  inline constexpr bool operator==(const optional<T>& lhs, const optional<U>& rhs) {
6014  return lhs.has_value() == rhs.has_value() && (!lhs.has_value() || *lhs == *rhs);
6015  }
6017  template <class T, class U>
6018  inline constexpr bool operator!=(const optional<T>& lhs, const optional<U>& rhs) {
6019  return lhs.has_value() != rhs.has_value() || (lhs.has_value() && *lhs != *rhs);
6020  }
6022  template <class T, class U>
6023  inline constexpr bool operator<(const optional<T>& lhs, const optional<U>& rhs) {
6024  return rhs.has_value() && (!lhs.has_value() || *lhs < *rhs);
6025  }
6027  template <class T, class U>
6028  inline constexpr bool operator>(const optional<T>& lhs, const optional<U>& rhs) {
6029  return lhs.has_value() && (!rhs.has_value() || *lhs > *rhs);
6030  }
6032  template <class T, class U>
6033  inline constexpr bool operator<=(const optional<T>& lhs, const optional<U>& rhs) {
6034  return !lhs.has_value() || (rhs.has_value() && *lhs <= *rhs);
6035  }
6037  template <class T, class U>
6038  inline constexpr bool operator>=(const optional<T>& lhs, const optional<U>& rhs) {
6039  return !rhs.has_value() || (lhs.has_value() && *lhs >= *rhs);
6040  }
6041 
6045  template <class T>
6046  inline constexpr bool operator==(const optional<T>& lhs, nullopt_t) noexcept {
6047  return !lhs.has_value();
6048  }
6050  template <class T>
6051  inline constexpr bool operator==(nullopt_t, const optional<T>& rhs) noexcept {
6052  return !rhs.has_value();
6053  }
6055  template <class T>
6056  inline constexpr bool operator!=(const optional<T>& lhs, nullopt_t) noexcept {
6057  return lhs.has_value();
6058  }
6060  template <class T>
6061  inline constexpr bool operator!=(nullopt_t, const optional<T>& rhs) noexcept {
6062  return rhs.has_value();
6063  }
6065  template <class T>
6066  inline constexpr bool operator<(const optional<T>&, nullopt_t) noexcept {
6067  return false;
6068  }
6070  template <class T>
6071  inline constexpr bool operator<(nullopt_t, const optional<T>& rhs) noexcept {
6072  return rhs.has_value();
6073  }
6075  template <class T>
6076  inline constexpr bool operator<=(const optional<T>& lhs, nullopt_t) noexcept {
6077  return !lhs.has_value();
6078  }
6080  template <class T>
6081  inline constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept {
6082  return true;
6083  }
6085  template <class T>
6086  inline constexpr bool operator>(const optional<T>& lhs, nullopt_t) noexcept {
6087  return lhs.has_value();
6088  }
6090  template <class T>
6091  inline constexpr bool operator>(nullopt_t, const optional<T>&) noexcept {
6092  return false;
6093  }
6095  template <class T>
6096  inline constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept {
6097  return true;
6098  }
6100  template <class T>
6101  inline constexpr bool operator>=(nullopt_t, const optional<T>& rhs) noexcept {
6102  return !rhs.has_value();
6103  }
6104 
6110  template <class T, class U>
6111  inline constexpr bool operator==(const optional<T>& lhs, const U& rhs) {
6112  return lhs.has_value() ? *lhs == rhs : false;
6113  }
6115  template <class T, class U>
6116  inline constexpr bool operator==(const U& lhs, const optional<T>& rhs) {
6117  return rhs.has_value() ? lhs == *rhs : false;
6118  }
6120  template <class T, class U>
6121  inline constexpr bool operator!=(const optional<T>& lhs, const U& rhs) {
6122  return lhs.has_value() ? *lhs != rhs : true;
6123  }
6125  template <class T, class U>
6126  inline constexpr bool operator!=(const U& lhs, const optional<T>& rhs) {
6127  return rhs.has_value() ? lhs != *rhs : true;
6128  }
6130  template <class T, class U>
6131  inline constexpr bool operator<(const optional<T>& lhs, const U& rhs) {
6132  return lhs.has_value() ? *lhs < rhs : true;
6133  }
6135  template <class T, class U>
6136  inline constexpr bool operator<(const U& lhs, const optional<T>& rhs) {
6137  return rhs.has_value() ? lhs < *rhs : false;
6138  }
6140  template <class T, class U>
6141  inline constexpr bool operator<=(const optional<T>& lhs, const U& rhs) {
6142  return lhs.has_value() ? *lhs <= rhs : true;
6143  }
6145  template <class T, class U>
6146  inline constexpr bool operator<=(const U& lhs, const optional<T>& rhs) {
6147  return rhs.has_value() ? lhs <= *rhs : false;
6148  }
6150  template <class T, class U>
6151  inline constexpr bool operator>(const optional<T>& lhs, const U& rhs) {
6152  return lhs.has_value() ? *lhs > rhs : false;
6153  }
6155  template <class T, class U>
6156  inline constexpr bool operator>(const U& lhs, const optional<T>& rhs) {
6157  return rhs.has_value() ? lhs > *rhs : true;
6158  }
6160  template <class T, class U>
6161  inline constexpr bool operator>=(const optional<T>& lhs, const U& rhs) {
6162  return lhs.has_value() ? *lhs >= rhs : false;
6163  }
6165  template <class T, class U>
6166  inline constexpr bool operator>=(const U& lhs, const optional<T>& rhs) {
6167  return rhs.has_value() ? lhs >= *rhs : true;
6168  }
6169 
6171  template <class T, detail::enable_if_t<std::is_move_constructible<T>::value>* = nullptr, detail::enable_if_t<detail::is_swappable<T>::value>* = nullptr>
6172  void swap(optional<T>& lhs, optional<T>& rhs) noexcept(noexcept(lhs.swap(rhs))) {
6173  return lhs.swap(rhs);
6174  }
6175 
6176  namespace detail {
6177  struct i_am_secret { };
6178  } // namespace detail
6179 
6180  template <class T = detail::i_am_secret, class U, class Ret = detail::conditional_t<std::is_same<T, detail::i_am_secret>::value, detail::decay_t<U>, T>>
6181  inline constexpr optional<Ret> make_optional(U&& v) {
6182  return optional<Ret>(std::forward<U>(v));
6183  }
6184 
6185  template <class T, class... Args>
6186  inline constexpr optional<T> make_optional(Args&&... args) {
6187  return optional<T>(in_place, std::forward<Args>(args)...);
6188  }
6189  template <class T, class U, class... Args>
6190  inline constexpr optional<T> make_optional(std::initializer_list<U> il, Args&&... args) {
6191  return optional<T>(in_place, il, std::forward<Args>(args)...);
6192  }
6193 
6194 #if __cplusplus >= 201703L
6195  template <class T>
6196  optional(T) -> optional<T>;
6197 #endif
6198 
6200  namespace detail {
6201 #ifdef SOL_TL_OPTIONAL_CXX14
6202  template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
6203  detail::enable_if_t<!std::is_void<Ret>::value>* = nullptr>
6204  constexpr auto optional_map_impl(Opt&& opt, F&& f) {
6205  return opt.has_value() ? detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt)) : optional<Ret>(nullopt);
6206  }
6207 
6208  template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
6209  detail::enable_if_t<std::is_void<Ret>::value>* = nullptr>
6210  auto optional_map_impl(Opt&& opt, F&& f) {
6211  if (opt.has_value()) {
6212  detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt));
6213  return make_optional(monostate {});
6214  }
6215 
6216  return optional<monostate>(nullopt);
6217  }
6218 #else
6219  template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
6220  detail::enable_if_t<!std::is_void<Ret>::value>* = nullptr>
6221 
6222  constexpr auto optional_map_impl(Opt&& opt, F&& f) -> optional<Ret> {
6223  return opt.has_value() ? detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt)) : optional<Ret>(nullopt);
6224  }
6225 
6226  template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
6227  detail::enable_if_t<std::is_void<Ret>::value>* = nullptr>
6228 
6229  auto optional_map_impl(Opt&& opt, F&& f) -> optional<monostate> {
6230  if (opt.has_value()) {
6231  detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt));
6232  return monostate {};
6233  }
6234 
6235  return nullopt;
6236  }
6237 #endif
6238  } // namespace detail
6239 
6262  template <class T>
6263  class optional<T&> {
6264  public:
6265 #if defined(SOL_TL_OPTIONAL_CXX14) && !defined(SOL_TL_OPTIONAL_GCC49) && !defined(SOL_TL_OPTIONAL_GCC54) && !defined(SOL_TL_OPTIONAL_GCC55)
6266  template <class F>
6277  SOL_TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f) & {
6278  using result = detail::invoke_result_t<F, T&>;
6279  static_assert(detail::is_optional<result>::value, "F must return an optional");
6280 
6281  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
6282  }
6283 
6286  template <class F>
6287  SOL_TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f) && {
6288  using result = detail::invoke_result_t<F, T&>;
6289  static_assert(detail::is_optional<result>::value, "F must return an optional");
6290 
6291  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
6292  }
6293 
6296  template <class F>
6297  constexpr auto and_then(F&& f) const& {
6298  using result = detail::invoke_result_t<F, const T&>;
6299  static_assert(detail::is_optional<result>::value, "F must return an optional");
6300 
6301  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
6302  }
6303 
6304 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6305  template <class F>
6308  constexpr auto and_then(F&& f) const&& {
6309  using result = detail::invoke_result_t<F, const T&>;
6310  static_assert(detail::is_optional<result>::value, "F must return an optional");
6311 
6312  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
6313  }
6314 #endif
6315 #else
6316  template <class F>
6327  SOL_TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T&> and_then(F&& f) & {
6328  using result = detail::invoke_result_t<F, T&>;
6329  static_assert(detail::is_optional<result>::value, "F must return an optional");
6330 
6331  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
6332  }
6333 
6336  template <class F>
6337  SOL_TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T&> and_then(F&& f) && {
6338  using result = detail::invoke_result_t<F, T&>;
6339  static_assert(detail::is_optional<result>::value, "F must return an optional");
6340 
6341  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
6342  }
6343 
6346  template <class F>
6347  constexpr detail::invoke_result_t<F, const T&> and_then(F&& f) const& {
6348  using result = detail::invoke_result_t<F, const T&>;
6349  static_assert(detail::is_optional<result>::value, "F must return an optional");
6350 
6351  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
6352  }
6353 
6354 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6355  template <class F>
6358  constexpr detail::invoke_result_t<F, const T&> and_then(F&& f) const&& {
6359  using result = detail::invoke_result_t<F, const T&>;
6360  static_assert(detail::is_optional<result>::value, "F must return an optional");
6361 
6362  return has_value() ? detail::invoke(std::forward<F>(f), **this) : result(nullopt);
6363  }
6364 #endif
6365 #endif
6366 
6367 #if defined(SOL_TL_OPTIONAL_CXX14) && !defined(SOL_TL_OPTIONAL_GCC49) && !defined(SOL_TL_OPTIONAL_GCC54) && !defined(SOL_TL_OPTIONAL_GCC55)
6368  template <class F>
6378  SOL_TL_OPTIONAL_11_CONSTEXPR auto map(F&& f) & {
6379  return detail::optional_map_impl(*this, std::forward<F>(f));
6380  }
6381 
6384  template <class F>
6385  SOL_TL_OPTIONAL_11_CONSTEXPR auto map(F&& f) && {
6386  return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
6387  }
6388 
6391  template <class F>
6392  constexpr auto map(F&& f) const& {
6393  return detail::optional_map_impl(*this, std::forward<F>(f));
6394  }
6395 
6398  template <class F>
6399  constexpr auto map(F&& f) const&& {
6400  return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
6401  }
6402 #else
6403  template <class F>
6413  SOL_TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl(std::declval<optional&>(), std::declval<F&&>())) map(F&& f) & {
6414  return detail::optional_map_impl(*this, std::forward<F>(f));
6415  }
6416 
6419  template <class F>
6420  SOL_TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl(std::declval<optional&&>(), std::declval<F&&>())) map(F&& f) && {
6421  return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
6422  }
6423 
6426  template <class F>
6427  constexpr decltype(detail::optional_map_impl(std::declval<const optional&>(), std::declval<F&&>())) map(F&& f) const& {
6428  return detail::optional_map_impl(*this, std::forward<F>(f));
6429  }
6430 
6431 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6432  template <class F>
6435  constexpr decltype(detail::optional_map_impl(std::declval<const optional&&>(), std::declval<F&&>())) map(F&& f) const&& {
6436  return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
6437  }
6438 #endif
6439 #endif
6440 
6449  template <class F, detail::enable_if_ret_void<F>* = nullptr>
6450  optional<T> SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) & {
6451  if (has_value())
6452  return *this;
6453 
6454  std::forward<F>(f)();
6455  return nullopt;
6456  }
6457 
6459  template <class F, detail::disable_if_ret_void<F>* = nullptr>
6460  optional<T> SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) & {
6461  return has_value() ? *this : std::forward<F>(f)();
6462  }
6463 
6466  template <class F, detail::enable_if_ret_void<F>* = nullptr>
6467  optional<T> or_else(F&& f) && {
6468  if (has_value())
6469  return std::move(*this);
6470 
6471  std::forward<F>(f)();
6472  return nullopt;
6473  }
6474 
6476  template <class F, detail::disable_if_ret_void<F>* = nullptr>
6477  optional<T> SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) && {
6478  return has_value() ? std::move(*this) : std::forward<F>(f)();
6479  }
6480 
6483  template <class F, detail::enable_if_ret_void<F>* = nullptr>
6484  optional<T> or_else(F&& f) const& {
6485  if (has_value())
6486  return *this;
6487 
6488  std::forward<F>(f)();
6489  return nullopt;
6490  }
6491 
6493  template <class F, detail::disable_if_ret_void<F>* = nullptr>
6494  optional<T> SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) const& {
6495  return has_value() ? *this : std::forward<F>(f)();
6496  }
6497 
6498 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6499  template <class F, detail::enable_if_ret_void<F>* = nullptr>
6501  optional<T> or_else(F&& f) const&& {
6502  if (has_value())
6503  return std::move(*this);
6504 
6505  std::forward<F>(f)();
6506  return nullopt;
6507  }
6508 
6510  template <class F, detail::disable_if_ret_void<F>* = nullptr>
6511  optional<T> or_else(F&& f) const&& {
6512  return has_value() ? std::move(*this) : std::forward<F>(f)();
6513  }
6514 #endif
6515 
6523  template <class F, class U>
6524  U map_or(F&& f, U&& u) & {
6525  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u);
6526  }
6527 
6529  template <class F, class U>
6530  U map_or(F&& f, U&& u) && {
6531  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u);
6532  }
6533 
6535  template <class F, class U>
6536  U map_or(F&& f, U&& u) const& {
6537  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u);
6538  }
6539 
6540 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6541  template <class F, class U>
6543  U map_or(F&& f, U&& u) const&& {
6544  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u);
6545  }
6546 #endif
6547 
6557  template <class F, class U>
6558  detail::invoke_result_t<U> map_or_else(F&& f, U&& u) & {
6559  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u)();
6560  }
6561 
6565  template <class F, class U>
6566  detail::invoke_result_t<U> map_or_else(F&& f, U&& u) && {
6567  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u)();
6568  }
6569 
6573  template <class F, class U>
6574  detail::invoke_result_t<U> map_or_else(F&& f, U&& u) const& {
6575  return has_value() ? detail::invoke(std::forward<F>(f), **this) : std::forward<U>(u)();
6576  }
6577 
6578 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6579  template <class F, class U>
6583  detail::invoke_result_t<U> map_or_else(F&& f, U&& u) const&& {
6584  return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) : std::forward<U>(u)();
6585  }
6586 #endif
6587 
6589  template <class U>
6591  using result = optional<detail::decay_t<U>>;
6592  return has_value() ? result { u } : result { nullopt };
6593  }
6594 
6597  SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional& rhs) & {
6598  return has_value() ? *this : rhs;
6599  }
6600 
6602  constexpr optional disjunction(const optional& rhs) const& {
6603  return has_value() ? *this : rhs;
6604  }
6605 
6607  SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional& rhs) && {
6608  return has_value() ? std::move(*this) : rhs;
6609  }
6610 
6611 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6612  constexpr optional disjunction(const optional& rhs) const&& {
6614  return has_value() ? std::move(*this) : rhs;
6615  }
6616 #endif
6617 
6619  SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional&& rhs) & {
6620  return has_value() ? *this : std::move(rhs);
6621  }
6622 
6624  constexpr optional disjunction(optional&& rhs) const& {
6625  return has_value() ? *this : std::move(rhs);
6626  }
6627 
6629  SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional&& rhs) && {
6630  return has_value() ? std::move(*this) : std::move(rhs);
6631  }
6632 
6633 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6634  constexpr optional disjunction(optional&& rhs) const&& {
6636  return has_value() ? std::move(*this) : std::move(rhs);
6637  }
6638 #endif
6639 
6643  optional ret = *this;
6644  reset();
6645  return ret;
6646  }
6647 
6649  optional take() const& {
6650  optional ret = *this;
6651  reset();
6652  return ret;
6653  }
6654 
6657  optional ret = std::move(*this);
6658  reset();
6659  return ret;
6660  }
6661 
6662 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6663  optional take() const&& {
6665  optional ret = std::move(*this);
6666  reset();
6667  return ret;
6668  }
6669 #endif
6670 
6671  using value_type = T&;
6672 
6675  constexpr optional() noexcept : m_value(nullptr) {
6676  }
6677 
6679  constexpr optional(nullopt_t) noexcept : m_value(nullptr) {
6680  }
6681 
6686  SOL_TL_OPTIONAL_11_CONSTEXPR optional(const optional& rhs) noexcept = default;
6687 
6692  SOL_TL_OPTIONAL_11_CONSTEXPR optional(optional&& rhs) = default;
6693 
6696  template <class U = T, detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>* = nullptr>
6697  constexpr optional(U&& u) : m_value(std::addressof(u)) {
6698  static_assert(std::is_lvalue_reference<U>::value, "U must be an lvalue");
6699  }
6700 
6702  template <class U>
6703  constexpr explicit optional(const optional<U>& rhs) : optional(*rhs) {
6704  }
6705 
6707  ~optional() = default;
6708 
6712  optional& operator=(nullopt_t) noexcept {
6713  m_value = nullptr;
6714  return *this;
6715  }
6716 
6721  optional& operator=(const optional& rhs) = default;
6722 
6727  template <class U = T, detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>* = nullptr>
6729  static_assert(std::is_lvalue_reference<U>::value, "U must be an lvalue");
6730  m_value = std::addressof(u);
6731  return *this;
6732  }
6733 
6738  template <class U>
6740  m_value = std::addressof(rhs.value());
6741  return *this;
6742  }
6743 
6748  template <class... Args>
6749  T& emplace(Args&&... args) noexcept {
6750  static_assert(std::is_constructible<T, Args&&...>::value, "T must be constructible with Args");
6751 
6752  *this = nullopt;
6753  this->construct(std::forward<Args>(args)...);
6754  }
6755 
6762  void swap(optional& rhs) noexcept {
6763  std::swap(m_value, rhs.m_value);
6764  }
6765 
6770  constexpr const T* operator->() const {
6771  return m_value;
6772  }
6773 
6776  SOL_TL_OPTIONAL_11_CONSTEXPR T* operator->() {
6777  return m_value;
6778  }
6779 
6784  SOL_TL_OPTIONAL_11_CONSTEXPR T& operator*() {
6785  return *m_value;
6786  }
6787 
6790  constexpr const T& operator*() const {
6791  return *m_value;
6792  }
6793 
6796  constexpr bool has_value() const noexcept {
6797  return m_value != nullptr;
6798  }
6799 
6801  constexpr explicit operator bool() const noexcept {
6802  return m_value != nullptr;
6803  }
6804 
6809  SOL_TL_OPTIONAL_11_CONSTEXPR T& value() {
6810  if (has_value())
6811  return *m_value;
6812 #if SOL_IS_OFF(SOL_EXCEPTIONS)
6813  std::abort();
6814 #else
6815  throw bad_optional_access();
6816 #endif // No exceptions allowed
6817  }
6820  SOL_TL_OPTIONAL_11_CONSTEXPR const T& value() const {
6821  if (has_value())
6822  return *m_value;
6823 #if SOL_IS_OFF(SOL_EXCEPTIONS)
6824  std::abort();
6825 #else
6826  throw bad_optional_access();
6827 #endif // No exceptions allowed
6828  }
6829 
6832  template <class U>
6833  constexpr T& value_or(U&& u) const {
6834  static_assert(std::is_convertible<U&&, T&>::value, "T must be convertible from U");
6835  return has_value() ? const_cast<T&>(**this) : static_cast<T&>(std::forward<U>(u));
6836  }
6837 
6839  void reset() noexcept {
6840  m_value = nullptr;
6841  }
6842 
6843  private:
6844  T* m_value;
6845  };
6846 
6847 } // namespace sol
6848 
6849 namespace std {
6850  // TODO SFINAE
6851  template <class T>
6852  struct hash<::sol::optional<T>> {
6853  ::std::size_t operator()(const ::sol::optional<T>& o) const {
6854  if (!o.has_value())
6855  return 0;
6856 
6857  return ::std::hash<::sol::detail::remove_const_t<T>>()(*o);
6858  }
6859  };
6860 } // namespace std
6861 
6862 // end of sol/optional_implementation.hpp
6863 
6864 #endif // Boost vs. Better optional
6865 
6866 #include <optional>
6867 
6868 namespace sol {
6869 
6870 #if SOL_IS_ON(SOL_USE_BOOST)
6871  template <typename T>
6872  using optional = boost::optional<T>;
6873  using nullopt_t = boost::none_t;
6874  SOL_BOOST_NONE_CONSTEXPR_I_ nullopt_t nullopt = boost::none;
6875 #endif // Boost vs. Better optional
6876 
6877  namespace meta {
6878  template <typename T>
6879  using is_optional = any<is_specialization_of<T, optional>, is_specialization_of<T, std::optional>>;
6880 
6881  template <typename T>
6882  constexpr inline bool is_optional_v = is_optional<T>::value;
6883  } // namespace meta
6884 
6885  namespace detail {
6886  template <typename T>
6888  inline static constexpr std::nullopt_t value = std::nullopt;
6889  };
6890 
6891 #if SOL_IS_ON(SOL_USE_BOOST)
6892  template <typename T>
6893  struct associated_nullopt<boost::optional<T>> {
6894  inline static SOL_BOOST_NONE_CONSTEXPR_I_ boost::none_t value = boost::none;
6895  };
6896 #endif // Boost nullopt
6897 
6898 #if SOL_IS_ON(SOL_USE_BOOST)
6899  template <typename T>
6900  inline SOL_BOOST_NONE_CONSTEXPR_I_ auto associated_nullopt_v = associated_nullopt<T>::value;
6901 #else
6902  template <typename T>
6903  inline constexpr auto associated_nullopt_v = associated_nullopt<T>::value;
6904 #endif // Boost continues to lag behind, to not many people's surprise...
6905  } // namespace detail
6906 } // namespace sol
6907 
6908 #if SOL_IS_ON(SOL_USE_BOOST)
6909 #undef SOL_BOOST_NONE_CONSTEXPR_I_
6910 #endif
6911 
6912 // end of sol/optional.hpp
6913 
6914 // beginning of sol/raii.hpp
6915 
6916 #include <memory>
6917 
6918 namespace sol {
6919  namespace detail {
6921  template <typename T, typename... Args>
6922  static void construct(T&& obj, Args&&... args) {
6923  typedef meta::unqualified_t<T> Tu;
6924  std::allocator<Tu> alloc {};
6925  std::allocator_traits<std::allocator<Tu>>::construct(alloc, std::forward<T>(obj), std::forward<Args>(args)...);
6926  }
6927 
6928  template <typename T, typename... Args>
6929  void operator()(T&& obj, Args&&... args) const {
6930  construct(std::forward<T>(obj), std::forward<Args>(args)...);
6931  }
6932  };
6933 
6935  template <typename T>
6936  static void destroy(T&& obj) {
6937  std::allocator<meta::unqualified_t<T>> alloc {};
6938  alloc.destroy(obj);
6939  }
6940 
6941  template <typename T>
6942  void operator()(T&& obj) const {
6943  destroy(std::forward<T>(obj));
6944  }
6945  };
6946 
6947  struct deleter {
6948  template <typename T>
6949  void operator()(T* p) const {
6950  delete p;
6951  }
6952  };
6953 
6954  struct state_deleter {
6955  void operator()(lua_State* L) const {
6956  lua_close(L);
6957  }
6958  };
6959 
6960  template <typename T, typename Dx, typename... Args>
6961  inline std::unique_ptr<T, Dx> make_unique_deleter(Args&&... args) {
6962  return std::unique_ptr<T, Dx>(new T(std::forward<Args>(args)...));
6963  }
6964 
6965  template <typename Tag, typename T>
6966  struct tagged {
6967  private:
6968  T value_;
6969 
6970  public:
6971  template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, tagged>> = meta::enabler>
6972  tagged(Arg&& arg, Args&&... args) : value_(std::forward<Arg>(arg), std::forward<Args>(args)...) {
6973  }
6974 
6975  T& value() & {
6976  return value_;
6977  }
6978 
6979  T const& value() const& {
6980  return value_;
6981  }
6982 
6983  T&& value() && {
6984  return std::move(value_);
6985  }
6986  };
6987  } // namespace detail
6988 
6989  template <typename... Args>
6990  struct constructor_list { };
6991 
6992  template <typename... Args>
6993  using constructors = constructor_list<Args...>;
6994 
6995  const auto default_constructor = constructors<types<>> {};
6996 
6997  struct no_construction { };
6998  const auto no_constructor = no_construction {};
6999 
7000  struct call_construction { };
7001  const auto call_constructor = call_construction {};
7002 
7003  template <typename... Functions>
7005  std::tuple<Functions...> functions;
7006  template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, constructor_wrapper>> = meta::enabler>
7007  constructor_wrapper(Arg&& arg, Args&&... args) : functions(std::forward<Arg>(arg), std::forward<Args>(args)...) {
7008  }
7009  };
7010 
7011  template <typename... Functions>
7012  inline auto initializers(Functions&&... functions) {
7013  return constructor_wrapper<std::decay_t<Functions>...>(std::forward<Functions>(functions)...);
7014  }
7015 
7016  template <typename... Functions>
7018  std::tuple<Functions...> functions;
7019  template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, factory_wrapper>> = meta::enabler>
7020  factory_wrapper(Arg&& arg, Args&&... args) : functions(std::forward<Arg>(arg), std::forward<Args>(args)...) {
7021  }
7022  };
7023 
7024  template <typename... Functions>
7025  inline auto factories(Functions&&... functions) {
7026  return factory_wrapper<std::decay_t<Functions>...>(std::forward<Functions>(functions)...);
7027  }
7028 
7029  template <typename Function>
7031  Function fx;
7032  destructor_wrapper(Function f) : fx(std::move(f)) {
7033  }
7034  };
7035 
7036  template <>
7037  struct destructor_wrapper<void> { };
7038 
7039  const destructor_wrapper<void> default_destructor {};
7040 
7041  template <typename Fx>
7042  inline auto destructor(Fx&& fx) {
7043  return destructor_wrapper<std::decay_t<Fx>>(std::forward<Fx>(fx));
7044  }
7045 
7046 } // namespace sol
7047 
7048 // end of sol/raii.hpp
7049 
7050 // beginning of sol/policies.hpp
7051 
7052 #include <array>
7053 
7054 namespace sol {
7055  namespace detail {
7056  struct policy_base_tag { };
7057  } // namespace detail
7058 
7059  template <int Target, int... In>
7062  template <int... In>
7065 
7067  int target;
7068  std::array<int, 64> stack_indices;
7069  std::size_t len;
7070 
7071  template <typename... Args>
7072  stack_dependencies(int stack_target, Args&&... args) : target(stack_target), stack_indices(), len(sizeof...(Args)) {
7073  std::size_t i = 0;
7074  (void)detail::swallow { int(), (stack_indices[i++] = static_cast<int>(std::forward<Args>(args)), int())... };
7075  }
7076 
7077  int& operator[](std::size_t i) {
7078  return stack_indices[i];
7079  }
7080 
7081  const int& operator[](std::size_t i) const {
7082  return stack_indices[i];
7083  }
7084 
7085  std::size_t size() const {
7086  return len;
7087  }
7088  };
7089 
7090  template <typename F, typename... Policies>
7091  struct policy_wrapper {
7092  typedef std::index_sequence_for<Policies...> indices;
7093 
7094  F value;
7095  std::tuple<Policies...> policies;
7096 
7097  template <typename Fx, typename... Args, meta::enable<meta::neg<std::is_same<meta::unqualified_t<Fx>, policy_wrapper>>> = meta::enabler>
7098  policy_wrapper(Fx&& fx, Args&&... args) : value(std::forward<Fx>(fx)), policies(std::forward<Args>(args)...) {
7099  }
7100 
7101  policy_wrapper(const policy_wrapper&) = default;
7102  policy_wrapper& operator=(const policy_wrapper&) = default;
7103  policy_wrapper(policy_wrapper&&) = default;
7104  policy_wrapper& operator=(policy_wrapper&&) = default;
7105  };
7106 
7107  template <typename F, typename... Args>
7108  auto policies(F&& f, Args&&... args) {
7109  return policy_wrapper<std::decay_t<F>, std::decay_t<Args>...>(std::forward<F>(f), std::forward<Args>(args)...);
7110  }
7111 
7112  namespace detail {
7113  template <typename T>
7115 
7116  template <typename T>
7117  inline constexpr bool is_policy_v = is_policy<T>::value;
7118  } // namespace detail
7119 } // namespace sol
7120 
7121 // end of sol/policies.hpp
7122 
7123 // beginning of sol/ebco.hpp
7124 
7125 #include <type_traits>
7126 #include <utility>
7127 #include <memory>
7128 
7129 namespace sol { namespace detail {
7130 
7131  template <typename T, std::size_t tag = 0, typename = void>
7132  struct ebco {
7133  T m_value;
7134 
7135  ebco() = default;
7136  ebco(const ebco&) = default;
7137  ebco(ebco&&) = default;
7138  ebco& operator=(const ebco&) = default;
7139  ebco& operator=(ebco&&) = default;
7140  ebco(const T& v) noexcept(std::is_nothrow_copy_constructible_v<T>) : m_value(v) {};
7141  ebco(T&& v) noexcept(std::is_nothrow_move_constructible_v<T>) : m_value(std::move(v)) {};
7142  ebco& operator=(const T& v) noexcept(std::is_nothrow_copy_assignable_v<T>) {
7143  m_value = v;
7144  return *this;
7145  }
7146  ebco& operator=(T&& v) noexcept(std::is_nothrow_move_assignable_v<T>) {
7147  m_value = std::move(v);
7148  return *this;
7149  };
7150  template <typename Arg, typename... Args,
7151  typename = std::enable_if_t<
7152  !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
7153  ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T> && (sizeof...(Args) > 0 || !std::is_convertible_v<Arg, T>)>>
7154  ebco(Arg&& arg, Args&&... args) noexcept(std::is_nothrow_constructible_v<T, Arg, Args...>)
7155  : m_value(std::forward<Arg>(arg), std::forward<Args>(args)...) {
7156  }
7157 
7158  T& value() & noexcept {
7159  return m_value;
7160  }
7161 
7162  T const& value() const& noexcept {
7163  return m_value;
7164  }
7165 
7166  T&& value() && noexcept {
7167  return std::move(m_value);
7168  }
7169  };
7170 
7171  template <typename T, std::size_t tag>
7172  struct ebco<T, tag, std::enable_if_t<!std::is_reference_v<T> && std::is_class_v<T> && !std::is_final_v<T>>> : T {
7173  ebco() = default;
7174  ebco(const ebco&) = default;
7175  ebco(ebco&&) = default;
7176  ebco(const T& v) noexcept(std::is_nothrow_copy_constructible_v<T>) : T(v) {};
7177  ebco(T&& v) noexcept(std::is_nothrow_move_constructible_v<T>) : T(std::move(v)) {};
7178  template <typename Arg, typename... Args,
7179  typename = std::enable_if_t<
7180  !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
7181  ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T> && (sizeof...(Args) > 0 || !std::is_convertible_v<Arg, T>)>>
7182  ebco(Arg&& arg, Args&&... args) noexcept(std::is_nothrow_constructible_v<T, Arg, Args...>) : T(std::forward<Arg>(arg), std::forward<Args>(args)...) {
7183  }
7184 
7185  ebco& operator=(const ebco&) = default;
7186  ebco& operator=(ebco&&) = default;
7187  ebco& operator=(const T& v) noexcept(std::is_nothrow_copy_assignable_v<T>) {
7188  static_cast<T&>(*this) = v;
7189  return *this;
7190  }
7191  ebco& operator=(T&& v) noexcept(std::is_nothrow_move_assignable_v<T>) {
7192  static_cast<T&>(*this) = std::move(v);
7193  return *this;
7194  };
7195 
7196  T& value() & noexcept {
7197  return static_cast<T&>(*this);
7198  }
7199 
7200  T const& value() const& noexcept {
7201  return static_cast<T const&>(*this);
7202  }
7203 
7204  T&& value() && noexcept {
7205  return std::move(static_cast<T&>(*this));
7206  }
7207  };
7208 
7209  template <typename T, std::size_t tag>
7210  struct ebco<T&, tag> {
7211  private:
7212  T* m_ref;
7213 
7214  public:
7215  ebco() = default;
7216  ebco(const ebco&) = default;
7217  ebco(ebco&&) = default;
7218  ebco(T& v) noexcept : m_ref(std::addressof(v)) {};
7219 
7220  ebco& operator=(const ebco&) = default;
7221  ebco& operator=(ebco&&) = default;
7222  ebco& operator=(T& v) noexcept {
7223  m_ref = std::addressof(v);
7224  return *this;
7225  }
7226 
7227  T& value() const noexcept {
7228  return *(const_cast<ebco<T&, tag>&>(*this).m_ref);
7229  }
7230  };
7231 
7232  template <typename T, std::size_t tag>
7233  struct ebco<T&&, tag> {
7234  T&& ref;
7235 
7236  ebco() = default;
7237  ebco(const ebco&) = delete;
7238  ebco(ebco&&) = default;
7239  ebco(T&& v) noexcept : ref(v) {};
7240 
7241  ebco& operator=(const ebco&) = delete;
7242  ebco& operator=(ebco&&) = delete;
7243 
7244  T& value() & noexcept {
7245  return ref;
7246  }
7247 
7248  const T& value() const& noexcept {
7249  return ref;
7250  }
7251 
7252  T&& value() && noexcept {
7253  return std::move(ref);
7254  }
7255  };
7256 
7257 }} // namespace sol::detail
7258 
7259 // end of sol/ebco.hpp
7260 
7261 #include <array>
7262 #include <initializer_list>
7263 #include <string>
7264 #include <string_view>
7265 #include <optional>
7266 #include <memory>
7267 #if SOL_IS_ON(SOL_STD_VARIANT)
7268 #include <variant>
7269 #endif // variant shenanigans (thanks, Mac OSX)
7270 
7271 namespace sol {
7272  namespace d {
7273  // shortest possible hidden detail namespace
7274  // when types are transcribed, this saves
7275  // quite a bit of space, actually.
7276  // it's a little unfortunate, but here we are?
7277  template <typename T>
7278  struct u { };
7279  } // namespace d
7280 
7281  namespace detail {
7282 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
7283  typedef int (*lua_CFunction_noexcept)(lua_State* L) noexcept;
7284 #else
7285  typedef int (*lua_CFunction_noexcept)(lua_State* L);
7286 #endif // noexcept function type for lua_CFunction
7287 
7288  template <typename T>
7290  T& value;
7291 
7292  implicit_wrapper(T* value_) : value(*value_) {
7293  }
7294 
7295  implicit_wrapper(T& value_) : value(value_) {
7296  }
7297 
7298  operator T&() {
7299  return value;
7300  }
7301 
7302  operator T*() {
7303  return std::addressof(value);
7304  }
7305  };
7306 
7307  struct yield_tag_t { };
7308  inline constexpr yield_tag_t yield_tag {};
7309  } // namespace detail
7310 
7311  struct lua_nil_t { };
7312  inline constexpr lua_nil_t lua_nil {};
7313  inline bool operator==(lua_nil_t, lua_nil_t) {
7314  return true;
7315  }
7316  inline bool operator!=(lua_nil_t, lua_nil_t) {
7317  return false;
7318  }
7319 #if SOL_IS_ON(SOL_NIL)
7320  using nil_t = lua_nil_t;
7321  inline constexpr const nil_t& nil = lua_nil;
7322 #endif
7323 
7324  namespace detail {
7325  struct non_lua_nil_t { };
7326  } // namespace detail
7327 
7328  struct metatable_key_t { };
7329  inline constexpr metatable_key_t metatable_key {};
7330 
7331  struct global_tag_t {
7332  } inline constexpr global_tag {};
7333 
7334  struct env_key_t { };
7335  inline constexpr env_key_t env_key {};
7336 
7337  struct no_metatable_t { };
7338  inline constexpr no_metatable_t no_metatable {};
7339 
7340  template <typename T>
7341  struct yielding_t {
7342  T func;
7343 
7344  yielding_t() = default;
7345  yielding_t(const yielding_t&) = default;
7346  yielding_t(yielding_t&&) = default;
7347  yielding_t& operator=(const yielding_t&) = default;
7348  yielding_t& operator=(yielding_t&&) = default;
7349  template <typename Arg,
7350  meta::enable<meta::neg<std::is_same<meta::unqualified_t<Arg>, yielding_t>>,
7351  meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<Arg>>>> = meta::enabler>
7352  yielding_t(Arg&& arg) : func(std::forward<Arg>(arg)) {
7353  }
7354  template <typename Arg0, typename Arg1, typename... Args>
7355  yielding_t(Arg0&& arg0, Arg1&& arg1, Args&&... args) : func(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...) {
7356  }
7357  };
7358 
7359  template <typename F>
7360  inline yielding_t<std::decay_t<F>> yielding(F&& f) {
7361  return yielding_t<std::decay_t<F>>(std::forward<F>(f));
7362  }
7363 
7364  typedef std::remove_pointer_t<lua_CFunction> lua_CFunction_ref;
7365 
7366  template <typename T>
7367  struct non_null { };
7368 
7369  template <typename... Args>
7370  struct function_sig { };
7371 
7372  struct upvalue_index {
7373  int index;
7374  upvalue_index(int idx) : index(lua_upvalueindex(idx)) {
7375  }
7376 
7377  operator int() const {
7378  return index;
7379  }
7380  };
7381 
7382  struct raw_index {
7383  int index;
7384  raw_index(int i) : index(i) {
7385  }
7386 
7387  operator int() const {
7388  return index;
7389  }
7390  };
7391 
7393  int index;
7394  absolute_index(lua_State* L, int idx) : index(lua_absindex(L, idx)) {
7395  }
7396 
7397  operator int() const {
7398  return index;
7399  }
7400  };
7401 
7402  struct ref_index {
7403  int index;
7404  ref_index(int idx) : index(idx) {
7405  }
7406 
7407  operator int() const {
7408  return index;
7409  }
7410  };
7411 
7412  struct stack_count {
7413  int count;
7414 
7415  stack_count(int cnt) : count(cnt) {
7416  }
7417  };
7418 
7420  void* value;
7421  lightuserdata_value(void* data) : value(data) {
7422  }
7423  operator void*() const {
7424  return value;
7425  }
7426  };
7427 
7429  private:
7430  void* m_value;
7431 
7432  public:
7433  userdata_value(void* data) : m_value(data) {
7434  }
7435 
7436  void* value() const {
7437  return m_value;
7438  }
7439 
7440  operator void*() const {
7441  return value();
7442  }
7443  };
7444 
7445  template <typename T>
7446  struct light {
7447  private:
7448  static_assert(!std::is_void_v<T>, "the type for light will never be void");
7449  T* m_value;
7450 
7451  public:
7452  light(T& x) : m_value(std::addressof(x)) {
7453  }
7454  light(T* x) : m_value(x) {
7455  }
7456  explicit light(void* x) : m_value(static_cast<T*>(x)) {
7457  }
7458 
7459  T* value() const {
7460  return m_value;
7461  }
7462 
7463  operator T*() const {
7464  return m_value;
7465  }
7466  operator T&() const {
7467  return *m_value;
7468  }
7469 
7470  void* void_value() const {
7471  return m_value;
7472  }
7473  };
7474 
7475  template <typename T>
7476  auto make_light(T& l) {
7477  typedef meta::unwrapped_t<std::remove_pointer_t<std::remove_pointer_t<T>>> L;
7478  return light<L>(l);
7479  }
7480 
7481  template <typename T>
7482  struct user : private detail::ebco<T> {
7483  private:
7484  using base_t = detail::ebco<T>;
7485 
7486  public:
7487  using base_t::base_t;
7488 
7489  using base_t::value;
7490 
7491  operator std::add_pointer_t<std::remove_reference_t<T>>() {
7492  return std::addressof(this->base_t::value());
7493  }
7494 
7495  operator std::add_pointer_t<std::add_const_t<std::remove_reference_t<T>>>() const {
7496  return std::addressof(this->base_t::value());
7497  }
7498 
7499  operator std::add_lvalue_reference_t<T>() {
7500  return this->base_t::value();
7501  }
7502 
7503  operator std::add_const_t<std::add_lvalue_reference_t<T>>&() const {
7504  return this->base_t::value();
7505  }
7506  };
7507 
7508  template <typename T>
7509  auto make_user(T&& u) {
7510  typedef meta::unwrapped_t<meta::unqualified_t<T>> U;
7511  return user<U>(std::forward<T>(u));
7512  }
7513 
7514  template <typename T>
7515  struct metatable_registry_key : private detail::ebco<T> {
7516  private:
7517  using base_t = detail::ebco<T>;
7518 
7519  public:
7520  using base_t::base_t;
7521 
7522  using base_t::value;
7523  };
7524 
7525  template <typename T>
7526  auto meta_registry_key(T&& key) {
7527  typedef meta::unqualified_t<T> K;
7528  return metatable_registry_key<K>(std::forward<T>(key));
7529  }
7530 
7531  template <typename... Upvalues>
7532  struct closure {
7533  lua_CFunction c_function;
7534  std::tuple<Upvalues...> upvalues;
7535  closure(lua_CFunction f, Upvalues... targetupvalues) : c_function(f), upvalues(std::forward<Upvalues>(targetupvalues)...) {
7536  }
7537  };
7538 
7539  template <>
7540  struct closure<> {
7541  lua_CFunction c_function;
7542  int upvalues;
7543  closure(lua_CFunction f, int upvalue_count = 0) : c_function(f), upvalues(upvalue_count) {
7544  }
7545  };
7546 
7547  typedef closure<> c_closure;
7548 
7549  template <typename... Args>
7550  closure<Args...> make_closure(lua_CFunction f, Args&&... args) {
7551  return closure<Args...>(f, std::forward<Args>(args)...);
7552  }
7553 
7554  template <typename Sig, typename... Ps>
7556  std::tuple<Ps...> arguments;
7557  template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, function_arguments>> = meta::enabler>
7558  function_arguments(Arg&& arg, Args&&... args) : arguments(std::forward<Arg>(arg), std::forward<Args>(args)...) {
7559  }
7560  };
7561 
7562  template <typename Sig = function_sig<>, typename... Args>
7563  auto as_function(Args&&... args) {
7564  return function_arguments<Sig, std::decay_t<Args>...>(std::forward<Args>(args)...);
7565  }
7566 
7567  template <typename Sig = function_sig<>, typename... Args>
7568  auto as_function_reference(Args&&... args) {
7569  return function_arguments<Sig, Args...>(std::forward<Args>(args)...);
7570  }
7571 
7572  template <typename T>
7573  struct as_table_t : private detail::ebco<T> {
7574  private:
7575  using base_t = detail::ebco<T>;
7576 
7577  public:
7578  as_table_t() = default;
7579  as_table_t(const as_table_t&) = default;
7580  as_table_t(as_table_t&&) = default;
7581  as_table_t& operator=(const as_table_t&) = default;
7582  as_table_t& operator=(as_table_t&&) = default;
7583  as_table_t(const meta::unqualified_t<T>& obj) noexcept(std::is_nothrow_constructible_v<base_t, const meta::unqualified_t<T>&>) : base_t(obj) {
7584  }
7585  as_table_t(meta::unqualified_t<T>&& obj) noexcept(std::is_nothrow_constructible_v<base_t, meta::unqualified_t<T>&&>) : base_t(std::move(obj)) {
7586  }
7587  template <typename Arg, typename... Args,
7588  std::enable_if_t<
7589  !std::is_same_v<as_table_t, meta::unqualified_t<Arg>> && !std::is_same_v<meta::unqualified_t<T>, meta::unqualified_t<Arg>>>* = nullptr>
7590  as_table_t(Arg&& arg, Args&&... args) noexcept(std::is_nothrow_constructible_v<base_t, Arg, Args...>)
7591  : base_t(std::forward<Arg>(arg), std::forward<Args>(args)...) {
7592  }
7593 
7594  using base_t::value;
7595 
7596  operator std::add_lvalue_reference_t<T>() {
7597  return this->base_t::value();
7598  }
7599 
7600  operator std::add_const_t<std::add_lvalue_reference_t<T>>() const {
7601  return this->base_t::value();
7602  }
7603  };
7604 
7605  template <typename T>
7606  struct nested : private detail::ebco<T> {
7607  private:
7608  using base_t = detail::ebco<T>;
7609 
7610  public:
7611  using nested_type = T;
7612 
7613  nested() = default;
7614  nested(const nested&) = default;
7615  nested(nested&&) = default;
7616  nested& operator=(const nested&) = default;
7617  nested& operator=(nested&&) = default;
7618  nested(const meta::unqualified_t<T>& obj) noexcept(std::is_nothrow_constructible_v<base_t, const meta::unqualified_t<T>&>) : base_t(obj) {
7619  }
7620  nested(meta::unqualified_t<T>&& obj) noexcept(std::is_nothrow_constructible_v<base_t, meta::unqualified_t<T>&&>) : base_t(std::move(obj)) {
7621  }
7622  template <typename Arg, typename... Args,
7623  std::enable_if_t<
7624  !std::is_same_v<nested, meta::unqualified_t<Arg>> && !std::is_same_v<meta::unqualified_t<T>, meta::unqualified_t<Arg>>>* = nullptr>
7625  nested(Arg&& arg, Args&&... args) noexcept(std::is_nothrow_constructible_v<base_t, Arg, Args...>)
7626  : base_t(std::forward<Arg>(arg), std::forward<Args>(args)...) {
7627  }
7628 
7629  using base_t::value;
7630 
7631  operator std::add_lvalue_reference_t<T>() {
7632  return this->base_t::value();
7633  }
7634 
7635  operator std::add_const_t<std::add_lvalue_reference_t<T>>() const {
7636  return this->base_t::value();
7637  }
7638  };
7639 
7640  struct nested_tag_t { };
7641  constexpr inline nested_tag_t nested_tag {};
7642 
7643  template <typename T>
7644  as_table_t<T> as_table_ref(T&& container) {
7645  return as_table_t<T>(std::forward<T>(container));
7646  }
7647 
7648  template <typename T>
7649  as_table_t<meta::unqualified_t<T>> as_table(T&& container) {
7650  return as_table_t<meta::unqualified_t<T>>(std::forward<T>(container));
7651  }
7652 
7653  template <typename T>
7654  nested<T> as_nested_ref(T&& container) {
7655  return nested<T>(std::forward<T>(container));
7656  }
7657 
7658  template <typename T>
7659  nested<meta::unqualified_t<T>> as_nested(T&& container) {
7660  return nested<meta::unqualified_t<T>>(std::forward<T>(container));
7661  }
7662 
7663  template <typename T>
7664  struct as_container_t : private detail::ebco<T> {
7665  private:
7666  using base_t = detail::ebco<T>;
7667 
7668  public:
7669  using type = T;
7670 
7671  as_container_t() = default;
7672  as_container_t(const as_container_t&) = default;
7673  as_container_t(as_container_t&&) = default;
7674  as_container_t& operator=(const as_container_t&) = default;
7675  as_container_t& operator=(as_container_t&&) = default;
7676 
7677  using base_t::base_t;
7678 
7679  using base_t::value;
7680 
7681  operator std::add_lvalue_reference_t<T>() {
7682  return value();
7683  }
7684  };
7685 
7686  template <typename T>
7687  auto as_container(T&& value) {
7688  return as_container_t<T>(std::forward<T>(value));
7689  }
7690 
7691  template <typename T>
7692  struct push_invoke_t : private detail::ebco<T> {
7693  private:
7694  using base_t = detail::ebco<T>;
7695 
7696  public:
7697  push_invoke_t() = default;
7698  push_invoke_t(const push_invoke_t&) = default;
7699  push_invoke_t(push_invoke_t&&) = default;
7700  push_invoke_t& operator=(const push_invoke_t&) = default;
7701  push_invoke_t& operator=(push_invoke_t&&) = default;
7702 
7703  using base_t::base_t;
7704 
7705  using base_t::value;
7706  };
7707 
7708  template <typename Fx>
7709  auto push_invoke(Fx&& fx) {
7710  return push_invoke_t<Fx>(std::forward<Fx>(fx));
7711  }
7712 
7713  template <typename T>
7714  struct forward_as_value_t : private detail::ebco<T> {
7715  private:
7716  using base_t = detail::ebco<T>;
7717 
7718  public:
7719  forward_as_value_t() = default;
7720  forward_as_value_t(const forward_as_value_t&) = default;
7722  forward_as_value_t& operator=(const forward_as_value_t&) = default;
7723  forward_as_value_t& operator=(forward_as_value_t&&) = default;
7724 
7725  using base_t::base_t;
7726 
7727  using base_t::value;
7728  };
7729 
7730  template <typename T>
7731  auto pass_as_value(T& value_ref_) {
7732  return forward_as_value_t<T>(value_ref_);
7733  }
7734 
7735  struct override_value_t { };
7736  constexpr inline override_value_t override_value = override_value_t();
7737  struct update_if_empty_t { };
7738  constexpr inline update_if_empty_t update_if_empty = update_if_empty_t();
7739  struct create_if_nil_t { };
7740  constexpr inline create_if_nil_t create_if_nil = create_if_nil_t();
7741 
7742  namespace detail {
7743  enum insert_mode { none = 0x0, update_if_empty = 0x01, override_value = 0x02, create_if_nil = 0x04 };
7744 
7745  template <typename T, typename...>
7746  using is_insert_mode = std::integral_constant<bool,
7747  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>>;
7748 
7749  template <typename T, typename...>
7750  using is_not_insert_mode = meta::neg<is_insert_mode<T>>;
7751  } // namespace detail
7752 
7753  struct this_state {
7754  lua_State* L;
7755 
7756  this_state(lua_State* Ls) : L(Ls) {
7757  }
7758 
7759  operator lua_State*() const noexcept {
7760  return lua_state();
7761  }
7762 
7763  lua_State* operator->() const noexcept {
7764  return lua_state();
7765  }
7766 
7767  lua_State* lua_state() const noexcept {
7768  return L;
7769  }
7770  };
7771 
7773  lua_State* L;
7774 
7775  this_main_state(lua_State* Ls) : L(Ls) {
7776  }
7777 
7778  operator lua_State*() const noexcept {
7779  return lua_state();
7780  }
7781 
7782  lua_State* operator->() const noexcept {
7783  return lua_state();
7784  }
7785 
7786  lua_State* lua_state() const noexcept {
7787  return L;
7788  }
7789  };
7790 
7791  struct new_table {
7792  int sequence_hint = 0;
7793  int map_hint = 0;
7794 
7795  new_table() = default;
7796  new_table(const new_table&) = default;
7797  new_table(new_table&&) = default;
7798  new_table& operator=(const new_table&) = default;
7799  new_table& operator=(new_table&&) = default;
7800 
7801  new_table(int sequence_hint_, int map_hint_ = 0) noexcept : sequence_hint(sequence_hint_), map_hint(map_hint_) {
7802  }
7803  };
7804 
7805  const new_table create = {};
7806 
7807  enum class lib : unsigned char {
7808  // print, assert, and other base functions
7809  base,
7810  // require and other package functions
7811  package,
7812  // coroutine functions and utilities
7813  coroutine,
7814  // string library
7815  string,
7816  // functionality from the OS
7817  os,
7818  // all things math
7819  math,
7820  // the table manipulator and observer functions
7821  table,
7822  // the debug library
7823  debug,
7824  // the bit library: different based on which you're using
7825  bit32,
7826  // input/output library
7827  io,
7828  // LuaJIT only
7829  ffi,
7830  // LuaJIT only
7831  jit,
7832  // library for handling utf8: new to Lua
7833  utf8,
7834  // do not use
7835  count
7836  };
7837 
7838  enum class call_syntax { dot = 0, colon = 1 };
7839 
7840  enum class load_mode {
7841  any = 0,
7842  text = 1,
7843  binary = 2,
7844  };
7845 
7846  enum class call_status : int {
7847  ok = LUA_OK,
7848  yielded = LUA_YIELD,
7849  runtime = LUA_ERRRUN,
7850  memory = LUA_ERRMEM,
7851  handler = LUA_ERRERR,
7852  gc = LUA_ERRGCMM,
7853  syntax = LUA_ERRSYNTAX,
7854  file = LUA_ERRFILE,
7855  };
7856 
7857  enum class thread_status : int {
7858  ok = LUA_OK,
7859  yielded = LUA_YIELD,
7860  runtime = LUA_ERRRUN,
7861  memory = LUA_ERRMEM,
7862  gc = LUA_ERRGCMM,
7863  handler = LUA_ERRERR,
7864  dead = -1,
7865  };
7866 
7867  enum class load_status : int {
7868  ok = LUA_OK,
7869  syntax = LUA_ERRSYNTAX,
7870  memory = LUA_ERRMEM,
7871  gc = LUA_ERRGCMM,
7872  file = LUA_ERRFILE,
7873  };
7874 
7875  enum class gc_mode : int {
7876  incremental = 0,
7877  generational = 1,
7878  default_value = incremental,
7879  };
7880 
7881  enum class type : int {
7882  none = LUA_TNONE,
7883  lua_nil = LUA_TNIL,
7884 #if SOL_IS_ON(SOL_NIL)
7885  nil = lua_nil,
7886 #endif // Objective C/C++ Keyword that's found in OSX SDK and OBJC -- check for all forms to protect
7887  string = LUA_TSTRING,
7888  number = LUA_TNUMBER,
7889  thread = LUA_TTHREAD,
7890  boolean = LUA_TBOOLEAN,
7891  function = LUA_TFUNCTION,
7892  userdata = LUA_TUSERDATA,
7893  lightuserdata = LUA_TLIGHTUSERDATA,
7894  table = LUA_TTABLE,
7895  poly = -0xFFFF
7896  };
7897 
7898  inline const std::string& to_string(call_status c) {
7899  static const std::array<std::string, 10> names { { "ok",
7900  "yielded",
7901  "runtime",
7902  "memory",
7903  "handler",
7904  "gc",
7905  "syntax",
7906  "file",
7907  "CRITICAL_EXCEPTION_FAILURE",
7908  "CRITICAL_INDETERMINATE_STATE_FAILURE" } };
7909  switch (c) {
7910  case call_status::ok:
7911  return names[0];
7912  case call_status::yielded:
7913  return names[1];
7914  case call_status::runtime:
7915  return names[2];
7916  case call_status::memory:
7917  return names[3];
7918  case call_status::handler:
7919  return names[4];
7920  case call_status::gc:
7921  return names[5];
7922  case call_status::syntax:
7923  return names[6];
7924  case call_status::file:
7925  return names[7];
7926  }
7927  if (static_cast<std::ptrdiff_t>(c) == -1) {
7928  // One of the many cases where a critical exception error has occurred
7929  return names[8];
7930  }
7931  return names[9];
7932  }
7933 
7934  inline bool is_indeterminate_call_failure(call_status c) {
7935  switch (c) {
7936  case call_status::ok:
7937  case call_status::yielded:
7938  case call_status::runtime:
7939  case call_status::memory:
7940  case call_status::handler:
7941  case call_status::gc:
7942  case call_status::syntax:
7943  case call_status::file:
7944  return false;
7945  }
7946  return true;
7947  }
7948 
7949  inline const std::string& to_string(load_status c) {
7950  static const std::array<std::string, 7> names {
7951  { "ok", "memory", "gc", "syntax", "file", "CRITICAL_EXCEPTION_FAILURE", "CRITICAL_INDETERMINATE_STATE_FAILURE" }
7952  };
7953  switch (c) {
7954  case load_status::ok:
7955  return names[0];
7956  case load_status::memory:
7957  return names[1];
7958  case load_status::gc:
7959  return names[2];
7960  case load_status::syntax:
7961  return names[3];
7962  case load_status::file:
7963  return names[4];
7964  }
7965  if (static_cast<int>(c) == -1) {
7966  // One of the many cases where a critical exception error has occurred
7967  return names[5];
7968  }
7969  return names[6];
7970  }
7971 
7972  inline const std::string& to_string(load_mode c) {
7973  static const std::array<std::string, 3> names { {
7974  "bt",
7975  "t",
7976  "b",
7977  } };
7978  return names[static_cast<std::size_t>(c)];
7979  }
7980 
7981  enum class meta_function : unsigned {
7982  construct,
7983  index,
7984  new_index,
7985  mode,
7986  call,
7987  call_function = call,
7988  metatable,
7989  to_string,
7990  length,
7991  unary_minus,
7992  addition,
7993  subtraction,
7994  multiplication,
7995  division,
7996  modulus,
7997  power_of,
7998  involution = power_of,
7999  concatenation,
8000  equal_to,
8001  less_than,
8002  less_than_or_equal_to,
8003  garbage_collect,
8004  floor_division,
8005  bitwise_left_shift,
8006  bitwise_right_shift,
8007  bitwise_not,
8008  bitwise_and,
8009  bitwise_or,
8010  bitwise_xor,
8011  pairs,
8012  ipairs,
8013  next,
8014  type,
8015  type_info,
8016  call_construct,
8017  storage,
8018  gc_names,
8019  static_index,
8020  static_new_index,
8021  };
8022 
8023  typedef meta_function meta_method;
8024 
8025  inline const std::array<std::string, 37>& meta_function_names() {
8026  static const std::array<std::string, 37> names = { { "new",
8027  "__index",
8028  "__newindex",
8029  "__mode",
8030  "__call",
8031  "__metatable",
8032  "__tostring",
8033  "__len",
8034  "__unm",
8035  "__add",
8036  "__sub",
8037  "__mul",
8038  "__div",
8039  "__mod",
8040  "__pow",
8041  "__concat",
8042  "__eq",
8043  "__lt",
8044  "__le",
8045  "__gc",
8046 
8047  "__idiv",
8048  "__shl",
8049  "__shr",
8050  "__bnot",
8051  "__band",
8052  "__bor",
8053  "__bxor",
8054 
8055  "__pairs",
8056  "__ipairs",
8057  "next",
8058 
8059  "__type",
8060  "__typeinfo",
8061  "__sol.call_new",
8062  "__sol.storage",
8063  "__sol.gc_names",
8064  "__sol.static_index",
8065  "__sol.static_new_index" } };
8066  return names;
8067  }
8068 
8069  inline const std::string& to_string(meta_function mf) {
8070  return meta_function_names()[static_cast<std::size_t>(mf)];
8071  }
8072 
8073  inline type type_of(lua_State* L, int index) {
8074  return static_cast<type>(lua_type(L, index));
8075  }
8076 
8077  inline std::string type_name(lua_State* L, type t) {
8078  return lua_typename(L, static_cast<int>(t));
8079  }
8080 
8081  template <typename T>
8083  : std::integral_constant<bool,
8084  (std::is_base_of_v<stateless_stack_reference, T> || std::is_base_of_v<stateless_reference, T>)&&(
8085  !std::is_base_of_v<stack_reference, T> && !std::is_base_of_v<reference, T> && !std::is_base_of_v<main_reference, T>)> { };
8086 
8087  template <typename T>
8088  inline constexpr bool is_stateless_lua_reference_v = is_stateless_lua_reference<T>::value;
8089 
8090  template <typename T>
8092  : std::integral_constant<bool,
8093  std::is_base_of_v<reference,
8094  T> || std::is_base_of_v<main_reference, T> || std::is_base_of_v<stack_reference, T> || std::is_base_of_v<stateless_stack_reference, T> || std::is_base_of_v<stateless_reference, T>> {
8095  };
8096 
8097  template <typename T>
8098  inline constexpr bool is_lua_reference_v = is_lua_reference<T>::value;
8099 
8100  template <typename T>
8101  struct is_lua_reference_or_proxy : std::integral_constant<bool, is_lua_reference_v<T> || meta::is_specialization_of_v<T, table_proxy>> { };
8102 
8103  template <typename T>
8104  inline constexpr bool is_lua_reference_or_proxy_v = is_lua_reference_or_proxy<T>::value;
8105 
8106  template <typename T>
8108  : std::integral_constant<bool,
8109  std::is_same_v<meta::unqualified_t<T>,
8110  this_state> || std::is_same_v<meta::unqualified_t<T>, this_main_state> || std::is_same_v<meta::unqualified_t<T>, this_environment> || std::is_same_v<meta::unqualified_t<T>, variadic_args>> {
8111  };
8112 
8113  template <typename T>
8114  constexpr inline bool is_transparent_argument_v = is_transparent_argument<T>::value;
8115 
8116  template <typename T>
8117  struct is_variadic_arguments : meta::any<std::is_same<T, variadic_args>, meta::is_optional<T>> { };
8118 
8119  template <typename T>
8121  : std::integral_constant<bool,
8122  !std::is_same_v<state_view,
8123  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>)> {
8124  };
8125 
8126  template <typename T>
8127  constexpr inline bool is_container_v = is_container<T>::value;
8128 
8129  template <typename T>
8130  struct is_to_stringable : meta::any<meta::supports_to_string_member<meta::unqualified_t<T>>, meta::supports_adl_to_string<meta::unqualified_t<T>>,
8131  meta::supports_op_left_shift<std::ostream, meta::unqualified_t<T>>> { };
8132 
8133  template <typename T>
8134  inline constexpr bool is_to_stringable_v = is_to_stringable<T>::value;
8135 
8136  template <typename T>
8137  struct is_callable : std::true_type { };
8138 
8139  template <typename T>
8140  inline constexpr bool is_callable_v = is_callable<T>::value;
8141 
8142  namespace detail {
8143  template <typename T, typename = void>
8144  struct lua_type_of : std::integral_constant<type, type::userdata> { };
8145 
8146  template <typename C, typename T, typename A>
8147  struct lua_type_of<std::basic_string<C, T, A>> : std::integral_constant<type, type::string> { };
8148 
8149  template <typename C, typename T>
8150  struct lua_type_of<basic_string_view<C, T>> : std::integral_constant<type, type::string> { };
8151 
8152  template <std::size_t N>
8153  struct lua_type_of<char[N]> : std::integral_constant<type, type::string> { };
8154 
8155  template <std::size_t N>
8156  struct lua_type_of<wchar_t[N]> : std::integral_constant<type, type::string> { };
8157 
8158 #if SOL_IS_ON(SOL_CHAR8_T)
8159  template <std::size_t N>
8160  struct lua_type_of<char8_t[N]> : std::integral_constant<type, type::string> { };
8161 #endif
8162 
8163  template <std::size_t N>
8164  struct lua_type_of<char16_t[N]> : std::integral_constant<type, type::string> { };
8165 
8166  template <std::size_t N>
8167  struct lua_type_of<char32_t[N]> : std::integral_constant<type, type::string> { };
8168 
8169  template <>
8170  struct lua_type_of<char> : std::integral_constant<type, type::string> { };
8171 
8172  template <>
8173  struct lua_type_of<wchar_t> : std::integral_constant<type, type::string> { };
8174 
8175 #if SOL_IS_ON(SOL_CHAR8_T)
8176  template <>
8177  struct lua_type_of<char8_t> : std::integral_constant<type, type::string> { };
8178 #endif
8179 
8180  template <>
8181  struct lua_type_of<char16_t> : std::integral_constant<type, type::string> { };
8182 
8183  template <>
8184  struct lua_type_of<char32_t> : std::integral_constant<type, type::string> { };
8185 
8186  template <>
8187  struct lua_type_of<const char*> : std::integral_constant<type, type::string> { };
8188 
8189  template <>
8190  struct lua_type_of<const wchar_t*> : std::integral_constant<type, type::string> { };
8191 
8192 #if SOL_IS_ON(SOL_CHAR8_T)
8193  template <>
8194  struct lua_type_of<const char8_t*> : std::integral_constant<type, type::string> { };
8195 #endif
8196 
8197  template <>
8198  struct lua_type_of<const char16_t*> : std::integral_constant<type, type::string> { };
8199 
8200  template <>
8201  struct lua_type_of<const char32_t*> : std::integral_constant<type, type::string> { };
8202 
8203  template <>
8204  struct lua_type_of<bool> : std::integral_constant<type, type::boolean> { };
8205 
8206  template <>
8207  struct lua_type_of<lua_nil_t> : std::integral_constant<type, type::lua_nil> { };
8208 
8209  template <>
8210  struct lua_type_of<nullopt_t> : std::integral_constant<type, type::lua_nil> { };
8211 
8212  template <>
8213  struct lua_type_of<lua_value> : std::integral_constant<type, type::poly> { };
8214 
8215  template <>
8216  struct lua_type_of<detail::non_lua_nil_t> : std::integral_constant<type, type::poly> { };
8217 
8218  template <>
8219  struct lua_type_of<std::nullptr_t> : std::integral_constant<type, type::lua_nil> { };
8220 
8221  template <>
8222  struct lua_type_of<error> : std::integral_constant<type, type::string> { };
8223 
8224  template <bool b, typename Base>
8225  struct lua_type_of<basic_table_core<b, Base>> : std::integral_constant<type, type::table> { };
8226 
8227  template <typename Base>
8228  struct lua_type_of<basic_lua_table<Base>> : std::integral_constant<type, type::table> { };
8229 
8230  template <typename Base>
8231  struct lua_type_of<basic_metatable<Base>> : std::integral_constant<type, type::table> { };
8232 
8233  template <typename T, typename Base>
8234  struct lua_type_of<basic_usertype<T, Base>> : std::integral_constant<type, type::table> { };
8235 
8236  template <>
8237  struct lua_type_of<metatable_key_t> : std::integral_constant<type, type::table> { };
8238 
8239  template <typename B>
8240  struct lua_type_of<basic_environment<B>> : std::integral_constant<type, type::poly> { };
8241 
8242  template <>
8243  struct lua_type_of<env_key_t> : std::integral_constant<type, type::poly> { };
8244 
8245  template <>
8246  struct lua_type_of<new_table> : std::integral_constant<type, type::table> { };
8247 
8248  template <typename T>
8249  struct lua_type_of<as_table_t<T>> : std::integral_constant<type, type::table> { };
8250 
8251  template <typename T>
8252  struct lua_type_of<std::initializer_list<T>> : std::integral_constant<type, type::table> { };
8253 
8254  template <bool b>
8255  struct lua_type_of<basic_reference<b>> : std::integral_constant<type, type::poly> { };
8256 
8257  template <>
8258  struct lua_type_of<stack_reference> : std::integral_constant<type, type::poly> { };
8259 
8260  template <typename Base>
8261  struct lua_type_of<basic_object<Base>> : std::integral_constant<type, type::poly> { };
8262 
8263  template <typename... Args>
8264  struct lua_type_of<std::tuple<Args...>> : std::integral_constant<type, type::poly> { };
8265 
8266  template <typename A, typename B>
8267  struct lua_type_of<std::pair<A, B>> : std::integral_constant<type, type::poly> { };
8268 
8269  template <>
8270  struct lua_type_of<void*> : std::integral_constant<type, type::lightuserdata> { };
8271 
8272  template <>
8273  struct lua_type_of<const void*> : std::integral_constant<type, type::lightuserdata> { };
8274 
8275  template <>
8276  struct lua_type_of<lightuserdata_value> : std::integral_constant<type, type::lightuserdata> { };
8277 
8278  template <>
8279  struct lua_type_of<userdata_value> : std::integral_constant<type, type::userdata> { };
8280 
8281  template <typename T>
8282  struct lua_type_of<light<T>> : std::integral_constant<type, type::lightuserdata> { };
8283 
8284  template <typename T>
8285  struct lua_type_of<user<T>> : std::integral_constant<type, type::userdata> { };
8286 
8287  template <typename Base>
8288  struct lua_type_of<basic_lightuserdata<Base>> : std::integral_constant<type, type::lightuserdata> { };
8289 
8290  template <typename Base>
8291  struct lua_type_of<basic_userdata<Base>> : std::integral_constant<type, type::userdata> { };
8292 
8293  template <>
8294  struct lua_type_of<lua_CFunction> : std::integral_constant<type, type::function> { };
8295 
8296  template <>
8297  struct lua_type_of<std::remove_pointer_t<lua_CFunction>> : std::integral_constant<type, type::function> { };
8298 
8299  template <typename Base, bool aligned>
8300  struct lua_type_of<basic_function<Base, aligned>> : std::integral_constant<type, type::function> { };
8301 
8302  template <typename Base, bool aligned, typename Handler>
8303  struct lua_type_of<basic_protected_function<Base, aligned, Handler>> : std::integral_constant<type, type::function> { };
8304 
8305  template <typename Base>
8306  struct lua_type_of<basic_coroutine<Base>> : std::integral_constant<type, type::function> { };
8307 
8308  template <typename Base>
8309  struct lua_type_of<basic_thread<Base>> : std::integral_constant<type, type::thread> { };
8310 
8311  template <typename Signature>
8312  struct lua_type_of<std::function<Signature>> : std::integral_constant<type, type::function> { };
8313 
8314  template <typename T>
8315  struct lua_type_of<optional<T>> : std::integral_constant<type, type::poly> { };
8316 
8317  template <typename T>
8318  struct lua_type_of<std::optional<T>> : std::integral_constant<type, type::poly> { };
8319 
8320  template <>
8321  struct lua_type_of<variadic_args> : std::integral_constant<type, type::poly> { };
8322 
8323  template <>
8324  struct lua_type_of<variadic_results> : std::integral_constant<type, type::poly> { };
8325 
8326  template <>
8327  struct lua_type_of<stack_count> : std::integral_constant<type, type::poly> { };
8328 
8329  template <>
8330  struct lua_type_of<this_state> : std::integral_constant<type, type::poly> { };
8331 
8332  template <>
8333  struct lua_type_of<this_main_state> : std::integral_constant<type, type::poly> { };
8334 
8335  template <>
8336  struct lua_type_of<this_environment> : std::integral_constant<type, type::poly> { };
8337 
8338  template <>
8339  struct lua_type_of<type> : std::integral_constant<type, type::poly> { };
8340 
8341 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
8342  template <typename T>
8343  struct lua_type_of<T*> : std::integral_constant<type, std::is_function_v<T> ? type::function : type::userdata> { };
8344 #else
8345  template <typename T>
8346  struct lua_type_of<T*> : std::integral_constant<type, type::userdata> { };
8347 #endif
8348 
8349  template <typename T>
8350  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>>>
8351  : std::integral_constant<type, type::number> { };
8352 
8353  template <typename T>
8354  struct lua_type_of<T, std::enable_if_t<std::is_function_v<T>>> : std::integral_constant<type, type::function> { };
8355 
8356  template <typename T>
8357  struct lua_type_of<T, std::enable_if_t<std::is_enum_v<T>>> : std::integral_constant<type, type::number> { };
8358 
8359  template <>
8360  struct lua_type_of<meta_function> : std::integral_constant<type, type::string> { };
8361 
8362 #if SOL_IS_ON(SOL_STD_VARIANT)
8363  template <typename... Tn>
8364  struct lua_type_of<std::variant<Tn...>> : std::integral_constant<type, type::poly> { };
8365 #endif // std::variant deployment sucks on Clang
8366 
8367  template <typename T>
8368  struct lua_type_of<nested<T>> : meta::conditional_t<::sol::is_container_v<T>, std::integral_constant<type, type::table>, lua_type_of<T>> { };
8369 
8370  template <typename C, C v, template <typename...> class V, typename... Args>
8371  struct accumulate : std::integral_constant<C, v> { };
8372 
8373  template <typename C, C v, template <typename...> class V, typename T, typename... Args>
8374  struct accumulate<C, v, V, T, Args...> : accumulate<C, v + V<T>::value, V, Args...> { };
8375 
8376  template <typename C, C v, template <typename...> class V, typename List>
8378 
8379  template <typename C, C v, template <typename...> class V, typename... Args>
8380  struct accumulate_list<C, v, V, types<Args...>> : accumulate<C, v, V, Args...> { };
8381  } // namespace detail
8382 
8383  template <typename T>
8385  typedef int SOL_INTERNAL_UNSPECIALIZED_MARKER_;
8386  };
8387 
8388  template <typename T>
8389  inline constexpr type lua_type_of_v = lua_type_of<T>::value;
8390 
8391  template <typename T>
8392  struct lua_size : std::integral_constant<int, 1> {
8393  typedef int SOL_INTERNAL_UNSPECIALIZED_MARKER_;
8394  };
8395 
8396  template <typename A, typename B>
8397  struct lua_size<std::pair<A, B>> : std::integral_constant<int, lua_size<A>::value + lua_size<B>::value> { };
8398 
8399  template <typename... Args>
8400  struct lua_size<std::tuple<Args...>> : std::integral_constant<int, detail::accumulate<int, 0, lua_size, Args...>::value> { };
8401 
8402  template <typename T>
8403  inline constexpr int lua_size_v = lua_size<T>::value;
8404 
8405  namespace detail {
8406  // MSVC's decltype detection is broken, which breaks other
8407  // parts of the code. So we add more workarounds. The moment it's fixed,
8408  // we take it away and break everyone that doesn't upgrade.
8409  template <typename T>
8413 
8414  template <typename T>
8415  inline constexpr bool is_msvc_callable_rigged_v = is_msvc_callable_rigged<T>::value;
8416  } // namespace detail
8417 
8418  template <typename T>
8420  : std::integral_constant<bool,
8421  type::userdata
8422  != lua_type_of_v<
8423  T> || ((type::userdata == lua_type_of_v<T>)&&meta::meta_detail::has_internal_marker_v<lua_type_of<T>> && !meta::meta_detail::has_internal_marker_v<lua_size<T>>)
8424  || is_lua_reference_or_proxy_v<T> || meta::is_specialization_of_v<T, std::tuple> || meta::is_specialization_of_v<T, std::pair>> { };
8425 
8426  template <typename T>
8427  constexpr inline bool is_lua_primitive_v = is_lua_primitive<T>::value;
8428 
8429  template <typename T>
8431 #if SOL_IS_ON(SOL_FUNCTION_CALL_VALUE_SEMANTICS)
8432  : std::true_type {
8433  };
8434 #else
8435  : std::false_type {
8436  };
8437 #endif
8438 
8439  template <typename T>
8440  constexpr inline bool is_value_semantic_for_function_v = is_value_semantic_for_function<T>::value;
8441 
8442  template <typename T>
8443  struct is_main_threaded : std::is_base_of<main_reference, T> { };
8444 
8445  template <typename T>
8446  inline constexpr bool is_main_threaded_v = is_main_threaded<T>::value;
8447 
8448  template <typename T>
8449  struct is_stack_based : std::is_base_of<stack_reference, T> { };
8450  template <>
8451  struct is_stack_based<variadic_args> : std::true_type { };
8452  template <>
8453  struct is_stack_based<unsafe_function_result> : std::true_type { };
8454  template <>
8455  struct is_stack_based<protected_function_result> : std::true_type { };
8456  template <>
8457  struct is_stack_based<stack_proxy> : std::true_type { };
8458  template <>
8459  struct is_stack_based<stack_proxy_base> : std::true_type { };
8460  template <>
8461  struct is_stack_based<stack_count> : std::true_type { };
8462 
8463  template <typename T>
8464  constexpr inline bool is_stack_based_v = is_stack_based<T>::value;
8465 
8466  template <typename T>
8467  struct is_lua_primitive<T*> : std::true_type { };
8468  template <>
8469  struct is_lua_primitive<unsafe_function_result> : std::true_type { };
8470  template <>
8471  struct is_lua_primitive<protected_function_result> : std::true_type { };
8472  template <typename T>
8473  struct is_lua_primitive<std::reference_wrapper<T>> : std::true_type { };
8474  template <typename T>
8475  struct is_lua_primitive<user<T>> : std::true_type { };
8476  template <typename T>
8478  template <typename T>
8479  struct is_lua_primitive<optional<T>> : std::true_type { };
8480  template <typename T>
8481  struct is_lua_primitive<std::optional<T>> : std::true_type { };
8482  template <typename T>
8483  struct is_lua_primitive<as_table_t<T>> : std::true_type { };
8484  template <typename T>
8485  struct is_lua_primitive<nested<T>> : std::true_type { };
8486  template <>
8487  struct is_lua_primitive<userdata_value> : std::true_type { };
8488  template <>
8489  struct is_lua_primitive<lightuserdata_value> : std::true_type { };
8490  template <>
8491  struct is_lua_primitive<stack_proxy> : std::true_type { };
8492  template <>
8493  struct is_lua_primitive<stack_proxy_base> : std::true_type { };
8494  template <typename T>
8496 
8497  template <typename T>
8498  struct is_lua_index : std::is_integral<T> { };
8499  template <>
8500  struct is_lua_index<raw_index> : std::true_type { };
8501  template <>
8502  struct is_lua_index<absolute_index> : std::true_type { };
8503  template <>
8504  struct is_lua_index<ref_index> : std::true_type { };
8505  template <>
8506  struct is_lua_index<upvalue_index> : std::true_type { };
8507 
8508  template <typename Signature>
8509  struct lua_bind_traits : meta::bind_traits<Signature> {
8510  private:
8512 
8513  public:
8514  typedef std::integral_constant<bool, meta::count_for<is_variadic_arguments, typename base_t::args_list>::value != 0> runtime_variadics_t;
8515  static const std::size_t true_arity = base_t::arity;
8518  static const std::size_t true_free_arity = base_t::free_arity;
8520  - meta::count_for<is_transparent_argument, typename base_t::args_list>::value;
8521  };
8522 
8523  template <typename T>
8524  struct is_table : std::false_type { };
8525  template <bool x, typename T>
8526  struct is_table<basic_table_core<x, T>> : std::true_type { };
8527  template <typename T>
8528  struct is_table<basic_lua_table<T>> : std::true_type { };
8529 
8530  template <typename T>
8531  inline constexpr bool is_table_v = is_table<T>::value;
8532 
8533  template <typename T>
8534  struct is_global_table : std::false_type { };
8535  template <typename T>
8536  struct is_global_table<basic_table_core<true, T>> : std::true_type { };
8537 
8538  template <typename T>
8539  inline constexpr bool is_global_table_v = is_global_table<T>::value;
8540 
8541  template <typename T>
8542  struct is_stack_table : std::false_type { };
8543  template <bool x, typename T>
8544  struct is_stack_table<basic_table_core<x, T>> : std::integral_constant<bool, std::is_base_of_v<stack_reference, T>> { };
8545  template <typename T>
8546  struct is_stack_table<basic_lua_table<T>> : std::integral_constant<bool, std::is_base_of_v<stack_reference, T>> { };
8547 
8548  template <typename T>
8549  inline constexpr bool is_stack_table_v = is_stack_table<T>::value;
8550 
8551  template <typename T>
8552  struct is_function : std::false_type { };
8553  template <typename T, bool aligned>
8554  struct is_function<basic_function<T, aligned>> : std::true_type { };
8555  template <typename T, bool aligned, typename Handler>
8556  struct is_function<basic_protected_function<T, aligned, Handler>> : std::true_type { };
8557 
8558  template <typename T>
8560 
8561  template <typename T>
8562  inline constexpr bool is_lightuserdata_v = is_lightuserdata<T>::value;
8563 
8564  template <typename T>
8566 
8567  template <typename T>
8568  inline constexpr bool is_userdata_v = is_userdata<T>::value;
8569 
8570  template <typename T>
8571  using is_environment = std::integral_constant<bool, is_userdata_v<T> || is_table_v<T> || meta::is_specialization_of_v<T, basic_environment>>;
8572 
8573  template <typename T>
8574  inline constexpr bool is_environment_v = is_environment<T>::value;
8575 
8576  template <typename T>
8577  using is_table_like = std::integral_constant<bool, is_table_v<T> || is_environment_v<T> || is_userdata_v<T>>;
8578 
8579  template <typename T>
8580  inline constexpr bool is_table_like_v = is_table_like<T>::value;
8581 
8582  template <typename T>
8584  : std::integral_constant<bool,
8585  (SOL_IS_ON(SOL_DEFAULT_AUTOMAGICAL_USERTYPES))
8586  || (std::is_array_v<
8587  meta::unqualified_t<T>> || (!std::is_same_v<meta::unqualified_t<T>, state> && !std::is_same_v<meta::unqualified_t<T>, state_view>))> {
8588  };
8589 
8590  template <typename T>
8591  inline type type_of() {
8592  return lua_type_of<meta::unqualified_t<T>>::value;
8593  }
8594 
8595  namespace detail {
8596  template <typename T>
8597  struct is_non_factory_constructor : std::false_type { };
8598 
8599  template <typename... Args>
8600  struct is_non_factory_constructor<constructors<Args...>> : std::true_type { };
8601 
8602  template <typename... Args>
8603  struct is_non_factory_constructor<constructor_wrapper<Args...>> : std::true_type { };
8604 
8605  template <>
8606  struct is_non_factory_constructor<no_construction> : std::true_type { };
8607 
8608  template <typename T>
8609  inline constexpr bool is_non_factory_constructor_v = is_non_factory_constructor<T>::value;
8610 
8611  template <typename T>
8613 
8614  template <typename... Args>
8615  struct is_constructor<factory_wrapper<Args...>> : std::true_type { };
8616 
8617  template <typename T>
8618  struct is_constructor<protect_t<T>> : is_constructor<meta::unqualified_t<T>> { };
8619 
8620  template <typename F, typename... Policies>
8621  struct is_constructor<policy_wrapper<F, Policies...>> : is_constructor<meta::unqualified_t<F>> { };
8622 
8623  template <typename T>
8624  inline constexpr bool is_constructor_v = is_constructor<T>::value;
8625 
8626  template <typename... Args>
8628 
8629  template <typename... Args>
8630  inline constexpr bool any_is_constructor_v = any_is_constructor<Args...>::value;
8631 
8632  template <typename T>
8633  struct is_destructor : std::false_type { };
8634 
8635  template <typename Fx>
8636  struct is_destructor<destructor_wrapper<Fx>> : std::true_type { };
8637 
8638  template <typename... Args>
8640 
8641  template <typename... Args>
8642  inline constexpr bool any_is_destructor_v = any_is_destructor<Args...>::value;
8643  } // namespace detail
8644 
8645  template <typename T>
8646  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>>;
8647 
8648  template <typename T>
8649  inline constexpr bool is_lua_c_function_v = is_lua_c_function<T>::value;
8650 
8651  enum class automagic_flags : unsigned {
8652  none = 0x000u,
8653  default_constructor = 0x001,
8654  destructor = 0x002u,
8655  pairs_operator = 0x004u,
8656  to_string_operator = 0x008u,
8657  call_operator = 0x010u,
8658  less_than_operator = 0x020u,
8659  less_than_or_equal_to_operator = 0x040u,
8660  length_operator = 0x080u,
8661  equal_to_operator = 0x100u,
8662  all = default_constructor | destructor | pairs_operator | to_string_operator | call_operator | less_than_operator | less_than_or_equal_to_operator
8663  | length_operator | equal_to_operator
8664  };
8665 
8666  inline constexpr automagic_flags operator|(automagic_flags left, automagic_flags right) noexcept {
8667  return static_cast<automagic_flags>(
8668  static_cast<std::underlying_type_t<automagic_flags>>(left) | static_cast<std::underlying_type_t<automagic_flags>>(right));
8669  }
8670 
8671  inline constexpr automagic_flags operator&(automagic_flags left, automagic_flags right) noexcept {
8672  return static_cast<automagic_flags>(
8673  static_cast<std::underlying_type_t<automagic_flags>>(left) & static_cast<std::underlying_type_t<automagic_flags>>(right));
8674  }
8675 
8676  inline constexpr automagic_flags& operator|=(automagic_flags& left, automagic_flags right) noexcept {
8677  left = left | right;
8678  return left;
8679  }
8680 
8681  inline constexpr automagic_flags& operator&=(automagic_flags& left, automagic_flags right) noexcept {
8682  left = left & right;
8683  return left;
8684  }
8685 
8686  template <typename Left, typename Right>
8687  constexpr bool has_flag(Left left, Right right) noexcept {
8688  return (left & right) == right;
8689  }
8690 
8691  template <typename Left, typename Right>
8692  constexpr bool has_any_flag(Left left, Right right) noexcept {
8693  return (left & right) != static_cast<Left>(static_cast<std::underlying_type_t<Left>>(0));
8694  }
8695 
8696  template <typename Left, typename Right>
8697  constexpr auto clear_flags(Left left, Right right) noexcept {
8698  return static_cast<Left>(static_cast<std::underlying_type_t<Left>>(left) & ~static_cast<std::underlying_type_t<Right>>(right));
8699  }
8700 
8702  bool default_constructor = true;
8703  bool destructor = true;
8704  bool pairs_operator = true;
8705  bool to_string_operator = true;
8706  bool call_operator = true;
8707  bool less_than_operator = true;
8708  bool less_than_or_equal_to_operator = true;
8709  bool length_operator = true;
8710  bool equal_to_operator = true;
8711  };
8712 
8713  template <automagic_flags compile_time_defaults = automagic_flags::all>
8715 
8716 } // namespace sol
8717 
8718 // end of sol/types.hpp
8719 
8720 #include <exception>
8721 #include <cstring>
8722 
8723 #if SOL_IS_ON(SOL_PRINT_ERRORS)
8724 #include <iostream>
8725 #endif
8726 
8727 namespace sol {
8728  // must push a single object to be the error object
8729  // NOTE: the VAST MAJORITY of all Lua libraries -- C or otherwise -- expect a string for the type of error
8730  // break this convention at your own risk
8731  using exception_handler_function = int (*)(lua_State*, optional<const std::exception&>, string_view);
8732 
8733  namespace detail {
8734  inline const char (&default_exception_handler_name())[11] {
8735  static const char name[11] = "sol.\xE2\x98\xA2\xE2\x98\xA2";
8736  return name;
8737  }
8738 
8739  // must push at least 1 object on the stack
8740  inline int default_exception_handler(lua_State* L, optional<const std::exception&>, string_view what) {
8741 #if SOL_IS_ON(SOL_PRINT_ERRORS)
8742  std::cerr << "[sol2] An exception occurred: ";
8743  std::cerr.write(what.data(), static_cast<std::streamsize>(what.size()));
8744  std::cerr << std::endl;
8745 #endif
8746  lua_pushlstring(L, what.data(), what.size());
8747  return 1;
8748  }
8749 
8750  inline int call_exception_handler(lua_State* L, optional<const std::exception&> maybe_ex, string_view what) {
8751  lua_getglobal(L, default_exception_handler_name());
8752  type t = static_cast<type>(lua_type(L, -1));
8753  if (t != type::lightuserdata) {
8754  lua_pop(L, 1);
8755  return default_exception_handler(L, std::move(maybe_ex), std::move(what));
8756  }
8757  void* vfunc = lua_touserdata(L, -1);
8758  lua_pop(L, 1);
8759  if (vfunc == nullptr) {
8760  return default_exception_handler(L, std::move(maybe_ex), std::move(what));
8761  }
8762  exception_handler_function exfunc = reinterpret_cast<exception_handler_function>(vfunc);
8763  return exfunc(L, std::move(maybe_ex), std::move(what));
8764  }
8765 
8766 #if SOL_IS_OFF(SOL_EXCEPTIONS)
8767  template <lua_CFunction f>
8768  int static_trampoline(lua_State* L) noexcept {
8769  return f(L);
8770  }
8771 
8772 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
8773  template <lua_CFunction_noexcept f>
8774  int static_trampoline_noexcept(lua_State* L) noexcept {
8775  return f(L);
8776  }
8777 #else
8778  template <lua_CFunction f>
8779  int static_trampoline_noexcept(lua_State* L) noexcept {
8780  return f(L);
8781  }
8782 #endif
8783 
8784  template <typename Fx, typename... Args>
8785  int trampoline(lua_State* L, Fx&& f, Args&&... args) noexcept {
8786  return f(L, std::forward<Args>(args)...);
8787  }
8788 
8789  inline int c_trampoline(lua_State* L, lua_CFunction f) noexcept {
8790  return trampoline(L, f);
8791  }
8792 #else
8793 
8794  inline int lua_cfunction_trampoline(lua_State* L, lua_CFunction f) {
8795 #if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS)
8796  return f(L);
8797 #else
8798  try {
8799  return f(L);
8800  }
8801  catch (const char* cs) {
8802  call_exception_handler(L, optional<const std::exception&>(nullopt), string_view(cs));
8803  }
8804  catch (const std::string& s) {
8805  call_exception_handler(L, optional<const std::exception&>(nullopt), string_view(s.c_str(), s.size()));
8806  }
8807  catch (const std::exception& e) {
8808  call_exception_handler(L, optional<const std::exception&>(e), e.what());
8809  }
8810 #if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL)
8811  // LuaJIT cannot have the catchall when the safe propagation is on
8812  // but LuaJIT will swallow all C++ errors
8813  // if we don't at least catch std::exception ones
8814  catch (...) {
8815  call_exception_handler(L, optional<const std::exception&>(nullopt), "caught (...) exception");
8816  }
8817 #endif // LuaJIT cannot have the catchall, but we must catch std::exceps for it
8818  return lua_error(L);
8819 #endif // Safe exceptions
8820  }
8821 
8822  template <lua_CFunction f>
8823  int static_trampoline(lua_State* L) {
8824  return lua_cfunction_trampoline(L, f);
8825  }
8826 
8827 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
8828  template <lua_CFunction_noexcept f>
8829  int static_trampoline_noexcept(lua_State* L) noexcept {
8830  return f(L);
8831  }
8832 #else
8833  template <lua_CFunction f>
8834  int static_trampoline_noexcept(lua_State* L) noexcept {
8835  return f(L);
8836  }
8837 #endif
8838 
8839  template <typename Fx, typename... Args>
8840  int trampoline(lua_State* L, Fx&& f, Args&&... args) {
8841  if constexpr (meta::bind_traits<meta::unqualified_t<Fx>>::is_noexcept) {
8842  return f(L, std::forward<Args>(args)...);
8843  }
8844  else {
8845 #if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS)
8846  return f(L, std::forward<Args>(args)...);
8847 #else
8848  try {
8849  return f(L, std::forward<Args>(args)...);
8850  }
8851  catch (const char* cs) {
8852  call_exception_handler(L, optional<const std::exception&>(nullopt), string_view(cs));
8853  }
8854  catch (const std::string& s) {
8855  call_exception_handler(L, optional<const std::exception&>(nullopt), string_view(s.c_str(), s.size()));
8856  }
8857  catch (const std::exception& e) {
8858  call_exception_handler(L, optional<const std::exception&>(e), e.what());
8859  }
8860 #if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL)
8861  // LuaJIT cannot have the catchall when the safe propagation is on
8862  // but LuaJIT will swallow all C++ errors
8863  // if we don't at least catch std::exception ones
8864  catch (...) {
8865  call_exception_handler(L, optional<const std::exception&>(nullopt), "caught (...) exception");
8866  }
8867 #endif
8868  return lua_error(L);
8869 #endif
8870  }
8871  }
8872 
8873  inline int c_trampoline(lua_State* L, lua_CFunction f) {
8874  return trampoline(L, f);
8875  }
8876 #endif // Exceptions vs. No Exceptions
8877 
8878  template <typename F, F fx>
8879  inline int typed_static_trampoline(lua_State* L) {
8880 #if 0
8881  // TODO: you must evaluate the get/check_get of every
8882  // argument, to ensure it doesn't throw
8883  // (e.g., for the sol_lua_check_access extension point!)
8884  // This incluudes properly noexcept-ing all the above
8885  // trampolines / safety nets
8886  if constexpr (meta::bind_traits<F>::is_noexcept) {
8887  return static_trampoline_noexcept<fx>(L);
8888  }
8889  else
8890 #endif
8891  { return static_trampoline<fx>(L); }
8892  }
8893  } // namespace detail
8894 
8895  inline void set_default_exception_handler(lua_State* L, exception_handler_function exf = &detail::default_exception_handler) {
8896  static_assert(sizeof(void*) >= sizeof(exception_handler_function),
8897  "void* storage is too small to transport the exception handler: please file a bug on the sol2 issue tracker to get this looked at!");
8898  void* storage;
8899  std::memcpy(&storage, &exf, sizeof(exception_handler_function));
8900  lua_pushlightuserdata(L, storage);
8901  lua_setglobal(L, detail::default_exception_handler_name());
8902  }
8903 } // namespace sol
8904 
8905 // end of sol/trampoline.hpp
8906 
8907 // beginning of sol/stack_core.hpp
8908 
8909 // beginning of sol/inheritance.hpp
8910 
8911 // beginning of sol/usertype_traits.hpp
8912 
8913 // beginning of sol/demangle.hpp
8914 
8915 #include <string>
8916 #include <array>
8917 #include <cctype>
8918 #if SOL_IS_ON(SOL_MINGW_CCTYPE_IS_POISONED)
8919 extern "C" {
8920 #include <ctype.h>
8921 }
8922 #endif // MinGW is on some stuff
8923 #include <locale>
8924 
8925 namespace sol { namespace detail {
8926  inline constexpr std::array<string_view, 9> removals { { "{anonymous}",
8927  "(anonymous namespace)",
8928  "public:",
8929  "private:",
8930  "protected:",
8931  "struct ",
8932  "class ",
8933  "`anonymous-namespace'",
8934  "`anonymous namespace'" } };
8935 
8936 #if SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
8937  inline std::string ctti_get_type_name_from_sig(std::string name) {
8938  // cardinal sins from MINGW
8939  using namespace std;
8940  std::size_t start = name.find_first_of('[');
8941  start = name.find_first_of('=', start);
8942  std::size_t end = name.find_last_of(']');
8943  if (end == std::string::npos)
8944  end = name.size();
8945  if (start == std::string::npos)
8946  start = 0;
8947  if (start < name.size() - 1)
8948  start += 1;
8949  name = name.substr(start, end - start);
8950  start = name.rfind("seperator_mark");
8951  if (start != std::string::npos) {
8952  name.erase(start - 2, name.length());
8953  }
8954  while (!name.empty() && isblank(name.front()))
8955  name.erase(name.begin());
8956  while (!name.empty() && isblank(name.back()))
8957  name.pop_back();
8958 
8959  for (std::size_t r = 0; r < removals.size(); ++r) {
8960  auto found = name.find(removals[r]);
8961  while (found != std::string::npos) {
8962  name.erase(found, removals[r].size());
8963  found = name.find(removals[r]);
8964  }
8965  }
8966 
8967  return name;
8968  }
8969 
8970  template <typename T, class seperator_mark = int>
8971  inline std::string ctti_get_type_name() {
8972  return ctti_get_type_name_from_sig(__PRETTY_FUNCTION__);
8973  }
8974 #elif SOL_IS_ON(SOL_COMPILER_VCXX)
8975  inline std::string ctti_get_type_name_from_sig(std::string name) {
8976  std::size_t start = name.find("get_type_name");
8977  if (start == std::string::npos)
8978  start = 0;
8979  else
8980  start += 13;
8981  if (start < name.size() - 1)
8982  start += 1;
8983  std::size_t end = name.find_last_of('>');
8984  if (end == std::string::npos)
8985  end = name.size();
8986  name = name.substr(start, end - start);
8987  if (name.find("struct", 0) == 0)
8988  name.replace(0, 6, "", 0);
8989  if (name.find("class", 0) == 0)
8990  name.replace(0, 5, "", 0);
8991  while (!name.empty() && isblank(name.front()))
8992  name.erase(name.begin());
8993  while (!name.empty() && isblank(name.back()))
8994  name.pop_back();
8995 
8996  for (std::size_t r = 0; r < removals.size(); ++r) {
8997  auto found = name.find(removals[r]);
8998  while (found != std::string::npos) {
8999  name.erase(found, removals[r].size());
9000  found = name.find(removals[r]);
9001  }
9002  }
9003 
9004  return name;
9005  }
9006 
9007  template <typename T>
9008  std::string ctti_get_type_name() {
9009  return ctti_get_type_name_from_sig(__FUNCSIG__);
9010  }
9011 #else
9012 #error Compiler not supported for demangling
9013 #endif // compilers
9014 
9015  template <typename T>
9016  std::string demangle_once() {
9017  std::string realname = ctti_get_type_name<T>();
9018  return realname;
9019  }
9020 
9021  inline std::string short_demangle_from_type_name(std::string realname) {
9022  // This isn't the most complete but it'll do for now...?
9023  static const std::array<std::string, 10> ops = {
9024  { "operator<", "operator<<", "operator<<=", "operator<=", "operator>", "operator>>", "operator>>=", "operator>=", "operator->", "operator->*" }
9025  };
9026  int level = 0;
9027  std::size_t idx = 0;
9028  for (idx = static_cast<std::size_t>(realname.empty() ? 0 : realname.size() - 1); idx > 0; --idx) {
9029  if (level == 0 && realname[idx] == ':') {
9030  break;
9031  }
9032  bool isleft = realname[idx] == '<';
9033  bool isright = realname[idx] == '>';
9034  if (!isleft && !isright)
9035  continue;
9036  bool earlybreak = false;
9037  for (const auto& op : ops) {
9038  std::size_t nisop = realname.rfind(op, idx);
9039  if (nisop == std::string::npos)
9040  continue;
9041  std::size_t nisopidx = idx - op.size() + 1;
9042  if (nisop == nisopidx) {
9043  idx = static_cast<std::size_t>(nisopidx);
9044  earlybreak = true;
9045  }
9046  break;
9047  }
9048  if (earlybreak) {
9049  continue;
9050  }
9051  level += isleft ? -1 : 1;
9052  }
9053  if (idx > 0) {
9054  realname.erase(0, realname.length() < static_cast<std::size_t>(idx) ? realname.length() : idx + 1);
9055  }
9056  return realname;
9057  }
9058 
9059  template <typename T>
9060  std::string short_demangle_once() {
9061  std::string realname = ctti_get_type_name<T>();
9062  return short_demangle_from_type_name(realname);
9063  }
9064 
9065  template <typename T>
9066  const std::string& demangle() {
9067  static const std::string d = demangle_once<T>();
9068  return d;
9069  }
9070 
9071  template <typename T>
9072  const std::string& short_demangle() {
9073  static const std::string d = short_demangle_once<T>();
9074  return d;
9075  }
9076 }} // namespace sol::detail
9077 
9078 // end of sol/demangle.hpp
9079 
9080 namespace sol {
9081 
9082  template <typename T>
9083  struct usertype_traits {
9084  static const std::string& name() {
9085  static const std::string& n = detail::short_demangle<T>();
9086  return n;
9087  }
9088  static const std::string& qualified_name() {
9089  static const std::string& q_n = detail::demangle<T>();
9090  return q_n;
9091  }
9092  static const std::string& metatable() {
9093  static const std::string m = std::string("sol.").append(detail::demangle<T>());
9094  return m;
9095  }
9096  static const std::string& user_metatable() {
9097  static const std::string u_m = std::string("sol.").append(detail::demangle<T>()).append(".user");
9098  return u_m;
9099  }
9100  static const std::string& user_gc_metatable() {
9101  static const std::string u_g_m = std::string("sol.").append(detail::demangle<T>()).append(".user\xE2\x99\xBB");
9102  return u_g_m;
9103  }
9104  static const std::string& gc_table() {
9105  static const std::string g_t = std::string("sol.").append(detail::demangle<T>()).append(".\xE2\x99\xBB");
9106  return g_t;
9107  }
9108  };
9109 
9110 } // namespace sol
9111 
9112 // end of sol/usertype_traits.hpp
9113 
9114 // beginning of sol/unique_usertype_traits.hpp
9115 
9116 #include <memory>
9117 
9118 namespace sol {
9119 
9120  namespace detail {
9121  template <typename T>
9123  using SOL_INTERNAL_UNSPECIALIZED_MARKER_ = int;
9124  };
9125 
9126  template <typename T>
9127  struct unique_fallback<std::shared_ptr<T>> {
9128  private:
9129  using pointer = typename std::pointer_traits<std::shared_ptr<T>>::element_type*;
9130 
9131  public:
9132  // rebind is non-void
9133  // if and only if unique usertype
9134  // is cast-capable
9135  template <typename X>
9136  using rebind_actual_type = std::shared_ptr<X>;
9137 
9138  static bool is_null(lua_State*, const std::shared_ptr<T>& p) noexcept {
9139  return p == nullptr;
9140  }
9141 
9142  static pointer get(lua_State*, const std::shared_ptr<T>& p) noexcept {
9143  return p.get();
9144  }
9145  };
9146 
9147  template <typename T, typename D>
9148  struct unique_fallback<std::unique_ptr<T, D>> {
9149  private:
9150  using pointer = typename std::unique_ptr<T, D>::pointer;
9151 
9152  public:
9153  static bool is_null(lua_State*, const std::unique_ptr<T, D>& p) noexcept {
9154  return p == nullptr;
9155  }
9156 
9157  static pointer get(lua_State*, const std::unique_ptr<T, D>& p) noexcept {
9158  return p.get();
9159  }
9160  };
9161  } // namespace detail
9162 
9163  namespace meta { namespace meta_detail {
9164  template <typename T, typename = void>
9166 
9167  template <typename T>
9168  struct unique_actual_type<T, meta::void_t<typename T::actual_type>> {
9169  using type = typename T::actual_type;
9170  };
9171 
9172  template <typename T, typename... Rest, template <typename...> class Templ>
9173  struct unique_actual_type<Templ<T, Rest...>> {
9174  using type = T;
9175  };
9176 
9177  }} // namespace meta::meta_detail
9178 
9179  template <typename T>
9180  using unique_usertype_actual_t = typename meta::meta_detail::unique_actual_type<unique_usertype_traits<T>>::type;
9181 
9182  namespace meta { namespace meta_detail {
9183  template <typename T>
9184  using value_test_t = decltype(T::value);
9185 
9186  template <typename T>
9187  using type_test_t = typename T::type;
9188 
9189  template <typename T>
9190  using type_element_type_t = typename T::element_type;
9191 
9192  template <typename T, typename = void>
9194  using type = typename std::pointer_traits<typename unique_actual_type<T>::type>::element_type;
9195  };
9196 
9197  template <typename T>
9198  struct unique_element_type<T, std::enable_if_t<meta::is_detected_v<type_element_type_t, T>>> {
9199  using type = typename T::element_type;
9200  };
9201 
9202  template <typename T>
9203  struct unique_element_type<T, std::enable_if_t<meta::is_detected_v<type_test_t, T>>> {
9204  using type = typename T::type;
9205  };
9206 
9207  template <typename T, typename = void>
9208  struct unique_valid : std::integral_constant<bool, !has_internal_marker_v<T>> { };
9209 
9210  template <typename T>
9211  struct unique_valid<T, meta::void_t<decltype(T::value)>> : std::integral_constant<bool, T::value> { };
9212  }} // namespace meta::meta_detail
9213 
9214  template <typename T>
9215  using unique_usertype_element_t = typename meta::meta_detail::unique_element_type<unique_usertype_traits<T>>::type;
9216 
9217  template <typename T, typename Element = void>
9218  using unique_usertype_rebind_actual_t = typename unique_usertype_traits<T>::template rebind_actual_type<Element>;
9219 
9220  template <typename T>
9221  struct unique_usertype_traits : public detail::unique_fallback<T> { };
9222 
9223  template <typename T>
9224  struct is_unique_usertype : std::integral_constant<bool, meta::meta_detail::unique_valid<unique_usertype_traits<T>>::value> { };
9225 
9226  template <typename T>
9227  inline constexpr bool is_unique_usertype_v = is_unique_usertype<T>::value;
9228 
9229  namespace meta { namespace meta_detail {
9230  template <typename T>
9231  using adl_sol_lua_check_access_test_t
9232  = decltype(sol_lua_check_access(types<T>(), static_cast<lua_State*>(nullptr), -1, std::declval<stack::record&>()));
9233 
9234  template <typename T>
9235  inline constexpr bool is_adl_sol_lua_check_access_v = meta::is_detected_v<adl_sol_lua_check_access_test_t, T>;
9236 
9237  template <typename T>
9238  using unique_usertype_get_with_state_test_t
9239  = decltype(unique_usertype_traits<T>::get(static_cast<lua_State*>(nullptr), std::declval<unique_usertype_actual_t<T>>()));
9240 
9241  template <typename T>
9242  inline constexpr bool unique_usertype_get_with_state_v = meta::is_detected_v<unique_usertype_get_with_state_test_t, T>;
9243 
9244  template <typename T>
9245  using unique_usertype_is_null_with_state_test_t
9246  = decltype(unique_usertype_traits<T>::is_null(static_cast<lua_State*>(nullptr), std::declval<unique_usertype_actual_t<T>>()));
9247 
9248  template <typename T>
9249  inline constexpr bool unique_usertype_is_null_with_state_v = meta::is_detected_v<unique_usertype_is_null_with_state_test_t, T>;
9250  }} // namespace meta::meta_detail
9251 
9252  namespace detail {
9253  template <typename T>
9254  constexpr bool unique_is_null_noexcept() noexcept {
9255  if constexpr (meta::meta_detail::unique_usertype_is_null_with_state_v<std::remove_cv_t<T>>) {
9256  return noexcept(
9257  unique_usertype_traits<T>::is_null(static_cast<lua_State*>(nullptr), std::declval<unique_usertype_actual_t<std::remove_cv_t<T>>>()));
9258  }
9259  else {
9260  return noexcept(unique_usertype_traits<T>::is_null(std::declval<unique_usertype_actual_t<std::remove_cv_t<T>>>()));
9261  }
9262  }
9263 
9264  template <typename T>
9265  bool unique_is_null(lua_State* L_, T& value_) noexcept(unique_is_null_noexcept<std::remove_cv_t<T>>()) {
9266  using Tu = std::remove_cv_t<T>;
9267  if constexpr (meta::meta_detail::unique_usertype_is_null_with_state_v<Tu>) {
9268  return unique_usertype_traits<Tu>::is_null(L_, value_);
9269  }
9270  else {
9271  return unique_usertype_traits<Tu>::is_null(value_);
9272  }
9273  }
9274 
9275  template <typename T>
9276  constexpr bool unique_get_noexcept() noexcept {
9277  if constexpr (meta::meta_detail::unique_usertype_get_with_state_v<std::remove_cv_t<T>>) {
9278  return noexcept(
9279  unique_usertype_traits<T>::get(static_cast<lua_State*>(nullptr), std::declval<unique_usertype_actual_t<std::remove_cv_t<T>>>()));
9280  }
9281  else {
9282  return noexcept(unique_usertype_traits<T>::get(std::declval<unique_usertype_actual_t<std::remove_cv_t<T>>>()));
9283  }
9284  }
9285 
9286  template <typename T>
9287  auto unique_get(lua_State* L_, T& value_) noexcept(unique_get_noexcept<std::remove_cv_t<T>>()) {
9288  using Tu = std::remove_cv_t<T>;
9289  if constexpr (meta::meta_detail::unique_usertype_get_with_state_v<Tu>) {
9290  return unique_usertype_traits<Tu>::get(L_, value_);
9291  }
9292  else {
9293  return unique_usertype_traits<Tu>::get(value_);
9294  }
9295  }
9296  } // namespace detail
9297 
9298  namespace meta { namespace meta_detail {
9299  template <typename T, typename Element = void>
9300  using is_rebind_actual_type_test_t = typename T::template rebind_actual_type<Element>;
9301 
9302  template <typename T, typename Element = void>
9303  using is_rebind_actual_type = meta::is_detected<is_rebind_actual_type_test_t, T, Element>;
9304 
9305  template <typename T, typename Element = void>
9306  inline constexpr bool is_rebind_actual_type_v = is_rebind_actual_type<T, Element>::value;
9307 
9308  template <typename T, typename Element, bool = is_rebind_actual_type_v<T, Element>>
9309  struct is_actual_type_rebindable_for_test : std::false_type { };
9310 
9311  template <typename T, typename Element>
9312  struct is_actual_type_rebindable_for_test<T, Element, true>
9313  : std::integral_constant<bool, !std::is_void_v<typename T::template rebind_actual_type<Element>>> { };
9314  }} // namespace meta::meta_detail
9315 
9316  template <typename T, typename Element = void>
9317  using is_actual_type_rebindable_for = typename meta::meta_detail::is_actual_type_rebindable_for_test<unique_usertype_traits<T>, Element>::type;
9318 
9319  template <typename T, typename Element = void>
9320  inline constexpr bool is_actual_type_rebindable_for_v = is_actual_type_rebindable_for<T, Element>::value;
9321 
9322 } // namespace sol
9323 
9324 // end of sol/unique_usertype_traits.hpp
9325 
9326 namespace sol {
9327  template <typename... Args>
9328  struct base_list { };
9329  template <typename... Args>
9330  using bases = base_list<Args...>;
9331 
9332  typedef bases<> base_classes_tag;
9333  const auto base_classes = base_classes_tag();
9334 
9335  template <typename... Args>
9336  struct is_to_stringable<base_list<Args...>> : std::false_type { };
9337 
9338  namespace detail {
9339 
9340  inline decltype(auto) base_class_check_key() {
9341  static const auto& key = "class_check";
9342  return key;
9343  }
9344 
9345  inline decltype(auto) base_class_cast_key() {
9346  static const auto& key = "class_cast";
9347  return key;
9348  }
9349 
9350  inline decltype(auto) base_class_index_propogation_key() {
9351  static const auto& key = u8"\xF0\x9F\x8C\xB2.index";
9352  return key;
9353  }
9354 
9355  inline decltype(auto) base_class_new_index_propogation_key() {
9356  static const auto& key = u8"\xF0\x9F\x8C\xB2.new_index";
9357  return key;
9358  }
9359 
9360  template <typename T>
9361  struct inheritance {
9362  typedef typename base<T>::type bases_t;
9363 
9364  static bool type_check_bases(types<>, const string_view&) {
9365  return false;
9366  }
9367 
9368  template <typename Base, typename... Args>
9369  static bool type_check_bases(types<Base, Args...>, const string_view& ti) {
9370  return ti == usertype_traits<Base>::qualified_name() || type_check_bases(types<Args...>(), ti);
9371  }
9372 
9373  static bool type_check(const string_view& ti) {
9374  return ti == usertype_traits<T>::qualified_name() || type_check_bases(bases_t(), ti);
9375  }
9376 
9377  template <typename... Bases>
9378  static bool type_check_with(const string_view& ti) {
9379  return ti == usertype_traits<T>::qualified_name() || type_check_bases(types<Bases...>(), ti);
9380  }
9381 
9382  static void* type_cast_bases(types<>, T*, const string_view&) {
9383  return nullptr;
9384  }
9385 
9386  template <typename Base, typename... Args>
9387  static void* type_cast_bases(types<Base, Args...>, T* data, const string_view& ti) {
9388  // Make sure to convert to T first, and then dynamic cast to the proper type
9389  return ti != usertype_traits<Base>::qualified_name() ? type_cast_bases(types<Args...>(), data, ti)
9390  : static_cast<void*>(static_cast<Base*>(data));
9391  }
9392 
9393  static void* type_cast(void* voiddata, const string_view& ti) {
9394  T* data = static_cast<T*>(voiddata);
9395  return static_cast<void*>(ti != usertype_traits<T>::qualified_name() ? type_cast_bases(bases_t(), data, ti) : data);
9396  }
9397 
9398  template <typename... Bases>
9399  static void* type_cast_with(void* voiddata, const string_view& ti) {
9400  T* data = static_cast<T*>(voiddata);
9401  return static_cast<void*>(ti != usertype_traits<T>::qualified_name() ? type_cast_bases(types<Bases...>(), data, ti) : data);
9402  }
9403 
9404  template <typename U>
9405  static bool type_unique_cast_bases(types<>, void*, void*, const string_view&) {
9406  return 0;
9407  }
9408 
9409  template <typename U, typename Base, typename... Args>
9410  static int type_unique_cast_bases(types<Base, Args...>, void* source_data, void* target_data, const string_view& ti) {
9411  using uu_traits = unique_usertype_traits<U>;
9412  using base_ptr = typename uu_traits::template rebind_actual_type<Base>;
9413  string_view base_ti = usertype_traits<Base>::qualified_name();
9414  if (base_ti == ti) {
9415  if (target_data != nullptr) {
9416  U* source = static_cast<U*>(source_data);
9417  base_ptr* target = static_cast<base_ptr*>(target_data);
9418  // perform proper derived -> base conversion
9419  *target = *source;
9420  }
9421  return 2;
9422  }
9423  return type_unique_cast_bases<U>(types<Args...>(), source_data, target_data, ti);
9424  }
9425 
9426  template <typename U>
9427  static int type_unique_cast(void* source_data, void* target_data, const string_view& ti, const string_view& rebind_ti) {
9428  if constexpr (is_actual_type_rebindable_for_v<U>) {
9429  using rebound_actual_type = unique_usertype_rebind_actual_t<U>;
9430  using maybe_bases_or_empty = meta::conditional_t<std::is_void_v<rebound_actual_type>, types<>, bases_t>;
9431  string_view this_rebind_ti = usertype_traits<rebound_actual_type>::qualified_name();
9432  if (rebind_ti != this_rebind_ti) {
9433  // this is not even of the same unique type
9434  return 0;
9435  }
9436  string_view this_ti = usertype_traits<T>::qualified_name();
9437  if (ti == this_ti) {
9438  // direct match, return 1
9439  return 1;
9440  }
9441  return type_unique_cast_bases<U>(maybe_bases_or_empty(), source_data, target_data, ti);
9442  }
9443  else {
9444  (void)rebind_ti;
9445  string_view this_ti = usertype_traits<T>::qualified_name();
9446  if (ti == this_ti) {
9447  // direct match, return 1
9448  return 1;
9449  }
9450  return type_unique_cast_bases<U>(types<>(), source_data, target_data, ti);
9451  }
9452  }
9453 
9454  template <typename U, typename... Bases>
9455  static int type_unique_cast_with(void* source_data, void* target_data, const string_view& ti, const string_view& rebind_ti) {
9456  using uc_bases_t = types<Bases...>;
9457  if constexpr (is_actual_type_rebindable_for_v<U>) {
9458  using rebound_actual_type = unique_usertype_rebind_actual_t<U>;
9459  using cond_bases_t = meta::conditional_t<std::is_void_v<rebound_actual_type>, types<>, uc_bases_t>;
9460  string_view this_rebind_ti = usertype_traits<rebound_actual_type>::qualified_name();
9461  if (rebind_ti != this_rebind_ti) {
9462  // this is not even of the same unique type
9463  return 0;
9464  }
9465  string_view this_ti = usertype_traits<T>::qualified_name();
9466  if (ti == this_ti) {
9467  // direct match, return 1
9468  return 1;
9469  }
9470  return type_unique_cast_bases<U>(cond_bases_t(), source_data, target_data, ti);
9471  }
9472  else {
9473  (void)rebind_ti;
9474  string_view this_ti = usertype_traits<T>::qualified_name();
9475  if (ti == this_ti) {
9476  // direct match, return 1
9477  return 1;
9478  }
9479  return type_unique_cast_bases<U>(types<>(), source_data, target_data, ti);
9480  }
9481  }
9482  };
9483 
9484  using inheritance_check_function = decltype(&inheritance<void>::type_check);
9485  using inheritance_cast_function = decltype(&inheritance<void>::type_cast);
9486  using inheritance_unique_cast_function = decltype(&inheritance<void>::type_unique_cast<void>);
9487  } // namespace detail
9488 } // namespace sol
9489 
9490 // end of sol/inheritance.hpp
9491 
9492 // beginning of sol/error_handler.hpp
9493 
9494 #include <cstdio>
9495 
9496 namespace sol {
9497 
9498  namespace detail {
9499  constexpr const char* not_a_number = "not a numeric type";
9500  constexpr const char* not_a_number_or_number_string = "not a numeric type or numeric string";
9501  constexpr const char* not_a_number_integral = "not a numeric type that fits exactly an integer (number maybe has significant decimals)";
9502  constexpr const char* not_a_number_or_number_string_integral
9503  = "not a numeric type or a numeric string that fits exactly an integer (e.g. number maybe has significant decimals)";
9504 
9505  constexpr const char* not_enough_stack_space = "not enough space left on Lua stack";
9506  constexpr const char* not_enough_stack_space_floating = "not enough space left on Lua stack for a floating point number";
9507  constexpr const char* not_enough_stack_space_integral = "not enough space left on Lua stack for an integral number";
9508  constexpr const char* not_enough_stack_space_string = "not enough space left on Lua stack for a string";
9509  constexpr const char* not_enough_stack_space_meta_function_name = "not enough space left on Lua stack for the name of a meta_function";
9510  constexpr const char* not_enough_stack_space_userdata = "not enough space left on Lua stack to create a sol2 userdata";
9511  constexpr const char* not_enough_stack_space_generic = "not enough space left on Lua stack to push valuees";
9512  constexpr const char* not_enough_stack_space_environment = "not enough space left on Lua stack to retrieve environment";
9513  constexpr const char* protected_function_error = "caught (...) unknown error during protected_function call";
9514 
9515  inline void accumulate_and_mark(const std::string& n, std::string& aux_message, int& marker) {
9516  if (marker > 0) {
9517  aux_message += ", ";
9518  }
9519  aux_message += n;
9520  ++marker;
9521  }
9522  } // namespace detail
9523 
9524  inline std::string associated_type_name(lua_State* L, int index, type t) {
9525  switch (t) {
9526  case type::poly:
9527  return "anything";
9528  case type::userdata: {
9529 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
9530  luaL_checkstack(L, 2, "not enough space to push get the type name");
9531 #endif // make sure stack doesn't overflow
9532  if (lua_getmetatable(L, index) == 0) {
9533  break;
9534  }
9535  lua_pushlstring(L, "__name", 6);
9536  lua_rawget(L, -2);
9537  size_t sz;
9538  const char* name = lua_tolstring(L, -1, &sz);
9539  std::string tn(name, static_cast<std::string::size_type>(sz));
9540  lua_pop(L, 2);
9541  return tn;
9542  }
9543  default:
9544  break;
9545  }
9546  return lua_typename(L, static_cast<int>(t));
9547  }
9548 
9549  inline int push_type_panic_string(lua_State* L, int index, type expected, type actual, string_view message, string_view aux_message) noexcept {
9550  const char* err = message.size() == 0
9551  ? (aux_message.size() == 0 ? "stack index %d, expected %s, received %s" : "stack index %d, expected %s, received %s: %s")
9552  : "stack index %d, expected %s, received %s: %s %s";
9553  const char* type_name = expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected));
9554  {
9555  std::string actual_name = associated_type_name(L, index, actual);
9556  lua_pushfstring(L, err, index, type_name, actual_name.c_str(), message.data(), aux_message.data());
9557  }
9558  return 1;
9559  }
9560 
9561  inline int type_panic_string(lua_State* L, int index, type expected, type actual, string_view message = "") noexcept(false) {
9562  push_type_panic_string(L, index, expected, actual, message, "");
9563  return lua_error(L);
9564  }
9565 
9566  inline int type_panic_c_str(lua_State* L, int index, type expected, type actual, const char* message = nullptr) noexcept(false) {
9567  push_type_panic_string(L, index, expected, actual, message == nullptr ? "" : message, "");
9568  return lua_error(L);
9569  }
9570 
9571  struct type_panic_t {
9572  int operator()(lua_State* L, int index, type expected, type actual) const noexcept(false) {
9573  return type_panic_c_str(L, index, expected, actual, nullptr);
9574  }
9575  int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
9576  return type_panic_c_str(L, index, expected, actual, message.data());
9577  }
9578  };
9579 
9580  const type_panic_t type_panic = {};
9581 
9583  int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
9584  push_type_panic_string(L, index, expected, actual, message, "(type check failed in constructor)");
9585  return lua_error(L);
9586  }
9587  };
9588 
9589  template <typename F = void>
9591  int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
9592  push_type_panic_string(L, index, expected, actual, message, "(bad argument to variable or function call)");
9593  return lua_error(L);
9594  }
9595  };
9596 
9597  template <typename R, typename... Args>
9598  struct argument_handler<types<R, Args...>> {
9599  int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
9600  {
9601  std::string aux_message = "(bad argument into '";
9602  aux_message += detail::demangle<R>();
9603  aux_message += "(";
9604  int marker = 0;
9605  (void)detail::swallow { int(), (detail::accumulate_and_mark(detail::demangle<Args>(), aux_message, marker), int())... };
9606  aux_message += ")')";
9607  push_type_panic_string(L, index, expected, actual, message, aux_message);
9608  }
9609  return lua_error(L);
9610  }
9611  };
9612 
9613  // Specify this function as the handler for lua::check if you know there's nothing wrong
9614  inline int no_panic(lua_State*, int, type, type, const char* = nullptr) noexcept {
9615  return 0;
9616  }
9617 
9618  inline void type_error(lua_State* L, int expected, int actual) noexcept(false) {
9619  luaL_error(L, "expected %s, received %s", lua_typename(L, expected), lua_typename(L, actual));
9620  }
9621 
9622  inline void type_error(lua_State* L, type expected, type actual) noexcept(false) {
9623  type_error(L, static_cast<int>(expected), static_cast<int>(actual));
9624  }
9625 
9626  inline void type_assert(lua_State* L, int index, type expected, type actual) noexcept(false) {
9627  if (expected != type::poly && expected != actual) {
9628  type_panic_c_str(L, index, expected, actual, nullptr);
9629  }
9630  }
9631 
9632  inline void type_assert(lua_State* L, int index, type expected) {
9633  type actual = type_of(L, index);
9634  type_assert(L, index, expected, actual);
9635  }
9636 
9637 } // namespace sol
9638 
9639 // end of sol/error_handler.hpp
9640 
9641 // beginning of sol/reference.hpp
9642 
9643 // beginning of sol/stack_reference.hpp
9644 
9645 namespace sol {
9646  namespace detail {
9647  inline bool xmovable(lua_State* leftL, lua_State* rightL) {
9648  if (rightL == nullptr || leftL == nullptr || leftL == rightL) {
9649  return false;
9650  }
9651  const void* leftregistry = lua_topointer(leftL, LUA_REGISTRYINDEX);
9652  const void* rightregistry = lua_topointer(rightL, LUA_REGISTRYINDEX);
9653  return leftregistry == rightregistry;
9654  }
9655  } // namespace detail
9656 
9658  private:
9659  friend class stack_reference;
9660 
9661  int m_index = 0;
9662 
9663  int registry_index() const noexcept {
9664  return LUA_NOREF;
9665  }
9666 
9667  public:
9668  stateless_stack_reference() noexcept = default;
9670  stateless_stack_reference(lua_State* L_, int index_) noexcept : stateless_stack_reference(absolute_index(L_, index_)) {
9671  }
9673  }
9675  }
9676  stateless_stack_reference(absolute_index index_) noexcept : m_index(index_) {
9677  }
9678  stateless_stack_reference(raw_index index_) noexcept : m_index(index_) {
9679  }
9680  stateless_stack_reference(lua_State*, ref_index) noexcept = delete;
9681  stateless_stack_reference(ref_index) noexcept = delete;
9682  stateless_stack_reference(const reference&) noexcept = delete;
9683  stateless_stack_reference(const stateless_stack_reference&) noexcept = default;
9684  stateless_stack_reference(stateless_stack_reference&& o) noexcept = default;
9685  stateless_stack_reference& operator=(stateless_stack_reference&&) noexcept = default;
9686  stateless_stack_reference& operator=(const stateless_stack_reference&) noexcept = default;
9687 
9688  int push(lua_State* L_) const noexcept {
9689 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
9690  luaL_checkstack(L_, 1, "not enough Lua stack space to push a single reference value");
9691 #endif // make sure stack doesn't overflow
9692  lua_pushvalue(L_, m_index);
9693  return 1;
9694  }
9695 
9696  void pop(lua_State* L_, int pop_count = 1) const noexcept {
9697  lua_pop(L_, pop_count);
9698  }
9699 
9700  int stack_index() const noexcept {
9701  return m_index;
9702  }
9703 
9704  const void* pointer(lua_State* L_) const noexcept {
9705  const void* pointer_id = lua_topointer(L_, stack_index());
9706  return pointer_id;
9707  }
9708 
9709  type get_type(lua_State* L_) const noexcept {
9710  int untyped_value = lua_type(L_, stack_index());
9711  return static_cast<type>(untyped_value);
9712  }
9713 
9714  bool valid(lua_State* L) const noexcept {
9715  type t = get_type(L);
9716  return t != type::lua_nil && t != type::none;
9717  }
9718 
9719  void reset(lua_State*) noexcept {
9720  m_index = 0;
9721  }
9722 
9723  void reset(lua_State* L_, int index_) noexcept {
9724  m_index = absolute_index(L_, index_);
9725  }
9726 
9727  void abandon(lua_State* = nullptr) noexcept {
9728  m_index = 0;
9729  }
9730 
9731  stateless_stack_reference copy(lua_State* L_) const noexcept {
9732  return stateless_stack_reference(L_, raw_index(m_index));
9733  }
9734 
9735  void copy_assign(lua_State*, const stateless_stack_reference& right) noexcept {
9736  m_index = right.m_index;
9737  }
9738 
9739  bool equals(lua_State* L_, const stateless_stack_reference& r) const noexcept {
9740  return lua_compare(L_, this->stack_index(), r.stack_index(), LUA_OPEQ) == 1;
9741  }
9742 
9743  bool equals(lua_State* L_, lua_nil_t) const noexcept {
9744  return valid(L_);
9745  }
9746  };
9747 
9749  private:
9750  lua_State* luastate = nullptr;
9751 
9752  public:
9753  stack_reference() noexcept = default;
9754  stack_reference(lua_nil_t) noexcept : stack_reference() {};
9755  stack_reference(lua_State* L, lua_nil_t) noexcept : stateless_stack_reference(L, 0), luastate(L) {
9756  }
9757  stack_reference(lua_State* L, int i) noexcept : stateless_stack_reference(L, i), luastate(L) {
9758  }
9759  stack_reference(lua_State* L, absolute_index i) noexcept : stateless_stack_reference(L, i), luastate(L) {
9760  }
9761  stack_reference(lua_State* L, raw_index i) noexcept : stateless_stack_reference(L, i), luastate(L) {
9762  }
9763  stack_reference(lua_State* L, ref_index i) noexcept = delete;
9764  stack_reference(lua_State* L, const reference& r) noexcept = delete;
9765  stack_reference(lua_State* L, const stack_reference& r) noexcept : luastate(L) {
9766  if (!r.valid()) {
9767  m_index = 0;
9768  return;
9769  }
9770  int i = r.stack_index();
9771  if (detail::xmovable(lua_state(), r.lua_state())) {
9772 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
9773  luaL_checkstack(L, 1, "not enough Lua stack space to push a single reference value");
9774 #endif // make sure stack doesn't overflow
9775  lua_pushvalue(r.lua_state(), r.stack_index());
9776  lua_xmove(r.lua_state(), luastate, 1);
9777  i = absolute_index(luastate, -1);
9778  }
9779  m_index = i;
9780  }
9781  stack_reference(stack_reference&& o) noexcept = default;
9782  stack_reference& operator=(stack_reference&&) noexcept = default;
9783  stack_reference(const stack_reference&) noexcept = default;
9784  stack_reference& operator=(const stack_reference&) noexcept = default;
9785 
9786  int push() const noexcept {
9787  return push(lua_state());
9788  }
9789 
9790  int push(lua_State* L_) const noexcept {
9791  return stateless_stack_reference::push(L_);
9792  }
9793 
9794  void pop() const noexcept {
9795  pop(lua_state());
9796  }
9797 
9798  void pop(lua_State* L_, int pop_count_ = 1) const noexcept {
9799  stateless_stack_reference::pop(L_, pop_count_);
9800  }
9801 
9802  const void* pointer() const noexcept {
9803  return stateless_stack_reference::pointer(lua_state());
9804  }
9805 
9806  type get_type() const noexcept {
9807  return stateless_stack_reference::get_type(lua_state());
9808  }
9809 
9810  lua_State* lua_state() const noexcept {
9811  return luastate;
9812  }
9813 
9814  bool valid() const noexcept {
9815  return stateless_stack_reference::valid(lua_state());
9816  }
9817 
9818  void abandon() {
9819  stateless_stack_reference::abandon(lua_state());
9820  }
9821  };
9822 
9823  inline bool operator==(const stack_reference& l, const stack_reference& r) {
9824  return lua_compare(l.lua_state(), l.stack_index(), r.stack_index(), LUA_OPEQ) == 1;
9825  }
9826 
9827  inline bool operator!=(const stack_reference& l, const stack_reference& r) {
9828  return !operator==(l, r);
9829  }
9830 
9831  inline bool operator==(const stack_reference& lhs, const lua_nil_t&) {
9832  return !lhs.valid();
9833  }
9834 
9835  inline bool operator==(const lua_nil_t&, const stack_reference& rhs) {
9836  return !rhs.valid();
9837  }
9838 
9839  inline bool operator!=(const stack_reference& lhs, const lua_nil_t&) {
9840  return lhs.valid();
9841  }
9842 
9843  inline bool operator!=(const lua_nil_t&, const stack_reference& rhs) {
9844  return rhs.valid();
9845  }
9846 
9847  inline bool operator==(const stateless_stack_reference& l, const stateless_stack_reference& r) {
9848  return l.stack_index() == r.stack_index();
9849  }
9850 
9851  inline bool operator!=(const stateless_stack_reference& l, const stateless_stack_reference& r) {
9852  return l.stack_index() != r.stack_index();
9853  }
9854 
9856  using is_transparent = std::true_type;
9857 
9858  stateless_stack_reference_equals(lua_State* L_) noexcept : m_L(L_) {
9859  }
9860 
9861  lua_State* lua_state() const noexcept {
9862  return m_L;
9863  }
9864 
9865  bool operator()(const stateless_stack_reference& lhs, const stateless_stack_reference& rhs) const {
9866  return lhs.equals(lua_state(), rhs);
9867  }
9868 
9869  bool operator()(lua_nil_t lhs, const stateless_stack_reference& rhs) const {
9870  return rhs.equals(lua_state(), lhs);
9871  }
9872 
9873  bool operator()(const stateless_stack_reference& lhs, lua_nil_t rhs) const {
9874  return lhs.equals(lua_state(), rhs);
9875  }
9876 
9877  private:
9878  lua_State* m_L;
9879  };
9880 
9882  using is_transparent = std::true_type;
9883 
9884  bool operator()(const lua_nil_t& lhs, const stack_reference& rhs) const {
9885  return lhs == rhs;
9886  }
9887 
9888  bool operator()(const stack_reference& lhs, const lua_nil_t& rhs) const {
9889  return lhs == rhs;
9890  }
9891 
9892  bool operator()(const stack_reference& lhs, const stack_reference& rhs) const {
9893  return lhs == rhs;
9894  }
9895  };
9896 
9899  using result_type = std::size_t;
9900  using is_transparent = std::true_type;
9901 
9902  stateless_stack_reference_hash(lua_State* L_) noexcept : m_L(L_) {
9903  }
9904 
9905  lua_State* lua_state() const noexcept {
9906  return m_L;
9907  }
9908 
9909  result_type operator()(const argument_type& lhs) const noexcept {
9910  std::hash<const void*> h;
9911  return h(lhs.pointer(lua_state()));
9912  }
9913 
9914  private:
9915  lua_State* m_L;
9916  };
9917 
9920  using result_type = std::size_t;
9921  using is_transparent = std::true_type;
9922 
9923  result_type operator()(const argument_type& lhs) const noexcept {
9924  std::hash<const void*> h;
9925  return h(lhs.pointer());
9926  }
9927  };
9928 } // namespace sol
9929 
9930 // end of sol/stack_reference.hpp
9931 
9932 #include <functional>
9933 
9934 namespace sol {
9935  namespace detail {
9936  inline const char (&default_main_thread_name())[9] {
9937  static const char name[9] = "sol.\xF0\x9F\x93\x8C";
9938  return name;
9939  }
9940  } // namespace detail
9941 
9942  namespace stack {
9943  inline void remove(lua_State* L_, int rawindex, int count) {
9944  if (count < 1)
9945  return;
9946  int top = lua_gettop(L_);
9947  if (top < 1) {
9948  return;
9949  }
9950  if (rawindex == -count || top == rawindex) {
9951  // Slice them right off the top
9952  lua_pop(L_, static_cast<int>(count));
9953  return;
9954  }
9955 
9956  // Remove each item one at a time using stack operations
9957  // Probably slower, maybe, haven't benchmarked,
9958  // but necessary
9959  int index = lua_absindex(L_, rawindex);
9960  if (index < 0) {
9961  index = lua_gettop(L_) + (index + 1);
9962  }
9963  int last = index + count;
9964  for (int i = index; i < last; ++i) {
9965  lua_remove(L_, index);
9966  }
9967  }
9968 
9970  lua_State* L;
9971  int index;
9972  int count;
9973  push_popper_at(lua_State* L_, int index_ = -1, int count_ = 1) : L(L_), index(index_), count(count_) {
9974  }
9975  ~push_popper_at() {
9976  remove(L, index, count);
9977  }
9978  };
9979 
9980  template <bool top_level>
9981  struct push_popper_n {
9982  lua_State* L;
9983  int pop_count;
9984  push_popper_n(lua_State* L_, int pop_count_) : L(L_), pop_count(pop_count_) {
9985  }
9986  push_popper_n(const push_popper_n&) = delete;
9987  push_popper_n(push_popper_n&&) = default;
9988  push_popper_n& operator=(const push_popper_n&) = delete;
9989  push_popper_n& operator=(push_popper_n&&) = default;
9990  ~push_popper_n() {
9991  lua_pop(L, pop_count);
9992  }
9993  };
9994 
9995  template <>
9996  struct push_popper_n<true> {
9997  push_popper_n(lua_State*, int) {
9998  }
9999  };
10000 
10001  template <bool, typename T, typename = void>
10002  struct push_popper {
10003  using Tu = meta::unqualified_t<T>;
10004  T m_object;
10005  int m_index;
10006 
10007  push_popper(T object_) noexcept : m_object(object_), m_index(lua_absindex(m_object.lua_state(), -m_object.push())) {
10008  }
10009 
10010  int index_of(const Tu&) const noexcept {
10011  return m_index;
10012  }
10013 
10014  ~push_popper() {
10015  m_object.pop();
10016  }
10017  };
10018 
10019  template <typename T, typename C>
10020  struct push_popper<true, T, C> {
10021  using Tu = meta::unqualified_t<T>;
10022 
10023  push_popper(T) noexcept {
10024  }
10025 
10026  int index_of(const Tu&) const noexcept {
10027  return -1;
10028  }
10029 
10030  ~push_popper() {
10031  }
10032  };
10033 
10034  template <typename T>
10035  struct push_popper<false, T, std::enable_if_t<is_stack_based_v<meta::unqualified_t<T>>>> {
10036  using Tu = meta::unqualified_t<T>;
10037 
10038  push_popper(T) noexcept {
10039  }
10040 
10041  int index_of(const Tu& object_) const noexcept {
10042  return object_.stack_index();
10043  }
10044 
10045  ~push_popper() {
10046  }
10047  };
10048 
10049  template <bool, typename T, typename = void>
10051  using Tu = meta::unqualified_t<T>;
10052  lua_State* m_L;
10053  T m_object;
10054  int m_index;
10055 
10056  stateless_push_popper(lua_State* L_, T object_) noexcept : m_L(L_), m_object(object_), m_index(lua_absindex(m_L, -m_object.push(m_L))) {
10057  }
10058 
10059  int index_of(const Tu&) const noexcept {
10060  return m_index;
10061  }
10062 
10064  m_object.pop(m_L);
10065  }
10066  };
10067 
10068  template <typename T, typename C>
10069  struct stateless_push_popper<true, T, C> {
10070  using Tu = meta::unqualified_t<T>;
10071 
10072  stateless_push_popper(lua_State*, T) noexcept {
10073  }
10074 
10075  int index_of(lua_State*, const Tu&) const noexcept {
10076  return -1;
10077  }
10078 
10080  }
10081  };
10082 
10083  template <typename T>
10084  struct stateless_push_popper<false, T, std::enable_if_t<is_stack_based_v<meta::unqualified_t<T>>>> {
10085  using Tu = meta::unqualified_t<T>;
10086  lua_State* m_L;
10087 
10088  stateless_push_popper(lua_State* L_, T) noexcept : m_L(L_) {
10089  }
10090 
10091  int index_of(const Tu& object_) const noexcept {
10092  return object_.stack_index();
10093  }
10094 
10096  }
10097  };
10098 
10099  template <bool top_level = false, typename T>
10100  push_popper<top_level, T> push_pop(T&& x) {
10101  return push_popper<top_level, T>(std::forward<T>(x));
10102  }
10103 
10104  template <bool top_level = false, typename T>
10105  stateless_push_popper<top_level, T> push_pop(lua_State* L_, T&& object_) {
10106  return stateless_push_popper<top_level, T>(L_, std::forward<T>(object_));
10107  }
10108 
10109  template <typename T>
10110  push_popper_at push_pop_at(T&& object_) {
10111  int push_count = object_.push();
10112  lua_State* L = object_.lua_state();
10113  return push_popper_at(L, lua_absindex(L, -push_count), push_count);
10114  }
10115 
10116  template <bool top_level = false>
10117  push_popper_n<top_level> pop_n(lua_State* L_, int pop_count_) {
10118  return push_popper_n<top_level>(L_, pop_count_);
10119  }
10120  } // namespace stack
10121 
10122  inline lua_State* main_thread(lua_State* L_, lua_State* backup_if_unsupported_ = nullptr) {
10123 #if SOL_LUA_VERSION_I_ < 502
10124  if (L_ == nullptr)
10125  return backup_if_unsupported_;
10126  lua_getglobal(L_, detail::default_main_thread_name());
10127  auto pp = stack::pop_n(L_, 1);
10128  if (type_of(L_, -1) == type::thread) {
10129  return lua_tothread(L_, -1);
10130  }
10131  return backup_if_unsupported_;
10132 #else
10133  if (L_ == nullptr)
10134  return backup_if_unsupported_;
10135  lua_rawgeti(L_, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD);
10136  lua_State* Lmain = lua_tothread(L_, -1);
10137  lua_pop(L_, 1);
10138  return Lmain;
10139 #endif // Lua 5.2+ has the main thread unqualified_getter
10140  }
10141 
10142  namespace detail {
10143  struct no_safety_tag {
10144  } inline constexpr no_safety {};
10145 
10146  template <bool b>
10147  inline lua_State* pick_main_thread(lua_State* L_, lua_State* backup_if_unsupported = nullptr) {
10148  (void)L_;
10149  (void)backup_if_unsupported;
10150  if (b) {
10151  return main_thread(L_, backup_if_unsupported);
10152  }
10153  return L_;
10154  }
10155  } // namespace detail
10156 
10158  private:
10159  template <bool o_main_only>
10160  friend class basic_reference;
10161 
10162  int ref = LUA_NOREF;
10163 
10164  int copy_ref(lua_State* L_) const noexcept {
10165  if (ref == LUA_NOREF)
10166  return LUA_NOREF;
10167  push(L_);
10168  return luaL_ref(L_, LUA_REGISTRYINDEX);
10169  }
10170 
10171  lua_State* copy_assign_ref(lua_State* L_, lua_State* rL, const stateless_reference& r) {
10172  if (valid(L_)) {
10173  deref(L_);
10174  }
10175  ref = r.copy_ref(L_);
10176  return rL;
10177  }
10178 
10179  lua_State* move_assign(lua_State* L_, lua_State* rL, stateless_reference&& r) {
10180  if (valid(L_)) {
10181  deref(L_);
10182  }
10183  ref = r.ref;
10184  r.ref = LUA_NOREF;
10185  return rL;
10186  }
10187 
10188  protected:
10189  int stack_index() const noexcept {
10190  return -1;
10191  }
10192 
10193  stateless_reference(lua_State* L_, global_tag_t) noexcept {
10194 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
10195  luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
10196 #endif // make sure stack doesn't overflow
10197  lua_pushglobaltable(L_);
10198  ref = luaL_ref(L_, LUA_REGISTRYINDEX);
10199  }
10200 
10201  stateless_reference(int raw_ref_index) noexcept : ref(raw_ref_index) {
10202  }
10203 
10204  public:
10205  stateless_reference() noexcept = default;
10207  }
10208  stateless_reference(const stack_reference& r) noexcept : stateless_reference(r.lua_state(), r.stack_index()) {
10209  }
10210  stateless_reference(stack_reference&& r) noexcept : stateless_reference(r.lua_state(), r.stack_index()) {
10211  }
10212  stateless_reference(lua_State* L_, const stateless_reference& r) noexcept {
10213  if (r.ref == LUA_REFNIL) {
10214  ref = LUA_REFNIL;
10215  return;
10216  }
10217  if (r.ref == LUA_NOREF || L_ == nullptr) {
10218  ref = LUA_NOREF;
10219  return;
10220  }
10221  ref = r.copy_ref(L_);
10222  }
10223 
10225  if (r.ref == LUA_REFNIL) {
10226  ref = LUA_REFNIL;
10227  return;
10228  }
10229  if (r.ref == LUA_NOREF || L_ == nullptr) {
10230  ref = LUA_NOREF;
10231  return;
10232  }
10233  ref = r.ref;
10234  r.ref = LUA_NOREF;
10235  }
10236 
10237  stateless_reference(lua_State* L_, const stack_reference& r) noexcept {
10238  if (L_ == nullptr || r.lua_state() == nullptr || r.get_type() == type::none) {
10239  ref = LUA_NOREF;
10240  return;
10241  }
10242  if (r.get_type() == type::lua_nil) {
10243  ref = LUA_REFNIL;
10244  return;
10245  }
10246  if (L_ != r.lua_state() && !detail::xmovable(L_, r.lua_state())) {
10247  return;
10248  }
10249  r.push(L_);
10250  ref = luaL_ref(L_, LUA_REGISTRYINDEX);
10251  }
10252 
10253  stateless_reference(lua_State* L_, const stateless_stack_reference& r) noexcept : stateless_reference(L_, r.stack_index()) {
10254  }
10255 
10256  stateless_reference(lua_State* L_, int index = -1) noexcept {
10257 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
10258  luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
10259 #endif // make sure stack doesn't overflow
10260  lua_pushvalue(L_, index);
10261  ref = luaL_ref(L_, LUA_REGISTRYINDEX);
10262  }
10263  stateless_reference(lua_State* L_, absolute_index index_) noexcept : stateless_reference(L_, index_.index) {
10264  }
10265  stateless_reference(lua_State* L_, ref_index index_) noexcept {
10266  lua_rawgeti(L_, LUA_REGISTRYINDEX, index_.index);
10267  ref = luaL_ref(L_, LUA_REGISTRYINDEX);
10268  }
10270  }
10271 
10272  ~stateless_reference() noexcept = default;
10273 
10274  stateless_reference(const stateless_reference& o) noexcept = delete;
10275  stateless_reference& operator=(const stateless_reference& r) noexcept = delete;
10276 
10277  stateless_reference(stateless_reference&& o) noexcept : ref(o.ref) {
10278  o.ref = LUA_NOREF;
10279  }
10280 
10281  stateless_reference& operator=(stateless_reference&& o) noexcept {
10282  ref = o.ref;
10283  o.ref = LUA_NOREF;
10284  return *this;
10285  }
10286 
10287  int push(lua_State* L_) const noexcept {
10288 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
10289  luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
10290 #endif // make sure stack doesn't overflow
10291  lua_rawgeti(L_, LUA_REGISTRYINDEX, ref);
10292  return 1;
10293  }
10294 
10295  void pop(lua_State* L_, int n = 1) const noexcept {
10296  lua_pop(L_, n);
10297  }
10298 
10299  int registry_index() const noexcept {
10300  return ref;
10301  }
10302 
10303  void reset(lua_State* L_) noexcept {
10304  if (valid(L_)) {
10305  deref(L_);
10306  }
10307  ref = LUA_NOREF;
10308  }
10309 
10310  void reset(lua_State* L_, int index_) noexcept {
10311  reset(L_);
10312 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
10313  luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
10314 #endif // make sure stack doesn't overflow
10315  lua_pushvalue(L_, index_);
10316  ref = luaL_ref(L_, LUA_REGISTRYINDEX);
10317  }
10318 
10319  bool valid(lua_State*) const noexcept {
10320  return !(ref == LUA_NOREF || ref == LUA_REFNIL);
10321  }
10322 
10323  const void* pointer(lua_State* L_) const noexcept {
10324  int si = push(L_);
10325  const void* vp = lua_topointer(L_, -si);
10326  lua_pop(L_, si);
10327  return vp;
10328  }
10329 
10330  type get_type(lua_State* L_) const noexcept {
10331  int p = push(L_);
10332  int result = lua_type(L_, -1);
10333  pop(L_, p);
10334  return static_cast<type>(result);
10335  }
10336 
10337  void abandon(lua_State* = nullptr) {
10338  ref = LUA_NOREF;
10339  }
10340 
10341  void deref(lua_State* L_) const noexcept {
10342  luaL_unref(L_, LUA_REGISTRYINDEX, ref);
10343  }
10344 
10345  stateless_reference copy(lua_State* L_) const noexcept {
10346  if (!valid(L_)) {
10347  return {};
10348  }
10349  return stateless_reference(copy_ref(L_));
10350  }
10351 
10352  void copy_assign(lua_State* L_, const stateless_reference& right) noexcept {
10353  if (valid(L_)) {
10354  deref(L_);
10355  }
10356  if (!right.valid(L_)) {
10357  return;
10358  }
10359  ref = right.copy_ref(L_);
10360  }
10361 
10362  bool equals(lua_State* L_, const stateless_reference& r) const noexcept {
10363  auto ppl = stack::push_pop(L_, *this);
10364  auto ppr = stack::push_pop(L_, r);
10365  return lua_compare(L_, -1, -2, LUA_OPEQ) == 1;
10366  }
10367 
10368  bool equals(lua_State* L_, const stateless_stack_reference& r) const noexcept {
10369  auto ppl = stack::push_pop(L_, *this);
10370  return lua_compare(L_, -1, r.stack_index(), LUA_OPEQ) == 1;
10371  }
10372 
10373  bool equals(lua_State* L_, lua_nil_t) const noexcept {
10374  return valid(L_);
10375  }
10376  };
10377 
10378  template <bool main_only = false>
10379  class basic_reference : public stateless_reference {
10380  private:
10381  template <bool o_main_only>
10382  friend class basic_reference;
10383  lua_State* luastate = nullptr; // non-owning
10384 
10385  template <bool r_main_only>
10386  void copy_assign_complex(const basic_reference<r_main_only>& r) {
10387  if (valid()) {
10388  deref();
10389  }
10390  if (r.ref == LUA_REFNIL) {
10391  luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
10392  ref = LUA_REFNIL;
10393  return;
10394  }
10395  if (r.ref == LUA_NOREF) {
10396  luastate = r.luastate;
10397  ref = LUA_NOREF;
10398  return;
10399  }
10400  if (detail::xmovable(lua_state(), r.lua_state())) {
10401  r.push(lua_state());
10402  ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
10403  return;
10404  }
10405  luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
10406  ref = r.copy_ref();
10407  }
10408 
10409  template <bool r_main_only>
10410  void move_assign(basic_reference<r_main_only>&& r) {
10411  if (valid()) {
10412  deref();
10413  }
10414  if (r.ref == LUA_REFNIL) {
10415  luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
10416  ref = LUA_REFNIL;
10417  return;
10418  }
10419  if (r.ref == LUA_NOREF) {
10420  luastate = r.luastate;
10421  ref = LUA_NOREF;
10422  return;
10423  }
10424  if (detail::xmovable(lua_state(), r.lua_state())) {
10425  r.push(lua_state());
10426  ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
10427  return;
10428  }
10429 
10430  luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
10431  ref = r.ref;
10432  r.ref = LUA_NOREF;
10433  r.luastate = nullptr;
10434  }
10435 
10436  protected:
10437  basic_reference(lua_State* L_, global_tag_t) noexcept : basic_reference(detail::pick_main_thread<main_only>(L_, L_), global_tag, global_tag) {
10438  }
10439 
10440  basic_reference(lua_State* L_, global_tag_t, global_tag_t) noexcept : stateless_reference(L_, global_tag), luastate(L_) {
10441  }
10442 
10443  basic_reference(lua_State* oL, const basic_reference<!main_only>& o) noexcept : stateless_reference(oL, o), luastate(oL) {
10444  }
10445 
10446  void deref() const noexcept {
10447  return stateless_reference::deref(lua_state());
10448  }
10449 
10450  int copy_ref() const noexcept {
10451  return copy_ref(lua_state());
10452  }
10453 
10454  int copy_ref(lua_State* L_) const noexcept {
10455  return stateless_reference::copy_ref(L_);
10456  }
10457 
10458  public:
10459  basic_reference() noexcept = default;
10460  basic_reference(lua_nil_t) noexcept : basic_reference() {
10461  }
10462  basic_reference(const stack_reference& r) noexcept : basic_reference(r.lua_state(), r.stack_index()) {
10463  }
10464  basic_reference(stack_reference&& r) noexcept : basic_reference(r.lua_state(), r.stack_index()) {
10465  }
10466  template <bool r_main_only>
10467  basic_reference(lua_State* L_, const basic_reference<r_main_only>& r) noexcept : luastate(detail::pick_main_thread<main_only>(L_, L_)) {
10468  if (r.ref == LUA_REFNIL) {
10469  ref = LUA_REFNIL;
10470  return;
10471  }
10472  if (r.ref == LUA_NOREF || lua_state() == nullptr) {
10473  ref = LUA_NOREF;
10474  return;
10475  }
10476  if (detail::xmovable(lua_state(), r.lua_state())) {
10477  r.push(lua_state());
10478  ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
10479  return;
10480  }
10481  ref = r.copy_ref();
10482  }
10483 
10484  template <bool r_main_only>
10485  basic_reference(lua_State* L_, basic_reference<r_main_only>&& r) noexcept : luastate(detail::pick_main_thread<main_only>(L_, L_)) {
10486  if (r.ref == LUA_REFNIL) {
10487  ref = LUA_REFNIL;
10488  return;
10489  }
10490  if (r.ref == LUA_NOREF || lua_state() == nullptr) {
10491  ref = LUA_NOREF;
10492  return;
10493  }
10494  if (detail::xmovable(lua_state(), r.lua_state())) {
10495  r.push(lua_state());
10496  ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
10497  return;
10498  }
10499  ref = r.ref;
10500  r.ref = LUA_NOREF;
10501  r.luastate = nullptr;
10502  }
10503 
10504  basic_reference(lua_State* L_, const stack_reference& r) noexcept : luastate(detail::pick_main_thread<main_only>(L_, L_)) {
10505  if (lua_state() == nullptr || r.lua_state() == nullptr || r.get_type() == type::none) {
10506  ref = LUA_NOREF;
10507  return;
10508  }
10509  if (r.get_type() == type::lua_nil) {
10510  ref = LUA_REFNIL;
10511  return;
10512  }
10513  if (lua_state() != r.lua_state() && !detail::xmovable(lua_state(), r.lua_state())) {
10514  return;
10515  }
10516  r.push(lua_state());
10517  ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
10518  }
10519  basic_reference(lua_State* L_, int index = -1) noexcept : luastate(detail::pick_main_thread<main_only>(L_, L_)) {
10520  // use L_ to stick with that state's execution stack
10521 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
10522  luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
10523 #endif // make sure stack doesn't overflow
10524  lua_pushvalue(L_, index);
10525  ref = luaL_ref(L_, LUA_REGISTRYINDEX);
10526  }
10527  basic_reference(lua_State* L_, ref_index index) noexcept : luastate(detail::pick_main_thread<main_only>(L_, L_)) {
10528  lua_rawgeti(lua_state(), LUA_REGISTRYINDEX, index.index);
10529  ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
10530  }
10531  basic_reference(lua_State* L_, lua_nil_t) noexcept : luastate(detail::pick_main_thread<main_only>(L_, L_)) {
10532  }
10533 
10534  ~basic_reference() noexcept {
10535  if (lua_state() == nullptr || ref == LUA_NOREF)
10536  return;
10537  deref();
10538  }
10539 
10540  basic_reference(const basic_reference& o) noexcept : stateless_reference(o.copy_ref()), luastate(o.lua_state()) {
10541  }
10542 
10543  basic_reference(basic_reference&& o) noexcept : stateless_reference(std::move(o)), luastate(o.lua_state()) {
10544  o.luastate = nullptr;
10545  }
10546 
10547  basic_reference(const basic_reference<!main_only>& o) noexcept
10548  : basic_reference(detail::pick_main_thread<main_only>(o.lua_state(), o.lua_state()), o) {
10549  }
10550 
10552  : stateless_reference(std::move(o)), luastate(detail::pick_main_thread<main_only>(o.lua_state(), o.lua_state())) {
10553  o.luastate = nullptr;
10554  o.ref = LUA_NOREF;
10555  }
10556 
10557  basic_reference& operator=(basic_reference&& r) noexcept {
10558  move_assign(std::move(r));
10559  return *this;
10560  }
10561 
10562  basic_reference& operator=(const basic_reference& r) noexcept {
10563  copy_assign_complex(r);
10564  return *this;
10565  }
10566 
10567  basic_reference& operator=(basic_reference<!main_only>&& r) noexcept {
10568  move_assign(std::move(r));
10569  return *this;
10570  }
10571 
10572  basic_reference& operator=(const basic_reference<!main_only>& r) noexcept {
10573  copy_assign_complex(r);
10574  return *this;
10575  }
10576 
10577  basic_reference& operator=(const lua_nil_t&) noexcept {
10578  reset();
10579  return *this;
10580  }
10581 
10582  template <typename Super>
10583  basic_reference& operator=(proxy_base<Super>&& r);
10584 
10585  template <typename Super>
10586  basic_reference& operator=(const proxy_base<Super>& r);
10587 
10588  int push() const noexcept {
10589  return push(lua_state());
10590  }
10591 
10592  void reset() noexcept {
10593  stateless_reference::reset(luastate);
10594  luastate = nullptr;
10595  }
10596 
10597  int push(lua_State* L_) const noexcept {
10598 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
10599  luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
10600 #endif // make sure stack doesn't overflow
10601  if (lua_state() == nullptr) {
10602  lua_pushnil(L_);
10603  return 1;
10604  }
10605  lua_rawgeti(lua_state(), LUA_REGISTRYINDEX, ref);
10606  if (L_ != lua_state()) {
10607  lua_xmove(lua_state(), L_, 1);
10608  }
10609  return 1;
10610  }
10611 
10612  void pop() const noexcept {
10613  pop(lua_state());
10614  }
10615 
10616  void pop(lua_State* L_, int n = 1) const noexcept {
10617  stateless_reference::pop(L_, n);
10618  }
10619 
10620  int registry_index() const noexcept {
10621  return stateless_reference::registry_index();
10622  }
10623 
10624  bool valid() const noexcept {
10625  return stateless_reference::valid(lua_state());
10626  }
10627 
10628  bool valid(lua_State* L_) const noexcept {
10629  return stateless_reference::valid(L_);
10630  }
10631 
10632  const void* pointer() const noexcept {
10633  return stateless_reference::pointer(lua_state());
10634  }
10635 
10636  explicit operator bool() const noexcept {
10637  return valid();
10638  }
10639 
10640  type get_type() const noexcept {
10641  return stateless_reference::get_type(lua_state());
10642  }
10643 
10644  lua_State* lua_state() const noexcept {
10645  return luastate;
10646  }
10647  };
10648 
10649  template <bool lb, bool rb>
10650  inline bool operator==(const basic_reference<lb>& l, const basic_reference<rb>& r) noexcept {
10651  auto ppl = stack::push_pop(l);
10652  auto ppr = stack::push_pop(r);
10653  return lua_compare(l.lua_state(), -1, -2, LUA_OPEQ) == 1;
10654  }
10655 
10656  template <bool lb, bool rb>
10657  inline bool operator!=(const basic_reference<lb>& l, const basic_reference<rb>& r) noexcept {
10658  return !operator==(l, r);
10659  }
10660 
10661  template <bool lb>
10662  inline bool operator==(const basic_reference<lb>& l, const stack_reference& r) noexcept {
10663  auto ppl = stack::push_pop(l);
10664  return lua_compare(l.lua_state(), -1, r.stack_index(), LUA_OPEQ) == 1;
10665  }
10666 
10667  template <bool lb>
10668  inline bool operator!=(const basic_reference<lb>& l, const stack_reference& r) noexcept {
10669  return !operator==(l, r);
10670  }
10671 
10672  template <bool rb>
10673  inline bool operator==(const stack_reference& l, const basic_reference<rb>& r) noexcept {
10674  auto ppr = stack::push_pop(r);
10675  return lua_compare(l.lua_state(), -1, r.stack_index(), LUA_OPEQ) == 1;
10676  }
10677 
10678  template <bool rb>
10679  inline bool operator!=(const stack_reference& l, const basic_reference<rb>& r) noexcept {
10680  return !operator==(l, r);
10681  }
10682 
10683  template <bool lb>
10684  inline bool operator==(const basic_reference<lb>& lhs, const lua_nil_t&) noexcept {
10685  return !lhs.valid();
10686  }
10687 
10688  template <bool rb>
10689  inline bool operator==(const lua_nil_t&, const basic_reference<rb>& rhs) noexcept {
10690  return !rhs.valid();
10691  }
10692 
10693  template <bool lb>
10694  inline bool operator!=(const basic_reference<lb>& lhs, const lua_nil_t&) noexcept {
10695  return lhs.valid();
10696  }
10697 
10698  template <bool rb>
10699  inline bool operator!=(const lua_nil_t&, const basic_reference<rb>& rhs) noexcept {
10700  return rhs.valid();
10701  }
10702 
10703  inline bool operator==(const stateless_reference& l, const stateless_reference& r) noexcept {
10704  return l.registry_index() == r.registry_index();
10705  }
10706 
10707  inline bool operator!=(const stateless_reference& l, const stateless_reference& r) noexcept {
10708  return l.registry_index() != r.registry_index();
10709  }
10710 
10711  inline bool operator==(const stateless_reference& lhs, const lua_nil_t&) noexcept {
10712  return lhs.registry_index() == LUA_REFNIL;
10713  }
10714 
10715  inline bool operator==(const lua_nil_t&, const stateless_reference& rhs) noexcept {
10716  return rhs.registry_index() == LUA_REFNIL;
10717  }
10718 
10719  inline bool operator!=(const stateless_reference& lhs, const lua_nil_t&) noexcept {
10720  return lhs.registry_index() != LUA_REFNIL;
10721  }
10722 
10723  inline bool operator!=(const lua_nil_t&, const stateless_reference& rhs) noexcept {
10724  return rhs.registry_index() != LUA_REFNIL;
10725  }
10726 
10728  using is_transparent = std::true_type;
10729 
10731  }
10732 
10733  bool operator()(const lua_nil_t& lhs, const stateless_reference& rhs) const noexcept {
10734  return rhs.equals(lua_state(), lhs);
10735  }
10736 
10737  bool operator()(const stateless_reference& lhs, const lua_nil_t& rhs) const noexcept {
10738  return lhs.equals(lua_state(), rhs);
10739  }
10740 
10741  bool operator()(const stateless_reference& lhs, const stateless_reference& rhs) const noexcept {
10742  return lhs.equals(lua_state(), rhs);
10743  }
10744  };
10745 
10747  using is_transparent = std::true_type;
10748 
10749  template <bool rb>
10750  bool operator()(const lua_nil_t& lhs, const basic_reference<rb>& rhs) const noexcept {
10751  return lhs == rhs;
10752  }
10753 
10754  template <bool lb>
10755  bool operator()(const basic_reference<lb>& lhs, const lua_nil_t& rhs) const noexcept {
10756  return lhs == rhs;
10757  }
10758 
10759  template <bool lb, bool rb>
10760  bool operator()(const basic_reference<lb>& lhs, const basic_reference<rb>& rhs) const noexcept {
10761  return lhs == rhs;
10762  }
10763 
10764  template <bool lb>
10765  bool operator()(const basic_reference<lb>& lhs, const stack_reference& rhs) const noexcept {
10766  return lhs == rhs;
10767  }
10768 
10769  template <bool rb>
10770  bool operator()(const stack_reference& lhs, const basic_reference<rb>& rhs) const noexcept {
10771  return lhs == rhs;
10772  }
10773  };
10774 
10777  using result_type = std::size_t;
10778  using is_transparent = std::true_type;
10779 
10781  }
10782 
10783  result_type operator()(const stateless_reference& lhs) const noexcept {
10784  std::hash<const void*> h;
10785  return h(lhs.pointer(lua_state()));
10786  }
10787  };
10788 
10790  using argument_type = reference;
10791  using result_type = std::size_t;
10792  using is_transparent = std::true_type;
10793 
10794  template <bool lb>
10795  result_type operator()(const basic_reference<lb>& lhs) const noexcept {
10796  std::hash<const void*> h;
10797  return h(lhs.pointer());
10798  }
10799  };
10800 } // namespace sol
10801 
10802 // end of sol/reference.hpp
10803 
10804 // beginning of sol/tie.hpp
10805 
10806 namespace sol {
10807 
10808  namespace detail {
10809  template <typename T>
10810  struct is_speshul : std::false_type { };
10811  } // namespace detail
10812 
10813  template <typename T>
10814  struct tie_size : std::tuple_size<T> { };
10815 
10816  template <typename T>
10817  struct is_tieable : std::integral_constant<bool, (::sol::tie_size<T>::value > 0)> { };
10818 
10819  template <typename... Tn>
10820  struct tie_t : public std::tuple<std::add_lvalue_reference_t<Tn>...> {
10821  private:
10822  typedef std::tuple<std::add_lvalue_reference_t<Tn>...> base_t;
10823 
10824  template <typename T>
10825  void set(std::false_type, T&& target) {
10826  std::get<0>(*this) = std::forward<T>(target);
10827  }
10828 
10829  template <typename T>
10830  void set(std::true_type, T&& target) {
10831  typedef tie_size<meta::unqualified_t<T>> value_size;
10832  typedef tie_size<std::tuple<Tn...>> tie_size;
10833  typedef meta::conditional_t<(value_size::value < tie_size::value), value_size, tie_size> indices_size;
10834  typedef std::make_index_sequence<indices_size::value> indices;
10835  set_extra(detail::is_speshul<meta::unqualified_t<T>>(), indices(), std::forward<T>(target));
10836  }
10837 
10838  template <std::size_t... I, typename T>
10839  void set_extra(std::true_type, std::index_sequence<I...>, T&& target) {
10840  using std::get;
10841  (void)detail::swallow { 0, (get<I>(static_cast<base_t&>(*this)) = get<I>(types<Tn...>(), target), 0)..., 0 };
10842  }
10843 
10844  template <std::size_t... I, typename T>
10845  void set_extra(std::false_type, std::index_sequence<I...>, T&& target) {
10846  using std::get;
10847  (void)detail::swallow { 0, (get<I>(static_cast<base_t&>(*this)) = get<I>(target), 0)..., 0 };
10848  }
10849 
10850  public:
10851  using base_t::base_t;
10852 
10853  template <typename T>
10854  tie_t& operator=(T&& value) {
10855  typedef is_tieable<meta::unqualified_t<T>> tieable;
10856  set(tieable(), std::forward<T>(value));
10857  return *this;
10858  }
10859  };
10860 
10861  template <typename... Tn>
10862  struct tie_size<tie_t<Tn...>> : std::tuple_size<std::tuple<Tn...>> { };
10863 
10864  namespace adl_barrier_detail {
10865  template <typename... Tn>
10866  inline tie_t<std::remove_reference_t<Tn>...> tie(Tn&&... argn) {
10867  return tie_t<std::remove_reference_t<Tn>...>(std::forward<Tn>(argn)...);
10868  }
10869  } // namespace adl_barrier_detail
10870 
10871  using namespace adl_barrier_detail;
10872 
10873 } // namespace sol
10874 
10875 // end of sol/tie.hpp
10876 
10877 // beginning of sol/stack_guard.hpp
10878 
10879 #include <functional>
10880 
10881 namespace sol {
10882  namespace detail {
10883  inline void stack_fail(int, int) {
10884 #if SOL_IS_ON(SOL_EXCEPTIONS)
10885  throw error(detail::direct_error, "imbalanced stack after operation finish");
10886 #else
10887  // Lol, what do you want, an error printout? :3c
10888  // There's no sane default here. The right way would be C-style abort(), and that's not acceptable, so
10889  // hopefully someone will register their own stack_fail thing for the `fx` parameter of stack_guard.
10890 #endif // No Exceptions
10891  }
10892  } // namespace detail
10893 
10894  struct stack_guard {
10895  lua_State* L;
10896  int top;
10897  std::function<void(int, int)> on_mismatch;
10898 
10899  stack_guard(lua_State* L) : stack_guard(L, lua_gettop(L)) {
10900  }
10901  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)) {
10902  }
10903  bool check_stack(int modification = 0) const {
10904  int bottom = lua_gettop(L) + modification;
10905  if (top == bottom) {
10906  return true;
10907  }
10908  on_mismatch(top, bottom);
10909  return false;
10910  }
10911  ~stack_guard() {
10912  check_stack();
10913  }
10914  };
10915 } // namespace sol
10916 
10917 // end of sol/stack_guard.hpp
10918 
10919 #include <vector>
10920 #include <bitset>
10921 #include <forward_list>
10922 #include <string>
10923 #include <limits>
10924 #include <algorithm>
10925 #include <sstream>
10926 #include <optional>
10927 #include <type_traits>
10928 
10929 namespace sol {
10930  namespace detail {
10931  struct with_function_tag { };
10932  struct as_reference_tag { };
10933  template <typename T>
10934  struct as_pointer_tag { };
10935  template <typename T>
10936  struct as_value_tag { };
10937  template <typename T>
10938  struct as_unique_tag { };
10939  template <typename T>
10940  struct as_table_tag { };
10941 
10942  template <typename Tag>
10943  inline constexpr bool is_tagged_v
10944  = meta::is_specialization_of_v<Tag,
10945  detail::
10946  as_pointer_tag> || meta::is_specialization_of_v<Tag, as_value_tag> || meta::is_specialization_of_v<Tag, as_unique_tag> || meta::is_specialization_of_v<Tag, as_table_tag> || std::is_same_v<Tag, as_reference_tag> || std::is_same_v<Tag, with_function_tag>;
10947 
10948  using lua_reg_table = luaL_Reg[64];
10949 
10950  using unique_destructor = void (*)(void*);
10951  using unique_tag = detail::inheritance_unique_cast_function;
10952 
10953  inline void* alloc_newuserdata(lua_State* L, std::size_t bytesize) {
10954 #if SOL_LUA_VERSION_I_ >= 504
10955  return lua_newuserdatauv(L, bytesize, 1);
10956 #else
10957  return lua_newuserdata(L, bytesize);
10958 #endif
10959  }
10960 
10961  constexpr std::uintptr_t align(std::size_t alignment, std::uintptr_t ptr, std::size_t& space) {
10962  // this handles arbitrary alignments...
10963  // make this into a power-of-2-only?
10964  // actually can't: this is a C++14-compatible framework,
10965  // power of 2 alignment is C++17
10966  std::uintptr_t offby = static_cast<std::uintptr_t>(ptr % alignment);
10967  std::uintptr_t padding = (alignment - offby) % alignment;
10968  ptr += padding;
10969  space -= padding;
10970  return ptr;
10971  }
10972 
10973  inline void* align(std::size_t alignment, void* ptr, std::size_t& space) {
10974  return reinterpret_cast<void*>(align(alignment, reinterpret_cast<std::uintptr_t>(ptr), space));
10975  }
10976 
10977  constexpr std::uintptr_t align_one(std::size_t alignment, std::size_t size, std::uintptr_t ptr) {
10978  std::size_t space = (std::numeric_limits<std::size_t>::max)();
10979  return align(alignment, ptr, space) + size;
10980  }
10981 
10982  template <typename... Args>
10983  constexpr std::size_t aligned_space_for(std::uintptr_t ptr) {
10984  std::uintptr_t end = ptr;
10985  ((end = align_one(alignof(Args), sizeof(Args), end)), ...);
10986  return static_cast<std::size_t>(end - ptr);
10987  }
10988 
10989  template <typename... Args>
10990  constexpr std::size_t aligned_space_for() {
10991  static_assert(sizeof...(Args) > 0);
10992 
10993  constexpr std::size_t max_arg_alignment = (std::max)({ alignof(Args)... });
10994  if constexpr (max_arg_alignment <= alignof(std::max_align_t)) {
10995  // If all types are `good enough`, simply calculate alignment in case of the worst allocator
10996  std::size_t worst_required_size = 0;
10997  for (std::size_t ptr = 0; ptr < max_arg_alignment; ptr++) {
10998  worst_required_size = (std::max)(worst_required_size, aligned_space_for<Args...>(ptr));
10999  }
11000  return worst_required_size;
11001  }
11002  else {
11003  // For over-aligned types let's assume that every Arg in Args starts at the worst aligned address
11004  return (aligned_space_for<Args>(0x1) + ...);
11005  }
11006  }
11007 
11008  inline void* align_usertype_pointer(void* ptr) {
11009  using use_align = std::integral_constant<bool,
11010 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11011  false
11012 #else
11013  (std::alignment_of<void*>::value > 1)
11014 #endif
11015  >;
11016  if (!use_align::value) {
11017  return ptr;
11018  }
11019  std::size_t space = (std::numeric_limits<std::size_t>::max)();
11020  return align(std::alignment_of<void*>::value, ptr, space);
11021  }
11022 
11023  template <bool pre_aligned = false, bool pre_shifted = false>
11024  void* align_usertype_unique_destructor(void* ptr) {
11025  using use_align = std::integral_constant<bool,
11026 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11027  false
11028 #else
11029  (std::alignment_of<unique_destructor>::value > 1)
11030 #endif
11031  >;
11032  if (!pre_aligned) {
11033  ptr = align_usertype_pointer(ptr);
11034  }
11035  if (!pre_shifted) {
11036  ptr = static_cast<void*>(static_cast<char*>(ptr) + sizeof(void*));
11037  }
11038  if (!use_align::value) {
11039  return static_cast<void*>(static_cast<void**>(ptr) + 1);
11040  }
11041  std::size_t space = (std::numeric_limits<std::size_t>::max)();
11042  return align(std::alignment_of<unique_destructor>::value, ptr, space);
11043  }
11044 
11045  template <bool pre_aligned = false, bool pre_shifted = false>
11046  void* align_usertype_unique_tag(void* ptr) {
11047  using use_align = std::integral_constant<bool,
11048 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11049  false
11050 #else
11051  (std::alignment_of<unique_tag>::value > 1)
11052 #endif
11053  >;
11054  if (!pre_aligned) {
11055  ptr = align_usertype_unique_destructor(ptr);
11056  }
11057  if (!pre_shifted) {
11058  ptr = static_cast<void*>(static_cast<char*>(ptr) + sizeof(unique_destructor));
11059  }
11060  if (!use_align::value) {
11061  return ptr;
11062  }
11063  std::size_t space = (std::numeric_limits<std::size_t>::max)();
11064  return align(std::alignment_of<unique_tag>::value, ptr, space);
11065  }
11066 
11067  template <typename T, bool pre_aligned = false, bool pre_shifted = false>
11068  void* align_usertype_unique(void* ptr) {
11069  typedef std::integral_constant<bool,
11070 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11071  false
11072 #else
11073  (std::alignment_of_v<T> > 1)
11074 #endif
11075  >
11076  use_align;
11077  if (!pre_aligned) {
11078  ptr = align_usertype_unique_tag(ptr);
11079  }
11080  if (!pre_shifted) {
11081  ptr = static_cast<void*>(static_cast<char*>(ptr) + sizeof(unique_tag));
11082  }
11083  if (!use_align::value) {
11084  return ptr;
11085  }
11086  std::size_t space = (std::numeric_limits<std::size_t>::max)();
11087  return align(std::alignment_of_v<T>, ptr, space);
11088  }
11089 
11090  template <typename T>
11091  void* align_user(void* ptr) {
11092  typedef std::integral_constant<bool,
11093 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11094  false
11095 #else
11096  (std::alignment_of_v<T> > 1)
11097 #endif
11098  >
11099  use_align;
11100  if (!use_align::value) {
11101  return ptr;
11102  }
11103  std::size_t space = (std::numeric_limits<std::size_t>::max)();
11104  return align(std::alignment_of_v<T>, ptr, space);
11105  }
11106 
11107  template <typename T>
11108  T** usertype_allocate_pointer(lua_State* L) {
11109  typedef std::integral_constant<bool,
11110 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11111  false
11112 #else
11113  (std::alignment_of<T*>::value > 1)
11114 #endif
11115  >
11116  use_align;
11117  if (!use_align::value) {
11118  T** pointerpointer = static_cast<T**>(alloc_newuserdata(L, sizeof(T*)));
11119  return pointerpointer;
11120  }
11121  constexpr std::size_t initial_size = aligned_space_for<T*>();
11122 
11123  std::size_t allocated_size = initial_size;
11124  void* unadjusted = alloc_newuserdata(L, initial_size);
11125  void* adjusted = align(std::alignment_of<T*>::value, unadjusted, allocated_size);
11126  if (adjusted == nullptr) {
11127  // trash allocator can burn in hell
11128  lua_pop(L, 1);
11129  // luaL_error(L, "if you are the one that wrote this allocator you should feel bad for doing a
11130  // worse job than malloc/realloc and should go read some books, yeah?");
11131  luaL_error(L, "cannot properly align memory for '%s'", detail::demangle<T*>().data());
11132  }
11133  return static_cast<T**>(adjusted);
11134  }
11135 
11136  inline bool attempt_alloc(lua_State* L, std::size_t ptr_align, std::size_t ptr_size, std::size_t value_align,
11137  std::size_t allocated_size, void*& pointer_adjusted, void*& data_adjusted) {
11138  void* adjusted = alloc_newuserdata(L, allocated_size);
11139  pointer_adjusted = align(ptr_align, adjusted, allocated_size);
11140  if (pointer_adjusted == nullptr) {
11141  lua_pop(L, 1);
11142  return false;
11143  }
11144  // subtract size of what we're going to allocate there
11145  allocated_size -= ptr_size;
11146  adjusted = static_cast<void*>(static_cast<char*>(pointer_adjusted) + ptr_size);
11147  data_adjusted = align(value_align, adjusted, allocated_size);
11148  if (data_adjusted == nullptr) {
11149  lua_pop(L, 1);
11150  return false;
11151  }
11152  return true;
11153  }
11154 
11155  inline bool attempt_alloc_unique(lua_State* L, std::size_t ptr_align, std::size_t ptr_size, std::size_t real_align,
11156  std::size_t allocated_size, void*& pointer_adjusted, void*& dx_adjusted, void*& id_adjusted, void*& data_adjusted) {
11157  void* adjusted = alloc_newuserdata(L, allocated_size);
11158  pointer_adjusted = align(ptr_align, adjusted, allocated_size);
11159  if (pointer_adjusted == nullptr) {
11160  lua_pop(L, 1);
11161  return false;
11162  }
11163  allocated_size -= ptr_size;
11164 
11165  adjusted = static_cast<void*>(static_cast<char*>(pointer_adjusted) + ptr_size);
11166  dx_adjusted = align(std::alignment_of_v<unique_destructor>, adjusted, allocated_size);
11167  if (dx_adjusted == nullptr) {
11168  lua_pop(L, 1);
11169  return false;
11170  }
11171  allocated_size -= sizeof(unique_destructor);
11172 
11173  adjusted = static_cast<void*>(static_cast<char*>(dx_adjusted) + sizeof(unique_destructor));
11174 
11175  id_adjusted = align(std::alignment_of_v<unique_tag>, adjusted, allocated_size);
11176  if (id_adjusted == nullptr) {
11177  lua_pop(L, 1);
11178  return false;
11179  }
11180  allocated_size -= sizeof(unique_tag);
11181 
11182  adjusted = static_cast<void*>(static_cast<char*>(id_adjusted) + sizeof(unique_tag));
11183  data_adjusted = align(real_align, adjusted, allocated_size);
11184  if (data_adjusted == nullptr) {
11185  lua_pop(L, 1);
11186  return false;
11187  }
11188  return true;
11189  }
11190 
11191  template <typename T>
11192  T* usertype_allocate(lua_State* L) {
11193  typedef std::integral_constant<bool,
11194 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11195  false
11196 #else
11197  (std::alignment_of<T*>::value > 1 || std::alignment_of_v<T> > 1)
11198 #endif
11199  >
11200  use_align;
11201  if (!use_align::value) {
11202  T** pointerpointer = static_cast<T**>(alloc_newuserdata(L, sizeof(T*) + sizeof(T)));
11203  T*& pointerreference = *pointerpointer;
11204  T* allocationtarget = reinterpret_cast<T*>(pointerpointer + 1);
11205  pointerreference = allocationtarget;
11206  return allocationtarget;
11207  }
11208 
11209  constexpr std::size_t initial_size = aligned_space_for<T*, T>();
11210 
11211  void* pointer_adjusted;
11212  void* data_adjusted;
11213  bool result
11214  = attempt_alloc(L, std::alignment_of_v<T*>, sizeof(T*), std::alignment_of_v<T>, initial_size, pointer_adjusted, data_adjusted);
11215  if (!result) {
11216  if (pointer_adjusted == nullptr) {
11217  luaL_error(L, "aligned allocation of userdata block (pointer section) for '%s' failed", detail::demangle<T>().c_str());
11218  }
11219  else {
11220  luaL_error(L, "aligned allocation of userdata block (data section) for '%s' failed", detail::demangle<T>().c_str());
11221  }
11222  return nullptr;
11223  }
11224 
11225  T** pointerpointer = reinterpret_cast<T**>(pointer_adjusted);
11226  T*& pointerreference = *pointerpointer;
11227  T* allocationtarget = reinterpret_cast<T*>(data_adjusted);
11228  pointerreference = allocationtarget;
11229  return allocationtarget;
11230  }
11231 
11232  template <typename T, typename Real>
11233  Real* usertype_unique_allocate(lua_State* L, T**& pref, unique_destructor*& dx, unique_tag*& id) {
11234  typedef std::integral_constant<bool,
11235 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11236  false
11237 #else
11238  (std::alignment_of<T*>::value > 1 || std::alignment_of<unique_tag>::value > 1 || std::alignment_of<unique_destructor>::value > 1
11239  || std::alignment_of<Real>::value > 1)
11240 #endif
11241  >
11242  use_align;
11243  if (!use_align::value) {
11244  pref = static_cast<T**>(alloc_newuserdata(L, sizeof(T*) + sizeof(detail::unique_destructor) + sizeof(unique_tag) + sizeof(Real)));
11245  dx = static_cast<detail::unique_destructor*>(static_cast<void*>(pref + 1));
11246  id = static_cast<unique_tag*>(static_cast<void*>(dx + 1));
11247  Real* mem = static_cast<Real*>(static_cast<void*>(id + 1));
11248  return mem;
11249  }
11250 
11251  constexpr std::size_t initial_size = aligned_space_for<T*, unique_destructor, unique_tag, Real>();
11252 
11253  void* pointer_adjusted;
11254  void* dx_adjusted;
11255  void* id_adjusted;
11256  void* data_adjusted;
11257  bool result = attempt_alloc_unique(L,
11258  std::alignment_of_v<T*>,
11259  sizeof(T*),
11260  std::alignment_of_v<Real>,
11261  initial_size,
11262  pointer_adjusted,
11263  dx_adjusted,
11264  id_adjusted,
11265  data_adjusted);
11266  if (!result) {
11267  if (pointer_adjusted == nullptr) {
11268  luaL_error(L, "aligned allocation of userdata block (pointer section) for '%s' failed", detail::demangle<T>().c_str());
11269  }
11270  else if (dx_adjusted == nullptr) {
11271  luaL_error(L, "aligned allocation of userdata block (deleter section) for '%s' failed", detail::demangle<T>().c_str());
11272  }
11273  else {
11274  luaL_error(L, "aligned allocation of userdata block (data section) for '%s' failed", detail::demangle<T>().c_str());
11275  }
11276  return nullptr;
11277  }
11278 
11279  pref = static_cast<T**>(pointer_adjusted);
11280  dx = static_cast<detail::unique_destructor*>(dx_adjusted);
11281  id = static_cast<unique_tag*>(id_adjusted);
11282  Real* mem = static_cast<Real*>(data_adjusted);
11283  return mem;
11284  }
11285 
11286  template <typename T>
11287  T* user_allocate(lua_State* L) {
11288  typedef std::integral_constant<bool,
11289 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11290  false
11291 #else
11292  (std::alignment_of_v<T> > 1)
11293 #endif
11294  >
11295  use_align;
11296  if (!use_align::value) {
11297  T* pointer = static_cast<T*>(alloc_newuserdata(L, sizeof(T)));
11298  return pointer;
11299  }
11300 
11301  constexpr std::size_t initial_size = aligned_space_for<T>();
11302 
11303  std::size_t allocated_size = initial_size;
11304  void* unadjusted = alloc_newuserdata(L, allocated_size);
11305  void* adjusted = align(std::alignment_of_v<T>, unadjusted, allocated_size);
11306  if (adjusted == nullptr) {
11307  lua_pop(L, 1);
11308  luaL_error(L, "cannot properly align memory for '%s'", detail::demangle<T>().data());
11309  }
11310  return static_cast<T*>(adjusted);
11311  }
11312 
11313  template <typename T>
11314  int usertype_alloc_destroy(lua_State* L) noexcept {
11315  void* memory = lua_touserdata(L, 1);
11316  memory = align_usertype_pointer(memory);
11317  T** pdata = static_cast<T**>(memory);
11318  T* data = *pdata;
11319  std::allocator<T> alloc {};
11320  std::allocator_traits<std::allocator<T>>::destroy(alloc, data);
11321  return 0;
11322  }
11323 
11324  template <typename T>
11325  int unique_destroy(lua_State* L) noexcept {
11326  void* memory = lua_touserdata(L, 1);
11327  memory = align_usertype_unique_destructor(memory);
11328  unique_destructor& dx = *static_cast<unique_destructor*>(memory);
11329  memory = align_usertype_unique_tag<true>(memory);
11330  (dx)(memory);
11331  return 0;
11332  }
11333 
11334  template <typename T>
11335  int user_alloc_destroy(lua_State* L) noexcept {
11336  void* memory = lua_touserdata(L, 1);
11337  void* aligned_memory = align_user<T>(memory);
11338  T* typed_memory = static_cast<T*>(aligned_memory);
11339  std::allocator<T> alloc;
11340  std::allocator_traits<std::allocator<T>>::destroy(alloc, typed_memory);
11341  return 0;
11342  }
11343 
11344  template <typename T, typename Real>
11345  void usertype_unique_alloc_destroy(void* memory) {
11346  void* aligned_memory = align_usertype_unique<Real, true>(memory);
11347  Real* typed_memory = static_cast<Real*>(aligned_memory);
11348  std::allocator<Real> alloc;
11349  std::allocator_traits<std::allocator<Real>>::destroy(alloc, typed_memory);
11350  }
11351 
11352  template <typename T>
11353  int cannot_destroy(lua_State* L) {
11354  return luaL_error(L,
11355  "cannot call the destructor for '%s': it is either hidden (protected/private) or removed with '= "
11356  "delete' and thusly this type is being destroyed without properly destroying, invoking undefined "
11357  "behavior: please bind a usertype and specify a custom destructor to define the behavior properly",
11358  detail::demangle<T>().data());
11359  }
11360 
11361  template <typename T>
11362  void reserve(T&, std::size_t) {
11363  }
11364 
11365  template <typename T, typename Al>
11366  void reserve(std::vector<T, Al>& vec, std::size_t hint) {
11367  vec.reserve(hint);
11368  }
11369 
11370  template <typename T, typename Tr, typename Al>
11371  void reserve(std::basic_string<T, Tr, Al>& str, std::size_t hint) {
11372  str.reserve(hint);
11373  }
11374 
11375  inline bool property_always_true(meta_function) {
11376  return true;
11377  }
11378 
11380  int& times_through;
11381  std::bitset<64>& properties;
11382  automagic_enrollments& enrollments;
11383 
11384  properties_enrollment_allowed(int& times_through_, std::bitset<64>& properties_, automagic_enrollments& enrollments_)
11385  : times_through(times_through_), properties(properties_), enrollments(enrollments_) {
11386  }
11387 
11388  bool operator()(meta_function mf) const {
11389  bool p = properties[static_cast<std::size_t>(mf)];
11390  if (times_through > 0) {
11391  return p;
11392  }
11393  switch (mf) {
11394  case meta_function::length:
11395  return enrollments.length_operator && !p;
11396  case meta_function::pairs:
11397  return enrollments.pairs_operator && !p;
11398  case meta_function::call:
11399  return enrollments.call_operator && !p;
11400  case meta_function::less_than:
11401  return enrollments.less_than_operator && !p;
11402  case meta_function::less_than_or_equal_to:
11403  return enrollments.less_than_or_equal_to_operator && !p;
11404  case meta_function::equal_to:
11405  return enrollments.equal_to_operator && !p;
11406  default:
11407  break;
11408  }
11409  return !p;
11410  }
11411  };
11412 
11414  lua_reg_table& registration_table;
11415  int& index;
11416 
11417  indexed_insert(lua_reg_table& registration_table_, int& index_ref_) : registration_table(registration_table_), index(index_ref_) {
11418  }
11419  void operator()(meta_function meta_function_name_, lua_CFunction c_function_) {
11420  registration_table[index] = luaL_Reg { to_string(meta_function_name_).c_str(), c_function_ };
11421  ++index;
11422  }
11423  };
11424  } // namespace detail
11425 
11426  namespace stack {
11427 
11428  template <typename T, bool global = false, bool raw = false, typename = void>
11430  template <typename T, typename P, bool global = false, bool raw = false, typename = void>
11432 
11433  template <typename T, bool global = false, bool raw = false, typename = void>
11435 
11436  template <typename T, typename = void>
11438  template <typename T, typename = void>
11440 
11441  template <typename T, typename = void>
11443  template <typename T, typename = void>
11445 
11446  template <typename T, typename = void>
11447  struct popper;
11448 
11449  template <typename T, typename = void>
11451 
11452  template <typename T, type t, typename = void>
11454  template <typename T, type t, typename = void>
11456 
11457  template <typename T, typename = void>
11459  template <typename T, typename = void>
11461 
11462  struct probe {
11463  bool success;
11464  int levels;
11465 
11466  probe(bool s, int l) : success(s), levels(l) {
11467  }
11468 
11469  operator bool() const {
11470  return success;
11471  };
11472  };
11473 
11474  struct record {
11475  int last;
11476  int used;
11477 
11478  record() noexcept : last(), used() {
11479  }
11480  void use(int count) noexcept {
11481  last = count;
11482  used += count;
11483  }
11484  };
11485 
11486  namespace stack_detail {
11487  template <typename Function>
11488  Function* get_function_pointer(lua_State*, int, record&) noexcept;
11489  template <typename Function, typename Handler>
11490  bool check_function_pointer(lua_State* L, int index, Handler&& handler, record& tracking) noexcept;
11491  } // namespace stack_detail
11492 
11493  } // namespace stack
11494 
11495  namespace meta { namespace meta_detail {
11496  template <typename T>
11497  using adl_sol_lua_get_test_t = decltype(sol_lua_get(types<T>(), static_cast<lua_State*>(nullptr), -1, std::declval<stack::record&>()));
11498 
11499  template <typename T>
11500  using adl_sol_lua_interop_get_test_t
11501  = decltype(sol_lua_interop_get(types<T>(), static_cast<lua_State*>(nullptr), -1, static_cast<void*>(nullptr), std::declval<stack::record&>()));
11502 
11503  template <typename T>
11504  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&>()));
11505 
11506  template <typename T>
11507  using adl_sol_lua_interop_check_test_t
11508  = decltype(sol_lua_interop_check(types<T>(), static_cast<lua_State*>(nullptr), -1, type::none, &no_panic, std::declval<stack::record&>()));
11509 
11510  template <typename T>
11511  using adl_sol_lua_check_get_test_t
11512  = decltype(sol_lua_check_get(types<T>(), static_cast<lua_State*>(nullptr), -1, &no_panic, std::declval<stack::record&>()));
11513 
11514  template <typename... Args>
11515  using adl_sol_lua_push_test_t = decltype(sol_lua_push(static_cast<lua_State*>(nullptr), std::declval<Args>()...));
11516 
11517  template <typename T, typename... Args>
11518  using adl_sol_lua_push_exact_test_t = decltype(sol_lua_push(types<T>(), static_cast<lua_State*>(nullptr), std::declval<Args>()...));
11519 
11520  template <typename T>
11521  inline constexpr bool is_adl_sol_lua_get_v = meta::is_detected_v<adl_sol_lua_get_test_t, T>;
11522 
11523  template <typename T>
11524  inline constexpr bool is_adl_sol_lua_interop_get_v = meta::is_detected_v<adl_sol_lua_interop_get_test_t, T>;
11525 
11526  template <typename T>
11527  inline constexpr bool is_adl_sol_lua_check_v = meta::is_detected_v<adl_sol_lua_check_test_t, T>;
11528 
11529  template <typename T>
11530  inline constexpr bool is_adl_sol_lua_interop_check_v = meta::is_detected_v<adl_sol_lua_interop_check_test_t, T>;
11531 
11532  template <typename T>
11533  inline constexpr bool is_adl_sol_lua_check_get_v = meta::is_detected_v<adl_sol_lua_check_get_test_t, T>;
11534 
11535  template <typename... Args>
11536  inline constexpr bool is_adl_sol_lua_push_v = meta::is_detected_v<adl_sol_lua_push_test_t, Args...>;
11537 
11538  template <typename T, typename... Args>
11539  inline constexpr bool is_adl_sol_lua_push_exact_v = meta::is_detected_v<adl_sol_lua_push_exact_test_t, T, Args...>;
11540  }} // namespace meta::meta_detail
11541 
11542  namespace stack {
11543  namespace stack_detail {
11544  constexpr const char* not_enough_stack_space = "not enough space left on Lua stack";
11545  constexpr const char* not_enough_stack_space_floating = "not enough space left on Lua stack for a floating point number";
11546  constexpr const char* not_enough_stack_space_integral = "not enough space left on Lua stack for an integral number";
11547  constexpr const char* not_enough_stack_space_string = "not enough space left on Lua stack for a string";
11548  constexpr const char* not_enough_stack_space_meta_function_name = "not enough space left on Lua stack for the name of a meta_function";
11549  constexpr const char* not_enough_stack_space_userdata = "not enough space left on Lua stack to create a sol2 userdata";
11550  constexpr const char* not_enough_stack_space_generic = "not enough space left on Lua stack to push valuees";
11551  constexpr const char* not_enough_stack_space_environment = "not enough space left on Lua stack to retrieve environment";
11552 
11553  template <typename T>
11554  struct strip {
11555  typedef T type;
11556  };
11557  template <typename T>
11558  struct strip<std::reference_wrapper<T>> {
11559  typedef T& type;
11560  };
11561  template <typename T>
11562  struct strip<user<T>> {
11563  typedef T& type;
11564  };
11565  template <typename T>
11566  struct strip<non_null<T>> {
11567  typedef T type;
11568  };
11569  template <typename T>
11570  using strip_t = typename strip<T>::type;
11571 
11572  template <typename C>
11573  static int get_size_hint(C& c) {
11574  return static_cast<int>(c.size());
11575  }
11576 
11577  template <typename V, typename Al>
11578  static int get_size_hint(const std::forward_list<V, Al>&) {
11579  // forward_list makes me sad
11580  return static_cast<int>(32);
11581  }
11582 
11583  template <typename T>
11584  decltype(auto) unchecked_unqualified_get(lua_State* L, int index, record& tracking) {
11585  using Tu = meta::unqualified_t<T>;
11586  if constexpr (meta::meta_detail::is_adl_sol_lua_get_v<Tu>) {
11587  return sol_lua_get(types<Tu>(), L, index, tracking);
11588  }
11589  else {
11591  return g.get(L, index, tracking);
11592  }
11593  }
11594 
11595  template <typename T>
11596  decltype(auto) unchecked_get(lua_State* L, int index, record& tracking) {
11597  if constexpr (meta::meta_detail::is_adl_sol_lua_get_v<T>) {
11598  return sol_lua_get(types<T>(), L, index, tracking);
11599  }
11600  else {
11601  qualified_getter<T> g {};
11602  return g.get(L, index, tracking);
11603  }
11604  }
11605 
11606  template <typename T>
11607  decltype(auto) unqualified_interop_get(lua_State* L, int index, void* unadjusted_pointer, record& tracking) {
11608  using Tu = meta::unqualified_t<T>;
11609  if constexpr (meta::meta_detail::is_adl_sol_lua_interop_get_v<Tu>) {
11610  return sol_lua_interop_get(types<Tu>(), L, index, unadjusted_pointer, tracking);
11611  }
11612  else {
11613  (void)L;
11614  (void)index;
11615  (void)unadjusted_pointer;
11616  (void)tracking;
11617  using Ti = stack_detail::strip_t<Tu>;
11618  return std::pair<bool, Ti*> { false, nullptr };
11619  }
11620  }
11621 
11622  template <typename T>
11623  decltype(auto) interop_get(lua_State* L, int index, void* unadjusted_pointer, record& tracking) {
11624  if constexpr (meta::meta_detail::is_adl_sol_lua_interop_get_v<T>) {
11625  return sol_lua_interop_get(types<T>(), L, index, unadjusted_pointer, tracking);
11626  }
11627  else {
11628  return unqualified_interop_get<T>(L, index, unadjusted_pointer, tracking);
11629  }
11630  }
11631 
11632  template <typename T, typename Handler>
11633  bool unqualified_interop_check(lua_State* L, int index, type index_type, Handler&& handler, record& tracking) {
11634  using Tu = meta::unqualified_t<T>;
11635  if constexpr (meta::meta_detail::is_adl_sol_lua_interop_check_v<Tu>) {
11636  return sol_lua_interop_check(types<Tu>(), L, index, index_type, std::forward<Handler>(handler), tracking);
11637  }
11638  else {
11639  (void)L;
11640  (void)index;
11641  (void)index_type;
11642  (void)handler;
11643  (void)tracking;
11644  return false;
11645  }
11646  }
11647 
11648  template <typename T, typename Handler>
11649  bool interop_check(lua_State* L, int index, type index_type, Handler&& handler, record& tracking) {
11650  if constexpr (meta::meta_detail::is_adl_sol_lua_interop_check_v<T>) {
11651  return sol_lua_interop_check(types<T>(), L, index, index_type, std::forward<Handler>(handler), tracking);
11652  }
11653  else {
11654  return unqualified_interop_check<T>(L, index, index_type, std::forward<Handler>(handler), tracking);
11655  }
11656  }
11657 
11658  using undefined_method_func = void (*)(stack_reference);
11659 
11661  lua_State* L;
11662  const char* key;
11663  undefined_method_func on_new_table;
11664 
11665  undefined_metatable(lua_State* l, const char* k, undefined_method_func umf) : L(l), key(k), on_new_table(umf) {
11666  }
11667 
11668  void operator()() const {
11669  if (luaL_newmetatable(L, key) == 1) {
11670  on_new_table(stack_reference(L, -1));
11671  }
11672  lua_setmetatable(L, -2);
11673  }
11674  };
11675  } // namespace stack_detail
11676 
11677  inline bool maybe_indexable(lua_State* L, int index = -1) {
11678  type t = type_of(L, index);
11679  return t == type::userdata || t == type::table;
11680  }
11681 
11682  inline int top(lua_State* L) {
11683  return lua_gettop(L);
11684  }
11685 
11686  inline bool is_main_thread(lua_State* L) {
11687  int ismainthread = lua_pushthread(L);
11688  lua_pop(L, 1);
11689  return ismainthread == 1;
11690  }
11691 
11692  inline void coroutine_create_guard(lua_State* L) {
11693  if (is_main_thread(L)) {
11694  return;
11695  }
11696  int stacksize = lua_gettop(L);
11697  if (stacksize < 1) {
11698  return;
11699  }
11700  if (type_of(L, 1) != type::function) {
11701  return;
11702  }
11703  // well now we're screwed...
11704  // we can clean the stack and pray it doesn't destroy anything?
11705  lua_pop(L, stacksize);
11706  }
11707 
11708  inline void clear(lua_State* L, int table_index) {
11709  lua_pushnil(L);
11710  while (lua_next(L, table_index) != 0) {
11711  // remove value
11712  lua_pop(L, 1);
11713  // duplicate key to protect form rawset
11714  lua_pushvalue(L, -1);
11715  // push new value
11716  lua_pushnil(L);
11717  // table_index%[key] = nil
11718  lua_rawset(L, table_index);
11719  }
11720  }
11721 
11722  inline void clear(reference& r) {
11723  auto pp = push_pop<false>(r);
11724  int stack_index = pp.index_of(r);
11725  clear(r.lua_state(), stack_index);
11726  }
11727 
11728  inline void clear(stack_reference& r) {
11729  clear(r.lua_state(), r.stack_index());
11730  }
11731 
11732  inline void clear(lua_State* L_, stateless_reference& r) {
11733  r.push(L_);
11734  int stack_index = absolute_index(L_, -1);
11735  clear(L_, stack_index);
11736  r.pop(L_);
11737  }
11738 
11739  inline void clear(lua_State* L_, stateless_stack_reference& r) {
11740  clear(L_, r.stack_index());
11741  }
11742 
11743  template <typename T, typename... Args>
11744  int push(lua_State* L, T&& t, Args&&... args) {
11745  using Tu = meta::unqualified_t<T>;
11746  if constexpr (meta::meta_detail::is_adl_sol_lua_push_exact_v<T, T, Args...>) {
11747  return sol_lua_push(types<T>(), L, std::forward<T>(t), std::forward<Args>(args)...);
11748  }
11749  else if constexpr (meta::meta_detail::is_adl_sol_lua_push_exact_v<Tu, T, Args...>) {
11750  return sol_lua_push(types<Tu>(), L, std::forward<T>(t), std::forward<Args>(args)...);
11751  }
11752  else if constexpr (meta::meta_detail::is_adl_sol_lua_push_v<T, Args...>) {
11753  return sol_lua_push(L, std::forward<T>(t), std::forward<Args>(args)...);
11754  }
11755  else {
11757  return p.push(L, std::forward<T>(t), std::forward<Args>(args)...);
11758  }
11759  }
11760 
11761  // overload allows to use a pusher of a specific type, but pass in any kind of args
11762  template <typename T, typename Arg, typename... Args, typename = std::enable_if_t<!std::is_same<T, Arg>::value>>
11763  int push(lua_State* L, Arg&& arg, Args&&... args) {
11764  using Tu = meta::unqualified_t<T>;
11765  if constexpr (meta::meta_detail::is_adl_sol_lua_push_exact_v<T, Arg, Args...>) {
11766  return sol_lua_push(types<T>(), L, std::forward<Arg>(arg), std::forward<Args>(args)...);
11767  }
11768  else if constexpr (meta::meta_detail::is_adl_sol_lua_push_exact_v<Tu, Arg, Args...>) {
11769  return sol_lua_push(types<Tu>(), L, std::forward<Arg>(arg), std::forward<Args>(args)...);
11770  }
11771  else if constexpr (meta::meta_detail::is_adl_sol_lua_push_v<Arg, Args...> && !detail::is_tagged_v<Tu>) {
11772  return sol_lua_push(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
11773  }
11774  else {
11776  return p.push(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
11777  }
11778  }
11779 
11780  template <typename T, typename... Args>
11781  int push_userdata(lua_State* L, T&& t, Args&&... args) {
11782  using U = meta::unqualified_t<T>;
11783  using Tr = meta::conditional_t<std::is_pointer_v<U>,
11785  meta::conditional_t<is_unique_usertype_v<U>, detail::as_unique_tag<U>, detail::as_value_tag<U>>>;
11786  return stack::push<Tr>(L, std::forward<T>(t), std::forward<Args>(args)...);
11787  }
11788 
11789  template <typename T, typename Arg, typename... Args>
11790  int push_userdata(lua_State* L, Arg&& arg, Args&&... args) {
11791  using U = meta::unqualified_t<T>;
11792  using Tr = meta::conditional_t<std::is_pointer_v<U>,
11794  meta::conditional_t<is_unique_usertype_v<U>, detail::as_unique_tag<U>, detail::as_value_tag<U>>>;
11795  return stack::push<Tr>(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
11796  }
11797 
11798  namespace stack_detail {
11799 
11800  template <typename T, typename Arg, typename... Args>
11801  int push_reference(lua_State* L, Arg&& arg, Args&&... args) {
11802  // clang-format off
11803  using use_reference_tag =
11804  meta::all<
11805  meta::neg<is_value_semantic_for_function<T>>
11806 #if SOL_IS_OFF(SOL_FUNCTION_CALL_VALUE_SEMANTICS)
11807  , std::is_lvalue_reference<T>,
11808  meta::neg<std::is_const<std::remove_reference_t<T>>>,
11809  meta::neg<is_lua_primitive<meta::unqualified_t<T>>>,
11810  meta::neg<is_unique_usertype<meta::unqualified_t<T>>>
11811 #endif
11812  >;
11813  // clang-format on
11814  using Tr = meta::conditional_t<use_reference_tag::value, detail::as_reference_tag, meta::unqualified_t<T>>;
11815  return stack::push<Tr>(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
11816  }
11817 
11818  } // namespace stack_detail
11819 
11820  template <typename T, typename... Args>
11821  int push_reference(lua_State* L, T&& t, Args&&... args) {
11822  return stack_detail::push_reference<T>(L, std::forward<T>(t), std::forward<Args>(args)...);
11823  }
11824 
11825  template <typename T, typename Arg, typename... Args>
11826  int push_reference(lua_State* L, Arg&& arg, Args&&... args) {
11827  return stack_detail::push_reference<T>(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
11828  }
11829 
11830  inline int multi_push(lua_State*) {
11831  // do nothing
11832  return 0;
11833  }
11834 
11835  template <typename T, typename... Args>
11836  int multi_push(lua_State* L, T&& t, Args&&... args) {
11837  int pushcount = push(L, std::forward<T>(t));
11838  void(detail::swallow { (pushcount += stack::push(L, std::forward<Args>(args)), 0)... });
11839  return pushcount;
11840  }
11841 
11842  inline int multi_push_reference(lua_State*) {
11843  // do nothing
11844  return 0;
11845  }
11846 
11847  template <typename T, typename... Args>
11848  int multi_push_reference(lua_State* L, T&& t, Args&&... args) {
11849  int pushcount = stack::push_reference(L, std::forward<T>(t));
11850  void(detail::swallow { (pushcount += stack::push_reference(L, std::forward<Args>(args)), 0)... });
11851  return pushcount;
11852  }
11853 
11854  template <typename T, typename Handler>
11855  bool unqualified_check(lua_State* L, int index, Handler&& handler, record& tracking) {
11856  using Tu = meta::unqualified_t<T>;
11857  if constexpr (meta::meta_detail::is_adl_sol_lua_check_v<Tu>) {
11858  return sol_lua_check(types<Tu>(), L, index, std::forward<Handler>(handler), tracking);
11859  }
11860  else {
11862  return c.check(L, index, std::forward<Handler>(handler), tracking);
11863  }
11864  }
11865 
11866  template <typename T, typename Handler>
11867  bool unqualified_check(lua_State* L, int index, Handler&& handler) {
11868  record tracking {};
11869  return unqualified_check<T>(L, index, std::forward<Handler>(handler), tracking);
11870  }
11871 
11872  template <typename T>
11873  bool unqualified_check(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
11874  auto handler = &no_panic;
11875  return unqualified_check<T>(L, index, handler);
11876  }
11877 
11878  template <typename T, typename Handler>
11879  bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
11880  if constexpr (meta::meta_detail::is_adl_sol_lua_check_v<T>) {
11881  return sol_lua_check(types<T>(), L, index, std::forward<Handler>(handler), tracking);
11882  }
11883  else {
11884  using Tu = meta::unqualified_t<T>;
11886  return c.check(L, index, std::forward<Handler>(handler), tracking);
11887  }
11888  }
11889 
11890  template <typename T, typename Handler>
11891  bool check(lua_State* L, int index, Handler&& handler) {
11892  record tracking {};
11893  return check<T>(L, index, std::forward<Handler>(handler), tracking);
11894  }
11895 
11896  template <typename T>
11897  bool check(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
11898  auto handler = &no_panic;
11899  return check<T>(L, index, handler);
11900  }
11901 
11902  template <typename T, typename Handler>
11903  bool check_usertype(lua_State* L, int index, type, Handler&& handler, record& tracking) {
11904  using Tu = meta::unqualified_t<T>;
11905  using detail_t = meta::conditional_t<std::is_pointer_v<T>, detail::as_pointer_tag<Tu>, detail::as_value_tag<Tu>>;
11906  return check<detail_t>(L, index, std::forward<Handler>(handler), tracking);
11907  }
11908 
11909  template <typename T, typename Handler>
11910  bool check_usertype(lua_State* L, int index, Handler&& handler, record& tracking) {
11911  using Tu = meta::unqualified_t<T>;
11912  using detail_t = meta::conditional_t<std::is_pointer_v<T>, detail::as_pointer_tag<Tu>, detail::as_value_tag<Tu>>;
11913  return check<detail_t>(L, index, std::forward<Handler>(handler), tracking);
11914  }
11915 
11916  template <typename T, typename Handler>
11917  bool check_usertype(lua_State* L, int index, Handler&& handler) {
11918  record tracking {};
11919  return check_usertype<T>(L, index, std::forward<Handler>(handler), tracking);
11920  }
11921 
11922  template <typename T>
11923  bool check_usertype(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
11924  auto handler = &no_panic;
11925  return check_usertype<T>(L, index, handler);
11926  }
11927 
11928  template <typename T, typename Handler>
11929  decltype(auto) unqualified_check_get(lua_State* L, int index, Handler&& handler, record& tracking) {
11930  using Tu = meta::unqualified_t<T>;
11931  if constexpr (meta::meta_detail::is_adl_sol_lua_check_get_v<T>) {
11932  return sol_lua_check_get(types<T>(), L, index, std::forward<Handler>(handler), tracking);
11933  }
11934  else if constexpr (meta::meta_detail::is_adl_sol_lua_check_get_v<Tu>) {
11935  return sol_lua_check_get(types<Tu>(), L, index, std::forward<Handler>(handler), tracking);
11936  }
11937  else {
11939  return cg.get(L, index, std::forward<Handler>(handler), tracking);
11940  }
11941  }
11942 
11943  template <typename T, typename Handler>
11944  decltype(auto) unqualified_check_get(lua_State* L, int index, Handler&& handler) {
11945  record tracking {};
11946  return unqualified_check_get<T>(L, index, handler, tracking);
11947  }
11948 
11949  template <typename T>
11950  decltype(auto) unqualified_check_get(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
11951  auto handler = &no_panic;
11952  return unqualified_check_get<T>(L, index, handler);
11953  }
11954 
11955  template <typename T, typename Handler>
11956  decltype(auto) check_get(lua_State* L, int index, Handler&& handler, record& tracking) {
11957  if constexpr (meta::meta_detail::is_adl_sol_lua_check_get_v<T>) {
11958  return sol_lua_check_get(types<T>(), L, index, std::forward<Handler>(handler), tracking);
11959  }
11960  else {
11962  return cg.get(L, index, std::forward<Handler>(handler), tracking);
11963  }
11964  }
11965 
11966  template <typename T, typename Handler>
11967  decltype(auto) check_get(lua_State* L, int index, Handler&& handler) {
11968  record tracking {};
11969  return check_get<T>(L, index, handler, tracking);
11970  }
11971 
11972  template <typename T>
11973  decltype(auto) check_get(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
11974  auto handler = &no_panic;
11975  return check_get<T>(L, index, handler);
11976  }
11977 
11978  namespace stack_detail {
11979 
11980  template <typename Handler>
11981  bool check_types(lua_State*, int, Handler&&, record&) {
11982  return true;
11983  }
11984 
11985  template <typename T, typename... Args, typename Handler>
11986  bool check_types(lua_State* L, int firstargument, Handler&& handler, record& tracking) {
11987  if (!stack::check<T>(L, firstargument + tracking.used, handler, tracking))
11988  return false;
11989  return check_types<Args...>(L, firstargument, std::forward<Handler>(handler), tracking);
11990  }
11991 
11992  template <typename... Args, typename Handler>
11993  bool check_types(types<Args...>, lua_State* L, int index, Handler&& handler, record& tracking) {
11994  return check_types<Args...>(L, index, std::forward<Handler>(handler), tracking);
11995  }
11996 
11997  } // namespace stack_detail
11998 
11999  template <typename... Args, typename Handler>
12000  bool multi_check(lua_State* L, int index, Handler&& handler, record& tracking) {
12001  return stack_detail::check_types<Args...>(L, index, std::forward<Handler>(handler), tracking);
12002  }
12003 
12004  template <typename... Args, typename Handler>
12005  bool multi_check(lua_State* L, int index, Handler&& handler) {
12006  record tracking {};
12007  return multi_check<Args...>(L, index, std::forward<Handler>(handler), tracking);
12008  }
12009 
12010  template <typename... Args>
12011  bool multi_check(lua_State* L, int index) {
12012  return multi_check<Args...>(L, index);
12013  }
12014 
12015  template <typename T>
12016  auto unqualified_get(lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_unqualified_get<T>(L, index, tracking)) {
12017 #if SOL_IS_ON(SOL_SAFE_GETTER)
12018  static constexpr bool is_op = meta::is_optional_v<T>;
12019  if constexpr (is_op) {
12020  return stack_detail::unchecked_unqualified_get<T>(L, index, tracking);
12021  }
12022  else {
12024  return stack_detail::unchecked_unqualified_get<T>(L, index, tracking);
12025  }
12026  auto op = unqualified_check_get<T>(L, index, type_panic_c_str, tracking);
12027  return *std::move(op);
12028  }
12029 #else
12030  return stack_detail::unchecked_unqualified_get<T>(L, index, tracking);
12031 #endif
12032  }
12033 
12034  template <typename T>
12035  decltype(auto) unqualified_get(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
12036  record tracking {};
12037  return unqualified_get<T>(L, index, tracking);
12038  }
12039 
12040  template <typename T>
12041  auto get(lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_get<T>(L, index, tracking)) {
12042 #if SOL_IS_ON(SOL_SAFE_GETTER)
12043  static constexpr bool is_op = meta::is_optional_v<T>;
12044  if constexpr (is_op) {
12045  return stack_detail::unchecked_get<T>(L, index, tracking);
12046  }
12047  else {
12049  return stack_detail::unchecked_get<T>(L, index, tracking);
12050  }
12051  auto op = check_get<T>(L, index, type_panic_c_str, tracking);
12052  return *std::move(op);
12053  }
12054 #else
12055  return stack_detail::unchecked_get<T>(L, index, tracking);
12056 #endif
12057  }
12058 
12059  template <typename T>
12060  decltype(auto) get(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
12061  record tracking {};
12062  return get<T>(L, index, tracking);
12063  }
12064 
12065  template <typename T>
12066  decltype(auto) get_usertype(lua_State* L, int index, record& tracking) {
12067  using UT = meta::conditional_t<std::is_pointer<T>::value, detail::as_pointer_tag<std::remove_pointer_t<T>>, detail::as_value_tag<T>>;
12068  return get<UT>(L, index, tracking);
12069  }
12070 
12071  template <typename T>
12072  decltype(auto) get_usertype(lua_State* L, int index = -lua_size_v<meta::unqualified_t<T>>) {
12073  record tracking {};
12074  return get_usertype<T>(L, index, tracking);
12075  }
12076 
12077  template <typename T>
12078  decltype(auto) pop(lua_State* L) {
12079  return popper<T> {}.pop(L);
12080  }
12081 
12082  template <bool global = false, bool raw = false, typename Key>
12083  void get_field(lua_State* L, Key&& key) {
12084  field_getter<meta::unqualified_t<Key>, global, raw> {}.get(L, std::forward<Key>(key));
12085  }
12086 
12087  template <bool global = false, bool raw = false, typename Key>
12088  void get_field(lua_State* L, Key&& key, int tableindex) {
12089  field_getter<meta::unqualified_t<Key>, global, raw> {}.get(L, std::forward<Key>(key), tableindex);
12090  }
12091 
12092  template <bool global = false, typename Key>
12093  void raw_get_field(lua_State* L, Key&& key) {
12094  get_field<global, true>(L, std::forward<Key>(key));
12095  }
12096 
12097  template <bool global = false, typename Key>
12098  void raw_get_field(lua_State* L, Key&& key, int tableindex) {
12099  get_field<global, true>(L, std::forward<Key>(key), tableindex);
12100  }
12101 
12102  template <bool global = false, bool raw = false, typename C = detail::non_lua_nil_t, typename Key>
12103  probe probe_get_field(lua_State* L, Key&& key) {
12104  return probe_field_getter<meta::unqualified_t<Key>, C, global, raw> {}.get(L, std::forward<Key>(key));
12105  }
12106 
12107  template <bool global = false, bool raw = false, typename C = detail::non_lua_nil_t, typename Key>
12108  probe probe_get_field(lua_State* L, Key&& key, int tableindex) {
12109  return probe_field_getter<meta::unqualified_t<Key>, C, global, raw> {}.get(L, std::forward<Key>(key), tableindex);
12110  }
12111 
12112  template <bool global = false, typename C = detail::non_lua_nil_t, typename Key>
12113  probe probe_raw_get_field(lua_State* L, Key&& key) {
12114  return probe_get_field<global, true, C>(L, std::forward<Key>(key));
12115  }
12116 
12117  template <bool global = false, typename C = detail::non_lua_nil_t, typename Key>
12118  probe probe_raw_get_field(lua_State* L, Key&& key, int tableindex) {
12119  return probe_get_field<global, true, C>(L, std::forward<Key>(key), tableindex);
12120  }
12121 
12122  template <bool global = false, bool raw = false, typename Key, typename Value>
12123  void set_field(lua_State* L, Key&& key, Value&& value) {
12124  field_setter<meta::unqualified_t<Key>, global, raw> {}.set(L, std::forward<Key>(key), std::forward<Value>(value));
12125  }
12126 
12127  template <bool global = false, bool raw = false, typename Key, typename Value>
12128  void set_field(lua_State* L, Key&& key, Value&& value, int tableindex) {
12129  field_setter<meta::unqualified_t<Key>, global, raw> {}.set(L, std::forward<Key>(key), std::forward<Value>(value), tableindex);
12130  }
12131 
12132  template <bool global = false, typename Key, typename Value>
12133  void raw_set_field(lua_State* L, Key&& key, Value&& value) {
12134  set_field<global, true>(L, std::forward<Key>(key), std::forward<Value>(value));
12135  }
12136 
12137  template <bool global = false, typename Key, typename Value>
12138  void raw_set_field(lua_State* L, Key&& key, Value&& value, int tableindex) {
12139  set_field<global, true>(L, std::forward<Key>(key), std::forward<Value>(value), tableindex);
12140  }
12141 
12142  template <typename T, typename F>
12143  void modify_unique_usertype_as(const stack_reference& obj, F&& f) {
12144  void* raw = lua_touserdata(obj.lua_state(), obj.stack_index());
12145  void* ptr_memory = detail::align_usertype_pointer(raw);
12146  void* uu_memory = detail::align_usertype_unique<T>(raw);
12147  T& uu = *static_cast<T*>(uu_memory);
12148  f(uu);
12149  *static_cast<void**>(ptr_memory) = static_cast<void*>(detail::unique_get(obj.lua_state(), uu));
12150  }
12151 
12152  template <typename F>
12153  void modify_unique_usertype(const stack_reference& obj, F&& f) {
12155  using T = typename bt::template arg_at<0>;
12156  using Tu = meta::unqualified_t<T>;
12157  modify_unique_usertype_as<Tu>(obj, std::forward<F>(f));
12158  }
12159 
12160  namespace stack_detail {
12161  template <typename T, typename Handler>
12162  decltype(auto) check_get_arg(lua_State* L_, int index_, Handler&& handler_, record& tracking_) {
12163  if constexpr (meta::meta_detail::is_adl_sol_lua_check_access_v<T>) {
12164  sol_lua_check_access(types<meta::unqualified_t<T>>(), L_, index_, tracking_);
12165  }
12166  return check_get<T>(L_, index_, std::forward<Handler>(handler_), tracking_);
12167  }
12168 
12169  template <typename T>
12170  decltype(auto) unchecked_get_arg(lua_State* L_, int index_, record& tracking_) {
12171  if constexpr (meta::meta_detail::is_adl_sol_lua_check_access_v<T>) {
12172  sol_lua_check_access(types<meta::unqualified_t<T>>(), L_, index_, tracking_);
12173  }
12174  return unchecked_get<T>(L_, index_, tracking_);
12175  }
12176  } // namespace stack_detail
12177 
12178  } // namespace stack
12179 
12180  namespace detail {
12181 
12182  template <typename T>
12183  lua_CFunction make_destructor(std::true_type) {
12184  if constexpr (is_unique_usertype_v<T>) {
12185  return &unique_destroy<T>;
12186  }
12187  else if constexpr (!std::is_pointer_v<T>) {
12188  return &usertype_alloc_destroy<T>;
12189  }
12190  else {
12191  return &cannot_destroy<T>;
12192  }
12193  }
12194 
12195  template <typename T>
12196  lua_CFunction make_destructor(std::false_type) {
12197  return &cannot_destroy<T>;
12198  }
12199 
12200  template <typename T>
12201  lua_CFunction make_destructor() {
12202  return make_destructor<T>(std::is_destructible<T>());
12203  }
12204 
12205  struct no_comp {
12206  template <typename A, typename B>
12207  bool operator()(A&&, B&&) const {
12208  return false;
12209  }
12210  };
12211 
12212  template <typename T>
12213  int is_check(lua_State* L) {
12214  return stack::push(L, stack::check<T>(L, 1, &no_panic));
12215  }
12216 
12217  template <typename T>
12218  int member_default_to_string(std::true_type, lua_State* L) {
12219  decltype(auto) ts = stack::get<T>(L, 1).to_string();
12220  return stack::push(L, std::forward<decltype(ts)>(ts));
12221  }
12222 
12223  template <typename T>
12224  int member_default_to_string(std::false_type, lua_State* L) {
12225  return luaL_error(L,
12226  "cannot perform to_string on '%s': no 'to_string' overload in namespace, 'to_string' member "
12227  "function, or operator<<(ostream&, ...) present",
12228  detail::demangle<T>().data());
12229  }
12230 
12231  template <typename T>
12232  int adl_default_to_string(std::true_type, lua_State* L) {
12233  using namespace std;
12234  decltype(auto) ts = to_string(stack::get<T>(L, 1));
12235  return stack::push(L, std::forward<decltype(ts)>(ts));
12236  }
12237 
12238  template <typename T>
12239  int adl_default_to_string(std::false_type, lua_State* L) {
12240  return member_default_to_string<T>(meta::supports_to_string_member<T>(), L);
12241  }
12242 
12243  template <typename T>
12244  int oss_default_to_string(std::true_type, lua_State* L) {
12245  std::ostringstream oss;
12246  oss << stack::unqualified_get<T>(L, 1);
12247  return stack::push(L, oss.str());
12248  }
12249 
12250  template <typename T>
12251  int oss_default_to_string(std::false_type, lua_State* L) {
12252  return adl_default_to_string<T>(meta::supports_adl_to_string<T>(), L);
12253  }
12254 
12255  template <typename T>
12256  int default_to_string(lua_State* L) {
12257  return oss_default_to_string<T>(meta::supports_op_left_shift<std::ostream, T>(), L);
12258  }
12259 
12260  template <typename T>
12261  int default_size(lua_State* L) {
12262  decltype(auto) self = stack::unqualified_get<T>(L, 1);
12263  return stack::push(L, self.size());
12264  }
12265 
12266  template <typename T, typename Op>
12267  int comparsion_operator_wrap(lua_State* L) {
12268  if constexpr (std::is_void_v<T>) {
12269  return stack::push(L, false);
12270  }
12271  else {
12272  auto maybel = stack::unqualified_check_get<T>(L, 1);
12273  if (!maybel) {
12274  return stack::push(L, false);
12275  }
12276  auto mayber = stack::unqualified_check_get<T>(L, 2);
12277  if (!mayber) {
12278  return stack::push(L, false);
12279  }
12280  decltype(auto) l = *maybel;
12281  decltype(auto) r = *mayber;
12282  if constexpr (std::is_same_v<no_comp, Op>) {
12283  std::equal_to<> op;
12284  return stack::push(L, op(detail::ptr(l), detail::ptr(r)));
12285  }
12286  else {
12287  if constexpr (std::is_same_v<std::equal_to<>, Op> // clang-format hack
12288  || std::is_same_v<std::less_equal<>, Op> //
12289  || std::is_same_v<std::less_equal<>, Op>) { //
12290  if (detail::ptr(l) == detail::ptr(r)) {
12291  return stack::push(L, true);
12292  }
12293  }
12294  Op op;
12295  return stack::push(L, op(detail::deref(l), detail::deref(r)));
12296  }
12297  }
12298  }
12299 
12300  template <typename T, typename IFx, typename Fx>
12301  void insert_default_registrations(IFx&& ifx, Fx&& fx);
12302 
12303  template <typename T, bool, bool>
12305 
12306  template <typename T>
12307  struct get_is_primitive<T, true, false>
12308  : meta::neg<std::is_reference<decltype(sol_lua_get(types<T>(), nullptr, -1, std::declval<stack::record&>()))>> { };
12309 
12310  template <typename T>
12311  struct get_is_primitive<T, false, true>
12312  : meta::neg<std::is_reference<decltype(sol_lua_get(types<meta::unqualified_t<T>>(), nullptr, -1, std::declval<stack::record&>()))>> { };
12313 
12314  template <typename T>
12315  struct get_is_primitive<T, true, true> : get_is_primitive<T, true, false> { };
12316 
12317  } // namespace detail
12318 
12319  template <typename T>
12321  : 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>>> { };
12322 
12323 } // namespace sol
12324 
12325 // end of sol/stack_core.hpp
12326 
12327 // beginning of sol/stack_check.hpp
12328 
12329 // beginning of sol/stack_check_unqualified.hpp
12330 
12331 #include <memory>
12332 #include <functional>
12333 #include <utility>
12334 #include <cmath>
12335 #include <optional>
12336 #if SOL_IS_ON(SOL_STD_VARIANT)
12337 #include <variant>
12338 #endif // variant shenanigans
12339 
12340 namespace sol { namespace stack {
12341  template <typename Handler>
12342  bool loose_table_check(lua_State* L_, int index, Handler&& handler, record& tracking) {
12343  tracking.use(1);
12344  type t = type_of(L_, index);
12345  if (t == type::table) {
12346  return true;
12347  }
12348  if (t != type::userdata) {
12349  handler(L_, index, type::table, t, "value is not a table or a userdata that can behave like one");
12350  return false;
12351  }
12352  return true;
12353  }
12354 
12355  namespace stack_detail {
12356  inline bool impl_check_metatable(lua_State* L_, int index, const std::string& metakey, bool poptable) {
12357  luaL_getmetatable(L_, &metakey[0]);
12358  const type expectedmetatabletype = static_cast<type>(lua_type(L_, -1));
12359  if (expectedmetatabletype != type::lua_nil) {
12360  if (lua_rawequal(L_, -1, index) == 1) {
12361  lua_pop(L_, 1 + static_cast<int>(poptable));
12362  return true;
12363  }
12364  }
12365  lua_pop(L_, 1);
12366  return false;
12367  }
12368 
12369  template <typename T, bool poptable = true>
12370  inline bool check_metatable(lua_State* L_, int index = -2) {
12371  return impl_check_metatable(L_, index, usertype_traits<T>::metatable(), poptable);
12372  }
12373 
12374  template <type expected, int (*check_func)(lua_State*, int)>
12375  struct basic_check {
12376  template <typename Handler>
12377  static bool check(lua_State* L_, int index, Handler&& handler, record& tracking) {
12378  tracking.use(1);
12379  bool success = check_func(L_, index) == 1;
12380  if (!success) {
12381  // expected type, actual type
12382  handler(L_, index, expected, type_of(L_, index), "");
12383  }
12384  return success;
12385  }
12386  };
12387  } // namespace stack_detail
12388 
12389  template <typename T, typename>
12391  template <typename Handler>
12392  static bool check(lua_State*, int, type, Handler&&, record&) {
12393  return false;
12394  }
12395  };
12396 
12397  template <typename T, typename>
12399  template <typename Handler>
12400  static bool check(lua_State* L_, int index, type index_type, Handler&& handler, record& tracking) {
12401  return stack_detail::unqualified_interop_check<T>(L_, index, index_type, std::forward<Handler>(handler), tracking);
12402  }
12403  };
12404 
12405  template <typename T, type expected, typename>
12406  struct unqualified_checker {
12407  template <typename Handler>
12408  static bool check(lua_State* L_, int index, Handler&& handler, record& tracking) {
12409  if constexpr (std::is_same_v<T, bool>) {
12410  tracking.use(1);
12411  bool success = lua_isboolean(L_, index) == 1;
12412  if (!success) {
12413  // expected type, actual type
12414  handler(L_, index, expected, type_of(L_, index), "");
12415  }
12416  return success;
12417  }
12418  else if constexpr (meta::any_same_v<T,
12419  char
12420 #if SOL_IS_ON(SOL_CHAR8_T)
12421  ,
12422  char8_t
12423 #endif
12424  ,
12425  char16_t,
12426  char32_t>) {
12427  return stack::check<std::basic_string<T>>(L_, index, std::forward<Handler>(handler), tracking);
12428  }
12429  else if constexpr (std::is_integral_v<T> || std::is_same_v<T, lua_Integer>) {
12430  tracking.use(1);
12431 #if SOL_LUA_VERSION_I_ >= 503
12432  // Lua 5.3 and greater checks for numeric precision
12433 #if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS)
12434  // imprecise, sloppy conversions
12435  int isnum = 0;
12436  lua_tointegerx(L_, index, &isnum);
12437  const bool success = isnum != 0;
12438  if (!success) {
12439  // expected type, actual type
12440  handler(L_, index, type::number, type_of(L_, index), detail::not_a_number_or_number_string_integral);
12441  }
12442 #elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
12443  // this check is precise, do not convert
12444  if (lua_isinteger(L_, index) == 1) {
12445  return true;
12446  }
12447  const bool success = false;
12448  if (!success) {
12449  // expected type, actual type
12450  handler(L_, index, type::number, type_of(L_, index), detail::not_a_number_integral);
12451  }
12452 #else
12453  // Numerics are neither safe nor string-convertible
12454  type t = type_of(L_, index);
12455  const bool success = t == type::number;
12456 #endif
12457  if (!success) {
12458  // expected type, actual type
12459  handler(L_, index, type::number, type_of(L_, index), detail::not_a_number);
12460  }
12461  return success;
12462 #else
12463  // Lua 5.2 and below checks
12464 #if SOL_IS_OFF(SOL_STRINGS_ARE_NUMBERS)
12465  // must pre-check, because it will convert
12466  type t = type_of(L_, index);
12467  if (t != type::number) {
12468  // expected type, actual type
12469  handler(L_, index, type::number, t, detail::not_a_number);
12470  return false;
12471  }
12472 #endif // Do not allow strings to be numbers
12473 
12474 #if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
12475  int isnum = 0;
12476  const lua_Number v = lua_tonumberx(L_, index, &isnum);
12477  const bool success = isnum != 0 && static_cast<lua_Number>(llround(v)) == v;
12478 #else
12479  const bool success = true;
12480 #endif // Safe numerics and number precision checking
12481  if (!success) {
12482  // Use defines to provide a better error message!
12483 #if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS)
12484  handler(L_, index, type::number, type_of(L_, index), detail::not_a_number_or_number_string);
12485 #elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
12486  handler(L_, index, type::number, t, detail::not_a_number_or_number_string);
12487 #else
12488  handler(L_, index, type::number, t, detail::not_a_number);
12489 #endif
12490  }
12491  return success;
12492 #endif
12493  }
12494  else if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, lua_Number>) {
12495  tracking.use(1);
12496 #if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS)
12497  bool success = lua_isnumber(L_, index) == 1;
12498  if (!success) {
12499  // expected type, actual type
12500  handler(L_, index, type::number, type_of(L_, index), detail::not_a_number_or_number_string);
12501  }
12502  return success;
12503 #else
12504  type t = type_of(L_, index);
12505  bool success = t == type::number;
12506  if (!success) {
12507  // expected type, actual type
12508  handler(L_, index, type::number, t, detail::not_a_number);
12509  }
12510  return success;
12511 #endif // Strings are Numbers
12512  }
12513  else if constexpr (meta::any_same_v<T, type, this_state, this_main_state, this_environment, variadic_args>) {
12514  (void)L_;
12515  (void)index;
12516  (void)handler;
12517  tracking.use(0);
12518  return true;
12519  }
12520  else if constexpr (is_unique_usertype_v<T>) {
12521  using element = unique_usertype_element_t<T>;
12522  using actual = unique_usertype_actual_t<T>;
12523  const type indextype = type_of(L_, index);
12524  tracking.use(1);
12525  if (indextype != type::userdata) {
12526  handler(L_, index, type::userdata, indextype, "value is not a userdata");
12527  return false;
12528  }
12529  if (lua_getmetatable(L_, index) == 0) {
12530  return true;
12531  }
12532  int metatableindex = lua_gettop(L_);
12533  if (stack_detail::check_metatable<d::u<element>>(L_, metatableindex)) {
12534  void* memory = lua_touserdata(L_, index);
12535  memory = detail::align_usertype_unique_destructor(memory);
12536  detail::unique_destructor& pdx = *static_cast<detail::unique_destructor*>(memory);
12537  bool success = &detail::usertype_unique_alloc_destroy<element, actual> == pdx;
12538  if (!success) {
12539  memory = detail::align_usertype_unique_tag<true>(memory);
12540 #if 0
12541  // New version, one day
12542 #else
12543  const char*& name_tag = *static_cast<const char**>(memory);
12544  success = usertype_traits<T>::qualified_name() == name_tag;
12545 #endif
12546  if (!success) {
12547  handler(L_, index, type::userdata, indextype, "value is a userdata but is not the correct unique usertype");
12548  }
12549  }
12550  return success;
12551  }
12552  lua_pop(L_, 1);
12553  handler(L_, index, type::userdata, indextype, "unrecognized userdata (not pushed by sol?)");
12554  return false;
12555  }
12556  else if constexpr (meta::any_same_v<T, lua_nil_t, std::nullopt_t, nullopt_t>) {
12557  bool success = lua_isnil(L_, index);
12558  if (success) {
12559  tracking.use(1);
12560  return success;
12561  }
12562  tracking.use(0);
12563  success = lua_isnone(L_, index);
12564  if (!success) {
12565  // expected type, actual type
12566  handler(L_, index, expected, type_of(L_, index), "");
12567  }
12568  return success;
12569  }
12570  else if constexpr (std::is_same_v<T, env_key_t>) {
12571  tracking.use(1);
12572  type t = type_of(L_, index);
12573  if (t == type::table || t == type::none || t == type::lua_nil || t == type::userdata) {
12574  return true;
12575  }
12576  handler(L_, index, type::table, t, "value cannot not have a valid environment");
12577  return true;
12578  }
12579  else if constexpr (std::is_same_v<T, detail::non_lua_nil_t>) {
12580  return !stack::unqualified_check<lua_nil_t>(L_, index, std::forward<Handler>(handler), tracking);
12581  }
12582  else if constexpr (meta::is_specialization_of_v<T, basic_lua_table>) {
12583  tracking.use(1);
12584  type t = type_of(L_, index);
12585  if (t != type::table) {
12586  handler(L_, index, type::table, t, "value is not a table");
12587  return false;
12588  }
12589  return true;
12590  }
12591  else if constexpr (meta::is_specialization_of_v<T, basic_bytecode>) {
12592  tracking.use(1);
12593  type t = type_of(L_, index);
12594  if (t != type::function) {
12595  handler(L_, index, type::function, t, "value is not a function that can be dumped");
12596  return false;
12597  }
12598  return true;
12599  }
12600  else if constexpr (meta::is_specialization_of_v<T, basic_environment>) {
12601  tracking.use(1);
12602  if (lua_getmetatable(L_, index) == 0) {
12603  return true;
12604  }
12605  type t = type_of(L_, -1);
12606  if (t == type::table || t == type::none || t == type::lua_nil) {
12607  lua_pop(L_, 1);
12608  return true;
12609  }
12610  if (t != type::userdata) {
12611  lua_pop(L_, 1);
12612  handler(L_, index, type::table, t, "value does not have a valid metatable");
12613  return false;
12614  }
12615  return true;
12616  }
12617  else if constexpr (std::is_same_v<T, metatable_key_t>) {
12618  tracking.use(1);
12619  if (lua_getmetatable(L_, index) == 0) {
12620  return true;
12621  }
12622  type t = type_of(L_, -1);
12623  if (t == type::table || t == type::none || t == type::lua_nil) {
12624  lua_pop(L_, 1);
12625  return true;
12626  }
12627  if (t != type::userdata) {
12628  lua_pop(L_, 1);
12629  handler(L_, index, expected, t, "value does not have a valid metatable");
12630  return false;
12631  }
12632  return true;
12633  }
12634  else if constexpr (std::is_same_v<T, luaL_Stream*> || std::is_same_v<T, luaL_Stream>) {
12635  if (lua_getmetatable(L_, index) == 0) {
12636  type t = type_of(L_, index);
12637  handler(L_, index, expected, t, "value is not a valid luaL_Stream (has no metatable/is not a valid value)");
12638  return false;
12639  }
12640  luaL_getmetatable(L_, LUA_FILEHANDLE);
12641  if (type_of(L_, index) != type::table) {
12642  type t = type_of(L_, index);
12643  lua_pop(L_, 1);
12644  handler(L_,
12645  index,
12646  expected,
12647  t,
12648  "value is not a valid luaL_Stream (there is no metatable for luaL_Stream -- did you forget to "
12649  "my_lua_state.open_libraries(sol::lib::state) or equivalent?)");
12650  return false;
12651  }
12652  int is_stream_table = lua_compare(L_, -1, -2, LUA_OPEQ);
12653  lua_pop(L_, 2);
12654  if (is_stream_table == 0) {
12655  type t = type_of(L_, index);
12656  handler(L_, index, expected, t, "value is not a valid luaL_Stream (incorrect metatable)");
12657  return false;
12658  }
12659  return true;
12660  }
12661  else if constexpr (meta::is_optional_v<T>) {
12662  using ValueType = typename T::value_type;
12663  (void)handler;
12664  type t = type_of(L_, index);
12665  if (t == type::none) {
12666  tracking.use(0);
12667  return true;
12668  }
12669  if (t == type::lua_nil) {
12670  tracking.use(1);
12671  return true;
12672  }
12673  return stack::unqualified_check<ValueType>(L_, index, &no_panic, tracking);
12674  }
12675 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
12676  else if constexpr (std::is_function_v<T> || (std::is_pointer_v<T> && std::is_function_v<std::remove_pointer_t<T>>)) {
12677  return stack_detail::check_function_pointer<std::remove_pointer_t<T>>(L_, index, std::forward<Handler>(handler), tracking);
12678  }
12679 #endif
12680  else if constexpr (expected == type::userdata) {
12681  if constexpr (meta::any_same_v<T, userdata_value> || meta::is_specialization_of_v<T, basic_userdata>) {
12682  tracking.use(1);
12683  type t = type_of(L_, index);
12684  bool success = t == type::userdata;
12685  if (!success) {
12686  // expected type, actual type
12687  handler(L_, index, type::userdata, t, "");
12688  }
12689  return success;
12690  }
12691  else if constexpr (meta::is_specialization_of_v<T, user>) {
12693  (void)c;
12694  return c.check(L_, index, std::forward<Handler>(handler), tracking);
12695  }
12696  else {
12697  if constexpr (std::is_pointer_v<T>) {
12698  return check_usertype<T>(L_, index, std::forward<Handler>(handler), tracking);
12699  }
12700  else if constexpr (meta::is_specialization_of_v<T, std::reference_wrapper>) {
12701  using T_internal = typename T::type;
12702  return stack::check<T_internal>(L_, index, std::forward<Handler>(handler), tracking);
12703  }
12704  else {
12705  return check_usertype<T>(L_, index, std::forward<Handler>(handler), tracking);
12706  }
12707  }
12708  }
12709  else if constexpr (expected == type::poly) {
12710  tracking.use(1);
12711  bool success = is_lua_reference_v<T> || !lua_isnone(L_, index);
12712  if (!success) {
12713  // expected type, actual type
12714  handler(L_, index, type::poly, type_of(L_, index), "");
12715  }
12716  return success;
12717  }
12718  else if constexpr (expected == type::lightuserdata) {
12719  tracking.use(1);
12720  type t = type_of(L_, index);
12721  bool success = t == type::userdata || t == type::lightuserdata;
12722  if (!success) {
12723  // expected type, actual type
12724  handler(L_, index, type::lightuserdata, t, "");
12725  }
12726  return success;
12727  }
12728  else if constexpr (expected == type::function) {
12729  if constexpr (meta::any_same_v<T, lua_CFunction, std::remove_pointer_t<lua_CFunction>, c_closure>) {
12730  tracking.use(1);
12731  bool success = lua_iscfunction(L_, index) == 1;
12732  if (!success) {
12733  // expected type, actual type
12734  handler(L_, index, expected, type_of(L_, index), "");
12735  }
12736  return success;
12737  }
12738  else {
12739  tracking.use(1);
12740  type t = type_of(L_, index);
12741  if (t == type::lua_nil || t == type::none || t == type::function) {
12742  // allow for lua_nil to be returned
12743  return true;
12744  }
12745  if (t != type::userdata && t != type::table) {
12746  handler(L_, index, type::function, t, "must be a function or table or a userdata");
12747  return false;
12748  }
12749  // Do advanced check for call-style userdata?
12750  static const auto& callkey = to_string(meta_function::call);
12751  if (lua_getmetatable(L_, index) == 0) {
12752  // No metatable, no __call key possible
12753  handler(L_, index, type::function, t, "value is not a function and does not have overriden metatable");
12754  return false;
12755  }
12756  if (lua_isnoneornil(L_, -1)) {
12757  lua_pop(L_, 1);
12758  handler(L_, index, type::function, t, "value is not a function and does not have valid metatable");
12759  return false;
12760  }
12761  lua_getfield(L_, -1, &callkey[0]);
12762  if (lua_isnoneornil(L_, -1)) {
12763  lua_pop(L_, 2);
12764  handler(L_, index, type::function, t, "value's metatable does not have __call overridden in metatable, cannot call this type");
12765  return false;
12766  }
12767  // has call, is definitely a function
12768  lua_pop(L_, 2);
12769  return true;
12770  }
12771  }
12772  else if constexpr (expected == type::table) {
12773  return stack::loose_table_check(L_, index, std::forward<Handler>(handler), tracking);
12774  }
12775  else {
12776  tracking.use(1);
12777  const type indextype = type_of(L_, index);
12778  bool success = expected == indextype;
12779  if (!success) {
12780  // expected type, actual type, message
12781  handler(L_, index, expected, indextype, "");
12782  }
12783  return success;
12784  }
12785  }
12786  };
12787 
12788  template <typename T>
12789  struct unqualified_checker<non_null<T>, type::userdata> : unqualified_checker<T, lua_type_of_v<T>> { };
12790 
12791  template <typename T>
12792  struct unqualified_checker<detail::as_value_tag<T>, type::userdata> {
12793  template <typename Handler>
12794  static bool check(lua_State* L_, int index, Handler&& handler, record& tracking) {
12795  const type indextype = type_of(L_, index);
12796  return check(types<T>(), L_, index, indextype, std::forward<Handler>(handler), tracking);
12797  }
12798 
12799  template <typename U, typename Handler>
12800  static bool check(types<U>, lua_State* L_, int index, type indextype, Handler&& handler, record& tracking) {
12801  if constexpr (
12802  std::is_same_v<T,
12803  lightuserdata_value> || std::is_same_v<T, userdata_value> || std::is_same_v<T, userdata> || std::is_same_v<T, lightuserdata>) {
12804  tracking.use(1);
12805  if (indextype != type::userdata) {
12806  handler(L_, index, type::userdata, indextype, "value is not a valid userdata");
12807  return false;
12808  }
12809  return true;
12810  }
12811  else {
12812 #if SOL_IS_ON(SOL_USE_INTEROP)
12813  if (stack_detail::interop_check<U>(L_, index, indextype, handler, tracking)) {
12814  return true;
12815  }
12816 #endif // interop extensibility
12817  tracking.use(1);
12818 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
12819  if (lua_iscfunction(L_, index) != 0) {
12820  // a potential match...
12821  return true;
12822  }
12823 #endif
12824  if (indextype != type::userdata) {
12825  handler(L_, index, type::userdata, indextype, "value is not a valid userdata");
12826  return false;
12827  }
12828  if (lua_getmetatable(L_, index) == 0) {
12829  return true;
12830  }
12831  int metatableindex = lua_gettop(L_);
12832  if (stack_detail::check_metatable<U>(L_, metatableindex))
12833  return true;
12834  if (stack_detail::check_metatable<U*>(L_, metatableindex))
12835  return true;
12836  if (stack_detail::check_metatable<d::u<U>>(L_, metatableindex))
12837  return true;
12838  if (stack_detail::check_metatable<as_container_t<U>>(L_, metatableindex))
12839  return true;
12840  bool success = false;
12841  bool has_derived = derive<T>::value || weak_derive<T>::value;
12842  if (has_derived) {
12843 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
12844  luaL_checkstack(L_, 1, detail::not_enough_stack_space_string);
12845 #endif // make sure stack doesn't overflow
12846  auto pn = stack::pop_n(L_, 1);
12847  lua_pushstring(L_, &detail::base_class_check_key()[0]);
12848  lua_rawget(L_, metatableindex);
12849  if (type_of(L_, -1) != type::lua_nil) {
12850  void* basecastdata = lua_touserdata(L_, -1);
12851  detail::inheritance_check_function ic = reinterpret_cast<detail::inheritance_check_function>(basecastdata);
12852  success = ic(usertype_traits<T>::qualified_name());
12853  }
12854  }
12855  lua_pop(L_, 1);
12856  if (!success) {
12857  handler(L_, index, type::userdata, indextype, "value at this index does not properly reflect the desired type");
12858  return false;
12859  }
12860  return true;
12861  }
12862  }
12863  };
12864 
12865  template <typename T>
12866  struct unqualified_checker<detail::as_pointer_tag<T>, type::userdata> {
12867  template <typename Handler>
12868  static bool check(lua_State* L_, int index, type indextype, Handler&& handler, record& tracking) {
12869  if (indextype == type::lua_nil) {
12870  tracking.use(1);
12871  return true;
12872  }
12873  return check_usertype<std::remove_pointer_t<T>>(L_, index, std::forward<Handler>(handler), tracking);
12874  }
12875 
12876  template <typename Handler>
12877  static bool check(lua_State* L_, int index, Handler&& handler, record& tracking) {
12878  const type indextype = type_of(L_, index);
12879  return check(L_, index, indextype, std::forward<Handler>(handler), tracking);
12880  }
12881  };
12882 
12883  template <typename... Args>
12884  struct unqualified_checker<std::tuple<Args...>, type::poly> {
12885  template <typename Handler>
12886  static bool check(lua_State* L_, int index, Handler&& handler, record& tracking) {
12887  return stack::multi_check<Args...>(L_, index, std::forward<Handler>(handler), tracking);
12888  }
12889  };
12890 
12891  template <typename A, typename B>
12892  struct unqualified_checker<std::pair<A, B>, type::poly> {
12893  template <typename Handler>
12894  static bool check(lua_State* L_, int index, Handler&& handler, record& tracking) {
12895  return stack::multi_check<A, B>(L_, index, std::forward<Handler>(handler), tracking);
12896  }
12897  };
12898 
12899 #if SOL_IS_ON(SOL_STD_VARIANT)
12900 
12901  template <typename... Tn>
12902  struct unqualified_checker<std::variant<Tn...>, type::poly> {
12903  typedef std::variant<Tn...> V;
12904  typedef std::variant_size<V> V_size;
12905  typedef std::integral_constant<bool, V_size::value == 0> V_is_empty;
12906 
12907  template <typename Handler>
12908  static bool is_one(std::integral_constant<std::size_t, 0>, lua_State* L_, int index, Handler&& handler, record& tracking) {
12909  if constexpr (V_is_empty::value) {
12910  if (lua_isnone(L_, index)) {
12911  return true;
12912  }
12913  }
12914  tracking.use(1);
12915  handler(L_, index, type::poly, type_of(L_, index), "value does not fit any type present in the variant");
12916  return false;
12917  }
12918 
12919  template <std::size_t I, typename Handler>
12920  static bool is_one(std::integral_constant<std::size_t, I>, lua_State* L_, int index, Handler&& handler, record& tracking) {
12921  typedef std::variant_alternative_t<I - 1, V> T;
12922  record temp_tracking = tracking;
12923  if (stack::check<T>(L_, index, &no_panic, temp_tracking)) {
12924  tracking = temp_tracking;
12925  return true;
12926  }
12927  return is_one(std::integral_constant<std::size_t, I - 1>(), L_, index, std::forward<Handler>(handler), tracking);
12928  }
12929 
12930  template <typename Handler>
12931  static bool check(lua_State* L_, int index, Handler&& handler, record& tracking) {
12932  return is_one(std::integral_constant<std::size_t, V_size::value>(), L_, index, std::forward<Handler>(handler), tracking);
12933  }
12934  };
12935 
12936 #endif // variant shenanigans
12937 
12938 }} // namespace sol::stack
12939 
12940 // end of sol/stack_check_unqualified.hpp
12941 
12942 // beginning of sol/stack_check_qualified.hpp
12943 
12944 namespace sol { namespace stack {
12945 
12946  template <typename X, type expected, typename>
12947  struct qualified_checker {
12948  template <typename Handler>
12949  static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
12950  using no_cv_X = meta::unqualified_t<X>;
12951  if constexpr (!std::is_reference_v<X> && is_unique_usertype_v<no_cv_X>) {
12952  using element = unique_usertype_element_t<no_cv_X>;
12953  if constexpr (is_actual_type_rebindable_for_v<no_cv_X>) {
12954  using rebound_actual_type = unique_usertype_rebind_actual_t<no_cv_X>;
12955  // we have a unique pointer type that can be
12956  // rebound to a base/derived type
12957  const type indextype = type_of(L, index);
12958  tracking.use(1);
12959  if (indextype != type::userdata) {
12960  handler(L, index, type::userdata, indextype, "value is not a userdata");
12961  return false;
12962  }
12963  void* memory = lua_touserdata(L, index);
12964  memory = detail::align_usertype_unique_destructor(memory);
12965  detail::unique_destructor& pdx = *static_cast<detail::unique_destructor*>(memory);
12966  if (&detail::usertype_unique_alloc_destroy<element, no_cv_X> == pdx) {
12967  return true;
12968  }
12969  if constexpr (derive<element>::value) {
12970  memory = detail::align_usertype_unique_tag<true, false>(memory);
12971  detail::unique_tag& ic = *reinterpret_cast<detail::unique_tag*>(memory);
12972  string_view ti = usertype_traits<element>::qualified_name();
12973  string_view rebind_ti = usertype_traits<rebound_actual_type>::qualified_name();
12974  if (ic(nullptr, nullptr, ti, rebind_ti) != 0) {
12975  return true;
12976  }
12977  }
12978  handler(L, index, type::userdata, indextype, "value is a userdata but is not the correct unique usertype");
12979  return false;
12980  }
12981  else {
12982  return stack::unqualified_check<X>(L, index, std::forward<Handler>(handler), tracking);
12983  }
12984  }
12985  else if constexpr (!std::is_reference_v<X> && is_container_v<no_cv_X>) {
12986  if (type_of(L, index) == type::userdata) {
12987  return stack::unqualified_check<X>(L, index, std::forward<Handler>(handler), tracking);
12988  }
12989  else {
12990  return stack::unqualified_check<nested<X>>(L, index, std::forward<Handler>(handler), tracking);
12991  }
12992  }
12993  else if constexpr (!std::is_reference_v<X> && meta::is_specialization_of_v<X, nested>) {
12994  using NestedX = typename meta::unqualified_t<X>::nested_type;
12995  return stack::check<NestedX>(L, index, ::std::forward<Handler>(handler), tracking);
12996  }
12997  else {
12998  return stack::unqualified_check<X>(L, index, std::forward<Handler>(handler), tracking);
12999  }
13000  }
13001  };
13002 }} // namespace sol::stack
13003 
13004 // end of sol/stack_check_qualified.hpp
13005 
13006 // end of sol/stack_check.hpp
13007 
13008 // beginning of sol/stack_get.hpp
13009 
13010 // beginning of sol/stack_get_unqualified.hpp
13011 
13012 // beginning of sol/overload.hpp
13013 
13014 #include <utility>
13015 
13016 namespace sol {
13017  template <typename... Functions>
13018  struct overload_set {
13019  std::tuple<Functions...> functions;
13020  template <typename Arg, typename... Args, meta::disable<std::is_same<overload_set, meta::unqualified_t<Arg>>> = meta::enabler>
13021  overload_set(Arg&& arg, Args&&... args) : functions(std::forward<Arg>(arg), std::forward<Args>(args)...) {
13022  }
13023  overload_set(const overload_set&) = default;
13024  overload_set(overload_set&&) = default;
13025  overload_set& operator=(const overload_set&) = default;
13026  overload_set& operator=(overload_set&&) = default;
13027  };
13028 
13029  template <typename... Args>
13030  decltype(auto) overload(Args&&... args) {
13031  return overload_set<std::decay_t<Args>...>(std::forward<Args>(args)...);
13032  }
13033 } // namespace sol
13034 
13035 // end of sol/overload.hpp
13036 
13037 // beginning of sol/unicode.hpp
13038 
13039 #include <array>
13040 #include <cstring>
13041 
13042 namespace sol {
13043  // Everything here was lifted pretty much straight out of
13044  // ogonek, because fuck figuring it out=
13045  namespace unicode {
13046  enum class error_code {
13047  ok = 0,
13048  invalid_code_point,
13049  invalid_code_unit,
13050  invalid_leading_surrogate,
13051  invalid_trailing_surrogate,
13052  sequence_too_short,
13053  overlong_sequence,
13054  };
13055 
13056  inline const string_view& to_string(error_code ec) {
13057  static const string_view storage[7] = { "ok",
13058  "invalid code points",
13059  "invalid code unit",
13060  "invalid leading surrogate",
13061  "invalid trailing surrogate",
13062  "sequence too short",
13063  "overlong sequence" };
13064  return storage[static_cast<std::size_t>(ec)];
13065  }
13066 
13067  template <typename It>
13069  error_code error;
13070  char32_t codepoint;
13071  It next;
13072  };
13073 
13074  template <typename C>
13076  error_code error;
13077  std::size_t code_units_size;
13078  std::array<C, 4> code_units;
13079  };
13080 
13082  // codepoint related
13083  static constexpr char32_t last_code_point = 0x10FFFF;
13084 
13085  static constexpr char32_t first_lead_surrogate = 0xD800;
13086  static constexpr char32_t last_lead_surrogate = 0xDBFF;
13087 
13088  static constexpr char32_t first_trail_surrogate = 0xDC00;
13089  static constexpr char32_t last_trail_surrogate = 0xDFFF;
13090 
13091  static constexpr char32_t first_surrogate = first_lead_surrogate;
13092  static constexpr char32_t last_surrogate = last_trail_surrogate;
13093 
13094  static constexpr bool is_lead_surrogate(char32_t u) {
13095  return u >= first_lead_surrogate && u <= last_lead_surrogate;
13096  }
13097  static constexpr bool is_trail_surrogate(char32_t u) {
13098  return u >= first_trail_surrogate && u <= last_trail_surrogate;
13099  }
13100  static constexpr bool is_surrogate(char32_t u) {
13101  return u >= first_surrogate && u <= last_surrogate;
13102  }
13103 
13104  // utf8 related
13105  static constexpr auto last_1byte_value = 0x7Fu;
13106  static constexpr auto last_2byte_value = 0x7FFu;
13107  static constexpr auto last_3byte_value = 0xFFFFu;
13108 
13109  static constexpr auto start_2byte_mask = 0x80u;
13110  static constexpr auto start_3byte_mask = 0xE0u;
13111  static constexpr auto start_4byte_mask = 0xF0u;
13112 
13113  static constexpr auto continuation_mask = 0xC0u;
13114  static constexpr auto continuation_signature = 0x80u;
13115 
13116  static constexpr bool is_invalid(unsigned char b) {
13117  return b == 0xC0 || b == 0xC1 || b > 0xF4;
13118  }
13119 
13120  static constexpr bool is_continuation(unsigned char b) {
13121  return (b & unicode_detail::continuation_mask) == unicode_detail::continuation_signature;
13122  }
13123 
13124  static constexpr bool is_overlong(char32_t u, std::size_t bytes) {
13125  return u <= unicode_detail::last_1byte_value || (u <= unicode_detail::last_2byte_value && bytes > 2)
13126  || (u <= unicode_detail::last_3byte_value && bytes > 3);
13127  }
13128 
13129  static constexpr int sequence_length(unsigned char b) {
13130  return (b & start_2byte_mask) == 0 ? 1
13131  : (b & start_3byte_mask) != start_3byte_mask ? 2
13132  : (b & start_4byte_mask) != start_4byte_mask ? 3
13133  : 4;
13134  }
13135 
13136  static constexpr char32_t decode(unsigned char b0, unsigned char b1) {
13137  return (static_cast<char32_t>((b0 & 0x1Fu) << 6u) | static_cast<char32_t>(b1 & 0x3Fu));
13138  }
13139  static constexpr char32_t decode(unsigned char b0, unsigned char b1, unsigned char b2) {
13140  return static_cast<char32_t>((b0 & 0x0Fu) << 12u) | static_cast<char32_t>((b1 & 0x3Fu) << 6u) | static_cast<char32_t>(b2 & 0x3Fu);
13141  }
13142  static constexpr char32_t decode(unsigned char b0, unsigned char b1, unsigned char b2, unsigned char b3) {
13143  return static_cast<char32_t>(static_cast<char32_t>((b0 & 0x07u) << 18u) | static_cast<char32_t>((b1 & 0x3F) << 12)
13144  | static_cast<char32_t>((b2 & 0x3Fu) << 6u) | static_cast<char32_t>(b3 & 0x3Fu));
13145  }
13146 
13147  // utf16 related
13148  static constexpr char32_t last_bmp_value = 0xFFFF;
13149  static constexpr char32_t normalizing_value = 0x10000;
13150  static constexpr int lead_surrogate_bitmask = 0xFFC00;
13151  static constexpr int trail_surrogate_bitmask = 0x3FF;
13152  static constexpr int lead_shifted_bits = 10;
13153  static constexpr char32_t replacement = 0xFFFD;
13154 
13155  static char32_t combine_surrogates(char16_t lead, char16_t trail) {
13156  auto hi = lead - first_lead_surrogate;
13157  auto lo = trail - first_trail_surrogate;
13158  return normalizing_value + ((hi << lead_shifted_bits) | lo);
13159  }
13160  };
13161 
13162  inline encoded_result<char> code_point_to_utf8(char32_t codepoint) {
13164  er.error = error_code::ok;
13165  if (codepoint <= unicode_detail::last_1byte_value) {
13166  er.code_units_size = 1;
13167  er.code_units = std::array<char, 4> { { static_cast<char>(codepoint) } };
13168  }
13169  else if (codepoint <= unicode_detail::last_2byte_value) {
13170  er.code_units_size = 2;
13171  er.code_units = std::array<char, 4> { {
13172  static_cast<char>(0xC0 | ((codepoint & 0x7C0) >> 6)),
13173  static_cast<char>(0x80 | (codepoint & 0x3F)),
13174  } };
13175  }
13176  else if (codepoint <= unicode_detail::last_3byte_value) {
13177  er.code_units_size = 3;
13178  er.code_units = std::array<char, 4> { {
13179  static_cast<char>(0xE0 | ((codepoint & 0xF000) >> 12)),
13180  static_cast<char>(0x80 | ((codepoint & 0xFC0) >> 6)),
13181  static_cast<char>(0x80 | (codepoint & 0x3F)),
13182  } };
13183  }
13184  else {
13185  er.code_units_size = 4;
13186  er.code_units = std::array<char, 4> { {
13187  static_cast<char>(0xF0 | ((codepoint & 0x1C0000) >> 18)),
13188  static_cast<char>(0x80 | ((codepoint & 0x3F000) >> 12)),
13189  static_cast<char>(0x80 | ((codepoint & 0xFC0) >> 6)),
13190  static_cast<char>(0x80 | (codepoint & 0x3F)),
13191  } };
13192  }
13193  return er;
13194  }
13195 
13196  inline encoded_result<char16_t> code_point_to_utf16(char32_t codepoint) {
13198 
13199  if (codepoint <= unicode_detail::last_bmp_value) {
13200  er.code_units_size = 1;
13201  er.code_units = std::array<char16_t, 4> { { static_cast<char16_t>(codepoint) } };
13202  er.error = error_code::ok;
13203  }
13204  else {
13205  auto normal = codepoint - unicode_detail::normalizing_value;
13206  auto lead = unicode_detail::first_lead_surrogate + ((normal & unicode_detail::lead_surrogate_bitmask) >> unicode_detail::lead_shifted_bits);
13207  auto trail = unicode_detail::first_trail_surrogate + (normal & unicode_detail::trail_surrogate_bitmask);
13208  er.code_units = std::array<char16_t, 4> { { static_cast<char16_t>(lead), static_cast<char16_t>(trail) } };
13209  er.code_units_size = 2;
13210  er.error = error_code::ok;
13211  }
13212  return er;
13213  }
13214 
13215  inline encoded_result<char32_t> code_point_to_utf32(char32_t codepoint) {
13217  er.code_units_size = 1;
13218  er.code_units[0] = codepoint;
13219  er.error = error_code::ok;
13220  return er;
13221  }
13222 
13223  template <typename It>
13224  inline decoded_result<It> utf8_to_code_point(It it, It last) {
13225  decoded_result<It> dr;
13226  if (it == last) {
13227  dr.next = it;
13228  dr.error = error_code::sequence_too_short;
13229  return dr;
13230  }
13231 
13232  unsigned char b0 = static_cast<unsigned char>(*it);
13233  std::size_t length = static_cast<std::size_t>(unicode_detail::sequence_length(b0));
13234 
13235  if (length == 1) {
13236  dr.codepoint = static_cast<char32_t>(b0);
13237  dr.error = error_code::ok;
13238  ++it;
13239  dr.next = it;
13240  return dr;
13241  }
13242 
13243  if (unicode_detail::is_invalid(b0) || unicode_detail::is_continuation(b0)) {
13244  dr.error = error_code::invalid_code_unit;
13245  dr.next = it;
13246  return dr;
13247  }
13248 
13249  ++it;
13250  std::array<unsigned char, 4> b;
13251  b[0] = b0;
13252  for (std::size_t i = 1; i < length; ++i) {
13253  b[i] = static_cast<unsigned char>(*it);
13254  if (!unicode_detail::is_continuation(b[i])) {
13255  dr.error = error_code::invalid_code_unit;
13256  dr.next = it;
13257  return dr;
13258  }
13259  ++it;
13260  }
13261 
13262  char32_t decoded;
13263  switch (length) {
13264  case 2:
13265  decoded = unicode_detail::decode(b[0], b[1]);
13266  break;
13267  case 3:
13268  decoded = unicode_detail::decode(b[0], b[1], b[2]);
13269  break;
13270  default:
13271  decoded = unicode_detail::decode(b[0], b[1], b[2], b[3]);
13272  break;
13273  }
13274 
13275  if (unicode_detail::is_overlong(decoded, length)) {
13276  dr.error = error_code::overlong_sequence;
13277  return dr;
13278  }
13279  if (unicode_detail::is_surrogate(decoded) || decoded > unicode_detail::last_code_point) {
13280  dr.error = error_code::invalid_code_point;
13281  return dr;
13282  }
13283 
13284  // then everything is fine
13285  dr.codepoint = decoded;
13286  dr.error = error_code::ok;
13287  dr.next = it;
13288  return dr;
13289  }
13290 
13291  template <typename It>
13292  inline decoded_result<It> utf16_to_code_point(It it, It last) {
13293  decoded_result<It> dr;
13294  if (it == last) {
13295  dr.next = it;
13296  dr.error = error_code::sequence_too_short;
13297  return dr;
13298  }
13299 
13300  char16_t lead = static_cast<char16_t>(*it);
13301 
13302  if (!unicode_detail::is_surrogate(lead)) {
13303  ++it;
13304  dr.codepoint = static_cast<char32_t>(lead);
13305  dr.next = it;
13306  dr.error = error_code::ok;
13307  return dr;
13308  }
13309  if (!unicode_detail::is_lead_surrogate(lead)) {
13310  dr.error = error_code::invalid_leading_surrogate;
13311  dr.next = it;
13312  return dr;
13313  }
13314 
13315  ++it;
13316  auto trail = *it;
13317  if (!unicode_detail::is_trail_surrogate(trail)) {
13318  dr.error = error_code::invalid_trailing_surrogate;
13319  dr.next = it;
13320  return dr;
13321  }
13322 
13323  dr.codepoint = unicode_detail::combine_surrogates(lead, trail);
13324  dr.next = ++it;
13325  dr.error = error_code::ok;
13326  return dr;
13327  }
13328 
13329  template <typename It>
13330  inline decoded_result<It> utf32_to_code_point(It it, It last) {
13331  decoded_result<It> dr;
13332  if (it == last) {
13333  dr.next = it;
13334  dr.error = error_code::sequence_too_short;
13335  return dr;
13336  }
13337  dr.codepoint = static_cast<char32_t>(*it);
13338  dr.next = ++it;
13339  dr.error = error_code::ok;
13340  return dr;
13341  }
13342  } // namespace unicode
13343 } // namespace sol
13344 // end of sol/unicode.hpp
13345 
13346 #include <memory>
13347 #include <functional>
13348 #include <utility>
13349 #include <cstdlib>
13350 #include <cmath>
13351 #include <string_view>
13352 #if SOL_IS_ON(SOL_STD_VARIANT)
13353 #include <variant>
13354 #endif // Apple clang screwed up
13355 
13356 namespace sol { namespace stack {
13357 
13358  namespace stack_detail {
13359  template <typename Ch>
13361  std::size_t needed_size;
13362 
13363  count_code_units_utf() : needed_size(0) {
13364  }
13365 
13366  void operator()(const unicode::encoded_result<Ch> er) {
13367  needed_size += er.code_units_size;
13368  }
13369  };
13370 
13371  template <typename Ch, typename ErCh>
13373  Ch* target_;
13374 
13375  copy_code_units_utf(Ch* target) : target_(target) {
13376  }
13377 
13378  void operator()(const unicode::encoded_result<ErCh> er) {
13379  std::memcpy(target_, er.code_units.data(), er.code_units_size * sizeof(ErCh));
13380  target_ += er.code_units_size;
13381  }
13382  };
13383 
13384  template <typename Ch, typename F>
13385  inline void convert(const char* strb, const char* stre, F&& f) {
13386  char32_t cp = 0;
13387  for (const char* strtarget = strb; strtarget < stre;) {
13388  auto dr = unicode::utf8_to_code_point(strtarget, stre);
13389  if (dr.error != unicode::error_code::ok) {
13390  cp = unicode::unicode_detail::replacement;
13391  ++strtarget;
13392  }
13393  else {
13394  cp = dr.codepoint;
13395  strtarget = dr.next;
13396  }
13397  if constexpr (std::is_same_v<Ch, char32_t>) {
13398  auto er = unicode::code_point_to_utf32(cp);
13399  f(er);
13400  }
13401  else {
13402  auto er = unicode::code_point_to_utf16(cp);
13403  f(er);
13404  }
13405  }
13406  }
13407 
13408  template <typename BaseCh, typename S>
13409  inline S get_into(lua_State* L, int index, record& tracking) {
13410  using Ch = typename S::value_type;
13411  tracking.use(1);
13412  size_t len;
13413  auto utf8p = lua_tolstring(L, index, &len);
13414  if (len < 1)
13415  return S();
13416  const char* strb = utf8p;
13417  const char* stre = utf8p + len;
13419  convert<BaseCh>(strb, stre, count_units);
13420  S r(count_units.needed_size, static_cast<Ch>(0));
13421  r.resize(count_units.needed_size);
13422  Ch* target = &r[0];
13424  convert<BaseCh>(strb, stre, copy_units);
13425  return r;
13426  }
13427  } // namespace stack_detail
13428 
13429  template <typename T, typename>
13430  struct unqualified_getter {
13431  static decltype(auto) get(lua_State* L, int index, record& tracking) {
13432  if constexpr (std::is_same_v<T, bool>) {
13433  tracking.use(1);
13434  return lua_toboolean(L, index) != 0;
13435  }
13436  else if constexpr (std::is_enum_v<T>) {
13437  tracking.use(1);
13438  return static_cast<T>(lua_tointegerx(L, index, nullptr));
13439  }
13440  else if constexpr (std::is_integral_v<T> || std::is_same_v<T, lua_Integer>) {
13441  tracking.use(1);
13442 #if SOL_LUA_VERSION_I_ >= 503
13443  if (lua_isinteger(L, index) != 0) {
13444  return static_cast<T>(lua_tointeger(L, index));
13445  }
13446 #endif
13447  return static_cast<T>(llround(lua_tonumber(L, index)));
13448  }
13449  else if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, lua_Number>) {
13450  tracking.use(1);
13451  return static_cast<T>(lua_tonumber(L, index));
13452  }
13453  else if constexpr (is_lua_reference_v<T>) {
13454  if constexpr (is_global_table_v<T>) {
13455  tracking.use(1);
13456  return T(L, global_tag);
13457  }
13458  else {
13459  tracking.use(1);
13460  return T(L, index);
13461  }
13462  }
13463  else if constexpr (is_unique_usertype_v<T>) {
13464  using actual = unique_usertype_actual_t<T>;
13465 
13466  tracking.use(1);
13467  void* memory = lua_touserdata(L, index);
13468  void* aligned_memory = detail::align_usertype_unique<actual>(memory);
13469  actual* typed_memory = static_cast<actual*>(aligned_memory);
13470  return *typed_memory;
13471  }
13472  else if constexpr (meta::is_optional_v<T>) {
13473  using ValueType = typename T::value_type;
13474  return unqualified_check_getter<ValueType>::template get_using<T>(L, index, &no_panic, tracking);
13475  }
13476  else if constexpr (std::is_same_v<T, luaL_Stream*>) {
13477  luaL_Stream* pstream = static_cast<luaL_Stream*>(lua_touserdata(L, index));
13478  return pstream;
13479  }
13480  else if constexpr (std::is_same_v<T, luaL_Stream>) {
13481  luaL_Stream* pstream = static_cast<luaL_Stream*>(lua_touserdata(L, index));
13482  return *pstream;
13483  }
13484 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
13485  else if constexpr (std::is_function_v<T> || (std::is_pointer_v<T> && std::is_function_v<std::remove_pointer_t<T>>)) {
13486  return stack_detail::get_function_pointer<std::remove_pointer_t<T>>(L, index, tracking);
13487  }
13488 #endif
13489  else {
13490  return stack_detail::unchecked_unqualified_get<detail::as_value_tag<T>>(L, index, tracking);
13491  }
13492  }
13493  };
13494 
13495  template <typename X, typename>
13496  struct qualified_getter {
13497  static decltype(auto) get(lua_State* L, int index, record& tracking) {
13498  using Tu = meta::unqualified_t<X>;
13499  static constexpr bool is_userdata_of_some_kind
13500  = !std::is_reference_v<
13501  X> && is_container_v<Tu> && std::is_default_constructible_v<Tu> && !is_lua_primitive_v<Tu> && !is_transparent_argument_v<Tu>;
13502  if constexpr (is_userdata_of_some_kind) {
13503  if (type_of(L, index) == type::userdata) {
13504  return static_cast<Tu>(stack_detail::unchecked_unqualified_get<Tu>(L, index, tracking));
13505  }
13506  else {
13507  return stack_detail::unchecked_unqualified_get<sol::nested<Tu>>(L, index, tracking);
13508  }
13509  }
13510  else if constexpr (!std::is_reference_v<X> && is_unique_usertype_v<Tu> && !is_actual_type_rebindable_for_v<Tu>) {
13511  using element = unique_usertype_element_t<Tu>;
13512  using actual = unique_usertype_actual_t<Tu>;
13513  tracking.use(1);
13514  void* memory = lua_touserdata(L, index);
13515  memory = detail::align_usertype_unique_destructor(memory);
13516  detail::unique_destructor& pdx = *static_cast<detail::unique_destructor*>(memory);
13517  if (&detail::usertype_unique_alloc_destroy<element, Tu> == pdx) {
13518  memory = detail::align_usertype_unique_tag<true, false>(memory);
13519  memory = detail::align_usertype_unique<actual, true, false>(memory);
13520  actual* mem = static_cast<actual*>(memory);
13521  return static_cast<actual>(*mem);
13522  }
13523  actual r {};
13524  if constexpr (!derive<element>::value) {
13525 #if SOL_IS_ON(SOL_DEBUG_BUILD)
13526  // In debug mode we would rather abort you for this grave failure rather
13527  // than let you deref a null pointer and fuck everything over
13528  std::abort();
13529 #endif
13530  return static_cast<actual>(std::move(r));
13531  }
13532  else {
13533  memory = detail::align_usertype_unique_tag<true, false>(memory);
13534  detail::unique_tag& ic = *reinterpret_cast<detail::unique_tag*>(memory);
13535  memory = detail::align_usertype_unique<actual, true, false>(memory);
13536  string_view ti = usertype_traits<element>::qualified_name();
13537  int cast_operation;
13538  if constexpr (is_actual_type_rebindable_for_v<Tu>) {
13539  using rebound_actual_type = unique_usertype_rebind_actual_t<Tu, void>;
13540  string_view rebind_ti = usertype_traits<rebound_actual_type>::qualified_name();
13541  cast_operation = ic(memory, &r, ti, rebind_ti);
13542  }
13543  else {
13544  string_view rebind_ti("");
13545  cast_operation = ic(memory, &r, ti, rebind_ti);
13546  }
13547  switch (cast_operation) {
13548  case 1: {
13549  // it's a perfect match,
13550  // alias memory directly
13551  actual* mem = static_cast<actual*>(memory);
13552  return static_cast<actual>(*mem);
13553  }
13554  case 2:
13555  // it's a base match, return the
13556  // aliased creation
13557  return static_cast<actual>(std::move(r));
13558  default:
13559  // uh oh..
13560  break;
13561  }
13562 #if SOL_IS_ON(SOL_DEBUG_BUILD)
13563  // In debug mode we would rather abort you for this grave failure rather
13564  // than let you deref a null pointer and fuck everything over
13565  std::abort();
13566 #endif
13567  return static_cast<actual>(r);
13568  }
13569  }
13570  else {
13571  return stack_detail::unchecked_unqualified_get<Tu>(L, index, tracking);
13572  }
13573  }
13574  };
13575 
13576  template <typename T>
13578  using Tu = meta::unqualified_t<T>;
13579 
13580  template <typename V>
13581  static void push_back_at_end(std::true_type, types<V>, lua_State* L, T& cont, std::size_t) {
13582  cont.push_back(stack::get<V>(L, -lua_size<V>::value));
13583  }
13584 
13585  template <typename V>
13586  static void push_back_at_end(std::false_type, types<V> t, lua_State* L, T& cont, std::size_t idx) {
13587  insert_at_end(meta::has_insert<Tu>(), t, L, cont, idx);
13588  }
13589 
13590  template <typename V>
13591  static void insert_at_end(std::true_type, types<V>, lua_State* L, T& cont, std::size_t) {
13592  using std::cend;
13593  cont.insert(cend(cont), stack::get<V>(L, -lua_size<V>::value));
13594  }
13595 
13596  template <typename V>
13597  static void insert_at_end(std::false_type, types<V>, lua_State* L, T& cont, std::size_t idx) {
13598  cont[idx] = stack::get<V>(L, -lua_size<V>::value);
13599  }
13600 
13601  static bool max_size_check(std::false_type, T&, std::size_t) {
13602  return false;
13603  }
13604 
13605  static bool max_size_check(std::true_type, T& cont, std::size_t idx) {
13606  return idx >= cont.max_size();
13607  }
13608 
13609  static T get(lua_State* L, int relindex, record& tracking) {
13610  return get(meta::is_associative<Tu>(), L, relindex, tracking);
13611  }
13612 
13613  static T get(std::false_type, lua_State* L, int relindex, record& tracking) {
13614  typedef typename Tu::value_type V;
13615  return get(types<V>(), L, relindex, tracking);
13616  }
13617 
13618  template <typename V>
13619  static T get(types<V> t, lua_State* L, int relindex, record& tracking) {
13620  tracking.use(1);
13621 
13622  // the W4 flag is really great,
13623  // so great that it can tell my for loops (twice nested)
13624  // below never actually terminate
13625  // without hitting where the gotos have infested
13626 
13627  // so now I would get the error W4XXX unreachable
13628  // me that the return cont at the end of this function
13629  // which is fair until other compilers complain
13630  // that there isn't a return and that based on
13631  // SOME MAGICAL FORCE
13632  // control flow falls off the end of a non-void function
13633  // so it needs to be there for the compilers that are
13634  // too flimsy to analyze the basic blocks...
13635  // (I'm sure I should file a bug but those compilers are already
13636  // in the wild; it doesn't matter if I fix them,
13637  // someone else is still going to get some old-ass compiler
13638  // and then bother me about the unclean build for the 30th
13639  // time)
13640 
13641  // "Why not an IIFE?"
13642  // Because additional lambdas / functions which serve as
13643  // capture-all-and-then-invoke bloat binary sizes
13644  // by an actually detectable amount
13645  // (one user uses sol2 pretty heavily and 22 MB of binary size
13646  // was saved by reducing reliance on lambdas in templates)
13647 
13648  // This would really be solved by having break N;
13649  // be a real, proper thing...
13650  // but instead, we have to use labels and gotos
13651  // and earn the universal vitriol of the dogmatic
13652  // programming community
13653 
13654  // all in all: W4 is great!~
13655 
13656  int index = lua_absindex(L, relindex);
13657  T cont;
13658  std::size_t idx = 0;
13659 #if SOL_LUA_VERSION_I_ >= 503
13660  // This method is HIGHLY performant over regular table iteration
13661  // thanks to the Lua API changes in 5.3
13662  // Questionable in 5.4
13663  for (lua_Integer i = 0;; i += lua_size<V>::value) {
13664  if (max_size_check(meta::has_max_size<Tu>(), cont, idx)) {
13665  // see above comment
13666  goto done;
13667  }
13668  bool isnil = false;
13669  for (int vi = 0; vi < lua_size<V>::value; ++vi) {
13670 #if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES) && SOL_LUA_VERSION_I_ >= 600
13671 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
13672  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
13673 #endif // make sure stack doesn't overflow
13674  lua_pushinteger(L, static_cast<lua_Integer>(i + vi));
13675  if (lua_keyin(L, index) == 0) {
13676  // it's time to stop
13677  isnil = true;
13678  }
13679  else {
13680  // we have a key, have to get the value
13681  lua_geti(L, index, i + vi);
13682  }
13683 #else
13684  type vt = static_cast<type>(lua_geti(L, index, i + vi));
13685  isnil = vt == type::none || vt == type::lua_nil;
13686 #endif
13687  if (isnil) {
13688  if (i == 0) {
13689  break;
13690  }
13691 #if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES) && SOL_LUA_VERSION_I_ >= 600
13692  lua_pop(L, vi);
13693 #else
13694  lua_pop(L, (vi + 1));
13695 #endif
13696  // see above comment
13697  goto done;
13698  }
13699  }
13700  if (isnil) {
13701 #if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES) && SOL_LUA_VERSION_I_ >= 600
13702 #else
13703  lua_pop(L, lua_size<V>::value);
13704 #endif
13705  continue;
13706  }
13707 
13708  push_back_at_end(meta::has_push_back<Tu>(), t, L, cont, idx);
13709  ++idx;
13710  lua_pop(L, lua_size<V>::value);
13711  }
13712 #else
13713  // Zzzz slower but necessary thanks to the lower version API and missing functions qq
13714  for (lua_Integer i = 0;; i += lua_size<V>::value, lua_pop(L, lua_size<V>::value)) {
13715  if (idx >= cont.max_size()) {
13716  // see above comment
13717  goto done;
13718  }
13719 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
13720  luaL_checkstack(L, 2, detail::not_enough_stack_space_generic);
13721 #endif // make sure stack doesn't overflow
13722  bool isnil = false;
13723  for (int vi = 0; vi < lua_size<V>::value; ++vi) {
13724  lua_pushinteger(L, i);
13725  lua_gettable(L, index);
13726  type vt = type_of(L, -1);
13727  isnil = vt == type::lua_nil;
13728  if (isnil) {
13729  if (i == 0) {
13730  break;
13731  }
13732  lua_pop(L, (vi + 1));
13733  // see above comment
13734  goto done;
13735  }
13736  }
13737  if (isnil)
13738  continue;
13739  push_back_at_end(meta::has_push_back<Tu>(), t, L, cont, idx);
13740  ++idx;
13741  }
13742 #endif
13743  done:
13744  return cont;
13745  }
13746 
13747  static T get(std::true_type, lua_State* L, int index, record& tracking) {
13748  typedef typename Tu::value_type P;
13749  typedef typename P::first_type K;
13750  typedef typename P::second_type V;
13751  return get(types<K, V>(), L, index, tracking);
13752  }
13753 
13754  template <typename K, typename V>
13755  static T get(types<K, V>, lua_State* L, int relindex, record& tracking) {
13756  tracking.use(1);
13757 
13758 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
13759  luaL_checkstack(L, 3, detail::not_enough_stack_space_generic);
13760 #endif // make sure stack doesn't overflow
13761 
13762  T associative;
13763  int index = lua_absindex(L, relindex);
13764  lua_pushnil(L);
13765  while (lua_next(L, index) != 0) {
13766  decltype(auto) key = stack::check_get<K>(L, -2);
13767  if (!key) {
13768  lua_pop(L, 1);
13769  continue;
13770  }
13771  associative.emplace(std::forward<decltype(*key)>(*key), stack::get<V>(L, -1));
13772  lua_pop(L, 1);
13773  }
13774  return associative;
13775  }
13776  };
13777 
13778  template <typename T, typename Al>
13779  struct unqualified_getter<as_table_t<std::forward_list<T, Al>>> {
13780  typedef std::forward_list<T, Al> C;
13781 
13782  static C get(lua_State* L, int relindex, record& tracking) {
13783  return get(meta::has_key_value_pair<C>(), L, relindex, tracking);
13784  }
13785 
13786  static C get(std::true_type, lua_State* L, int index, record& tracking) {
13787  typedef typename T::value_type P;
13788  typedef typename P::first_type K;
13789  typedef typename P::second_type V;
13790  return get(types<K, V>(), L, index, tracking);
13791  }
13792 
13793  static C get(std::false_type, lua_State* L, int relindex, record& tracking) {
13794  typedef typename C::value_type V;
13795  return get(types<V>(), L, relindex, tracking);
13796  }
13797 
13798  template <typename V>
13799  static C get(types<V>, lua_State* L, int relindex, record& tracking) {
13800  tracking.use(1);
13801 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
13802  luaL_checkstack(L, 3, detail::not_enough_stack_space_generic);
13803 #endif // make sure stack doesn't overflow
13804 
13805  int index = lua_absindex(L, relindex);
13806  C cont;
13807  auto at = cont.cbefore_begin();
13808  std::size_t idx = 0;
13809 #if SOL_LUA_VERSION_I_ >= 503
13810  // This method is HIGHLY performant over regular table iteration thanks to the Lua API changes in 5.3
13811  for (lua_Integer i = 0;; i += lua_size<V>::value, lua_pop(L, lua_size<V>::value)) {
13812  if (idx >= cont.max_size()) {
13813  goto done;
13814  }
13815  bool isnil = false;
13816  for (int vi = 0; vi < lua_size<V>::value; ++vi) {
13817  type t = static_cast<type>(lua_geti(L, index, i + vi));
13818  isnil = t == type::lua_nil;
13819  if (isnil) {
13820  if (i == 0) {
13821  break;
13822  }
13823  lua_pop(L, (vi + 1));
13824  goto done;
13825  }
13826  }
13827  if (isnil)
13828  continue;
13829  at = cont.insert_after(at, stack::get<V>(L, -lua_size<V>::value));
13830  ++idx;
13831  }
13832 #else
13833  // Zzzz slower but necessary thanks to the lower version API and missing functions qq
13834  for (lua_Integer i = 0;; i += lua_size<V>::value, lua_pop(L, lua_size<V>::value)) {
13835  if (idx >= cont.max_size()) {
13836  goto done;
13837  }
13838  bool isnil = false;
13839  for (int vi = 0; vi < lua_size<V>::value; ++vi) {
13840  lua_pushinteger(L, i);
13841  lua_gettable(L, index);
13842  type t = type_of(L, -1);
13843  isnil = t == type::lua_nil;
13844  if (isnil) {
13845  if (i == 0) {
13846  break;
13847  }
13848  lua_pop(L, (vi + 1));
13849  goto done;
13850  }
13851  }
13852  if (isnil)
13853  continue;
13854  at = cont.insert_after(at, stack::get<V>(L, -lua_size<V>::value));
13855  ++idx;
13856  }
13857 #endif
13858  done:
13859  return cont;
13860  }
13861 
13862  template <typename K, typename V>
13863  static C get(types<K, V>, lua_State* L, int relindex, record& tracking) {
13864  tracking.use(1);
13865 
13866 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
13867  luaL_checkstack(L, 3, detail::not_enough_stack_space_generic);
13868 #endif // make sure stack doesn't overflow
13869 
13870  C associative;
13871  auto at = associative.cbefore_begin();
13872  int index = lua_absindex(L, relindex);
13873  lua_pushnil(L);
13874  while (lua_next(L, index) != 0) {
13875  decltype(auto) key = stack::check_get<K>(L, -2);
13876  if (!key) {
13877  lua_pop(L, 1);
13878  continue;
13879  }
13880  at = associative.emplace_after(at, std::forward<decltype(*key)>(*key), stack::get<V>(L, -1));
13881  lua_pop(L, 1);
13882  }
13883  return associative;
13884  }
13885  };
13886 
13887  template <typename T>
13889  static T get(lua_State* L, int index, record& tracking) {
13890  using Tu = meta::unqualified_t<T>;
13891  if constexpr (is_container_v<Tu>) {
13892  if constexpr (meta::is_associative<Tu>::value) {
13893  typedef typename T::value_type P;
13894  typedef typename P::first_type K;
13895  typedef typename P::second_type V;
13897  return g.get(types<K, nested<V>>(), L, index, tracking);
13898  }
13899  else {
13900  typedef typename T::value_type V;
13902  return g.get(types<nested<V>>(), L, index, tracking);
13903  }
13904  }
13905  else {
13907  return g.get(L, index, tracking);
13908  }
13909  }
13910  };
13911 
13912  template <typename T>
13914  static decltype(auto) get(lua_State* L, int index, record& tracking) {
13915  return stack::unqualified_get<T>(L, index, tracking);
13916  }
13917  };
13918 
13919  template <typename T>
13921  static decltype(auto) get(lua_State* L, int index, record& tracking) {
13922  return stack::unqualified_get<T*>(L, index, tracking);
13923  }
13924  };
13925 
13926  template <>
13928  static userdata_value get(lua_State* L, int index, record& tracking) {
13929  tracking.use(1);
13930  return userdata_value(lua_touserdata(L, index));
13931  }
13932  };
13933 
13934  template <>
13936  static lightuserdata_value get(lua_State* L, int index, record& tracking) {
13937  tracking.use(1);
13938  return lightuserdata_value(lua_touserdata(L, index));
13939  }
13940  };
13941 
13942  template <typename T>
13944  static light<T> get(lua_State* L, int index, record& tracking) {
13945  tracking.use(1);
13946  void* memory = lua_touserdata(L, index);
13947  return light<T>(static_cast<T*>(memory));
13948  }
13949  };
13950 
13951  template <typename T>
13953  static std::add_lvalue_reference_t<T> get(lua_State* L, int index, record& tracking) {
13954  tracking.use(1);
13955  void* memory = lua_touserdata(L, index);
13956  memory = detail::align_user<T>(memory);
13957  return *static_cast<std::remove_reference_t<T>*>(memory);
13958  }
13959  };
13960 
13961  template <typename T>
13962  struct unqualified_getter<user<T*>> {
13963  static T* get(lua_State* L, int index, record& tracking) {
13964  tracking.use(1);
13965  void* memory = lua_touserdata(L, index);
13966  memory = detail::align_user<T*>(memory);
13967  return static_cast<T*>(memory);
13968  }
13969  };
13970 
13971  template <>
13972  struct unqualified_getter<type> {
13973  static type get(lua_State* L, int index, record& tracking) {
13974  tracking.use(1);
13975  return static_cast<type>(lua_type(L, index));
13976  }
13977  };
13978 
13979  template <>
13980  struct unqualified_getter<std::string> {
13981  static std::string get(lua_State* L, int index, record& tracking) {
13982  tracking.use(1);
13983  std::size_t len;
13984  auto str = lua_tolstring(L, index, &len);
13985  return std::string(str, len);
13986  }
13987  };
13988 
13989  template <>
13990  struct unqualified_getter<const char*> {
13991  static const char* get(lua_State* L, int index, record& tracking) {
13992  tracking.use(1);
13993  size_t sz;
13994  return lua_tolstring(L, index, &sz);
13995  }
13996  };
13997 
13998  template <>
13999  struct unqualified_getter<char> {
14000  static char get(lua_State* L, int index, record& tracking) {
14001  tracking.use(1);
14002  size_t len;
14003  auto str = lua_tolstring(L, index, &len);
14004  return len > 0 ? str[0] : '\0';
14005  }
14006  };
14007 
14008  template <typename Traits>
14009  struct unqualified_getter<basic_string_view<char, Traits>> {
14010  static string_view get(lua_State* L, int index, record& tracking) {
14011  tracking.use(1);
14012  size_t sz;
14013  const char* str = lua_tolstring(L, index, &sz);
14014  return basic_string_view<char, Traits>(str, sz);
14015  }
14016  };
14017 
14018  template <typename Traits, typename Al>
14019  struct unqualified_getter<std::basic_string<wchar_t, Traits, Al>> {
14020  using S = std::basic_string<wchar_t, Traits, Al>;
14021  static S get(lua_State* L, int index, record& tracking) {
14022  using Ch = meta::conditional_t<sizeof(wchar_t) == 2, char16_t, char32_t>;
14023  return stack_detail::get_into<Ch, S>(L, index, tracking);
14024  }
14025  };
14026 
14027  template <typename Traits, typename Al>
14028  struct unqualified_getter<std::basic_string<char16_t, Traits, Al>> {
14029  static std::basic_string<char16_t, Traits, Al> get(lua_State* L, int index, record& tracking) {
14030  return stack_detail::get_into<char16_t, std::basic_string<char16_t, Traits, Al>>(L, index, tracking);
14031  }
14032  };
14033 
14034  template <typename Traits, typename Al>
14035  struct unqualified_getter<std::basic_string<char32_t, Traits, Al>> {
14036  static std::basic_string<char32_t, Traits, Al> get(lua_State* L, int index, record& tracking) {
14037  return stack_detail::get_into<char32_t, std::basic_string<char32_t, Traits, Al>>(L, index, tracking);
14038  }
14039  };
14040 
14041  template <>
14042  struct unqualified_getter<char16_t> {
14043  static char16_t get(lua_State* L, int index, record& tracking) {
14044  string_view utf8 = stack::get<string_view>(L, index, tracking);
14045  const char* strb = utf8.data();
14046  const char* stre = utf8.data() + utf8.size();
14047  char32_t cp = 0;
14048  auto dr = unicode::utf8_to_code_point(strb, stre);
14049  if (dr.error != unicode::error_code::ok) {
14050  cp = unicode::unicode_detail::replacement;
14051  }
14052  else {
14053  cp = dr.codepoint;
14054  }
14055  auto er = unicode::code_point_to_utf16(cp);
14056  return er.code_units[0];
14057  }
14058  };
14059 
14060  template <>
14061  struct unqualified_getter<char32_t> {
14062  static char32_t get(lua_State* L, int index, record& tracking) {
14063  string_view utf8 = stack::get<string_view>(L, index, tracking);
14064  const char* strb = utf8.data();
14065  const char* stre = utf8.data() + utf8.size();
14066  char32_t cp = 0;
14067  auto dr = unicode::utf8_to_code_point(strb, stre);
14068  if (dr.error != unicode::error_code::ok) {
14069  cp = unicode::unicode_detail::replacement;
14070  }
14071  else {
14072  cp = dr.codepoint;
14073  }
14074  auto er = unicode::code_point_to_utf32(cp);
14075  return er.code_units[0];
14076  }
14077  };
14078 
14079  template <>
14080  struct unqualified_getter<wchar_t> {
14081  static wchar_t get(lua_State* L, int index, record& tracking) {
14082  typedef meta::conditional_t<sizeof(wchar_t) == 2, char16_t, char32_t> Ch;
14084  (void)g;
14085  auto c = g.get(L, index, tracking);
14086  return static_cast<wchar_t>(c);
14087  }
14088  };
14089 
14090  template <>
14091  struct unqualified_getter<meta_function> {
14092  static meta_function get(lua_State* L, int index, record& tracking) {
14093  tracking.use(1);
14094  const char* name = unqualified_getter<const char*> {}.get(L, index, tracking);
14095  const auto& mfnames = meta_function_names();
14096  for (std::size_t i = 0; i < mfnames.size(); ++i)
14097  if (mfnames[i] == name)
14098  return static_cast<meta_function>(i);
14099  return meta_function::construct;
14100  }
14101  };
14102 
14103  template <>
14105  static lua_nil_t get(lua_State*, int, record& tracking) {
14106  tracking.use(1);
14107  return lua_nil;
14108  }
14109  };
14110 
14111  template <>
14112  struct unqualified_getter<std::nullptr_t> {
14113  static std::nullptr_t get(lua_State*, int, record& tracking) {
14114  tracking.use(1);
14115  return nullptr;
14116  }
14117  };
14118 
14119  template <>
14120  struct unqualified_getter<nullopt_t> {
14121  static nullopt_t get(lua_State*, int, record& tracking) {
14122  tracking.use(1);
14123  return nullopt;
14124  }
14125  };
14126 
14127  template <>
14129  static this_state get(lua_State* L, int, record& tracking) {
14130  tracking.use(0);
14131  return this_state(L);
14132  }
14133  };
14134 
14135  template <>
14137  static this_main_state get(lua_State* L, int, record& tracking) {
14138  tracking.use(0);
14139  return this_main_state(main_thread(L, L));
14140  }
14141  };
14142 
14143  template <>
14144  struct unqualified_getter<lua_CFunction> {
14145  static lua_CFunction get(lua_State* L, int index, record& tracking) {
14146  tracking.use(1);
14147  return lua_tocfunction(L, index);
14148  }
14149  };
14150 
14151  template <>
14153  static c_closure get(lua_State* L, int index, record& tracking) {
14154  tracking.use(1);
14155  return c_closure(lua_tocfunction(L, index), -1);
14156  }
14157  };
14158 
14159  template <>
14161  static error get(lua_State* L, int index, record& tracking) {
14162  tracking.use(1);
14163  size_t sz = 0;
14164  const char* err = lua_tolstring(L, index, &sz);
14165  if (err == nullptr) {
14166  return error(detail::direct_error, "");
14167  }
14168  return error(detail::direct_error, std::string(err, sz));
14169  }
14170  };
14171 
14172  template <>
14173  struct unqualified_getter<void*> {
14174  static void* get(lua_State* L, int index, record& tracking) {
14175  tracking.use(1);
14176  return lua_touserdata(L, index);
14177  }
14178  };
14179 
14180  template <>
14181  struct unqualified_getter<const void*> {
14182  static const void* get(lua_State* L, int index, record& tracking) {
14183  tracking.use(1);
14184  return lua_touserdata(L, index);
14185  }
14186  };
14187 
14188  template <typename T>
14189  struct unqualified_getter<detail::as_value_tag<T>> {
14190  static T* get_no_lua_nil(lua_State* L, int index, record& tracking) {
14191  void* memory = lua_touserdata(L, index);
14192 #if SOL_IS_ON(SOL_USE_INTEROP)
14193  auto ugr = stack_detail::interop_get<T>(L, index, memory, tracking);
14194  if (ugr.first) {
14195  return ugr.second;
14196  }
14197 #endif // interop extensibility
14198  tracking.use(1);
14199  void* rawdata = detail::align_usertype_pointer(memory);
14200  void** pudata = static_cast<void**>(rawdata);
14201  void* udata = *pudata;
14202  return get_no_lua_nil_from(L, udata, index, tracking);
14203  }
14204 
14205  static T* get_no_lua_nil_from(lua_State* L, void* udata, int index, record&) {
14206  bool has_derived = derive<T>::value || weak_derive<T>::value;
14207  if (has_derived) {
14208  if (lua_getmetatable(L, index) == 1) {
14209  lua_getfield(L, -1, &detail::base_class_cast_key()[0]);
14210  if (type_of(L, -1) != type::lua_nil) {
14211  void* basecastdata = lua_touserdata(L, -1);
14212  detail::inheritance_cast_function ic = reinterpret_cast<detail::inheritance_cast_function>(basecastdata);
14213  // use the casting function to properly adjust the pointer for the desired T
14214  udata = ic(udata, usertype_traits<T>::qualified_name());
14215  }
14216  lua_pop(L, 2);
14217  }
14218  }
14219  if constexpr (std::is_function_v<T>) {
14220  T* func = reinterpret_cast<T*>(udata);
14221  return func;
14222  }
14223  else {
14224  T* obj = static_cast<T*>(udata);
14225  return obj;
14226  }
14227  }
14228 
14229  static T& get(lua_State* L, int index, record& tracking) {
14230  return *get_no_lua_nil(L, index, tracking);
14231  }
14232  };
14233 
14234  template <typename T>
14235  struct unqualified_getter<detail::as_pointer_tag<T>> {
14236  static T* get(lua_State* L, int index, record& tracking) {
14237  type t = type_of(L, index);
14238  if (t == type::lua_nil) {
14239  tracking.use(1);
14240  return nullptr;
14241  }
14243  return g.get_no_lua_nil(L, index, tracking);
14244  }
14245  };
14246 
14247  template <typename T>
14249  static T* get(lua_State* L, int index, record& tracking) {
14251  return g.get_no_lua_nil(L, index, tracking);
14252  }
14253  };
14254 
14255  template <typename T>
14256  struct unqualified_getter<T&> {
14257  static T& get(lua_State* L, int index, record& tracking) {
14259  return g.get(L, index, tracking);
14260  }
14261  };
14262 
14263  template <typename T>
14264  struct unqualified_getter<std::reference_wrapper<T>> {
14265  static T& get(lua_State* L, int index, record& tracking) {
14267  return g.get(L, index, tracking);
14268  }
14269  };
14270 
14271  template <typename T>
14272  struct unqualified_getter<T*> {
14273  static T* get(lua_State* L, int index, record& tracking) {
14274 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
14275  if constexpr (std::is_function_v<T>) {
14276  return stack_detail::get_function_pointer<T>(L, index, tracking);
14277  }
14278  else {
14280  return g.get(L, index, tracking);
14281  }
14282 #else
14284  return g.get(L, index, tracking);
14285 #endif
14286  }
14287  };
14288 
14289  template <typename... Tn>
14290  struct unqualified_getter<std::tuple<Tn...>> {
14291  typedef std::tuple<decltype(stack::get<Tn>(nullptr, 0))...> R;
14292 
14293  template <typename... Args>
14294  static R apply(std::index_sequence<>, lua_State*, int, record&, Args&&... args) {
14295  // Fuck you too, VC++
14296  return R { std::forward<Args>(args)... };
14297  }
14298 
14299  template <std::size_t I, std::size_t... Ix, typename... Args>
14300  static R apply(std::index_sequence<I, Ix...>, lua_State* L, int index, record& tracking, Args&&... args) {
14301  // Fuck you too, VC++
14302  typedef std::tuple_element_t<I, std::tuple<Tn...>> T;
14303  return apply(std::index_sequence<Ix...>(), L, index, tracking, std::forward<Args>(args)..., stack::get<T>(L, index + tracking.used, tracking));
14304  }
14305 
14306  static R get(lua_State* L, int index, record& tracking) {
14307  return apply(std::make_index_sequence<sizeof...(Tn)>(), L, index, tracking);
14308  }
14309  };
14310 
14311  template <typename A, typename B>
14312  struct unqualified_getter<std::pair<A, B>> {
14313  static decltype(auto) get(lua_State* L, int index, record& tracking) {
14314  return std::pair<decltype(stack::get<A>(L, index)), decltype(stack::get<B>(L, index))> { stack::get<A>(L, index, tracking),
14315  stack::get<B>(L, index + tracking.used, tracking) };
14316  }
14317  };
14318 
14319 #if SOL_IS_ON(SOL_STD_VARIANT)
14320 
14321  template <typename... Tn>
14322  struct unqualified_getter<std::variant<Tn...>> {
14323  using V = std::variant<Tn...>;
14324 
14325  static V get_one(std::integral_constant<std::size_t, std::variant_size_v<V>>, lua_State* L, int index, record& tracking) {
14326  (void)L;
14327  (void)index;
14328  (void)tracking;
14329  if constexpr (std::variant_size_v<V> == 0) {
14330  return V();
14331  }
14332  else {
14333  // using T = std::variant_alternative_t<0, V>;
14334  std::abort();
14335  // return V(std::in_place_index<0>, stack::get<T>(L, index, tracking));
14336  }
14337  }
14338 
14339  template <std::size_t I>
14340  static V get_one(std::integral_constant<std::size_t, I>, lua_State* L, int index, record& tracking) {
14341  typedef std::variant_alternative_t<I, V> T;
14342  record temp_tracking = tracking;
14343  if (stack::check<T>(L, index, &no_panic, temp_tracking)) {
14344  tracking = temp_tracking;
14345  return V(std::in_place_index<I>, stack::get<T>(L, index));
14346  }
14347  return get_one(std::integral_constant<std::size_t, I + 1>(), L, index, tracking);
14348  }
14349 
14350  static V get(lua_State* L, int index, record& tracking) {
14351  return get_one(std::integral_constant<std::size_t, 0>(), L, index, tracking);
14352  }
14353  };
14354 #endif // variant
14355 
14356 }} // namespace sol::stack
14357 
14358 // end of sol/stack_get_unqualified.hpp
14359 
14360 // beginning of sol/stack_get_qualified.hpp
14361 
14362 namespace sol { namespace stack {
14363 
14364  // There are no more enable_ifs that can be used here,
14365  // so this is just for posterity, I guess?
14366  // maybe I'll fill this file in later.
14367 
14368 }} // namespace sol::stack
14369 
14370 // end of sol/stack_get_qualified.hpp
14371 
14372 // end of sol/stack_get.hpp
14373 
14374 // beginning of sol/stack_check_get.hpp
14375 
14376 // beginning of sol/stack_check_get_unqualified.hpp
14377 
14378 #include <cstdlib>
14379 #include <cmath>
14380 #include <optional>
14381 #if SOL_IS_ON(SOL_STD_VARIANT)
14382 #include <variant>
14383 #endif // variant shenanigans (thanks, Mac OSX)
14384 
14385 namespace sol { namespace stack {
14386  template <typename T, typename>
14387  struct unqualified_check_getter {
14388  typedef decltype(stack_detail::unchecked_unqualified_get<T>(nullptr, -1, std::declval<record&>())) R;
14389 
14390  template <typename Optional, typename Handler>
14391  static Optional get_using(lua_State* L, int index, Handler&& handler, record& tracking) {
14392  if constexpr (!meta::meta_detail::is_adl_sol_lua_check_v<T> && !meta::meta_detail::is_adl_sol_lua_get_v<T>) {
14393  if constexpr (is_lua_reference_v<T>) {
14394  if constexpr (is_global_table_v<T>) {
14395  (void)L;
14396  (void)index;
14397  (void)handler;
14398  tracking.use(1);
14399  return true;
14400  }
14401  else {
14402  // actually check if it's none here, otherwise
14403  // we'll have a none object inside an optional!
14404  bool success = lua_isnoneornil(L, index) == 0 && stack::check<T>(L, index, &no_panic);
14405  if (!success) {
14406  // expected type, actual type
14407  tracking.use(static_cast<int>(success));
14408  handler(L, index, type::poly, type_of(L, index), "");
14409  return detail::associated_nullopt_v<Optional>;
14410  }
14411  return stack_detail::unchecked_get<T>(L, index, tracking);
14412  }
14413  }
14414  else if constexpr ((std::is_integral_v<T> || std::is_same_v<T, lua_Integer>)&&!std::is_same_v<T, bool>) {
14415 #if SOL_LUA_VERSION_I_ >= 503
14416  if (lua_isinteger(L, index) != 0) {
14417  tracking.use(1);
14418  return static_cast<T>(lua_tointeger(L, index));
14419  }
14420 #endif
14421  int isnum = 0;
14422  const lua_Number value = lua_tonumberx(L, index, &isnum);
14423  if (isnum != 0) {
14424 #if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
14425  const auto integer_value = llround(value);
14426  if (static_cast<lua_Number>(integer_value) == value) {
14427  tracking.use(1);
14428  return static_cast<T>(integer_value);
14429  }
14430 #else
14431  tracking.use(1);
14432  return static_cast<T>(value);
14433 #endif
14434  }
14435  const type t = type_of(L, index);
14436  tracking.use(static_cast<int>(t != type::none));
14437  handler(L, index, type::number, t, "not an integer");
14438  return detail::associated_nullopt_v<Optional>;
14439  }
14440  else if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, lua_Number>) {
14441  int isnum = 0;
14442  lua_Number value = lua_tonumberx(L, index, &isnum);
14443  if (isnum == 0) {
14444  type t = type_of(L, index);
14445  tracking.use(static_cast<int>(t != type::none));
14446  handler(L, index, type::number, t, "not a valid floating point number");
14447  return detail::associated_nullopt_v<Optional>;
14448  }
14449  tracking.use(1);
14450  return static_cast<T>(value);
14451  }
14452  else if constexpr (std::is_enum_v<T> && !meta::any_same_v<T, meta_function, type>) {
14453  int isnum = 0;
14454  lua_Integer value = lua_tointegerx(L, index, &isnum);
14455  if (isnum == 0) {
14456  type t = type_of(L, index);
14457  tracking.use(static_cast<int>(t != type::none));
14458  handler(L, index, type::number, t, "not a valid enumeration value");
14459  return detail::associated_nullopt_v<Optional>;
14460  }
14461  tracking.use(1);
14462  return static_cast<T>(value);
14463  }
14464  else {
14465  if (!unqualified_check<T>(L, index, std::forward<Handler>(handler))) {
14466  tracking.use(static_cast<int>(!lua_isnone(L, index)));
14467  return detail::associated_nullopt_v<Optional>;
14468  }
14469  return stack_detail::unchecked_unqualified_get<T>(L, index, tracking);
14470  }
14471  }
14472  else {
14473  if (!unqualified_check<T>(L, index, std::forward<Handler>(handler))) {
14474  tracking.use(static_cast<int>(!lua_isnone(L, index)));
14475  return detail::associated_nullopt_v<Optional>;
14476  }
14477  return stack_detail::unchecked_unqualified_get<T>(L, index, tracking);
14478  }
14479  }
14480 
14481  template <typename Handler>
14482  static optional<R> get(lua_State* L, int index, Handler&& handler, record& tracking) {
14483  return get_using<optional<R>>(L, index, std::forward<Handler>(handler), tracking);
14484  }
14485  };
14486 
14487 #if SOL_IS_ON(SOL_STD_VARIANT)
14488  template <typename... Tn, typename C>
14489  struct unqualified_check_getter<std::variant<Tn...>, C> {
14490  typedef std::variant<Tn...> V;
14491  typedef std::variant_size<V> V_size;
14492  typedef std::integral_constant<bool, V_size::value == 0> V_is_empty;
14493 
14494  template <typename Handler>
14495  static optional<V> get_empty(std::true_type, lua_State*, int, Handler&&, record&) {
14496  return nullopt;
14497  }
14498 
14499  template <typename Handler>
14500  static optional<V> get_empty(std::false_type, lua_State* L, int index, Handler&& handler, record&) {
14501  // This should never be reached...
14502  // please check your code and understand what you did to bring yourself here
14503  // maybe file a bug report, or 5
14504  handler(
14505  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");
14506  return nullopt;
14507  }
14508 
14509  template <typename Handler>
14510  static optional<V> get_one(std::integral_constant<std::size_t, 0>, lua_State* L, int index, Handler&& handler, record& tracking) {
14511  return get_empty(V_is_empty(), L, index, std::forward<Handler>(handler), tracking);
14512  }
14513 
14514  template <std::size_t I, typename Handler>
14515  static optional<V> get_one(std::integral_constant<std::size_t, I>, lua_State* L, int index, Handler&& handler, record& tracking) {
14516  typedef std::variant_alternative_t<I - 1, V> T;
14517  if (stack::check<T>(L, index, &no_panic, tracking)) {
14518  return V(std::in_place_index<I - 1>, stack::get<T>(L, index));
14519  }
14520  return get_one(std::integral_constant<std::size_t, I - 1>(), L, index, std::forward<Handler>(handler), tracking);
14521  }
14522 
14523  template <typename Handler>
14524  static optional<V> get(lua_State* L, int index, Handler&& handler, record& tracking) {
14525  return get_one(std::integral_constant<std::size_t, V_size::value>(), L, index, std::forward<Handler>(handler), tracking);
14526  }
14527  };
14528 #endif // standard variant
14529 }} // namespace sol::stack
14530 
14531 // end of sol/stack_check_get_unqualified.hpp
14532 
14533 // beginning of sol/stack_check_get_qualified.hpp
14534 
14535 namespace sol { namespace stack {
14536 
14537 #if SOL_IS_ON(SOL_COMPILER_GCC)
14538 #pragma GCC diagnostic push
14539 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
14540 #endif
14541 
14542  namespace stack_detail {
14543  template <typename OptionalType, typename T, typename Handler>
14544  OptionalType get_optional(lua_State* L, int index, Handler&& handler, record& tracking) {
14545  using Tu = meta::unqualified_t<T>;
14546 
14547  if constexpr (is_lua_reference_v<T>) {
14548  if constexpr (is_global_table_v<Tu>) {
14549  (void)L;
14550  (void)index;
14551  (void)handler;
14552  tracking.use(1);
14553  return true;
14554  }
14555  else {
14556  // actually check if it's none here, otherwise
14557  // we'll have a none object inside an optional!
14558  bool success = lua_isnoneornil(L, index) == 0 && stack::check<T>(L, index, &no_panic);
14559  if (!success) {
14560  // expected type, actual type
14561  tracking.use(static_cast<int>(success));
14562  handler(L, index, type::poly, type_of(L, index), "");
14563  return {};
14564  }
14565  return OptionalType(stack_detail::unchecked_get<T>(L, index, tracking));
14566  }
14567  }
14568  else if constexpr (!std::is_reference_v<T> && is_unique_usertype_v<Tu> && !is_actual_type_rebindable_for_v<Tu>) {
14569  // we can take shortcuts here to save on separate checking, and just return nullopt!
14570  using element = unique_usertype_element_t<Tu>;
14571  using actual = unique_usertype_actual_t<Tu>;
14572  tracking.use(1);
14573  void* memory = lua_touserdata(L, index);
14574  memory = detail::align_usertype_unique_destructor(memory);
14575  detail::unique_destructor& pdx = *static_cast<detail::unique_destructor*>(memory);
14576  if (&detail::usertype_unique_alloc_destroy<element, Tu> == pdx) {
14577  memory = detail::align_usertype_unique_tag<true, false>(memory);
14578  memory = detail::align_usertype_unique<actual, true, false>(memory);
14579  actual* mem = static_cast<actual*>(memory);
14580  return static_cast<actual>(*mem);
14581  }
14582  if constexpr (!derive<element>::value) {
14583  return OptionalType();
14584  }
14585  else {
14586  memory = detail::align_usertype_unique_tag<true, false>(memory);
14587  detail::unique_tag& ic = *reinterpret_cast<detail::unique_tag*>(memory);
14588  memory = detail::align_usertype_unique<actual, true, false>(memory);
14589  string_view ti = usertype_traits<element>::qualified_name();
14590  int cast_operation;
14591  actual r {};
14592  if constexpr (is_actual_type_rebindable_for_v<Tu>) {
14593  using rebound_actual_type = unique_usertype_rebind_actual_t<Tu, void>;
14594  string_view rebind_ti = usertype_traits<rebound_actual_type>::qualified_name();
14595  cast_operation = ic(memory, &r, ti, rebind_ti);
14596  }
14597  else {
14598  string_view rebind_ti("");
14599  cast_operation = ic(memory, &r, ti, rebind_ti);
14600  }
14601  switch (cast_operation) {
14602  case 1: {
14603  // it's a perfect match,
14604  // alias memory directly
14605  actual* mem = static_cast<actual*>(memory);
14606  return OptionalType(*mem);
14607  }
14608  case 2:
14609  // it's a base match, return the
14610  // aliased creation
14611  return OptionalType(std::move(r));
14612  default:
14613  break;
14614  }
14615  return OptionalType();
14616  }
14617  }
14618  else {
14619  if (!check<T>(L, index, std::forward<Handler>(handler))) {
14620  tracking.use(static_cast<int>(!lua_isnone(L, index)));
14621  return OptionalType();
14622  }
14623  return OptionalType(stack_detail::unchecked_get<T>(L, index, tracking));
14624  }
14625  }
14626  } // namespace stack_detail
14627 
14628 #if SOL_IS_ON(SOL_COMPILER_GCC)
14629 #pragma GCC diagnostic pop
14630 #endif
14631 
14632  template <typename T, typename>
14633  struct qualified_check_getter {
14634  typedef decltype(stack_detail::unchecked_get<T>(nullptr, -1, std::declval<record&>())) R;
14635 
14636  template <typename Handler>
14637  optional<R> get(lua_State* L, int index, Handler&& handler, record& tracking) {
14638  return stack_detail::get_optional<optional<R>, T>(L, index, std::forward<Handler>(handler), tracking);
14639  }
14640  };
14641 
14642  template <typename Optional>
14643  struct qualified_getter<Optional, std::enable_if_t<meta::is_optional_v<Optional>>> {
14644  static Optional get(lua_State* L, int index, record& tracking) {
14645  using T = typename meta::unqualified_t<Optional>::value_type;
14646  return stack_detail::get_optional<Optional, T>(L, index, &no_panic, tracking);
14647  }
14648  };
14649 
14650 }} // namespace sol::stack
14651 
14652 // end of sol/stack_check_get_qualified.hpp
14653 
14654 // end of sol/stack_check_get.hpp
14655 
14656 // beginning of sol/stack_push.hpp
14657 
14658 #include <memory>
14659 #include <type_traits>
14660 #include <cassert>
14661 #include <limits>
14662 #include <cmath>
14663 #include <string_view>
14664 #if SOL_IS_ON(SOL_STD_VARIANT)
14665 #include <variant>
14666 #endif // Can use variant
14667 
14668 // beginning of sol/debug.hpp
14669 
14670 #include <iostream>
14671 
14672 namespace sol { namespace detail { namespace debug {
14673  inline std::string dump_types(lua_State* L) {
14674  std::string visual;
14675  std::size_t size = lua_gettop(L) + 1;
14676  for (std::size_t i = 1; i < size; ++i) {
14677  if (i != 1) {
14678  visual += " | ";
14679  }
14680  visual += type_name(L, stack::get<type>(L, static_cast<int>(i)));
14681  }
14682  return visual;
14683  }
14684 
14685  inline void print_stack(lua_State* L) {
14686  std::cout << dump_types(L) << std::endl;
14687  }
14688 
14689  inline void print_section(const std::string& message, lua_State* L) {
14690  std::cout << "-- " << message << " -- [ " << dump_types(L) << " ]" << std::endl;
14691  }
14692 }}} // namespace sol::detail::debug
14693 
14694 // end of sol/debug.hpp
14695 
14696 namespace sol { namespace stack {
14697  namespace stack_detail {
14698  template <typename T>
14699  inline bool integer_value_fits(const T& value) {
14700  // We check if we can rely on casts or a lack of padding bits to satisfy
14701  // the requirements here
14702  // If it lacks padding bits, we can jump back and forth between lua_Integer and whatever type without
14703  // loss of information
14704  constexpr bool is_same_signedness
14705  = (std::is_signed_v<T> && std::is_signed_v<lua_Integer>) || (std::is_unsigned_v<T> && std::is_unsigned_v<lua_Integer>);
14706  constexpr bool probaby_fits_within_lua_Integer = sizeof(T) == sizeof(lua_Integer)
14707 #if SOL_IS_ON(SOL_ALL_INTEGER_VALUES_FIT)
14708  && ((std::has_unique_object_representations_v<T> && std::has_unique_object_representations_v<lua_Integer>) ? true : is_same_signedness)
14709 #else
14710  && is_same_signedness
14711 #endif
14712  ;
14713  if constexpr (sizeof(T) < sizeof(lua_Integer) || probaby_fits_within_lua_Integer) {
14714  (void)value;
14715  return true;
14716  }
14717  else {
14718  auto u_min = static_cast<std::intmax_t>((std::numeric_limits<lua_Integer>::min)());
14719  auto u_max = static_cast<std::uintmax_t>((std::numeric_limits<lua_Integer>::max)());
14720  auto t_min = static_cast<std::intmax_t>((std::numeric_limits<T>::min)());
14721  auto t_max = static_cast<std::uintmax_t>((std::numeric_limits<T>::max)());
14722  return (u_min <= t_min || value >= static_cast<T>(u_min)) && (u_max >= t_max || value <= static_cast<T>(u_max));
14723  }
14724  }
14725 
14726  template <typename T>
14727  int msvc_is_ass_with_if_constexpr_push_enum(std::true_type, lua_State* L, const T& value) {
14728  if constexpr (meta::any_same_v<std::underlying_type_t<T>,
14729  char
14730 #if SOL_IS_ON(SOL_CHAR8_T)
14731  ,
14732  char8_t
14733 #endif
14734  ,
14735  char16_t,
14736  char32_t>) {
14737  if constexpr (std::is_signed_v<T>) {
14738  return stack::push(L, static_cast<std::int_least32_t>(value));
14739  }
14740  else {
14741  return stack::push(L, static_cast<std::uint_least32_t>(value));
14742  }
14743  }
14744  else {
14745  return stack::push(L, static_cast<std::underlying_type_t<T>>(value));
14746  }
14747  }
14748 
14749  template <typename T>
14750  int msvc_is_ass_with_if_constexpr_push_enum(std::false_type, lua_State*, const T&) {
14751  return 0;
14752  }
14753  } // namespace stack_detail
14754 
14755  inline int push_environment_of(lua_State* L, int target_index = -1) {
14756 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
14757  luaL_checkstack(L, 1, detail::not_enough_stack_space_environment);
14758 #endif // make sure stack doesn't overflow
14759 #if SOL_LUA_VERSION_I_ < 502
14760  // Use lua_getfenv
14761  lua_getfenv(L, target_index);
14762 #else
14763 
14764  if (lua_iscfunction(L, target_index) != 0) {
14765  const char* maybe_upvalue_name = lua_getupvalue(L, target_index, 1);
14766  if (maybe_upvalue_name != nullptr) {
14767  // it worked, take this one
14768  return 1;
14769  }
14770  }
14771  // Nominally, we search for the `"_ENV"` value.
14772  // If we don't find it.... uh, well. We've got a problem?
14773  for (int upvalue_index = 1;; ++upvalue_index) {
14774  const char* maybe_upvalue_name = lua_getupvalue(L, target_index, upvalue_index);
14775  if (maybe_upvalue_name == nullptr) {
14776  push(L, lua_nil);
14777  break;
14778  }
14779 
14780  string_view upvalue_name(maybe_upvalue_name);
14781  if (upvalue_name == "_ENV") {
14782  // Keep this one!
14783  break;
14784  }
14785  // Discard what we received, loop back around
14786  lua_pop(L, 1);
14787  }
14788 #endif
14789  return 1;
14790  }
14791 
14792  template <typename T>
14793  int push_environment_of(const T& target) {
14794  lua_State* target_L = target.lua_state();
14795  int target_index = absolute_index(target_L, -target.push());
14796  int env_count = push_environment_of(target_L, target_index);
14797  sol_c_assert(env_count == 1);
14798  lua_rotate(target_L, target_index, 1);
14799  lua_pop(target_L, 1);
14800  return env_count;
14801  }
14802 
14803  template <typename T>
14804  struct unqualified_pusher<detail::as_value_tag<T>> {
14805  template <typename F, typename... Args>
14806  static int push_fx(lua_State* L, F&& f, Args&&... args) {
14807 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
14808  luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata);
14809 #endif // make sure stack doesn't overflow
14810  // Basically, we store all user-data like this:
14811  // If it's a movable/copyable value (no std::ref(x)), then we store the pointer to the new
14812  // data in the first sizeof(T*) bytes, and then however many bytes it takes to
14813  // do the actual object. Things that are std::ref or plain T* are stored as
14814  // just the sizeof(T*), and nothing else.
14815  T* obj = detail::usertype_allocate<T>(L);
14816  f();
14817  std::allocator<T> alloc {};
14818  std::allocator_traits<std::allocator<T>>::construct(alloc, obj, std::forward<Args>(args)...);
14819  return 1;
14820  }
14821 
14822  template <typename K, typename... Args>
14823  static int push_keyed(lua_State* L, K&& k, Args&&... args) {
14824  stack_detail::undefined_metatable fx(L, &k[0], &stack::stack_detail::set_undefined_methods_on<T>);
14825  return push_fx(L, fx, std::forward<Args>(args)...);
14826  }
14827 
14828  template <typename Arg, typename... Args>
14829  static int push(lua_State* L, Arg&& arg, Args&&... args) {
14830  if constexpr (std::is_same_v<meta::unqualified_t<Arg>, detail::with_function_tag>) {
14831  (void)arg;
14832  return push_fx(L, std::forward<Args>(args)...);
14833  }
14834  else {
14835  return push_keyed(L, usertype_traits<T>::metatable(), std::forward<Arg>(arg), std::forward<Args>(args)...);
14836  }
14837  }
14838 
14839  static int push(lua_State* L) {
14840  return push_keyed(L, usertype_traits<T>::metatable());
14841  }
14842  };
14843 
14844  template <typename T>
14845  struct unqualified_pusher<detail::as_pointer_tag<T>> {
14846  typedef meta::unqualified_t<T> U;
14847 
14848  template <typename F>
14849  static int push_fx(lua_State* L, F&& f, T* obj) {
14850  if (obj == nullptr)
14851  return stack::push(L, lua_nil);
14852 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
14853  luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata);
14854 #endif // make sure stack doesn't overflow
14855  T** pref = detail::usertype_allocate_pointer<T>(L);
14856  f();
14857  *pref = obj;
14858  return 1;
14859  }
14860 
14861  template <typename K>
14862  static int push_keyed(lua_State* L, K&& k, T* obj) {
14863  stack_detail::undefined_metatable fx(L, &k[0], &stack::stack_detail::set_undefined_methods_on<U*>);
14864  return push_fx(L, fx, obj);
14865  }
14866 
14867  template <typename Arg, typename... Args>
14868  static int push(lua_State* L, Arg&& arg, Args&&... args) {
14869  if constexpr (std::is_same_v<meta::unqualified_t<Arg>, detail::with_function_tag>) {
14870  (void)arg;
14871  return push_fx(L, std::forward<Args>(args)...);
14872  }
14873  else {
14874  return push_keyed(L, usertype_traits<U*>::metatable(), std::forward<Arg>(arg), std::forward<Args>(args)...);
14875  }
14876  }
14877  };
14878 
14879  template <>
14880  struct unqualified_pusher<detail::as_reference_tag> {
14881  template <typename T>
14882  static int push(lua_State* L, T&& obj) {
14883  return stack::push(L, detail::ptr(obj));
14884  }
14885  };
14886 
14887  namespace stack_detail {
14888  template <typename T>
14889  struct uu_pusher {
14890  using element = unique_usertype_element_t<T>;
14891  using actual = unique_usertype_actual_t<T>;
14892 
14893  template <typename Arg, typename... Args>
14894  static int push(lua_State* L, Arg&& arg, Args&&... args) {
14895  if constexpr (std::is_base_of_v<actual, meta::unqualified_t<Arg>>) {
14896  if (detail::unique_is_null(L, arg)) {
14897  return stack::push(L, lua_nil);
14898  }
14899  return push_deep(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
14900  }
14901  else {
14902  return push_deep(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
14903  }
14904  }
14905 
14906  template <typename... Args>
14907  static int push_deep(lua_State* L, Args&&... args) {
14908 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
14909  luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata);
14910 #endif // make sure stack doesn't overflow
14911  element** pointer_to_memory = nullptr;
14912  detail::unique_destructor* fx = nullptr;
14913  detail::unique_tag* id = nullptr;
14914  actual* typed_memory = detail::usertype_unique_allocate<element, actual>(L, pointer_to_memory, fx, id);
14915  if (luaL_newmetatable(L, &usertype_traits<d::u<std::remove_cv_t<element>>>::metatable()[0]) == 1) {
14916  detail::lua_reg_table registration_table {};
14917  int index = 0;
14918  detail::indexed_insert insert_callable(registration_table, index);
14919  detail::insert_default_registrations<element>(insert_callable, detail::property_always_true);
14920  registration_table[index] = { to_string(meta_function::garbage_collect).c_str(), detail::make_destructor<T>() };
14921  luaL_setfuncs(L, registration_table, 0);
14922  }
14923  lua_setmetatable(L, -2);
14924  *fx = detail::usertype_unique_alloc_destroy<element, actual>;
14925  *id = &detail::inheritance<element>::template type_unique_cast<actual>;
14926  detail::default_construct::construct(typed_memory, std::forward<Args>(args)...);
14927  *pointer_to_memory = detail::unique_get<T>(L, *typed_memory);
14928  return 1;
14929  }
14930  };
14931  } // namespace stack_detail
14932 
14933  template <typename T>
14934  struct unqualified_pusher<detail::as_unique_tag<T>> {
14935  template <typename... Args>
14936  static int push(lua_State* L, Args&&... args) {
14938  (void)p;
14939  return p.push(L, std::forward<Args>(args)...);
14940  }
14941  };
14942 
14943  template <typename T, typename>
14944  struct unqualified_pusher {
14945  template <typename... Args>
14946  static int push(lua_State* L, Args&&... args) {
14947  using Tu = meta::unqualified_t<T>;
14948  if constexpr (is_lua_reference_v<Tu>) {
14949  using int_arr = int[];
14950  int_arr p { (std::forward<Args>(args).push(L))... };
14951  return p[0];
14952  }
14953  else if constexpr (std::is_same_v<Tu, bool>) {
14954 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
14955  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
14956 #endif // make sure stack doesn't overflow
14957  lua_pushboolean(L, std::forward<Args>(args)...);
14958  return 1;
14959  }
14960  else if constexpr (std::is_integral_v<Tu> || std::is_same_v<Tu, lua_Integer>) {
14961  const Tu& value(std::forward<Args>(args)...);
14962 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
14963  luaL_checkstack(L, 1, detail::not_enough_stack_space_integral);
14964 #endif // make sure stack doesn't overflow
14965 #if SOL_LUA_VERSION_I_ >= 503
14966  if (stack_detail::integer_value_fits<Tu>(value)) {
14967  lua_pushinteger(L, static_cast<lua_Integer>(value));
14968  return 1;
14969  }
14970 #endif // Lua 5.3 and above
14971 #if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
14972  if (static_cast<T>(llround(static_cast<lua_Number>(value))) != value) {
14973 #if SOL_IS_OFF(SOL_EXCEPTIONS)
14974  // Is this really worth it?
14975  sol_m_assert(false, "integer value will be misrepresented in lua");
14976  lua_pushinteger(L, static_cast<lua_Integer>(value));
14977  return 1;
14978 #else
14979  throw error(detail::direct_error, "integer value will be misrepresented in lua");
14980 #endif // No Exceptions
14981  }
14982 #endif // Safe Numerics and Number Precision Check
14983  lua_pushnumber(L, static_cast<lua_Number>(value));
14984  return 1;
14985  }
14986  else if constexpr (std::is_floating_point_v<Tu> || std::is_same_v<Tu, lua_Number>) {
14987 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
14988  luaL_checkstack(L, 1, detail::not_enough_stack_space_floating);
14989 #endif // make sure stack doesn't overflow
14990  lua_pushnumber(L, std::forward<Args>(args)...);
14991  return 1;
14992  }
14993  else if constexpr (std::is_same_v<Tu, luaL_Stream*>) {
14994  luaL_Stream* source { std::forward<Args>(args)... };
14995  luaL_Stream* stream = static_cast<luaL_Stream*>(detail::alloc_newuserdata(L, sizeof(luaL_Stream)));
14996  stream->f = source->f;
14997 #if SOL_IS_ON(SOL_LUAL_STREAM_USE_CLOSE_FUNCTION)
14998  stream->closef = source->closef;
14999 #endif // LuaJIT and Lua 5.1 and below do not have
15000  return 1;
15001  }
15002  else if constexpr (std::is_same_v<Tu, luaL_Stream>) {
15003  luaL_Stream& source(std::forward<Args>(args)...);
15004  luaL_Stream* stream = static_cast<luaL_Stream*>(detail::alloc_newuserdata(L, sizeof(luaL_Stream)));
15005  stream->f = source.f;
15006 #if SOL_IS_ON(SOL_LUAL_STREAM_USE_CLOSE_FUNCTION)
15007  stream->closef = source.closef;
15008 #endif // LuaJIT and Lua 5.1 and below do not have
15009  return 1;
15010  }
15011  else if constexpr (std::is_enum_v<Tu>) {
15012  return stack_detail::msvc_is_ass_with_if_constexpr_push_enum(std::true_type(), L, std::forward<Args>(args)...);
15013  }
15014  else if constexpr (std::is_pointer_v<Tu>) {
15015  return stack::push<detail::as_pointer_tag<std::remove_pointer_t<T>>>(L, std::forward<Args>(args)...);
15016  }
15017  else if constexpr (is_unique_usertype_v<Tu>) {
15018  return stack::push<detail::as_unique_tag<T>>(L, std::forward<Args>(args)...);
15019  }
15020  else {
15021  return stack::push<detail::as_value_tag<T>>(L, std::forward<Args>(args)...);
15022  }
15023  }
15024  };
15025 
15026  template <typename T>
15027  struct unqualified_pusher<std::reference_wrapper<T>> {
15028  static int push(lua_State* L, const std::reference_wrapper<T>& t) {
15029  return stack::push(L, std::addressof(detail::deref(t.get())));
15030  }
15031  };
15032 
15033  template <typename T>
15034  struct unqualified_pusher<detail::as_table_tag<T>> {
15036 
15037  static int push(lua_State* L, const T& tablecont) {
15038  return push(has_kvp(), std::false_type(), L, tablecont);
15039  }
15040 
15041  static int push(lua_State* L, const T& tablecont, nested_tag_t) {
15042  return push(has_kvp(), std::true_type(), L, tablecont);
15043  }
15044 
15045  static int push(std::true_type, lua_State* L, const T& tablecont) {
15046  return push(has_kvp(), std::true_type(), L, tablecont);
15047  }
15048 
15049  static int push(std::false_type, lua_State* L, const T& tablecont) {
15050  return push(has_kvp(), std::false_type(), L, tablecont);
15051  }
15052 
15053  template <bool is_nested>
15054  static int push(std::true_type, std::integral_constant<bool, is_nested>, lua_State* L, const T& tablecont) {
15055  auto& cont = detail::deref(detail::unwrap(tablecont));
15056  lua_createtable(L, static_cast<int>(cont.size()), 0);
15057  int tableindex = lua_gettop(L);
15058  for (const auto& pair : cont) {
15059  if (is_nested) {
15060  set_field(L, pair.first, as_nested_ref(pair.second), tableindex);
15061  }
15062  else {
15063  set_field(L, pair.first, pair.second, tableindex);
15064  }
15065  }
15066  return 1;
15067  }
15068 
15069  template <bool is_nested>
15070  static int push(std::false_type, std::integral_constant<bool, is_nested>, lua_State* L, const T& tablecont) {
15071  auto& cont = detail::deref(detail::unwrap(tablecont));
15072  lua_createtable(L, stack_detail::get_size_hint(cont), 0);
15073  int tableindex = lua_gettop(L);
15074  std::size_t index = 1;
15075  for (const auto& i : cont) {
15076 #if SOL_LUA_VERSION_I_ >= 503
15077  int p = is_nested ? stack::push(L, as_nested_ref(i)) : stack::push(L, i);
15078  for (int pi = 0; pi < p; ++pi) {
15079  lua_seti(L, tableindex, static_cast<lua_Integer>(index++));
15080  }
15081 #else
15082 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15083  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15084 #endif // make sure stack doesn't overflow
15085  lua_pushinteger(L, static_cast<lua_Integer>(index));
15086  int p = is_nested ? stack::push(L, as_nested_ref(i)) : stack::push(L, i);
15087  if (p == 1) {
15088  ++index;
15089  lua_settable(L, tableindex);
15090  }
15091  else {
15092  int firstindex = tableindex + 1 + 1;
15093  for (int pi = 0; pi < p; ++pi) {
15094  stack::push(L, index);
15095 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15096  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15097 #endif // make sure stack doesn't overflow
15098  lua_pushvalue(L, firstindex);
15099  lua_settable(L, tableindex);
15100  ++index;
15101  ++firstindex;
15102  }
15103  lua_pop(L, 1 + p);
15104  }
15105 #endif // Lua Version 5.3 and others
15106  }
15107  // TODO: figure out a better way to do this...?
15108  // set_field(L, -1, cont.size());
15109  return 1;
15110  }
15111  };
15112 
15113  template <typename T>
15115  static int push(lua_State* L, const as_table_t<T>& value_) {
15116  using inner_t = std::remove_pointer_t<meta::unwrap_unqualified_t<T>>;
15117  if constexpr (is_container_v<inner_t>) {
15118  return stack::push<detail::as_table_tag<T>>(L, value_.value());
15119  }
15120  else {
15121  return stack::push(L, value_.value());
15122  }
15123  }
15124 
15125  static int push(lua_State* L, const T& value_) {
15126  using inner_t = std::remove_pointer_t<meta::unwrap_unqualified_t<T>>;
15127  if constexpr (is_container_v<inner_t>) {
15128  return stack::push<detail::as_table_tag<T>>(L, value_);
15129  }
15130  else {
15131  return stack::push(L, value_);
15132  }
15133  }
15134  };
15135 
15136  template <typename T>
15138  static int push(lua_State* L, const T& nested_value) noexcept {
15139  using Tu = meta::unwrap_unqualified_t<T>;
15140  using inner_t = std::remove_pointer_t<Tu>;
15141  if constexpr (is_container_v<inner_t>) {
15142  return stack::push<detail::as_table_tag<T>>(L, nested_value, nested_tag);
15143  }
15144  else {
15145  return stack::push<Tu>(L, nested_value);
15146  }
15147  }
15148 
15149  static int push(lua_State* L, const nested<T>& nested_wrapper_) noexcept {
15150  using Tu = meta::unwrap_unqualified_t<T>;
15151  using inner_t = std::remove_pointer_t<Tu>;
15152  if constexpr (is_container_v<inner_t>) {
15153  return stack::push<detail::as_table_tag<T>>(L, nested_wrapper_.value(), nested_tag);
15154  }
15155  else {
15156  return stack::push<Tu>(L, nested_wrapper_.value());
15157  }
15158  }
15159  };
15160 
15161  template <typename T>
15162  struct unqualified_pusher<std::initializer_list<T>> {
15163  static int push(lua_State* L, const std::initializer_list<T>& il) noexcept {
15165  return p.push(L, il);
15166  }
15167  };
15168 
15169  template <>
15171  static int push(lua_State* L, lua_nil_t) noexcept {
15172 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15173  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15174 #endif // make sure stack doesn't overflow
15175  lua_pushnil(L);
15176  return 1;
15177  }
15178  };
15179 
15180  template <>
15182  static int push(lua_State*, stack_count st) noexcept {
15183  return st.count;
15184  }
15185  };
15186 
15187  template <>
15189  static int push(lua_State* L, metatable_key_t) {
15190 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15191  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15192 #endif // make sure stack doesn't overflow
15193  lua_pushlstring(L, to_string(meta_function::metatable).c_str(), 4);
15194  return 1;
15195  }
15196  };
15197 
15198  template <>
15199  struct unqualified_pusher<std::remove_pointer_t<lua_CFunction>> {
15200  static int push(lua_State* L, lua_CFunction func, int n = 0) noexcept {
15201 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15202  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15203 #endif // make sure stack doesn't overflow
15204  lua_pushcclosure(L, func, n);
15205  return 1;
15206  }
15207  };
15208 
15209  template <>
15210  struct unqualified_pusher<lua_CFunction> {
15211  static int push(lua_State* L, lua_CFunction func, int n = 0) {
15212 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15213  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15214 #endif // make sure stack doesn't overflow
15215  lua_pushcclosure(L, func, n);
15216  return 1;
15217  }
15218  };
15219 
15220 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
15221  template <>
15222  struct unqualified_pusher<std::remove_pointer_t<detail::lua_CFunction_noexcept>> {
15223  static int push(lua_State* L, detail::lua_CFunction_noexcept func, int n = 0) {
15224 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15225  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15226 #endif // make sure stack doesn't overflow
15227  lua_pushcclosure(L, func, n);
15228  return 1;
15229  }
15230  };
15231 
15232  template <>
15233  struct unqualified_pusher<detail::lua_CFunction_noexcept> {
15234  static int push(lua_State* L, detail::lua_CFunction_noexcept func, int n = 0) {
15235 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15236  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15237 #endif // make sure stack doesn't overflow
15238  lua_pushcclosure(L, func, n);
15239  return 1;
15240  }
15241  };
15242 #endif // noexcept function type
15243 
15244  template <>
15246  static int push(lua_State* L, c_closure cc) {
15247 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15248  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15249 #endif // make sure stack doesn't overflow
15250  lua_pushcclosure(L, cc.c_function, cc.upvalues);
15251  return 1;
15252  }
15253  };
15254 
15255  template <typename Arg, typename... Args>
15256  struct unqualified_pusher<closure<Arg, Args...>> {
15257  template <std::size_t... I, typename T>
15258  static int push(std::index_sequence<I...>, lua_State* L, T&& c) {
15259  using f_tuple = decltype(std::forward<T>(c).upvalues);
15260  int pushcount = multi_push(L, std::get<I>(std::forward<f_tuple>(std::forward<T>(c).upvalues))...);
15261  return stack::push(L, c_closure(c.c_function, pushcount));
15262  }
15263 
15264  template <typename T>
15265  static int push(lua_State* L, T&& c) {
15266  return push(std::make_index_sequence<1 + sizeof...(Args)>(), L, std::forward<T>(c));
15267  }
15268  };
15269 
15270  template <>
15271  struct unqualified_pusher<void*> {
15272  static int push(lua_State* L, void* userdata) noexcept {
15273 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15274  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15275 #endif // make sure stack doesn't overflow
15276  lua_pushlightuserdata(L, userdata);
15277  return 1;
15278  }
15279  };
15280 
15281  template <>
15282  struct unqualified_pusher<const void*> {
15283  static int push(lua_State* L, const void* userdata) noexcept {
15284 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15285  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15286 #endif // make sure stack doesn't overflow
15287  lua_pushlightuserdata(L, const_cast<void*>(userdata));
15288  return 1;
15289  }
15290  };
15291 
15292  template <>
15294  static int push(lua_State* L, lightuserdata_value userdata) noexcept {
15295 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15296  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15297 #endif // make sure stack doesn't overflow
15298  lua_pushlightuserdata(L, userdata);
15299  return 1;
15300  }
15301  };
15302 
15303  template <typename T>
15305  static int push(lua_State* L, light<T> l) noexcept {
15306 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15307  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15308 #endif // make sure stack doesn't overflow
15309  lua_pushlightuserdata(L, static_cast<void*>(l.value()));
15310  return 1;
15311  }
15312  };
15313 
15314  template <typename T>
15316  template <bool with_meta = true, typename Key, typename... Args>
15317  static int push_with(lua_State* L, Key&& name, Args&&... args) {
15318 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15319  luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata);
15320 #endif // make sure stack doesn't overflow
15321  // A dumb pusher
15322  T* data = detail::user_allocate<T>(L);
15323  if (with_meta) {
15324  // Make sure we have a plain GC set for this data
15325 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15326  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15327 #endif // make sure stack doesn't overflow
15328  if (luaL_newmetatable(L, name) != 0) {
15329  lua_CFunction cdel = detail::user_alloc_destroy<T>;
15330  lua_pushcclosure(L, cdel, 0);
15331  lua_setfield(L, -2, "__gc");
15332  }
15333  lua_setmetatable(L, -2);
15334  }
15335  std::allocator<T> alloc {};
15336  std::allocator_traits<std::allocator<T>>::construct(alloc, data, std::forward<Args>(args)...);
15337  return 1;
15338  }
15339 
15340  template <typename Arg, typename... Args>
15341  static int push(lua_State* L, Arg&& arg, Args&&... args) {
15342  if constexpr (std::is_same_v<meta::unqualified_t<Arg>, metatable_key_t>) {
15343  const auto name = &arg[0];
15344  return push_with<true>(L, name, std::forward<Args>(args)...);
15345  }
15346  else if constexpr (std::is_same_v<meta::unqualified_t<Arg>, no_metatable_t>) {
15347  (void)arg;
15348  const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
15349  return push_with<false>(L, name, std::forward<Args>(args)...);
15350  }
15351  else {
15352  const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
15353  return push_with(L, name, std::forward<Arg>(arg), std::forward<Args>(args)...);
15354  }
15355  }
15356 
15357  static int push(lua_State* L, const user<T>& u) {
15358  const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
15359  return push_with(L, name, u.value);
15360  }
15361 
15362  static int push(lua_State* L, user<T>&& u) {
15363  const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
15364  return push_with(L, name, std::move(u.value()));
15365  }
15366 
15367  static int push(lua_State* L, no_metatable_t, const user<T>& u) {
15368  const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
15369  return push_with<false>(L, name, u.value());
15370  }
15371 
15372  static int push(lua_State* L, no_metatable_t, user<T>&& u) {
15373  const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
15374  return push_with<false>(L, name, std::move(u.value()));
15375  }
15376  };
15377 
15378  template <>
15380  static int push(lua_State* L, userdata_value data) {
15381 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15382  luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata);
15383 #endif // make sure stack doesn't overflow
15384  void** ud = detail::usertype_allocate_pointer<void>(L);
15385  *ud = data.value();
15386  return 1;
15387  }
15388  };
15389 
15390  template <>
15391  struct unqualified_pusher<const char*> {
15392  static int push_sized(lua_State* L, const char* str, std::size_t len) {
15393 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15394  luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
15395 #endif // make sure stack doesn't overflow
15396  lua_pushlstring(L, str, len);
15397  return 1;
15398  }
15399 
15400  static int push(lua_State* L, const char* str) {
15401  if (str == nullptr)
15402  return stack::push(L, lua_nil);
15403  return push_sized(L, str, std::char_traits<char>::length(str));
15404  }
15405 
15406  static int push(lua_State* L, const char* strb, const char* stre) {
15407  return push_sized(L, strb, static_cast<std::size_t>(stre - strb));
15408  }
15409 
15410  static int push(lua_State* L, const char* str, std::size_t len) {
15411  return push_sized(L, str, len);
15412  }
15413  };
15414 
15415  template <>
15416  struct unqualified_pusher<char*> {
15417  static int push_sized(lua_State* L, const char* str, std::size_t len) {
15419  (void)p;
15420  return p.push_sized(L, str, len);
15421  }
15422 
15423  static int push(lua_State* L, const char* str) {
15425  (void)p;
15426  return p.push(L, str);
15427  }
15428 
15429  static int push(lua_State* L, const char* strb, const char* stre) {
15431  (void)p;
15432  return p.push(L, strb, stre);
15433  }
15434 
15435  static int push(lua_State* L, const char* str, std::size_t len) {
15437  (void)p;
15438  return p.push(L, str, len);
15439  }
15440  };
15441 
15442  template <size_t N>
15443  struct unqualified_pusher<char[N]> {
15444  static int push(lua_State* L, const char (&str)[N]) {
15445 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15446  luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
15447 #endif // make sure stack doesn't overflow
15448  lua_pushlstring(L, str, std::char_traits<char>::length(str));
15449  return 1;
15450  }
15451 
15452  static int push(lua_State* L, const char (&str)[N], std::size_t sz) {
15453 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15454  luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
15455 #endif // make sure stack doesn't overflow
15456  lua_pushlstring(L, str, sz);
15457  return 1;
15458  }
15459  };
15460 
15461  template <>
15462  struct unqualified_pusher<char> {
15463  static int push(lua_State* L, char c) {
15464  const char str[2] = { c, '\0' };
15465  return stack::push(L, static_cast<const char*>(str), 1u);
15466  }
15467  };
15468 
15469 #if SOL_IS_ON(SOL_CHAR8_T)
15470  template <>
15471  struct unqualified_pusher<const char8_t*> {
15472  static int push_sized(lua_State* L, const char8_t* str, std::size_t len) {
15473 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15474  luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
15475 #endif // make sure stack doesn't overflow
15476  lua_pushlstring(L, reinterpret_cast<const char*>(str), len);
15477  return 1;
15478  }
15479 
15480  static int push(lua_State* L, const char8_t* str) {
15481  if (str == nullptr)
15482  return stack::push(L, lua_nil);
15483  return push_sized(L, str, std::char_traits<char>::length(reinterpret_cast<const char*>(str)));
15484  }
15485 
15486  static int push(lua_State* L, const char8_t* strb, const char8_t* stre) {
15487  return push_sized(L, strb, static_cast<std::size_t>(stre - strb));
15488  }
15489 
15490  static int push(lua_State* L, const char8_t* str, std::size_t len) {
15491  return push_sized(L, str, len);
15492  }
15493  };
15494 
15495  template <>
15496  struct unqualified_pusher<char8_t*> {
15497  static int push_sized(lua_State* L, const char8_t* str, std::size_t len) {
15499  (void)p;
15500  return p.push_sized(L, str, len);
15501  }
15502 
15503  static int push(lua_State* L, const char8_t* str) {
15505  (void)p;
15506  return p.push(L, str);
15507  }
15508 
15509  static int push(lua_State* L, const char8_t* strb, const char8_t* stre) {
15511  (void)p;
15512  return p.push(L, strb, stre);
15513  }
15514 
15515  static int push(lua_State* L, const char8_t* str, std::size_t len) {
15517  (void)p;
15518  return p.push(L, str, len);
15519  }
15520  };
15521 
15522  template <size_t N>
15523  struct unqualified_pusher<char8_t[N]> {
15524  static int push(lua_State* L, const char8_t (&str)[N]) {
15525 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15526  luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
15527 #endif // make sure stack doesn't overflow
15528  const char* str_as_char = reinterpret_cast<const char*>(static_cast<const char8_t*>(str));
15529  lua_pushlstring(L, str_as_char, std::char_traits<char>::length(str_as_char));
15530  return 1;
15531  }
15532 
15533  static int push(lua_State* L, const char8_t (&str)[N], std::size_t sz) {
15534 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15535  luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
15536 #endif // make sure stack doesn't overflow
15537  lua_pushlstring(L, str, sz);
15538  return 1;
15539  }
15540  };
15541 
15542  template <>
15543  struct unqualified_pusher<char8_t> {
15544  static int push(lua_State* L, char8_t c) {
15545  const char8_t str[2] = { c, '\0' };
15546  return stack::push(L, static_cast<const char8_t*>(str), 1u);
15547  }
15548  };
15549 #endif // char8_t
15550 
15551  template <typename Ch, typename Traits, typename Al>
15552  struct unqualified_pusher<std::basic_string<Ch, Traits, Al>> {
15553  static int push(lua_State* L, const std::basic_string<Ch, Traits, Al>& str) {
15554  if constexpr (!std::is_same_v<Ch, char>) {
15555  return stack::push(L, str.data(), str.size());
15556  }
15557  else {
15558 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15559  luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
15560 #endif // make sure stack doesn't overflow
15561  lua_pushlstring(L, str.c_str(), str.size());
15562  return 1;
15563  }
15564  }
15565 
15566  static int push(lua_State* L, const std::basic_string<Ch, Traits, Al>& str, std::size_t sz) {
15567  if constexpr (!std::is_same_v<Ch, char>) {
15568  return stack::push(L, str.data(), sz);
15569  }
15570  else {
15571 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15572  luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
15573 #endif // make sure stack doesn't overflow
15574  lua_pushlstring(L, str.c_str(), sz);
15575  return 1;
15576  }
15577  }
15578  };
15579 
15580  template <typename Ch, typename Traits>
15581  struct unqualified_pusher<basic_string_view<Ch, Traits>> {
15582  static int push(lua_State* L, const basic_string_view<Ch, Traits>& sv) {
15583  return stack::push(L, sv.data(), sv.length());
15584  }
15585 
15586  static int push(lua_State* L, const basic_string_view<Ch, Traits>& sv, std::size_t n) {
15587  return stack::push(L, sv.data(), n);
15588  }
15589  };
15590 
15591  template <>
15592  struct unqualified_pusher<meta_function> {
15593  static int push(lua_State* L, meta_function m) {
15594 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15595  luaL_checkstack(L, 1, detail::not_enough_stack_space_meta_function_name);
15596 #endif // make sure stack doesn't overflow
15597  const std::string& str = to_string(m);
15598  lua_pushlstring(L, str.c_str(), str.size());
15599  return 1;
15600  }
15601  };
15602 
15603  template <>
15605  static int push(lua_State* L, absolute_index ai) {
15606 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15607  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15608 #endif // make sure stack doesn't overflow
15609  lua_pushvalue(L, ai);
15610  return 1;
15611  }
15612  };
15613 
15614  template <>
15616  static int push(lua_State* L, raw_index ri) {
15617 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15618  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15619 #endif // make sure stack doesn't overflow
15620  lua_pushvalue(L, ri);
15621  return 1;
15622  }
15623  };
15624 
15625  template <>
15627  static int push(lua_State* L, ref_index ri) {
15628 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15629  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
15630 #endif // make sure stack doesn't overflow
15631  lua_rawgeti(L, LUA_REGISTRYINDEX, ri);
15632  return 1;
15633  }
15634  };
15635 
15636  template <>
15637  struct unqualified_pusher<const wchar_t*> {
15638  static int push(lua_State* L, const wchar_t* wstr) {
15639  return push(L, wstr, std::char_traits<wchar_t>::length(wstr));
15640  }
15641 
15642  static int push(lua_State* L, const wchar_t* wstr, std::size_t sz) {
15643  return push(L, wstr, wstr + sz);
15644  }
15645 
15646  static int push(lua_State* L, const wchar_t* strb, const wchar_t* stre) {
15647  if constexpr (sizeof(wchar_t) == 2) {
15648  const char16_t* sb = reinterpret_cast<const char16_t*>(strb);
15649  const char16_t* se = reinterpret_cast<const char16_t*>(stre);
15650  return stack::push(L, sb, se);
15651  }
15652  else {
15653  const char32_t* sb = reinterpret_cast<const char32_t*>(strb);
15654  const char32_t* se = reinterpret_cast<const char32_t*>(stre);
15655  return stack::push(L, sb, se);
15656  }
15657  }
15658  };
15659 
15660  template <>
15661  struct unqualified_pusher<wchar_t*> {
15662  static int push(lua_State* L, const wchar_t* str) {
15664  (void)p;
15665  return p.push(L, str);
15666  }
15667 
15668  static int push(lua_State* L, const wchar_t* strb, const wchar_t* stre) {
15670  (void)p;
15671  return p.push(L, strb, stre);
15672  }
15673 
15674  static int push(lua_State* L, const wchar_t* str, std::size_t len) {
15676  (void)p;
15677  return p.push(L, str, len);
15678  }
15679  };
15680 
15681  template <>
15682  struct unqualified_pusher<const char16_t*> {
15683  static int convert_into(lua_State* L, char* start, std::size_t, const char16_t* strb, const char16_t* stre) {
15684  char* target = start;
15685  char32_t cp = 0;
15686  for (const char16_t* strtarget = strb; strtarget < stre;) {
15687  auto dr = unicode::utf16_to_code_point(strtarget, stre);
15688  if (dr.error != unicode::error_code::ok) {
15689  cp = unicode::unicode_detail::replacement;
15690  }
15691  else {
15692  cp = dr.codepoint;
15693  }
15694  auto er = unicode::code_point_to_utf8(cp);
15695  const char* utf8data = er.code_units.data();
15696  std::memcpy(target, utf8data, er.code_units_size);
15697  target += er.code_units_size;
15698  strtarget = dr.next;
15699  }
15700 
15701  return stack::push(L, start, target);
15702  }
15703 
15704  static int push(lua_State* L, const char16_t* u16str) {
15705  return push(L, u16str, std::char_traits<char16_t>::length(u16str));
15706  }
15707 
15708  static int push(lua_State* L, const char16_t* u16str, std::size_t sz) {
15709  return push(L, u16str, u16str + sz);
15710  }
15711 
15712  static int push(lua_State* L, const char16_t* strb, const char16_t* stre) {
15713  char sbo[SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_];
15714  // if our max string space is small enough, use SBO
15715  // right off the bat
15716  std::size_t max_possible_code_units = static_cast<std::size_t>(static_cast<std::size_t>(stre - strb) * static_cast<std::size_t>(4));
15717  if (max_possible_code_units <= SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_) {
15718  return convert_into(L, sbo, max_possible_code_units, strb, stre);
15719  }
15720  // otherwise, we must manually count/check size
15721  std::size_t needed_size = 0;
15722  for (const char16_t* strtarget = strb; strtarget < stre;) {
15723  auto dr = unicode::utf16_to_code_point(strtarget, stre);
15724  auto er = unicode::code_point_to_utf8(dr.codepoint);
15725  needed_size += er.code_units_size;
15726  strtarget = dr.next;
15727  }
15728  if (needed_size < SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_) {
15729  return convert_into(L, sbo, needed_size, strb, stre);
15730  }
15731  std::string u8str("", 0);
15732  u8str.resize(needed_size);
15733  char* target = const_cast<char*>(u8str.data());
15734  return convert_into(L, target, needed_size, strb, stre);
15735  }
15736  };
15737 
15738  template <>
15739  struct unqualified_pusher<char16_t*> {
15740  static int push(lua_State* L, const char16_t* str) {
15742  (void)p;
15743  return p.push(L, str);
15744  }
15745 
15746  static int push(lua_State* L, const char16_t* strb, const char16_t* stre) {
15748  (void)p;
15749  return p.push(L, strb, stre);
15750  }
15751 
15752  static int push(lua_State* L, const char16_t* str, std::size_t len) {
15754  (void)p;
15755  return p.push(L, str, len);
15756  }
15757  };
15758 
15759  template <>
15760  struct unqualified_pusher<const char32_t*> {
15761  static int convert_into(lua_State* L, char* start, std::size_t, const char32_t* strb, const char32_t* stre) {
15762  char* target = start;
15763  char32_t cp = 0;
15764  for (const char32_t* strtarget = strb; strtarget < stre;) {
15765  auto dr = unicode::utf32_to_code_point(strtarget, stre);
15766  if (dr.error != unicode::error_code::ok) {
15767  cp = unicode::unicode_detail::replacement;
15768  }
15769  else {
15770  cp = dr.codepoint;
15771  }
15772  auto er = unicode::code_point_to_utf8(cp);
15773  const char* data = er.code_units.data();
15774  std::memcpy(target, data, er.code_units_size);
15775  target += er.code_units_size;
15776  strtarget = dr.next;
15777  }
15778  return stack::push(L, start, target);
15779  }
15780 
15781  static int push(lua_State* L, const char32_t* u32str) {
15782  return push(L, u32str, u32str + std::char_traits<char32_t>::length(u32str));
15783  }
15784 
15785  static int push(lua_State* L, const char32_t* u32str, std::size_t sz) {
15786  return push(L, u32str, u32str + sz);
15787  }
15788 
15789  static int push(lua_State* L, const char32_t* strb, const char32_t* stre) {
15790  char sbo[SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_];
15791  // if our max string space is small enough, use SBO
15792  // right off the bat
15793  std::size_t max_possible_code_units = static_cast<std::size_t>(static_cast<std::size_t>(stre - strb) * static_cast<std::size_t>(4));
15794  if (max_possible_code_units <= SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_) {
15795  return convert_into(L, sbo, max_possible_code_units, strb, stre);
15796  }
15797  // otherwise, we must manually count/check size
15798  std::size_t needed_size = 0;
15799  for (const char32_t* strtarget = strb; strtarget < stre;) {
15800  auto dr = unicode::utf32_to_code_point(strtarget, stre);
15801  auto er = unicode::code_point_to_utf8(dr.codepoint);
15802  needed_size += er.code_units_size;
15803  strtarget = dr.next;
15804  }
15805  if (needed_size < SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_) {
15806  return convert_into(L, sbo, needed_size, strb, stre);
15807  }
15808  std::string u8str("", 0);
15809  u8str.resize(needed_size);
15810  char* target = const_cast<char*>(u8str.data());
15811  return convert_into(L, target, needed_size, strb, stre);
15812  }
15813  };
15814 
15815  template <>
15816  struct unqualified_pusher<char32_t*> {
15817  static int push(lua_State* L, const char32_t* str) {
15819  (void)p;
15820  return p.push(L, str);
15821  }
15822 
15823  static int push(lua_State* L, const char32_t* strb, const char32_t* stre) {
15825  (void)p;
15826  return p.push(L, strb, stre);
15827  }
15828 
15829  static int push(lua_State* L, const char32_t* str, std::size_t len) {
15831  (void)p;
15832  return p.push(L, str, len);
15833  }
15834  };
15835 
15836  template <size_t N>
15837  struct unqualified_pusher<wchar_t[N]> {
15838  static int push(lua_State* L, const wchar_t (&str)[N]) {
15839  return push(L, str, std::char_traits<wchar_t>::length(str));
15840  }
15841 
15842  static int push(lua_State* L, const wchar_t (&str)[N], std::size_t sz) {
15843  const wchar_t* str_ptr = static_cast<const wchar_t*>(str);
15844  return stack::push<const wchar_t*>(L, str_ptr, str_ptr + sz);
15845  }
15846  };
15847 
15848  template <size_t N>
15849  struct unqualified_pusher<char16_t[N]> {
15850  static int push(lua_State* L, const char16_t (&str)[N]) {
15851  return push(L, str, std::char_traits<char16_t>::length(str));
15852  }
15853 
15854  static int push(lua_State* L, const char16_t (&str)[N], std::size_t sz) {
15855  const char16_t* str_ptr = static_cast<const char16_t*>(str);
15856  return stack::push<const char16_t*>(L, str_ptr, str_ptr + sz);
15857  }
15858  };
15859 
15860  template <size_t N>
15861  struct unqualified_pusher<char32_t[N]> {
15862  static int push(lua_State* L, const char32_t (&str)[N]) {
15863  return push(L, str, std::char_traits<char32_t>::length(str));
15864  }
15865 
15866  static int push(lua_State* L, const char32_t (&str)[N], std::size_t sz) {
15867  const char32_t* str_ptr = static_cast<const char32_t*>(str);
15868  return stack::push<const char32_t*>(L, str_ptr, str_ptr + sz);
15869  }
15870  };
15871 
15872  template <>
15873  struct unqualified_pusher<wchar_t> {
15874  static int push(lua_State* L, wchar_t c) {
15875  const wchar_t str[2] = { c, '\0' };
15876  return stack::push(L, static_cast<const wchar_t*>(str), 1u);
15877  }
15878  };
15879 
15880  template <>
15881  struct unqualified_pusher<char16_t> {
15882  static int push(lua_State* L, char16_t c) {
15883  const char16_t str[2] = { c, '\0' };
15884  return stack::push(L, static_cast<const char16_t*>(str), 1u);
15885  }
15886  };
15887 
15888  template <>
15889  struct unqualified_pusher<char32_t> {
15890  static int push(lua_State* L, char32_t c) {
15891  const char32_t str[2] = { c, '\0' };
15892  return stack::push(L, static_cast<const char32_t*>(str), 1u);
15893  }
15894  };
15895 
15896  template <typename... Args>
15897  struct unqualified_pusher<std::tuple<Args...>> {
15898  template <std::size_t... I, typename T>
15899  static int push(std::index_sequence<I...>, lua_State* L, T&& t) {
15900 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15901  luaL_checkstack(L, static_cast<int>(sizeof...(I)), detail::not_enough_stack_space_generic);
15902 #endif // make sure stack doesn't overflow
15903  int pushcount = 0;
15904  (void)detail::swallow { 0, (pushcount += stack::push(L, std::get<I>(std::forward<T>(t))), 0)... };
15905  return pushcount;
15906  }
15907 
15908  template <typename T>
15909  static int push(lua_State* L, T&& t) {
15910  return push(std::index_sequence_for<Args...>(), L, std::forward<T>(t));
15911  }
15912  };
15913 
15914  template <typename A, typename B>
15915  struct unqualified_pusher<std::pair<A, B>> {
15916  template <typename T>
15917  static int push(lua_State* L, T&& t) {
15918  int pushcount = stack::push(L, std::get<0>(std::forward<T>(t)));
15919  pushcount += stack::push(L, std::get<1>(std::forward<T>(t)));
15920  return pushcount;
15921  }
15922  };
15923 
15924  template <typename T>
15925  struct unqualified_pusher<T, std::enable_if_t<meta::is_optional_v<T>>> {
15926  using ValueType = typename meta::unqualified_t<T>::value_type;
15927 
15928  template <typename Optional>
15929  static int push(lua_State* L, Optional&& op) {
15930  using QualifiedValueType = meta::conditional_t<std::is_lvalue_reference_v<Optional>, ValueType&, ValueType&&>;
15931  if (!op) {
15932  return stack::push(L, nullopt);
15933  }
15934  return stack::push(L, static_cast<QualifiedValueType>(op.value()));
15935  }
15936  };
15937 
15938  template <typename T>
15940  static int push(lua_State* L, const forward_as_value_t<T>& value_) {
15941  return stack::push<T>(L, value_.value());
15942  }
15943 
15944  static int push(lua_State* L, forward_as_value_t<T>&& value_) {
15945  return stack::push<T>(L, std::move(value_).value());
15946  }
15947  };
15948 
15949  template <>
15950  struct unqualified_pusher<nullopt_t> {
15951  static int push(lua_State* L, nullopt_t) noexcept {
15952  return stack::push(L, lua_nil);
15953  }
15954  };
15955 
15956  template <>
15957  struct unqualified_pusher<std::nullptr_t> {
15958  static int push(lua_State* L, std::nullptr_t) noexcept {
15959  return stack::push(L, lua_nil);
15960  }
15961  };
15962 
15963  template <>
15965  static int push(lua_State*, const this_state&) noexcept {
15966  return 0;
15967  }
15968  };
15969 
15970  template <>
15972  static int push(lua_State*, const this_main_state&) noexcept {
15973  return 0;
15974  }
15975  };
15976 
15977  template <>
15979  static int push(lua_State* L, const new_table& nt) {
15980  lua_createtable(L, nt.sequence_hint, nt.map_hint);
15981  return 1;
15982  }
15983  };
15984 
15985  template <typename Allocator>
15986  struct unqualified_pusher<basic_bytecode<Allocator>> {
15987  template <typename T>
15988  static int push(lua_State* L, T&& bc, const char* bytecode_name) {
15989  const auto first = bc.data();
15990  const auto bcsize = bc.size();
15991  // pushes either the function, or an error
15992  // if it errors, shit goes south, and people can test that upstream
15993  (void)luaL_loadbuffer(
15994  L, reinterpret_cast<const char*>(first), static_cast<std::size_t>(bcsize * (sizeof(*first) / sizeof(const char))), bytecode_name);
15995  return 1;
15996  }
15997 
15998  template <typename T>
15999  static int push(lua_State* L, T&& bc) {
16000  return push(L, std::forward<bc>(bc), "bytecode");
16001  }
16002  };
16003 
16004 #if SOL_IS_ON(SOL_STD_VARIANT)
16005  namespace stack_detail {
16006 
16007  struct push_function {
16008  lua_State* L;
16009 
16010  push_function(lua_State* L_) noexcept : L(L_) {
16011  }
16012 
16013  template <typename T>
16014  int operator()(T&& value) const {
16015  return stack::push<T>(L, std::forward<T>(value));
16016  }
16017  };
16018 
16019  } // namespace stack_detail
16020 
16021  template <typename... Tn>
16022  struct unqualified_pusher<std::variant<Tn...>> {
16023  static int push(lua_State* L, const std::variant<Tn...>& v) {
16024  return std::visit(stack_detail::push_function(L), v);
16025  }
16026 
16027  static int push(lua_State* L, std::variant<Tn...>&& v) {
16028  return std::visit(stack_detail::push_function(L), std::move(v));
16029  }
16030  };
16031 #endif // Variant because Clang is terrible
16032 
16033 }} // namespace sol::stack
16034 
16035 // end of sol/stack_push.hpp
16036 
16037 // beginning of sol/stack_pop.hpp
16038 
16039 #include <utility>
16040 #include <tuple>
16041 
16042 namespace sol { namespace stack {
16043  template <typename T, typename>
16044  struct popper {
16045  inline static decltype(auto) pop(lua_State* L) {
16046  if constexpr (is_stack_based_v<meta::unqualified_t<T>>) {
16047  static_assert(!is_stack_based_v<meta::unqualified_t<T>>,
16048  "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 "
16049  "scope!");
16050  }
16051  else {
16052  record tracking {};
16053  decltype(auto) r = get<T>(L, -lua_size<T>::value, tracking);
16054  lua_pop(L, tracking.used);
16055  return r;
16056  }
16057  }
16058  };
16059 }} // namespace sol::stack
16060 
16061 // end of sol/stack_pop.hpp
16062 
16063 // beginning of sol/stack_field.hpp
16064 
16065 namespace sol { namespace stack {
16066 
16067  namespace stack_detail {
16068  template <typename T, bool global, bool raw>
16069  inline constexpr bool is_get_direct_tableless_v = (global && !raw && meta::is_c_str_or_string_v<T>);
16070 
16071  template <typename T, bool global, bool raw>
16072  inline constexpr bool is_get_direct_v = (is_get_direct_tableless_v<T, global, raw>) // cf-hack
16073  || (!global && !raw && (meta::is_c_str_or_string_v<T> || meta::is_string_of_v<T, char>)) // cf-hack
16074  || (!global && raw && (std::is_integral_v<T> && !std::is_same_v<T, bool>))
16075 #if SOL_LUA_VERSION_I_ >= 503
16076  || (!global && !raw && (std::is_integral_v<T> && !std::is_same_v<T, bool>))
16077 #endif // integer keys 5.3 or better
16078 #if SOL_LUA_VERSION_I_ >= 502
16079  || (!global && raw && std::is_pointer_v<T> && std::is_void_v<std::remove_pointer_t<T>>)
16080 #endif // void pointer keys 5.2 or better
16081  ;
16082 
16083  template <typename T, bool global, bool raw>
16084  inline constexpr bool is_set_direct_tableless_v = (global && !raw && meta::is_c_str_or_string_v<T>);
16085 
16086  template <typename T, bool global, bool raw>
16087  inline constexpr bool is_set_direct_v = (is_set_direct_tableless_v<T, global, raw>) // cf-hack
16088  || (!global && !raw && (meta::is_c_str_or_string_v<T> || meta::is_string_of_v<T, char>)) // cf-hack
16089  || (!global && raw && (std::is_integral_v<T> && !std::is_same_v<T, bool>)) // cf-hack
16090 #if SOL_LUA_VERSION_I_ >= 503
16091  || (!global && !raw && (std::is_integral_v<T> && !std::is_same_v<T, bool>))
16092 #endif // integer keys 5.3 or better
16093 #if SOL_LUA_VERSION_I_ >= 502
16094  || (!global && raw && (std::is_pointer_v<T> && std::is_void_v<std::remove_pointer_t<T>>))
16095 #endif // void pointer keys 5.2 or better
16096  ;
16097  } // namespace stack_detail
16098 
16099  template <typename T, bool global, bool raw, typename>
16100  struct field_getter {
16101  static inline constexpr int default_table_index
16102  = meta::conditional_t<stack_detail::is_get_direct_v<T, global, raw>, std::integral_constant<int, -1>, std::integral_constant<int, -2>>::value;
16103 
16104  template <typename Key>
16105  void get(lua_State* L, Key&& key, int tableindex = default_table_index) {
16106  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>) {
16107  (void)L;
16108  (void)key;
16109  (void)tableindex;
16110  }
16111  else if constexpr (std::is_same_v<T, env_key_t>) {
16112  (void)key;
16113 #if SOL_LUA_VERSION_I_ < 502
16114  // Use lua_setfenv
16115  lua_getfenv(L, tableindex);
16116 #else
16117  // Use upvalues as explained in Lua 5.2 and beyond's manual
16118  if (lua_getupvalue(L, tableindex, 1) == nullptr) {
16119  push(L, lua_nil);
16120  }
16121 #endif
16122  }
16123  else if constexpr (std::is_same_v<T, metatable_key_t>) {
16124  (void)key;
16125  if (lua_getmetatable(L, tableindex) == 0)
16126  push(L, lua_nil);
16127  }
16128  else if constexpr (raw) {
16129  if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
16130  lua_rawgeti(L, tableindex, static_cast<lua_Integer>(key));
16131  }
16132 #if SOL_LUA_VERSION_I_ >= 502
16133  else if constexpr (std::is_pointer_v<T> && std::is_void_v<std::remove_pointer_t<T>>) {
16134  lua_rawgetp(L, tableindex, key);
16135  }
16136 #endif // Lua 5.2.x+
16137  else {
16138  push(L, std::forward<Key>(key));
16139  lua_rawget(L, tableindex);
16140  }
16141  }
16142  else {
16143  if constexpr (meta::is_c_str_or_string_v<T>) {
16144  if constexpr (global) {
16145  (void)tableindex;
16146  lua_getglobal(L, &key[0]);
16147  }
16148  else {
16149  lua_getfield(L, tableindex, &key[0]);
16150  }
16151  }
16152  else if constexpr (std::is_same_v<T, meta_function>) {
16153  const auto& real_key = to_string(key);
16154  lua_getfield(L, tableindex, &real_key[0]);
16155  }
16156 #if SOL_LUA_VERSION_I_ >= 503
16157  else if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
16158  lua_geti(L, tableindex, static_cast<lua_Integer>(key));
16159  }
16160 #endif // Lua 5.3.x+
16161  else {
16162  push(L, std::forward<Key>(key));
16163  lua_gettable(L, tableindex);
16164  }
16165  }
16166  }
16167  };
16168 
16169  template <typename... Args, bool b, bool raw, typename C>
16170  struct field_getter<std::tuple<Args...>, b, raw, C> {
16171  template <std::size_t... I, typename Keys>
16172  void apply(std::index_sequence<0, I...>, lua_State* L, Keys&& keys, int tableindex) {
16173  get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)), tableindex);
16174  void(detail::swallow { (get_field<false, raw>(L, std::get<I>(std::forward<Keys>(keys))), 0)... });
16175  reference saved(L, -1);
16176  lua_pop(L, static_cast<int>(sizeof...(I)));
16177  saved.push();
16178  }
16179 
16180  template <typename Keys>
16181  void get(lua_State* L, Keys&& keys) {
16182  apply(std::make_index_sequence<sizeof...(Args)>(), L, std::forward<Keys>(keys), lua_absindex(L, -1));
16183  }
16184 
16185  template <typename Keys>
16186  void get(lua_State* L, Keys&& keys, int tableindex) {
16187  apply(std::make_index_sequence<sizeof...(Args)>(), L, std::forward<Keys>(keys), tableindex);
16188  }
16189  };
16190 
16191  template <typename A, typename B, bool b, bool raw, typename C>
16192  struct field_getter<std::pair<A, B>, b, raw, C> {
16193  template <typename Keys>
16194  void get(lua_State* L, Keys&& keys, int tableindex) {
16195  get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)), tableindex);
16196  get_field<false, raw>(L, std::get<1>(std::forward<Keys>(keys)));
16197  reference saved(L, -1);
16198  lua_pop(L, static_cast<int>(2));
16199  saved.push();
16200  }
16201 
16202  template <typename Keys>
16203  void get(lua_State* L, Keys&& keys) {
16204  get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)));
16205  get_field<false, raw>(L, std::get<1>(std::forward<Keys>(keys)));
16206  reference saved(L, -1);
16207  lua_pop(L, static_cast<int>(2));
16208  saved.push();
16209  }
16210  };
16211 
16212  template <typename T, bool global, bool raw, typename>
16213  struct field_setter {
16214  static constexpr int default_table_index
16215  = meta::conditional_t<stack_detail::is_set_direct_v<T, global, raw>, std::integral_constant<int, -2>, std::integral_constant<int, -3>>::value;
16216 
16217  template <typename Key, typename Value>
16218  void set(lua_State* L, Key&& key, Value&& value, int tableindex = default_table_index) {
16219  if constexpr (std::is_same_v<T, update_if_empty_t> || std::is_same_v<T, override_value_t>) {
16220  (void)L;
16221  (void)key;
16222  (void)value;
16223  (void)tableindex;
16224  }
16225  else if constexpr (std::is_same_v<T, metatable_key_t>) {
16226  (void)key;
16227  push(L, std::forward<Value>(value));
16228  lua_setmetatable(L, tableindex);
16229  }
16230  else if constexpr (raw) {
16231  if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
16232  push(L, std::forward<Value>(value));
16233  lua_rawseti(L, tableindex, static_cast<lua_Integer>(key));
16234  }
16235 #if SOL_LUA_VERSION_I_ >= 502
16236  else if constexpr (std::is_pointer_v<T> && std::is_void_v<std::remove_pointer_t<T>>) {
16237  push(L, std::forward<Value>(value));
16238  lua_rawsetp(L, tableindex, std::forward<Key>(key));
16239  }
16240 #endif // Lua 5.2.x
16241  else {
16242  push(L, std::forward<Key>(key));
16243  push(L, std::forward<Value>(value));
16244  lua_rawset(L, tableindex);
16245  }
16246  }
16247  else {
16248  if constexpr (meta::is_c_str_or_string_v<T>) {
16249  if constexpr (global) {
16250  push(L, std::forward<Value>(value));
16251  lua_setglobal(L, &key[0]);
16252  (void)tableindex;
16253  }
16254  else {
16255  push(L, std::forward<Value>(value));
16256  lua_setfield(L, tableindex, &key[0]);
16257  }
16258  }
16259 #if SOL_LUA_VERSION_I_ >= 503
16260  else if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
16261  push(L, std::forward<Value>(value));
16262  lua_seti(L, tableindex, static_cast<lua_Integer>(key));
16263  }
16264 #endif // Lua 5.3.x
16265  else {
16266  push(L, std::forward<Key>(key));
16267  push(L, std::forward<Value>(value));
16268  lua_settable(L, tableindex);
16269  }
16270  }
16271  }
16272  };
16273 
16274  template <typename... Args, bool b, bool raw, typename C>
16275  struct field_setter<std::tuple<Args...>, b, raw, C> {
16276  template <bool g, std::size_t I, typename Keys, typename Value>
16277  void apply(std::index_sequence<I>, lua_State* L, Keys&& keys, Value&& value, int tableindex) {
16278  I < 1 ? set_field<g, raw>(L, std::get<I>(std::forward<Keys>(keys)), std::forward<Value>(value), tableindex)
16279  : set_field<g, raw>(L, std::get<I>(std::forward<Keys>(keys)), std::forward<Value>(value));
16280  }
16281 
16282  template <bool g, std::size_t I0, std::size_t I1, std::size_t... I, typename Keys, typename Value>
16283  void apply(std::index_sequence<I0, I1, I...>, lua_State* L, Keys&& keys, Value&& value, int tableindex) {
16284  I0 < 1 ? get_field<g, raw>(L, std::get<I0>(std::forward<Keys>(keys)), tableindex)
16285  : get_field<g, raw>(L, std::get<I0>(std::forward<Keys>(keys)), -1);
16286  apply<false>(std::index_sequence<I1, I...>(), L, std::forward<Keys>(keys), std::forward<Value>(value), -1);
16287  }
16288 
16289  template <bool g, std::size_t I0, std::size_t... I, typename Keys, typename Value>
16290  void top_apply(std::index_sequence<I0, I...>, lua_State* L, Keys&& keys, Value&& value, int tableindex) {
16291  apply<g>(std::index_sequence<I0, I...>(), L, std::forward<Keys>(keys), std::forward<Value>(value), tableindex);
16292  lua_pop(L, static_cast<int>(sizeof...(I)));
16293  }
16294 
16295  template <typename Keys, typename Value>
16296  void set(lua_State* L, Keys&& keys, Value&& value, int tableindex = -3) {
16297  top_apply<b>(std::make_index_sequence<sizeof...(Args)>(), L, std::forward<Keys>(keys), std::forward<Value>(value), tableindex);
16298  }
16299  };
16300 
16301  template <typename A, typename B, bool b, bool raw, typename C>
16302  struct field_setter<std::pair<A, B>, b, raw, C> {
16303  template <typename Keys, typename Value>
16304  void set(lua_State* L, Keys&& keys, Value&& value, int tableindex = -1) {
16305  get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)), tableindex);
16306  set_field<false, raw>(L, std::get<1>(std::forward<Keys>(keys)), std::forward<Value>(value), lua_gettop(L));
16307  lua_pop(L, 1);
16308  }
16309  };
16310 }} // namespace sol::stack
16311 
16312 // end of sol/stack_field.hpp
16313 
16314 // beginning of sol/stack_probe.hpp
16315 
16316 namespace sol { namespace stack {
16317  template <typename T, typename P, bool b, bool raw, typename>
16318  struct probe_field_getter {
16319  template <typename Key>
16320  probe get(lua_State* L, Key&& key, int tableindex = -2) {
16321  if constexpr (!b) {
16322  if (!maybe_indexable(L, tableindex)) {
16323  return probe(false, 0);
16324  }
16325  }
16326  get_field<b, raw>(L, std::forward<Key>(key), tableindex);
16327  return probe(check<P>(L), 1);
16328  }
16329  };
16330 
16331  template <typename A, typename B, typename P, bool b, bool raw, typename C>
16332  struct probe_field_getter<std::pair<A, B>, P, b, raw, C> {
16333  template <typename Keys>
16334  probe get(lua_State* L, Keys&& keys, int tableindex = -2) {
16335  if (!b && !maybe_indexable(L, tableindex)) {
16336  return probe(false, 0);
16337  }
16338  get_field<b, raw>(L, std::get<0>(keys), tableindex);
16339  if (!maybe_indexable(L)) {
16340  return probe(false, 1);
16341  }
16342  get_field<false, raw>(L, std::get<1>(keys), tableindex);
16343  return probe(check<P>(L), 2);
16344  }
16345  };
16346 
16347  template <typename... Args, typename P, bool b, bool raw, typename C>
16348  struct probe_field_getter<std::tuple<Args...>, P, b, raw, C> {
16349  template <std::size_t I, typename Keys>
16350  probe apply(std::index_sequence<I>, int sofar, lua_State* L, Keys&& keys, int tableindex) {
16351  get_field<(I < 1) && b, raw>(L, std::get<I>(keys), tableindex);
16352  return probe(check<P>(L), sofar);
16353  }
16354 
16355  template <std::size_t I, std::size_t I1, std::size_t... In, typename Keys>
16356  probe apply(std::index_sequence<I, I1, In...>, int sofar, lua_State* L, Keys&& keys, int tableindex) {
16357  get_field < I<1 && b, raw>(L, std::get<I>(keys), tableindex);
16358  if (!maybe_indexable(L)) {
16359  return probe(false, sofar);
16360  }
16361  return apply(std::index_sequence<I1, In...>(), sofar + 1, L, std::forward<Keys>(keys), -1);
16362  }
16363 
16364  template <typename Keys>
16365  probe get(lua_State* L, Keys&& keys, int tableindex = -2) {
16366  if constexpr (!b) {
16367  if (!maybe_indexable(L, tableindex)) {
16368  return probe(false, 0);
16369  }
16370  return apply(std::index_sequence_for<Args...>(), 1, L, std::forward<Keys>(keys), tableindex);
16371  }
16372  else {
16373  return apply(std::index_sequence_for<Args...>(), 1, L, std::forward<Keys>(keys), tableindex);
16374  }
16375  }
16376  };
16377 }} // namespace sol::stack
16378 
16379 // end of sol/stack_probe.hpp
16380 
16381 #include <cstring>
16382 #include <array>
16383 
16384 namespace sol {
16385  namespace detail {
16386  using typical_chunk_name_t = char[SOL_ID_SIZE_I_];
16387  using typical_file_chunk_name_t = char[SOL_FILE_ID_SIZE_I_];
16388 
16389  inline const std::string& default_chunk_name() {
16390  static const std::string name = "";
16391  return name;
16392  }
16393 
16394  template <std::size_t N>
16395  const char* make_chunk_name(const string_view& code, const std::string& chunkname, char (&basechunkname)[N]) {
16396  if (chunkname.empty()) {
16397  auto it = code.cbegin();
16398  auto e = code.cend();
16399  std::size_t i = 0;
16400  static const std::size_t n = N - 4;
16401  for (i = 0; i < n && it != e; ++i, ++it) {
16402  basechunkname[i] = *it;
16403  }
16404  if (it != e) {
16405  for (std::size_t c = 0; c < 3; ++i, ++c) {
16406  basechunkname[i] = '.';
16407  }
16408  }
16409  basechunkname[i] = '\0';
16410  return &basechunkname[0];
16411  }
16412  else {
16413  return chunkname.c_str();
16414  }
16415  }
16416 
16417  inline void clear_entries(stack_reference r) {
16418  stack::push(r.lua_state(), lua_nil);
16419  while (lua_next(r.lua_state(), -2)) {
16420  absolute_index key(r.lua_state(), -2);
16421  auto pn = stack::pop_n(r.lua_state(), 1);
16422  stack::set_field<false, true>(r.lua_state(), key, lua_nil, r.stack_index());
16423  }
16424  }
16425 
16426  inline void clear_entries(const reference& registry_reference) {
16427  auto pp = stack::push_pop(registry_reference);
16428  stack_reference ref(registry_reference.lua_state(), -1);
16429  clear_entries(ref);
16430  }
16431  } // namespace detail
16432 
16433  namespace stack {
16434  namespace stack_detail {
16435  template <typename T>
16436  inline int push_as_upvalues(lua_State* L, T& item) {
16437  typedef std::decay_t<T> TValue;
16438  static const std::size_t itemsize = sizeof(TValue);
16439  static const std::size_t voidsize = sizeof(void*);
16440  static const std::size_t voidsizem1 = voidsize - 1;
16441  static const std::size_t data_t_count = (sizeof(TValue) + voidsizem1) / voidsize;
16442  typedef std::array<void*, data_t_count> data_t;
16443 
16444  data_t data { {} };
16445  std::memcpy(&data[0], std::addressof(item), itemsize);
16446  int pushcount = 0;
16447  for (const auto& v : data) {
16448  lua_pushlightuserdata(L, v);
16449  pushcount += 1;
16450  }
16451  return pushcount;
16452  }
16453 
16454  template <typename T>
16455  inline std::pair<T, int> get_as_upvalues(lua_State* L, int index = 2) {
16456  static const std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*);
16457  typedef std::array<void*, data_t_count> data_t;
16458  data_t voiddata { {} };
16459  for (std::size_t i = 0, d = 0; d < sizeof(T); ++i, d += sizeof(void*)) {
16460  voiddata[i] = lua_touserdata(L, upvalue_index(index++));
16461  }
16462  return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index);
16463  }
16464 
16465  template <typename T>
16466  inline std::pair<T, int> get_as_upvalues_using_function(lua_State* L, int function_index = -1) {
16467  static const std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*);
16468  typedef std::array<void*, data_t_count> data_t;
16469  function_index = lua_absindex(L, function_index);
16470  int index = 0;
16471  data_t voiddata { {} };
16472  for (std::size_t d = 0; d < sizeof(T); d += sizeof(void*)) {
16473  // first upvalue is nullptr to respect environment shenanigans
16474  // So +2 instead of +1
16475  const char* upvalue_name = lua_getupvalue(L, function_index, index + 2);
16476  if (upvalue_name == nullptr) {
16477  // We should freak out here...
16478  break;
16479  }
16480  voiddata[index] = lua_touserdata(L, -1);
16481  ++index;
16482  }
16483  lua_pop(L, index);
16484  return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index);
16485  }
16486 
16487  template <bool checked, typename Handler, typename Fx, typename... Args>
16488  static decltype(auto) eval(types<>, std::index_sequence<>, lua_State*, int, Handler&&, record&, Fx&& fx, Args&&... args) {
16489  return std::forward<Fx>(fx)(std::forward<Args>(args)...);
16490  }
16491 
16492  template <bool checked, typename Arg, typename... Args, std::size_t I, std::size_t... Is, typename Handler, typename Fx, typename... FxArgs>
16493  static decltype(auto) eval(types<Arg, Args...>, std::index_sequence<I, Is...>, lua_State* L_, int start_index_, Handler&& handler_,
16494  record& tracking_, Fx&& fx_, FxArgs&&... fxargs_) {
16495 #if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS)
16496  // We can save performance/time by letting errors unwind produced arguments
16497  // rather than checking everything once, and then potentially re-doing work
16498  if constexpr (checked) {
16499  return eval<checked>(types<Args...>(),
16500  std::index_sequence<Is...>(),
16501  L_,
16502  start_index_,
16503  std::forward<Handler>(handler_),
16504  tracking_,
16505  std::forward<Fx>(fx_),
16506  std::forward<FxArgs>(fxargs_)...,
16507  *stack_detail::check_get_arg<Arg>(L_, start_index_ + tracking_.used, handler_, tracking_));
16508  }
16509  else
16510 #endif
16511  {
16512  return eval<checked>(types<Args...>(),
16513  std::index_sequence<Is...>(),
16514  L_,
16515  start_index_,
16516  std::forward<Handler>(handler_),
16517  tracking_,
16518  std::forward<Fx>(fx_),
16519  std::forward<FxArgs>(fxargs_)...,
16520  stack_detail::unchecked_get_arg<Arg>(L_, start_index_ + tracking_.used, tracking_));
16521  }
16522  }
16523 
16524  template <bool checkargs = detail::default_safe_function_calls, std::size_t... I, typename R, typename... Args, typename Fx, typename... FxArgs>
16525  inline decltype(auto) call(types<R>, types<Args...> argument_types_, std::index_sequence<I...> argument_indices_, lua_State* L_,
16526  int start_index_, Fx&& fx_, FxArgs&&... args_) {
16527  static_assert(meta::all_v<meta::is_not_move_only<Args>...>,
16528  "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 "
16529  "a reference and std::move it manually if this was your intention.");
16530  argument_handler<types<R, Args...>> handler {};
16531  record tracking {};
16532 #if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS)
16533  if constexpr (checkargs) {
16534  multi_check<Args...>(L_, start_index_, handler);
16535  }
16536 #endif
16537  if constexpr (std::is_void_v<R>) {
16538  eval<checkargs>(
16539  argument_types_, argument_indices_, L_, start_index_, handler, tracking, std::forward<Fx>(fx_), std::forward<FxArgs>(args_)...);
16540  }
16541  else {
16542  return eval<checkargs>(
16543  argument_types_, argument_indices_, L_, start_index_, handler, tracking, std::forward<Fx>(fx_), std::forward<FxArgs>(args_)...);
16544  }
16545  }
16546 
16547  template <typename T>
16548  void raw_table_set(lua_State* L, T&& arg, int tableindex = -2) {
16549  int push_count = push(L, std::forward<T>(arg));
16550  sol_c_assert(push_count == 1);
16551  std::size_t unique_index = static_cast<std::size_t>(luaL_len(L, tableindex) + 1u);
16552  lua_rawseti(L, tableindex, unique_index);
16553  }
16554 
16555  } // namespace stack_detail
16556 
16557  template <typename T>
16558  int set_ref(lua_State* L, T&& arg, int tableindex = -2) {
16559  int push_count = push(L, std::forward<T>(arg));
16560  sol_c_assert(push_count == 1);
16561  return luaL_ref(L, tableindex);
16562  }
16563 
16564  template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
16565  inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
16566  using args_indices = std::make_index_sequence<sizeof...(Args)>;
16567  if constexpr (std::is_void_v<R>) {
16568  stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
16569  }
16570  else {
16571  return stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
16572  }
16573  }
16574 
16575  template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
16576  inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
16577  if constexpr (std::is_void_v<R>) {
16578  call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
16579  }
16580  else {
16581  return call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
16582  }
16583  }
16584 
16585  template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
16586  inline decltype(auto) call_from_top(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
16587  using expected_count_t = meta::count_for_pack<lua_size, Args...>;
16588  if constexpr (std::is_void_v<R>) {
16589  call<check_args>(tr,
16590  ta,
16591  L,
16592  (std::max)(static_cast<int>(lua_gettop(L) - expected_count_t::value), static_cast<int>(0)),
16593  std::forward<Fx>(fx),
16594  std::forward<FxArgs>(args)...);
16595  }
16596  else {
16597  return call<check_args>(tr,
16598  ta,
16599  L,
16600  (std::max)(static_cast<int>(lua_gettop(L) - expected_count_t::value), static_cast<int>(0)),
16601  std::forward<Fx>(fx),
16602  std::forward<FxArgs>(args)...);
16603  }
16604  }
16605 
16606  template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Ret0, typename... Ret, typename... Args,
16607  typename Fx, typename... FxArgs>
16608  inline int call_into_lua(types<Ret0, Ret...> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
16609  if constexpr (std::is_void_v<Ret0>) {
16610  call<check_args>(tr, ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
16611  if constexpr (clean_stack) {
16612  lua_settop(L, 0);
16613  }
16614  return 0;
16615  }
16616  else {
16617  (void)tr;
16618  decltype(auto) r
16619  = call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
16620  using R = meta::unqualified_t<decltype(r)>;
16621  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>>;
16622  if constexpr (clean_stack && !is_stack::value) {
16623  lua_settop(L, 0);
16624  }
16625  return push_reference(L, std::forward<decltype(r)>(r));
16626  }
16627  }
16628 
16629  template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Fx, typename... FxArgs>
16630  inline int call_lua(lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
16631  using traits_type = lua_bind_traits<meta::unqualified_t<Fx>>;
16632  using args_list = typename traits_type::args_list;
16633  using returns_list = typename traits_type::returns_list;
16634  return call_into_lua<check_args, clean_stack>(returns_list(), args_list(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
16635  }
16636 
16637  inline call_syntax get_call_syntax(lua_State* L, const string_view& key, int index) {
16638  if (lua_gettop(L) < 1) {
16639  return call_syntax::dot;
16640  }
16641  luaL_getmetatable(L, key.data());
16642  auto pn = pop_n(L, 1);
16643  if (lua_compare(L, -1, index, LUA_OPEQ) != 1) {
16644  return call_syntax::dot;
16645  }
16646  return call_syntax::colon;
16647  }
16648 
16649  inline void script(
16650  lua_State* L, lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
16651  detail::typical_chunk_name_t basechunkname = {};
16652  const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
16653  if (lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
16654  lua_error(L);
16655  }
16656  }
16657 
16658  inline void script(
16659  lua_State* L, const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
16660 
16661  detail::typical_chunk_name_t basechunkname = {};
16662  const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
16663  if (luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
16664  lua_error(L);
16665  }
16666  }
16667 
16668  inline void script_file(lua_State* L, const std::string& filename, load_mode mode = load_mode::any) {
16669  if (luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
16670  lua_error(L);
16671  }
16672  }
16673 
16674  inline void luajit_exception_handler(lua_State* L, int (*handler)(lua_State*, lua_CFunction) = detail::c_trampoline) {
16675 #if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE)
16676  if (L == nullptr) {
16677  return;
16678  }
16679 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
16680  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
16681 #endif // make sure stack doesn't overflow
16682  lua_pushlightuserdata(L, (void*)handler);
16683  auto pn = pop_n(L, 1);
16684  luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON);
16685 #else
16686  (void)L;
16687  (void)handler;
16688 #endif
16689  }
16690 
16691  inline void luajit_exception_off(lua_State* L) {
16692 #if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE)
16693  if (L == nullptr) {
16694  return;
16695  }
16696  luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_OFF);
16697 #else
16698  (void)L;
16699 #endif
16700  }
16701  } // namespace stack
16702 } // namespace sol
16703 
16704 // end of sol/stack.hpp
16705 
16706 // beginning of sol/object.hpp
16707 
16708 // beginning of sol/make_reference.hpp
16709 
16710 namespace sol {
16711 
16712  template <typename R = reference, bool should_pop = !is_stack_based_v<R>, typename T>
16713  R make_reference(lua_State* L, T&& value) {
16714  int backpedal = stack::push(L, std::forward<T>(value));
16715  R r = stack::get<R>(L, -backpedal);
16716  if (should_pop) {
16717  lua_pop(L, backpedal);
16718  }
16719  return r;
16720  }
16721 
16722  template <typename T, typename R = reference, bool should_pop = !is_stack_based_v<R>, typename... Args>
16723  R make_reference(lua_State* L, Args&&... args) {
16724  int backpedal = stack::push<T>(L, std::forward<Args>(args)...);
16725  R r = stack::get<R>(L, -backpedal);
16726  if (should_pop) {
16727  lua_pop(L, backpedal);
16728  }
16729  return r;
16730  }
16731 
16732  template <typename R = reference, bool should_pop = !is_stack_based_v<R>, typename T>
16733  R make_reference_userdata(lua_State* L, T&& value) {
16734  int backpedal = stack::push_userdata(L, std::forward<T>(value));
16735  R r = stack::get<R>(L, -backpedal);
16736  if (should_pop) {
16737  lua_pop(L, backpedal);
16738  }
16739  return r;
16740  }
16741 
16742  template <typename T, typename R = reference, bool should_pop = !is_stack_based_v<R>, typename... Args>
16743  R make_reference_userdata(lua_State* L, Args&&... args) {
16744  int backpedal = stack::push_userdata<T>(L, std::forward<Args>(args)...);
16745  R r = stack::get<R>(L, -backpedal);
16746  if (should_pop) {
16747  lua_pop(L, backpedal);
16748  }
16749  return r;
16750  }
16751 
16752 } // namespace sol
16753 
16754 // end of sol/make_reference.hpp
16755 
16756 // beginning of sol/object_base.hpp
16757 
16758 namespace sol {
16759 
16760  template <typename ref_t>
16761  class basic_object_base : public ref_t {
16762  private:
16763  using base_t = ref_t;
16764 
16765  template <typename T>
16766  decltype(auto) as_stack(std::true_type) const {
16767  return stack::get<T>(base_t::lua_state(), base_t::stack_index());
16768  }
16769 
16770  template <typename T>
16771  decltype(auto) as_stack(std::false_type) const {
16772  base_t::push();
16773  return stack::pop<T>(base_t::lua_state());
16774  }
16775 
16776  template <typename T>
16777  bool is_stack(std::true_type) const {
16778  return stack::check<T>(base_t::lua_state(), base_t::stack_index(), &no_panic);
16779  }
16780 
16781  template <typename T>
16782  bool is_stack(std::false_type) const {
16783  int r = base_t::registry_index();
16784  if (r == LUA_REFNIL)
16785  return meta::any_same<meta::unqualified_t<T>, lua_nil_t, nullopt_t, std::nullptr_t>::value ? true : false;
16786  if (r == LUA_NOREF)
16787  return false;
16788  auto pp = stack::push_pop(*this);
16789  return stack::check<T>(base_t::lua_state(), -1, &no_panic);
16790  }
16791 
16792  public:
16793  basic_object_base() noexcept = default;
16794  basic_object_base(const basic_object_base&) = default;
16795  basic_object_base(basic_object_base&&) = default;
16796  basic_object_base& operator=(const basic_object_base&) = default;
16797  basic_object_base& operator=(basic_object_base&&) = default;
16798  template <typename T, typename... Args, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_object_base>>> = meta::enabler>
16799  basic_object_base(T&& arg, Args&&... args) : base_t(std::forward<T>(arg), std::forward<Args>(args)...) {
16800  }
16801 
16802  template <typename T>
16803  decltype(auto) as() const {
16804  return as_stack<T>(is_stack_based<base_t>());
16805  }
16806 
16807  template <typename T>
16808  bool is() const {
16809  return is_stack<T>(is_stack_based<base_t>());
16810  }
16811  };
16812 } // namespace sol
16813 
16814 // end of sol/object_base.hpp
16815 
16816 namespace sol {
16817 
16818  template <typename base_type>
16819  class basic_object : public basic_object_base<base_type> {
16820  private:
16821  typedef basic_object_base<base_type> base_t;
16822 
16823  template <bool invert_and_pop = false>
16824  basic_object(std::integral_constant<bool, invert_and_pop>, lua_State* L_, int index_ = -1) noexcept : base_t(L_, index_) {
16825  if (invert_and_pop) {
16826  lua_pop(L_, -index_);
16827  }
16828  }
16829 
16830  protected:
16831  basic_object(detail::no_safety_tag, lua_nil_t n) : base_t(n) {
16832  }
16833  basic_object(detail::no_safety_tag, lua_State* L_, int index_) : base_t(L_, index_) {
16834  }
16835  basic_object(detail::no_safety_tag, lua_State* L_, ref_index index_) : base_t(L_, index_) {
16836  }
16837  template <typename T,
16838  meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_object>>, meta::neg<std::is_same<base_type, stack_reference>>,
16839  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
16840  basic_object(detail::no_safety_tag, T&& r) noexcept : base_t(std::forward<T>(r)) {
16841  }
16842 
16843  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
16844  basic_object(detail::no_safety_tag, lua_State* L_, T&& r) noexcept : base_t(L_, std::forward<T>(r)) {
16845  }
16846 
16847  public:
16848  basic_object() noexcept = default;
16849  template <typename T,
16850  meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_object>>, meta::neg<std::is_same<base_type, stack_reference>>,
16851  is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
16852  basic_object(T&& r) : base_t(std::forward<T>(r)) {
16853  }
16854  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
16855  basic_object(lua_State* L_, T&& r) : base_t(L_, std::forward<T>(r)) {
16856  }
16857  basic_object(lua_State* L_, global_tag_t t) : base_t(L_, t) {
16858  }
16859  basic_object(lua_nil_t r) : base_t(r) {
16860  }
16861  basic_object(const basic_object&) = default;
16862  basic_object(basic_object&&) = default;
16863  basic_object(const stack_reference& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {
16864  }
16865  basic_object(stack_reference&& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {
16866  }
16867  template <typename Super>
16868  basic_object(const proxy_base<Super>& r) noexcept : basic_object(r.operator basic_object()) {
16869  }
16870  template <typename Super>
16871  basic_object(proxy_base<Super>&& r) noexcept : basic_object(r.operator basic_object()) {
16872  }
16873  basic_object(lua_State* L_, lua_nil_t r) noexcept : base_t(L_, r) {
16874  }
16875  basic_object(lua_State* L_, int index_ = -1) noexcept : base_t(L_, index_) {
16876  }
16877  basic_object(lua_State* L_, absolute_index index_) noexcept : base_t(L_, index_) {
16878  }
16879  basic_object(lua_State* L_, raw_index index_) noexcept : base_t(L_, index_) {
16880  }
16881  basic_object(lua_State* L_, ref_index index_) noexcept : base_t(L_, index_) {
16882  }
16883  template <typename T, typename... Args>
16884  basic_object(lua_State* L_, in_place_type_t<T>, Args&&... args) noexcept
16885  : basic_object(std::integral_constant<bool, !is_stack_based<base_t>::value>(), L_, -stack::push<T>(L_, std::forward<Args>(args)...)) {
16886  }
16887  template <typename T, typename... Args>
16888  basic_object(lua_State* L_, in_place_t, T&& arg, Args&&... args) noexcept
16889  : basic_object(L_, in_place_type<T>, std::forward<T>(arg), std::forward<Args>(args)...) {
16890  }
16891  basic_object& operator=(const basic_object&) = default;
16892  basic_object& operator=(basic_object&&) = default;
16893  basic_object& operator=(const base_type& b) {
16894  base_t::operator=(b);
16895  return *this;
16896  }
16897  basic_object& operator=(base_type&& b) {
16898  base_t::operator=(std::move(b));
16899  return *this;
16900  }
16901  template <typename Super>
16902  basic_object& operator=(const proxy_base<Super>& r) {
16903  this->operator=(r.operator basic_object());
16904  return *this;
16905  }
16906  template <typename Super>
16907  basic_object& operator=(proxy_base<Super>&& r) {
16908  this->operator=(r.operator basic_object());
16909  return *this;
16910  }
16911  };
16912 
16913  template <typename T>
16914  object make_object(lua_State* L_, T&& value) {
16915  return make_reference<object, true>(L_, std::forward<T>(value));
16916  }
16917 
16918  template <typename T, typename... Args>
16919  object make_object(lua_State* L_, Args&&... args) {
16920  return make_reference<T, object, true>(L_, std::forward<Args>(args)...);
16921  }
16922 
16923  template <typename T>
16924  object make_object_userdata(lua_State* L_, T&& value) {
16925  return make_reference_userdata<object, true>(L_, std::forward<T>(value));
16926  }
16927 
16928  template <typename T, typename... Args>
16929  object make_object_userdata(lua_State* L_, Args&&... args) {
16930  return make_reference_userdata<T, object, true>(L_, std::forward<Args>(args)...);
16931  }
16932 } // namespace sol
16933 
16934 // end of sol/object.hpp
16935 
16936 // beginning of sol/function.hpp
16937 
16938 // beginning of sol/unsafe_function.hpp
16939 
16940 // beginning of sol/function_result.hpp
16941 
16942 // beginning of sol/protected_function_result.hpp
16943 
16944 // beginning of sol/proxy_base.hpp
16945 
16946 namespace sol {
16947  struct proxy_base_tag { };
16948 
16949  namespace detail {
16950  template <typename T>
16951  using proxy_key_t = meta::conditional_t<meta::is_specialization_of_v<meta::unqualified_t<T>, std::tuple>, T,
16952  std::tuple<meta::conditional_t<std::is_array_v<meta::unqualified_t<T>>, std::remove_reference_t<T>&, meta::unqualified_t<T>>>>;
16953  }
16954 
16955  template <typename Super>
16956  struct proxy_base : public proxy_base_tag {
16957  lua_State* lua_state() const {
16958  const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
16959  return super.lua_state();
16960  }
16961 
16962  operator std::string() const {
16963  const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
16964  return super.template get<std::string>();
16965  }
16966 
16967  template <typename T, meta::enable<meta::neg<meta::is_string_constructible<T>>, is_proxy_primitive<meta::unqualified_t<T>>> = meta::enabler>
16968  operator T() const {
16969  const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
16970  return super.template get<T>();
16971  }
16972 
16973  template <typename T,
16974  meta::enable<meta::neg<meta::is_string_constructible<T>>, meta::neg<is_proxy_primitive<meta::unqualified_t<T>>>> = meta::enabler>
16975  operator T&() const {
16976  const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
16977  return super.template get<T&>();
16978  }
16979  };
16980 
16981 } // namespace sol
16982 
16983 // end of sol/proxy_base.hpp
16984 
16985 // beginning of sol/stack_iterator.hpp
16986 
16987 #include <limits>
16988 #include <iterator>
16989 
16990 namespace sol {
16991  template <typename proxy_t, bool is_const>
16993  typedef meta::conditional_t<is_const, const proxy_t, proxy_t> reference;
16994  typedef meta::conditional_t<is_const, const proxy_t*, proxy_t*> pointer;
16995  typedef proxy_t value_type;
16996  typedef std::ptrdiff_t difference_type;
16997  typedef std::random_access_iterator_tag iterator_category;
16998  lua_State* L;
16999  int index;
17000  int stacktop;
17001  proxy_t sp;
17002 
17003  stack_iterator() : L(nullptr), index((std::numeric_limits<int>::max)()), stacktop((std::numeric_limits<int>::max)()), sp() {
17004  }
17005  stack_iterator(const stack_iterator<proxy_t, true>& r) : L(r.L), index(r.index), stacktop(r.stacktop), sp(r.sp) {
17006  }
17007  stack_iterator(lua_State* luastate, int idx, int topidx) : L(luastate), index(idx), stacktop(topidx), sp(luastate, idx) {
17008  }
17009 
17010  reference operator*() {
17011  return proxy_t(L, index);
17012  }
17013 
17014  reference operator*() const {
17015  return proxy_t(L, index);
17016  }
17017 
17018  pointer operator->() {
17019  sp = proxy_t(L, index);
17020  return &sp;
17021  }
17022 
17023  pointer operator->() const {
17024  const_cast<proxy_t&>(sp) = proxy_t(L, index);
17025  return &sp;
17026  }
17027 
17028  stack_iterator& operator++() {
17029  ++index;
17030  return *this;
17031  }
17032 
17033  stack_iterator operator++(int) {
17034  auto r = *this;
17035  this->operator++();
17036  return r;
17037  }
17038 
17039  stack_iterator& operator--() {
17040  --index;
17041  return *this;
17042  }
17043 
17044  stack_iterator operator--(int) {
17045  auto r = *this;
17046  this->operator--();
17047  return r;
17048  }
17049 
17050  stack_iterator& operator+=(difference_type idx) {
17051  index += static_cast<int>(idx);
17052  return *this;
17053  }
17054 
17055  stack_iterator& operator-=(difference_type idx) {
17056  index -= static_cast<int>(idx);
17057  return *this;
17058  }
17059 
17060  difference_type operator-(const stack_iterator& r) const {
17061  return index - r.index;
17062  }
17063 
17064  stack_iterator operator+(difference_type idx) const {
17065  stack_iterator r = *this;
17066  r += idx;
17067  return r;
17068  }
17069 
17070  reference operator[](difference_type idx) const {
17071  return proxy_t(L, index + static_cast<int>(idx));
17072  }
17073 
17074  bool operator==(const stack_iterator& r) const {
17075  if (stacktop == (std::numeric_limits<int>::max)()) {
17076  return r.index == r.stacktop;
17077  }
17078  else if (r.stacktop == (std::numeric_limits<int>::max)()) {
17079  return index == stacktop;
17080  }
17081  return index == r.index;
17082  }
17083 
17084  bool operator!=(const stack_iterator& r) const {
17085  return !(this->operator==(r));
17086  }
17087 
17088  bool operator<(const stack_iterator& r) const {
17089  return index < r.index;
17090  }
17091 
17092  bool operator>(const stack_iterator& r) const {
17093  return index > r.index;
17094  }
17095 
17096  bool operator<=(const stack_iterator& r) const {
17097  return index <= r.index;
17098  }
17099 
17100  bool operator>=(const stack_iterator& r) const {
17101  return index >= r.index;
17102  }
17103  };
17104 
17105  template <typename proxy_t, bool is_const>
17106  inline stack_iterator<proxy_t, is_const> operator+(
17107  typename stack_iterator<proxy_t, is_const>::difference_type n, const stack_iterator<proxy_t, is_const>& r) {
17108  return r + n;
17109  }
17110 } // namespace sol
17111 
17112 // end of sol/stack_iterator.hpp
17113 
17114 // beginning of sol/stack_proxy.hpp
17115 
17116 // beginning of sol/stack_proxy_base.hpp
17117 
17118 namespace sol {
17119  struct stack_proxy_base : public proxy_base<stack_proxy_base> {
17120  private:
17121  lua_State* m_L;
17122  int m_index;
17123 
17124  public:
17125  stack_proxy_base() : m_L(nullptr), m_index(0) {
17126  }
17127  stack_proxy_base(lua_State* L_, int index_) : m_L(L_), m_index(index_) {
17128  }
17129 
17130  template <typename T>
17131  decltype(auto) get() const {
17132  return stack::get<T>(m_L, stack_index());
17133  }
17134 
17135  template <typename T>
17136  bool is() const {
17137  return stack::check<T>(m_L, stack_index());
17138  }
17139 
17140  template <typename T>
17141  decltype(auto) as() const {
17142  return get<T>();
17143  }
17144 
17145  type get_type() const noexcept {
17146  return type_of(lua_state(), stack_index());
17147  }
17148 
17149  int push() const {
17150  return push(m_L);
17151  }
17152 
17153  int push(lua_State* L_) const {
17154  lua_pushvalue(L_, m_index);
17155  return 1;
17156  }
17157 
17158  lua_State* lua_state() const {
17159  return m_L;
17160  }
17161  int stack_index() const {
17162  return m_index;
17163  }
17164  };
17165 
17166  namespace stack {
17167  template <>
17169  static stack_proxy_base get(lua_State* L_, int index_ = -1) {
17170  return stack_proxy_base(L_, index_);
17171  }
17172  };
17173 
17174  template <>
17176  static int push(lua_State*, const stack_proxy_base& proxy_reference) {
17177  return proxy_reference.push();
17178  }
17179  };
17180  } // namespace stack
17181 
17182 } // namespace sol
17183 
17184 // end of sol/stack_proxy_base.hpp
17185 
17186 namespace sol {
17187  struct stack_proxy : public stack_proxy_base {
17188  public:
17190  }
17191  stack_proxy(lua_State* L, int index) : stack_proxy_base(L, index) {
17192  }
17193 
17194  template <typename... Ret, typename... Args>
17195  decltype(auto) call(Args&&... args);
17196 
17197  template <typename... Args>
17198  decltype(auto) operator()(Args&&... args) {
17199  return call<>(std::forward<Args>(args)...);
17200  }
17201  };
17202 
17203  namespace stack {
17204  template <>
17206  static stack_proxy get(lua_State* L, int index, record& tracking) {
17207  tracking.use(0);
17208  return stack_proxy(L, index);
17209  }
17210  };
17211 
17212  template <>
17214  static int push(lua_State*, const stack_proxy& ref) {
17215  return ref.push();
17216  }
17217  };
17218  } // namespace stack
17219 } // namespace sol
17220 
17221 // end of sol/stack_proxy.hpp
17222 
17223 #include <cstdint>
17224 
17225 namespace sol {
17226  struct protected_function_result : public proxy_base<protected_function_result> {
17227  private:
17228  lua_State* L;
17229  int index;
17230  int returncount;
17231  int popcount;
17232  call_status err;
17233 
17234  public:
17235  typedef stack_proxy reference_type;
17236  typedef stack_proxy value_type;
17237  typedef stack_proxy* pointer;
17238  typedef std::ptrdiff_t difference_type;
17239  typedef std::size_t size_type;
17242  typedef std::reverse_iterator<iterator> reverse_iterator;
17243  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
17244 
17245  protected_function_result() noexcept : protected_function_result(nullptr) {}
17246  protected_function_result(lua_State* Ls, int idx = -1, int retnum = 0, int popped = 0, call_status pferr = call_status::ok) noexcept
17247  : L(Ls), index(idx), returncount(retnum), popcount(popped), err(pferr) {
17248  }
17249 
17250  // We do not want anyone to copy these around willy-nilly
17251  // Will likely break people, but also will probably get rid of quiet bugs that have
17252  // been lurking. (E.g., Vanilla Lua will just quietly discard over-pops and under-pops:
17253  // LuaJIT and other Lua engines will implode and segfault at random later times.)
17255  protected_function_result& operator=(const protected_function_result&) = delete;
17256 
17258  : L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) {
17259  // Must be manual, otherwise destructor will screw us
17260  // return count being 0 is enough to keep things clean
17261  // but we will be thorough
17262  o.abandon();
17263  }
17264  protected_function_result& operator=(protected_function_result&& o) noexcept {
17265  L = o.L;
17266  index = o.index;
17267  returncount = o.returncount;
17268  popcount = o.popcount;
17269  err = o.err;
17270  // Must be manual, otherwise destructor will screw us
17271  // return count being 0 is enough to keep things clean
17272  // but we will be thorough
17273  o.abandon();
17274  return *this;
17275  }
17276 
17278  protected_function_result& operator=(const unsafe_function_result& o) = delete;
17280  protected_function_result& operator=(unsafe_function_result&& o) noexcept;
17281 
17282  call_status status() const noexcept {
17283  return err;
17284  }
17285 
17286  bool valid() const noexcept {
17287  return status() == call_status::ok || status() == call_status::yielded;
17288  }
17289 
17290 #if SOL_IS_ON(SOL_COMPILER_GCC)
17291 #pragma GCC diagnostic push
17292 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
17293 #endif
17294 
17295  template <typename T>
17296  decltype(auto) get(int index_offset = 0) const {
17297  using UT = meta::unqualified_t<T>;
17298  int target = index + index_offset;
17299  if constexpr (meta::is_optional_v<UT>) {
17300  using ValueType = typename UT::value_type;
17301  if constexpr (std::is_same_v<ValueType, error>) {
17302  if (valid()) {
17303  return UT();
17304  }
17305  return UT(error(detail::direct_error, stack::get<std::string>(L, target)));
17306  }
17307  else {
17308  if (!valid()) {
17309  return UT();
17310  }
17311  return stack::get<UT>(L, target);
17312  }
17313  }
17314  else {
17315  if constexpr (std::is_same_v<T, error>) {
17316 #if SOL_IS_ON(SOL_SAFE_PROXIES)
17317  if (valid()) {
17318  type t = type_of(L, target);
17319  type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is an error)");
17320  }
17321 #endif // Check Argument Safety
17322  return error(detail::direct_error, stack::get<std::string>(L, target));
17323  }
17324  else {
17325 #if SOL_IS_ON(SOL_SAFE_PROXIES)
17326  if (!valid()) {
17327  type t = type_of(L, target);
17328  type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is not an error)");
17329  }
17330 #endif // Check Argument Safety
17331  return stack::get<T>(L, target);
17332  }
17333  }
17334  }
17335 
17336 #if SOL_IS_ON(SOL_COMPILER_GCC)
17337 #pragma GCC diagnostic pop
17338 #endif
17339 
17340  type get_type(int index_offset = 0) const noexcept {
17341  return type_of(L, index + static_cast<int>(index_offset));
17342  }
17343 
17344  stack_proxy operator[](difference_type index_offset) const {
17345  return stack_proxy(L, index + static_cast<int>(index_offset));
17346  }
17347 
17348  iterator begin() {
17349  return iterator(L, index, stack_index() + return_count());
17350  }
17351  iterator end() {
17352  return iterator(L, stack_index() + return_count(), stack_index() + return_count());
17353  }
17354  const_iterator begin() const {
17355  return const_iterator(L, index, stack_index() + return_count());
17356  }
17357  const_iterator end() const {
17358  return const_iterator(L, stack_index() + return_count(), stack_index() + return_count());
17359  }
17360  const_iterator cbegin() const {
17361  return begin();
17362  }
17363  const_iterator cend() const {
17364  return end();
17365  }
17366 
17367  reverse_iterator rbegin() {
17368  return std::reverse_iterator<iterator>(begin());
17369  }
17370  reverse_iterator rend() {
17371  return std::reverse_iterator<iterator>(end());
17372  }
17373  const_reverse_iterator rbegin() const {
17374  return std::reverse_iterator<const_iterator>(begin());
17375  }
17376  const_reverse_iterator rend() const {
17377  return std::reverse_iterator<const_iterator>(end());
17378  }
17379  const_reverse_iterator crbegin() const {
17380  return std::reverse_iterator<const_iterator>(cbegin());
17381  }
17382  const_reverse_iterator crend() const {
17383  return std::reverse_iterator<const_iterator>(cend());
17384  }
17385 
17386  lua_State* lua_state() const noexcept {
17387  return L;
17388  };
17389  int stack_index() const noexcept {
17390  return index;
17391  };
17392  int return_count() const noexcept {
17393  return returncount;
17394  };
17395  int pop_count() const noexcept {
17396  return popcount;
17397  };
17398  void abandon() noexcept {
17399  // L = nullptr;
17400  index = 0;
17401  returncount = 0;
17402  popcount = 0;
17403  err = call_status::runtime;
17404  }
17406  if (L == nullptr)
17407  return;
17408  stack::remove(L, index, popcount);
17409  }
17410  };
17411 
17412  namespace stack {
17413  template <>
17415  static int push(lua_State* L, const protected_function_result& pfr) {
17416 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
17417  luaL_checkstack(L, static_cast<int>(pfr.pop_count()), detail::not_enough_stack_space_generic);
17418 #endif // make sure stack doesn't overflow
17419  int p = 0;
17420  for (int i = 0; i < pfr.pop_count(); ++i) {
17421  lua_pushvalue(L, i + pfr.stack_index());
17422  ++p;
17423  }
17424  return p;
17425  }
17426  };
17427  } // namespace stack
17428 } // namespace sol
17429 
17430 // end of sol/protected_function_result.hpp
17431 
17432 // beginning of sol/unsafe_function_result.hpp
17433 
17434 #include <cstdint>
17435 
17436 namespace sol {
17437  struct unsafe_function_result : public proxy_base<unsafe_function_result> {
17438  private:
17439  lua_State* L;
17440  int index;
17441  int returncount;
17442 
17443  public:
17444  typedef stack_proxy reference_type;
17445  typedef stack_proxy value_type;
17446  typedef stack_proxy* pointer;
17447  typedef std::ptrdiff_t difference_type;
17448  typedef std::size_t size_type;
17451  typedef std::reverse_iterator<iterator> reverse_iterator;
17452  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
17453 
17454  unsafe_function_result() noexcept : unsafe_function_result(nullptr) {}
17455  unsafe_function_result(lua_State* Ls, int idx = -1, int retnum = 0) noexcept : L(Ls), index(idx), returncount(retnum) {
17456  }
17457 
17458  // We do not want anyone to copy these around willy-nilly
17459  // Will likely break people, but also will probably get rid of quiet bugs that have
17460  // been lurking. (E.g., Vanilla Lua will just quietly discard over-pops and under-pops:
17461  // LuaJIT and other Lua engines will implode and segfault at random later times.)
17463  unsafe_function_result& operator=(const unsafe_function_result&) = delete;
17464 
17465  unsafe_function_result(unsafe_function_result&& o) noexcept : L(o.L), index(o.index), returncount(o.returncount) {
17466  // Must be manual, otherwise destructor will screw us
17467  // return count being 0 is enough to keep things clean
17468  // but will be thorough
17469  o.abandon();
17470  }
17471  unsafe_function_result& operator=(unsafe_function_result&& o) noexcept {
17472  L = o.L;
17473  index = o.index;
17474  returncount = o.returncount;
17475  // Must be manual, otherwise destructor will screw us
17476  // return count being 0 is enough to keep things clean
17477  // but will be thorough
17478  o.abandon();
17479  return *this;
17480  }
17481 
17483  unsafe_function_result& operator=(const protected_function_result& o) = delete;
17485  unsafe_function_result& operator=(protected_function_result&& o) noexcept;
17486 
17487  template <typename T>
17488  decltype(auto) get(difference_type index_offset = 0) const {
17489  return stack::get<T>(L, index + static_cast<int>(index_offset));
17490  }
17491 
17492  type get_type(difference_type index_offset = 0) const noexcept {
17493  return type_of(L, index + static_cast<int>(index_offset));
17494  }
17495 
17496  stack_proxy operator[](difference_type index_offset) const {
17497  return stack_proxy(L, index + static_cast<int>(index_offset));
17498  }
17499 
17500  iterator begin() {
17501  return iterator(L, index, stack_index() + return_count());
17502  }
17503  iterator end() {
17504  return iterator(L, stack_index() + return_count(), stack_index() + return_count());
17505  }
17506  const_iterator begin() const {
17507  return const_iterator(L, index, stack_index() + return_count());
17508  }
17509  const_iterator end() const {
17510  return const_iterator(L, stack_index() + return_count(), stack_index() + return_count());
17511  }
17512  const_iterator cbegin() const {
17513  return begin();
17514  }
17515  const_iterator cend() const {
17516  return end();
17517  }
17518 
17519  reverse_iterator rbegin() {
17520  return std::reverse_iterator<iterator>(begin());
17521  }
17522  reverse_iterator rend() {
17523  return std::reverse_iterator<iterator>(end());
17524  }
17525  const_reverse_iterator rbegin() const {
17526  return std::reverse_iterator<const_iterator>(begin());
17527  }
17528  const_reverse_iterator rend() const {
17529  return std::reverse_iterator<const_iterator>(end());
17530  }
17531  const_reverse_iterator crbegin() const {
17532  return std::reverse_iterator<const_iterator>(cbegin());
17533  }
17534  const_reverse_iterator crend() const {
17535  return std::reverse_iterator<const_iterator>(cend());
17536  }
17537 
17538  call_status status() const noexcept {
17539  return call_status::ok;
17540  }
17541 
17542  bool valid() const noexcept {
17543  return status() == call_status::ok || status() == call_status::yielded;
17544  }
17545 
17546  lua_State* lua_state() const {
17547  return L;
17548  };
17549  int stack_index() const {
17550  return index;
17551  };
17552  int return_count() const {
17553  return returncount;
17554  };
17555  void abandon() noexcept {
17556  // L = nullptr;
17557  index = 0;
17558  returncount = 0;
17559  }
17561  if (L != nullptr) {
17562  lua_pop(L, returncount);
17563  }
17564  }
17565  };
17566 
17567  namespace stack {
17568  template <>
17570  static int push(lua_State* L, const unsafe_function_result& fr) {
17571  int p = 0;
17572  for (int i = 0; i < fr.return_count(); ++i) {
17573  lua_pushvalue(L, i + fr.stack_index());
17574  ++p;
17575  }
17576  return p;
17577  }
17578  };
17579  } // namespace stack
17580 } // namespace sol
17581 
17582 // end of sol/unsafe_function_result.hpp
17583 
17584 #include <cstdint>
17585 
17586 namespace sol {
17587 
17588  namespace detail {
17589  template <>
17590  struct is_speshul<unsafe_function_result> : std::true_type { };
17591  template <>
17592  struct is_speshul<protected_function_result> : std::true_type { };
17593 
17594  template <std::size_t I, typename... Args, typename T>
17595  stack_proxy get(types<Args...>, meta::index_value<0>, meta::index_value<I>, const T& fr) {
17596  return stack_proxy(fr.lua_state(), fr.stack_index() + static_cast<int>(I));
17597  }
17598 
17599  template <std::size_t I, std::size_t N, typename Arg, typename... Args, typename T, meta::enable<meta::boolean<(N > 0)>> = meta::enabler>
17600  stack_proxy get(types<Arg, Args...>, meta::index_value<N>, meta::index_value<I>, const T& fr) {
17601  return get(types<Args...>(), meta::index_value<N - 1>(), meta::index_value<I + lua_size<Arg>::value>(), fr);
17602  }
17603  } // namespace detail
17604 
17605  template <>
17606  struct tie_size<unsafe_function_result> : std::integral_constant<std::size_t, SIZE_MAX> { };
17607 
17608  template <>
17609  struct tie_size<protected_function_result> : std::integral_constant<std::size_t, SIZE_MAX> { };
17610 
17611  template <std::size_t I>
17612  stack_proxy get(const unsafe_function_result& fr) {
17613  return stack_proxy(fr.lua_state(), fr.stack_index() + static_cast<int>(I));
17614  }
17615 
17616  template <std::size_t I, typename... Args>
17617  stack_proxy get(types<Args...> t, const unsafe_function_result& fr) {
17618  return detail::get(t, meta::index_value<I>(), meta::index_value<0>(), fr);
17619  }
17620 
17621  template <std::size_t I>
17622  stack_proxy get(const protected_function_result& fr) {
17623  return stack_proxy(fr.lua_state(), fr.stack_index() + static_cast<int>(I));
17624  }
17625 
17626  template <std::size_t I, typename... Args>
17627  stack_proxy get(types<Args...> t, const protected_function_result& fr) {
17628  return detail::get(t, meta::index_value<I>(), meta::index_value<0>(), fr);
17629  }
17630 } // namespace sol
17631 
17632 // end of sol/function_result.hpp
17633 
17634 // beginning of sol/function_types.hpp
17635 
17636 // beginning of sol/function_types_core.hpp
17637 
17638 // beginning of sol/wrapper.hpp
17639 
17640 namespace sol {
17641 
17642  namespace detail {
17643  template <typename T>
17644  using array_return_type = meta::conditional_t<std::is_array<T>::value, std::add_lvalue_reference_t<T>, T>;
17645  }
17646 
17647  template <typename F, typename = void>
17648  struct wrapper {
17650  typedef typename traits_type::args_list args_list;
17651  typedef typename traits_type::args_list free_args_list;
17652  typedef typename traits_type::returns_list returns_list;
17653 
17654  template <typename... Args>
17655  static decltype(auto) call(F& f, Args&&... args) {
17656  return f(std::forward<Args>(args)...);
17657  }
17658 
17659  struct caller {
17660  template <typename... Args>
17661  decltype(auto) operator()(F& fx, Args&&... args) const {
17662  return call(fx, std::forward<Args>(args)...);
17663  }
17664  };
17665  };
17666 
17667  template <typename F>
17668  struct wrapper<F, std::enable_if_t<std::is_function<std::remove_pointer_t<meta::unqualified_t<F>>>::value>> {
17670  typedef typename traits_type::args_list args_list;
17671  typedef typename traits_type::args_list free_args_list;
17672  typedef typename traits_type::returns_list returns_list;
17673 
17674  template <F fx, typename... Args>
17675  static decltype(auto) invoke(Args&&... args) {
17676  return fx(std::forward<Args>(args)...);
17677  }
17678 
17679  template <typename... Args>
17680  static decltype(auto) call(F& fx, Args&&... args) {
17681  return fx(std::forward<Args>(args)...);
17682  }
17683 
17684  struct caller {
17685  template <typename... Args>
17686  decltype(auto) operator()(F& fx, Args&&... args) const {
17687  return call(fx, std::forward<Args>(args)...);
17688  }
17689  };
17690 
17691  template <F fx>
17692  struct invoker {
17693  template <typename... Args>
17694  decltype(auto) operator()(Args&&... args) const {
17695  return invoke<fx>(std::forward<Args>(args)...);
17696  }
17697  };
17698  };
17699 
17700  template <typename F>
17701  struct wrapper<F, std::enable_if_t<std::is_member_object_pointer<meta::unqualified_t<F>>::value>> {
17703  typedef typename traits_type::object_type object_type;
17704  typedef typename traits_type::return_type return_type;
17705  typedef typename traits_type::args_list args_list;
17707  typedef typename traits_type::returns_list returns_list;
17708 
17709  template <F fx>
17710  static auto call(object_type& mem) -> detail::array_return_type<decltype(mem.*fx)> {
17711  return mem.*fx;
17712  }
17713 
17714  template <F fx, typename Arg, typename... Args>
17715  static decltype(auto) invoke(object_type& mem, Arg&& arg, Args&&...) {
17716  return mem.*fx = std::forward<Arg>(arg);
17717  }
17718 
17719  template <typename Fx>
17720  static auto call(Fx&& fx, object_type& mem) -> detail::array_return_type<decltype(mem.*fx)> {
17721  return mem.*fx;
17722  }
17723 
17724  template <typename Fx, typename Arg, typename... Args>
17725  static void call(Fx&& fx, object_type& mem, Arg&& arg, Args&&...) {
17726  using actual_type = meta::unqualified_t<detail::array_return_type<decltype(mem.*fx)>>;
17727  if constexpr (std::is_array_v<actual_type>) {
17728  using std::cbegin;
17729  using std::cend;
17730  auto first = cbegin(arg);
17731  auto last = cend(arg);
17732  for (std::size_t i = 0; first != last; ++i, ++first) {
17733  (mem.*fx)[i] = *first;
17734  }
17735  }
17736  else {
17737  (mem.*fx) = std::forward<Arg>(arg);
17738  }
17739  }
17740 
17741  struct caller {
17742  template <typename Fx, typename... Args>
17743  decltype(auto) operator()(Fx&& fx, object_type& mem, Args&&... args) const {
17744  return call(std::forward<Fx>(fx), mem, std::forward<Args>(args)...);
17745  }
17746  };
17747 
17748  template <F fx>
17749  struct invoker {
17750  template <typename... Args>
17751  decltype(auto) operator()(Args&&... args) const {
17752  return invoke<fx>(std::forward<Args>(args)...);
17753  }
17754  };
17755  };
17756 
17757  template <typename F, typename R, typename O, typename... FArgs>
17759  typedef O object_type;
17761  typedef typename traits_type::args_list args_list;
17762  typedef types<object_type&, FArgs...> free_args_list;
17763  typedef meta::tuple_types<R> returns_list;
17764 
17765  template <F fx, typename... Args>
17766  static R invoke(O& mem, Args&&... args) {
17767  return (mem.*fx)(std::forward<Args>(args)...);
17768  }
17769 
17770  template <typename Fx, typename... Args>
17771  static R call(Fx&& fx, O& mem, Args&&... args) {
17772  return (mem.*fx)(std::forward<Args>(args)...);
17773  }
17774 
17775  struct caller {
17776  template <typename Fx, typename... Args>
17777  decltype(auto) operator()(Fx&& fx, O& mem, Args&&... args) const {
17778  return call(std::forward<Fx>(fx), mem, std::forward<Args>(args)...);
17779  }
17780  };
17781 
17782  template <F fx>
17783  struct invoker {
17784  template <typename... Args>
17785  decltype(auto) operator()(O& mem, Args&&... args) const {
17786  return invoke<fx>(mem, std::forward<Args>(args)...);
17787  }
17788  };
17789  };
17790 
17791  template <typename R, typename O, typename... Args>
17792  struct wrapper<R (O::*)(Args...)> : public member_function_wrapper<R (O::*)(Args...), R, O, Args...> { };
17793 
17794  template <typename R, typename O, typename... Args>
17795  struct wrapper<R (O::*)(Args...) const> : public member_function_wrapper<R (O::*)(Args...) const, R, O, Args...> { };
17796 
17797  template <typename R, typename O, typename... Args>
17798  struct wrapper<R (O::*)(Args...) const volatile> : public member_function_wrapper<R (O::*)(Args...) const volatile, R, O, Args...> { };
17799 
17800  template <typename R, typename O, typename... Args>
17801  struct wrapper<R (O::*)(Args...)&> : public member_function_wrapper<R (O::*)(Args...)&, R, O, Args...> { };
17802 
17803  template <typename R, typename O, typename... Args>
17804  struct wrapper<R (O::*)(Args...) const&> : public member_function_wrapper<R (O::*)(Args...) const&, R, O, Args...> { };
17805 
17806  template <typename R, typename O, typename... Args>
17807  struct wrapper<R (O::*)(Args...) const volatile&> : public member_function_wrapper<R (O::*)(Args...) const volatile&, R, O, Args...> { };
17808 
17809  template <typename R, typename O, typename... Args>
17810  struct wrapper<R (O::*)(Args..., ...)&> : public member_function_wrapper<R (O::*)(Args..., ...)&, R, O, Args...> { };
17811 
17812  template <typename R, typename O, typename... Args>
17813  struct wrapper<R (O::*)(Args..., ...) const&> : public member_function_wrapper<R (O::*)(Args..., ...) const&, R, O, Args...> { };
17814 
17815  template <typename R, typename O, typename... Args>
17816  struct wrapper<R (O::*)(Args..., ...) const volatile&> : public member_function_wrapper<R (O::*)(Args..., ...) const volatile&, R, O, Args...> { };
17817 
17818  template <typename R, typename O, typename... Args>
17819  struct wrapper<R (O::*)(Args...) &&> : public member_function_wrapper<R (O::*)(Args...)&, R, O, Args...> { };
17820 
17821  template <typename R, typename O, typename... Args>
17822  struct wrapper<R (O::*)(Args...) const&&> : public member_function_wrapper<R (O::*)(Args...) const&, R, O, Args...> { };
17823 
17824  template <typename R, typename O, typename... Args>
17825  struct wrapper<R (O::*)(Args...) const volatile&&> : public member_function_wrapper<R (O::*)(Args...) const volatile&, R, O, Args...> { };
17826 
17827  template <typename R, typename O, typename... Args>
17828  struct wrapper<R (O::*)(Args..., ...) &&> : public member_function_wrapper<R (O::*)(Args..., ...)&, R, O, Args...> { };
17829 
17830  template <typename R, typename O, typename... Args>
17831  struct wrapper<R (O::*)(Args..., ...) const&&> : public member_function_wrapper<R (O::*)(Args..., ...) const&, R, O, Args...> { };
17832 
17833  template <typename R, typename O, typename... Args>
17834  struct wrapper<R (O::*)(Args..., ...) const volatile&&> : public member_function_wrapper<R (O::*)(Args..., ...) const volatile&, R, O, Args...> { };
17835 
17836 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
17837  // noexcept has become a part of a function's type
17838 
17839  template <typename R, typename O, typename... Args>
17840  struct wrapper<R (O::*)(Args...) noexcept> : public member_function_wrapper<R (O::*)(Args...) noexcept, R, O, Args...> { };
17841 
17842  template <typename R, typename O, typename... Args>
17843  struct wrapper<R (O::*)(Args...) const noexcept> : public member_function_wrapper<R (O::*)(Args...) const noexcept, R, O, Args...> { };
17844 
17845  template <typename R, typename O, typename... Args>
17846  struct wrapper<R (O::*)(Args...) const volatile noexcept> : public member_function_wrapper<R (O::*)(Args...) const volatile noexcept, R, O, Args...> { };
17847 
17848  template <typename R, typename O, typename... Args>
17849  struct wrapper<R (O::*)(Args...)& noexcept> : public member_function_wrapper<R (O::*)(Args...)& noexcept, R, O, Args...> { };
17850 
17851  template <typename R, typename O, typename... Args>
17852  struct wrapper<R (O::*)(Args...) const& noexcept> : public member_function_wrapper<R (O::*)(Args...) const& noexcept, R, O, Args...> { };
17853 
17854  template <typename R, typename O, typename... Args>
17855  struct wrapper<R (O::*)(Args...) const volatile& noexcept> : public member_function_wrapper<R (O::*)(Args...) const volatile& noexcept, R, O, Args...> { };
17856 
17857  template <typename R, typename O, typename... Args>
17858  struct wrapper<R (O::*)(Args..., ...)& noexcept> : public member_function_wrapper<R (O::*)(Args..., ...)& noexcept, R, O, Args...> { };
17859 
17860  template <typename R, typename O, typename... Args>
17861  struct wrapper<R (O::*)(Args..., ...) const& noexcept> : public member_function_wrapper<R (O::*)(Args..., ...) const& noexcept, R, O, Args...> { };
17862 
17863  template <typename R, typename O, typename... Args>
17864  struct wrapper<R (O::*)(Args..., ...) const volatile& noexcept>
17865  : public member_function_wrapper<R (O::*)(Args..., ...) const volatile& noexcept, R, O, Args...> { };
17866 
17867  template <typename R, typename O, typename... Args>
17868  struct wrapper<R (O::*)(Args...)&& noexcept> : public member_function_wrapper<R (O::*)(Args...)& noexcept, R, O, Args...> { };
17869 
17870  template <typename R, typename O, typename... Args>
17871  struct wrapper<R (O::*)(Args...) const&& noexcept> : public member_function_wrapper<R (O::*)(Args...) const& noexcept, R, O, Args...> { };
17872 
17873  template <typename R, typename O, typename... Args>
17874  struct wrapper<R (O::*)(Args...) const volatile&& noexcept> : public member_function_wrapper<R (O::*)(Args...) const volatile& noexcept, R, O, Args...> {
17875  };
17876 
17877  template <typename R, typename O, typename... Args>
17878  struct wrapper<R (O::*)(Args..., ...)&& noexcept> : public member_function_wrapper<R (O::*)(Args..., ...)& noexcept, R, O, Args...> { };
17879 
17880  template <typename R, typename O, typename... Args>
17881  struct wrapper<R (O::*)(Args..., ...) const&& noexcept> : public member_function_wrapper<R (O::*)(Args..., ...) const& noexcept, R, O, Args...> { };
17882 
17883  template <typename R, typename O, typename... Args>
17884  struct wrapper<R (O::*)(Args..., ...) const volatile&& noexcept>
17885  : public member_function_wrapper<R (O::*)(Args..., ...) const volatile& noexcept, R, O, Args...> { };
17886 
17887 #endif // noexcept is part of a function's type
17888 
17889 } // namespace sol
17890 
17891 // end of sol/wrapper.hpp
17892 
17893 #include <memory>
17894 
17895 namespace sol { namespace function_detail {
17896  template <typename Fx, int start = 1, bool is_yielding = false>
17897  int call(lua_State* L) {
17898  Fx& fx = stack::get<user<Fx>>(L, upvalue_index(start));
17899  int nr = fx(L);
17900  if (is_yielding) {
17901  return lua_yield(L, nr);
17902  }
17903  else {
17904  return nr;
17905  }
17906  }
17907 }} // namespace sol::function_detail
17908 
17909 // end of sol/function_types_core.hpp
17910 
17911 // beginning of sol/function_types_templated.hpp
17912 
17913 // beginning of sol/call.hpp
17914 
17915 // beginning of sol/property.hpp
17916 
17917 #include <type_traits>
17918 #include <utility>
17919 
17920 namespace sol {
17921  namespace detail {
17922  struct no_prop { };
17923  } // namespace detail
17924 
17925  template <typename R, typename W>
17927  private:
17930 
17931  public:
17932  template <typename Rx, typename Wx>
17933  property_wrapper(Rx&& r, Wx&& w) : read_base_t(std::forward<Rx>(r)), write_base_t(std::forward<Wx>(w)) {
17934  }
17935 
17936  W& write() {
17937  return write_base_t::value();
17938  }
17939 
17940  const W& write() const {
17941  return write_base_t::value();
17942  }
17943 
17944  R& read() {
17945  return read_base_t::value();
17946  }
17947 
17948  const R& read() const {
17949  return read_base_t::value();
17950  }
17951  };
17952 
17953  template <typename F, typename G>
17954  inline decltype(auto) property(F&& f, G&& g) {
17955  typedef lua_bind_traits<meta::unqualified_t<F>> left_traits;
17956  typedef lua_bind_traits<meta::unqualified_t<G>> right_traits;
17957  if constexpr (left_traits::free_arity < right_traits::free_arity) {
17958  return property_wrapper<std::decay_t<F>, std::decay_t<G>>(std::forward<F>(f), std::forward<G>(g));
17959  }
17960  else {
17961  return property_wrapper<std::decay_t<G>, std::decay_t<F>>(std::forward<G>(g), std::forward<F>(f));
17962  }
17963  }
17964 
17965  template <typename F>
17966  inline decltype(auto) property(F&& f) {
17967  typedef lua_bind_traits<meta::unqualified_t<F>> left_traits;
17968  if constexpr (left_traits::free_arity < 2) {
17969  return property_wrapper<std::decay_t<F>, detail::no_prop>(std::forward<F>(f), detail::no_prop());
17970  }
17971  else {
17973  }
17974  }
17975 
17976  template <typename F>
17977  inline decltype(auto) readonly_property(F&& f) {
17978  return property_wrapper<std::decay_t<F>, detail::no_prop>(std::forward<F>(f), detail::no_prop());
17979  }
17980 
17981  template <typename F>
17982  inline decltype(auto) writeonly_property(F&& f) {
17984  }
17985 
17986  template <typename T>
17988  private:
17989  using base_t = detail::ebco<T>;
17990 
17991  public:
17992  using base_t::base_t;
17993 
17994  operator T&() {
17995  return base_t::value();
17996  }
17997  operator const T&() const {
17998  return base_t::value();
17999  }
18000  };
18001 
18002  // Allow someone to make a member variable readonly (const)
18003  template <typename R, typename T>
18004  inline auto readonly(R T::*v) {
18006  }
18007 
18008  template <typename T>
18010  private:
18011  using base_t = detail::ebco<T>;
18012 
18013  public:
18014  using base_t::base_t;
18015  };
18016 
18017  template <typename V>
18018  inline auto var(V&& v) {
18019  typedef std::decay_t<V> T;
18020  return var_wrapper<T>(std::forward<V>(v));
18021  }
18022 
18023  namespace meta {
18024  template <typename T>
18025  using is_member_object = std::integral_constant<bool, std::is_member_object_pointer_v<T> || is_specialization_of_v<T, readonly_wrapper>>;
18026 
18027  template <typename T>
18028  inline constexpr bool is_member_object_v = is_member_object<T>::value;
18029 
18030  template <typename T>
18031  using is_member_object_or_function = std::integral_constant<bool, is_member_object_v<T> || std::is_member_pointer_v<T>>;
18032 
18033  template <typename T>
18034  inline constexpr bool is_member_object_or_function_v = is_member_object_or_function<T>::value;
18035  } // namespace meta
18036 
18037 } // namespace sol
18038 
18039 // end of sol/property.hpp
18040 
18041 // beginning of sol/protect.hpp
18042 
18043 #include <utility>
18044 
18045 namespace sol {
18046 
18047  template <typename T>
18048  struct protect_t {
18049  T value;
18050 
18051  template <typename Arg, typename... Args, meta::disable<std::is_same<protect_t, meta::unqualified_t<Arg>>> = meta::enabler>
18052  protect_t(Arg&& arg, Args&&... args) : value(std::forward<Arg>(arg), std::forward<Args>(args)...) {
18053  }
18054 
18055  protect_t(const protect_t&) = default;
18056  protect_t(protect_t&&) = default;
18057  protect_t& operator=(const protect_t&) = default;
18058  protect_t& operator=(protect_t&&) = default;
18059  };
18060 
18061  template <typename T>
18062  auto protect(T&& value) {
18063  return protect_t<std::decay_t<T>>(std::forward<T>(value));
18064  }
18065 
18066 } // namespace sol
18067 
18068 // end of sol/protect.hpp
18069 
18070 namespace sol {
18071  namespace u_detail {
18072 
18073  } // namespace u_detail
18074 
18075  namespace policy_detail {
18076  template <int I, int... In>
18077  inline void handle_policy(static_stack_dependencies<I, In...>, lua_State* L, int&) {
18078  if constexpr (sizeof...(In) == 0) {
18079  (void)L;
18080  return;
18081  }
18082  else {
18083  absolute_index ai(L, I);
18084  if (type_of(L, ai) != type::userdata) {
18085  return;
18086  }
18087  lua_createtable(L, static_cast<int>(sizeof...(In)), 0);
18088  stack_reference deps(L, -1);
18089  auto per_dep = [&L, &deps](int i) {
18090 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
18091  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
18092 #endif // make sure stack doesn't overflow
18093  lua_pushvalue(L, i);
18094  luaL_ref(L, deps.stack_index());
18095  };
18096  (void)per_dep;
18097  (void)detail::swallow { int(), (per_dep(In), int())... };
18098  lua_setuservalue(L, ai);
18099  }
18100  }
18101 
18102  template <int... In>
18103  inline void handle_policy(returns_self_with<In...>, lua_State* L, int& pushed) {
18104  pushed = stack::push(L, raw_index(1));
18105  handle_policy(static_stack_dependencies<-1, In...>(), L, pushed);
18106  }
18107 
18108  inline void handle_policy(const stack_dependencies& sdeps, lua_State* L, int&) {
18109  absolute_index ai(L, sdeps.target);
18110  if (type_of(L, ai) != type::userdata) {
18111  return;
18112  }
18113  lua_createtable(L, static_cast<int>(sdeps.size()), 0);
18114  stack_reference deps(L, -1);
18115 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
18116  luaL_checkstack(L, static_cast<int>(sdeps.size()), detail::not_enough_stack_space_generic);
18117 #endif // make sure stack doesn't overflow
18118  for (std::size_t i = 0; i < sdeps.size(); ++i) {
18119  lua_pushvalue(L, sdeps.stack_indices[i]);
18120  luaL_ref(L, deps.stack_index());
18121  }
18122  lua_setuservalue(L, ai);
18123  }
18124 
18125  template <typename P, meta::disable<std::is_base_of<detail::policy_base_tag, meta::unqualified_t<P>>> = meta::enabler>
18126  inline void handle_policy(P&& p, lua_State* L, int& pushed) {
18127  pushed = std::forward<P>(p)(L, pushed);
18128  }
18129  } // namespace policy_detail
18130 
18131  namespace function_detail {
18132  inline int no_construction_error(lua_State* L) {
18133  return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)");
18134  }
18135  } // namespace function_detail
18136 
18137  namespace call_detail {
18138 
18139  template <typename R, typename W>
18140  inline auto& pick(std::true_type, property_wrapper<R, W>& f) {
18141  return f.read();
18142  }
18143 
18144  template <typename R, typename W>
18145  inline auto& pick(std::false_type, property_wrapper<R, W>& f) {
18146  return f.write();
18147  }
18148 
18149  template <typename T, typename List>
18150  struct void_call : void_call<T, meta::function_args_t<List>> { };
18151 
18152  template <typename T, typename... Args>
18153  struct void_call<T, types<Args...>> {
18154  static void call(Args...) {
18155  }
18156  };
18157 
18158  template <typename T, bool checked, bool clean_stack>
18160  T* obj_;
18161  reference* obj_lua_ref_;
18163 
18165  : obj_(obj_ptr), obj_lua_ref_(&obj_lua_ref), p_umf_(&umf) {
18166  }
18167 
18168  template <typename Fx, std::size_t I, typename... R, typename... Args>
18169  int operator()(types<Fx>, meta::index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) const {
18170  detail::default_construct func {};
18171  int result = stack::call_into_lua<checked, clean_stack>(r, a, L, start, func, this->obj_);
18172  // construct userdata table
18173  // SPECIFICALLY, after we've created it successfully.
18174  // If the constructor exits for any reason we have to break things down...
18175  if constexpr (clean_stack) {
18176  obj_lua_ref_->push();
18177  (*this->p_umf_)();
18178  obj_lua_ref_->pop();
18179  }
18180  else {
18181  (*this->p_umf_)();
18182  }
18183  return result;
18184  }
18185  };
18186 
18187  namespace overload_detail {
18188  template <std::size_t... M, typename Match, typename... Args>
18189  inline int overload_match_arity(types<>, std::index_sequence<>, std::index_sequence<M...>, Match&&, lua_State* L, int, int, Args&&...) {
18190  return luaL_error(L, "sol: no matching function call takes this number of arguments and the specified types");
18191  }
18192 
18193  template <typename Fx, typename... Fxs, std::size_t I, std::size_t... In, std::size_t... M, typename Match, typename... Args>
18194  inline int overload_match_arity(types<Fx, Fxs...>, std::index_sequence<I, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L,
18195  int fxarity, int start, Args&&... args) {
18197  typedef meta::tuple_types<typename traits::return_type> return_types;
18198  typedef typename traits::free_args_list args_list;
18199  // compile-time eliminate any functions that we know ahead of time are of improper arity
18200  if constexpr (!traits::runtime_variadics_t::value
18201  && meta::find_in_pack_v<meta::index_value<traits::free_arity>, meta::index_value<M>...>::value) {
18202  return overload_match_arity(types<Fxs...>(),
18203  std::index_sequence<In...>(),
18204  std::index_sequence<M...>(),
18205  std::forward<Match>(matchfx),
18206  L,
18207  fxarity,
18208  start,
18209  std::forward<Args>(args)...);
18210  }
18211  else {
18212  if constexpr (!traits::runtime_variadics_t::value) {
18213  if (traits::free_arity != fxarity) {
18214  return overload_match_arity(types<Fxs...>(),
18215  std::index_sequence<In...>(),
18216  std::index_sequence<traits::free_arity, M...>(),
18217  std::forward<Match>(matchfx),
18218  L,
18219  fxarity,
18220  start,
18221  std::forward<Args>(args)...);
18222  }
18223  }
18224  stack::record tracking {};
18225  if (!stack::stack_detail::check_types(args_list(), L, start, &no_panic, tracking)) {
18226  return overload_match_arity(types<Fxs...>(),
18227  std::index_sequence<In...>(),
18228  std::index_sequence<M...>(),
18229  std::forward<Match>(matchfx),
18230  L,
18231  fxarity,
18232  start,
18233  std::forward<Args>(args)...);
18234  }
18235  return matchfx(types<Fx>(), meta::index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
18236  }
18237  }
18238 
18239  template <std::size_t... M, typename Match, typename... Args>
18240  inline int overload_match_arity_single(
18241  types<>, std::index_sequence<>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
18242  return overload_match_arity(types<>(),
18243  std::index_sequence<>(),
18244  std::index_sequence<M...>(),
18245  std::forward<Match>(matchfx),
18246  L,
18247  fxarity,
18248  start,
18249  std::forward<Args>(args)...);
18250  }
18251 
18252  template <typename Fx, std::size_t I, std::size_t... M, typename Match, typename... Args>
18253  inline int overload_match_arity_single(
18254  types<Fx>, std::index_sequence<I>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
18256  typedef meta::tuple_types<typename traits::return_type> return_types;
18257  typedef typename traits::free_args_list args_list;
18258  // compile-time eliminate any functions that we know ahead of time are of improper arity
18259  if constexpr (!traits::runtime_variadics_t::value
18260  && meta::find_in_pack_v<meta::index_value<traits::free_arity>, meta::index_value<M>...>::value) {
18261  return overload_match_arity(types<>(),
18262  std::index_sequence<>(),
18263  std::index_sequence<M...>(),
18264  std::forward<Match>(matchfx),
18265  L,
18266  fxarity,
18267  start,
18268  std::forward<Args>(args)...);
18269  }
18270  if constexpr (!traits::runtime_variadics_t::value) {
18271  if (traits::free_arity != fxarity) {
18272  return overload_match_arity(types<>(),
18273  std::index_sequence<>(),
18274  std::index_sequence<traits::free_arity, M...>(),
18275  std::forward<Match>(matchfx),
18276  L,
18277  fxarity,
18278  start,
18279  std::forward<Args>(args)...);
18280  }
18281  }
18282  return matchfx(types<Fx>(), meta::index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
18283  }
18284 
18285  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,
18286  typename... Args>
18287  inline int overload_match_arity_single(types<Fx, Fx1, Fxs...>, std::index_sequence<I, I1, In...>, std::index_sequence<M...>, Match&& matchfx,
18288  lua_State* L, int fxarity, int start, Args&&... args) {
18290  typedef meta::tuple_types<typename traits::return_type> return_types;
18291  typedef typename traits::free_args_list args_list;
18292  // compile-time eliminate any functions that we know ahead of time are of improper arity
18293  if constexpr (!traits::runtime_variadics_t::value
18294  && meta::find_in_pack_v<meta::index_value<traits::free_arity>, meta::index_value<M>...>::value) {
18295  return overload_match_arity(types<Fx1, Fxs...>(),
18296  std::index_sequence<I1, In...>(),
18297  std::index_sequence<M...>(),
18298  std::forward<Match>(matchfx),
18299  L,
18300  fxarity,
18301  start,
18302  std::forward<Args>(args)...);
18303  }
18304  else {
18305  if constexpr (!traits::runtime_variadics_t::value) {
18306  if (traits::free_arity != fxarity) {
18307  return overload_match_arity(types<Fx1, Fxs...>(),
18308  std::index_sequence<I1, In...>(),
18309  std::index_sequence<traits::free_arity, M...>(),
18310  std::forward<Match>(matchfx),
18311  L,
18312  fxarity,
18313  start,
18314  std::forward<Args>(args)...);
18315  }
18316  }
18317  stack::record tracking {};
18318  if (!stack::stack_detail::check_types(args_list(), L, start, &no_panic, tracking)) {
18319  return overload_match_arity(types<Fx1, Fxs...>(),
18320  std::index_sequence<I1, In...>(),
18321  std::index_sequence<M...>(),
18322  std::forward<Match>(matchfx),
18323  L,
18324  fxarity,
18325  start,
18326  std::forward<Args>(args)...);
18327  }
18328  return matchfx(types<Fx>(), meta::index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
18329  }
18330  }
18331  } // namespace overload_detail
18332 
18333  template <typename... Functions, typename Match, typename... Args>
18334  inline int overload_match_arity(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
18335  return overload_detail::overload_match_arity_single(types<Functions...>(),
18336  std::make_index_sequence<sizeof...(Functions)>(),
18337  std::index_sequence<>(),
18338  std::forward<Match>(matchfx),
18339  L,
18340  fxarity,
18341  start,
18342  std::forward<Args>(args)...);
18343  }
18344 
18345  template <typename... Functions, typename Match, typename... Args>
18346  inline int overload_match(Match&& matchfx, lua_State* L, int start, Args&&... args) {
18347  int fxarity = lua_gettop(L) - (start - 1);
18348  return overload_match_arity<Functions...>(std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
18349  }
18350 
18351  template <typename T, typename... TypeLists, typename Match, typename... Args>
18352  inline int construct_match(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
18353  // use same overload resolution matching as all other parts of the framework
18354  return overload_match_arity<decltype(void_call<T, TypeLists>::call)...>(
18355  std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
18356  }
18357 
18358  template <typename T, bool checked, bool clean_stack, typename... TypeLists>
18359  inline int construct_trampolined(lua_State* L) {
18360  static const auto& meta = usertype_traits<T>::metatable();
18361  int argcount = lua_gettop(L);
18362  call_syntax syntax = argcount > 0 ? stack::get_call_syntax(L, usertype_traits<T>::user_metatable(), 1) : call_syntax::dot;
18363  argcount -= static_cast<int>(syntax);
18364 
18365  T* obj = detail::usertype_allocate<T>(L);
18366  reference userdataref(L, -1);
18367  stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
18368 
18369  // put userdata at the first index
18370  lua_insert(L, 1);
18371  construct_match<T, TypeLists...>(constructor_match<T, checked, clean_stack>(obj, userdataref, umf), L, argcount, 1 + static_cast<int>(syntax));
18372 
18373  userdataref.push();
18374  return 1;
18375  }
18376 
18377  template <typename T, bool checked, bool clean_stack, typename... TypeLists>
18378  inline int construct(lua_State* L) {
18379  return detail::static_trampoline<&construct_trampolined<T, checked, clean_stack, TypeLists...>>(L);
18380  }
18381 
18382  template <typename F, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename = void>
18384  template <typename Fx, typename... Args>
18385  static int call(lua_State* L, Fx&& f, Args&&... args) {
18386  using uFx = meta::unqualified_t<Fx>;
18387  static constexpr bool is_ref = is_lua_reference_v<uFx>;
18388  if constexpr (is_ref) {
18389  if constexpr (is_index) {
18390  return stack::push(L, std::forward<Fx>(f), std::forward<Args>(args)...);
18391  }
18392  else {
18393  std::forward<Fx>(f) = stack::unqualified_get<F>(L, boost + (is_variable ? 3 : 1));
18394  return 0;
18395  }
18396  }
18397  else {
18398  using wrap = wrapper<uFx>;
18399  using traits_type = typename wrap::traits_type;
18400  using fp_t = typename traits_type::function_pointer_type;
18401  constexpr bool is_function_pointer_convertible = std::is_class_v<uFx> && std::is_convertible_v<std::decay_t<Fx>, fp_t>;
18402  if constexpr (is_function_pointer_convertible) {
18403  fp_t fx = f;
18405  L, fx, std::forward<Args>(args)...);
18406  }
18407  else {
18408  using returns_list = typename wrap::returns_list;
18409  using args_list = typename wrap::free_args_list;
18410  using caller = typename wrap::caller;
18411  return stack::call_into_lua<checked, clean_stack>(
18412  returns_list(), args_list(), L, boost + 1, caller(), std::forward<Fx>(f), std::forward<Args>(args)...);
18413  }
18414  }
18415  }
18416  };
18417 
18418  template <typename T, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18419  struct agnostic_lua_call_wrapper<var_wrapper<T>, is_index, is_variable, checked, boost, clean_stack, C> {
18420  template <typename F>
18421  static int call(lua_State* L, F&& f) {
18422  if constexpr (is_index) {
18423  constexpr bool is_stack = is_stack_based_v<meta::unqualified_t<decltype(detail::unwrap(f.value()))>>;
18424  if constexpr (clean_stack && !is_stack) {
18425  lua_settop(L, 0);
18426  }
18427  return stack::push_reference(L, detail::unwrap(f.value()));
18428  }
18429  else {
18430  if constexpr (std::is_const_v<meta::unwrapped_t<T>>) {
18431  (void)f;
18432  return luaL_error(L, "sol: cannot write to a readonly (const) variable");
18433  }
18434  else {
18435  using R = meta::unwrapped_t<T>;
18436  if constexpr (std::is_assignable_v<std::add_lvalue_reference_t<meta::unqualified_t<R>>, R>) {
18437  detail::unwrap(f.value()) = stack::unqualified_get<meta::unwrapped_t<T>>(L, boost + (is_variable ? 3 : 1));
18438  if (clean_stack) {
18439  lua_settop(L, 0);
18440  }
18441  return 0;
18442  }
18443  else {
18444  return luaL_error(L, "sol: cannot write to this variable: copy assignment/constructor not available");
18445  }
18446  }
18447  }
18448  }
18449  };
18450 
18451  template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18452  struct agnostic_lua_call_wrapper<lua_CFunction_ref, is_index, is_variable, checked, boost, clean_stack, C> {
18453  static int call(lua_State* L, lua_CFunction_ref f) {
18454  return f(L);
18455  }
18456  };
18457 
18458  template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18459  struct agnostic_lua_call_wrapper<lua_CFunction, is_index, is_variable, checked, boost, clean_stack, C> {
18460  static int call(lua_State* L, lua_CFunction f) {
18461  return f(L);
18462  }
18463  };
18464 
18465 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
18466  template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18467  struct agnostic_lua_call_wrapper<detail::lua_CFunction_noexcept, is_index, is_variable, checked, boost, clean_stack, C> {
18468  static int call(lua_State* L, detail::lua_CFunction_noexcept f) {
18469  return f(L);
18470  }
18471  };
18472 #endif // noexcept function types
18473 
18474  template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18475  struct agnostic_lua_call_wrapper<detail::no_prop, is_index, is_variable, checked, boost, clean_stack, C> {
18476  static int call(lua_State* L, const detail::no_prop&) {
18477  return luaL_error(L, is_index ? "sol: cannot read from a writeonly property" : "sol: cannot write to a readonly property");
18478  }
18479  };
18480 
18481  template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18482  struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, checked, boost, clean_stack, C> {
18483  static int call(lua_State* L, const no_construction&) {
18484  return function_detail::no_construction_error(L);
18485  }
18486  };
18487 
18488  template <typename... Args, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18489  struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, checked, boost, clean_stack, C> {
18490  static int call(lua_State*, const bases<Args...>&) {
18491  // Uh. How did you even call this, lul
18492  return 0;
18493  }
18494  };
18495 
18496  template <typename T, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18497  struct agnostic_lua_call_wrapper<std::reference_wrapper<T>, is_index, is_variable, checked, boost, clean_stack, C> {
18498  static int call(lua_State* L, std::reference_wrapper<T> f) {
18500  return alcw.call(L, f.get());
18501  }
18502  };
18503 
18504  template <typename T, typename F, bool is_index, bool is_variable, bool checked = detail::default_safe_function_calls, int boost = 0,
18505  bool clean_stack = true, typename = void>
18507  template <typename Fx, typename... Args>
18508  static int call(lua_State* L, Fx&& fx, Args&&... args) {
18509  if constexpr (std::is_member_function_pointer_v<F>) {
18510  using wrap = wrapper<F>;
18511  using object_type = typename wrap::object_type;
18512  if constexpr (sizeof...(Args) < 1) {
18513  using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
18514  static_assert(std::is_base_of_v<object_type, Ta>,
18515  "It seems like you might have accidentally bound a class type with a member function method that does not correspond to the "
18516  "class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one class \"T\" "
18517  "but then bind member methods from a complete unrelated class. Check things over!");
18518 #if SOL_IS_ON(SOL_SAFE_USERTYPE)
18519  auto maybeo = stack::check_get<Ta*>(L, 1);
18520  if (!maybeo || maybeo.value() == nullptr) {
18521  return luaL_error(L,
18522  "sol: received nil for 'self' argument (use ':' for accessing member functions, make sure member variables are "
18523  "preceeded by the "
18524  "actual object with '.' syntax)");
18525  }
18526  object_type* o = static_cast<object_type*>(maybeo.value());
18527  return call(L, std::forward<Fx>(fx), *o);
18528 #else
18529  object_type& o = static_cast<object_type&>(*stack::unqualified_get<non_null<Ta*>>(L, 1));
18530  return call(L, std::forward<Fx>(fx), o);
18531 #endif // Safety
18532  }
18533  else {
18534  using returns_list = typename wrap::returns_list;
18535  using args_list = typename wrap::args_list;
18536  using caller = typename wrap::caller;
18537  return stack::call_into_lua<checked, clean_stack>(
18538  returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), std::forward<Fx>(fx), std::forward<Args>(args)...);
18539  }
18540  }
18541  else if constexpr (std::is_member_object_pointer_v<F>) {
18542  using wrap = wrapper<F>;
18543  using object_type = typename wrap::object_type;
18544  if constexpr (is_index) {
18545  if constexpr (sizeof...(Args) < 1) {
18546  using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
18547  static_assert(std::is_base_of_v<object_type, Ta>,
18548  "It seems like you might have accidentally bound a class type with a member function method that does not correspond "
18549  "to the class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one "
18550  "class \"T\" but then bind member methods from a complete unrelated class. Check things over!");
18551 #if SOL_IS_ON(SOL_SAFE_USERTYPE)
18552  auto maybeo = stack::check_get<Ta*>(L, 1);
18553  if (!maybeo || maybeo.value() == nullptr) {
18554  if (is_variable) {
18555  return luaL_error(L, "sol: 'self' argument is lua_nil (bad '.' access?)");
18556  }
18557  return luaL_error(L, "sol: 'self' argument is lua_nil (pass 'self' as first argument)");
18558  }
18559  object_type* o = static_cast<object_type*>(maybeo.value());
18560  return call(L, std::forward<Fx>(fx), *o);
18561 #else
18562  object_type& o = static_cast<object_type&>(*stack::get<non_null<Ta*>>(L, 1));
18563  return call(L, std::forward<Fx>(fx), o);
18564 #endif // Safety
18565  }
18566  else {
18567  using returns_list = typename wrap::returns_list;
18568  using caller = typename wrap::caller;
18569  return stack::call_into_lua<checked, clean_stack>(returns_list(),
18570  types<>(),
18571  L,
18572  boost + (is_variable ? 3 : 2),
18573  caller(),
18574  std::forward<Fx>(fx),
18575  std::forward<Args>(args)...);
18576  }
18577  }
18578  else {
18579  using traits_type = lua_bind_traits<F>;
18580  using return_type = typename traits_type::return_type;
18581  constexpr bool ret_is_const = std::is_const_v<std::remove_reference_t<return_type>>;
18582  if constexpr (ret_is_const) {
18583  (void)fx;
18584  (void)detail::swallow { 0, (static_cast<void>(args), 0)... };
18585  return luaL_error(L, "sol: cannot write to a readonly (const) variable");
18586  }
18587  else {
18588  using u_return_type = meta::unqualified_t<return_type>;
18589  constexpr bool is_assignable = std::is_copy_assignable_v<u_return_type> || std::is_array_v<u_return_type>;
18590  if constexpr (!is_assignable) {
18591  (void)fx;
18592  (void)detail::swallow { 0, ((void)args, 0)... };
18593  return luaL_error(L, "sol: cannot write to this variable: copy assignment/constructor not available");
18594  }
18595  else {
18596  using args_list = typename wrap::args_list;
18597  using caller = typename wrap::caller;
18598  if constexpr (sizeof...(Args) > 0) {
18599  return stack::call_into_lua<checked, clean_stack>(types<void>(),
18600  args_list(),
18601  L,
18602  boost + (is_variable ? 3 : 2),
18603  caller(),
18604  std::forward<Fx>(fx),
18605  std::forward<Args>(args)...);
18606  }
18607  else {
18608  using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
18609 #if SOL_IS_ON(SOL_SAFE_USERTYPE)
18610  auto maybeo = stack::check_get<Ta*>(L, 1);
18611  if (!maybeo || maybeo.value() == nullptr) {
18612  if (is_variable) {
18613  return luaL_error(L, "sol: received nil for 'self' argument (bad '.' access?)");
18614  }
18615  return luaL_error(L, "sol: received nil for 'self' argument (pass 'self' as first argument)");
18616  }
18617  object_type* po = static_cast<object_type*>(maybeo.value());
18618  object_type& o = *po;
18619 #else
18620  object_type& o = static_cast<object_type&>(*stack::get<non_null<Ta*>>(L, 1));
18621 #endif // Safety
18622 
18623  return stack::call_into_lua<checked, clean_stack>(
18624  types<void>(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), std::forward<Fx>(fx), o);
18625  }
18626  }
18627  }
18628  }
18629  }
18630  else {
18632  return alcw.call(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
18633  }
18634  }
18635  };
18636 
18637  template <typename T, typename F, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18638  struct lua_call_wrapper<T, readonly_wrapper<F>, is_index, is_variable, checked, boost, clean_stack, C> {
18640  using wrap = wrapper<F>;
18641  using object_type = typename wrap::object_type;
18642 
18643  static int call(lua_State* L, readonly_wrapper<F>&& rw) {
18644  if constexpr (!is_index) {
18645  (void)rw;
18646  return luaL_error(L, "sol: cannot write to a sol::readonly variable");
18647  }
18648  else {
18650  return lcw.call(L, std::move(rw.value()));
18651  }
18652  }
18653 
18654  static int call(lua_State* L, readonly_wrapper<F>&& rw, object_type& o) {
18655  if constexpr (!is_index) {
18656  (void)o;
18657  return call(L, std::move(rw));
18658  }
18659  else {
18661  return lcw.call(L, rw.value(), o);
18662  }
18663  }
18664 
18665  static int call(lua_State* L, const readonly_wrapper<F>& rw) {
18666  if constexpr (!is_index) {
18667  (void)rw;
18668  return luaL_error(L, "sol: cannot write to a sol::readonly variable");
18669  }
18670  else {
18672  return lcw.call(L, rw.value());
18673  }
18674  }
18675 
18676  static int call(lua_State* L, const readonly_wrapper<F>& rw, object_type& o) {
18677  if constexpr (!is_index) {
18678  (void)o;
18679  return call(L, rw);
18680  }
18681  else {
18683  return lcw.call(L, rw.value(), o);
18684  }
18685  }
18686  };
18687 
18688  template <typename T, typename... Args, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18689  struct lua_call_wrapper<T, constructor_list<Args...>, is_index, is_variable, checked, boost, clean_stack, C> {
18690  typedef constructor_list<Args...> F;
18691 
18692  static int call(lua_State* L, F&) {
18693  const auto& meta = usertype_traits<T>::metatable();
18694  int argcount = lua_gettop(L);
18695  call_syntax syntax = argcount > 0 ? stack::get_call_syntax(L, usertype_traits<T>::user_metatable(), 1) : call_syntax::dot;
18696  argcount -= static_cast<int>(syntax);
18697 
18698  T* obj = detail::usertype_allocate<T>(L);
18699  reference userdataref(L, -1);
18700  stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
18701 
18702  // put userdata at the first index
18703  lua_insert(L, 1);
18704  // Because of the way constructors work,
18705  // we have to kill the data, but only if the cosntructor is successfulyl invoked...
18706  // if it's not successfully invoked and we panic,
18707  // we cannot actually deallcoate/delete the data.
18708  construct_match<T, Args...>(
18709  constructor_match<T, checked, clean_stack>(obj, userdataref, umf), L, argcount, boost + 1 + 1 + static_cast<int>(syntax));
18710 
18711  userdataref.push();
18712  return 1;
18713  }
18714  };
18715 
18716  template <typename T, typename... Cxs, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18717  struct lua_call_wrapper<T, constructor_wrapper<Cxs...>, is_index, is_variable, checked, boost, clean_stack, C> {
18718  typedef constructor_wrapper<Cxs...> F;
18719 
18720  struct onmatch {
18721  template <typename Fx, std::size_t I, typename... R, typename... Args>
18722  int operator()(types<Fx>, meta::index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start, F& f) {
18723  const auto& meta = usertype_traits<T>::metatable();
18724  T* obj = detail::usertype_allocate<T>(L);
18725  reference userdataref(L, -1);
18726  stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
18727  umf();
18728 
18729  auto& func = std::get<I>(f.functions);
18730  // put userdata at the first index
18731  lua_insert(L, 1);
18732  stack::call_into_lua<checked, clean_stack>(r, a, L, boost + 1 + start, func, detail::implicit_wrapper<T>(obj));
18733 
18734  userdataref.push();
18735  return 1;
18736  }
18737  };
18738 
18739  static int call(lua_State* L, F& f) {
18740  call_syntax syntax = stack::get_call_syntax(L, usertype_traits<T>::user_metatable(), 1);
18741  int syntaxval = static_cast<int>(syntax);
18742  int argcount = lua_gettop(L) - syntaxval;
18743  return construct_match<T, meta::pop_front_type_t<meta::function_args_t<Cxs>>...>(onmatch(), L, argcount, 1 + syntaxval, f);
18744  }
18745  };
18746 
18747  template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18748  struct lua_call_wrapper<T, destructor_wrapper<Fx>, is_index, is_variable, checked, boost, clean_stack, C> {
18749 
18750  template <typename F>
18751  static int call(lua_State* L, F&& f) {
18752  if constexpr (std::is_void_v<Fx>) {
18753  return detail::usertype_alloc_destroy<T>(L);
18754  }
18755  else {
18756  using uFx = meta::unqualified_t<Fx>;
18758  return lcw.call(L, std::forward<F>(f).fx);
18759  }
18760  }
18761  };
18762 
18763  template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18764  struct lua_call_wrapper<T, overload_set<Fs...>, is_index, is_variable, checked, boost, clean_stack, C> {
18765  typedef overload_set<Fs...> F;
18766 
18767  struct on_match {
18768  template <typename Fx, std::size_t I, typename... R, typename... Args>
18769  int operator()(types<Fx>, meta::index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int, F& fx) {
18770  auto& f = std::get<I>(fx.functions);
18772  }
18773  };
18774 
18775  static int call(lua_State* L, F& fx) {
18776  return overload_match_arity<Fs...>(on_match(), L, lua_gettop(L), 1, fx);
18777  }
18778  };
18779 
18780  template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18781  struct lua_call_wrapper<T, factory_wrapper<Fs...>, is_index, is_variable, checked, boost, clean_stack, C> {
18782  typedef factory_wrapper<Fs...> F;
18783 
18784  struct on_match {
18785  template <typename Fx, std::size_t I, typename... R, typename... Args>
18786  int operator()(types<Fx>, meta::index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int, F& fx) {
18787  auto& f = std::get<I>(fx.functions);
18789  }
18790  };
18791 
18792  static int call(lua_State* L, F& fx) {
18793  return overload_match_arity<Fs...>(on_match(), L, lua_gettop(L) - boost, 1 + boost, fx);
18794  }
18795  };
18796 
18797  template <typename T, typename R, typename W, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18798  struct lua_call_wrapper<T, property_wrapper<R, W>, is_index, is_variable, checked, boost, clean_stack, C> {
18799  typedef meta::conditional_t<is_index, R, W> P;
18800  typedef meta::unqualified_t<P> U;
18801  typedef wrapper<U> wrap;
18803  typedef meta::unqualified_t<typename traits_type::template arg_at<0>> object_type;
18804 
18805  template <typename F, typename... Args>
18806  static int call(lua_State* L, F&& f, Args&&... args) {
18807  constexpr bool is_specialized = meta::any<std::is_same<U, detail::no_prop>,
18811  std::is_member_pointer<U>>::value;
18812  if constexpr (is_specialized) {
18813  if constexpr (is_index) {
18814  decltype(auto) p = f.read();
18815  lua_call_wrapper<T, meta::unqualified_t<decltype(p)>, is_index, is_variable, checked, boost, clean_stack> lcw {};
18816  return lcw.call(L, p, std::forward<Args>(args)...);
18817  }
18818  else {
18819  decltype(auto) p = f.write();
18820  lua_call_wrapper<T, meta::unqualified_t<decltype(p)>, is_index, is_variable, checked, boost, clean_stack> lcw {};
18821  return lcw.call(L, p, std::forward<Args>(args)...);
18822  }
18823  }
18824  else {
18825  constexpr bool non_class_object_type = meta::any<std::is_void<object_type>,
18826  meta::boolean<lua_type_of<meta::unwrap_unqualified_t<object_type>>::value != type::userdata>>::value;
18827  if constexpr (non_class_object_type) {
18828  // The type being void means we don't have any arguments, so it might be a free functions?
18829  using args_list = typename traits_type::free_args_list;
18830  using returns_list = typename wrap::returns_list;
18831  using caller = typename wrap::caller;
18832  if constexpr (is_index) {
18833  decltype(auto) pf = f.read();
18834  return stack::call_into_lua<checked, clean_stack>(
18835  returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), pf);
18836  }
18837  else {
18838  decltype(auto) pf = f.write();
18839  return stack::call_into_lua<checked, clean_stack>(
18840  returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), pf);
18841  }
18842  }
18843  else {
18844  using args_list = meta::pop_front_type_t<typename traits_type::free_args_list>;
18845  using Ta = T;
18846  using Oa = std::remove_pointer_t<object_type>;
18847 #if SOL_IS_ON(SOL_SAFE_USERTYPE)
18848  auto maybeo = stack::check_get<Ta*>(L, 1);
18849  if (!maybeo || maybeo.value() == nullptr) {
18850  if (is_variable) {
18851  return luaL_error(L, "sol: 'self' argument is lua_nil (bad '.' access?)");
18852  }
18853  return luaL_error(L, "sol: 'self' argument is lua_nil (pass 'self' as first argument)");
18854  }
18855  Oa* o = static_cast<Oa*>(maybeo.value());
18856 #else
18857  Oa* o = static_cast<Oa*>(stack::get<non_null<Ta*>>(L, 1));
18858 #endif // Safety
18859  using returns_list = typename wrap::returns_list;
18860  using caller = typename wrap::caller;
18861  if constexpr (is_index) {
18862  decltype(auto) pf = f.read();
18863  return stack::call_into_lua<checked, clean_stack>(
18864  returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), pf, detail::implicit_wrapper<Oa>(*o));
18865  }
18866  else {
18867  decltype(auto) pf = f.write();
18868  return stack::call_into_lua<checked, clean_stack>(
18869  returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), pf, detail::implicit_wrapper<Oa>(*o));
18870  }
18871  }
18872  }
18873  }
18874  };
18875 
18876  template <typename T, typename V, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18877  struct lua_call_wrapper<T, protect_t<V>, is_index, is_variable, checked, boost, clean_stack, C> {
18878  typedef protect_t<V> F;
18879 
18880  template <typename... Args>
18881  static int call(lua_State* L, F& fx, Args&&... args) {
18882  return lua_call_wrapper<T, V, is_index, is_variable, true, boost, clean_stack> {}.call(L, fx.value, std::forward<Args>(args)...);
18883  }
18884  };
18885 
18886  template <typename T, typename F, typename... Policies, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18887  struct lua_call_wrapper<T, policy_wrapper<F, Policies...>, is_index, is_variable, checked, boost, clean_stack, C> {
18888  typedef policy_wrapper<F, Policies...> P;
18889 
18890  template <std::size_t... In>
18891  static int call(std::index_sequence<In...>, lua_State* L, P& fx) {
18893  (void)detail::swallow { int(), (policy_detail::handle_policy(std::get<In>(fx.policies), L, pushed), int())... };
18894  return pushed;
18895  }
18896 
18897  static int call(lua_State* L, P& fx) {
18898  typedef typename P::indices indices;
18899  return call(indices(), L, fx);
18900  }
18901  };
18902 
18903  template <typename T, typename Y, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18904  struct lua_call_wrapper<T, yielding_t<Y>, is_index, is_variable, checked, boost, clean_stack, C> {
18905  template <typename F>
18906  static int call(lua_State* L, F&& f) {
18907  return lua_call_wrapper<T, meta::unqualified_t<Y>, is_index, is_variable, checked, boost, clean_stack> {}.call(L, f.func);
18908  }
18909  };
18910 
18911  template <typename T, typename Sig, typename P, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
18912  struct lua_call_wrapper<T, function_arguments<Sig, P>, is_index, is_variable, checked, boost, clean_stack, C> {
18913  static int call(lua_State* L, const function_arguments<Sig, P>& f) {
18914  lua_call_wrapper<T, meta::unqualified_t<P>, is_index, is_variable, checked, boost, clean_stack> lcw {};
18915  return lcw.call(L, std::get<0>(f.arguments));
18916  }
18917 
18918  static int call(lua_State* L, function_arguments<Sig, P>& f) {
18919  lua_call_wrapper<T, meta::unqualified_t<P>, is_index, is_variable, checked, boost, clean_stack> lcw {};
18920  return lcw.call(L, std::get<0>(f.arguments));
18921  }
18922 
18923  static int call(lua_State* L, function_arguments<Sig, P>&& f) {
18924  lua_call_wrapper<T, meta::unqualified_t<P>, is_index, is_variable, checked, boost, clean_stack> lcw {};
18925  return lcw.call(L, std::get<0>(std::move(f.arguments)));
18926  }
18927  };
18928 
18929  template <typename T, bool is_index, bool is_variable, int boost = 0, bool checked = detail::default_safe_function_calls, bool clean_stack = true,
18930  typename Fx, typename... Args>
18931  inline int call_wrapped(lua_State* L, Fx&& fx, Args&&... args) {
18932  using uFx = meta::unqualified_t<Fx>;
18933  if constexpr (meta::is_specialization_of_v<uFx, yielding_t>) {
18934  using real_fx = meta::unqualified_t<decltype(std::forward<Fx>(fx).func)>;
18936  return lcw.call(L, std::forward<Fx>(fx).func, std::forward<Args>(args)...);
18937  }
18938  else {
18940  return lcw.call(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
18941  }
18942  }
18943 
18944  template <typename T, bool is_index, bool is_variable, typename F, int start = 1, bool checked = detail::default_safe_function_calls,
18945  bool clean_stack = true>
18946  inline int call_user(lua_State* L) {
18947  auto& fx = stack::unqualified_get<user<F>>(L, upvalue_index(start));
18948  using uFx = meta::unqualified_t<F>;
18949  int nr = call_wrapped<T, is_index, is_variable, 0, checked, clean_stack>(L, fx);
18950  if constexpr (meta::is_specialization_of_v<uFx, yielding_t>) {
18951  return lua_yield(L, nr);
18952  }
18953  else {
18954  return nr;
18955  }
18956  }
18957 
18958  template <typename T, typename = void>
18959  struct is_var_bind : std::false_type { };
18960 
18961  template <typename T>
18962  struct is_var_bind<T, std::enable_if_t<std::is_member_object_pointer<T>::value>> : std::true_type { };
18963 
18964  template <typename T>
18965  struct is_var_bind<T, std::enable_if_t<is_lua_reference_or_proxy<T>::value>> : std::true_type { };
18966 
18967  template <>
18968  struct is_var_bind<detail::no_prop> : std::true_type { };
18969 
18970  template <typename R, typename W>
18971  struct is_var_bind<property_wrapper<R, W>> : std::true_type { };
18972 
18973  template <typename T>
18974  struct is_var_bind<var_wrapper<T>> : std::true_type { };
18975 
18976  template <typename T>
18977  struct is_var_bind<readonly_wrapper<T>> : is_var_bind<meta::unqualified_t<T>> { };
18978 
18979  template <typename F, typename... Policies>
18980  struct is_var_bind<policy_wrapper<F, Policies...>> : is_var_bind<meta::unqualified_t<F>> { };
18981  } // namespace call_detail
18982 
18983  template <typename T>
18984  struct is_variable_binding : call_detail::is_var_bind<meta::unqualified_t<T>> { };
18985 
18986  template <typename T>
18988 
18989  template <typename T>
18990  struct is_function_binding : meta::neg<is_variable_binding<T>> { };
18991 
18992 } // namespace sol
18993 
18994 // end of sol/call.hpp
18995 
18996 namespace sol {
18997  namespace function_detail {
18998  template <typename F, F fx>
18999  inline int call_wrapper_variable(std::false_type, lua_State* L) {
19000  typedef meta::bind_traits<meta::unqualified_t<F>> traits_type;
19001  typedef typename traits_type::args_list args_list;
19002  typedef meta::tuple_types<typename traits_type::return_type> return_type;
19003  return stack::call_into_lua(return_type(), args_list(), L, 1, fx);
19004  }
19005 
19006  template <typename R, typename V, V, typename T>
19007  inline int call_set_assignable(std::false_type, T&&, lua_State* L) {
19008  return luaL_error(L, "cannot write to this type: copy assignment/constructor not available");
19009  }
19010 
19011  template <typename R, typename V, V variable, typename T>
19012  inline int call_set_assignable(std::true_type, lua_State* L, T&& mem) {
19013  (mem.*variable) = stack::get<R>(L, 2);
19014  return 0;
19015  }
19016 
19017  template <typename R, typename V, V, typename T>
19018  inline int call_set_variable(std::false_type, lua_State* L, T&&) {
19019  return luaL_error(L, "cannot write to a const variable");
19020  }
19021 
19022  template <typename R, typename V, V variable, typename T>
19023  inline int call_set_variable(std::true_type, lua_State* L, T&& mem) {
19024  return call_set_assignable<R, V, variable>(std::is_assignable<std::add_lvalue_reference_t<R>, R>(), L, std::forward<T>(mem));
19025  }
19026 
19027  template <typename V, V variable>
19028  inline int call_wrapper_variable(std::true_type, lua_State* L) {
19029  typedef meta::bind_traits<meta::unqualified_t<V>> traits_type;
19030  typedef typename traits_type::object_type T;
19031  typedef typename traits_type::return_type R;
19032  auto& mem = stack::get<T>(L, 1);
19033  switch (lua_gettop(L)) {
19034  case 1: {
19035  decltype(auto) r = (mem.*variable);
19036  stack::push_reference(L, std::forward<decltype(r)>(r));
19037  return 1;
19038  }
19039  case 2:
19040  return call_set_variable<R, V, variable>(meta::neg<std::is_const<R>>(), L, mem);
19041  default:
19042  return luaL_error(L, "incorrect number of arguments to member variable function call");
19043  }
19044  }
19045 
19046  template <typename F, F fx>
19047  inline int call_wrapper_function(std::false_type, lua_State* L) {
19048  return call_wrapper_variable<F, fx>(std::is_member_object_pointer<F>(), L);
19049  }
19050 
19051  template <typename F, F fx>
19052  inline int call_wrapper_function(std::true_type, lua_State* L) {
19053  return call_detail::call_wrapped<void, false, false>(L, fx);
19054  }
19055 
19056  template <typename F, F fx>
19057  int call_wrapper_entry(lua_State* L) noexcept(meta::bind_traits<F>::is_noexcept) {
19058  return call_wrapper_function<F, fx>(std::is_member_function_pointer<meta::unqualified_t<F>>(), L);
19059  }
19060 
19061  template <typename... Fxs>
19063  template <typename Fx, std::size_t I, typename R, typename... Args>
19064  int operator()(types<Fx>, meta::index_value<I>, types<R>, types<Args...>, lua_State* L, int, int) const {
19065  typedef meta::at_in_pack_t<I, Fxs...> target;
19066  return target::call(L);
19067  }
19068  };
19069 
19070  template <typename F, F fx>
19071  inline int c_call_raw(std::true_type, lua_State* L) {
19072  return fx(L);
19073  }
19074 
19075  template <typename F, F fx>
19076  inline int c_call_raw(std::false_type, lua_State* L) {
19077 #ifdef __clang__
19078  return detail::trampoline(L, function_detail::call_wrapper_entry<F, fx>);
19079 #else
19080  return detail::typed_static_trampoline<decltype(&function_detail::call_wrapper_entry<F, fx>), (&function_detail::call_wrapper_entry<F, fx>)>(L);
19081 #endif // fuck you clang :c
19082  }
19083 
19084  } // namespace function_detail
19085 
19086  template <typename F, F fx>
19087  inline int c_call(lua_State* L) {
19088  typedef meta::unqualified_t<F> Fu;
19089  typedef std::integral_constant<bool,
19090  std::is_same<Fu, lua_CFunction>::value
19091 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
19092  || std::is_same<Fu, detail::lua_CFunction_noexcept>::value
19093 #endif
19094  >
19095  is_raw;
19096  return function_detail::c_call_raw<F, fx>(is_raw(), L);
19097  }
19098 
19099  template <typename F, F f>
19100  struct wrap {
19101  typedef F type;
19102 
19103  static int call(lua_State* L) noexcept(noexcept(c_call<type, f>(L))) {
19104  return c_call<type, f>(L);
19105  }
19106  };
19107 
19108  template <typename... Fxs>
19109  inline int c_call(lua_State* L) {
19110  if constexpr (sizeof...(Fxs) < 2) {
19111  using target = meta::at_in_pack_t<0, Fxs...>;
19112  return target::call(L);
19113  }
19114  else {
19115  return call_detail::overload_match_arity<typename Fxs::type...>(function_detail::c_call_matcher<Fxs...>(), L, lua_gettop(L), 1);
19116  }
19117  }
19118 
19119 } // namespace sol
19120 
19121 // end of sol/function_types_templated.hpp
19122 
19123 // beginning of sol/function_types_stateless.hpp
19124 
19125 namespace sol { namespace function_detail {
19126  template <typename Function>
19128  using function_type = std::remove_pointer_t<std::decay_t<Function>>;
19130 
19131  static int real_call(lua_State* L)
19132 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19133  // MSVC is broken, what a surprise...
19134 #else
19135  noexcept(traits_type::is_noexcept)
19136 #endif
19137  {
19138  auto udata = stack::stack_detail::get_as_upvalues<function_type*>(L);
19139  function_type* fx = udata.first;
19140  return call_detail::call_wrapped<void, true, false>(L, fx);
19141  }
19142 
19143  template <bool is_yielding, bool no_trampoline>
19144  static int call(lua_State* L) {
19145  int nr;
19146  if constexpr (no_trampoline) {
19147  nr = real_call(L);
19148  }
19149  else {
19150  nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
19151  }
19152  if (is_yielding) {
19153  return lua_yield(L, nr);
19154  }
19155  else {
19156  return nr;
19157  }
19158  }
19159  };
19160 
19161  template <typename T, typename Function>
19163  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
19165 
19166  static int real_call(lua_State* L)
19167 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19168  // MSVC is broken, what a surprise...
19169 #else
19170  noexcept(traits_type::is_noexcept)
19171 #endif
19172  {
19173  // Layout:
19174  // idx 1...n: verbatim data of member function pointer
19175  // idx n + 1: is the object's void pointer
19176  // We don't need to store the size, because the other side is templated
19177  // with the same member function pointer type
19178  function_type& memfx = stack::get<user<function_type>>(L, upvalue_index(2));
19179  auto& item = *static_cast<T*>(stack::get<void*>(L, upvalue_index(3)));
19180  return call_detail::call_wrapped<T, true, false, -1>(L, memfx, item);
19181  }
19182 
19183  template <bool is_yielding, bool no_trampoline>
19184  static int call(lua_State* L)
19185 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19186  // MSVC is broken, what a surprise...
19187 #else
19188  noexcept(traits_type::is_noexcept)
19189 #endif
19190  {
19191  int nr;
19192  if constexpr (no_trampoline) {
19193  nr = real_call(L);
19194  }
19195  else {
19196  nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
19197  }
19198  if (is_yielding) {
19199  return lua_yield(L, nr);
19200  }
19201  else {
19202  return nr;
19203  }
19204  }
19205 
19206  int operator()(lua_State* L)
19207 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19208  // MSVC is broken, what a surprise...
19209 #else
19210  noexcept(traits_type::is_noexcept)
19211 #endif
19212  {
19213  return call(L);
19214  }
19215  };
19216 
19217  template <typename T, typename Function>
19219  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
19221 
19222  static int real_call(lua_State* L)
19223 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19224  // MSVC is broken, what a surprise...
19225 #else
19226  noexcept(traits_type::is_noexcept)
19227 #endif
19228  {
19229  // Layout:
19230  // idx 1...n: verbatim data of member variable pointer
19231  // idx n + 1: is the object's void pointer
19232  // We don't need to store the size, because the other side is templated
19233  // with the same member function pointer type
19234  auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
19235  auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
19236  auto& mem = *objdata.first;
19237  function_type& var = memberdata.first;
19238  switch (lua_gettop(L)) {
19239  case 0:
19240  return call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
19241  case 1:
19242  return call_detail::call_wrapped<T, false, false, -1>(L, var, mem);
19243  default:
19244  return luaL_error(L, "sol: incorrect number of arguments to member variable function");
19245  }
19246  }
19247 
19248  template <bool is_yielding, bool no_trampoline>
19249  static int call(lua_State* L)
19250 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19251  // MSVC is broken, what a surprise...
19252 #else
19253  noexcept(traits_type::is_noexcept)
19254 #endif
19255  {
19256  int nr;
19257  if constexpr (no_trampoline) {
19258  nr = real_call(L);
19259  }
19260  else {
19261  nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
19262  }
19263  if (is_yielding) {
19264  return lua_yield(L, nr);
19265  }
19266  else {
19267  return nr;
19268  }
19269  }
19270 
19271  int operator()(lua_State* L)
19272 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19273  // MSVC is broken, what a surprise...
19274 #else
19275  noexcept(traits_type::is_noexcept)
19276 #endif
19277  {
19278  return call(L);
19279  }
19280  };
19281 
19282  template <typename T, typename Function>
19284  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
19286 
19287  static int real_call(lua_State* L)
19288 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19289  // MSVC is broken, what a surprise...
19290 #else
19291  noexcept(traits_type::is_noexcept)
19292 #endif
19293  {
19294  // Layout:
19295  // idx 1...n: verbatim data of member variable pointer
19296  // idx n + 1: is the object's void pointer
19297  // We don't need to store the size, because the other side is templated
19298  // with the same member function pointer type
19299  auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
19300  auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
19301  auto& mem = *objdata.first;
19302  function_type& var = memberdata.first;
19303  switch (lua_gettop(L)) {
19304  case 0:
19305  return call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
19306  default:
19307  return luaL_error(L, "sol: incorrect number of arguments to member variable function");
19308  }
19309  }
19310 
19311  template <bool is_yielding, bool no_trampoline>
19312  static int call(lua_State* L)
19313 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19314  // MSVC is broken, what a surprise...
19315 #else
19316  noexcept(traits_type::is_noexcept)
19317 #endif
19318  {
19319  int nr;
19320  if constexpr (no_trampoline) {
19321  nr = real_call(L);
19322  }
19323  else {
19324  nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
19325  }
19326  if (is_yielding) {
19327  return lua_yield(L, nr);
19328  }
19329  else {
19330  return nr;
19331  }
19332  }
19333 
19334  int operator()(lua_State* L)
19335 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19336  // MSVC is broken, what a surprise...
19337 #else
19338  noexcept(traits_type::is_noexcept)
19339 #endif
19340  {
19341  return call(L);
19342  }
19343  };
19344 
19345  template <typename T, typename Function>
19347  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
19349 
19350  static int real_call(lua_State* L)
19351 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19352  // MSVC is broken, what a surprise...
19353 #else
19354  noexcept(traits_type::is_noexcept)
19355 #endif
19356  {
19357  // Layout:
19358  // idx 1...n: verbatim data of member variable pointer
19359  function_type& memfx = stack::get<user<function_type>>(L, upvalue_index(2));
19360  return call_detail::call_wrapped<T, false, false>(L, memfx);
19361  }
19362 
19363  template <bool is_yielding, bool no_trampoline>
19364  static int call(lua_State* L)
19365 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19366  // MSVC is broken, what a surprise...
19367 #else
19368  noexcept(traits_type::is_noexcept)
19369 #endif
19370  {
19371  int nr;
19372  if constexpr (no_trampoline) {
19373  nr = real_call(L);
19374  }
19375  else {
19376  nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
19377  }
19378  if (is_yielding) {
19379  return lua_yield(L, nr);
19380  }
19381  else {
19382  return nr;
19383  }
19384  }
19385 
19386  int operator()(lua_State* L)
19387 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19388  // MSVC is broken, what a surprise...
19389 #else
19390  noexcept(traits_type::is_noexcept)
19391 #endif
19392  {
19393  return call(L);
19394  }
19395  };
19396 
19397  template <typename T, typename Function>
19399  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
19400 
19401  static int real_call(lua_State* L) noexcept(std::is_nothrow_copy_assignable_v<T>) {
19402  // Layout:
19403  // idx 1...n: verbatim data of member variable pointer
19404  auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
19405  function_type& var = memberdata.first;
19406  switch (lua_gettop(L)) {
19407  case 1:
19408  return call_detail::call_wrapped<T, true, false>(L, var);
19409  case 2:
19410  return call_detail::call_wrapped<T, false, false>(L, var);
19411  default:
19412  return luaL_error(L, "sol: incorrect number of arguments to member variable function");
19413  }
19414  }
19415 
19416  template <bool is_yielding, bool no_trampoline>
19417  static int call(lua_State* L) noexcept(std::is_nothrow_copy_assignable_v<T>) {
19418  int nr;
19419  if constexpr (no_trampoline) {
19420  nr = real_call(L);
19421  }
19422  else {
19423  nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
19424  }
19425  if (is_yielding) {
19426  return lua_yield(L, nr);
19427  }
19428  else {
19429  return nr;
19430  }
19431  }
19432 
19433  int operator()(lua_State* L) noexcept(std::is_nothrow_copy_assignable_v<T>) {
19434  return call(L);
19435  }
19436  };
19437 
19438  template <typename T, typename Function>
19440  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
19442 
19443  static int real_call(lua_State* L) noexcept(std::is_nothrow_copy_assignable_v<T>) {
19444  // Layout:
19445  // idx 1...n: verbatim data of member variable pointer
19446  auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
19447  function_type& var = memberdata.first;
19448  switch (lua_gettop(L)) {
19449  case 1:
19450  return call_detail::call_wrapped<T, true, false>(L, var);
19451  default:
19452  return luaL_error(L, "sol: incorrect number of arguments to member variable function");
19453  }
19454  }
19455 
19456  template <bool is_yielding, bool no_trampoline>
19457  static int call(lua_State* L) noexcept(std::is_nothrow_copy_assignable_v<T>) {
19458  int nr;
19459  if constexpr (no_trampoline) {
19460  nr = real_call(L);
19461  }
19462  else {
19463  nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
19464  }
19465  if (is_yielding) {
19466  return lua_yield(L, nr);
19467  }
19468  else {
19469  return nr;
19470  }
19471  }
19472 
19473  int operator()(lua_State* L) noexcept(std::is_nothrow_copy_assignable_v<T>) {
19474  return call(L);
19475  }
19476  };
19477 }} // namespace sol::function_detail
19478 
19479 // end of sol/function_types_stateless.hpp
19480 
19481 // beginning of sol/function_types_stateful.hpp
19482 
19483 namespace sol { namespace function_detail {
19484  template <typename Func, bool is_yielding, bool no_trampoline>
19486  typedef std::decay_t<meta::unwrap_unqualified_t<Func>> function_type;
19487  function_type invocation;
19488 
19489  template <typename... Args>
19490  functor_function(function_type f, Args&&... args) noexcept(std::is_nothrow_constructible_v<function_type, function_type, Args...>)
19491  : invocation(std::move(f), std::forward<Args>(args)...) {
19492  }
19493 
19494  static int call(lua_State* L, functor_function& self) noexcept(noexcept(call_detail::call_wrapped<void, true, false>(L, self.invocation))) {
19495  int nr = call_detail::call_wrapped<void, true, false>(L, self.invocation);
19496  if (is_yielding) {
19497  return lua_yield(L, nr);
19498  }
19499  else {
19500  return nr;
19501  }
19502  }
19503 
19504  int operator()(lua_State* L) noexcept(noexcept(call_detail::call_wrapped<void, true, false>(L, invocation))) {
19505  if constexpr (no_trampoline) {
19506  return call(L, *this);
19507  }
19508  else {
19509  return detail::trampoline(L, &call, *this);
19510  }
19511  }
19512  };
19513 
19514  template <typename T, typename Function, bool is_yielding, bool no_trampoline>
19516  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
19517  typedef meta::function_return_t<function_type> return_type;
19518  typedef meta::function_args_t<function_type> args_lists;
19520  function_type invocation;
19521  T member;
19522 
19523  template <typename... Args>
19524  member_function(function_type f, Args&&... args) noexcept(
19525  std::is_nothrow_constructible_v<function_type, function_type>&& std::is_nothrow_constructible_v<T, Args...>)
19526  : invocation(std::move(f)), member(std::forward<Args>(args)...) {
19527  }
19528 
19529  static int call(lua_State* L, member_function& self)
19530 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19531  // MSVC is broken, what a surprise...
19532 #else
19533  noexcept(traits_type::is_noexcept)
19534 #endif
19535  {
19536  int nr = call_detail::call_wrapped<T, true, false, -1>(L, self.invocation, detail::unwrap(detail::deref(self.member)));
19537  if (is_yielding) {
19538  return lua_yield(L, nr);
19539  }
19540  else {
19541  return nr;
19542  }
19543  }
19544 
19545  int operator()(lua_State* L)
19546 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19547  // MSVC is broken, what a surprise...
19548 #else
19549  noexcept(traits_type::is_noexcept)
19550 #endif
19551  {
19552  if constexpr (no_trampoline) {
19553  return call(L, *this);
19554  }
19555  else {
19556  return detail::trampoline(L, &call, *this);
19557  }
19558  }
19559  };
19560 
19561  template <typename T, typename Function, bool is_yielding, bool no_trampoline>
19563  typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
19564  typedef typename meta::bind_traits<function_type>::return_type return_type;
19566  function_type var;
19567  T member;
19568  typedef std::add_lvalue_reference_t<meta::unwrapped_t<std::remove_reference_t<decltype(detail::deref(member))>>> M;
19569 
19570  template <typename... Args>
19571  member_variable(function_type v, Args&&... args) noexcept(
19572  std::is_nothrow_constructible_v<function_type, function_type>&& std::is_nothrow_constructible_v<T, Args...>)
19573  : var(std::move(v)), member(std::forward<Args>(args)...) {
19574  }
19575 
19576  static int call(lua_State* L, member_variable& self) noexcept(std::is_nothrow_copy_assignable_v<T>) {
19577  int nr;
19578  {
19579  M mem = detail::unwrap(detail::deref(self.member));
19580  switch (lua_gettop(L)) {
19581  case 0:
19582  nr = call_detail::call_wrapped<T, true, false, -1>(L, self.var, mem);
19583  break;
19584  case 1:
19585  nr = call_detail::call_wrapped<T, false, false, -1>(L, self.var, mem);
19586  break;
19587  default:
19588  nr = luaL_error(L, "sol: incorrect number of arguments to member variable function");
19589  break;
19590  }
19591  }
19592  if (is_yielding) {
19593  return lua_yield(L, nr);
19594  }
19595  else {
19596  return nr;
19597  }
19598  }
19599 
19600  int operator()(lua_State* L) noexcept(std::is_nothrow_copy_assignable_v<T>) {
19601  if constexpr (no_trampoline) {
19602  return call(L, *this);
19603  }
19604  else {
19605  return detail::trampoline(L, &call, *this);
19606  }
19607  }
19608  };
19609 }} // namespace sol::function_detail
19610 
19611 // end of sol/function_types_stateful.hpp
19612 
19613 // beginning of sol/function_types_overloaded.hpp
19614 
19615 namespace sol { namespace function_detail {
19616  template <int start_skew, typename... Functions>
19618  typedef std::tuple<Functions...> overload_list;
19619  typedef std::make_index_sequence<sizeof...(Functions)> indices;
19620  overload_list overloads;
19621 
19622  overloaded_function(overload_list set) : overloads(std::move(set)) {
19623  }
19624 
19625  overloaded_function(Functions... fxs) : overloads(fxs...) {
19626  }
19627 
19628  template <typename Fx, std::size_t I, typename... R, typename... Args>
19629  static int call(types<Fx>, meta::index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int, overload_list& ol) {
19630  auto& func = std::get<I>(ol);
19631  int nr = call_detail::call_wrapped<void, true, false, start_skew>(L, func);
19632  return nr;
19633  }
19634 
19635  struct on_success {
19636  template <typename... Args>
19637  int operator()(Args&&... args) const {
19638  return call(std::forward<Args>(args)...);
19639  }
19640  };
19641 
19642  int operator()(lua_State* L) {
19643  on_success call_obj {};
19644  return call_detail::overload_match<Functions...>(call_obj, L, 1 + start_skew, overloads);
19645  }
19646  };
19647 }} // namespace sol::function_detail
19648 
19649 // end of sol/function_types_overloaded.hpp
19650 
19651 // beginning of sol/resolve.hpp
19652 
19653 namespace sol {
19654 
19655 #ifndef __clang__
19656  // constexpr is fine for not-clang
19657 
19658  namespace detail {
19659  template <typename R, typename... Args, typename F, typename = std::invoke_result_t<meta::unqualified_t<F>, Args...>>
19660  inline constexpr auto resolve_i(types<R(Args...)>, F&&) -> R (meta::unqualified_t<F>::*)(Args...) {
19661  using Sig = R(Args...);
19662  typedef meta::unqualified_t<F> Fu;
19663  return static_cast<Sig Fu::*>(&Fu::operator());
19664  }
19665 
19666  template <typename F, typename U = meta::unqualified_t<F>>
19667  inline constexpr auto resolve_f(std::true_type, F&& f)
19668  -> decltype(resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
19669  return resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
19670  }
19671 
19672  template <typename F>
19673  inline constexpr void resolve_f(std::false_type, F&&) {
19674  static_assert(meta::call_operator_deducible_v<F>, "Cannot use no-template-parameter call with an overloaded functor: specify the signature");
19675  }
19676 
19677  template <typename F, typename U = meta::unqualified_t<F>>
19678  inline constexpr auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::call_operator_deducible<U>(), std::forward<F>(f))) {
19679  return resolve_f(meta::call_operator_deducible<U> {}, std::forward<F>(f));
19680  }
19681 
19682  template <typename... Args, typename F, typename R = std::invoke_result_t<F&, Args...>>
19683  inline constexpr auto resolve_i(types<Args...>, F&& f) -> decltype(resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
19684  return resolve_i(types<R(Args...)>(), std::forward<F>(f));
19685  }
19686 
19687  template <typename Sig, typename C>
19688  inline constexpr Sig C::*resolve_v(std::false_type, Sig C::*mem_func_ptr) {
19689  return mem_func_ptr;
19690  }
19691 
19692  template <typename Sig, typename C>
19693  inline constexpr Sig C::*resolve_v(std::true_type, Sig C::*mem_variable_ptr) {
19694  return mem_variable_ptr;
19695  }
19696  } // namespace detail
19697 
19698  template <typename... Args, typename R>
19699  inline constexpr auto resolve(R fun_ptr(Args...)) -> R (*)(Args...) {
19700  return fun_ptr;
19701  }
19702 
19703  template <typename Sig>
19704  inline constexpr Sig* resolve(Sig* fun_ptr) {
19705  return fun_ptr;
19706  }
19707 
19708  template <typename... Args, typename R, typename C>
19709  inline constexpr auto resolve(R (C::*mem_ptr)(Args...)) -> R (C::*)(Args...) {
19710  return mem_ptr;
19711  }
19712 
19713  template <typename Sig, typename C>
19714  inline constexpr Sig C::*resolve(Sig C::*mem_ptr) {
19715  return detail::resolve_v(std::is_member_object_pointer<Sig C::*>(), mem_ptr);
19716  }
19717 
19718  template <typename... Sig, typename F, meta::disable<std::is_function<meta::unqualified_t<F>>> = meta::enabler>
19719  inline constexpr auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
19720  return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
19721  }
19722 #else
19723 
19724  // Clang has distinct problems with constexpr arguments,
19725  // so don't use the constexpr versions inside of clang.
19726 
19727  namespace detail {
19728  template <typename R, typename... Args, typename F, typename = std::invoke_result_t<meta::unqualified_t<F>, Args...>>
19729  inline auto resolve_i(types<R(Args...)>, F&&) -> R (meta::unqualified_t<F>::*)(Args...) {
19730  using Sig = R(Args...);
19731  typedef meta::unqualified_t<F> Fu;
19732  return static_cast<Sig Fu::*>(&Fu::operator());
19733  }
19734 
19735  template <typename F, typename U = meta::unqualified_t<F>>
19736  inline auto resolve_f(std::true_type, F&& f)
19737  -> decltype(resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
19738  return resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
19739  }
19740 
19741  template <typename F>
19742  inline void resolve_f(std::false_type, F&&) {
19743  static_assert(meta::call_operator_deducible_v<F>, "Cannot use no-template-parameter call with an overloaded functor: specify the signature");
19744  }
19745 
19746  template <typename F, typename U = meta::unqualified_t<F>>
19747  inline auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::call_operator_deducible<U>(), std::forward<F>(f))) {
19748  return resolve_f(meta::call_operator_deducible<U> {}, std::forward<F>(f));
19749  }
19750 
19751  template <typename... Args, typename F, typename R = std::invoke_result_t<F&, Args...>>
19752  inline auto resolve_i(types<Args...>, F&& f) -> decltype(resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
19753  return resolve_i(types<R(Args...)>(), std::forward<F>(f));
19754  }
19755 
19756  template <typename Sig, typename C>
19757  inline Sig C::*resolve_v(std::false_type, Sig C::*mem_func_ptr) {
19758  return mem_func_ptr;
19759  }
19760 
19761  template <typename Sig, typename C>
19762  inline Sig C::*resolve_v(std::true_type, Sig C::*mem_variable_ptr) {
19763  return mem_variable_ptr;
19764  }
19765  } // namespace detail
19766 
19767  template <typename... Args, typename R>
19768  inline auto resolve(R fun_ptr(Args...)) -> R (*)(Args...) {
19769  return fun_ptr;
19770  }
19771 
19772  template <typename Sig>
19773  inline Sig* resolve(Sig* fun_ptr) {
19774  return fun_ptr;
19775  }
19776 
19777  template <typename... Args, typename R, typename C>
19778  inline auto resolve(R (C::*mem_ptr)(Args...)) -> R (C::*)(Args...) {
19779  return mem_ptr;
19780  }
19781 
19782  template <typename Sig, typename C>
19783  inline Sig C::*resolve(Sig C::*mem_ptr) {
19784  return detail::resolve_v(std::is_member_object_pointer<Sig C::*>(), mem_ptr);
19785  }
19786 
19787  template <typename... Sig, typename F>
19788  inline auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
19789  return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
19790  }
19791 
19792 #endif
19793 
19794 } // namespace sol
19795 
19796 // end of sol/resolve.hpp
19797 
19798 namespace sol {
19799  namespace function_detail {
19800  template <typename T>
19802  using type = T;
19803  };
19804 
19805  struct call_indicator { };
19806 
19807  template <bool yielding>
19808  int lua_c_wrapper(lua_State* L) {
19809  lua_CFunction cf = lua_tocfunction(L, lua_upvalueindex(2));
19810  int nr = cf(L);
19811  if constexpr (yielding) {
19812  return lua_yield(L, nr);
19813  }
19814  else {
19815  return nr;
19816  }
19817  }
19818 
19819  template <bool yielding>
19820  int lua_c_noexcept_wrapper(lua_State* L) noexcept {
19821  detail::lua_CFunction_noexcept cf = reinterpret_cast<detail::lua_CFunction_noexcept>(lua_tocfunction(L, lua_upvalueindex(2)));
19822  int nr = cf(L);
19823  if constexpr (yielding) {
19824  return lua_yield(L, nr);
19825  }
19826  else {
19827  return nr;
19828  }
19829  }
19830 
19832 
19833  template <bool is_yielding, bool no_trampoline, typename Fx, typename... Args>
19834  void select(lua_State* L, Fx&& fx, Args&&... args);
19835 
19836  template <bool is_yielding, bool no_trampoline, typename Fx, typename... Args>
19837  void select_set_fx(lua_State* L, Args&&... args) {
19838  lua_CFunction freefunc = no_trampoline ? function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>
19839  : detail::static_trampoline<function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>>;
19840 
19841  int upvalues = 0;
19842  upvalues += stack::push(L, nullptr);
19843  upvalues += stack::push<user<Fx>>(L, std::forward<Args>(args)...);
19844  stack::push(L, c_closure(freefunc, upvalues));
19845  }
19846 
19847  template <bool is_yielding, bool no_trampoline, typename R, typename... A, typename Fx, typename... Args>
19848  void select_convertible(types<R(A...)>, lua_State* L, Fx&& fx, Args&&... args) {
19849  using dFx = std::decay_t<meta::unwrap_unqualified_t<Fx>>;
19850  using fx_ptr_t = R (*)(A...);
19851  constexpr bool is_convertible = std::is_convertible_v<dFx, fx_ptr_t>;
19852  if constexpr (is_convertible) {
19853  fx_ptr_t fxptr = detail::unwrap(std::forward<Fx>(fx));
19854  select<is_yielding, no_trampoline>(L, std::move(fxptr), std::forward<Args>(args)...);
19855  }
19856  else {
19858  select_set_fx<is_yielding, no_trampoline, F>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
19859  }
19860  }
19861 
19862  template <bool is_yielding, bool no_trampoline, typename Fx, typename... Args>
19863  void select_convertible(types<>, lua_State* L, Fx&& fx, Args&&... args) {
19864  typedef meta::function_signature_t<meta::unwrap_unqualified_t<Fx>> Sig;
19865  select_convertible<is_yielding, no_trampoline>(types<Sig>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
19866  }
19867 
19868  template <bool is_yielding, bool no_trampoline, typename Fx, typename... Args>
19869  void select_member_variable(lua_State* L, Fx&& fx, Args&&... args) {
19870  using uFx = meta::unqualified_t<Fx>;
19871  if constexpr (sizeof...(Args) < 1) {
19872  using C = typename meta::bind_traits<uFx>::object_type;
19873  lua_CFunction freefunc = &function_detail::upvalue_this_member_variable<C, Fx>::template call<is_yielding, no_trampoline>;
19874 
19875  int upvalues = 0;
19876  upvalues += stack::push(L, nullptr);
19877  upvalues += stack::stack_detail::push_as_upvalues(L, fx);
19878  stack::push(L, c_closure(freefunc, upvalues));
19879  }
19880  else if constexpr (sizeof...(Args) < 2) {
19881  using Tu = typename meta::meta_detail::unqualified_non_alias<Args...>::type;
19882  constexpr bool is_reference = meta::is_specialization_of_v<Tu, std::reference_wrapper> || std::is_pointer_v<Tu>;
19883  if constexpr (meta::is_specialization_of_v<Tu, function_detail::class_indicator>) {
19884  lua_CFunction freefunc
19886 
19887  int upvalues = 0;
19888  upvalues += stack::push(L, nullptr);
19889  upvalues += stack::stack_detail::push_as_upvalues(L, fx);
19890  stack::push(L, c_closure(freefunc, upvalues));
19891  }
19892  else if constexpr (is_reference) {
19893  typedef std::decay_t<Fx> dFx;
19894  dFx memfxptr(std::forward<Fx>(fx));
19895  auto userptr = detail::ptr(std::forward<Args>(args)...);
19897  meta::unqualified_t<Fx>>::template call<is_yielding, no_trampoline>;
19898 
19899  int upvalues = 0;
19900  upvalues += stack::push(L, nullptr);
19901  upvalues += stack::stack_detail::push_as_upvalues(L, memfxptr);
19902  upvalues += stack::push(L, static_cast<void const*>(userptr));
19903  stack::push(L, c_closure(freefunc, upvalues));
19904  }
19905  else {
19906  using clean_fx = std::remove_pointer_t<std::decay_t<Fx>>;
19908  select_set_fx<is_yielding, no_trampoline, F>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
19909  }
19910  }
19911  else {
19912  using C = typename meta::bind_traits<uFx>::object_type;
19913  using clean_fx = std::remove_pointer_t<std::decay_t<Fx>>;
19915  select_set_fx<is_yielding, no_trampoline, F>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
19916  }
19917  }
19918 
19919  template <bool is_yielding, bool no_trampoline, typename Fx, typename T, typename... Args>
19920  void select_member_function_with(lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
19921  using dFx = std::decay_t<Fx>;
19922  using Tu = meta::unqualified_t<T>;
19923  if constexpr (meta::is_specialization_of_v<Tu, function_detail::class_indicator>) {
19924  (void)obj;
19925  using C = typename Tu::type;
19926  lua_CFunction freefunc = &function_detail::upvalue_this_member_function<C, dFx>::template call<is_yielding, no_trampoline>;
19927 
19928  int upvalues = 0;
19929  upvalues += stack::push(L, nullptr);
19930  upvalues += stack::push<user<dFx>>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
19931  stack::push(L, c_closure(freefunc, upvalues));
19932  }
19933  else {
19934  constexpr bool is_reference = meta::is_specialization_of_v<Tu, std::reference_wrapper> || std::is_pointer_v<Tu>;
19935  if constexpr (is_reference) {
19936  auto userptr = detail::ptr(std::forward<T>(obj));
19937  lua_CFunction freefunc
19938  = &function_detail::upvalue_member_function<std::decay_t<decltype(*userptr)>, dFx>::template call<is_yielding, no_trampoline>;
19939 
19940  int upvalues = 0;
19941  upvalues += stack::push(L, nullptr);
19942  upvalues += stack::push<user<dFx>>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
19943  upvalues += stack::push(L, lightuserdata_value(static_cast<void*>(userptr)));
19944  stack::push(L, c_closure(freefunc, upvalues));
19945  }
19946  else {
19948  select_set_fx<is_yielding, no_trampoline, F>(L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
19949  }
19950  }
19951  }
19952 
19953  template <bool is_yielding, bool no_trampoline, typename Fx, typename... Args>
19954  void select_member_function(lua_State* L, Fx&& fx, Args&&... args) {
19955  using dFx = std::decay_t<Fx>;
19956  if constexpr (sizeof...(Args) < 1) {
19957  using C = typename meta::bind_traits<meta::unqualified_t<Fx>>::object_type;
19958  lua_CFunction freefunc = &function_detail::upvalue_this_member_function<C, dFx>::template call<is_yielding, no_trampoline>;
19959 
19960  int upvalues = 0;
19961  upvalues += stack::push(L, nullptr);
19962  upvalues += stack::push<user<dFx>>(L, std::forward<Fx>(fx));
19963  stack::push(L, c_closure(freefunc, upvalues));
19964  }
19965  else {
19966  select_member_function_with<is_yielding, no_trampoline>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
19967  }
19968  }
19969 
19970  template <bool is_yielding, bool no_trampoline, typename Fx, typename... Args>
19971  void select(lua_State* L, Fx&& fx, Args&&... args) {
19972  using uFx = meta::unqualified_t<Fx>;
19973  if constexpr (is_lua_reference_v<uFx>) {
19974  // TODO: hoist into lambda in this case for yielding???
19975  stack::push(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
19976  }
19977  else if constexpr (is_lua_c_function_v<uFx>) {
19978  if constexpr (no_trampoline) {
19979  if (is_yielding) {
19980  int upvalues = 0;
19981  upvalues += stack::push(L, nullptr);
19982  upvalues += stack::push(L, std::forward<Fx>(fx));
19983 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
19984  if constexpr (std::is_nothrow_invocable_r_v<int, uFx, lua_State*>) {
19985  detail::lua_CFunction_noexcept cf = &lua_c_noexcept_wrapper<true>;
19986  lua_pushcclosure(L, reinterpret_cast<lua_CFunction>(cf), upvalues);
19987  }
19988  else
19989 #endif
19990  {
19991  lua_CFunction cf = &function_detail::lua_c_wrapper<true>;
19992  lua_pushcclosure(L, cf, upvalues);
19993  }
19994  }
19995  else {
19996  lua_pushcclosure(L, std::forward<Fx>(fx), 0);
19997  }
19998  }
19999  else {
20000  int upvalues = 0;
20001  upvalues += stack::push(L, nullptr);
20002  upvalues += stack::push(L, std::forward<Fx>(fx));
20003 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
20004  if constexpr (std::is_nothrow_invocable_r_v<int, uFx, lua_State*>) {
20005  detail::lua_CFunction_noexcept cf = &lua_c_noexcept_wrapper<is_yielding>;
20006  lua_pushcclosure(L, reinterpret_cast<lua_CFunction>(cf), upvalues);
20007  }
20008  else {
20009  lua_CFunction cf = &function_detail::lua_c_wrapper<is_yielding>;
20010  lua_pushcclosure(L, cf, upvalues);
20011  }
20012 #else
20013  lua_CFunction cf = &function_detail::lua_c_wrapper<is_yielding>;
20014  lua_pushcclosure(L, cf, upvalues);
20015 #endif
20016  }
20017  }
20018  else if constexpr (std::is_function_v<std::remove_pointer_t<uFx>>) {
20019  std::decay_t<Fx> target(std::forward<Fx>(fx), std::forward<Args>(args)...);
20020  lua_CFunction freefunc = &function_detail::upvalue_free_function<Fx>::template call<is_yielding, no_trampoline>;
20021 
20022  int upvalues = 0;
20023  upvalues += stack::push(L, nullptr);
20024  upvalues += stack::stack_detail::push_as_upvalues(L, target);
20025  stack::push(L, c_closure(freefunc, upvalues));
20026  }
20027  else if constexpr (std::is_member_function_pointer_v<uFx>) {
20028  select_member_function<is_yielding, no_trampoline>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
20029  }
20030  else if constexpr (meta::is_member_object_v<uFx>) {
20031  select_member_variable<is_yielding, no_trampoline>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
20032  }
20033  else {
20034  select_convertible<is_yielding, no_trampoline>(types<>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
20035  }
20036  }
20037  } // namespace function_detail
20038 
20039  namespace stack {
20040  template <typename... Sigs>
20042  template <bool is_yielding, typename Arg0, typename... Args>
20043  static int push_yielding(lua_State* L, Arg0&& arg0, Args&&... args) {
20044  if constexpr (meta::is_specialization_of_v<meta::unqualified_t<Arg0>, std::function>) {
20045  if constexpr (is_yielding) {
20046  return stack::push<meta::unqualified_t<Arg0>>(L, detail::yield_tag, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
20047  }
20048  else {
20049  return stack::push(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
20050  }
20051  }
20052  else {
20053  function_detail::select<is_yielding, false>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
20054  return 1;
20055  }
20056  }
20057 
20058  template <typename Arg0, typename... Args>
20059  static int push(lua_State* L, Arg0&& arg0, Args&&... args) {
20060  if constexpr (std::is_same_v<meta::unqualified_t<Arg0>, detail::yield_tag_t>) {
20061  push_yielding<true>(L, std::forward<Args>(args)...);
20062  }
20063  else if constexpr (meta::is_specialization_of_v<meta::unqualified_t<Arg0>, yielding_t>) {
20064  push_yielding<true>(L, std::forward<Arg0>(arg0).func, std::forward<Args>(args)...);
20065  }
20066  else {
20067  push_yielding<false>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
20068  }
20069  return 1;
20070  }
20071  };
20072 
20073  template <typename T>
20075  template <typename... Args>
20076  static int push(lua_State* L, const yielding_t<T>& f, Args&&... args) {
20077  if constexpr (meta::is_specialization_of_v<meta::unqualified_t<T>, std::function>) {
20078  return stack::push<T>(L, detail::yield_tag, f.func, std::forward<Args>(args)...);
20079  }
20080  else {
20081  function_detail::select<true, false>(L, f.func, std::forward<Args>(args)...);
20082  return 1;
20083  }
20084  }
20085 
20086  template <typename... Args>
20087  static int push(lua_State* L, yielding_t<T>&& f, Args&&... args) {
20088  if constexpr (meta::is_specialization_of_v<meta::unqualified_t<T>, std::function>) {
20089  return stack::push<T>(L, detail::yield_tag, std::move(f.func), std::forward<Args>(args)...);
20090  }
20091  else {
20092  function_detail::select<true, false>(L, std::move(f.func), std::forward<Args>(args)...);
20093  return 1;
20094  }
20095  }
20096  };
20097 
20098  template <typename T, typename... Args>
20100  template <std::size_t... I, typename FP>
20101  static int push_func(std::index_sequence<I...>, lua_State* L, FP&& fp) {
20102  return stack::push<T>(L, std::get<I>(std::forward<FP>(fp).arguments)...);
20103  }
20104 
20105  static int push(lua_State* L, const function_arguments<T, Args...>& fp) {
20106  return push_func(std::make_index_sequence<sizeof...(Args)>(), L, fp);
20107  }
20108 
20109  static int push(lua_State* L, function_arguments<T, Args...>&& fp) {
20110  return push_func(std::make_index_sequence<sizeof...(Args)>(), L, std::move(fp));
20111  }
20112  };
20113 
20114  template <typename Signature>
20115  struct unqualified_pusher<std::function<Signature>> {
20117 
20118  static int push(lua_State* L, detail::yield_tag_t, const std::function<Signature>& fx) {
20119  if (fx) {
20120  function_detail::select_set_fx<true, false, TargetFunctor>(L, fx);
20121  return 1;
20122  }
20123  return stack::push(L, lua_nil);
20124  }
20125 
20126  static int push(lua_State* L, detail::yield_tag_t, std::function<Signature>&& fx) {
20127  if (fx) {
20128  function_detail::select_set_fx<true, false, TargetFunctor>(L, std::move(fx));
20129  return 1;
20130  }
20131  return stack::push(L, lua_nil);
20132  }
20133 
20134  static int push(lua_State* L, const std::function<Signature>& fx) {
20135  if (fx) {
20136  function_detail::select_set_fx<false, false, TargetFunctor>(L, fx);
20137  return 1;
20138  }
20139  return stack::push(L, lua_nil);
20140  }
20141 
20142  static int push(lua_State* L, std::function<Signature>&& fx) {
20143  if (fx) {
20144  function_detail::select_set_fx<false, false, TargetFunctor>(L, std::move(fx));
20145  return 1;
20146  }
20147  return stack::push(L, lua_nil);
20148  }
20149  };
20150 
20151  template <typename Signature>
20152  struct unqualified_pusher<Signature, std::enable_if_t<meta::is_member_object_or_function_v<Signature>>> {
20153  template <typename... Args>
20154  static int push(lua_State* L, Args&&... args) {
20155  function_detail::select<false, false>(L, std::forward<Args>(args)...);
20156  return 1;
20157  }
20158  };
20159 
20160  template <typename Signature>
20161  struct unqualified_pusher<Signature,
20162  std::enable_if_t<meta::all<std::is_function<std::remove_pointer_t<Signature>>, meta::neg<std::is_same<Signature, lua_CFunction>>,
20163  meta::neg<std::is_same<Signature, std::remove_pointer_t<lua_CFunction>>>
20164 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
20165  ,
20166  meta::neg<std::is_same<Signature, detail::lua_CFunction_noexcept>>,
20167  meta::neg<std::is_same<Signature, std::remove_pointer_t<detail::lua_CFunction_noexcept>>>
20168 #endif // noexcept function types
20169  >::value>> {
20170  template <typename F>
20171  static int push(lua_State* L, F&& f) {
20172  function_detail::select<false, true>(L, std::forward<F>(f));
20173  return 1;
20174  }
20175  };
20176 
20177  template <typename... Functions>
20178  struct unqualified_pusher<overload_set<Functions...>> {
20179  static int push(lua_State* L, overload_set<Functions...>&& set) {
20180  using F = function_detail::overloaded_function<0, Functions...>;
20181  function_detail::select_set_fx<false, false, F>(L, std::move(set.functions));
20182  return 1;
20183  }
20184 
20185  static int push(lua_State* L, const overload_set<Functions...>& set) {
20186  using F = function_detail::overloaded_function<0, Functions...>;
20187  function_detail::select_set_fx<false, false, F>(L, set.functions);
20188  return 1;
20189  }
20190  };
20191 
20192  template <typename T>
20194  static int push(lua_State* L, protect_t<T>&& pw) {
20195  lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>, 2>;
20196  int upvalues = 0;
20197  upvalues += stack::push(L, nullptr);
20198  upvalues += stack::push<user<protect_t<T>>>(L, std::move(pw.value));
20199  return stack::push(L, c_closure(cf, upvalues));
20200  }
20201 
20202  static int push(lua_State* L, const protect_t<T>& pw) {
20203  lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>, 2>;
20204  int upvalues = 0;
20205  upvalues += stack::push(L, nullptr);
20206  upvalues += stack::push<user<protect_t<T>>>(L, pw.value);
20207  return stack::push(L, c_closure(cf, upvalues));
20208  }
20209  };
20210 
20211  template <typename F, typename G>
20213  static int push(lua_State* L, property_wrapper<F, G>&& pw) {
20214  if constexpr (std::is_void_v<F>) {
20215  return stack::push(L, std::move(pw.write()));
20216  }
20217  else if constexpr (std::is_void_v<G>) {
20218  return stack::push(L, std::move(pw.read()));
20219  }
20220  else {
20221  return stack::push(L, overload(std::move(pw.read()), std::move(pw.write())));
20222  }
20223  }
20224 
20225  static int push(lua_State* L, const property_wrapper<F, G>& pw) {
20226  if constexpr (std::is_void_v<F>) {
20227  return stack::push(L, pw.write);
20228  }
20229  else if constexpr (std::is_void_v<G>) {
20230  return stack::push(L, pw.read);
20231  }
20232  else {
20233  return stack::push(L, overload(pw.read, pw.write));
20234  }
20235  }
20236  };
20237 
20238  template <typename T>
20240  static int push(lua_State* L, var_wrapper<T>&& vw) {
20241  return stack::push(L, std::move(vw.value()));
20242  }
20243  static int push(lua_State* L, const var_wrapper<T>& vw) {
20244  return stack::push(L, vw.value());
20245  }
20246  };
20247 
20248  template <typename... Functions>
20249  struct unqualified_pusher<factory_wrapper<Functions...>> {
20250  static int push(lua_State* L, const factory_wrapper<Functions...>& fw) {
20251  using F = function_detail::overloaded_function<0, Functions...>;
20252  function_detail::select_set_fx<false, false, F>(L, fw.functions);
20253  return 1;
20254  }
20255 
20256  static int push(lua_State* L, factory_wrapper<Functions...>&& fw) {
20257  using F = function_detail::overloaded_function<0, Functions...>;
20258  function_detail::select_set_fx<false, false, F>(L, std::move(fw.functions));
20259  return 1;
20260  }
20261 
20263  using F = function_detail::overloaded_function<1, Functions...>;
20264  function_detail::select_set_fx<false, false, F>(L, fw.functions);
20265  return 1;
20266  }
20267 
20269  using F = function_detail::overloaded_function<1, Functions...>;
20270  function_detail::select_set_fx<false, false, F>(L, std::move(fw.functions));
20271  return 1;
20272  }
20273  };
20274 
20275  template <>
20277  static int push(lua_State* L, no_construction) {
20278  lua_CFunction cf = &function_detail::no_construction_error;
20279  return stack::push(L, cf);
20280  }
20281 
20283  return push(L, c);
20284  }
20285  };
20286 
20287  template <typename T>
20288  struct unqualified_pusher<detail::tagged<T, no_construction>> {
20289  static int push(lua_State* L, detail::tagged<T, no_construction>) {
20290  lua_CFunction cf = &function_detail::no_construction_error;
20291  return stack::push(L, cf);
20292  }
20293 
20295  lua_CFunction cf = &function_detail::no_construction_error;
20296  return stack::push(L, cf);
20297  }
20298  };
20299 
20300  template <typename T, typename... Lists>
20301  struct unqualified_pusher<detail::tagged<T, constructor_list<Lists...>>> {
20302  static int push(lua_State* L, detail::tagged<T, constructor_list<Lists...>>) {
20303  lua_CFunction cf = call_detail::construct<T, detail::default_safe_function_calls, true, Lists...>;
20304  return stack::push(L, cf);
20305  }
20306 
20307  static int push(lua_State* L, constructor_list<Lists...>) {
20308  lua_CFunction cf = call_detail::construct<T, detail::default_safe_function_calls, true, Lists...>;
20309  return stack::push(L, cf);
20310  }
20311  };
20312 
20313  template <typename L0, typename... Lists>
20314  struct unqualified_pusher<constructor_list<L0, Lists...>> {
20315  typedef constructor_list<L0, Lists...> cl_t;
20316  static int push(lua_State* L, cl_t cl) {
20317  typedef typename meta::bind_traits<L0>::return_type T;
20318  return stack::push<detail::tagged<T, cl_t>>(L, cl);
20319  }
20320  };
20321 
20322  template <typename T, typename... Fxs>
20323  struct unqualified_pusher<detail::tagged<T, constructor_wrapper<Fxs...>>> {
20324  static int push(lua_State* L, detail::tagged<T, constructor_wrapper<Fxs...>>&& c) {
20325  return push(L, std::move(c.value()));
20326  }
20327 
20328  static int push(lua_State* L, const detail::tagged<T, const constructor_wrapper<Fxs...>>& c) {
20329  return push(L, c.value());
20330  }
20331 
20332  static int push(lua_State* L, constructor_wrapper<Fxs...>&& c) {
20333  lua_CFunction cf = call_detail::call_user<T, false, false, constructor_wrapper<Fxs...>, 2>;
20334  int upvalues = 0;
20335  upvalues += stack::push(L, nullptr);
20336  upvalues += stack::push<user<constructor_wrapper<Fxs...>>>(L, std::move(c));
20337  return stack::push(L, c_closure(cf, upvalues));
20338  }
20339 
20340  static int push(lua_State* L, const constructor_wrapper<Fxs...>& c) {
20341  lua_CFunction cf = call_detail::call_user<T, false, false, constructor_wrapper<Fxs...>, 2>;
20342  int upvalues = 0;
20343  upvalues += stack::push(L, nullptr);
20344  upvalues += stack::push<user<constructor_wrapper<Fxs...>>>(L, c);
20345  return stack::push(L, c_closure(cf, upvalues));
20346  }
20347  };
20348 
20349  template <typename F, typename... Fxs>
20351  static int push(lua_State* L, const constructor_wrapper<F, Fxs...>& c) {
20352  typedef typename meta::bind_traits<F>::template arg_at<0> arg0;
20353  typedef meta::unqualified_t<std::remove_pointer_t<arg0>> T;
20354  return stack::push<detail::tagged<T, constructor_wrapper<F, Fxs...>>>(L, c);
20355  }
20356 
20357  static int push(lua_State* L, constructor_wrapper<F, Fxs...>&& c) {
20358  typedef typename meta::bind_traits<F>::template arg_at<0> arg0;
20359  typedef meta::unqualified_t<std::remove_pointer_t<arg0>> T;
20360  return stack::push<detail::tagged<T, constructor_wrapper<F, Fxs...>>>(L, std::move(c));
20361  }
20362  };
20363 
20364  template <typename T>
20365  struct unqualified_pusher<detail::tagged<T, destructor_wrapper<void>>> {
20366  static int push(lua_State* L, destructor_wrapper<void>) {
20367  lua_CFunction cf = detail::usertype_alloc_destroy<T>;
20368  return stack::push(L, cf);
20369  }
20370  };
20371 
20372  template <typename T, typename Fx>
20373  struct unqualified_pusher<detail::tagged<T, destructor_wrapper<Fx>>> {
20374  static int push(lua_State* L, destructor_wrapper<Fx>&& c) {
20375  lua_CFunction cf = call_detail::call_user<T, false, false, destructor_wrapper<Fx>, 2>;
20376  int upvalues = 0;
20377  upvalues += stack::push(L, nullptr);
20378  upvalues += stack::push<user<destructor_wrapper<Fx>>>(L, std::move(c));
20379  return stack::push(L, c_closure(cf, upvalues));
20380  }
20381 
20382  static int push(lua_State* L, const destructor_wrapper<Fx>& c) {
20383  lua_CFunction cf = call_detail::call_user<T, false, false, destructor_wrapper<Fx>, 2>;
20384  int upvalues = 0;
20385  upvalues += stack::push(L, nullptr);
20386  upvalues += stack::push<user<destructor_wrapper<Fx>>>(L, c);
20387  return stack::push(L, c_closure(cf, upvalues));
20388  }
20389  };
20390 
20391  template <typename Fx>
20393  static int push(lua_State* L, destructor_wrapper<Fx>&& c) {
20394  lua_CFunction cf = call_detail::call_user<void, false, false, destructor_wrapper<Fx>, 2>;
20395  int upvalues = 0;
20396  upvalues += stack::push(L, nullptr);
20397  upvalues += stack::push<user<destructor_wrapper<Fx>>>(L, std::move(c));
20398  return stack::push(L, c_closure(cf, upvalues));
20399  }
20400 
20401  static int push(lua_State* L, const destructor_wrapper<Fx>& c) {
20402  lua_CFunction cf = call_detail::call_user<void, false, false, destructor_wrapper<Fx>, 2>;
20403  int upvalues = 0;
20404  upvalues += stack::push(L, nullptr);
20405  upvalues += stack::push<user<destructor_wrapper<Fx>>>(L, c);
20406  return stack::push(L, c_closure(cf, upvalues));
20407  }
20408  };
20409 
20410  template <typename F, typename... Policies>
20411  struct unqualified_pusher<policy_wrapper<F, Policies...>> {
20412  using P = policy_wrapper<F, Policies...>;
20413 
20414  static int push(lua_State* L, const P& p) {
20415  lua_CFunction cf = call_detail::call_user<void, false, false, P, 2>;
20416  int upvalues = 0;
20417  upvalues += stack::push(L, nullptr);
20418  upvalues += stack::push<user<P>>(L, p);
20419  return stack::push(L, c_closure(cf, upvalues));
20420  }
20421 
20422  static int push(lua_State* L, P&& p) {
20423  lua_CFunction cf = call_detail::call_user<void, false, false, P, 2>;
20424  int upvalues = 0;
20425  upvalues += stack::push(L, nullptr);
20426  upvalues += stack::push<user<P>>(L, std::move(p));
20427  return stack::push(L, c_closure(cf, upvalues));
20428  }
20429  };
20430 
20431  template <typename T, typename F, typename... Policies>
20432  struct unqualified_pusher<detail::tagged<T, policy_wrapper<F, Policies...>>> {
20433  using P = policy_wrapper<F, Policies...>;
20434  using Tagged = detail::tagged<T, P>;
20435 
20436  static int push(lua_State* L, const Tagged& p) {
20437  lua_CFunction cf = call_detail::call_user<T, false, false, P, 2>;
20438  int upvalues = 0;
20439  upvalues += stack::push(L, nullptr);
20440  upvalues += stack::push<user<P>>(L, p.value());
20441  return stack::push(L, c_closure(cf, upvalues));
20442  }
20443 
20444  static int push(lua_State* L, Tagged&& p) {
20445  lua_CFunction cf = call_detail::call_user<T, false, false, P, 2>;
20446  int upvalues = 0;
20447  upvalues += stack::push(L, nullptr);
20448  upvalues += stack::push<user<P>>(L, std::move(p.value()));
20449  return stack::push(L, c_closure(cf, upvalues));
20450  }
20451  };
20452 
20453  template <typename T>
20455  static int push(lua_State* L, push_invoke_t<T>&& pi) {
20456  if constexpr (std::is_invocable_v<std::add_rvalue_reference_t<T>, lua_State*>) {
20457  return stack::push(L, std::move(pi.value())(L));
20458  }
20459  else {
20460  return stack::push(L, std::move(pi.value())());
20461  }
20462  }
20463 
20464  static int push(lua_State* L, const push_invoke_t<T>& pi) {
20465  if constexpr (std::is_invocable_v<const T, lua_State*>) {
20466  return stack::push(L, pi.value()(L));
20467  }
20468  else {
20469  return stack::push(L, pi.value()());
20470  }
20471  }
20472  };
20473 
20474  namespace stack_detail {
20475  template <typename Function, typename Handler>
20476  bool check_function_pointer(lua_State* L, int index, Handler&& handler, record& tracking) noexcept {
20477 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
20478  tracking.use(1);
20479  bool success = lua_iscfunction(L, index) == 1;
20480  if (success) {
20481  // there must be at LEAST 2 upvalues; otherwise, we didn't serialize it.
20482  const char* upvalue_name = lua_getupvalue(L, index, 2);
20483  lua_pop(L, 1);
20484  success = upvalue_name != nullptr;
20485  }
20486  if (!success) {
20487  // expected type, actual type
20488  handler(
20489  L, index, type::function, type_of(L, index), "type must be a Lua C Function gotten from a function pointer serialized by sol2");
20490  }
20491  return success;
20492 #else
20493  (void)L;
20494  (void)index;
20495  (void)handler;
20496  (void)tracking;
20497  return false;
20498 #endif
20499  }
20500 
20501  template <typename Function>
20502  Function* get_function_pointer(lua_State* L, int index, record& tracking) noexcept {
20503 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
20504  tracking.use(1);
20505  auto udata = stack::stack_detail::get_as_upvalues_using_function<Function*>(L, index);
20506  Function* fx = udata.first;
20507  return fx;
20508 #else
20509  (void)L;
20510  (void)index;
20511  (void)tracking;
20513 #if SOL_IS_DEFAULT_OFF(SOL_GET_FUNCTION_POINTER_UNSAFE)
20514  "You are attempting to retrieve a function pointer type. "
20515  "This is inherently unsafe in sol2. In order to do this, you must turn on the "
20516  "SOL_GET_FUNCTION_POINTER_UNSAFE configuration macro, as detailed in the documentation. "
20517  "Please be careful!"
20518 #else
20519  "You are attempting to retrieve a function pointer type. "
20520  "You explicitly turned off the ability to do this by defining "
20521  "SOL_GET_FUNCTION_POINTER_UNSAFE or similar to be off. "
20522  "Please reconsider this!"
20523 #endif
20524  );
20525  return nullptr;
20526 #endif
20527  }
20528  } // namespace stack_detail
20529  } // namespace stack
20530 } // namespace sol
20531 
20532 // end of sol/function_types.hpp
20533 
20534 // beginning of sol/dump_handler.hpp
20535 
20536 #include <cstdint>
20537 #include <exception>
20538 
20539 namespace sol {
20540 
20541  class dump_error : public error {
20542  private:
20543  int m_ec;
20544 
20545  public:
20546  dump_error(int error_code_) : error("dump returned non-zero error of " + std::to_string(error_code_)), m_ec(error_code_) {
20547  }
20548 
20549  int error_code() const {
20550  return m_ec;
20551  }
20552  };
20553 
20554  inline int dump_pass_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) {
20555  (void)L_;
20556  (void)writer_function;
20557  (void)userdata_pointer_;
20558  (void)strip;
20559  return result_code;
20560  }
20561 
20562  inline int dump_panic_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) {
20563  (void)L_;
20564  (void)writer_function;
20565  (void)userdata_pointer_;
20566  (void)strip;
20567  return luaL_error(L_, "a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code);
20568  }
20569 
20570  inline int dump_throw_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) {
20571 #if SOL_IS_OFF(SOL_EXCEPTIONS)
20572  return dump_panic_on_error(L_, result_code, writer_function, userdata_pointer_, strip);
20573 #else
20574  (void)L_;
20575  (void)writer_function;
20576  (void)userdata_pointer_;
20577  (void)strip;
20578  throw dump_error(result_code);
20579 #endif // no exceptions stuff
20580  }
20581 
20582 } // namespace sol
20583 
20584 // end of sol/dump_handler.hpp
20585 
20586 #include <cstdint>
20587 
20588 namespace sol {
20589  template <typename ref_t, bool aligned = false>
20590  class basic_function : public basic_object<ref_t> {
20591  private:
20592  using base_t = basic_object<ref_t>;
20593 
20594  void luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount) const {
20595  lua_call(lua_state(), static_cast<int>(argcount), static_cast<int>(resultcount));
20596  }
20597 
20598  template <std::size_t... I, typename... Ret>
20599  auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n) const {
20600  luacall(n, lua_size<std::tuple<Ret...>>::value);
20601  return stack::pop<std::tuple<Ret...>>(lua_state());
20602  }
20603 
20604  template <std::size_t I, typename Ret, meta::enable<meta::neg<std::is_void<Ret>>> = meta::enabler>
20605  Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n) const {
20606  luacall(n, lua_size<Ret>::value);
20607  return stack::pop<Ret>(lua_state());
20608  }
20609 
20610  template <std::size_t I>
20611  void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n) const {
20612  luacall(n, 0);
20613  }
20614 
20615  unsafe_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n) const {
20616  int stacksize = lua_gettop(lua_state());
20617  int firstreturn = (std::max)(1, stacksize - static_cast<int>(n));
20618  luacall(n, LUA_MULTRET);
20619  int poststacksize = lua_gettop(lua_state());
20620  int returncount = poststacksize - (firstreturn - 1);
20621  return unsafe_function_result(lua_state(), firstreturn, returncount);
20622  }
20623 
20624  public:
20625  using base_t::lua_state;
20626 
20627  basic_function() = default;
20628  template <typename T,
20629  meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_function>>, meta::neg<std::is_same<base_t, stack_reference>>,
20630  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
20631  basic_function(T&& r) noexcept : base_t(std::forward<T>(r)) {
20632 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20633  if (!is_function<meta::unqualified_t<T>>::value) {
20634  auto pp = stack::push_pop(*this);
20635  constructor_handler handler {};
20636  stack::check<basic_function>(lua_state(), -1, handler);
20637  }
20638 #endif // Safety
20639  }
20640  basic_function(const basic_function&) = default;
20641  basic_function& operator=(const basic_function&) = default;
20642  basic_function(basic_function&&) = default;
20643  basic_function& operator=(basic_function&&) = default;
20644  basic_function(const stack_reference& r) : basic_function(r.lua_state(), r.stack_index()) {
20645  }
20646  basic_function(stack_reference&& r) : basic_function(r.lua_state(), r.stack_index()) {
20647  }
20648  basic_function(lua_nil_t n) : base_t(n) {
20649  }
20650  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
20651  basic_function(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
20652 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20653  auto pp = stack::push_pop(*this);
20654  constructor_handler handler {};
20655  stack::check<basic_function>(lua_state(), -1, handler);
20656 #endif // Safety
20657  }
20658  basic_function(lua_State* L, int index = -1) : base_t(L, index) {
20659 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20660  constructor_handler handler {};
20661  stack::check<basic_function>(L, index, handler);
20662 #endif // Safety
20663  }
20664  basic_function(lua_State* L, ref_index index) : base_t(L, index) {
20665 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20666  auto pp = stack::push_pop(*this);
20667  constructor_handler handler {};
20668  stack::check<basic_function>(lua_state(), -1, handler);
20669 #endif // Safety
20670  }
20671 
20672  template <typename Fx>
20673  int dump(lua_Writer writer, void* userdata, bool strip, Fx&& on_error) const {
20674  this->push();
20675  auto ppn = stack::push_popper_n<false>(this->lua_state(), 1);
20676  int r = lua_dump(this->lua_state(), writer, userdata, strip ? 1 : 0);
20677  if (r != 0) {
20678  return on_error(this->lua_state(), r, writer, userdata, strip);
20679  }
20680  return r;
20681  }
20682 
20683  int dump(lua_Writer writer, void* userdata, bool strip = false) const {
20684  return dump(writer, userdata, strip, &dump_throw_on_error);
20685  }
20686 
20687  template <typename Container = bytecode>
20688  Container dump() const {
20689  Container bc;
20690  (void)dump(static_cast<lua_Writer>(&basic_insert_dump_writer<Container>), static_cast<void*>(&bc), false, &dump_panic_on_error);
20691  return bc;
20692  }
20693 
20694  template <typename Container = bytecode, typename Fx>
20695  Container dump(Fx&& on_error) const {
20696  Container bc;
20697  (void)dump(static_cast<lua_Writer>(&basic_insert_dump_writer<Container>), static_cast<void*>(&bc), false, std::forward<Fx>(on_error));
20698  return bc;
20699  }
20700 
20701  template <typename... Args>
20702  unsafe_function_result operator()(Args&&... args) const {
20703  return call<>(std::forward<Args>(args)...);
20704  }
20705 
20706  template <typename... Ret, typename... Args>
20707  decltype(auto) operator()(types<Ret...>, Args&&... args) const {
20708  return call<Ret...>(std::forward<Args>(args)...);
20709  }
20710 
20711  template <typename... Ret, typename... Args>
20712  decltype(auto) call(Args&&... args) const {
20713  if (!aligned) {
20714  base_t::push();
20715  }
20716  int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
20717  return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), static_cast<std::ptrdiff_t>(pushcount));
20718  }
20719  };
20720 } // namespace sol
20721 
20722 // end of sol/unsafe_function.hpp
20723 
20724 // beginning of sol/protected_function.hpp
20725 
20726 // beginning of sol/protected_handler.hpp
20727 
20728 #include <cstdint>
20729 
20730 namespace sol { namespace detail {
20731  inline const char (&default_handler_name())[9] {
20732  static const char name[9] = "sol.\xF0\x9F\x94\xA9";
20733  return name;
20734  }
20735 
20736  template <bool ShouldPush, typename Target = reference>
20738  lua_State* m_L;
20739  const Target& target;
20740  int stack_index;
20741 
20742  protected_handler(std::false_type, lua_State* L_, const Target& target_) : m_L(L_), target(target_), stack_index(0) {
20743  if (ShouldPush) {
20744  stack_index = lua_gettop(L_) + 1;
20745  target.push(L_);
20746  }
20747  }
20748 
20749  protected_handler(std::true_type, lua_State* L_, const Target& target_) : m_L(L_), target(target_), stack_index(0) {
20750  if (ShouldPush) {
20751  stack_index = target.stack_index();
20752  }
20753  }
20754 
20755  protected_handler(lua_State* L_, const Target& target_) : protected_handler(meta::boolean<is_stack_based_v<Target>>(), L_, target_) {
20756  }
20757 
20758  bool valid() const noexcept {
20759  return ShouldPush;
20760  }
20761 
20762  ~protected_handler() {
20763  if constexpr (!is_stack_based_v<Target>) {
20764  if (stack_index != 0) {
20765  lua_remove(m_L, stack_index);
20766  }
20767  }
20768  }
20769  };
20770 
20771  template <typename Base, typename T>
20772  inline basic_function<Base> force_cast(T& p) {
20773  return p;
20774  }
20775 
20776  template <typename Reference, bool IsMainReference = false>
20777  inline Reference get_default_handler(lua_State* L_) {
20778  if (is_stack_based_v<Reference> || L_ == nullptr)
20779  return Reference(L_, lua_nil);
20780  L_ = IsMainReference ? main_thread(L_, L_) : L_;
20781  lua_getglobal(L_, default_handler_name());
20782  auto pp = stack::pop_n(L_, 1);
20783  return Reference(L_, -1);
20784  }
20785 
20786  template <typename T>
20787  inline void set_default_handler(lua_State* L, const T& ref) {
20788  if (L == nullptr) {
20789  return;
20790  }
20791  if (!ref.valid()) {
20792 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
20793  luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
20794 #endif // make sure stack doesn't overflow
20795  lua_pushnil(L);
20796  lua_setglobal(L, default_handler_name());
20797  }
20798  else {
20799  ref.push(L);
20800  lua_setglobal(L, default_handler_name());
20801  }
20802  }
20803 }} // namespace sol::detail
20804 
20805 // end of sol/protected_handler.hpp
20806 
20807 #include <cstdint>
20808 #include <algorithm>
20809 
20810 namespace sol {
20811 
20812  namespace detail {
20813  template <bool ShouldPush_, typename Handler_>
20814  inline void handle_protected_exception(
20816  handler_.stack_index = 0;
20817  if (ShouldPush_) {
20818  handler_.target.push(L_);
20819  detail::call_exception_handler(L_, maybe_ex, error);
20820  lua_call(L_, 1, 1);
20821  }
20822  else {
20823  detail::call_exception_handler(L_, maybe_ex, error);
20824  }
20825  }
20826  } // namespace detail
20827 
20828  template <typename Reference, bool Aligned = false, typename Handler = reference>
20829  class basic_protected_function : public basic_object<Reference> {
20830  private:
20831  using base_t = basic_object<Reference>;
20832  using handler_t = Handler;
20833  inline static constexpr bool is_stack_handler_v = is_stack_based_v<handler_t>;
20834 
20835  basic_protected_function(std::true_type, const basic_protected_function& other_) noexcept
20836  : base_t(other_), m_error_handler(other_.m_error_handler.copy(lua_state())) {
20837  }
20838 
20839  basic_protected_function(std::false_type, const basic_protected_function& other_) noexcept : base_t(other_), m_error_handler(other_.m_error_handler) {
20840  }
20841 
20842  public:
20843  basic_protected_function() = default;
20844  template <typename T,
20845  meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_protected_function>>,
20846  meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>,
20847  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
20848  basic_protected_function(T&& r) noexcept : base_t(std::forward<T>(r)), m_error_handler(get_default_handler(r.lua_state())) {
20849 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20850  if (!is_function<meta::unqualified_t<T>>::value) {
20851  auto pp = stack::push_pop(*this);
20852  constructor_handler handler {};
20853  stack::check<basic_protected_function>(lua_state(), -1, handler);
20854  }
20855 #endif // Safety
20856  }
20857  basic_protected_function(const basic_protected_function& other_) noexcept
20858  : basic_protected_function(meta::boolean<is_stateless_lua_reference_v<Handler>>(), other_) {
20859  }
20860  basic_protected_function& operator=(const basic_protected_function& other_) {
20861  base_t::operator=(other_);
20862  if constexpr (is_stateless_lua_reference_v<Handler>) {
20863  m_error_handler.copy_assign(lua_state(), other_.m_error_handler);
20864  }
20865  else {
20866  m_error_handler = other_.m_error_handler;
20867  }
20868  return *this;
20869  }
20870  basic_protected_function(basic_protected_function&&) = default;
20871  basic_protected_function& operator=(basic_protected_function&&) = default;
20872  basic_protected_function(const basic_function<base_t>& b) : basic_protected_function(b, get_default_handler(b.lua_state())) {
20873  }
20874  basic_protected_function(basic_function<base_t>&& b) : basic_protected_function(std::move(b), get_default_handler(b.lua_state())) {
20875  }
20876  basic_protected_function(const basic_function<base_t>& b, handler_t eh) : base_t(b), m_error_handler(std::move(eh)) {
20877  }
20878  basic_protected_function(basic_function<base_t>&& b, handler_t eh) : base_t(std::move(b)), m_error_handler(std::move(eh)) {
20879  }
20880  basic_protected_function(const stack_reference& r) : basic_protected_function(r.lua_state(), r.stack_index(), get_default_handler(r.lua_state())) {
20881  }
20882  basic_protected_function(stack_reference&& r) : basic_protected_function(r.lua_state(), r.stack_index(), get_default_handler(r.lua_state())) {
20883  }
20884  basic_protected_function(const stack_reference& r, handler_t eh) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {
20885  }
20886  basic_protected_function(stack_reference&& r, handler_t eh) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {
20887  }
20888 
20889  template <typename Super>
20890  basic_protected_function(const proxy_base<Super>& p) : basic_protected_function(p, get_default_handler(p.lua_state())) {
20891  }
20892  template <typename Super>
20893  basic_protected_function(proxy_base<Super>&& p) : basic_protected_function(std::move(p), get_default_handler(p.lua_state())) {
20894  }
20895  template <typename Proxy, typename HandlerReference,
20896  meta::enable<std::is_base_of<proxy_base_tag, meta::unqualified_t<Proxy>>,
20897  meta::neg<is_lua_index<meta::unqualified_t<HandlerReference>>>> = meta::enabler>
20898  basic_protected_function(Proxy&& p, HandlerReference&& eh)
20899  : basic_protected_function(detail::force_cast<base_t>(p), make_reference<handler_t>(p.lua_state(), std::forward<HandlerReference>(eh))) {
20900  }
20901 
20902  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
20903  basic_protected_function(lua_State* L_, T&& r) : basic_protected_function(L_, std::forward<T>(r), get_default_handler(L_)) {
20904  }
20905  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
20906  basic_protected_function(lua_State* L_, T&& r, handler_t eh) : base_t(L_, std::forward<T>(r)), m_error_handler(std::move(eh)) {
20907 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20908  auto pp = stack::push_pop(*this);
20909  constructor_handler handler {};
20910  stack::check<basic_protected_function>(lua_state(), -1, handler);
20911 #endif // Safety
20912  }
20913 
20914  basic_protected_function(lua_nil_t n) : base_t(n), m_error_handler(n) {
20915  }
20916 
20917  basic_protected_function(lua_State* L_, int index_ = -1) : basic_protected_function(L_, index_, get_default_handler(L_)) {
20918  }
20919  basic_protected_function(lua_State* L_, int index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
20920 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20921  constructor_handler handler {};
20922  stack::check<basic_protected_function>(L_, index_, handler);
20923 #endif // Safety
20924  }
20925  basic_protected_function(lua_State* L_, absolute_index index_) : basic_protected_function(L_, index_, get_default_handler(L_)) {
20926  }
20927  basic_protected_function(lua_State* L_, absolute_index index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
20928 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20929  constructor_handler handler {};
20930  stack::check<basic_protected_function>(L_, index_, handler);
20931 #endif // Safety
20932  }
20933  basic_protected_function(lua_State* L_, raw_index index_) : basic_protected_function(L_, index_, get_default_handler(L_)) {
20934  }
20935  basic_protected_function(lua_State* L_, raw_index index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
20936 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20937  constructor_handler handler {};
20938  stack::check<basic_protected_function>(L_, index_, handler);
20939 #endif // Safety
20940  }
20941  basic_protected_function(lua_State* L_, ref_index index_) : basic_protected_function(L_, index_, get_default_handler(L_)) {
20942  }
20943  basic_protected_function(lua_State* L_, ref_index index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
20944 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20945  auto pp = stack::push_pop(*this);
20946  constructor_handler handler {};
20947  stack::check<basic_protected_function>(lua_state(), -1, handler);
20948 #endif // Safety
20949  }
20950 
20951  using base_t::lua_state;
20952 
20953  template <typename Fx>
20954  int dump(lua_Writer writer, void* userdata_pointer_, bool strip, Fx&& on_error) const {
20955  this->push();
20956  auto ppn = stack::push_popper_n<false>(this->lua_state(), 1);
20957  int r = lua_dump(this->lua_state(), writer, userdata_pointer_, strip ? 1 : 0);
20958  if (r != 0) {
20959  return on_error(this->lua_state(), r, writer, userdata_pointer_, strip);
20960  }
20961  return r;
20962  }
20963 
20964  int dump(lua_Writer writer, void* userdata_pointer_, bool strip = false) const {
20965  return dump(writer, userdata_pointer_, strip, &dump_pass_on_error);
20966  }
20967 
20968  template <typename Container = bytecode>
20969  Container dump() const {
20970  Container bc;
20971  (void)dump(static_cast<lua_Writer>(&basic_insert_dump_writer<Container>), static_cast<void*>(&bc), false, &dump_throw_on_error);
20972  return bc;
20973  }
20974 
20975  template <typename Container = bytecode, typename Fx>
20976  Container dump(Fx&& on_error) const {
20977  Container bc;
20978  (void)dump(static_cast<lua_Writer>(&basic_insert_dump_writer<Container>), static_cast<void*>(&bc), false, std::forward<Fx>(on_error));
20979  return bc;
20980  }
20981 
20982  template <typename... Args>
20983  protected_function_result operator()(Args&&... args) const {
20984  return call<>(std::forward<Args>(args)...);
20985  }
20986 
20987  template <typename... Ret, typename... Args>
20988  decltype(auto) operator()(types<Ret...>, Args&&... args) const {
20989  return call<Ret...>(std::forward<Args>(args)...);
20990  }
20991 
20992  template <typename... Ret, typename... Args>
20993  decltype(auto) call(Args&&... args) const {
20994  if constexpr (!Aligned) {
20995  // we do not expect the function to already be on the stack: push it
20996  if (m_error_handler.valid(lua_state())) {
20997  detail::protected_handler<true, handler_t> h(lua_state(), m_error_handler);
20998  base_t::push();
20999  int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
21000  return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
21001  }
21002  else {
21003  detail::protected_handler<false, handler_t> h(lua_state(), m_error_handler);
21004  base_t::push();
21005  int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
21006  return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
21007  }
21008  }
21009  else {
21010  // the function is already on the stack at the right location
21011  if (m_error_handler.valid()) {
21012  // the handler will be pushed onto the stack manually,
21013  // since it's not already on the stack this means we need to push our own
21014  // function on the stack too and swap things to be in-place
21015  if constexpr (!is_stack_handler_v) {
21016  // so, we need to remove the function at the top and then dump the handler out ourselves
21017  base_t::push();
21018  }
21019  detail::protected_handler<true, handler_t> h(lua_state(), m_error_handler);
21020  if constexpr (!is_stack_handler_v) {
21021  lua_replace(lua_state(), -3);
21022  h.stack_index = lua_absindex(lua_state(), -2);
21023  }
21024  int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
21025  return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
21026  }
21027  else {
21028  detail::protected_handler<false, handler_t> h(lua_state(), m_error_handler);
21029  int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
21030  return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
21031  }
21032  }
21033  }
21034 
21035  ~basic_protected_function() {
21036  if constexpr (is_stateless_lua_reference_v<handler_t>) {
21037  this->m_error_handler.reset(lua_state());
21038  }
21039  }
21040 
21041  static handler_t get_default_handler(lua_State* L_) {
21042  return detail::get_default_handler<handler_t, is_main_threaded_v<base_t>>(L_);
21043  }
21044 
21045  template <typename T>
21046  static void set_default_handler(const T& ref) {
21047  detail::set_default_handler(ref.lua_state(), ref);
21048  }
21049 
21050  auto get_error_handler() const noexcept {
21051  if constexpr (is_stateless_lua_reference_v<handler_t>) {
21052  if constexpr (is_stack_based_v<handler_t>) {
21053  return stack_reference(lua_state(), m_error_handler.stack_index());
21054  }
21055  else {
21056  return basic_reference<is_main_threaded_v<base_t>>(lua_state(), ref_index(m_error_handler.registry_index()));
21057  }
21058  }
21059  else {
21060  return m_error_handler;
21061  }
21062  }
21063 
21064  template <typename ErrorHandler_>
21065  void set_error_handler(ErrorHandler_&& error_handler_) noexcept {
21066  static_assert(!is_stack_based_v<handler_t> || is_stack_based_v<ErrorHandler_>,
21067  "A stack-based error handler can only be set from a parameter that is also stack-based.");
21068  if constexpr (std::is_rvalue_reference_v<ErrorHandler_>) {
21069  m_error_handler = std::forward<ErrorHandler_>(error_handler_);
21070  }
21071  else {
21072  m_error_handler.copy_assign(lua_state(), std::forward<ErrorHandler_>(error_handler_));
21073  }
21074  }
21075 
21076  void abandon () noexcept {
21077  this->m_error_handler.abandon();
21078  base_t::abandon();
21079  }
21080 
21081  private:
21082  handler_t m_error_handler;
21083 
21084  template <bool b>
21085  call_status luacall(std::ptrdiff_t argcount, std::ptrdiff_t result_count_, detail::protected_handler<b, handler_t>& h) const {
21086  return static_cast<call_status>(lua_pcall(lua_state(), static_cast<int>(argcount), static_cast<int>(result_count_), h.stack_index));
21087  }
21088 
21089  template <std::size_t... I, bool b, typename... Ret>
21090  auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
21091  luacall(n, sizeof...(Ret), h);
21092  return stack::pop<std::tuple<Ret...>>(lua_state());
21093  }
21094 
21095  template <std::size_t I, bool b, typename Ret>
21096  Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
21097  luacall(n, 1, h);
21098  return stack::pop<Ret>(lua_state());
21099  }
21100 
21101  template <std::size_t I, bool b>
21102  void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
21103  luacall(n, 0, h);
21104  }
21105 
21106  template <bool b>
21107  protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
21108  int stacksize = lua_gettop(lua_state());
21109  int poststacksize = stacksize;
21110  int firstreturn = 1;
21111  int returncount = 0;
21112  call_status code = call_status::ok;
21113 #if SOL_IS_ON(SOL_EXCEPTIONS) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS)
21114  try {
21115 #endif // No Exceptions
21116  firstreturn = (std::max)(1, static_cast<int>(stacksize - n - static_cast<int>(h.valid() && !is_stack_handler_v)));
21117  code = luacall(n, LUA_MULTRET, h);
21118  poststacksize = lua_gettop(lua_state()) - static_cast<int>(h.valid() && !is_stack_handler_v);
21119  returncount = poststacksize - (firstreturn - 1);
21120 #if SOL_IS_ON(SOL_EXCEPTIONS) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS)
21121  }
21122  // Handle C++ errors thrown from C++ functions bound inside of lua
21123  catch (const char* error) {
21124  detail::handle_protected_exception(lua_state(), optional<const std::exception&>(nullopt), error, h);
21125  firstreturn = lua_gettop(lua_state());
21126  return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
21127  }
21128  catch (const std::string& error) {
21129  detail::handle_protected_exception(lua_state(), optional<const std::exception&>(nullopt), error.c_str(), h);
21130  firstreturn = lua_gettop(lua_state());
21131  return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
21132  }
21133  catch (const std::exception& error) {
21134  detail::handle_protected_exception(lua_state(), optional<const std::exception&>(error), error.what(), h);
21135  firstreturn = lua_gettop(lua_state());
21136  return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
21137  }
21138 #if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL)
21139  // LuaJIT cannot have the catchall when the safe propagation is on
21140  // but LuaJIT will swallow all C++ errors
21141  // if we don't at least catch std::exception ones
21142  catch (...) {
21143  detail::handle_protected_exception(lua_state(), optional<const std::exception&>(nullopt), detail::protected_function_error, h);
21144  firstreturn = lua_gettop(lua_state());
21145  return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
21146  }
21147 #endif // Always catch edge case
21148 #else
21149  // do not handle exceptions: they can be propogated into C++ and keep all type information / rich information
21150 #endif // Exceptions vs. No Exceptions
21151  return protected_function_result(lua_state(), firstreturn, returncount, returncount, code);
21152  }
21153  };
21154 } // namespace sol
21155 
21156 // end of sol/protected_function.hpp
21157 
21158 #include <functional>
21159 
21160 namespace sol {
21161  template <typename... Ret, typename... Args>
21162  decltype(auto) stack_proxy::call(Args&&... args) {
21163  stack_function sf(this->lua_state(), this->stack_index());
21164  return sf.template call<Ret...>(std::forward<Args>(args)...);
21165  }
21166 
21167  inline protected_function_result::protected_function_result(unsafe_function_result&& o) noexcept
21168  : L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()), popcount(o.return_count()), err(o.status()) {
21169  // Must be manual, otherwise destructor will screw us
21170  // return count being 0 is enough to keep things clean
21171  // but we will be thorough
21172  o.abandon();
21173  }
21174 
21175  inline protected_function_result& protected_function_result::operator=(unsafe_function_result&& o) noexcept {
21176  L = o.lua_state();
21177  index = o.stack_index();
21178  returncount = o.return_count();
21179  popcount = o.return_count();
21180  err = o.status();
21181  // Must be manual, otherwise destructor will screw us
21182  // return count being 0 is enough to keep things clean
21183  // but we will be thorough
21184  o.abandon();
21185  return *this;
21186  }
21187 
21188  inline unsafe_function_result::unsafe_function_result(protected_function_result&& o) noexcept
21189  : L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()) {
21190  // Must be manual, otherwise destructor will screw us
21191  // return count being 0 is enough to keep things clean
21192  // but we will be thorough
21193  o.abandon();
21194  }
21195  inline unsafe_function_result& unsafe_function_result::operator=(protected_function_result&& o) noexcept {
21196  L = o.lua_state();
21197  index = o.stack_index();
21198  returncount = o.return_count();
21199  // Must be manual, otherwise destructor will screw us
21200  // return count being 0 is enough to keep things clean
21201  // but we will be thorough
21202  o.abandon();
21203  return *this;
21204  }
21205 
21206  namespace detail {
21207  template <typename... R>
21208  struct std_shim {
21209  unsafe_function lua_func_;
21210 
21211  std_shim(unsafe_function lua_func) : lua_func_(std::move(lua_func)) {
21212  }
21213 
21214  template <typename... Args>
21215  meta::return_type_t<R...> operator()(Args&&... args) {
21216  return lua_func_.call<R...>(std::forward<Args>(args)...);
21217  }
21218  };
21219 
21220  template <>
21221  struct std_shim<void> {
21222  unsafe_function lua_func_;
21223 
21224  std_shim(unsafe_function lua_func) : lua_func_(std::move(lua_func)) {
21225  }
21226 
21227  template <typename... Args>
21228  void operator()(Args&&... args) {
21229  lua_func_.call<void>(std::forward<Args>(args)...);
21230  }
21231  };
21232  } // namespace detail
21233 
21234  namespace stack {
21235  template <typename Signature>
21236  struct unqualified_getter<std::function<Signature>> {
21238  typedef typename fx_t::args_list args_lists;
21239  typedef meta::tuple_types<typename fx_t::return_type> return_types;
21240 
21241  template <typename... R>
21242  static std::function<Signature> get_std_func(types<R...>, lua_State* L, int index) {
21243  detail::std_shim<R...> fx(unsafe_function(L, index));
21244  return fx;
21245  }
21246 
21247  static std::function<Signature> get(lua_State* L, int index, record& tracking) {
21248  tracking.use(1);
21249  type t = type_of(L, index);
21250  if (t == type::none || t == type::lua_nil) {
21251  return nullptr;
21252  }
21253  return get_std_func(return_types(), L, index);
21254  }
21255  };
21256 
21257  template <typename Allocator>
21258  struct unqualified_getter<basic_bytecode<Allocator>> {
21259  static basic_bytecode<Allocator> get(lua_State* L, int index, record& tracking) {
21260  tracking.use(1);
21261  stack_function sf(L, index);
21262  return sf.dump(&dump_panic_on_error);
21263  }
21264  };
21265  } // namespace stack
21266 
21267 } // namespace sol
21268 
21269 // end of sol/function.hpp
21270 
21271 // beginning of sol/usertype.hpp
21272 
21273 // beginning of sol/usertype_core.hpp
21274 
21275 // beginning of sol/deprecate.hpp
21276 
21277 #ifndef SOL_DEPRECATED
21278 #ifdef _MSC_VER
21279 #define SOL_DEPRECATED __declspec(deprecated)
21280 #elif __GNUC__
21281 #define SOL_DEPRECATED __attribute__((deprecated))
21282 #else
21283 #define SOL_DEPRECATED [[deprecated]]
21284 #endif // compilers
21285 #endif // SOL_DEPRECATED
21286 
21287 namespace sol { namespace detail {
21288  template <typename T>
21289  struct SOL_DEPRECATED deprecate_type {
21290  using type = T;
21291  };
21292 }} // namespace sol::detail
21293 
21294 // end of sol/deprecate.hpp
21295 
21296 // beginning of sol/usertype_container_launch.hpp
21297 
21298 // beginning of sol/usertype_container.hpp
21299 
21300 namespace sol {
21301 
21302  template <typename T>
21304 
21305  namespace container_detail {
21306 
21307  template <typename T>
21309  private:
21310  template <typename C>
21311  static meta::sfinae_yes_t test(decltype(&C::clear));
21312  template <typename C>
21313  static meta::sfinae_no_t test(...);
21314 
21315  public:
21316  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21317  };
21318 
21319  template <typename T>
21321  private:
21322  template <typename C>
21323  static meta::sfinae_yes_t test(decltype(&C::empty));
21324  template <typename C>
21325  static meta::sfinae_no_t test(...);
21326 
21327  public:
21328  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21329  };
21330 
21331  template <typename T>
21333  private:
21334  template <typename C>
21335  static meta::sfinae_yes_t test(
21336  decltype(std::declval<C>().erase_after(std::declval<std::add_rvalue_reference_t<typename C::const_iterator>>()))*);
21337  template <typename C>
21338  static meta::sfinae_no_t test(...);
21339 
21340  public:
21341  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21342  };
21343 
21344  template <typename T, typename = void>
21345  struct has_find_test {
21346  private:
21347  template <typename C>
21348  static meta::sfinae_yes_t test(decltype(std::declval<C>().find(std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
21349  template <typename C>
21350  static meta::sfinae_no_t test(...);
21351 
21352  public:
21353  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21354  };
21355 
21356  template <typename T>
21357  struct has_find_test<T, std::enable_if_t<meta::is_lookup<T>::value>> {
21358  private:
21359  template <typename C>
21360  static meta::sfinae_yes_t test(decltype(std::declval<C>().find(std::declval<std::add_rvalue_reference_t<typename C::key_type>>()))*);
21361  template <typename C>
21362  static meta::sfinae_no_t test(...);
21363 
21364  public:
21365  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21366  };
21367 
21368  template <typename T>
21370  private:
21371  template <typename C>
21372  static meta::sfinae_yes_t test(decltype(std::declval<C>().erase(std::declval<typename C::iterator>()))*);
21373  template <typename C>
21374  static meta::sfinae_no_t test(...);
21375 
21376  public:
21377  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21378  };
21379 
21380  template <typename T>
21382  private:
21383  template <typename C>
21384  static meta::sfinae_yes_t test(decltype(std::declval<C>().erase(std::declval<typename C::key_type>()))*);
21385  template <typename C>
21386  static meta::sfinae_no_t test(...);
21387 
21388  public:
21389  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21390  };
21391 
21392  template <typename T>
21394  private:
21395  template <typename C>
21396  static meta::sfinae_yes_t test(decltype(&C::find));
21397  template <typename C>
21398  static meta::sfinae_no_t test(...);
21399 
21400  public:
21401  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21402  };
21403 
21404  template <typename T>
21406  private:
21407  template <typename C>
21408  static meta::sfinae_yes_t test(decltype(&C::index_of));
21409  template <typename C>
21410  static meta::sfinae_no_t test(...);
21411 
21412  public:
21413  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21414  };
21415 
21416  template <typename T>
21418  private:
21419  template <typename C>
21420  static meta::sfinae_yes_t test(decltype(&C::insert));
21421  template <typename C>
21422  static meta::sfinae_no_t test(...);
21423 
21424  public:
21425  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21426  };
21427 
21428  template <typename T>
21430  private:
21431  template <typename C>
21432  static meta::sfinae_yes_t test(decltype(&C::erase));
21433  template <typename C>
21434  static meta::sfinae_no_t test(...);
21435 
21436  public:
21437  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21438  };
21439 
21440  template <typename T>
21442  private:
21443  template <typename C>
21444  static meta::sfinae_yes_t test(decltype(&C::index_set));
21445  template <typename C>
21446  static meta::sfinae_no_t test(...);
21447 
21448  public:
21449  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21450  };
21451 
21452  template <typename T>
21454  private:
21455  template <typename C>
21456  static meta::sfinae_yes_t test(decltype(&C::index_get));
21457  template <typename C>
21458  static meta::sfinae_no_t test(...);
21459 
21460  public:
21461  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21462  };
21463 
21464  template <typename T>
21466  private:
21467  template <typename C>
21468  static meta::sfinae_yes_t test(decltype(&C::set));
21469  template <typename C>
21470  static meta::sfinae_no_t test(...);
21471 
21472  public:
21473  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21474  };
21475 
21476  template <typename T>
21478  private:
21479  template <typename C>
21480  static meta::sfinae_yes_t test(decltype(&C::get));
21481  template <typename C>
21482  static meta::sfinae_no_t test(...);
21483 
21484  public:
21485  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21486  };
21487 
21488  template <typename T>
21490  private:
21491  template <typename C>
21492  static meta::sfinae_yes_t test(decltype(&C::at));
21493  template <typename C>
21494  static meta::sfinae_no_t test(...);
21495 
21496  public:
21497  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21498  };
21499 
21500  template <typename T>
21502  private:
21503  template <typename C>
21504  static meta::sfinae_yes_t test(decltype(&C::pairs));
21505  template <typename C>
21506  static meta::sfinae_no_t test(...);
21507 
21508  public:
21509  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21510  };
21511 
21512  template <typename T>
21514  private:
21515  template <typename C>
21516  static meta::sfinae_yes_t test(decltype(&C::ipairs));
21517  template <typename C>
21518  static meta::sfinae_no_t test(...);
21519 
21520  public:
21521  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21522  };
21523 
21524  template <typename T>
21526  private:
21527  template <typename C>
21528  static meta::sfinae_yes_t test(decltype(&C::next));
21529  template <typename C>
21530  static meta::sfinae_no_t test(...);
21531 
21532  public:
21533  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21534  };
21535 
21536  template <typename T>
21538  private:
21539  template <typename C>
21540  static meta::sfinae_yes_t test(decltype(&C::add));
21541  template <typename C>
21542  static meta::sfinae_no_t test(...);
21543 
21544  public:
21545  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21546  };
21547 
21548  template <typename T>
21550  private:
21551  template <typename C>
21552  static meta::sfinae_yes_t test(decltype(&C::size));
21553  template <typename C>
21554  static meta::sfinae_no_t test(...);
21555 
21556  public:
21557  static constexpr bool value = std::is_same_v<decltype(test<T>(0)), meta::sfinae_yes_t>;
21558  };
21559 
21560  template <typename T>
21561  using has_clear = meta::boolean<has_clear_test<T>::value>;
21562 
21563  template <typename T>
21564  using has_empty = meta::boolean<has_empty_test<T>::value>;
21565 
21566  template <typename T>
21567  using has_find = meta::boolean<has_find_test<T>::value>;
21568 
21569  template <typename T>
21570  using has_erase = meta::boolean<has_erase_test<T>::value>;
21571 
21572  template <typename T>
21573  using has_erase_key = meta::boolean<has_erase_key_test<T>::value>;
21574 
21575  template <typename T>
21576  using has_erase_after = meta::boolean<has_erase_after_test<T>::value>;
21577 
21578  template <typename T>
21579  using has_traits_get = meta::boolean<has_traits_get_test<T>::value>;
21580 
21581  template <typename T>
21582  using has_traits_at = meta::boolean<has_traits_at_test<T>::value>;
21583 
21584  template <typename T>
21585  using has_traits_set = meta::boolean<has_traits_set_test<T>::value>;
21586 
21587  template <typename T>
21588  using has_traits_index_get = meta::boolean<has_traits_index_get_test<T>::value>;
21589 
21590  template <typename T>
21591  using has_traits_index_set = meta::boolean<has_traits_index_set_test<T>::value>;
21592 
21593  template <typename T>
21594  using has_traits_pairs = meta::boolean<has_traits_pairs_test<T>::value>;
21595 
21596  template <typename T>
21597  using has_traits_ipairs = meta::boolean<has_traits_ipairs_test<T>::value>;
21598 
21599  template <typename T>
21600  using has_traits_next = meta::boolean<has_traits_next_test<T>::value>;
21601 
21602  template <typename T>
21603  using has_traits_add = meta::boolean<has_traits_add_test<T>::value>;
21604 
21605  template <typename T>
21606  using has_traits_size = meta::boolean<has_traits_size_test<T>::value>;
21607 
21608  template <typename T>
21609  using has_traits_clear = has_clear<T>;
21610 
21611  template <typename T>
21612  using has_traits_empty = has_empty<T>;
21613 
21614  template <typename T>
21615  using has_traits_find = meta::boolean<has_traits_find_test<T>::value>;
21616 
21617  template <typename T>
21618  using has_traits_index_of = meta::boolean<has_traits_index_of_test<T>::value>;
21619 
21620  template <typename T>
21621  using has_traits_insert = meta::boolean<has_traits_insert_test<T>::value>;
21622 
21623  template <typename T>
21624  using has_traits_erase = meta::boolean<has_traits_erase_test<T>::value>;
21625 
21626  template <typename T>
21628 
21629  template <typename T>
21630  struct is_forced_container<as_container_t<T>> : std::true_type { };
21631 
21632  template <typename T>
21634  typedef T type;
21635  };
21636 
21637  template <typename T>
21639  typedef T type;
21640  };
21641 
21642  template <typename T>
21643  using container_decay_t = typename container_decay<meta::unqualified_t<T>>::type;
21644 
21645  template <typename T>
21646  decltype(auto) get_key(std::false_type, T&& t) {
21647  return std::forward<T>(t);
21648  }
21649 
21650  template <typename T>
21651  decltype(auto) get_key(std::true_type, T&& t) {
21652  return t.first;
21653  }
21654 
21655  template <typename T>
21656  decltype(auto) get_value(std::false_type, T&& t) {
21657  return std::forward<T>(t);
21658  }
21659 
21660  template <typename T>
21661  decltype(auto) get_value(std::true_type, T&& t) {
21662  return t.second;
21663  }
21664 
21665  template <typename X, typename = void>
21667  private:
21668  typedef std::remove_pointer_t<meta::unwrap_unqualified_t<X>> T;
21669 
21670  public:
21671  typedef lua_nil_t iterator;
21672  typedef lua_nil_t value_type;
21673 
21674  static int at(lua_State* L_) {
21675  return luaL_error(L_, "sol: cannot call 'at(index)' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21676  }
21677 
21678  static int get(lua_State* L_) {
21679  return luaL_error(L_, "sol: cannot call 'get(key)' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21680  }
21681 
21682  static int index_get(lua_State* L_) {
21683  return luaL_error(L_, "sol: cannot call 'container[key]' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21684  }
21685 
21686  static int set(lua_State* L_) {
21687  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());
21688  }
21689 
21690  static int index_set(lua_State* L_) {
21691  return luaL_error(
21692  L_, "sol: cannot call 'container[key] = value' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21693  }
21694 
21695  static int add(lua_State* L_) {
21696  return luaL_error(L_, "sol: cannot call 'add' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21697  }
21698 
21699  static int insert(lua_State* L_) {
21700  return luaL_error(L_, "sol: cannot call 'insert' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21701  }
21702 
21703  static int find(lua_State* L_) {
21704  return luaL_error(L_, "sol: cannot call 'find' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21705  }
21706 
21707  static int index_of(lua_State* L_) {
21708  return luaL_error(L_, "sol: cannot call 'index_of' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21709  }
21710 
21711  static int size(lua_State* L_) {
21712  return luaL_error(L_, "sol: cannot call 'end' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21713  }
21714 
21715  static int clear(lua_State* L_) {
21716  return luaL_error(L_, "sol: cannot call 'clear' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21717  }
21718 
21719  static int empty(lua_State* L_) {
21720  return luaL_error(L_, "sol: cannot call 'empty' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21721  }
21722 
21723  static int erase(lua_State* L_) {
21724  return luaL_error(L_, "sol: cannot call 'erase' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21725  }
21726 
21727  static int next(lua_State* L_) {
21728  return luaL_error(L_, "sol: cannot call 'next' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21729  }
21730 
21731  static int pairs(lua_State* L_) {
21732  return luaL_error(L_, "sol: cannot call '__pairs/pairs' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21733  }
21734 
21735  static int ipairs(lua_State* L_) {
21736  return luaL_error(L_, "sol: cannot call '__ipairs' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21737  }
21738 
21739  static iterator begin(lua_State* L_, T&) {
21740  luaL_error(L_, "sol: cannot call 'being' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21741  return lua_nil;
21742  }
21743 
21744  static iterator end(lua_State* L_, T&) {
21745  luaL_error(L_, "sol: cannot call 'end' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21746  return lua_nil;
21747  }
21748  };
21749 
21750  template <typename X>
21752  std::enable_if_t<meta::all<is_forced_container<meta::unqualified_t<X>>, meta::has_value_type<meta::unqualified_t<container_decay_t<X>>>,
21753  meta::has_iterator<meta::unqualified_t<container_decay_t<X>>>>::value>> {
21754  private:
21755  using T = std::remove_pointer_t<meta::unwrap_unqualified_t<container_decay_t<X>>>;
21756 
21757  private:
21760  using is_lookup = meta::is_lookup<T>;
21763  using iterator = typename T::iterator;
21764  using value_type = typename T::value_type;
21765  typedef meta::conditional_t<is_matched_lookup::value, std::pair<value_type, value_type>,
21766  meta::conditional_t<is_associative::value || is_lookup::value, value_type, std::pair<std::ptrdiff_t, value_type>>>
21767  KV;
21768  typedef typename KV::first_type K;
21769  typedef typename KV::second_type V;
21770  typedef meta::conditional_t<is_matched_lookup::value, std::ptrdiff_t, K> next_K;
21771  typedef decltype(*std::declval<iterator&>()) iterator_return;
21772  typedef meta::conditional_t<is_associative::value || is_matched_lookup::value, std::add_lvalue_reference_t<V>,
21773  meta::conditional_t<is_lookup::value, V, iterator_return>>
21774  captured_type;
21775  typedef typename meta::iterator_tag<iterator>::type iterator_category;
21776  typedef std::is_same<iterator_category, std::input_iterator_tag> is_input_iterator;
21777  typedef meta::conditional_t<is_input_iterator::value, V, decltype(detail::deref_move_only(std::declval<captured_type>()))> push_type;
21778  typedef std::is_copy_assignable<V> is_copyable;
21779  typedef meta::neg<meta::any<std::is_const<V>, std::is_const<std::remove_reference_t<iterator_return>>, meta::neg<is_copyable>>> is_writable;
21780  typedef meta::unqualified_t<decltype(get_key(is_associative(), std::declval<std::add_lvalue_reference_t<value_type>>()))> key_type;
21781  typedef meta::all<std::is_integral<K>, meta::neg<meta::any<is_associative, is_lookup>>> is_linear_integral;
21782 
21783  struct iter {
21784  reference keep_alive;
21785  T& source;
21786  iterator it;
21787  std::size_t index;
21788 
21789  iter(lua_State* L_, int stack_index, T& source_, iterator it_) : keep_alive(sol::main_thread(L_, L_), stack_index), source(source_), it(std::move(it_)), index(0) {
21790  }
21791 
21792  ~iter() {
21793  }
21794  };
21795 
21796  static auto& get_src(lua_State* L_) {
21797 #if SOL_IS_ON(SOL_SAFE_USERTYPE)
21798  auto p = stack::unqualified_check_get<T*>(L_, 1);
21799  if (!p) {
21800  luaL_error(L_,
21801  "sol: 'self' is not of type '%s' (pass 'self' as first argument with ':' or call on proper type)",
21802  detail::demangle<T>().c_str());
21803  }
21804  if (p.value() == nullptr) {
21805  luaL_error(
21806  L_, "sol: 'self' argument is nil (pass 'self' as first argument with ':' or call on a '%s' type)", detail::demangle<T>().c_str());
21807  }
21808  return *p.value();
21809 #else
21810  return stack::unqualified_get<T>(L_, 1);
21811 #endif // Safe getting with error
21812  }
21813 
21814  static detail::error_result at_category(std::input_iterator_tag, lua_State* L_, T& self, std::ptrdiff_t pos) {
21815  pos += deferred_uc::index_adjustment(L_, self);
21816  if (pos < 0) {
21817  return stack::push(L_, lua_nil);
21818  }
21819  auto it = deferred_uc::begin(L_, self);
21820  auto e = deferred_uc::end(L_, self);
21821  if (it == e) {
21822  return stack::push(L_, lua_nil);
21823  }
21824  while (pos > 0) {
21825  --pos;
21826  ++it;
21827  if (it == e) {
21828  return stack::push(L_, lua_nil);
21829  }
21830  }
21831  return get_associative(is_associative(), L_, it);
21832  }
21833 
21834  static detail::error_result at_category(std::random_access_iterator_tag, lua_State* L_, T& self, std::ptrdiff_t pos) {
21835  std::ptrdiff_t len = static_cast<std::ptrdiff_t>(size_start(L_, self));
21836  pos += deferred_uc::index_adjustment(L_, self);
21837  if (pos < 0 || pos >= len) {
21838  return stack::push(L_, lua_nil);
21839  }
21840  auto it = std::next(deferred_uc::begin(L_, self), pos);
21841  return get_associative(is_associative(), L_, it);
21842  }
21843 
21844  static detail::error_result at_start(lua_State* L_, T& self, std::ptrdiff_t pos) {
21845  return at_category(iterator_category(), L_, self, pos);
21846  }
21847 
21848  template <typename Iter>
21849  static detail::error_result get_associative(std::true_type, lua_State* L_, Iter& it) {
21850  decltype(auto) v = *it;
21851  return stack::stack_detail::push_reference<push_type>(L_, detail::deref_move_only(v.second));
21852  }
21853 
21854  template <typename Iter>
21855  static detail::error_result get_associative(std::false_type, lua_State* L_, Iter& it) {
21856  return stack::stack_detail::push_reference<push_type>(L_, detail::deref_move_only(*it));
21857  }
21858 
21859  static detail::error_result get_category(std::input_iterator_tag, lua_State* L_, T& self, K& key) {
21860  key = static_cast<K>(key + deferred_uc::index_adjustment(L_, self));
21861  if (key < 0) {
21862  return stack::push(L_, lua_nil);
21863  }
21864  auto it = deferred_uc::begin(L_, self);
21865  auto e = deferred_uc::end(L_, self);
21866  if (it == e) {
21867  return stack::push(L_, lua_nil);
21868  }
21869  while (key > 0) {
21870  --key;
21871  ++it;
21872  if (it == e) {
21873  return stack::push(L_, lua_nil);
21874  }
21875  }
21876  return get_associative(is_associative(), L_, it);
21877  }
21878 
21879  static detail::error_result get_category(std::random_access_iterator_tag, lua_State* L_, T& self, K& key) {
21880  std::ptrdiff_t len = static_cast<std::ptrdiff_t>(size_start(L_, self));
21881  key = static_cast<K>(static_cast<std::ptrdiff_t>(key) + deferred_uc::index_adjustment(L_, self));
21882  if (key < 0 || key >= len) {
21883  return stack::push(L_, lua_nil);
21884  }
21885  auto it = std::next(deferred_uc::begin(L_, self), key);
21886  return get_associative(is_associative(), L_, it);
21887  }
21888 
21889  static detail::error_result get_it(std::true_type, lua_State* L_, T& self, K& key) {
21890  return get_category(iterator_category(), L_, self, key);
21891  }
21892 
21893  static detail::error_result get_comparative(std::true_type, lua_State* L_, T& self, K& key) {
21894  auto fx = [&](const value_type& r) -> bool { return key == get_key(is_associative(), r); };
21895  auto e = deferred_uc::end(L_, self);
21896  auto it = std::find_if(deferred_uc::begin(L_, self), e, std::ref(fx));
21897  if (it == e) {
21898  return stack::push(L_, lua_nil);
21899  }
21900  return get_associative(is_associative(), L_, it);
21901  }
21902 
21903  static detail::error_result get_comparative(std::false_type, lua_State*, T&, K&) {
21904  return detail::error_result("cannot get this key on '%s': no suitable way to increment iterator and compare to key value '%s'",
21905  detail::demangle<T>().data(),
21906  detail::demangle<K>().data());
21907  }
21908 
21909  static detail::error_result get_it(std::false_type, lua_State* L_, T& self, K& key) {
21910  return get_comparative(meta::supports_op_equal<K, key_type>(), L_, self, key);
21911  }
21912 
21913  static detail::error_result set_associative(std::true_type, iterator& it, stack_object value) {
21914  decltype(auto) v = *it;
21915  v.second = value.as<V>();
21916  return {};
21917  }
21918 
21919  static detail::error_result set_associative(std::false_type, iterator& it, stack_object value) {
21920  decltype(auto) v = *it;
21921  v = value.as<V>();
21922  return {};
21923  }
21924 
21925  static detail::error_result set_writable(std::true_type, lua_State*, T&, iterator& it, stack_object value) {
21926  return set_associative(is_associative(), it, std::move(value));
21927  }
21928 
21929  static detail::error_result set_writable(std::false_type, lua_State*, T&, iterator&, stack_object) {
21930  return detail::error_result(
21931  "cannot perform a 'set': '%s's iterator reference is not writable (non-copy-assignable or const)", detail::demangle<T>().data());
21932  }
21933 
21934  static detail::error_result set_category(std::input_iterator_tag, lua_State* L_, T& self, stack_object okey, stack_object value) {
21935  decltype(auto) key = okey.as<K>();
21936  key = static_cast<K>(static_cast<std::ptrdiff_t>(key) + deferred_uc::index_adjustment(L_, self));
21937  auto e = deferred_uc::end(L_, self);
21938  auto it = deferred_uc::begin(L_, self);
21939  auto backit = it;
21940  for (; key > 0 && it != e; --key, ++it) {
21941  backit = it;
21942  }
21943  if (it == e) {
21944  if (key == 0) {
21945  return add_copyable(is_copyable(), L_, self, std::move(value), meta::has_insert_after<T>::value ? backit : it);
21946  }
21947  return detail::error_result("out of bounds (too big) for set on '%s'", detail::demangle<T>().c_str());
21948  }
21949  return set_writable(is_writable(), L_, self, it, std::move(value));
21950  }
21951 
21952  static detail::error_result set_category(std::random_access_iterator_tag, lua_State* L_, T& self, stack_object okey, stack_object value) {
21953  decltype(auto) key = okey.as<K>();
21954  key = static_cast<K>(static_cast<std::ptrdiff_t>(key) + deferred_uc::index_adjustment(L_, self));
21955  if (key < 0) {
21956  return detail::error_result("sol: out of bounds (too small) for set on '%s'", detail::demangle<T>().c_str());
21957  }
21958  std::ptrdiff_t len = static_cast<std::ptrdiff_t>(size_start(L_, self));
21959  if (key == len) {
21960  return add_copyable(is_copyable(), L_, self, std::move(value));
21961  }
21962  else if (key >= len) {
21963  return detail::error_result("sol: out of bounds (too big) for set on '%s'", detail::demangle<T>().c_str());
21964  }
21965  auto it = std::next(deferred_uc::begin(L_, self), key);
21966  return set_writable(is_writable(), L_, self, it, std::move(value));
21967  }
21968 
21969  static detail::error_result set_comparative(std::true_type, lua_State* L_, T& self, stack_object okey, stack_object value) {
21970  decltype(auto) key = okey.as<K>();
21971  if (!is_writable::value) {
21972  return detail::error_result(
21973  "cannot perform a 'set': '%s's iterator reference is not writable (non-copy-assignable or const)", detail::demangle<T>().data());
21974  }
21975  auto fx = [&](const value_type& r) -> bool { return key == get_key(is_associative(), r); };
21976  auto e = deferred_uc::end(L_, self);
21977  auto it = std::find_if(deferred_uc::begin(L_, self), e, std::ref(fx));
21978  if (it == e) {
21979  return {};
21980  }
21981  return set_writable(is_writable(), L_, self, it, std::move(value));
21982  }
21983 
21984  static detail::error_result set_comparative(std::false_type, lua_State*, T&, stack_object, stack_object) {
21985  return detail::error_result("cannot set this value on '%s': no suitable way to increment iterator or compare to '%s' key",
21986  detail::demangle<T>().data(),
21987  detail::demangle<K>().data());
21988  }
21989 
21990  template <typename Iter>
21991  static detail::error_result set_associative_insert(std::true_type, lua_State*, T& self, Iter& it, K& key, stack_object value) {
21992  if constexpr (meta::has_insert_with_iterator<T>::value) {
21993  self.insert(it, value_type(key, value.as<V>()));
21994  return {};
21995  }
21996  else if constexpr (meta::has_insert<T>::value) {
21997  self.insert(value_type(key, value.as<V>()));
21998  return {};
21999  }
22000  else {
22001  (void)self;
22002  (void)it;
22003  (void)key;
22004  return detail::error_result(
22005  "cannot call 'set' on '%s': there is no 'insert' function on this associative type", detail::demangle<T>().c_str());
22006  }
22007  }
22008 
22009  template <typename Iter>
22010  static detail::error_result set_associative_insert(std::false_type, lua_State*, T& self, Iter& it, K& key, stack_object) {
22011  if constexpr (meta::has_insert_with_iterator<T>::value) {
22012  self.insert(it, key);
22013  return {};
22014  }
22015  else if constexpr (meta::has_insert<T>::value) {
22016  self.insert(key);
22017  return {};
22018  }
22019  else {
22020  (void)self;
22021  (void)it;
22022  (void)key;
22023  return detail::error_result(
22024  "cannot call 'set' on '%s': there is no 'insert' function on this non-associative type", detail::demangle<T>().c_str());
22025  }
22026  }
22027 
22028  static detail::error_result set_associative_find(std::true_type, lua_State* L_, T& self, stack_object okey, stack_object value) {
22029  decltype(auto) key = okey.as<K>();
22030  auto it = self.find(key);
22031  if (it == deferred_uc::end(L_, self)) {
22032  return set_associative_insert(is_associative(), L_, self, it, key, std::move(value));
22033  }
22034  return set_writable(is_writable(), L_, self, it, std::move(value));
22035  }
22036 
22037  static detail::error_result set_associative_find(std::false_type, lua_State* L_, T& self, stack_object key, stack_object value) {
22038  return set_comparative(meta::supports_op_equal<K, key_type>(), L_, self, std::move(key), std::move(value));
22039  }
22040 
22041  static detail::error_result set_it(std::true_type, lua_State* L_, T& self, stack_object key, stack_object value) {
22042  return set_category(iterator_category(), L_, self, std::move(key), std::move(value));
22043  }
22044 
22045  static detail::error_result set_it(std::false_type, lua_State* L_, T& self, stack_object key, stack_object value) {
22046  return set_associative_find(meta::all<has_find<T>, meta::any<is_associative, is_lookup>>(), L_, self, std::move(key), std::move(value));
22047  }
22048 
22049  template <bool idx_of = false>
22050  static detail::error_result find_has_associative_lookup(std::true_type, lua_State* L_, T& self) {
22051  if constexpr (!is_ordered::value && idx_of) {
22052  (void)L_;
22053  (void)self;
22054  return detail::error_result("cannot perform an 'index_of': '%s's is not an ordered container", detail::demangle<T>().data());
22055  }
22056  else {
22057  decltype(auto) key = stack::unqualified_get<K>(L_, 2);
22058  auto it = self.find(key);
22059  if (it == deferred_uc::end(L_, self)) {
22060  return stack::push(L_, lua_nil);
22061  }
22062  if constexpr (idx_of) {
22063  auto dist = std::distance(deferred_uc::begin(L_, self), it);
22064  dist -= deferred_uc::index_adjustment(L_, self);
22065  return stack::push(L_, dist);
22066  }
22067  else {
22068  return get_associative(is_associative(), L_, it);
22069  }
22070  }
22071  }
22072 
22073  template <bool idx_of = false>
22074  static detail::error_result find_has_associative_lookup(std::false_type, lua_State* L_, T& self) {
22075  if constexpr (!is_ordered::value && idx_of) {
22076  (void)L_;
22077  (void)self;
22078  return detail::error_result("cannot perform an 'index_of': '%s's is not an ordered container", detail::demangle<T>().data());
22079  }
22080  else {
22081  decltype(auto) value = stack::unqualified_get<V>(L_, 2);
22082  auto it = self.find(value);
22083  if (it == deferred_uc::end(L_, self)) {
22084  return stack::push(L_, lua_nil);
22085  }
22086  if constexpr (idx_of) {
22087  auto dist = std::distance(deferred_uc::begin(L_, self), it);
22088  dist -= deferred_uc::index_adjustment(L_, self);
22089  return stack::push(L_, dist);
22090  }
22091  else {
22092  return get_associative(is_associative(), L_, it);
22093  }
22094  }
22095  }
22096 
22097  template <bool idx_of = false>
22098  static detail::error_result find_has(std::true_type, lua_State* L_, T& self) {
22099  return find_has_associative_lookup<idx_of>(meta::any<is_lookup, is_associative>(), L_, self);
22100  }
22101 
22102  template <typename Iter>
22103  static detail::error_result find_associative_lookup(std::true_type, lua_State* L_, T&, Iter& it, std::size_t) {
22104  return get_associative(is_associative(), L_, it);
22105  }
22106 
22107  template <typename Iter>
22108  static detail::error_result find_associative_lookup(std::false_type, lua_State* L_, T& self, Iter&, std::size_t idx) {
22109  idx = static_cast<std::size_t>(static_cast<std::ptrdiff_t>(idx) - deferred_uc::index_adjustment(L_, self));
22110  return stack::push(L_, idx);
22111  }
22112 
22113  template <bool = false>
22114  static detail::error_result find_comparative(std::false_type, lua_State*, T&) {
22115  return detail::error_result("cannot call 'find' on '%s': there is no 'find' function and the value_type is not equality comparable",
22116  detail::demangle<T>().c_str());
22117  }
22118 
22119  template <bool idx_of = false>
22120  static detail::error_result find_comparative(std::true_type, lua_State* L_, T& self) {
22121  decltype(auto) value = stack::unqualified_get<V>(L_, 2);
22122  auto it = deferred_uc::begin(L_, self);
22123  auto e = deferred_uc::end(L_, self);
22124  std::size_t idx = 0;
22125  for (;; ++it, ++idx) {
22126  if (it == e) {
22127  return stack::push(L_, lua_nil);
22128  }
22129  if (value == get_value(is_associative(), *it)) {
22130  break;
22131  }
22132  }
22133  return find_associative_lookup(meta::all<meta::boolean<!idx_of>, meta::any<is_lookup, is_associative>>(), L_, self, it, idx);
22134  }
22135 
22136  template <bool idx_of = false>
22137  static detail::error_result find_has(std::false_type, lua_State* L_, T& self) {
22138  return find_comparative<idx_of>(meta::supports_op_equal<V>(), L_, self);
22139  }
22140 
22141  template <typename Iter>
22142  static detail::error_result add_insert_after(std::false_type, lua_State* L_, T& self, stack_object value, Iter&) {
22143  return add_insert_after(std::false_type(), L_, self, value);
22144  }
22145 
22146  static detail::error_result add_insert_after(std::false_type, lua_State*, T&, stack_object) {
22147  return detail::error_result("cannot call 'add' on type '%s': no suitable insert/push_back C++ functions", detail::demangle<T>().data());
22148  }
22149 
22150  template <typename Iter>
22151  static detail::error_result add_insert_after(std::true_type, lua_State*, T& self, stack_object value, Iter& pos) {
22152  self.insert_after(pos, value.as<V>());
22153  return {};
22154  }
22155 
22156  static detail::error_result add_insert_after(std::true_type, lua_State* L_, T& self, stack_object value) {
22157  auto backit = self.before_begin();
22158  {
22159  auto e = deferred_uc::end(L_, self);
22160  for (auto it = deferred_uc::begin(L_, self); it != e; ++backit, ++it) { }
22161  }
22162  return add_insert_after(std::true_type(), L_, self, value, backit);
22163  }
22164 
22165  template <typename Iter>
22166  static detail::error_result add_insert(std::true_type, lua_State*, T& self, stack_object value, Iter& pos) {
22167  self.insert(pos, value.as<V>());
22168  return {};
22169  }
22170 
22171  static detail::error_result add_insert(std::true_type, lua_State* L_, T& self, stack_object value) {
22172  auto pos = deferred_uc::end(L_, self);
22173  return add_insert(std::true_type(), L_, self, value, pos);
22174  }
22175 
22176  template <typename Iter>
22177  static detail::error_result add_insert(std::false_type, lua_State* L_, T& self, stack_object value, Iter& pos) {
22178  return add_insert_after(meta::has_insert_after<T>(), L_, self, std::move(value), pos);
22179  }
22180 
22181  static detail::error_result add_insert(std::false_type, lua_State* L_, T& self, stack_object value) {
22182  return add_insert_after(meta::has_insert_after<T>(), L_, self, std::move(value));
22183  }
22184 
22185  template <typename Iter>
22186  static detail::error_result add_push_back(std::true_type, lua_State*, T& self, stack_object value, Iter&) {
22187  self.push_back(value.as<V>());
22188  return {};
22189  }
22190 
22191  static detail::error_result add_push_back(std::true_type, lua_State*, T& self, stack_object value) {
22192  self.push_back(value.as<V>());
22193  return {};
22194  }
22195 
22196  template <typename Iter>
22197  static detail::error_result add_push_back(std::false_type, lua_State* L_, T& self, stack_object value, Iter& pos) {
22198  return add_insert(
22199  std::integral_constant < bool, meta::has_insert<T>::value || meta::has_insert_with_iterator<T>::value > (), L_, self, value, pos);
22200  }
22201 
22202  static detail::error_result add_push_back(std::false_type, lua_State* L_, T& self, stack_object value) {
22203  return add_insert(
22204  std::integral_constant < bool, meta::has_insert<T>::value || meta::has_insert_with_iterator<T>::value > (), L_, self, value);
22205  }
22206 
22207  template <typename Iter>
22208  static detail::error_result add_associative(std::true_type, lua_State* L_, T& self, stack_object key, Iter& pos) {
22209  if constexpr (meta::has_insert_with_iterator<T>::value) {
22210  self.insert(pos, value_type(key.as<K>(), stack::unqualified_get<V>(L_, 3)));
22211  return {};
22212  }
22213  else if constexpr (meta::has_insert<T>::value) {
22214  self.insert(value_type(key.as<K>(), stack::unqualified_get<V>(L_, 3)));
22215  return {};
22216  }
22217  else {
22218  (void)L_;
22219  (void)self;
22220  (void)key;
22221  (void)pos;
22222  return detail::error_result(
22223  "cannot call 'insert' on '%s': there is no 'insert' function on this associative type", detail::demangle<T>().c_str());
22224  }
22225  }
22226 
22227  static detail::error_result add_associative(std::true_type, lua_State* L_, T& self, stack_object key) {
22228  auto pos = deferred_uc::end(L_, self);
22229  return add_associative(std::true_type(), L_, self, std::move(key), pos);
22230  }
22231 
22232  template <typename Iter>
22233  static detail::error_result add_associative(std::false_type, lua_State* L_, T& self, stack_object value, Iter& pos) {
22234  return add_push_back(meta::has_push_back<T>(), L_, self, value, pos);
22235  }
22236 
22237  static detail::error_result add_associative(std::false_type, lua_State* L_, T& self, stack_object value) {
22238  return add_push_back(meta::has_push_back<T>(), L_, self, value);
22239  }
22240 
22241  template <typename Iter>
22242  static detail::error_result add_copyable(std::true_type, lua_State* L_, T& self, stack_object value, Iter& pos) {
22243  return add_associative(is_associative(), L_, self, std::move(value), pos);
22244  }
22245 
22246  static detail::error_result add_copyable(std::true_type, lua_State* L_, T& self, stack_object value) {
22247  return add_associative(is_associative(), L_, self, value);
22248  }
22249 
22250  template <typename Iter>
22251  static detail::error_result add_copyable(std::false_type, lua_State* L_, T& self, stack_object value, Iter&) {
22252  return add_copyable(std::false_type(), L_, self, std::move(value));
22253  }
22254 
22255  static detail::error_result add_copyable(std::false_type, lua_State*, T&, stack_object) {
22256  return detail::error_result("cannot call 'add' on '%s': value_type is non-copyable", detail::demangle<T>().data());
22257  }
22258 
22259  static detail::error_result insert_lookup(std::true_type, lua_State* L_, T& self, stack_object, stack_object value) {
22260  // TODO: should we warn or error about someone calling insert on an ordered / lookup container with no associativity?
22261  return add_copyable(std::true_type(), L_, self, std::move(value));
22262  }
22263 
22264  static detail::error_result insert_lookup(std::false_type, lua_State* L_, T& self, stack_object where, stack_object value) {
22265  auto it = deferred_uc::begin(L_, self);
22266  auto key = where.as<K>();
22267  key = static_cast<K>(static_cast<std::ptrdiff_t>(key) + deferred_uc::index_adjustment(L_, self));
22268  std::advance(it, key);
22269  self.insert(it, value.as<V>());
22270  return {};
22271  }
22272 
22273  static detail::error_result insert_after_has(std::true_type, lua_State* L_, T& self, stack_object where, stack_object value) {
22274  auto key = where.as<K>();
22275  auto backit = self.before_begin();
22276  {
22277  key = static_cast<K>(static_cast<std::ptrdiff_t>(key) + deferred_uc::index_adjustment(L_, self));
22278  auto e = deferred_uc::end(L_, self);
22279  for (auto it = deferred_uc::begin(L_, self); key > 0; ++backit, ++it, --key) {
22280  if (backit == e) {
22281  return detail::error_result("sol: out of bounds (too big) for set on '%s'", detail::demangle<T>().c_str());
22282  }
22283  }
22284  }
22285  self.insert_after(backit, value.as<V>());
22286  return {};
22287  }
22288 
22289  static detail::error_result insert_after_has(std::false_type, lua_State*, T&, stack_object, stack_object) {
22290  return detail::error_result(
22291  "cannot call 'insert' on '%s': no suitable or similar functionality detected on this container", detail::demangle<T>().data());
22292  }
22293 
22294  static detail::error_result insert_has(std::true_type, lua_State* L_, T& self, stack_object key, stack_object value) {
22295  return insert_lookup(meta::any<is_associative, is_lookup>(), L_, self, std::move(key), std::move(value));
22296  }
22297 
22298  static detail::error_result insert_has(std::false_type, lua_State* L_, T& self, stack_object where, stack_object value) {
22299  return insert_after_has(meta::has_insert_after<T>(), L_, self, where, value);
22300  }
22301 
22302  static detail::error_result insert_copyable(std::true_type, lua_State* L_, T& self, stack_object key, stack_object value) {
22303  return insert_has(std::integral_constant < bool,
22304  meta::has_insert<T>::value || meta::has_insert_with_iterator<T>::value > (),
22305  L_,
22306  self,
22307  std::move(key),
22308  std::move(value));
22309  }
22310 
22311  static detail::error_result insert_copyable(std::false_type, lua_State*, T&, stack_object, stack_object) {
22312  return detail::error_result("cannot call 'insert' on '%s': value_type is non-copyable", detail::demangle<T>().data());
22313  }
22314 
22315  static detail::error_result erase_integral(std::true_type, lua_State* L_, T& self, K& key) {
22316  auto it = deferred_uc::begin(L_, self);
22317  key = (static_cast<std::ptrdiff_t>(key) + deferred_uc::index_adjustment(L_, self));
22318  std::advance(it, key);
22319  self.erase(it);
22320 
22321  return {};
22322  }
22323 
22324  static detail::error_result erase_integral(std::false_type, lua_State* L_, T& self, const K& key) {
22325  auto fx = [&](const value_type& r) -> bool { return key == r; };
22326  auto e = deferred_uc::end(L_, self);
22327  auto it = std::find_if(deferred_uc::begin(L_, self), e, std::ref(fx));
22328  if (it == e) {
22329  return {};
22330  }
22331  self.erase(it);
22332 
22333  return {};
22334  }
22335 
22336  static detail::error_result erase_associative_lookup(std::true_type, lua_State*, T& self, const K& key) {
22337  self.erase(key);
22338  return {};
22339  }
22340 
22341  static detail::error_result erase_associative_lookup(std::false_type, lua_State* L_, T& self, K& key) {
22342  return erase_integral(std::is_integral<K>(), L_, self, key);
22343  }
22344 
22345  static detail::error_result erase_after_has(std::true_type, lua_State* L_, T& self, K& key) {
22346  auto backit = self.before_begin();
22347  {
22348  key = static_cast<K>(static_cast<std::ptrdiff_t>(key) + deferred_uc::index_adjustment(L_, self));
22349  auto e = deferred_uc::end(L_, self);
22350  for (auto it = deferred_uc::begin(L_, self); key > 0; ++backit, ++it, --key) {
22351  if (backit == e) {
22352  return detail::error_result("sol: out of bounds for erase on '%s'", detail::demangle<T>().c_str());
22353  }
22354  }
22355  }
22356  self.erase_after(backit);
22357  return {};
22358  }
22359 
22360  static detail::error_result erase_after_has(std::false_type, lua_State*, T&, const K&) {
22361  return detail::error_result("sol: cannot call erase on '%s'", detail::demangle<T>().c_str());
22362  }
22363 
22364  static detail::error_result erase_key_has(std::true_type, lua_State* L_, T& self, K& key) {
22365  return erase_associative_lookup(meta::any<is_associative, is_lookup>(), L_, self, key);
22366  }
22367 
22368  static detail::error_result erase_key_has(std::false_type, lua_State* L_, T& self, K& key) {
22369  return erase_after_has(has_erase_after<T>(), L_, self, key);
22370  }
22371 
22372  static detail::error_result erase_has(std::true_type, lua_State* L_, T& self, K& key) {
22373  return erase_associative_lookup(meta::any<is_associative, is_lookup>(), L_, self, key);
22374  }
22375 
22376  static detail::error_result erase_has(std::false_type, lua_State* L_, T& self, K& key) {
22377  return erase_key_has(has_erase_key<T>(), L_, self, key);
22378  }
22379 
22380  static auto size_has(std::false_type, lua_State* L_, T& self) {
22381  return std::distance(deferred_uc::begin(L_, self), deferred_uc::end(L_, self));
22382  }
22383 
22384  static auto size_has(std::true_type, lua_State*, T& self) {
22385  return self.size();
22386  }
22387 
22388  static void clear_has(std::true_type, lua_State*, T& self) {
22389  self.clear();
22390  }
22391 
22392  static void clear_has(std::false_type, lua_State* L_, T&) {
22393  luaL_error(L_, "sol: cannot call clear on '%s'", detail::demangle<T>().c_str());
22394  }
22395 
22396  static bool empty_has(std::true_type, lua_State*, T& self) {
22397  return self.empty();
22398  }
22399 
22400  static bool empty_has(std::false_type, lua_State* L_, T& self) {
22401  return deferred_uc::begin(L_, self) == deferred_uc::end(L_, self);
22402  }
22403 
22404  static detail::error_result get_associative_find(std::true_type, lua_State* L_, T& self, K& key) {
22405  auto it = self.find(key);
22406  if (it == deferred_uc::end(L_, self)) {
22407  stack::push(L_, lua_nil);
22408  return {};
22409  }
22410  return get_associative(std::true_type(), L_, it);
22411  }
22412 
22413  static detail::error_result get_associative_find(std::false_type, lua_State* L_, T& self, K& key) {
22414  return get_it(is_linear_integral(), L_, self, key);
22415  }
22416 
22417  static detail::error_result get_start(lua_State* L_, T& self, K& key) {
22418  return get_associative_find(std::integral_constant < bool, is_associative::value&& has_find<T>::value > (), L_, self, key);
22419  }
22420 
22421  static detail::error_result set_start(lua_State* L_, T& self, stack_object key, stack_object value) {
22422  return set_it(is_linear_integral(), L_, self, std::move(key), std::move(value));
22423  }
22424 
22425  static std::size_t size_start(lua_State* L_, T& self) {
22426  return static_cast<std::size_t>(size_has(meta::has_size<T>(), L_, self));
22427  }
22428 
22429  static void clear_start(lua_State* L_, T& self) {
22430  clear_has(has_clear<T>(), L_, self);
22431  }
22432 
22433  static bool empty_start(lua_State* L_, T& self) {
22434  return empty_has(has_empty<T>(), L_, self);
22435  }
22436 
22437  static detail::error_result erase_start(lua_State* L_, T& self, K& key) {
22438  return erase_has(has_erase<T>(), L_, self, key);
22439  }
22440 
22441  template <bool ip>
22442  static int next_associative(std::true_type, lua_State* L_) {
22443  iter& i = stack::unqualified_get<user<iter>>(L_, 1);
22444  auto& source = i.source;
22445  auto& it = i.it;
22446  if (it == deferred_uc::end(L_, source)) {
22447  return stack::push(L_, lua_nil);
22448  }
22449  int p;
22450  if constexpr (ip) {
22451  ++i.index;
22452  p = stack::push_reference(L_, i.index);
22453  }
22454  else {
22455  p = stack::push_reference(L_, it->first);
22456  }
22457  p += stack::stack_detail::push_reference<push_type>(L_, detail::deref_move_only(it->second));
22458  std::advance(it, 1);
22459  return p;
22460  }
22461 
22462  template <bool>
22463  static int next_associative(std::false_type, lua_State* L_) {
22464  iter& i = stack::unqualified_get<user<iter>>(L_, 1);
22465  auto& source = i.source;
22466  auto& it = i.it;
22467  next_K k = stack::unqualified_get<next_K>(L_, 2);
22468  if (it == deferred_uc::end(L_, source)) {
22469  return stack::push(L_, lua_nil);
22470  }
22471  int p;
22472  if constexpr (std::is_integral_v<next_K>) {
22473  p = stack::push_reference(L_, k + 1);
22474  }
22475  else {
22476  p = stack::stack_detail::push_reference(L_, k + 1);
22477  }
22478  p += stack::stack_detail::push_reference<push_type>(L_, detail::deref_move_only(*it));
22479  std::advance(it, 1);
22480  return p;
22481  }
22482 
22483  template <bool ip>
22484  static int next_iter(lua_State* L_) {
22486  return next_associative<ip>(is_assoc(), L_);
22487  }
22488 
22489  template <bool ip>
22490  static int pairs_associative(std::true_type, lua_State* L_) {
22491  auto& src = get_src(L_);
22492  stack::push(L_, next_iter<ip>);
22493  stack::push<user<iter>>(L_, L_, 1, src, deferred_uc::begin(L_, src));
22494  stack::push(L_, lua_nil);
22495  return 3;
22496  }
22497 
22498  template <bool ip>
22499  static int pairs_associative(std::false_type, lua_State* L_) {
22500  auto& src = get_src(L_);
22501  stack::push(L_, next_iter<ip>);
22502  stack::push<user<iter>>(L_, L_, 1, src, deferred_uc::begin(L_, src));
22503  stack::push(L_, 0);
22504  return 3;
22505  }
22506 
22507  public:
22508  static int at(lua_State* L_) {
22509  auto& self = get_src(L_);
22511  {
22512  std::ptrdiff_t pos = stack::unqualified_get<std::ptrdiff_t>(L_, 2);
22513  er = at_start(L_, self, pos);
22514  }
22515  return handle_errors(L_, er);
22516  }
22517 
22518  static int get(lua_State* L_) {
22519  auto& self = get_src(L_);
22521  {
22522  decltype(auto) key = stack::unqualified_get<K>(L_);
22523  er = get_start(L_, self, key);
22524  }
22525  return handle_errors(L_, er);
22526  }
22527 
22528  static int index_get(lua_State* L_) {
22529  return get(L_);
22530  }
22531 
22532  static int set(lua_State* L_) {
22533  stack_object value = stack_object(L_, raw_index(3));
22534  if constexpr (is_linear_integral::value) {
22535  // for non-associative containers,
22536  // erasure only happens if it is the
22537  // last index in the container
22538  auto key = stack::get<K>(L_, 2);
22539  auto self_size = deferred_uc::size(L_);
22540  if (key == static_cast<K>(self_size)) {
22541  if (type_of(L_, 3) == type::lua_nil) {
22542  return erase(L_);
22543  }
22544  }
22545  }
22546  else {
22547  if (type_of(L_, 3) == type::lua_nil) {
22548  return erase(L_);
22549  }
22550  }
22551  auto& self = get_src(L_);
22552  detail::error_result er = set_start(L_, self, stack_object(L_, raw_index(2)), std::move(value));
22553  return handle_errors(L_, er);
22554  }
22555 
22556  static int index_set(lua_State* L_) {
22557  return set(L_);
22558  }
22559 
22560  static int add(lua_State* L_) {
22561  auto& self = get_src(L_);
22562  detail::error_result er = add_copyable(is_copyable(), L_, self, stack_object(L_, raw_index(2)));
22563  return handle_errors(L_, er);
22564  }
22565 
22566  static int insert(lua_State* L_) {
22567  auto& self = get_src(L_);
22568  detail::error_result er = insert_copyable(is_copyable(), L_, self, stack_object(L_, raw_index(2)), stack_object(L_, raw_index(3)));
22569  return handle_errors(L_, er);
22570  }
22571 
22572  static int find(lua_State* L_) {
22573  auto& self = get_src(L_);
22574  detail::error_result er = find_has(has_find<T>(), L_, self);
22575  return handle_errors(L_, er);
22576  }
22577 
22578  static int index_of(lua_State* L_) {
22579  auto& self = get_src(L_);
22580  detail::error_result er = find_has<true>(has_find<T>(), L_, self);
22581  return handle_errors(L_, er);
22582  }
22583 
22584  static iterator begin(lua_State*, T& self) {
22585  if constexpr (meta::has_begin_end_v<T>) {
22586  return self.begin();
22587  }
22588  else {
22589  using std::begin;
22590  return begin(self);
22591  }
22592  }
22593 
22594  static iterator end(lua_State*, T& self) {
22595  if constexpr (meta::has_begin_end_v<T>) {
22596  return self.end();
22597  }
22598  else {
22599  using std::end;
22600  return end(self);
22601  }
22602  }
22603 
22604  static int size(lua_State* L_) {
22605  auto& self = get_src(L_);
22606  std::size_t r = size_start(L_, self);
22607  return stack::push(L_, r);
22608  }
22609 
22610  static int clear(lua_State* L_) {
22611  auto& self = get_src(L_);
22612  clear_start(L_, self);
22613  return 0;
22614  }
22615 
22616  static int erase(lua_State* L_) {
22617  auto& self = get_src(L_);
22619  {
22620  decltype(auto) key = stack::unqualified_get<K>(L_, 2);
22621  er = erase_start(L_, self, key);
22622  }
22623  return handle_errors(L_, er);
22624  }
22625 
22626  static int empty(lua_State* L_) {
22627  auto& self = get_src(L_);
22628  return stack::push(L_, empty_start(L_, self));
22629  }
22630 
22631  static std::ptrdiff_t index_adjustment(lua_State*, T&) {
22632  return static_cast<std::ptrdiff_t>((SOL_CONTAINER_START_INDEX_I_) == 0 ? 0 : -(SOL_CONTAINER_START_INDEX_I_));
22633  }
22634 
22635  static int pairs(lua_State* L_) {
22637  return pairs_associative<false>(is_assoc(), L_);
22638  }
22639 
22640  static int ipairs(lua_State* L_) {
22642  return pairs_associative<true>(is_assoc(), L_);
22643  }
22644 
22645  static int next(lua_State* L_) {
22646  return stack::push(L_, next_iter<false>);
22647  }
22648  };
22649 
22650  template <typename X>
22651  struct usertype_container_default<X, std::enable_if_t<std::is_array<std::remove_pointer_t<meta::unwrap_unqualified_t<X>>>::value>> {
22652  private:
22653  typedef std::remove_pointer_t<meta::unwrap_unqualified_t<X>> T;
22655 
22656  public:
22657  typedef std::remove_extent_t<T> value_type;
22658  typedef value_type* iterator;
22659 
22660  private:
22661  struct iter {
22662  reference keep_alive;
22663  T& source;
22664  iterator it;
22665 
22666  iter(lua_State* L_, int stack_index, T& source, iterator it) noexcept
22667  : keep_alive(sol::main_thread(L_, L_), stack_index), source(source), it(std::move(it)) {
22668  }
22669 
22670  ~iter() {
22671 
22672  }
22673  };
22674 
22675  static auto& get_src(lua_State* L_) {
22676  auto p = stack::unqualified_check_get<T*>(L_, 1);
22677 #if SOL_IS_ON(SOL_SAFE_USERTYPE)
22678  if (!p) {
22679  luaL_error(L_,
22680  "sol: 'self' is not of type '%s' (pass 'self' as first argument with ':' or call on proper type)",
22681  detail::demangle<T>().c_str());
22682  }
22683  if (p.value() == nullptr) {
22684  luaL_error(
22685  L_, "sol: 'self' argument is nil (pass 'self' as first argument with ':' or call on a '%s' type)", detail::demangle<T>().c_str());
22686  }
22687 #endif // Safe getting with error
22688  return *p.value();
22689  }
22690 
22691  static int find(std::true_type, lua_State* L_) {
22692  T& self = get_src(L_);
22693  decltype(auto) value = stack::unqualified_get<value_type>(L_, 2);
22694  std::size_t N = std::extent<T>::value;
22695  for (std::size_t idx = 0; idx < N; ++idx) {
22696  using v_t = std::add_const_t<decltype(self[idx])>;
22697  v_t v = self[idx];
22698  if (v == value) {
22699  idx = static_cast<std::size_t>(static_cast<std::ptrdiff_t>(idx) - deferred_uc::index_adjustment(L_, self));
22700  return stack::push(L_, idx);
22701  }
22702  }
22703  return stack::push(L_, lua_nil);
22704  }
22705 
22706  static int find(std::false_type, lua_State* L_) {
22707  return luaL_error(L_, "sol: cannot call 'find' on '%s': no supported comparison operator for the value type", detail::demangle<T>().c_str());
22708  }
22709 
22710  static int next_iter(lua_State* L_) {
22711  iter& i = stack::unqualified_get<user<iter>>(L_, 1);
22712  auto& source = i.source;
22713  auto& it = i.it;
22714  std::size_t k = stack::unqualified_get<std::size_t>(L_, 2);
22715  if (it == deferred_uc::end(L_, source)) {
22716  return 0;
22717  }
22718  int p;
22719  p = stack::push(L_, k + 1);
22720  p += stack::push_reference(L_, detail::deref_move_only(*it));
22721  std::advance(it, 1);
22722  return p;
22723  }
22724 
22725  public:
22726  static int clear(lua_State* L_) {
22727  return luaL_error(L_, "sol: cannot call 'clear' on type '%s': cannot remove all items from a fixed array", detail::demangle<T>().c_str());
22728  }
22729 
22730  static int erase(lua_State* L_) {
22731  return luaL_error(L_, "sol: cannot call 'erase' on type '%s': cannot remove an item from fixed arrays", detail::demangle<T>().c_str());
22732  }
22733 
22734  static int add(lua_State* L_) {
22735  return luaL_error(L_, "sol: cannot call 'add' on type '%s': cannot add to fixed arrays", detail::demangle<T>().c_str());
22736  }
22737 
22738  static int insert(lua_State* L_) {
22739  return luaL_error(L_, "sol: cannot call 'insert' on type '%s': cannot insert new entries into fixed arrays", detail::demangle<T>().c_str());
22740  }
22741 
22742  static int at(lua_State* L_) {
22743  return get(L_);
22744  }
22745 
22746  static int get(lua_State* L_) {
22747  T& self = get_src(L_);
22748  std::ptrdiff_t idx = stack::unqualified_get<std::ptrdiff_t>(L_, 2);
22749  idx += deferred_uc::index_adjustment(L_, self);
22750  if (idx >= static_cast<std::ptrdiff_t>(std::extent<T>::value) || idx < 0) {
22751  return stack::push(L_, lua_nil);
22752  }
22753  return stack::push_reference(L_, detail::deref_move_only(self[idx]));
22754  }
22755 
22756  static int index_get(lua_State* L_) {
22757  return get(L_);
22758  }
22759 
22760  static int set(lua_State* L_) {
22761  T& self = get_src(L_);
22762  std::ptrdiff_t idx = stack::unqualified_get<std::ptrdiff_t>(L_, 2);
22763  idx += deferred_uc::index_adjustment(L_, self);
22764  if (idx >= static_cast<std::ptrdiff_t>(std::extent<T>::value)) {
22765  return luaL_error(L_, "sol: index out of bounds (too big) for set on '%s'", detail::demangle<T>().c_str());
22766  }
22767  if (idx < 0) {
22768  return luaL_error(L_, "sol: index out of bounds (too small) for set on '%s'", detail::demangle<T>().c_str());
22769  }
22770  self[idx] = stack::unqualified_get<value_type>(L_, 3);
22771  return 0;
22772  }
22773 
22774  static int index_set(lua_State* L_) {
22775  return set(L_);
22776  }
22777 
22778  static int index_of(lua_State* L_) {
22779  return find(L_);
22780  }
22781 
22782  static int find(lua_State* L_) {
22784  }
22785 
22786  static int size(lua_State* L_) {
22787  return stack::push(L_, std::extent<T>::value);
22788  }
22789 
22790  static int empty(lua_State* L_) {
22791  return stack::push(L_, std::extent<T>::value > 0);
22792  }
22793 
22794  static int pairs(lua_State* L_) {
22795  auto& src = get_src(L_);
22796  stack::push(L_, next_iter);
22797  stack::push<user<iter>>(L_, L_, 1, src, deferred_uc::begin(L_, src));
22798  stack::push(L_, 0);
22799  return 3;
22800  }
22801 
22802  static int ipairs(lua_State* L_) {
22803  return pairs(L_);
22804  }
22805 
22806  static int next(lua_State* L_) {
22807  return stack::push(L_, next_iter);
22808  }
22809 
22810  static std::ptrdiff_t index_adjustment(lua_State*, T&) {
22811  return (SOL_CONTAINER_START_INDEX_I_) == 0 ? 0 : -(SOL_CONTAINER_START_INDEX_I_);
22812  }
22813 
22814  static iterator begin(lua_State*, T& self) {
22815  return std::addressof(self[0]);
22816  }
22817 
22818  static iterator end(lua_State*, T& self) {
22819  return std::addressof(self[0]) + std::extent<T>::value;
22820  }
22821  };
22822 
22823  template <typename X>
22825  } // namespace container_detail
22826 
22827  template <typename T>
22829 
22830 } // namespace sol
22831 
22832 // end of sol/usertype_container.hpp
22833 
22834 #include <unordered_map>
22835 
22836 namespace sol {
22837 
22838  namespace container_detail {
22839  template <typename X>
22840  struct u_c_launch {
22841  using T = std::remove_pointer_t<meta::unqualified_t<X>>;
22842  using uc = usertype_container<T>;
22844 
22845  static inline int real_index_get_traits(std::true_type, lua_State* L) {
22846  return uc::index_get(L);
22847  }
22848 
22849  static inline int real_index_get_traits(std::false_type, lua_State* L) {
22850  return default_uc::index_get(L);
22851  }
22852 
22853  static inline int real_index_call(lua_State* L) {
22854  static const std::unordered_map<string_view, lua_CFunction> calls {
22855  { "at", &real_at_call },
22856  { "get", &real_get_call },
22857  { "set", &real_set_call },
22858  { "size", &real_length_call },
22859  { "add", &real_add_call },
22860  { "empty", &real_empty_call },
22861  { "insert", &real_insert_call },
22862  { "clear", &real_clear_call },
22863  { "find", &real_find_call },
22864  { "index_of", &real_index_of_call },
22865  { "erase", &real_erase_call },
22866  { "pairs", &pairs_call },
22867  { "next", &next_call },
22868  };
22869  auto maybenameview = stack::unqualified_check_get<string_view>(L, 2);
22870  if (maybenameview) {
22871  const string_view& name = *maybenameview;
22872  auto it = calls.find(name);
22873  if (it != calls.cend()) {
22874  return stack::push(L, it->second);
22875  }
22876  }
22877  return real_index_get_traits(container_detail::has_traits_index_get<uc>(), L);
22878  }
22879 
22880  static inline int real_at_traits(std::true_type, lua_State* L) {
22881  return uc::at(L);
22882  }
22883 
22884  static inline int real_at_traits(std::false_type, lua_State* L) {
22885  return default_uc::at(L);
22886  }
22887 
22888  static inline int real_at_call(lua_State* L) {
22889  return real_at_traits(container_detail::has_traits_at<uc>(), L);
22890  }
22891 
22892  static inline int real_get_traits(std::true_type, lua_State* L) {
22893  return uc::get(L);
22894  }
22895 
22896  static inline int real_get_traits(std::false_type, lua_State* L) {
22897  return default_uc::get(L);
22898  }
22899 
22900  static inline int real_get_call(lua_State* L) {
22901  return real_get_traits(container_detail::has_traits_get<uc>(), L);
22902  }
22903 
22904  static inline int real_set_traits(std::true_type, lua_State* L) {
22905  return uc::set(L);
22906  }
22907 
22908  static inline int real_set_traits(std::false_type, lua_State* L) {
22909  return default_uc::set(L);
22910  }
22911 
22912  static inline int real_set_call(lua_State* L) {
22913  return real_set_traits(container_detail::has_traits_set<uc>(), L);
22914  }
22915 
22916  static inline int real_index_set_traits(std::true_type, lua_State* L) {
22917  return uc::index_set(L);
22918  }
22919 
22920  static inline int real_index_set_traits(std::false_type, lua_State* L) {
22921  return default_uc::index_set(L);
22922  }
22923 
22924  static inline int real_new_index_call(lua_State* L) {
22925  return real_index_set_traits(container_detail::has_traits_index_set<uc>(), L);
22926  }
22927 
22928  static inline int real_pairs_traits(std::true_type, lua_State* L) {
22929  return uc::pairs(L);
22930  }
22931 
22932  static inline int real_pairs_traits(std::false_type, lua_State* L) {
22933  return default_uc::pairs(L);
22934  }
22935 
22936  static inline int real_pairs_call(lua_State* L) {
22937  return real_pairs_traits(container_detail::has_traits_pairs<uc>(), L);
22938  }
22939 
22940  static inline int real_ipairs_traits(std::true_type, lua_State* L) {
22941  return uc::ipairs(L);
22942  }
22943 
22944  static inline int real_ipairs_traits(std::false_type, lua_State* L) {
22945  return default_uc::ipairs(L);
22946  }
22947 
22948  static inline int real_ipairs_call(lua_State* L) {
22949  return real_ipairs_traits(container_detail::has_traits_ipairs<uc>(), L);
22950  }
22951 
22952  static inline int real_next_traits(std::true_type, lua_State* L) {
22953  return uc::next(L);
22954  }
22955 
22956  static inline int real_next_traits(std::false_type, lua_State* L) {
22957  return default_uc::next(L);
22958  }
22959 
22960  static inline int real_next_call(lua_State* L) {
22961  return real_next_traits(container_detail::has_traits_next<uc>(), L);
22962  }
22963 
22964  static inline int real_size_traits(std::true_type, lua_State* L) {
22965  return uc::size(L);
22966  }
22967 
22968  static inline int real_size_traits(std::false_type, lua_State* L) {
22969  return default_uc::size(L);
22970  }
22971 
22972  static inline int real_length_call(lua_State* L) {
22973  return real_size_traits(container_detail::has_traits_size<uc>(), L);
22974  }
22975 
22976  static inline int real_add_traits(std::true_type, lua_State* L) {
22977  return uc::add(L);
22978  }
22979 
22980  static inline int real_add_traits(std::false_type, lua_State* L) {
22981  return default_uc::add(L);
22982  }
22983 
22984  static inline int real_add_call(lua_State* L) {
22985  return real_add_traits(container_detail::has_traits_add<uc>(), L);
22986  }
22987 
22988  static inline int real_insert_traits(std::true_type, lua_State* L) {
22989  return uc::insert(L);
22990  }
22991 
22992  static inline int real_insert_traits(std::false_type, lua_State* L) {
22993  return default_uc::insert(L);
22994  }
22995 
22996  static inline int real_insert_call(lua_State* L) {
22997  return real_insert_traits(container_detail::has_traits_insert<uc>(), L);
22998  }
22999 
23000  static inline int real_clear_traits(std::true_type, lua_State* L) {
23001  return uc::clear(L);
23002  }
23003 
23004  static inline int real_clear_traits(std::false_type, lua_State* L) {
23005  return default_uc::clear(L);
23006  }
23007 
23008  static inline int real_clear_call(lua_State* L) {
23009  return real_clear_traits(container_detail::has_traits_clear<uc>(), L);
23010  }
23011 
23012  static inline int real_empty_traits(std::true_type, lua_State* L) {
23013  return uc::empty(L);
23014  }
23015 
23016  static inline int real_empty_traits(std::false_type, lua_State* L) {
23017  return default_uc::empty(L);
23018  }
23019 
23020  static inline int real_empty_call(lua_State* L) {
23021  return real_empty_traits(container_detail::has_traits_empty<uc>(), L);
23022  }
23023 
23024  static inline int real_erase_traits(std::true_type, lua_State* L) {
23025  return uc::erase(L);
23026  }
23027 
23028  static inline int real_erase_traits(std::false_type, lua_State* L) {
23029  return default_uc::erase(L);
23030  }
23031 
23032  static inline int real_erase_call(lua_State* L) {
23033  return real_erase_traits(container_detail::has_traits_erase<uc>(), L);
23034  }
23035 
23036  static inline int real_find_traits(std::true_type, lua_State* L) {
23037  return uc::find(L);
23038  }
23039 
23040  static inline int real_find_traits(std::false_type, lua_State* L) {
23041  return default_uc::find(L);
23042  }
23043 
23044  static inline int real_find_call(lua_State* L) {
23045  return real_find_traits(container_detail::has_traits_find<uc>(), L);
23046  }
23047 
23048  static inline int real_index_of_call(lua_State* L) {
23049  if constexpr (container_detail::has_traits_index_of<uc>()) {
23050  return uc::index_of(L);
23051  }
23052  else {
23053  return default_uc::index_of(L);
23054  }
23055  }
23056 
23057  static inline int add_call(lua_State* L) {
23058  return detail::typed_static_trampoline<decltype(&real_add_call), (&real_add_call)>(L);
23059  }
23060 
23061  static inline int erase_call(lua_State* L) {
23062  return detail::typed_static_trampoline<decltype(&real_erase_call), (&real_erase_call)>(L);
23063  }
23064 
23065  static inline int insert_call(lua_State* L) {
23066  return detail::typed_static_trampoline<decltype(&real_insert_call), (&real_insert_call)>(L);
23067  }
23068 
23069  static inline int clear_call(lua_State* L) {
23070  return detail::typed_static_trampoline<decltype(&real_clear_call), (&real_clear_call)>(L);
23071  }
23072 
23073  static inline int empty_call(lua_State* L) {
23074  return detail::typed_static_trampoline<decltype(&real_empty_call), (&real_empty_call)>(L);
23075  }
23076 
23077  static inline int find_call(lua_State* L) {
23078  return detail::typed_static_trampoline<decltype(&real_find_call), (&real_find_call)>(L);
23079  }
23080 
23081  static inline int index_of_call(lua_State* L) {
23082  return detail::typed_static_trampoline<decltype(&real_index_of_call), (&real_index_of_call)>(L);
23083  }
23084 
23085  static inline int length_call(lua_State* L) {
23086  return detail::typed_static_trampoline<decltype(&real_length_call), (&real_length_call)>(L);
23087  }
23088 
23089  static inline int pairs_call(lua_State* L) {
23090  return detail::typed_static_trampoline<decltype(&real_pairs_call), (&real_pairs_call)>(L);
23091  }
23092 
23093  static inline int ipairs_call(lua_State* L) {
23094  return detail::typed_static_trampoline<decltype(&real_ipairs_call), (&real_ipairs_call)>(L);
23095  }
23096 
23097  static inline int next_call(lua_State* L) {
23098  return detail::typed_static_trampoline<decltype(&real_next_call), (&real_next_call)>(L);
23099  }
23100 
23101  static inline int at_call(lua_State* L) {
23102  return detail::typed_static_trampoline<decltype(&real_at_call), (&real_at_call)>(L);
23103  }
23104 
23105  static inline int get_call(lua_State* L) {
23106  return detail::typed_static_trampoline<decltype(&real_get_call), (&real_get_call)>(L);
23107  }
23108 
23109  static inline int set_call(lua_State* L) {
23110  return detail::typed_static_trampoline<decltype(&real_set_call), (&real_set_call)>(L);
23111  }
23112 
23113  static inline int index_call(lua_State* L) {
23114  return detail::typed_static_trampoline<decltype(&real_index_call), (&real_index_call)>(L);
23115  }
23116 
23117  static inline int new_index_call(lua_State* L) {
23118  return detail::typed_static_trampoline<decltype(&real_new_index_call), (&real_new_index_call)>(L);
23119  }
23120  };
23121  } // namespace container_detail
23122 
23123  namespace stack {
23124  namespace stack_detail {
23125  template <typename T, bool is_shim = false>
23127  lua_State* L;
23128 
23129  metatable_setup(lua_State* L) : L(L) {
23130  }
23131 
23132  void operator()() {
23133  using meta_usertype_container
23135  static const char* metakey
23137  static const std::array<luaL_Reg, 20> reg = { {
23138  // clang-format off
23139  { "__pairs", &meta_usertype_container::pairs_call },
23140  { "__ipairs", &meta_usertype_container::ipairs_call },
23141  { "__len", &meta_usertype_container::length_call },
23142  { "__index", &meta_usertype_container::index_call },
23143  { "__newindex", &meta_usertype_container::new_index_call },
23144  { "pairs", &meta_usertype_container::pairs_call },
23145  { "next", &meta_usertype_container::next_call },
23146  { "at", &meta_usertype_container::at_call },
23147  { "get", &meta_usertype_container::get_call },
23148  { "set", &meta_usertype_container::set_call },
23149  { "size", &meta_usertype_container::length_call },
23150  { "empty", &meta_usertype_container::empty_call },
23151  { "clear", &meta_usertype_container::clear_call },
23152  { "insert", &meta_usertype_container::insert_call },
23153  { "add", &meta_usertype_container::add_call },
23154  { "find", &meta_usertype_container::find_call },
23155  { "index_of", &meta_usertype_container::index_of_call },
23156  { "erase", &meta_usertype_container::erase_call },
23157  std::is_pointer<T>::value ? luaL_Reg{ nullptr, nullptr } : luaL_Reg{ "__gc", &detail::usertype_alloc_destroy<T> },
23158  { nullptr, nullptr }
23159  // clang-format on
23160  } };
23161 
23162  if (luaL_newmetatable(L, metakey) == 1) {
23163  luaL_setfuncs(L, reg.data(), 0);
23164  }
23165  lua_setmetatable(L, -2);
23166  }
23167  };
23168  } // namespace stack_detail
23169 
23170  template <typename T>
23172  using C = meta::unqualified_t<T>;
23173 
23174  static int push_lvalue(std::true_type, lua_State* L, const C& cont) {
23176  return stack::push<detail::as_pointer_tag<const C>>(L, detail::with_function_tag(), fx, detail::ptr(cont));
23177  }
23178 
23179  static int push_lvalue(std::false_type, lua_State* L, const C& cont) {
23181  return stack::push<detail::as_value_tag<C>>(L, detail::with_function_tag(), fx, cont);
23182  }
23183 
23184  static int push_rvalue(std::true_type, lua_State* L, C&& cont) {
23186  return stack::push<detail::as_value_tag<C>>(L, detail::with_function_tag(), fx, std::move(cont));
23187  }
23188 
23189  static int push_rvalue(std::false_type, lua_State* L, const C& cont) {
23190  return push_lvalue(std::is_lvalue_reference<T>(), L, cont);
23191  }
23192 
23193  static int push(lua_State* L, const as_container_t<T>& as_cont) {
23194  return push_lvalue(std::is_lvalue_reference<T>(), L, as_cont.value());
23195  }
23196 
23197  static int push(lua_State* L, as_container_t<T>&& as_cont) {
23198  return push_rvalue(meta::all<std::is_rvalue_reference<T>, meta::neg<std::is_lvalue_reference<T>>>(), L, std::forward<T>(as_cont.value()));
23199  }
23200  };
23201 
23202  template <typename T>
23204  using C = std::add_pointer_t<meta::unqualified_t<std::remove_pointer_t<T>>>;
23205 
23206  static int push(lua_State* L, T* cont) {
23208  return stack::push<detail::as_pointer_tag<T>>(L, detail::with_function_tag(), fx, cont);
23209  }
23210  };
23211 
23212  template <typename T>
23213  struct unqualified_pusher<T, std::enable_if_t<is_container_v<T>>> {
23214  using C = T;
23215 
23216  template <typename... Args>
23217  static int push(lua_State* L, Args&&... args) {
23219  return stack::push<detail::as_value_tag<T>>(L, detail::with_function_tag(), fx, std::forward<Args>(args)...);
23220  }
23221  };
23222 
23223  template <typename T>
23224  struct unqualified_pusher<T*, std::enable_if_t<is_container_v<T>>> {
23225  using C = std::add_pointer_t<meta::unqualified_t<std::remove_pointer_t<T>>>;
23226 
23227  static int push(lua_State* L, T* cont) {
23229  return stack::push<detail::as_pointer_tag<T>>(L, detail::with_function_tag(), fx, cont);
23230  }
23231  };
23232  } // namespace stack
23233 
23234 } // namespace sol
23235 
23236 // end of sol/usertype_container_launch.hpp
23237 
23238 #include <sstream>
23239 #include <type_traits>
23240 
23241 namespace sol {
23242  namespace u_detail {
23243  constexpr const lua_Integer toplevel_magic = static_cast<lua_Integer>(0xCCC2CCC1);
23244 
23245  constexpr const int environment_index = 1;
23246  constexpr const int usertype_storage_index = 2;
23247  constexpr const int usertype_storage_base_index = 3;
23248  constexpr const int exact_function_index = 4;
23249  constexpr const int magic_index = 5;
23250 
23251  constexpr const int simple_usertype_storage_index = 2;
23252  constexpr const int index_function_index = 3;
23253  constexpr const int new_index_function_index = 4;
23254 
23255  constexpr const int base_walking_failed_index = -32467;
23256  constexpr const int lookup_failed_index = -42469;
23257 
23258  enum class submetatable_type {
23259  // must be sequential
23260  value,
23261  reference,
23262  unique,
23263  const_reference,
23264  const_value,
23265  // must be LAST!
23266  named
23267  };
23268 
23269  inline auto make_string_view(string_view s) {
23270  return s;
23271  }
23272 
23273 #if SOL_IS_ON(SOL_CHAR8_T)
23274  inline auto make_string_view(const char8_t* s) {
23275  return string_view(reinterpret_cast<const char*>(s));
23276  }
23277 #endif
23278 
23279  inline auto make_string_view(call_construction) {
23280  return string_view(to_string(meta_function::call_function));
23281  }
23282 
23283  inline auto make_string_view(meta_function mf) {
23284  return string_view(to_string(mf));
23285  }
23286 
23287  inline auto make_string_view(base_classes_tag) {
23288  return string_view(detail::base_class_cast_key());
23289  }
23290 
23291  template <typename Arg>
23292  inline std::string make_string(Arg&& arg) {
23293  string_view s = make_string_view(arg);
23294  return std::string(s.data(), s.size());
23295  }
23296 
23297  inline int is_indexer(string_view s) {
23298  if (s == to_string(meta_function::index)) {
23299  return 1;
23300  }
23301  else if (s == to_string(meta_function::new_index)) {
23302  return 2;
23303  }
23304  return 0;
23305  }
23306 
23307  inline int is_indexer(meta_function mf) {
23308  if (mf == meta_function::index) {
23309  return 1;
23310  }
23311  else if (mf == meta_function::new_index) {
23312  return 2;
23313  }
23314  return 0;
23315  }
23316 
23317  inline int is_indexer(call_construction) {
23318  return 0;
23319  }
23320  } // namespace u_detail
23321 
23322  namespace detail {
23323 
23324  template <typename T, typename IFx, typename Fx>
23325  inline void insert_default_registrations(IFx&& ifx, Fx&& fx) {
23326  (void)ifx;
23327  (void)fx;
23328  if constexpr (is_automagical<T>::value) {
23329  if (fx(meta_function::less_than)) {
23330  if constexpr (meta::supports_op_less<T>::value) {
23331  lua_CFunction f = &comparsion_operator_wrap<T, std::less<>>;
23332  ifx(meta_function::less_than, f);
23333  }
23334  }
23335  if (fx(meta_function::less_than_or_equal_to)) {
23337  lua_CFunction f = &comparsion_operator_wrap<T, std::less_equal<>>;
23338  ifx(meta_function::less_than_or_equal_to, f);
23339  }
23340  }
23341  if (fx(meta_function::equal_to)) {
23342  if constexpr (meta::supports_op_equal<T>::value) {
23343  lua_CFunction f = &comparsion_operator_wrap<T, std::equal_to<>>;
23344  ifx(meta_function::equal_to, f);
23345  }
23346  else {
23347  lua_CFunction f = &comparsion_operator_wrap<T, no_comp>;
23348  ifx(meta_function::equal_to, f);
23349  }
23350  }
23351  if (fx(meta_function::pairs)) {
23352  ifx(meta_function::pairs, &container_detail::u_c_launch<as_container_t<T>>::pairs_call);
23353  }
23354  if (fx(meta_function::length)) {
23355  if constexpr (meta::has_size<const T>::value || meta::has_size<T>::value) {
23356  auto f = &default_size<T>;
23357  ifx(meta_function::length, f);
23358  }
23359  }
23360  if (fx(meta_function::to_string)) {
23361  if constexpr (is_to_stringable_v<T>) {
23362  if constexpr (!meta::is_probably_stateless_lambda_v<T> && !std::is_member_pointer_v<T>) {
23363  auto f = &detail::static_trampoline<&default_to_string<T>>;
23364  ifx(meta_function::to_string, f);
23365  }
23366  }
23367  }
23368  if (fx(meta_function::call_function)) {
23369  if constexpr (is_callable_v<T>) {
23370  if constexpr (meta::call_operator_deducible_v<T>) {
23371  auto f = &c_call<decltype(&T::operator()), &T::operator()>;
23372  ifx(meta_function::call_function, f);
23373  }
23374  }
23375  }
23376  }
23377  }
23378  } // namespace detail
23379 
23380  namespace stack { namespace stack_detail {
23381  template <typename X>
23382  void set_undefined_methods_on(stack_reference t) {
23383  using T = std::remove_pointer_t<X>;
23384 
23385  lua_State* L = t.lua_state();
23386 
23387  t.push();
23388 
23389  detail::lua_reg_table l {};
23390  int index = 0;
23391  detail::indexed_insert insert_fx(l, index);
23392  detail::insert_default_registrations<T>(insert_fx, detail::property_always_true);
23393  if constexpr (!std::is_pointer_v<X>) {
23394  l[index] = luaL_Reg { to_string(meta_function::garbage_collect).c_str(), detail::make_destructor<T>() };
23395  }
23396  luaL_setfuncs(L, l, 0);
23397 
23398  // __type table
23399  lua_createtable(L, 0, 2);
23400  const std::string& name = detail::demangle<T>();
23401  lua_pushlstring(L, name.c_str(), name.size());
23402  lua_setfield(L, -2, "name");
23403  lua_CFunction is_func = &detail::is_check<T>;
23404  lua_pushcclosure(L, is_func, 0);
23405  lua_setfield(L, -2, "is");
23406  lua_setfield(L, t.stack_index(), to_string(meta_function::type).c_str());
23407 
23408  t.pop();
23409  }
23410  }} // namespace stack::stack_detail
23411 } // namespace sol
23412 
23413 // end of sol/usertype_core.hpp
23414 
23415 // beginning of sol/usertype_storage.hpp
23416 
23417 #include <bitset>
23418 #include <unordered_map>
23419 #include <memory>
23420 
23421 namespace sol { namespace u_detail {
23422 
23423  struct usertype_storage_base;
23424  template <typename T>
23426 
23427  optional<usertype_storage_base&> maybe_get_usertype_storage_base(lua_State* L_, int index);
23428  usertype_storage_base& get_usertype_storage_base(lua_State* L_, const char* gcmetakey);
23429  template <typename T>
23430  optional<usertype_storage<T>&> maybe_get_usertype_storage(lua_State* L_);
23431  template <typename T>
23432  usertype_storage<T>& get_usertype_storage(lua_State* L_);
23433 
23434  using index_call_function = int(lua_State*, void*);
23435  using change_indexing_mem_func = void (usertype_storage_base::*)(
23436  lua_State*, submetatable_type, void*, stateless_stack_reference&, lua_CFunction, lua_CFunction, lua_CFunction, lua_CFunction);
23437 
23439  index_call_function* index;
23440  index_call_function* new_index;
23441  void* binding_data;
23442  };
23443 
23445  void* new_binding_data;
23446  };
23447 
23448  struct binding_base {
23449  virtual void* data() = 0;
23450  virtual ~binding_base() {
23451  }
23452  };
23453 
23454  template <typename K, typename Fq, typename T = void>
23456  using uF = meta::unqualified_t<Fq>;
23457  using F = meta::conditional_t<meta::is_c_str_of_v<uF, char>
23458 #if SOL_IS_ON(SOL_CHAR8_T)
23459  || meta::is_c_str_of_v<uF, char8_t>
23460 #endif
23461  || 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>,
23462  std::add_pointer_t<std::add_const_t<std::remove_all_extents_t<Fq>>>, std::decay_t<Fq>>;
23463  F data_;
23464 
23465  template <typename... Args>
23466  binding(Args&&... args) : data_(std::forward<Args>(args)...) {
23467  }
23468 
23469  virtual void* data() override {
23470  return static_cast<void*>(std::addressof(data_));
23471  }
23472 
23473  template <bool is_index = true, bool is_variable = false>
23474  static inline int call_with_(lua_State* L_, void* target) {
23475  constexpr int boost = !detail::is_non_factory_constructor<F>::value && std::is_same<K, call_construction>::value ? 1 : 0;
23476  auto& f = *static_cast<F*>(target);
23477  return call_detail::call_wrapped<T, is_index, is_variable, boost>(L_, f);
23478  }
23479 
23480  template <bool is_index = true, bool is_variable = false>
23481  static inline int call_(lua_State* L_) {
23482  void* f = stack::get<void*>(L_, upvalue_index(usertype_storage_index));
23483  return call_with_<is_index, is_variable>(L_, f);
23484  }
23485 
23486  template <bool is_index = true, bool is_variable = false>
23487  static inline int call(lua_State* L_) {
23488  int r = detail::typed_static_trampoline<decltype(&call_<is_index, is_variable>), (&call_<is_index, is_variable>)>(L_);
23489  if constexpr (meta::is_specialization_of_v<uF, yielding_t>) {
23490  return lua_yield(L_, r);
23491  }
23492  else {
23493  return r;
23494  }
23495  }
23496 
23497  template <bool is_index = true, bool is_variable = false>
23498  static inline int index_call_with_(lua_State* L_, void* target) {
23499  if constexpr (!is_variable) {
23500  if constexpr (is_lua_c_function_v<std::decay_t<F>>) {
23501  auto& f = *static_cast<std::decay_t<F>*>(target);
23502  return stack::push(L_, f);
23503  }
23504  else {
23505  // set up upvalues
23506  // for a chained call
23507  int upvalues = 0;
23508  upvalues += stack::push(L_, nullptr);
23509  upvalues += stack::push(L_, target);
23510  auto cfunc = &call<is_index, is_variable>;
23511  return stack::push(L_, c_closure(cfunc, upvalues));
23512  }
23513  }
23514  else {
23515  constexpr int boost = !detail::is_non_factory_constructor<F>::value && std::is_same<K, call_construction>::value ? 1 : 0;
23516  auto& f = *static_cast<F*>(target);
23517  return call_detail::call_wrapped<T, is_index, is_variable, boost>(L_, f);
23518  }
23519  }
23520 
23521  template <bool is_index = true, bool is_variable = false>
23522  static inline int index_call_(lua_State* L_) {
23523  void* f = stack::get<void*>(L_, upvalue_index(usertype_storage_index));
23524  return index_call_with_<is_index, is_variable>(L_, f);
23525  }
23526 
23527  template <bool is_index = true, bool is_variable = false>
23528  static inline int index_call(lua_State* L_) {
23529  int r = detail::typed_static_trampoline<decltype(&index_call_<is_index, is_variable>), (&index_call_<is_index, is_variable>)>(L_);
23530  if constexpr (meta::is_specialization_of_v<uF, yielding_t>) {
23531  return lua_yield(L_, r);
23532  }
23533  else {
23534  return r;
23535  }
23536  }
23537  };
23538 
23539  inline int index_fail(lua_State* L_) {
23540  if (lua_getmetatable(L_, 1) == 1) {
23541  int metatarget = lua_gettop(L_);
23542  stack::get_field<false, true>(L_, stack_reference(L_, raw_index(2)), metatarget);
23543  return 1;
23544  }
23545  // With runtime extensibility, we can't
23546  // hard-error things. They have to
23547  // return nil, like regular table types
23548  return stack::push(L_, lua_nil);
23549  }
23550 
23551  inline int index_target_fail(lua_State* L_, void*) {
23552  return index_fail(L_);
23553  }
23554 
23555  inline int new_index_fail(lua_State* L_) {
23556  return luaL_error(L_, "sol: cannot set (new_index) into this object: no defined new_index operation on usertype");
23557  }
23558 
23559  inline int new_index_target_fail(lua_State* L_, void*) {
23560  return new_index_fail(L_);
23561  }
23562 
23564  bool is_destruction = false;
23565  bool is_index = false;
23566  bool is_new_index = false;
23567  bool is_static_index = false;
23568  bool is_static_new_index = false;
23569  bool poison_indexing = false;
23570  bool is_unqualified_lua_CFunction = false;
23571  bool is_unqualified_lua_reference = false;
23572  std::string* p_key = nullptr;
23573  reference* p_binding_ref = nullptr;
23574  lua_CFunction call_func = nullptr;
23575  index_call_storage* p_ics = nullptr;
23576  usertype_storage_base* p_usb = nullptr;
23577  void* p_derived_usb = nullptr;
23578  lua_CFunction idx_call = nullptr, new_idx_call = nullptr, meta_idx_call = nullptr, meta_new_idx_call = nullptr;
23579  change_indexing_mem_func change_indexing;
23580 
23581  void operator()(lua_State* L_, submetatable_type smt_, stateless_reference& fast_index_table_) {
23582  std::string& key = *p_key;
23583  usertype_storage_base& usb = *p_usb;
23584  index_call_storage& ics = *p_ics;
23585 
23586  if (smt_ == submetatable_type::named) {
23587  // do not override __call or
23588  // other specific meta functions on named metatable:
23589  // we need that for call construction
23590  // and other amenities
23591  return;
23592  }
23593  int fast_index_table_push = fast_index_table_.push(L_);
23594  stateless_stack_reference t(L_, -fast_index_table_push);
23595  if (poison_indexing) {
23596  (usb.*change_indexing)(L_, smt_, p_derived_usb, t, idx_call, new_idx_call, meta_idx_call, meta_new_idx_call);
23597  }
23598  if (is_destruction
23599  && (smt_ == submetatable_type::reference || smt_ == submetatable_type::const_reference || smt_ == submetatable_type::named
23600  || smt_ == submetatable_type::unique)) {
23601  // gc does not apply to us here
23602  // for reference types (raw T*, std::ref)
23603  // for the named metatable itself,
23604  // or for unique_usertypes, which do their own custom destroyion
23605  t.pop(L_);
23606  return;
23607  }
23608  if (is_index || is_new_index || is_static_index || is_static_new_index) {
23609  // do not serialize the new_index and index functions here directly
23610  // we control those...
23611  t.pop(L_);
23612  return;
23613  }
23614  if (is_unqualified_lua_CFunction) {
23615  stack::set_field<false, true>(L_, key, call_func, t.stack_index());
23616  }
23617  else if (is_unqualified_lua_reference) {
23618  reference& binding_ref = *p_binding_ref;
23619  stack::set_field<false, true>(L_, key, binding_ref, t.stack_index());
23620  }
23621  else {
23622  stack::set_field<false, true>(L_, key, make_closure(call_func, nullptr, ics.binding_data), t.stack_index());
23623  }
23624  t.pop(L_);
23625  }
23626  };
23627 
23629  reference key;
23630  reference value;
23631 
23632  void operator()(lua_State* L_, submetatable_type smt_, stateless_reference& fast_index_table_) {
23633  if (smt_ == submetatable_type::named) {
23634  return;
23635  }
23636  int fast_index_table_push = fast_index_table_.push(L_);
23637  stateless_stack_reference t(L_, -fast_index_table_push);
23638  stack::set_field<false, true>(L_, key, value, t.stack_index());
23639  t.pop(L_);
23640  }
23641  };
23642 
23644  detail::inheritance_check_function base_class_check_func;
23645  detail::inheritance_cast_function base_class_cast_func;
23646  lua_CFunction idx_call, new_idx_call, meta_idx_call, meta_new_idx_call;
23647  usertype_storage_base* p_usb;
23648  void* p_derived_usb;
23649  change_indexing_mem_func change_indexing;
23650 
23651  void operator()(lua_State* L_, submetatable_type smt_, stateless_reference& fast_index_table_) {
23652  int fast_index_table_push = fast_index_table_.push(L_);
23653  stateless_stack_reference t(L_, -fast_index_table_push);
23654  stack::set_field(L_, detail::base_class_check_key(), reinterpret_cast<void*>(base_class_check_func), t.stack_index());
23655  stack::set_field(L_, detail::base_class_cast_key(), reinterpret_cast<void*>(base_class_cast_func), t.stack_index());
23656  // change indexing, forcefully
23657  (p_usb->*change_indexing)(L_, smt_, p_derived_usb, t, idx_call, new_idx_call, meta_idx_call, meta_new_idx_call);
23658  t.pop(L_);
23659  }
23660  };
23661 
23663  void* binding_data;
23664 
23665  binding_data_equals(void* b) : binding_data(b) {
23666  }
23667 
23668  bool operator()(const std::unique_ptr<binding_base>& ptr) const {
23669  return binding_data == ptr->data();
23670  }
23671  };
23672 
23674  public:
23675  lua_State* m_L;
23676  std::vector<std::unique_ptr<binding_base>> storage;
23677  std::vector<std::unique_ptr<char[]>> string_keys_storage;
23678  std::unordered_map<string_view, index_call_storage> string_keys;
23679  std::unordered_map<stateless_reference, stateless_reference, stateless_reference_hash, stateless_reference_equals> auxiliary_keys;
23680  stateless_reference value_index_table;
23681  stateless_reference reference_index_table;
23682  stateless_reference unique_index_table;
23683  stateless_reference const_reference_index_table;
23684  stateless_reference const_value_index_table;
23685  stateless_reference named_index_table;
23686  stateless_reference type_table;
23687  stateless_reference gc_names_table;
23688  stateless_reference named_metatable;
23689  new_index_call_storage base_index;
23690  new_index_call_storage static_base_index;
23691  bool is_using_index;
23692  bool is_using_new_index;
23693  std::bitset<64> properties;
23694 
23696  : m_L(L_)
23697  , storage()
23698  , string_keys_storage()
23699  , string_keys()
23700  , auxiliary_keys(0, stateless_reference_hash(L_), stateless_reference_equals(L_))
23701  , value_index_table()
23702  , reference_index_table()
23703  , unique_index_table()
23704  , const_reference_index_table()
23705  , const_value_index_table()
23706  , named_index_table()
23707  , type_table(make_reference<stateless_reference>(L_, create))
23708  , gc_names_table(make_reference<stateless_reference>(L_, create))
23709  , named_metatable(make_reference<stateless_reference>(L_, create))
23710  , base_index()
23711  , static_base_index()
23712  , is_using_index(false)
23713  , is_using_new_index(false)
23714  , properties() {
23715  base_index.binding_data = nullptr;
23716  base_index.index = index_target_fail;
23717  base_index.new_index = new_index_target_fail;
23718  base_index.new_binding_data = nullptr;
23719  static_base_index.binding_data = nullptr;
23720  static_base_index.index = index_target_fail;
23721  static_base_index.new_binding_data = this;
23722  static_base_index.new_index = new_index_target_set;
23723  }
23724 
23725  template <typename Fx>
23726  void for_each_table(lua_State* L_, Fx&& fx) {
23727  for (int i = 0; i < 6; ++i) {
23728  submetatable_type smt = static_cast<submetatable_type>(i);
23729  stateless_reference* p_fast_index_table = nullptr;
23730  switch (smt) {
23731  case submetatable_type::const_value:
23732  p_fast_index_table = &this->const_value_index_table;
23733  break;
23734  case submetatable_type::reference:
23735  p_fast_index_table = &this->reference_index_table;
23736  break;
23737  case submetatable_type::unique:
23738  p_fast_index_table = &this->unique_index_table;
23739  break;
23740  case submetatable_type::const_reference:
23741  p_fast_index_table = &this->const_reference_index_table;
23742  break;
23743  case submetatable_type::named:
23744  p_fast_index_table = &this->named_index_table;
23745  break;
23746  case submetatable_type::value:
23747  default:
23748  p_fast_index_table = &this->value_index_table;
23749  break;
23750  }
23751  fx(L_, smt, *p_fast_index_table);
23752  }
23753  }
23754 
23755  void add_entry(string_view sv, index_call_storage ics) {
23756  string_keys_storage.emplace_back(new char[sv.size()]);
23757  std::unique_ptr<char[]>& sv_storage = string_keys_storage.back();
23758  std::memcpy(sv_storage.get(), sv.data(), sv.size());
23759  string_view stored_sv(sv_storage.get(), sv.size());
23760  string_keys.insert_or_assign(std::move(stored_sv), std::move(ics));
23761  }
23762 
23763  template <typename T, typename... Bases>
23764  void update_bases(lua_State* L_, bases<Bases...>) {
23765  static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function),
23766  "The size of this data pointer is too small to fit the inheritance checking function: Please file "
23767  "a bug report.");
23768  static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function),
23769  "The size of this data pointer is too small to fit the inheritance checking function: Please file "
23770  "a bug report.");
23771  static_assert(!meta::any_same<T, Bases...>::value, "base classes cannot list the original class as part of the bases");
23772  if constexpr (sizeof...(Bases) > 0) {
23773  (void)detail::swallow { 0, ((weak_derive<Bases>::value = true), 0)... };
23774 
23775  void* derived_this = static_cast<void*>(static_cast<usertype_storage<T>*>(this));
23776 
23777  update_bases_func for_each_fx;
23778  for_each_fx.base_class_check_func = &detail::inheritance<T>::template type_check_with<Bases...>;
23779  for_each_fx.base_class_cast_func = &detail::inheritance<T>::template type_cast_with<Bases...>;
23780  for_each_fx.idx_call = &usertype_storage<T>::template index_call_with_bases<false, Bases...>;
23781  for_each_fx.new_idx_call = &usertype_storage<T>::template index_call_with_bases<true, Bases...>;
23782  for_each_fx.meta_idx_call = &usertype_storage<T>::template meta_index_call_with_bases<false, Bases...>;
23783  for_each_fx.meta_new_idx_call = &usertype_storage<T>::template meta_index_call_with_bases<true, Bases...>;
23784  for_each_fx.p_usb = this;
23785  for_each_fx.p_derived_usb = derived_this;
23786  for_each_fx.change_indexing = &usertype_storage_base::change_indexing;
23787  for_each_fx.p_derived_usb = derived_this;
23788  this->for_each_table(L_, for_each_fx);
23789  }
23790  else {
23791  (void)L_;
23792  }
23793  }
23794 
23795  void clear() {
23796  if (value_index_table.valid(m_L)) {
23797  stack::clear(m_L, value_index_table);
23798  }
23799  if (reference_index_table.valid(m_L)) {
23800  stack::clear(m_L, reference_index_table);
23801  }
23802  if (unique_index_table.valid(m_L)) {
23803  stack::clear(m_L, unique_index_table);
23804  }
23805  if (const_reference_index_table.valid(m_L)) {
23806  stack::clear(m_L, const_reference_index_table);
23807  }
23808  if (const_value_index_table.valid(m_L)) {
23809  stack::clear(m_L, const_value_index_table);
23810  }
23811  if (named_index_table.valid(m_L)) {
23812  stack::clear(m_L, named_index_table);
23813  }
23814  if (type_table.valid(m_L)) {
23815  stack::clear(m_L, type_table);
23816  }
23817  if (gc_names_table.valid(m_L)) {
23818  stack::clear(m_L, gc_names_table);
23819  }
23820  if (named_metatable.valid(m_L)) {
23821  auto pp = stack::push_pop(m_L, named_metatable);
23822  int named_metatable_index = pp.index_of(named_metatable);
23823  if (lua_getmetatable(m_L, named_metatable_index) == 1) {
23824  stack::clear(m_L, absolute_index(m_L, -1));
23825  }
23826  stack::clear(m_L, named_metatable);
23827  }
23828 
23829  value_index_table.reset(m_L);
23830  reference_index_table.reset(m_L);
23831  unique_index_table.reset(m_L);
23832  const_reference_index_table.reset(m_L);
23833  const_value_index_table.reset(m_L);
23834  named_index_table.reset(m_L);
23835  type_table.reset(m_L);
23836  gc_names_table.reset(m_L);
23837  named_metatable.reset(m_L);
23838 
23839  storage.clear();
23840  string_keys.clear();
23841  auxiliary_keys.clear();
23842  string_keys_storage.clear();
23843  }
23844 
23845  template <bool is_new_index, typename Base>
23846  static void base_walk_index(lua_State* L_, usertype_storage_base& self, bool& keep_going, int& base_result) {
23847  using bases = typename base<Base>::type;
23848  if (!keep_going) {
23849  return;
23850  }
23851  (void)L_;
23852  (void)self;
23853 #if SOL_IS_ON(SOL_USE_UNSAFE_BASE_LOOKUP)
23854  usertype_storage_base& base_storage = get_usertype_storage<Base>(L_);
23855  base_result = self_index_call<is_new_index, true>(bases(), L_, base_storage);
23856 #else
23857  optional<usertype_storage<Base>&> maybe_base_storage = maybe_get_usertype_storage<Base>(L_);
23858  if (static_cast<bool>(maybe_base_storage)) {
23859  base_result = self_index_call<is_new_index, true>(bases(), L_, *maybe_base_storage);
23860  keep_going = base_result == base_walking_failed_index;
23861  }
23862 #endif // Fast versus slow, safe base lookup
23863  }
23864 
23865  template <bool is_new_index = false, bool base_walking = false, bool from_named_metatable = false, typename... Bases>
23866  static inline int self_index_call(types<Bases...>, lua_State* L, usertype_storage_base& self) {
23867  if constexpr (!from_named_metatable || !is_new_index) {
23868  type k_type = stack::get<type>(L, 2);
23869  if (k_type == type::string) {
23870  index_call_storage* target = nullptr;
23871  string_view k = stack::get<string_view>(L, 2);
23872  {
23873  auto it = self.string_keys.find(k);
23874  if (it != self.string_keys.cend()) {
23875  target = &it->second;
23876  }
23877  }
23878  if (target != nullptr) {
23879  // let the target decide what to do, unless it's named...
23880  if constexpr (is_new_index) {
23881  return (target->new_index)(L, target->binding_data);
23882  }
23883  else {
23884  return (target->index)(L, target->binding_data);
23885  }
23886  }
23887  }
23888  else if (k_type != type::lua_nil && k_type != type::none) {
23889  stateless_reference* target = nullptr;
23890  {
23891  stack_reference k = stack::get<stack_reference>(L, 2);
23892  auto it = self.auxiliary_keys.find(k);
23893  if (it != self.auxiliary_keys.cend()) {
23894  target = &it->second;
23895  }
23896  }
23897  if (target != nullptr) {
23898  if constexpr (is_new_index) {
23899  // set value and return
23900  target->reset(L, 3);
23901  return 0;
23902  }
23903  else {
23904  // push target to return
23905  // what we found
23906  return stack::push(L, *target);
23907  }
23908  }
23909  }
23910  }
23911 
23912  // retrieve bases and walk through them.
23913  bool keep_going = true;
23914  int base_result;
23915  (void)keep_going;
23916  (void)base_result;
23917  (void)detail::swallow { 1, (base_walk_index<is_new_index, Bases>(L, self, keep_going, base_result), 1)... };
23918  if constexpr (sizeof...(Bases) > 0) {
23919  if (!keep_going) {
23920  return base_result;
23921  }
23922  }
23923  if constexpr (base_walking) {
23924  // if we're JUST base-walking then don't index-fail, just
23925  // return the false bits
23926  return base_walking_failed_index;
23927  }
23928  else if constexpr (from_named_metatable) {
23929  if constexpr (is_new_index) {
23930  return self.static_base_index.new_index(L, self.static_base_index.new_binding_data);
23931  }
23932  else {
23933  return self.static_base_index.index(L, self.static_base_index.binding_data);
23934  }
23935  }
23936  else {
23937  if constexpr (is_new_index) {
23938  return self.base_index.new_index(L, self.base_index.new_binding_data);
23939  }
23940  else {
23941  return self.base_index.index(L, self.base_index.binding_data);
23942  }
23943  }
23944  }
23945 
23946  void change_indexing(lua_State* L_, submetatable_type submetatable_, void* derived_this_, stateless_stack_reference& t_, lua_CFunction index_,
23947  lua_CFunction new_index_, lua_CFunction meta_index_, lua_CFunction meta_new_index_) {
23948  usertype_storage_base& this_base = *this;
23949  void* base_this = static_cast<void*>(&this_base);
23950 
23951  this->is_using_index |= true;
23952  this->is_using_new_index |= true;
23953  if (submetatable_ == submetatable_type::named) {
23954  stack::set_field(L_, metatable_key, named_index_table, t_.stack_index());
23955  stateless_stack_reference stack_metametatable(L_, -named_metatable.push(L_));
23956  stack::set_field<false, true>(L_,
23957  meta_function::index,
23958  make_closure(meta_index_, nullptr, derived_this_, base_this, nullptr, toplevel_magic),
23959  stack_metametatable.stack_index());
23960  stack::set_field<false, true>(L_,
23961  meta_function::new_index,
23962  make_closure(meta_new_index_, nullptr, derived_this_, base_this, nullptr, toplevel_magic),
23963  stack_metametatable.stack_index());
23964  stack_metametatable.pop(L_);
23965  }
23966  else {
23967  stack::set_field<false, true>(
23968  L_, meta_function::index, make_closure(index_, nullptr, derived_this_, base_this, nullptr, toplevel_magic), t_.stack_index());
23969  stack::set_field<false, true>(
23970  L_, meta_function::new_index, make_closure(new_index_, nullptr, derived_this_, base_this, nullptr, toplevel_magic), t_.stack_index());
23971  }
23972  }
23973 
23974  template <typename T = void, typename Key, typename Value>
23975  void set(lua_State* L, Key&& key, Value&& value);
23976 
23977  static int new_index_target_set(lua_State* L, void* target) {
23978  usertype_storage_base& self = *static_cast<usertype_storage_base*>(target);
23979  self.set(L, reference(L, raw_index(2)), reference(L, raw_index(3)));
23980  return 0;
23981  }
23982 
23984  value_index_table.reset(m_L);
23985  reference_index_table.reset(m_L);
23986  unique_index_table.reset(m_L);
23987  const_reference_index_table.reset(m_L);
23988  const_value_index_table.reset(m_L);
23989  named_index_table.reset(m_L);
23990  type_table.reset(m_L);
23991  gc_names_table.reset(m_L);
23992  named_metatable.reset(m_L);
23993 
23994  auto auxiliary_first = auxiliary_keys.cbegin();
23995  auto auxiliary_last = auxiliary_keys.cend();
23996  while (auxiliary_first != auxiliary_last) {
23997  // save a copy to what we're going to destroy
23998  auto auxiliary_target = auxiliary_first;
23999  // move the iterator up by 1
24000  ++auxiliary_first;
24001  // extract the node and destroy the key
24002  auto extracted_node = auxiliary_keys.extract(auxiliary_target);
24003  extracted_node.key().reset(m_L);
24004  extracted_node.mapped().reset(m_L);
24005  // continue if auxiliary_first hasn't been exhausted
24006  }
24007  }
24008  };
24009 
24010  template <typename T>
24012 
24013  using usertype_storage_base::usertype_storage_base;
24014 
24015  template <bool is_new_index, bool from_named_metatable>
24016  static inline int index_call_(lua_State* L) {
24017  using bases = typename base<T>::type;
24018  usertype_storage_base& self = stack::get<light<usertype_storage_base>>(L, upvalue_index(usertype_storage_index));
24019  return self_index_call<is_new_index, false, from_named_metatable>(bases(), L, self);
24020  }
24021 
24022  template <bool is_new_index, bool from_named_metatable, typename... Bases>
24023  static inline int index_call_with_bases_(lua_State* L) {
24024  using bases = types<Bases...>;
24025  usertype_storage_base& self = stack::get<light<usertype_storage_base>>(L, upvalue_index(usertype_storage_index));
24026  return self_index_call<is_new_index, false, from_named_metatable>(bases(), L, self);
24027  }
24028 
24029  template <bool is_new_index>
24030  static inline int index_call(lua_State* L) {
24031  return detail::static_trampoline<&index_call_<is_new_index, false>>(L);
24032  }
24033 
24034  template <bool is_new_index, typename... Bases>
24035  static inline int index_call_with_bases(lua_State* L) {
24036  return detail::static_trampoline<&index_call_with_bases_<is_new_index, false, Bases...>>(L);
24037  }
24038 
24039  template <bool is_new_index>
24040  static inline int meta_index_call(lua_State* L) {
24041  return detail::static_trampoline<&index_call_<is_new_index, true>>(L);
24042  }
24043 
24044  template <bool is_new_index, typename... Bases>
24045  static inline int meta_index_call_with_bases(lua_State* L) {
24046  return detail::static_trampoline<&index_call_with_bases_<is_new_index, true, Bases...>>(L);
24047  }
24048 
24049  template <typename Key, typename Value>
24050  inline void set(lua_State* L, Key&& key, Value&& value);
24051  };
24052 
24053  template <typename T, typename Key, typename Value>
24054  void usertype_storage_base::set(lua_State* L, Key&& key, Value&& value) {
24055  using ValueU = meta::unwrap_unqualified_t<Value>;
24056  using KeyU = meta::unwrap_unqualified_t<Key>;
24057  using Binding = binding<KeyU, ValueU, T>;
24058  using is_var_bind = is_variable_binding<ValueU>;
24059  if constexpr (std::is_same_v<KeyU, call_construction>) {
24060  (void)key;
24061  std::unique_ptr<Binding> p_binding = std::make_unique<Binding>(std::forward<Value>(value));
24062  Binding& b = *p_binding;
24063  this->storage.push_back(std::move(p_binding));
24064 
24065  this->named_index_table.push(L);
24066  absolute_index metametatable_index(L, -1);
24067  std::string_view call_metamethod_name = to_string(meta_function::call);
24068  lua_pushlstring(L, call_metamethod_name.data(), call_metamethod_name.size());
24069  stack::push(L, nullptr);
24070  stack::push(L, b.data());
24071  lua_CFunction target_func = &b.template call<false, false>;
24072  lua_pushcclosure(L, target_func, 2);
24073  lua_rawset(L, metametatable_index);
24074  this->named_index_table.pop(L);
24075  }
24076  else if constexpr (std::is_same_v<KeyU, base_classes_tag>) {
24077  (void)key;
24078  this->update_bases<T>(L, std::forward<Value>(value));
24079  }
24080  else if constexpr ((meta::is_string_like_or_constructible<KeyU>::value || std::is_same_v<KeyU, meta_function>)) {
24081  std::string s = u_detail::make_string(std::forward<Key>(key));
24082  auto storage_it = this->storage.end();
24083  auto string_it = this->string_keys.find(s);
24084  if (string_it != this->string_keys.cend()) {
24085  const auto& binding_data = string_it->second.binding_data;
24086  storage_it = std::find_if(this->storage.begin(), this->storage.end(), binding_data_equals(binding_data));
24087  this->string_keys.erase(string_it);
24088  }
24089 
24090  std::unique_ptr<Binding> p_binding = std::make_unique<Binding>(std::forward<Value>(value));
24091  Binding& b = *p_binding;
24092  if (storage_it != this->storage.cend()) {
24093  *storage_it = std::move(p_binding);
24094  }
24095  else {
24096  this->storage.push_back(std::move(p_binding));
24097  }
24098 
24099  bool is_index = (s == to_string(meta_function::index));
24100  bool is_new_index = (s == to_string(meta_function::new_index));
24101  bool is_static_index = (s == to_string(meta_function::static_index));
24102  bool is_static_new_index = (s == to_string(meta_function::static_new_index));
24103  bool is_destruction = s == to_string(meta_function::garbage_collect);
24104  bool poison_indexing = (!is_using_index || !is_using_new_index) && (is_var_bind::value || is_index || is_new_index);
24105  void* derived_this = static_cast<void*>(static_cast<usertype_storage<T>*>(this));
24106  index_call_storage ics;
24107  ics.binding_data = b.data();
24108  ics.index = is_index || is_static_index ? &Binding::template call_with_<true, is_var_bind::value>
24109  : &Binding::template index_call_with_<true, is_var_bind::value>;
24110  ics.new_index = is_new_index || is_static_new_index ? &Binding::template call_with_<false, is_var_bind::value>
24111  : &Binding::template index_call_with_<false, is_var_bind::value>;
24112 
24113  string_for_each_metatable_func for_each_fx;
24114  for_each_fx.is_destruction = is_destruction;
24115  for_each_fx.is_index = is_index;
24116  for_each_fx.is_new_index = is_new_index;
24117  for_each_fx.is_static_index = is_static_index;
24118  for_each_fx.is_static_new_index = is_static_new_index;
24119  for_each_fx.poison_indexing = poison_indexing;
24120  for_each_fx.p_key = &s;
24121  for_each_fx.p_ics = &ics;
24122  if constexpr (is_lua_c_function_v<ValueU>) {
24123  for_each_fx.is_unqualified_lua_CFunction = true;
24124  for_each_fx.call_func = *static_cast<lua_CFunction*>(ics.binding_data);
24125  }
24126  else if constexpr (is_lua_reference_or_proxy_v<ValueU>) {
24127  for_each_fx.is_unqualified_lua_reference = true;
24128  for_each_fx.p_binding_ref = static_cast<reference*>(ics.binding_data);
24129  }
24130  else {
24131  for_each_fx.call_func = &b.template call<false, is_var_bind::value>;
24132  }
24133  for_each_fx.p_usb = this;
24134  for_each_fx.p_derived_usb = derived_this;
24135  for_each_fx.idx_call = &usertype_storage<T>::template index_call<false>;
24136  for_each_fx.new_idx_call = &usertype_storage<T>::template index_call<true>;
24137  for_each_fx.meta_idx_call = &usertype_storage<T>::template meta_index_call<false>;
24138  for_each_fx.meta_new_idx_call = &usertype_storage<T>::template meta_index_call<true>;
24139  for_each_fx.change_indexing = &usertype_storage_base::change_indexing;
24140  // set base index and base new_index
24141  // functions here
24142  if (is_index) {
24143  this->base_index.index = ics.index;
24144  this->base_index.binding_data = ics.binding_data;
24145  }
24146  if (is_new_index) {
24147  this->base_index.new_index = ics.new_index;
24148  this->base_index.new_binding_data = ics.binding_data;
24149  }
24150  if (is_static_index) {
24151  this->static_base_index.index = ics.index;
24152  this->static_base_index.binding_data = ics.binding_data;
24153  }
24154  if (is_static_new_index) {
24155  this->static_base_index.new_index = ics.new_index;
24156  this->static_base_index.new_binding_data = ics.binding_data;
24157  }
24158  this->for_each_table(L, for_each_fx);
24159  this->add_entry(s, std::move(ics));
24160  }
24161  else {
24162  // the reference-based implementation might compare poorly and hash
24163  // poorly in some cases...
24164  if constexpr (is_lua_reference_v<KeyU> && is_lua_reference_v<ValueU>) {
24165  if (key.get_type() == type::string) {
24166  stack::push(L, key);
24167  std::string string_key = stack::pop<std::string>(L);
24168  this->set<T>(L, string_key, std::forward<Value>(value));
24169  }
24170  else {
24171  lua_reference_func ref_additions_fx { key, value };
24172 
24173  this->for_each_table(L, ref_additions_fx);
24174  this->auxiliary_keys.insert_or_assign(std::forward<Key>(key), std::forward<Value>(value));
24175  }
24176  }
24177  else {
24178  reference ref_key = make_reference(L, std::forward<Key>(key));
24179  reference ref_value = make_reference(L, std::forward<Value>(value));
24180  lua_reference_func ref_additions_fx { ref_key, ref_value };
24181 
24182  this->for_each_table(L, ref_additions_fx);
24183  this->auxiliary_keys.insert_or_assign(std::move(ref_key), std::move(ref_value));
24184  }
24185  }
24186  }
24187 
24188  template <typename T>
24189  template <typename Key, typename Value>
24190  void usertype_storage<T>::set(lua_State* L, Key&& key, Value&& value) {
24191  static_cast<usertype_storage_base&>(*this).set<T>(L, std::forward<Key>(key), std::forward<Value>(value));
24192  }
24193 
24194  template <typename T>
24195  inline void clear_usertype_registry_names(lua_State* L) {
24196  using u_traits = usertype_traits<T>;
24197  using u_const_traits = usertype_traits<const T>;
24198  using u_unique_traits = usertype_traits<d::u<T>>;
24199  using u_ref_traits = usertype_traits<T*>;
24200  using u_const_ref_traits = usertype_traits<T const*>;
24201 
24202  stack_reference registry(L, raw_index(LUA_REGISTRYINDEX));
24203  registry.push();
24204  // eliminate all named entries for this usertype
24205  // in the registry (luaL_newmetatable does
24206  // [name] = new table
24207  // in registry upon creation
24208  stack::set_field(L, &u_traits::metatable()[0], lua_nil, registry.stack_index());
24209  stack::set_field(L, &u_const_traits::metatable()[0], lua_nil, registry.stack_index());
24210  stack::set_field(L, &u_const_ref_traits::metatable()[0], lua_nil, registry.stack_index());
24211  stack::set_field(L, &u_ref_traits::metatable()[0], lua_nil, registry.stack_index());
24212  stack::set_field(L, &u_unique_traits::metatable()[0], lua_nil, registry.stack_index());
24213  registry.pop();
24214  }
24215 
24216  template <typename T>
24217  inline int destroy_usertype_storage(lua_State* L) noexcept {
24218  clear_usertype_registry_names<T>(L);
24219  return detail::user_alloc_destroy<usertype_storage<T>>(L);
24220  }
24221 
24222  template <typename T>
24223  inline usertype_storage<T>& create_usertype_storage(lua_State* L) {
24224  const char* gcmetakey = &usertype_traits<T>::gc_table()[0];
24225 
24226  // Make sure userdata's memory is properly in lua first,
24227  // otherwise all the light userdata we make later will become invalid
24228  int usertype_storage_push_count = stack::push<user<usertype_storage<T>>>(L, no_metatable, L);
24229  stack_reference usertype_storage_ref(L, -usertype_storage_push_count);
24230 
24231  // create and push onto the stack a table to use as metatable for this GC
24232  // we create a metatable to attach to the regular gc_table
24233  // so that the destructor is called for the usertype storage
24234  int usertype_storage_metatabe_count = stack::push(L, new_table(0, 1));
24235  stack_reference usertype_storage_metatable(L, -usertype_storage_metatabe_count);
24236  // set the destroyion routine on the metatable
24237  stack::set_field(L, meta_function::garbage_collect, &destroy_usertype_storage<T>, usertype_storage_metatable.stack_index());
24238  // set the metatable on the usertype storage userdata
24239  stack::set_field(L, metatable_key, usertype_storage_metatable, usertype_storage_ref.stack_index());
24240  usertype_storage_metatable.pop();
24241 
24242  // set the usertype storage and its metatable
24243  // into the global table...
24244  stack::set_field<true>(L, gcmetakey, usertype_storage_ref);
24245  usertype_storage_ref.pop();
24246 
24247  // then retrieve the lua-stored version so we have a well-pinned
24248  // reference that does not die
24249  stack::get_field<true>(L, gcmetakey);
24250  usertype_storage<T>& target_umt = stack::pop<user<usertype_storage<T>>>(L);
24251  return target_umt;
24252  }
24253 
24254  inline optional<usertype_storage_base&> maybe_as_usertype_storage_base(lua_State* L, int index) {
24255  if (type_of(L, index) != type::lightuserdata) {
24256  return nullopt;
24257  }
24258  usertype_storage_base& base_storage = *static_cast<usertype_storage_base*>(stack::get<void*>(L, index));
24259  return base_storage;
24260  }
24261 
24262  inline optional<usertype_storage_base&> maybe_get_usertype_storage_base_inside(lua_State* L, int index) {
24263  // okay, maybe we're looking at a table that is nested?
24264  if (type_of(L, index) != type::table) {
24265  return nullopt;
24266  }
24267  stack::get_field(L, meta_function::storage, index);
24268  auto maybe_storage_base = maybe_as_usertype_storage_base(L, -1);
24269  lua_pop(L, 1);
24270  return maybe_storage_base;
24271  }
24272 
24273  inline optional<usertype_storage_base&> maybe_get_usertype_storage_base(lua_State* L, int index) {
24274  // If we can get the index directly as this type, go for it
24275  auto maybe_already_is_usertype_storage_base = maybe_as_usertype_storage_base(L, index);
24276  if (maybe_already_is_usertype_storage_base) {
24277  return maybe_already_is_usertype_storage_base;
24278  }
24279  return maybe_get_usertype_storage_base_inside(L, index);
24280  }
24281 
24282  inline optional<usertype_storage_base&> maybe_get_usertype_storage_base(lua_State* L, const char* gcmetakey) {
24283  stack::get_field<true>(L, gcmetakey);
24284  auto maybe_storage = maybe_as_usertype_storage_base(L, lua_gettop(L));
24285  lua_pop(L, 1);
24286  return maybe_storage;
24287  }
24288 
24289  inline usertype_storage_base& get_usertype_storage_base(lua_State* L, const char* gcmetakey) {
24290  stack::get_field<true>(L, gcmetakey);
24291  stack::record tracking;
24292  usertype_storage_base& target_umt = stack::stack_detail::unchecked_unqualified_get<user<usertype_storage_base>>(L, -1, tracking);
24293  lua_pop(L, 1);
24294  return target_umt;
24295  }
24296 
24297  template <typename T>
24298  inline optional<usertype_storage<T>&> maybe_get_usertype_storage(lua_State* L) {
24299  const char* gcmetakey = &usertype_traits<T>::gc_table()[0];
24300  stack::get_field<true>(L, gcmetakey);
24301  int target = lua_gettop(L);
24302  if (!stack::check<user<usertype_storage<T>>>(L, target)) {
24303  return nullopt;
24304  }
24305  usertype_storage<T>& target_umt = stack::pop<user<usertype_storage<T>>>(L);
24306  return target_umt;
24307  }
24308 
24309  template <typename T>
24310  inline usertype_storage<T>& get_usertype_storage(lua_State* L) {
24311  const char* gcmetakey = &usertype_traits<T>::gc_table()[0];
24312  stack::get_field<true>(L, gcmetakey);
24313  usertype_storage<T>& target_umt = stack::pop<user<usertype_storage<T>>>(L);
24314  return target_umt;
24315  }
24316 
24317  template <typename T>
24318  inline void clear_usertype_storage(lua_State* L) {
24319  using u_traits = usertype_traits<T>;
24320 
24321  const char* gcmetakey = &u_traits::gc_table()[0];
24322  stack::get_field<true>(L, gcmetakey);
24323  if (!stack::check<user<usertype_storage<T>>>(L)) {
24324  lua_pop(L, 1);
24325  return;
24326  }
24327  usertype_storage<T>& target_umt = stack::pop<user<usertype_storage<T>>>(L);
24328  target_umt.clear();
24329 
24330  clear_usertype_registry_names<T>(L);
24331 
24332  stack::set_field<true>(L, gcmetakey, lua_nil);
24333  }
24334 
24335  template <typename T, automagic_flags enrollment_flags>
24336  inline int register_usertype(lua_State* L_, automagic_enrollments enrollments_ = {}) {
24337  using u_traits = usertype_traits<T>;
24338  using u_const_traits = usertype_traits<const T>;
24339  using u_unique_traits = usertype_traits<d::u<T>>;
24340  using u_ref_traits = usertype_traits<T*>;
24341  using u_const_ref_traits = usertype_traits<T const*>;
24342  using uts = usertype_storage<T>;
24343 
24344  // always have __new_index point to usertype_storage method
24345  // have __index always point to regular fast-lookup
24346  // meta_method table
24347  // if __new_index is invoked, runtime-swap
24348  // to slow __index if necessary
24349  // (no speed penalty because function calls
24350  // are all read-only -- only depend on __index
24351  // to retrieve function and then call happens VIA Lua)
24352 
24353  // __type entry:
24354  // table contains key -> value lookup,
24355  // where key is entry in metatable
24356  // and value is type information as a string as
24357  // best as we can give it
24358 
24359  // name entry:
24360  // string that contains raw class name,
24361  // as defined from C++
24362 
24363  // is entry:
24364  // checks if argument supplied is of type T
24365 
24366  // __storage entry:
24367  // a light userdata pointing to the storage
24368  // mostly to enable this new abstraction
24369  // to not require the type name `T`
24370  // to get at the C++ usertype storage within
24371 
24372  // we then let typical definitions potentially override these intrinsics
24373  // it's the user's fault if they override things or screw them up:
24374  // these names have been reserved and documented since sol2
24375 
24376  // STEP 0: tell the old usertype (if it exists)
24377  // to fuck off
24378  clear_usertype_storage<T>(L_);
24379 
24380  // STEP 1: Create backing store for usertype storage
24381  // Pretty much the most important step.
24382  // STEP 2: Create Lua tables used for fast method indexing.
24383  // This is done inside of the storage table's constructor
24384  usertype_storage<T>& storage = create_usertype_storage<T>(L_);
24385  usertype_storage_base& base_storage = storage;
24386  void* light_storage = static_cast<void*>(&storage);
24387  void* light_base_storage = static_cast<void*>(&base_storage);
24388 
24389  // STEP 3: set up GC escape hatch table entirely
24390  storage.gc_names_table.push(L_);
24391  stateless_stack_reference gnt(L_, -1);
24392  stack::set_field(L_, submetatable_type::named, &u_traits::gc_table()[0], gnt.stack_index());
24393  stack::set_field(L_, submetatable_type::const_value, &u_const_traits::metatable()[0], gnt.stack_index());
24394  stack::set_field(L_, submetatable_type::const_reference, &u_const_ref_traits::metatable()[0], gnt.stack_index());
24395  stack::set_field(L_, submetatable_type::reference, &u_ref_traits::metatable()[0], gnt.stack_index());
24396  stack::set_field(L_, submetatable_type::unique, &u_unique_traits::metatable()[0], gnt.stack_index());
24397  stack::set_field(L_, submetatable_type::value, &u_traits::metatable()[0], gnt.stack_index());
24398  gnt.pop(L_);
24399 
24400  // STEP 4: add some useful information to the type table
24401  stateless_stack_reference stacked_type_table(L_, -storage.type_table.push(L_));
24402  stack::set_field(L_, "name", detail::demangle<T>(), stacked_type_table.stack_index());
24403  stack::set_field(L_, "is", &detail::is_check<T>, stacked_type_table.stack_index());
24404  stacked_type_table.pop(L_);
24405 
24406  // STEP 5: create and hook up metatable,
24407  // add intrinsics
24408  // this one is the actual meta-handling table,
24409  // the next one will be the one for
24410  int for_each_backing_metatable_calls = 0;
24411  auto for_each_backing_metatable = [&](lua_State* L_, submetatable_type smt_, stateless_reference& fast_index_table_) {
24412  // Pointer types, AKA "references" from C++
24413  const char* metakey = nullptr;
24414  switch (smt_) {
24415  case submetatable_type::const_value:
24416  metakey = &u_const_traits::metatable()[0];
24417  break;
24418  case submetatable_type::reference:
24419  metakey = &u_ref_traits::metatable()[0];
24420  break;
24421  case submetatable_type::unique:
24422  metakey = &u_unique_traits::metatable()[0];
24423  break;
24424  case submetatable_type::const_reference:
24425  metakey = &u_const_ref_traits::metatable()[0];
24426  break;
24427  case submetatable_type::named:
24428  metakey = &u_traits::user_metatable()[0];
24429  break;
24430  case submetatable_type::value:
24431  default:
24432  metakey = &u_traits::metatable()[0];
24433  break;
24434  }
24435 
24436  luaL_newmetatable(L_, metakey);
24437  if (smt_ == submetatable_type::named) {
24438  // the named table itself
24439  // gets the associated name value
24440  storage.named_metatable.reset(L_, -1);
24441  lua_pop(L_, 1);
24442  // but the thing we perform the methods on
24443  // is still the metatable of the named
24444  // table
24445  lua_createtable(L_, 0, 6);
24446  }
24447  stateless_stack_reference t(L_, -1);
24448  fast_index_table_.reset(L_, t.stack_index());
24449  stack::set_field<false, true>(L_, meta_function::type, storage.type_table, t.stack_index());
24450  // destructible? serialize default destructor here
24451  // otherwise, not destructible: serialize a "hey you messed up"
24452  switch (smt_) {
24453  case submetatable_type::const_reference:
24454  case submetatable_type::reference:
24455  case submetatable_type::named:
24456  break;
24457  case submetatable_type::unique:
24458  if constexpr (std::is_destructible_v<T>) {
24459  stack::set_field<false, true>(L_, meta_function::garbage_collect, &detail::unique_destroy<T>, t.stack_index());
24460  }
24461  else {
24462  stack::set_field<false, true>(L_, meta_function::garbage_collect, &detail::cannot_destroy<T>, t.stack_index());
24463  }
24464  break;
24465  case submetatable_type::value:
24466  case submetatable_type::const_value:
24467  default:
24468  if constexpr (std::is_destructible_v<T>) {
24469  stack::set_field<false, true>(L_, meta_function::garbage_collect, detail::make_destructor<T>(), t.stack_index());
24470  }
24471  else {
24472  stack::set_field<false, true>(L_, meta_function::garbage_collect, &detail::cannot_destroy<T>, t.stack_index());
24473  }
24474  break;
24475  }
24476 
24477  static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function),
24478  "The size of this data pointer is too small to fit the inheritance checking function: file a bug "
24479  "report.");
24480  static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function),
24481  "The size of this data pointer is too small to fit the inheritance checking function: file a bug "
24482  "report.");
24483  stack::set_field<false, true>(L_, detail::base_class_check_key(), reinterpret_cast<void*>(&detail::inheritance<T>::type_check), t.stack_index());
24484  stack::set_field<false, true>(L_, detail::base_class_cast_key(), reinterpret_cast<void*>(&detail::inheritance<T>::type_cast), t.stack_index());
24485 
24486  auto prop_fx = detail::properties_enrollment_allowed(for_each_backing_metatable_calls, storage.properties, enrollments_);
24487  auto insert_fx = [&L_, &t, &storage](meta_function mf, lua_CFunction reg) {
24488  stack::set_field<false, true>(L_, mf, reg, t.stack_index());
24489  storage.properties[static_cast<std::size_t>(mf)] = true;
24490  };
24491  detail::insert_default_registrations<T>(insert_fx, prop_fx);
24492 
24493  // There are no variables, so serialize the fast function stuff
24494  // be sure to reset the index stuff to the non-fast version
24495  // if the user ever adds something later!
24496  if (smt_ == submetatable_type::named) {
24497  // add escape hatch storage pointer and gc names
24498  stack::set_field<false, true>(L_, meta_function::storage, light_base_storage, t.stack_index());
24499  stack::set_field<false, true>(L_, meta_function::gc_names, storage.gc_names_table, t.stack_index());
24500 
24501  // fancy new_indexing when using the named table
24502  {
24503  absolute_index named_metatable_index(L_, -storage.named_metatable.push(L_));
24504  stack::set_field<false, true>(L_, metatable_key, t, named_metatable_index);
24505  storage.named_metatable.pop(L_);
24506  }
24507  stack_reference stack_metametatable(L_, -storage.named_index_table.push(L_));
24508  stack::set_field<false, true>(L_,
24509  meta_function::index,
24510  make_closure(uts::template meta_index_call<false>, nullptr, light_storage, light_base_storage, nullptr, toplevel_magic),
24511  stack_metametatable.stack_index());
24512  stack::set_field<false, true>(L_,
24513  meta_function::new_index,
24514  make_closure(uts::template meta_index_call<true>, nullptr, light_storage, light_base_storage, nullptr, toplevel_magic),
24515  stack_metametatable.stack_index());
24516  stack_metametatable.pop();
24517  }
24518  else {
24519  // otherwise just plain for index,
24520  // and elaborated for new_index
24521  stack::set_field<false, true>(L_, meta_function::index, t, t.stack_index());
24522  stack::set_field<false, true>(L_,
24523  meta_function::new_index,
24524  make_closure(uts::template index_call<true>, nullptr, light_storage, light_base_storage, nullptr, toplevel_magic),
24525  t.stack_index());
24526  storage.is_using_new_index = true;
24527  }
24528 
24529  ++for_each_backing_metatable_calls;
24530  fast_index_table_.reset(L_, t.stack_index());
24531  t.pop(L_);
24532  };
24533 
24534  storage.for_each_table(L_, for_each_backing_metatable);
24535 
24536  // can only use set AFTER we initialize all the metatables
24537  if constexpr (std::is_default_constructible_v<T> && has_flag(enrollment_flags, automagic_flags::default_constructor)) {
24538  if (enrollments_.default_constructor) {
24539  storage.set(L_, meta_function::construct, constructors<T()>());
24540  }
24541  }
24542 
24543  // return the named metatable we want names linked into
24544  storage.named_metatable.push(L_);
24545  return 1;
24546  }
24547 }} // namespace sol::u_detail
24548 
24549 // end of sol/usertype_storage.hpp
24550 
24551 // beginning of sol/usertype_proxy.hpp
24552 
24553 namespace sol {
24554  template <typename Table, typename Key>
24555  struct usertype_proxy : public proxy_base<usertype_proxy<Table, Key>> {
24556  private:
24557  using key_type = detail::proxy_key_t<Key>;
24558 
24559  template <typename T, std::size_t... I>
24560  decltype(auto) tuple_get(std::index_sequence<I...>) const& {
24561  return tbl.template traverse_get<T>(std::get<I>(key)...);
24562  }
24563 
24564  template <typename T, std::size_t... I>
24565  decltype(auto) tuple_get(std::index_sequence<I...>) && {
24566  return tbl.template traverse_get<T>(std::get<I>(std::move(key))...);
24567  }
24568 
24569  template <std::size_t... I, typename T>
24570  void tuple_set(std::index_sequence<I...>, T&& value) & {
24571  if constexpr (sizeof...(I) > 1) {
24572  tbl.traverse_set(std::get<I>(key)..., std::forward<T>(value));
24573  }
24574  else {
24575  tbl.set(std::get<I>(key)..., std::forward<T>(value));
24576  }
24577  }
24578 
24579  template <std::size_t... I, typename T>
24580  void tuple_set(std::index_sequence<I...>, T&& value) && {
24581  if constexpr (sizeof...(I) > 1) {
24582  tbl.traverse_set(std::get<I>(std::move(key))..., std::forward<T>(value));
24583  }
24584  else {
24585  tbl.set(std::get<I>(std::move(key))..., std::forward<T>(value));
24586  }
24587  }
24588 
24589  public:
24590  Table tbl;
24591  key_type key;
24592 
24593  template <typename T>
24594  usertype_proxy(Table table, T&& k) : tbl(table), key(std::forward<T>(k)) {
24595  }
24596 
24597  template <typename T>
24598  usertype_proxy& set(T&& item) & {
24599  using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
24600  tuple_set(idx_seq(), std::forward<T>(item));
24601  return *this;
24602  }
24603 
24604  template <typename T>
24605  usertype_proxy&& set(T&& item) && {
24606  using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
24607  std::move(*this).tuple_set(idx_seq(), std::forward<T>(item));
24608  return std::move(*this);
24609  }
24610 
24611  template <typename T>
24612  usertype_proxy& operator=(T&& other) & {
24613  return set(std::forward<T>(other));
24614  }
24615 
24616  template <typename T>
24617  usertype_proxy&& operator=(T&& other) && {
24618  return std::move(*this).set(std::forward<T>(other));
24619  }
24620 
24621  template <typename T>
24622  usertype_proxy& operator=(std::initializer_list<T> other) & {
24623  return set(std::move(other));
24624  }
24625 
24626  template <typename T>
24627  usertype_proxy&& operator=(std::initializer_list<T> other) && {
24628  return std::move(*this).set(std::move(other));
24629  }
24630 
24631  template <typename T>
24632  decltype(auto) get() const& {
24633  using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
24634  return tuple_get<T>(idx_seq());
24635  }
24636 
24637  template <typename T>
24638  decltype(auto) get() && {
24639  using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
24640  return std::move(*this).template tuple_get<T>(idx_seq());
24641  }
24642 
24643  template <typename K>
24644  decltype(auto) operator[](K&& k) const& {
24645  auto keys = meta::tuplefy(key, std::forward<K>(k));
24646  return usertype_proxy<Table, decltype(keys)>(tbl, std::move(keys));
24647  }
24648 
24649  template <typename K>
24650  decltype(auto) operator[](K&& k) & {
24651  auto keys = meta::tuplefy(key, std::forward<K>(k));
24652  return usertype_proxy<Table, decltype(keys)>(tbl, std::move(keys));
24653  }
24654 
24655  template <typename K>
24656  decltype(auto) operator[](K&& k) && {
24657  auto keys = meta::tuplefy(std::move(key), std::forward<K>(k));
24658  return usertype_proxy<Table, decltype(keys)>(tbl, std::move(keys));
24659  }
24660 
24661  template <typename... Ret, typename... Args>
24662  decltype(auto) call(Args&&... args) {
24663 #if !defined(__clang__) && defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 191200000
24664  // MSVC is ass sometimes
24665  return get<function>().call<Ret...>(std::forward<Args>(args)...);
24666 #else
24667  return get<function>().template call<Ret...>(std::forward<Args>(args)...);
24668 #endif
24669  }
24670 
24671  template <typename... Args>
24672  decltype(auto) operator()(Args&&... args) {
24673  return call<>(std::forward<Args>(args)...);
24674  }
24675 
24676  bool valid() const {
24677  auto pp = stack::push_pop(tbl);
24678  auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(lua_state(), key, lua_gettop(lua_state()));
24679  lua_pop(lua_state(), p.levels);
24680  return p;
24681  }
24682 
24683  int push() const noexcept {
24684  return push(this->lua_state());
24685  }
24686 
24687  int push(lua_State* L) const noexcept {
24688  return get<reference>().push(L);
24689  }
24690 
24691  type get_type() const {
24692  type t = type::none;
24693  auto pp = stack::push_pop(tbl);
24694  auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(lua_state(), key, lua_gettop(lua_state()));
24695  if (p) {
24696  t = type_of(lua_state(), -1);
24697  }
24698  lua_pop(lua_state(), p.levels);
24699  return t;
24700  }
24701 
24702  lua_State* lua_state() const {
24703  return tbl.lua_state();
24704  }
24705  };
24706 } // namespace sol
24707 
24708 // end of sol/usertype_proxy.hpp
24709 
24710 // beginning of sol/metatable.hpp
24711 
24712 // beginning of sol/table_core.hpp
24713 
24714 // beginning of sol/table_proxy.hpp
24715 
24716 namespace sol {
24717 
24718  template <typename Table, typename Key>
24719  struct table_proxy : public proxy_base<table_proxy<Table, Key>> {
24720  private:
24721  using key_type = detail::proxy_key_t<Key>;
24722 
24723  template <typename T, std::size_t... I>
24724  decltype(auto) tuple_get(std::index_sequence<I...>) const& {
24725  return tbl.template traverse_get<T>(std::get<I>(key)...);
24726  }
24727 
24728  template <typename T, std::size_t... I>
24729  decltype(auto) tuple_get(std::index_sequence<I...>) && {
24730  return tbl.template traverse_get<T>(std::get<I>(std::move(key))...);
24731  }
24732 
24733  template <std::size_t... I, typename T>
24734  void tuple_set(std::index_sequence<I...>, T&& value) & {
24735  tbl.traverse_set(std::get<I>(key)..., std::forward<T>(value));
24736  }
24737 
24738  template <std::size_t... I, typename T>
24739  void tuple_set(std::index_sequence<I...>, T&& value) && {
24740  tbl.traverse_set(std::get<I>(std::move(key))..., std::forward<T>(value));
24741  }
24742 
24743  auto setup_table(std::true_type) {
24744  auto p = stack::probe_get_field<std::is_same_v<meta::unqualified_t<Table>, global_table>>(lua_state(), key, tbl.stack_index());
24745  lua_pop(lua_state(), p.levels);
24746  return p;
24747  }
24748 
24749  bool is_valid(std::false_type) {
24750  auto pp = stack::push_pop(tbl);
24751  auto p = stack::probe_get_field<std::is_same_v<meta::unqualified_t<Table>, global_table>>(lua_state(), key, lua_gettop(lua_state()));
24752  lua_pop(lua_state(), p.levels);
24753  return p;
24754  }
24755 
24756  public:
24757  Table tbl;
24758  key_type key;
24759 
24760  template <typename T>
24761  table_proxy(Table table, T&& k) : tbl(table), key(std::forward<T>(k)) {
24762  }
24763 
24764  template <typename T>
24765  table_proxy& set(T&& item) & {
24766  tuple_set(std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>(), std::forward<T>(item));
24767  return *this;
24768  }
24769 
24770  template <typename T>
24771  table_proxy&& set(T&& item) && {
24772  std::move(*this).tuple_set(std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>(), std::forward<T>(item));
24773  return std::move(*this);
24774  }
24775 
24776  template <typename... Args>
24777  table_proxy& set_function(Args&&... args) & {
24778  tbl.set_function(key, std::forward<Args>(args)...);
24779  return *this;
24780  }
24781 
24782  template <typename... Args>
24783  table_proxy&& set_function(Args&&... args) && {
24784  tbl.set_function(std::move(key), std::forward<Args>(args)...);
24785  return std::move(*this);
24786  }
24787 
24788  template <typename T>
24789  table_proxy& operator=(T&& other) & {
24790  using Tu = meta::unwrap_unqualified_t<T>;
24791  if constexpr (!is_lua_reference_or_proxy_v<Tu> && meta::is_invocable_v<Tu>) {
24792  return set_function(std::forward<T>(other));
24793  }
24794  else {
24795  return set(std::forward<T>(other));
24796  }
24797  }
24798 
24799  template <typename T>
24800  table_proxy&& operator=(T&& other) && {
24801  using Tu = meta::unwrap_unqualified_t<T>;
24802  if constexpr (!is_lua_reference_or_proxy_v<Tu> && meta::is_invocable_v<Tu> && !detail::is_msvc_callable_rigged_v<T>) {
24803  return std::move(*this).set_function(std::forward<T>(other));
24804  }
24805  else {
24806  return std::move(*this).set(std::forward<T>(other));
24807  }
24808  }
24809 
24810  template <typename T>
24811  table_proxy& operator=(std::initializer_list<T> other) & {
24812  return set(std::move(other));
24813  }
24814 
24815  template <typename T>
24816  table_proxy&& operator=(std::initializer_list<T> other) && {
24817  return std::move(*this).set(std::move(other));
24818  }
24819 
24820  template <typename T>
24821  bool is() const {
24822  typedef decltype(get<T>()) U;
24823  optional<U> option = this->get<optional<U>>();
24824  return option.has_value();
24825  }
24826 
24827  template <typename T>
24828  decltype(auto) get() const& {
24829  using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
24830  return tuple_get<T>(idx_seq());
24831  }
24832 
24833  template <typename T>
24834  decltype(auto) get() && {
24835  using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
24836  return std::move(*this).template tuple_get<T>(idx_seq());
24837  }
24838 
24839  template <typename T>
24840  decltype(auto) get_or(T&& otherwise) const {
24841  typedef decltype(get<T>()) U;
24842  optional<U> option = get<optional<U>>();
24843  if (option) {
24844  return static_cast<U>(option.value());
24845  }
24846  return static_cast<U>(std::forward<T>(otherwise));
24847  }
24848 
24849  template <typename T, typename D>
24850  decltype(auto) get_or(D&& otherwise) const {
24851  optional<T> option = get<optional<T>>();
24852  if (option) {
24853  return static_cast<T>(option.value());
24854  }
24855  return static_cast<T>(std::forward<D>(otherwise));
24856  }
24857 
24858  template <typename T>
24859  decltype(auto) get_or_create() {
24860  return get_or_create<T>(new_table());
24861  }
24862 
24863  template <typename T, typename Otherwise>
24864  decltype(auto) get_or_create(Otherwise&& other) {
24865  if (!this->valid()) {
24866  this->set(std::forward<Otherwise>(other));
24867  }
24868  return get<T>();
24869  }
24870 
24871  template <typename K>
24872  decltype(auto) operator[](K&& k) const& {
24873  auto keys = meta::tuplefy(key, std::forward<K>(k));
24874  return table_proxy<Table, decltype(keys)>(tbl, std::move(keys));
24875  }
24876 
24877  template <typename K>
24878  decltype(auto) operator[](K&& k) & {
24879  auto keys = meta::tuplefy(key, std::forward<K>(k));
24880  return table_proxy<Table, decltype(keys)>(tbl, std::move(keys));
24881  }
24882 
24883  template <typename K>
24884  decltype(auto) operator[](K&& k) && {
24885  auto keys = meta::tuplefy(std::move(key), std::forward<K>(k));
24886  return table_proxy<Table, decltype(keys)>(tbl, std::move(keys));
24887  }
24888 
24889  template <typename... Ret, typename... Args>
24890  decltype(auto) call(Args&&... args) {
24891  lua_State* L = this->lua_state();
24892  push(L);
24893  int idx = lua_gettop(L);
24894  stack_aligned_function func(L, idx);
24895  return func.call<Ret...>(std::forward<Args>(args)...);
24896  }
24897 
24898  template <typename... Args>
24899  decltype(auto) operator()(Args&&... args) {
24900  return call<>(std::forward<Args>(args)...);
24901  }
24902 
24903  bool valid() const {
24904  auto pp = stack::push_pop(tbl);
24905  auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(lua_state(), key, lua_gettop(lua_state()));
24906  lua_pop(lua_state(), p.levels);
24907  return p;
24908  }
24909 
24910  int push() const noexcept {
24911  return push(this->lua_state());
24912  }
24913 
24914  int push(lua_State* L) const noexcept {
24915  if constexpr (std::is_same_v<meta::unqualified_t<Table>, global_table> || is_stack_table_v<meta::unqualified_t<Table>>) {
24916  auto pp = stack::push_pop<true>(tbl);
24917  int tableindex = pp.index_of(tbl);
24918  int top_index = lua_gettop(L);
24919  stack::get_field<true>(lua_state(), key, tableindex);
24920  lua_replace(L, top_index + 1);
24921  lua_settop(L, top_index + 1);
24922  }
24923  else {
24924  auto pp = stack::push_pop<false>(tbl);
24925  int tableindex = pp.index_of(tbl);
24926  int aftertableindex = lua_gettop(L);
24927  stack::get_field<false>(lua_state(), key, tableindex);
24928  lua_replace(L, tableindex);
24929  lua_settop(L, aftertableindex + 1);
24930  }
24931  return 1;
24932  }
24933 
24934  type get_type() const {
24935  type t = type::none;
24936  auto pp = stack::push_pop(tbl);
24937  auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(lua_state(), key, lua_gettop(lua_state()));
24938  if (p) {
24939  t = type_of(lua_state(), -1);
24940  }
24941  lua_pop(lua_state(), p.levels);
24942  return t;
24943  }
24944 
24945  lua_State* lua_state() const {
24946  return tbl.lua_state();
24947  }
24948 
24949  table_proxy& force() {
24950  if (!this->valid()) {
24951  this->set(new_table());
24952  }
24953  return *this;
24954  }
24955  };
24956 
24957  template <typename Table, typename Key, typename T>
24958  inline bool operator==(T&& left, const table_proxy<Table, Key>& right) {
24959  using G = decltype(stack::get<T>(nullptr, 0));
24960  return right.template get<optional<G>>() == left;
24961  }
24962 
24963  template <typename Table, typename Key, typename T>
24964  inline bool operator==(const table_proxy<Table, Key>& right, T&& left) {
24965  using G = decltype(stack::get<T>(nullptr, 0));
24966  return right.template get<optional<G>>() == left;
24967  }
24968 
24969  template <typename Table, typename Key, typename T>
24970  inline bool operator!=(T&& left, const table_proxy<Table, Key>& right) {
24971  using G = decltype(stack::get<T>(nullptr, 0));
24972  return right.template get<optional<G>>() != left;
24973  }
24974 
24975  template <typename Table, typename Key, typename T>
24976  inline bool operator!=(const table_proxy<Table, Key>& right, T&& left) {
24977  using G = decltype(stack::get<T>(nullptr, 0));
24978  return right.template get<optional<G>>() != left;
24979  }
24980 
24981  template <typename Table, typename Key>
24982  inline bool operator==(lua_nil_t, const table_proxy<Table, Key>& right) {
24983  return !right.valid();
24984  }
24985 
24986  template <typename Table, typename Key>
24987  inline bool operator==(const table_proxy<Table, Key>& right, lua_nil_t) {
24988  return !right.valid();
24989  }
24990 
24991  template <typename Table, typename Key>
24992  inline bool operator!=(lua_nil_t, const table_proxy<Table, Key>& right) {
24993  return right.valid();
24994  }
24995 
24996  template <typename Table, typename Key>
24997  inline bool operator!=(const table_proxy<Table, Key>& right, lua_nil_t) {
24998  return right.valid();
24999  }
25000 
25001  template <bool b>
25002  template <typename Super>
25004  basic_reference<b> v = r;
25005  this->operator=(std::move(v));
25006  return *this;
25007  }
25008 
25009  template <bool b>
25010  template <typename Super>
25012  basic_reference<b> v = r;
25013  this->operator=(std::move(v));
25014  return *this;
25015  }
25016 
25017  namespace stack {
25018  template <typename Table, typename Key>
25020  static int push(lua_State* L, const table_proxy<Table, Key>& p) {
25021  return p.push(L);
25022  }
25023  };
25024  } // namespace stack
25025 } // namespace sol
25026 
25027 // end of sol/table_proxy.hpp
25028 
25029 // beginning of sol/table_iterator.hpp
25030 
25031 #include <iterator>
25032 
25033 namespace sol {
25034 
25035  template <typename reference_type>
25037  public:
25038  typedef object key_type;
25039  typedef object mapped_type;
25040  typedef std::pair<object, object> value_type;
25041  typedef std::input_iterator_tag iterator_category;
25042  typedef std::ptrdiff_t difference_type;
25043  typedef value_type* pointer;
25044  typedef value_type& reference;
25045  typedef const value_type& const_reference;
25046 
25047  private:
25048  std::pair<object, object> kvp;
25049  reference_type ref;
25050  int tableidx = 0;
25051  int keyidx = 0;
25052  std::ptrdiff_t idx = 0;
25053 
25054  public:
25055  basic_table_iterator() noexcept : keyidx(-1), idx(-1) {
25056  }
25057 
25058  basic_table_iterator(reference_type x) noexcept : ref(std::move(x)) {
25059  ref.push();
25060  tableidx = lua_gettop(ref.lua_state());
25061  stack::push(ref.lua_state(), lua_nil);
25062  this->operator++();
25063  if (idx == -1) {
25064  return;
25065  }
25066  --idx;
25067  }
25068 
25069  basic_table_iterator& operator++() noexcept {
25070  if (idx == -1)
25071  return *this;
25072 
25073  if (lua_next(ref.lua_state(), tableidx) == 0) {
25074  idx = -1;
25075  keyidx = -1;
25076  return *this;
25077  }
25078  ++idx;
25079  kvp.first = object(ref.lua_state(), -2);
25080  kvp.second = object(ref.lua_state(), -1);
25081  lua_pop(ref.lua_state(), 1);
25082  // leave key on the stack
25083  keyidx = lua_gettop(ref.lua_state());
25084  return *this;
25085  }
25086 
25087  basic_table_iterator operator++(int) noexcept {
25088  auto saved = *this;
25089  this->operator++();
25090  return saved;
25091  }
25092 
25093  reference operator*() const noexcept {
25094  return const_cast<reference>(kvp);
25095  }
25096 
25097  bool operator==(const basic_table_iterator& right) const noexcept {
25098  return idx == right.idx;
25099  }
25100 
25101  bool operator!=(const basic_table_iterator& right) const noexcept {
25102  return idx != right.idx;
25103  }
25104 
25106  if (keyidx != -1) {
25107  stack::remove(ref.lua_state(), keyidx, 1);
25108  }
25109  if (ref.lua_state() != nullptr && ref.valid()) {
25110  stack::remove(ref.lua_state(), tableidx, 1);
25111  }
25112  }
25113  };
25114 
25115 } // namespace sol
25116 
25117 // end of sol/table_iterator.hpp
25118 
25119 // beginning of sol/pairs_iterator.hpp
25120 
25121 // beginning of sol/stack/detail/pairs.hpp
25122 
25123 #include <optional>
25124 
25125 namespace sol { namespace stack { namespace stack_detail {
25126 
25127  inline bool maybe_push_lua_next_function(lua_State* L_) {
25128  stack::get_field<true, false>(L_, "next");
25129  bool is_next = stack::check<protected_function>(L_);
25130  if (is_next) {
25131  return true;
25132  }
25133  stack::get_field<true, false>(L_, "table");
25134  stack::record tracking{};
25135  if (!stack::loose_table_check(L_, -1, &no_panic, tracking)) {
25136  return false;
25137  }
25138  lua_getfield(L_, -1, "next");
25139  bool is_table_next_func = stack::check<protected_function>(L_, -1);
25140  if (is_table_next_func) {
25141  return true;
25142  }
25143  lua_pop(L_, 1);
25144  return false;
25145  }
25146 
25147  inline std::optional<protected_function> find_lua_next_function(lua_State* L_) {
25148  if (maybe_push_lua_next_function(L_)) {
25149  return stack::pop<protected_function>(L_);
25150  }
25151  return std::nullopt;
25152  }
25153 
25154  inline int c_lua_next(lua_State* L_) noexcept {
25155  stack_reference table_stack_ref(L_, raw_index(1));
25156  stateless_stack_reference key_stack_ref(L_, raw_index(2));
25157  int result = lua_next(table_stack_ref.lua_state(), table_stack_ref.stack_index());
25158  if (result == 0) {
25159  stack::push(L_, lua_nil);
25160  return 1;
25161  }
25162  return 2;
25163  }
25164 
25165  inline int readonly_pairs(lua_State* L_) noexcept {
25166  int pushed = 0;
25167  if (!maybe_push_lua_next_function(L_)) {
25168  // we do not have the "next" function in the global namespace
25169  // from the "table" global entiry, use our own
25170  pushed += stack::push(L_, &c_lua_next);
25171  }
25172  else {
25173  pushed += 1;
25174  }
25175  int metatable_exists = lua_getmetatable(L_, 1);
25176  sol_c_assert(metatable_exists == 1);
25177  const auto& index_key = to_string(sol::meta_function::index);
25178  lua_getfield(L_, lua_gettop(L_), index_key.c_str());
25179  lua_remove(L_, -2);
25180  pushed += 1;
25181  pushed += stack::push(L_, lua_nil);
25182  return pushed;
25183  }
25184 
25185 }}} // sol::stack::stack_detail
25186 
25187 // end of sol/stack/detail/pairs.hpp
25188 
25189 namespace sol {
25190 
25191  struct pairs_sentinel { };
25192 
25194  private:
25195  inline static constexpr int empty_key_index = -1;
25196 
25197  public:
25198  using key_type = object;
25199  using mapped_type = object;
25200  using value_type = std::pair<object, object>;
25201  using iterator_category = std::input_iterator_tag;
25202  using difference_type = std::ptrdiff_t;
25203  using pointer = value_type*;
25204  using const_pointer = value_type const*;
25205  using reference = value_type&;
25206  using const_reference = const value_type&;
25207 
25208  pairs_iterator() noexcept
25209  : m_L(nullptr)
25210  , m_next_function_ref(lua_nil)
25211  , m_table_ref(lua_nil)
25212  , m_cached_key_value_pair({ lua_nil, lua_nil })
25213  , m_key_index(empty_key_index)
25214  , m_iteration_index(0) {
25215  }
25216 
25217  pairs_iterator(const pairs_iterator&) = delete;
25218  pairs_iterator& operator=(const pairs_iterator&) = delete;
25219 
25220  pairs_iterator(pairs_iterator&& right) noexcept
25221  : m_L(right.m_L)
25222  , m_next_function_ref(std::move(right.m_next_function_ref))
25223  , m_table_ref(std::move(right.m_table_ref))
25224  , m_cached_key_value_pair(std::move(right.m_cached_key_value_pair))
25225  , m_key_index(right.m_key_index)
25226  , m_iteration_index(right.m_iteration_index) {
25227  right.m_key_index = empty_key_index;
25228  }
25229 
25230  pairs_iterator& operator=(pairs_iterator&& right) noexcept {
25231  m_L = right.m_L;
25232  m_next_function_ref = std::move(right.m_next_function_ref);
25233  m_table_ref = std::move(right.m_table_ref);
25234  m_cached_key_value_pair = std::move(right.m_cached_key_value_pair);
25235  m_key_index = right.m_key_index;
25236  m_iteration_index = right.m_iteration_index;
25237  right.m_key_index = empty_key_index;
25238  return *this;
25239  }
25240 
25241  template <typename Source>
25242  pairs_iterator(const Source& source_) noexcept : m_L(source_.lua_state()), m_key_index(empty_key_index), m_iteration_index(0) {
25243  if (m_L == nullptr || !source_.valid()) {
25244  m_key_index = empty_key_index;
25245  return;
25246  }
25247  int source_index = -source_.push(m_L);
25248  int abs_source_index = lua_absindex(m_L, source_index);
25249  int metatable_exists = lua_getmetatable(m_L, abs_source_index);
25250  lua_remove(m_L, abs_source_index);
25251  if (metatable_exists == 1) {
25252  // just has a metatable, but does it have __pairs ?
25253  stack_reference metatable(m_L, raw_index(abs_source_index));
25254  stack::get_field<is_global_table_v<Source>, true>(m_L, meta_function::pairs, metatable.stack_index());
25255  optional<protected_function> maybe_pairs_function = stack::pop<optional<protected_function>>(m_L);
25256  if (maybe_pairs_function.has_value()) {
25257  protected_function& pairs_function = *maybe_pairs_function;
25258  protected_function_result next_fn_and_table_and_first_key = pairs_function(source_);
25259  if (next_fn_and_table_and_first_key.valid()) {
25260  m_next_function_ref = next_fn_and_table_and_first_key.get<protected_function>(0);
25261  m_table_ref = next_fn_and_table_and_first_key.get<sol::reference>(1);
25262  m_key_index = next_fn_and_table_and_first_key.stack_index() - 1;
25263  // remove next function and table
25264  lua_remove(m_L, m_key_index);
25265  lua_remove(m_L, m_key_index);
25266  next_fn_and_table_and_first_key.abandon();
25267  lua_remove(m_L, abs_source_index);
25268  this->operator++();
25269  m_iteration_index = 0;
25270  return;
25271  }
25272  }
25273  }
25274 
25275  {
25276  auto maybe_next = stack::stack_detail::find_lua_next_function(m_L);
25277  if (maybe_next.has_value()) {
25278  m_next_function_ref = std::move(*maybe_next);
25279  m_table_ref = source_;
25280 
25281  stack::push(m_L, lua_nil);
25282  m_key_index = lua_gettop(m_L);
25283  this->operator++();
25284  m_iteration_index = 0;
25285  return;
25286  }
25287  }
25288 
25289  // okay, so none of the above worked and now we need to create
25290  // a shim / polyfill instead
25291  stack::push(m_L, &stack::stack_detail::c_lua_next);
25292  m_next_function_ref = stack::pop<protected_function>(m_L);
25293  m_table_ref = source_;
25294  stack::push(m_L, lua_nil);
25295  m_key_index = lua_gettop(m_L);
25296  this->operator++();
25297  m_iteration_index = 0;
25298  }
25299 
25300  pairs_iterator& operator++() {
25301  if (m_key_index == empty_key_index) {
25302  return *this;
25303  }
25304  {
25305  sol::protected_function_result next_results = m_next_function_ref(m_table_ref, stack_reference(m_L, m_key_index));
25306  if (!next_results.valid()) {
25307  // TODO: abort, or throw an error?
25308  m_clear();
25309  m_key_index = empty_key_index;
25310  return *this;
25311  }
25312  int next_results_count = next_results.return_count();
25313  if (next_results_count < 2) {
25314  // iteration is over!
25315  next_results.abandon();
25316  lua_settop(m_L, m_key_index - 1);
25317  m_key_index = empty_key_index;
25318  ++m_iteration_index;
25319  return *this;
25320  }
25321  else {
25322  lua_remove(m_L, m_key_index);
25323  m_key_index = next_results.stack_index() - 1;
25324  m_cached_key_value_pair.first = stack::get<object>(m_L, m_key_index);
25325  m_cached_key_value_pair.second = stack::get<object>(m_L, m_key_index + 1);
25326  lua_settop(m_L, m_key_index);
25327  next_results.abandon();
25328  }
25329  }
25330  ++m_iteration_index;
25331  return *this;
25332  }
25333 
25334  std::ptrdiff_t index() const {
25335  return static_cast<std::ptrdiff_t>(m_iteration_index);
25336  }
25337 
25338  const_reference operator*() const noexcept {
25339  return m_cached_key_value_pair;
25340  }
25341 
25342  reference operator*() noexcept {
25343  return m_cached_key_value_pair;
25344  }
25345 
25346  friend bool operator==(const pairs_iterator& left, const pairs_iterator& right) noexcept {
25347  return left.m_table_ref == right.m_table_ref && left.m_iteration_index == right.m_iteration_index;
25348  }
25349 
25350  friend bool operator!=(const pairs_iterator& left, const pairs_iterator& right) noexcept {
25351  return left.m_table_ref != right.m_table_ref || left.m_iteration_index != right.m_iteration_index;
25352  }
25353 
25354  friend bool operator==(const pairs_iterator& left, const pairs_sentinel&) noexcept {
25355  return left.m_key_index == empty_key_index;
25356  }
25357 
25358  friend bool operator!=(const pairs_iterator& left, const pairs_sentinel&) noexcept {
25359  return left.m_key_index != empty_key_index;
25360  }
25361 
25362  friend bool operator==(const pairs_sentinel&, const pairs_iterator& left) noexcept {
25363  return left.m_key_index == empty_key_index;
25364  }
25365 
25366  friend bool operator!=(const pairs_sentinel&, const pairs_iterator& left) noexcept {
25367  return left.m_key_index != empty_key_index;
25368  }
25369 
25370  ~pairs_iterator() {
25371  if (m_key_index != empty_key_index) {
25372  m_clear();
25373  }
25374  }
25375 
25376  private:
25377  void m_clear() noexcept {
25378  lua_remove(m_L, m_key_index);
25379  }
25380 
25381  lua_State* m_L;
25382  protected_function m_next_function_ref;
25383  sol::reference m_table_ref;
25384  std::pair<object, object> m_cached_key_value_pair;
25385  int m_key_index;
25386  int m_iteration_index;
25387  };
25388 
25389  template <typename Source>
25391  private:
25392  using source_t = std::add_lvalue_reference_t<Source>;
25393  source_t m_source;
25394 
25395  public:
25396  using iterator = pairs_iterator;
25398 
25399  basic_pairs_range(source_t source_) noexcept : m_source(source_) {
25400  }
25401 
25402  iterator begin() noexcept {
25403  return iterator(m_source);
25404  }
25405 
25406  iterator begin() const noexcept {
25407  return iterator(m_source);
25408  }
25409 
25410  const_iterator cbegin() const noexcept {
25411  return const_iterator(m_source);
25412  }
25413 
25414  pairs_sentinel end() noexcept {
25415  return {};
25416  }
25417 
25418  pairs_sentinel end() const noexcept {
25419  return {};
25420  }
25421 
25422  pairs_sentinel cend() const noexcept {
25423  return {};
25424  }
25425  };
25426 } // namespace sol
25427 
25428 // end of sol/pairs_iterator.hpp
25429 
25430 namespace sol {
25431  namespace detail {
25432  template <std::size_t n>
25433  struct clean {
25434  lua_State* L;
25435  clean(lua_State* luastate) : L(luastate) {
25436  }
25437  ~clean() {
25438  lua_pop(L, static_cast<int>(n));
25439  }
25440  };
25441 
25442  struct ref_clean {
25443  lua_State* L;
25444  int& pop_count;
25445 
25446  ref_clean(lua_State* L_, int& pop_count_) noexcept : L(L_), pop_count(pop_count_) {
25447  }
25448  ~ref_clean() {
25449  lua_pop(L, static_cast<int>(pop_count));
25450  }
25451  };
25452 
25453  inline int fail_on_newindex(lua_State* L_) {
25454  return luaL_error(L_, "sol: cannot modify the elements of an enumeration table");
25455  }
25456 
25457  } // namespace detail
25458 
25459  template <bool top_level, typename ref_t>
25460  class basic_table_core : public basic_object<ref_t> {
25461  private:
25462  using base_t = basic_object<ref_t>;
25463 
25464  friend class state;
25465  friend class state_view;
25466  template <typename, typename>
25467  friend class basic_usertype;
25468  template <typename>
25469  friend class basic_metatable;
25470 
25471  template <typename T>
25472  using is_get_direct_tableless = meta::boolean<stack::stack_detail::is_get_direct_tableless_v<T, top_level, false>>;
25473 
25474  template <typename T>
25475  using is_raw_get_direct_tableless = std::false_type;
25476 
25477  template <typename T>
25478  using is_set_direct_tableless = meta::boolean<stack::stack_detail::is_set_direct_tableless_v<T, top_level, false>>;
25479 
25480  template <typename T>
25481  using is_raw_set_direct_tableless = std::false_type;
25482 
25483  template <bool raw, typename... Ret, typename... Keys>
25484  decltype(auto) tuple_get(int table_index, Keys&&... keys) const {
25485  if constexpr (sizeof...(Ret) < 2) {
25486  return traverse_get_single_maybe_tuple<raw, Ret...>(table_index, std::forward<Keys>(keys)...);
25487  }
25488  else {
25489  using multi_ret = decltype(stack::pop<std::tuple<Ret...>>(nullptr));
25490  return multi_ret(traverse_get_single_maybe_tuple<raw, Ret>(table_index, std::forward<Keys>(keys))...);
25491  }
25492  }
25493 
25494  template <bool raw, typename Ret, size_t... I, typename Key>
25495  decltype(auto) traverse_get_single_tuple(int table_index, std::index_sequence<I...>, Key&& key) const {
25496  return traverse_get_single<raw, Ret>(table_index, std::get<I>(std::forward<Key>(key))...);
25497  }
25498 
25499  template <bool raw, typename Ret, typename Key>
25500  decltype(auto) traverse_get_single_maybe_tuple(int table_index, Key&& key) const {
25501  if constexpr (meta::is_tuple_v<meta::unqualified_t<Key>>) {
25502  return traverse_get_single_tuple<raw, Ret>(
25503  table_index, std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<Key>>>(), std::forward<Key>(key));
25504  }
25505  else {
25506  return traverse_get_single<raw, Ret>(table_index, std::forward<Key>(key));
25507  }
25508  }
25509 
25510  template <bool raw, typename Ret, typename... Keys>
25511  decltype(auto) traverse_get_single(int table_index, Keys&&... keys) const {
25512  constexpr static bool global = (meta::count_for_to_pack_v < 1, is_get_direct_tableless, meta::unqualified_t<Keys>... >> 0);
25513  if constexpr (meta::is_optional_v<meta::unqualified_t<Ret>>) {
25514  int popcount = 0;
25515  detail::ref_clean c(base_t::lua_state(), popcount);
25516  return traverse_get_deep_optional<global, raw, detail::insert_mode::none, Ret>(popcount, table_index, std::forward<Keys>(keys)...);
25517  }
25518  else {
25519  detail::clean<sizeof...(Keys) - meta::count_for_pack_v<detail::is_insert_mode, meta::unqualified_t<Keys>...>> c(base_t::lua_state());
25520  return traverse_get_deep<global, raw, detail::insert_mode::none, Ret>(table_index, std::forward<Keys>(keys)...);
25521  }
25522  }
25523 
25524  template <bool raw, typename Pairs, std::size_t... I>
25525  void tuple_set(std::index_sequence<I...>, Pairs&& pairs) {
25526  constexpr static bool global = (meta::count_even_for_pack_v < is_set_direct_tableless,
25527  meta::unqualified_t<decltype(std::get<I * 2>(std::forward<Pairs>(pairs)))>... >> 0);
25528  auto pp = stack::push_pop<global>(*this);
25529  int table_index = pp.index_of(*this);
25530  lua_State* L = base_t::lua_state();
25531  (void)table_index;
25532  (void)L;
25533  void(detail::swallow { (stack::set_field<(top_level), raw>(
25534  L, std::get<I * 2>(std::forward<Pairs>(pairs)), std::get<I * 2 + 1>(std::forward<Pairs>(pairs)), table_index),
25535  0)... });
25536  }
25537 
25538  template <bool global, bool raw, detail::insert_mode mode, typename T, typename Key, typename... Keys>
25539  decltype(auto) traverse_get_deep(int table_index, Key&& key, Keys&&... keys) const {
25540  if constexpr (std::is_same_v<meta::unqualified_t<Key>, create_if_nil_t>) {
25541  (void)key;
25542  return traverse_get_deep<false, raw, static_cast<detail::insert_mode>(mode | detail::insert_mode::create_if_nil), T>(
25543  table_index, std::forward<Keys>(keys)...);
25544  }
25545  else {
25546  lua_State* L = base_t::lua_state();
25547  stack::get_field<global, raw>(L, std::forward<Key>(key), table_index);
25548  if constexpr (sizeof...(Keys) > 0) {
25549  if constexpr ((mode & detail::insert_mode::create_if_nil) == detail::insert_mode::create_if_nil) {
25550  type t = type_of(L, -1);
25551  if (t == type::lua_nil || t == type::none) {
25552  lua_pop(L, 1);
25553  stack::push(L, new_table(0, 0));
25554  }
25555  }
25556  return traverse_get_deep<false, raw, mode, T>(lua_gettop(L), std::forward<Keys>(keys)...);
25557  }
25558  else {
25559  if constexpr ((mode & detail::insert_mode::create_if_nil) == detail::insert_mode::create_if_nil) {
25560  type t = type_of(L, -1);
25561  if ((t == type::lua_nil || t == type::none) && (is_table_like_v<T>)) {
25562  lua_pop(L, 1);
25563  stack::push(L, new_table(0, 0));
25564  }
25565  }
25566  return stack::get<T>(L);
25567  }
25568  }
25569  }
25570 
25571  template <bool global, bool raw, detail::insert_mode mode, typename T, typename Key, typename... Keys>
25572  decltype(auto) traverse_get_deep_optional(int& popcount, int table_index, Key&& key, Keys&&... keys) const {
25573  if constexpr (std::is_same_v<meta::unqualified_t<Key>, create_if_nil_t>) {
25574  constexpr detail::insert_mode new_mode = static_cast<detail::insert_mode>(mode | detail::insert_mode::create_if_nil);
25575  (void)key;
25576  return traverse_get_deep_optional<global, raw, new_mode, T>(popcount, table_index, std::forward<Keys>(keys)...);
25577  }
25578  else if constexpr (std::is_same_v<meta::unqualified_t<Key>, update_if_empty_t>) {
25579  constexpr detail::insert_mode new_mode = static_cast<detail::insert_mode>(mode | detail::insert_mode::update_if_empty);
25580  (void)key;
25581  return traverse_get_deep_optional<global, raw, new_mode, T>(popcount, table_index, std::forward<Keys>(keys)...);
25582  }
25583  else if constexpr (std::is_same_v<meta::unqualified_t<Key>, override_value_t>) {
25584  constexpr detail::insert_mode new_mode = static_cast<detail::insert_mode>(mode | detail::insert_mode::override_value);
25585  (void)key;
25586  return traverse_get_deep_optional<global, raw, new_mode, T>(popcount, table_index, std::forward<Keys>(keys)...);
25587  }
25588  else {
25589  if constexpr (sizeof...(Keys) > 0) {
25590  lua_State* L = base_t::lua_state();
25591  auto p = stack::probe_get_field<global, raw>(L, std::forward<Key>(key), table_index);
25592  popcount += p.levels;
25593  if (!p.success) {
25594  if constexpr ((mode & detail::insert_mode::create_if_nil) == detail::insert_mode::create_if_nil) {
25595  lua_pop(L, 1);
25596  constexpr bool is_seq = meta::count_for_to_pack_v < 1, std::is_integral, Keys... >> 0;
25597  stack::push(L, new_table(static_cast<int>(is_seq), static_cast<int>(!is_seq)));
25598  stack::set_field<global, raw>(L, std::forward<Key>(key), stack_reference(L, -1), table_index);
25599  }
25600  else {
25601  return T(nullopt);
25602  }
25603  }
25604  return traverse_get_deep_optional<false, raw, mode, T>(popcount, lua_gettop(L), std::forward<Keys>(keys)...);
25605  }
25606  else {
25607  using R = decltype(stack::get<T>(nullptr));
25608  using value_type = typename meta::unqualified_t<R>::value_type;
25609  lua_State* L = base_t::lua_state();
25610  auto p = stack::probe_get_field<global, raw, value_type>(L, key, table_index);
25611  popcount += p.levels;
25612  if (!p.success) {
25613  if constexpr ((mode & detail::insert_mode::create_if_nil) == detail::insert_mode::create_if_nil) {
25614  lua_pop(L, 1);
25615  stack::push(L, new_table(0, 0));
25616  stack::set_field<global, raw>(L, std::forward<Key>(key), stack_reference(L, -1), table_index);
25617  if (stack::check<value_type>(L, lua_gettop(L), &no_panic)) {
25618  return stack::get<T>(L);
25619  }
25620  }
25621  return R(nullopt);
25622  }
25623  return stack::get<T>(L);
25624  }
25625  }
25626  }
25627 
25628  template <bool global, bool raw, detail::insert_mode mode, typename Key, typename... Keys>
25629  void traverse_set_deep(int table_index, Key&& key, Keys&&... keys) const {
25630  using KeyU = meta::unqualified_t<Key>;
25631  if constexpr (std::is_same_v<KeyU, update_if_empty_t>) {
25632  (void)key;
25633  traverse_set_deep<global, raw, static_cast<detail::insert_mode>(mode | detail::insert_mode::update_if_empty)>(
25634  table_index, std::forward<Keys>(keys)...);
25635  }
25636  else if constexpr (std::is_same_v<KeyU, create_if_nil_t>) {
25637  (void)key;
25638  traverse_set_deep<global, raw, static_cast<detail::insert_mode>(mode | detail::insert_mode::create_if_nil)>(
25639  table_index, std::forward<Keys>(keys)...);
25640  }
25641  else if constexpr (std::is_same_v<KeyU, override_value_t>) {
25642  (void)key;
25643  traverse_set_deep<global, raw, static_cast<detail::insert_mode>(mode | detail::insert_mode::override_value)>(
25644  table_index, std::forward<Keys>(keys)...);
25645  }
25646  else {
25647  lua_State* L = base_t::lua_state();
25648  if constexpr (sizeof...(Keys) == 1) {
25649  if constexpr ((mode & detail::insert_mode::update_if_empty) == detail::insert_mode::update_if_empty) {
25650  auto p = stack::probe_get_field<global, raw>(L, key, table_index);
25651  lua_pop(L, p.levels);
25652  if (!p.success) {
25653  stack::set_field<global, raw>(L, std::forward<Key>(key), std::forward<Keys>(keys)..., table_index);
25654  }
25655  }
25656  else {
25657  stack::set_field<global, raw>(L, std::forward<Key>(key), std::forward<Keys>(keys)..., table_index);
25658  }
25659  }
25660  else {
25661  if constexpr (mode != detail::insert_mode::none) {
25662  stack::get_field<global, raw>(L, key, table_index);
25663  type vt = type_of(L, -1);
25664  if constexpr ((mode & detail::insert_mode::update_if_empty) == detail::insert_mode::update_if_empty
25665  || (mode & detail::insert_mode::create_if_nil) == detail::insert_mode::create_if_nil) {
25666  if (vt == type::lua_nil || vt == type::none) {
25667  constexpr bool is_seq = meta::count_for_to_pack_v < 1, std::is_integral, Keys... >> 0;
25668  lua_pop(L, 1);
25669  stack::push(L, new_table(static_cast<int>(is_seq), static_cast<int>(!is_seq)));
25670  stack::set_field<global, raw>(L, std::forward<Key>(key), stack_reference(L, -1), table_index);
25671  }
25672  }
25673  else {
25674  if (vt != type::table) {
25675  constexpr bool is_seq = meta::count_for_to_pack_v < 1, std::is_integral, Keys... >> 0;
25676  lua_pop(L, 1);
25677  stack::push(L, new_table(static_cast<int>(is_seq), static_cast<int>(!is_seq)));
25678  stack::set_field<global, raw>(L, std::forward<Key>(key), stack_reference(L, -1), table_index);
25679  }
25680  }
25681  }
25682  else {
25683  stack::get_field<global, raw>(L, std::forward<Key>(key), table_index);
25684  }
25685  traverse_set_deep<false, raw, mode>(lua_gettop(L), std::forward<Keys>(keys)...);
25686  }
25687  }
25688  }
25689 
25690  protected:
25692  }
25693  basic_table_core(detail::no_safety_tag, lua_State* L, int index) : base_t(L, index) {
25694  }
25695  basic_table_core(detail::no_safety_tag, lua_State* L, ref_index index) : base_t(L, index) {
25696  }
25697  template <typename T,
25698  meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_table_core>>, meta::neg<std::is_same<ref_t, stack_reference>>,
25699  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
25700  basic_table_core(detail::no_safety_tag, T&& r) noexcept : base_t(std::forward<T>(r)) {
25701  }
25702  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
25703  basic_table_core(detail::no_safety_tag, lua_State* L, T&& r) noexcept : base_t(L, std::forward<T>(r)) {
25704  }
25705 
25706  public:
25707  using iterator = basic_table_iterator<ref_t>;
25708  using const_iterator = iterator;
25709 
25710  using base_t::lua_state;
25711 
25712  basic_table_core() noexcept = default;
25713  basic_table_core(const basic_table_core&) = default;
25714  basic_table_core(basic_table_core&&) = default;
25715  basic_table_core& operator=(const basic_table_core&) = default;
25716  basic_table_core& operator=(basic_table_core&&) = default;
25717 
25718  basic_table_core(const stack_reference& r) : basic_table_core(r.lua_state(), r.stack_index()) {
25719  }
25720 
25721  basic_table_core(stack_reference&& r) : basic_table_core(r.lua_state(), r.stack_index()) {
25722  }
25723 
25724  template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
25725  basic_table_core(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
25726 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
25727  auto pp = stack::push_pop(*this);
25728  int table_index = pp.index_of(*this);
25729  constructor_handler handler {};
25730  stack::check<basic_table_core>(lua_state(), table_index, handler);
25731 #endif // Safety
25732  }
25733 
25734  basic_table_core(lua_State* L, const new_table& nt) : base_t(L, -stack::push(L, nt)) {
25735  if (!is_stack_based<meta::unqualified_t<ref_t>>::value) {
25736  lua_pop(L, 1);
25737  }
25738  }
25739 
25740  basic_table_core(lua_State* L, int index = -1) : basic_table_core(detail::no_safety, L, index) {
25741 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
25742  constructor_handler handler {};
25743  stack::check<basic_table_core>(L, index, handler);
25744 #endif // Safety
25745  }
25746 
25747  basic_table_core(lua_State* L, ref_index index) : basic_table_core(detail::no_safety, L, index) {
25748 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
25749  auto pp = stack::push_pop(*this);
25750  int table_index = pp.index_of(*this);
25751  constructor_handler handler {};
25752  stack::check<basic_table_core>(lua_state(), table_index, handler);
25753 #endif // Safety
25754  }
25755 
25756  template <typename T,
25757  meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_table_core>>, meta::neg<std::is_same<ref_t, stack_reference>>,
25758  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
25759  basic_table_core(T&& r) noexcept : basic_table_core(detail::no_safety, std::forward<T>(r)) {
25760 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
25761  if (!is_table<meta::unqualified_t<T>>::value) {
25762  auto pp = stack::push_pop(*this);
25763  int table_index = pp.index_of(*this);
25764  constructor_handler handler {};
25765  stack::check<basic_table_core>(lua_state(), table_index, handler);
25766  }
25767 #endif // Safety
25768  }
25769 
25770  basic_table_core(lua_nil_t r) noexcept : basic_table_core(detail::no_safety, r) {
25771  }
25772 
25773  basic_table_core(lua_State* L, global_tag_t t) noexcept : base_t(L, t) {
25774  }
25775 
25776  iterator begin() const {
25777  if (this->get_type() == type::table) {
25778  return iterator(*this);
25779  }
25780  return iterator();
25781  }
25782 
25783  iterator end() const {
25784  return iterator();
25785  }
25786 
25787  const_iterator cbegin() const {
25788  return begin();
25789  }
25790 
25791  const_iterator cend() const {
25792  return end();
25793  }
25794 
25795  basic_pairs_range<basic_table_core> pairs() noexcept {
25797  }
25798 
25799  basic_pairs_range<const basic_table_core> pairs() const noexcept {
25801  }
25802 
25803  void clear() {
25804  auto pp = stack::push_pop<false>(*this);
25805  int table_index = pp.index_of(*this);
25806  stack::clear(lua_state(), table_index);
25807  }
25808 
25809  template <typename... Ret, typename... Keys>
25810  decltype(auto) get(Keys&&... keys) const {
25811  static_assert(sizeof...(Keys) == sizeof...(Ret), "number of keys and number of return types do not match");
25812  constexpr static bool global = meta::all<meta::boolean<top_level>, is_get_direct_tableless<meta::unqualified_t<Keys>>...>::value;
25813  auto pp = stack::push_pop<global>(*this);
25814  int table_index = pp.index_of(*this);
25815  return tuple_get<false, Ret...>(table_index, std::forward<Keys>(keys)...);
25816  }
25817 
25818  template <typename T, typename Key>
25819  decltype(auto) get_or(Key&& key, T&& otherwise) const {
25820  typedef decltype(get<T>("")) U;
25821  optional<U> option = get<optional<U>>(std::forward<Key>(key));
25822  if (option) {
25823  return static_cast<U>(option.value());
25824  }
25825  return static_cast<U>(std::forward<T>(otherwise));
25826  }
25827 
25828  template <typename T, typename Key, typename D>
25829  decltype(auto) get_or(Key&& key, D&& otherwise) const {
25830  optional<T> option = get<optional<T>>(std::forward<Key>(key));
25831  if (option) {
25832  return static_cast<T>(option.value());
25833  }
25834  return static_cast<T>(std::forward<D>(otherwise));
25835  }
25836 
25837  template <typename T, typename... Keys>
25838  decltype(auto) traverse_get(Keys&&... keys) const {
25839  static_assert(sizeof...(Keys) > 0, "must pass at least 1 key to get");
25840  constexpr static bool global = (meta::count_for_to_pack_v < 1, is_get_direct_tableless, meta::unqualified_t<Keys>... >> 0);
25841  auto pp = stack::push_pop<global>(*this);
25842  int table_index = pp.index_of(*this);
25843  return traverse_get_single<false, T>(table_index, std::forward<Keys>(keys)...);
25844  }
25845 
25846  template <typename... Keys>
25847  basic_table_core& traverse_set(Keys&&... keys) {
25848  static_assert(sizeof...(Keys) > 1, "must pass at least 1 key and 1 value to set");
25849  constexpr static bool global
25850  = (meta::count_when_for_to_pack_v < detail::is_not_insert_mode, 1, is_set_direct_tableless, meta::unqualified_t<Keys>... >> 0);
25851  auto pp = stack::push_pop<global>(*this);
25852  int table_index = pp.index_of(*this);
25853  lua_State* L = base_t::lua_state();
25854  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>...>));
25855  traverse_set_deep<top_level, false, detail::insert_mode::none>(table_index, std::forward<Keys>(keys)...);
25856  return *this;
25857  }
25858 
25859  template <typename... Args>
25860  basic_table_core& set(Args&&... args) {
25861  if constexpr (sizeof...(Args) == 2) {
25862  traverse_set(std::forward<Args>(args)...);
25863  }
25864  else {
25865  tuple_set<false>(std::make_index_sequence<sizeof...(Args) / 2>(), std::forward_as_tuple(std::forward<Args>(args)...));
25866  }
25867  return *this;
25868  }
25869 
25870  template <typename... Ret, typename... Keys>
25871  decltype(auto) raw_get(Keys&&... keys) const {
25872  static_assert(sizeof...(Keys) == sizeof...(Ret), "number of keys and number of return types do not match");
25873  constexpr static bool global = (meta::count_for_to_pack_v < 1, is_raw_get_direct_tableless, meta::unqualified_t<Keys>... >> 0);
25874  auto pp = stack::push_pop<global>(*this);
25875  int table_index = pp.index_of(*this);
25876  return tuple_get<true, Ret...>(table_index, std::forward<Keys>(keys)...);
25877  }
25878 
25879  template <typename T, typename Key>
25880  decltype(auto) raw_get_or(Key&& key, T&& otherwise) const {
25881  typedef decltype(raw_get<T>("")) U;
25882  optional<U> option = raw_get<optional<U>>(std::forward<Key>(key));
25883  if (option) {
25884  return static_cast<U>(option.value());
25885  }
25886  return static_cast<U>(std::forward<T>(otherwise));
25887  }
25888 
25889  template <typename T, typename Key, typename D>
25890  decltype(auto) raw_get_or(Key&& key, D&& otherwise) const {
25891  optional<T> option = raw_get<optional<T>>(std::forward<Key>(key));
25892  if (option) {
25893  return static_cast<T>(option.value());
25894  }
25895  return static_cast<T>(std::forward<D>(otherwise));
25896  }
25897 
25898  template <typename T, typename... Keys>
25899  decltype(auto) traverse_raw_get(Keys&&... keys) const {
25900  constexpr static bool global = (meta::count_for_to_pack_v < 1, is_raw_get_direct_tableless, meta::unqualified_t<Keys>... >> 0);
25901  auto pp = stack::push_pop<global>(*this);
25902  int table_index = pp.index_of(*this);
25903  return traverse_get_single<true, T>(table_index, std::forward<Keys>(keys)...);
25904  }
25905 
25906  template <typename... Keys>
25907  basic_table_core& traverse_raw_set(Keys&&... keys) {
25908  constexpr static bool global = (meta::count_for_to_pack_v < 1, is_raw_set_direct_tableless, meta::unqualified_t<Keys>... >> 0);
25909  auto pp = stack::push_pop<global>(*this);
25910  lua_State* L = base_t::lua_state();
25911  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>...>));
25912  traverse_set_deep<top_level, true, false>(std::forward<Keys>(keys)...);
25913  return *this;
25914  }
25915 
25916  template <typename... Args>
25917  basic_table_core& raw_set(Args&&... args) {
25918  tuple_set<true>(std::make_index_sequence<sizeof...(Args) / 2>(), std::forward_as_tuple(std::forward<Args>(args)...));
25919  return *this;
25920  }
25921 
25922  template <typename Class, typename Key>
25923  usertype<Class> new_usertype(Key&& key);
25924 
25925  template <typename Class, typename Key, automagic_flags enrollment_flags>
25926  usertype<Class> new_usertype(Key&& key, constant_automagic_enrollments<enrollment_flags> enrollment);
25927 
25928  template <typename Class, typename Key>
25929  usertype<Class> new_usertype(Key&& key, automagic_enrollments enrollment);
25930 
25931  template <typename Class, typename Key, typename Arg, typename... Args,
25932  typename = std::enable_if_t<!std::is_base_of_v<automagic_enrollments, meta::unqualified_t<Arg>>>>
25933  usertype<Class> new_usertype(Key&& key, Arg&& arg, Args&&... args);
25934 
25935  template <bool read_only = true, typename... Args>
25936  table new_enum(const string_view& name, Args&&... args) {
25937  table target = create_with(std::forward<Args>(args)...);
25938  if constexpr (read_only) {
25939  // Need to create a special iterator to handle this
25940  table x
25941  = create_with(meta_function::new_index, detail::fail_on_newindex, meta_function::index, target, meta_function::pairs, stack::stack_detail::readonly_pairs);
25942  table shim = create_named(name, metatable_key, x);
25943  return shim;
25944  }
25945  else {
25946  set(name, target);
25947  return target;
25948  }
25949  }
25950 
25951  template <typename T, bool read_only = true>
25952  table new_enum(const string_view& name, std::initializer_list<std::pair<string_view, T>> items) {
25953  table target = create(static_cast<int>(items.size()), static_cast<int>(0));
25954  for (const auto& kvp : items) {
25955  target.set(kvp.first, kvp.second);
25956  }
25957  if constexpr (read_only) {
25958  table x = create_with(meta_function::new_index, detail::fail_on_newindex, meta_function::index, target);
25959  table shim = create_named(name, metatable_key, x);
25960  return shim;
25961  }
25962  else {
25963  set(name, target);
25964  return target;
25965  }
25966  }
25967 
25968  template <typename Key = object, typename Value = object, typename Fx>
25969  void for_each(Fx&& fx) const {
25970  lua_State* L = base_t::lua_state();
25971  if constexpr (std::is_invocable_v<Fx, Key, Value>) {
25972  auto pp = stack::push_pop(*this);
25973  int table_index = pp.index_of(*this);
25974  stack::push(L, lua_nil);
25975  while (lua_next(L, table_index)) {
25976  Key key(L, -2);
25977  Value value(L, -1);
25978  auto pn = stack::pop_n(L, 1);
25979  fx(key, value);
25980  }
25981  }
25982  else {
25983  auto pp = stack::push_pop(*this);
25984  int table_index = pp.index_of(*this);
25985  stack::push(L, lua_nil);
25986  while (lua_next(L, table_index)) {
25987  Key key(L, -2);
25988  Value value(L, -1);
25989  auto pn = stack::pop_n(L, 1);
25990  std::pair<Key&, Value&> keyvalue(key, value);
25991  fx(keyvalue);
25992  }
25993  }
25994  }
25995 
25996  size_t size() const {
25997  auto pp = stack::push_pop(*this);
25998  int table_index = pp.index_of(*this);
25999  lua_State* L = base_t::lua_state();
26000  lua_len(L, table_index);
26001  return stack::pop<size_t>(L);
26002  }
26003 
26004  bool empty() const {
26005  return cbegin() == cend();
26006  }
26007 
26008  template <typename T>
26009  auto operator[](T&& key) & {
26010  return table_proxy<basic_table_core&, detail::proxy_key_t<T>>(*this, std::forward<T>(key));
26011  }
26012 
26013  template <typename T>
26014  auto operator[](T&& key) const& {
26015  return table_proxy<const basic_table_core&, detail::proxy_key_t<T>>(*this, std::forward<T>(key));
26016  }
26017 
26018  template <typename T>
26019  auto operator[](T&& key) && {
26020  return table_proxy<basic_table_core, detail::proxy_key_t<T>>(std::move(*this), std::forward<T>(key));
26021  }
26022 
26023  template <typename Sig, typename Key, typename... Args>
26024  basic_table_core& set_function(Key&& key, Args&&... args) {
26025  set_fx(types<Sig>(), std::forward<Key>(key), std::forward<Args>(args)...);
26026  return *this;
26027  }
26028 
26029  template <typename Key, typename... Args>
26030  basic_table_core& set_function(Key&& key, Args&&... args) {
26031  set_fx(types<>(), std::forward<Key>(key), std::forward<Args>(args)...);
26032  return *this;
26033  }
26034 
26035  template <typename... Args>
26036  basic_table_core& add(Args&&... args) {
26037  auto pp = stack::push_pop(*this);
26038  int table_index = pp.index_of(*this);
26039  lua_State* L = base_t::lua_state();
26040  (void)detail::swallow { 0, (stack::stack_detail::raw_table_set(L, std::forward<Args>(args), table_index), 0)... };
26041  return *this;
26042  }
26043 
26044  private:
26045  template <typename R, typename... Args, typename Fx, typename Key, typename = std::invoke_result_t<Fx, Args...>>
26046  void set_fx(types<R(Args...)>, Key&& key, Fx&& fx) {
26047  set_resolved_function<R(Args...)>(std::forward<Key>(key), std::forward<Fx>(fx));
26048  }
26049 
26050  template <typename Fx, typename Key, meta::enable<meta::is_specialization_of<meta::unqualified_t<Fx>, overload_set>> = meta::enabler>
26051  void set_fx(types<>, Key&& key, Fx&& fx) {
26052  set(std::forward<Key>(key), std::forward<Fx>(fx));
26053  }
26054 
26055  template <typename Fx, typename Key, typename... Args,
26056  meta::disable<meta::is_specialization_of<meta::unqualified_t<Fx>, overload_set>> = meta::enabler>
26057  void set_fx(types<>, Key&& key, Fx&& fx, Args&&... args) {
26058  set(std::forward<Key>(key), as_function_reference(std::forward<Fx>(fx), std::forward<Args>(args)...));
26059  }
26060 
26061  template <typename... Sig, typename... Args, typename Key>
26062  void set_resolved_function(Key&& key, Args&&... args) {
26063  set(std::forward<Key>(key), as_function_reference<function_sig<Sig...>>(std::forward<Args>(args)...));
26064  }
26065 
26066  public:
26067  static inline table create(lua_State* L, int narr = 0, int nrec = 0) {
26068  lua_createtable(L, narr, nrec);
26069  table result(L);
26070  lua_pop(L, 1);
26071  return result;
26072  }
26073 
26074  template <typename Key, typename Value, typename... Args>
26075  static inline table create(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
26076  lua_createtable(L, narr, nrec);
26077  table result(L);
26078  result.set(std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
26079  lua_pop(L, 1);
26080  return result;
26081  }
26082 
26083  template <typename... Args>
26084  static inline table create_with(lua_State* L, Args&&... args) {
26085  static_assert(sizeof...(Args) % 2 == 0, "You must have an even number of arguments for a key, value ... list.");
26086  constexpr int narr = static_cast<int>(meta::count_odd_for_pack_v<std::is_integral, Args...>);
26087  return create(L, narr, static_cast<int>((sizeof...(Args) / 2) - narr), std::forward<Args>(args)...);
26088  }
26089 
26090  table create(int narr = 0, int nrec = 0) {
26091  return create(base_t::lua_state(), narr, nrec);
26092  }
26093 
26094  template <typename Key, typename Value, typename... Args>
26095  table create(int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
26096  return create(base_t::lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
26097  }
26098 
26099  template <typename Name>
26100  table create(Name&& name, int narr = 0, int nrec = 0) {
26101  table x = create(base_t::lua_state(), narr, nrec);
26102  this->set(std::forward<Name>(name), x);
26103  return x;
26104  }
26105 
26106  template <typename Name, typename Key, typename Value, typename... Args>
26107  table create(Name&& name, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
26108  table x = create(base_t::lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
26109  this->set(std::forward<Name>(name), x);
26110  return x;
26111  }
26112 
26113  template <typename... Args>
26114  table create_with(Args&&... args) {
26115  return create_with(base_t::lua_state(), std::forward<Args>(args)...);
26116  }
26117 
26118  template <typename Name, typename... Args>
26119  table create_named(Name&& name, Args&&... args) {
26120  static const int narr = static_cast<int>(meta::count_even_for_pack_v<std::is_integral, Args...>);
26121  return create(std::forward<Name>(name), narr, (sizeof...(Args) / 2) - narr, std::forward<Args>(args)...);
26122  }
26123  };
26124 } // namespace sol
26125 
26126 // end of sol/table_core.hpp
26127 
26128 namespace sol {
26129 
26130  template <typename base_type>
26131  class basic_metatable : public basic_table<base_type> {
26132  typedef basic_table<base_type> base_t;
26133  friend class state;
26134  friend class state_view;
26135 
26136  protected:
26138  }
26139  basic_metatable(detail::no_safety_tag, lua_State* L, int index) : base_t(L, index) {
26140  }
26141  basic_metatable(detail::no_safety_tag, lua_State* L, ref_index index) : base_t(L, index) {
26142  }
26143  template <typename T,
26144  meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_metatable>>, meta::neg<std::is_same<base_type, stack_reference>>,
26145  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26146  basic_metatable(detail::no_safety_tag, T&& r) noexcept : base_t(std::forward<T>(r)) {
26147  }
26148  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26149  basic_metatable(detail::no_safety_tag, lua_State* L, T&& r) noexcept : base_t(L, std::forward<T>(r)) {
26150  }
26151 
26152  template <typename R, typename... Args, typename Fx, typename Key, typename = std::invoke_result_t<Fx, Args...>>
26153  void set_fx(types<R(Args...)>, Key&& key, Fx&& fx) {
26154  set_resolved_function<R(Args...)>(std::forward<Key>(key), std::forward<Fx>(fx));
26155  }
26156 
26157  template <typename Fx, typename Key, meta::enable<meta::is_specialization_of<meta::unqualified_t<Fx>, overload_set>> = meta::enabler>
26158  void set_fx(types<>, Key&& key, Fx&& fx) {
26159  set(std::forward<Key>(key), std::forward<Fx>(fx));
26160  }
26161 
26162  template <typename Fx, typename Key, typename... Args,
26163  meta::disable<meta::is_specialization_of<meta::unqualified_t<Fx>, overload_set>> = meta::enabler>
26164  void set_fx(types<>, Key&& key, Fx&& fx, Args&&... args) {
26165  set(std::forward<Key>(key), as_function_reference(std::forward<Fx>(fx), std::forward<Args>(args)...));
26166  }
26167 
26168  template <typename... Sig, typename... Args, typename Key>
26169  void set_resolved_function(Key&& key, Args&&... args) {
26170  set(std::forward<Key>(key), as_function_reference<function_sig<Sig...>>(std::forward<Args>(args)...));
26171  }
26172 
26173  public:
26174  using base_t::lua_state;
26175 
26176  basic_metatable() noexcept = default;
26177  basic_metatable(const basic_metatable&) = default;
26178  basic_metatable(basic_metatable&&) = default;
26179  basic_metatable& operator=(const basic_metatable&) = default;
26180  basic_metatable& operator=(basic_metatable&&) = default;
26181  basic_metatable(const stack_reference& r) : basic_metatable(r.lua_state(), r.stack_index()) {
26182  }
26183  basic_metatable(stack_reference&& r) : basic_metatable(r.lua_state(), r.stack_index()) {
26184  }
26185  template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26186  basic_metatable(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
26187 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26188  auto pp = stack::push_pop(*this);
26189  constructor_handler handler {};
26190  stack::check<basic_metatable>(lua_state(), -1, handler);
26191 #endif // Safety
26192  }
26193  basic_metatable(lua_State* L, int index = -1) : basic_metatable(detail::no_safety, L, index) {
26194 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26195  constructor_handler handler {};
26196  stack::check<basic_metatable>(L, index, handler);
26197 #endif // Safety
26198  }
26199  basic_metatable(lua_State* L, ref_index index) : basic_metatable(detail::no_safety, L, index) {
26200 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26201  auto pp = stack::push_pop(*this);
26202  constructor_handler handler {};
26203  stack::check<basic_metatable>(lua_state(), -1, handler);
26204 #endif // Safety
26205  }
26206  template <typename T,
26207  meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_metatable>>, meta::neg<std::is_same<base_type, stack_reference>>,
26208  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26209  basic_metatable(T&& r) noexcept : basic_metatable(detail::no_safety, std::forward<T>(r)) {
26210 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26211  if (!is_table<meta::unqualified_t<T>>::value) {
26212  auto pp = stack::push_pop(*this);
26213  constructor_handler handler {};
26214  stack::check<basic_metatable>(base_t::lua_state(), -1, handler);
26215  }
26216 #endif // Safety
26217  }
26218  basic_metatable(lua_nil_t r) noexcept : basic_metatable(detail::no_safety, r) {
26219  }
26220 
26221  template <typename Key, typename Value>
26222  basic_metatable<base_type>& set(Key&& key, Value&& value);
26223 
26224  template <typename Sig, typename Key, typename... Args>
26225  basic_metatable& set_function(Key&& key, Args&&... args) {
26226  set_fx(types<Sig>(), std::forward<Key>(key), std::forward<Args>(args)...);
26227  return *this;
26228  }
26229 
26230  template <typename Key, typename... Args>
26231  basic_metatable& set_function(Key&& key, Args&&... args) {
26232  set_fx(types<>(), std::forward<Key>(key), std::forward<Args>(args)...);
26233  return *this;
26234  }
26235 
26236  void unregister() {
26237  using ustorage_base = u_detail::usertype_storage_base;
26238 
26239  lua_State* L = this->lua_state();
26240 
26241  auto pp = stack::push_pop(*this);
26242  int top = lua_gettop(L);
26243 
26244  stack_reference mt(L, -1);
26245  stack::get_field(L, meta_function::gc_names, mt.stack_index());
26246  if (type_of(L, -1) != type::table) {
26247  lua_settop(L, top);
26248  return;
26249  }
26250  stack_reference gc_names_table(L, -1);
26251  stack::get_field(L, meta_function::storage, mt.stack_index());
26252  if (type_of(L, -1) != type::lightuserdata) {
26253  lua_settop(L, top);
26254  return;
26255  }
26256  ustorage_base& base_storage = *static_cast<ustorage_base*>(stack::get<void*>(L, -1));
26257  std::array<string_view, 6> registry_traits;
26258  for (std::size_t i = 0; i < registry_traits.size(); ++i) {
26259  u_detail::submetatable_type smt = static_cast<u_detail::submetatable_type>(i);
26260  stack::get_field<false, true>(L, smt, gc_names_table.stack_index());
26261  registry_traits[i] = stack::get<string_view>(L, -1);
26262  }
26263 
26264  // get the registry
26265  stack_reference registry(L, raw_index(LUA_REGISTRYINDEX));
26266  registry.push();
26267  // eliminate all named entries for this usertype
26268  // in the registry (luaL_newmetatable does
26269  // [name] = new table
26270  // in registry upon creation)
26271  for (std::size_t i = 0; i < registry_traits.size(); ++i) {
26272  u_detail::submetatable_type smt = static_cast<u_detail::submetatable_type>(i);
26273  const string_view& gcmetakey = registry_traits[i];
26274  if (smt == u_detail::submetatable_type::named) {
26275  // use .data() to make it treat it like a c string,
26276  // which it is...
26277  stack::set_field<true>(L, gcmetakey.data(), lua_nil);
26278  }
26279  else {
26280  // do not change the values in the registry: they need to be present
26281  // no matter what, for safety's sake
26282  // stack::set_field(L, gcmetakey, lua_nil, registry.stack_index());
26283  }
26284  }
26285 
26286  // destroy all storage and tables
26287  base_storage.clear();
26288 
26289  // 6 strings from gc_names table,
26290  // + 1 registry,
26291  // + 1 gc_names table
26292  // + 1 light userdata of storage
26293  // + 1 registry
26294  // 10 total, 4 left since popping off 6 gc_names tables
26295  lua_settop(L, top);
26296  }
26297  };
26298 
26299 } // namespace sol
26300 
26301 // end of sol/metatable.hpp
26302 
26303 namespace sol {
26304 
26305  template <typename T, typename base_type>
26306  class basic_usertype : private basic_metatable<base_type> {
26307  private:
26308  using base_t = basic_metatable<base_type>;
26309  using table_base_t = basic_table<base_type>;
26310 
26311  template <typename>
26312  friend class basic_metatable;
26313 
26314  template <bool, typename>
26315  friend class basic_table_core;
26316 
26317  template <std::size_t... I, typename... Args>
26318  void tuple_set(std::index_sequence<I...>, std::tuple<Args...>&& args) {
26319  (void)args;
26320  (void)detail::swallow { 0, (this->set(std::get<I * 2>(std::move(args)), std::get<I * 2 + 1>(std::move(args))), 0)... };
26321  }
26322 
26323  template <typename R, typename... Args, typename Fx, typename Key, typename = std::invoke_result_t<Fx, Args...>>
26324  void set_fx(types<R(Args...)>, Key&& key, Fx&& fx) {
26325  set_resolved_function<R(Args...)>(std::forward<Key>(key), std::forward<Fx>(fx));
26326  }
26327 
26328  template <typename Fx, typename Key, meta::enable<meta::is_specialization_of<meta::unqualified_t<Fx>, overload_set>> = meta::enabler>
26329  void set_fx(types<>, Key&& key, Fx&& fx) {
26330  set(std::forward<Key>(key), std::forward<Fx>(fx));
26331  }
26332 
26333  template <typename Fx, typename Key, typename... Args,
26334  meta::disable<meta::is_specialization_of<meta::unqualified_t<Fx>, overload_set>> = meta::enabler>
26335  void set_fx(types<>, Key&& key, Fx&& fx, Args&&... args) {
26336  set(std::forward<Key>(key), as_function_reference(std::forward<Fx>(fx), std::forward<Args>(args)...));
26337  }
26338 
26339  template <typename... Sig, typename... Args, typename Key>
26340  void set_resolved_function(Key&& key, Args&&... args) {
26341  set(std::forward<Key>(key), as_function_reference<function_sig<Sig...>>(std::forward<Args>(args)...));
26342  }
26343 
26344  public:
26345  using base_t::base_t;
26346 
26347  using base_t::get;
26348  using base_t::lua_state;
26349  using base_t::pop;
26350  using base_t::push;
26351  using base_t::traverse_get;
26352  using base_t::traverse_set;
26353  using base_t::unregister;
26354 
26355  template <typename Key, typename Value>
26356  basic_usertype& set(Key&& key, Value&& value) {
26357  optional<u_detail::usertype_storage<T>&> maybe_uts = u_detail::maybe_get_usertype_storage<T>(this->lua_state());
26358  if (maybe_uts) {
26359  u_detail::usertype_storage<T>& uts = *maybe_uts;
26360  uts.set(this->lua_state(), std::forward<Key>(key), std::forward<Value>(value));
26361  }
26362  else {
26363  using ValueU = meta::unqualified_t<Value>;
26364  // cannot get metatable: try regular table set?
26365  if constexpr (detail::is_non_factory_constructor_v<ValueU> || detail::is_policy_v<ValueU>) {
26366  // tag constructors so we don't get destroyed by lack of info
26367  table_base_t::set(std::forward<Key>(key), detail::tagged<T, Value>(std::forward<Value>(value)));
26368  }
26369  else {
26370  table_base_t::set(std::forward<Key>(key), std::forward<Value>(value));
26371  }
26372  }
26373  return *this;
26374  }
26375 
26376  template <typename Sig, typename Key, typename... Args>
26377  basic_usertype& set_function(Key&& key, Args&&... args) {
26378  set_fx(types<Sig>(), std::forward<Key>(key), std::forward<Args>(args)...);
26379  return *this;
26380  }
26381 
26382  template <typename Key, typename... Args>
26383  basic_usertype& set_function(Key&& key, Args&&... args) {
26384  set_fx(types<>(), std::forward<Key>(key), std::forward<Args>(args)...);
26385  return *this;
26386  }
26387 
26388  template <typename Key>
26389  usertype_proxy<basic_usertype&, std::decay_t<Key>> operator[](Key&& key) {
26390  return usertype_proxy<basic_usertype&, std::decay_t<Key>>(*this, std::forward<Key>(key));
26391  }
26392 
26393  template <typename Key>
26394  usertype_proxy<const basic_usertype&, std::decay_t<Key>> operator[](Key&& key) const {
26395  return usertype_proxy<const basic_usertype&, std::decay_t<Key>>(*this, std::forward<Key>(key));
26396  }
26397  };
26398 
26399 } // namespace sol
26400 
26401 // end of sol/usertype.hpp
26402 
26403 // beginning of sol/table.hpp
26404 
26405 // beginning of sol/lua_table.hpp
26406 
26407 namespace sol {
26408 
26409  template <typename ref_t>
26410  struct basic_lua_table : basic_table_core<false, ref_t> {
26411  private:
26412  using base_t = basic_table_core<false, ref_t>;
26413 
26414  friend class state;
26415  friend class state_view;
26416 
26417  public:
26418  using base_t::lua_state;
26419 
26420  basic_lua_table() noexcept = default;
26421  basic_lua_table(const basic_lua_table&) = default;
26422  basic_lua_table(basic_lua_table&&) = default;
26423  basic_lua_table& operator=(const basic_lua_table&) = default;
26424  basic_lua_table& operator=(basic_lua_table&&) = default;
26425  basic_lua_table(const stack_reference& r) : basic_lua_table(r.lua_state(), r.stack_index()) {
26426  }
26427  basic_lua_table(stack_reference&& r) : basic_lua_table(r.lua_state(), r.stack_index()) {
26428  }
26429  template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26430  basic_lua_table(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
26431 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26432  auto pp = stack::push_pop(*this);
26433  constructor_handler handler {};
26434  stack::check<basic_lua_table>(lua_state(), -1, handler);
26435 #endif // Safety
26436  }
26437  basic_lua_table(lua_State* L, const new_table& nt) : base_t(L, nt) {
26438  if (!is_stack_based<meta::unqualified_t<ref_t>>::value) {
26439  lua_pop(L, 1);
26440  }
26441  }
26442  basic_lua_table(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
26443 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26444  constructor_handler handler {};
26445  stack::check<basic_lua_table>(L, index, handler);
26446 #endif // Safety
26447  }
26448  basic_lua_table(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
26449 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26450  auto pp = stack::push_pop(*this);
26451  constructor_handler handler {};
26452  stack::check<basic_lua_table>(lua_state(), -1, handler);
26453 #endif // Safety
26454  }
26455  template <typename T,
26456  meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_lua_table>>, meta::neg<std::is_same<ref_t, stack_reference>>,
26457  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26458  basic_lua_table(T&& r) noexcept : basic_lua_table(detail::no_safety, std::forward<T>(r)) {
26459 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26460  if (!is_table<meta::unqualified_t<T>>::value) {
26461  auto pp = stack::push_pop(*this);
26462  constructor_handler handler {};
26463  stack::check<basic_lua_table>(lua_state(), -1, handler);
26464  }
26465 #endif // Safety
26466  }
26467  basic_lua_table(lua_nil_t r) noexcept : basic_lua_table(detail::no_safety, r) {
26468  }
26469  };
26470 
26471 } // namespace sol
26472 
26473 // end of sol/lua_table.hpp
26474 
26475 namespace sol {
26476  typedef table_core<false> table;
26477 
26478  template <bool is_global, typename base_type>
26479  template <typename Class, typename Key>
26481  constant_automagic_enrollments<> enrollments {};
26482  return this->new_usertype<Class>(std::forward<Key>(key), std::move(enrollments));
26483  }
26484 
26485  template <bool is_global, typename base_type>
26486  template <typename Class, typename Key, automagic_flags enrollment_flags>
26488  int mt_index = u_detail::register_usertype<Class, enrollment_flags>(this->lua_state(), std::move(enrollments));
26489  usertype<Class> mt(this->lua_state(), -mt_index);
26490  lua_pop(this->lua_state(), 1);
26491  set(std::forward<Key>(key), mt);
26492  return mt;
26493  }
26494 
26495  template <bool is_global, typename base_type>
26496  template <typename Class, typename Key>
26498  int mt_index = u_detail::register_usertype<Class, automagic_flags::all>(this->lua_state(), std::move(enrollments));
26499  usertype<Class> mt(this->lua_state(), -mt_index);
26500  lua_pop(this->lua_state(), 1);
26501  set(std::forward<Key>(key), mt);
26502  return mt;
26503  }
26504 
26505  template <bool is_global, typename base_type>
26506  template <typename Class, typename Key, typename Arg, typename... Args, typename>
26507  usertype<Class> basic_table_core<is_global, base_type>::new_usertype(Key&& key, Arg&& arg, Args&&... args) {
26508  constexpr automagic_flags enrollment_flags = meta::any_same_v<no_construction, meta::unqualified_t<Arg>, meta::unqualified_t<Args>...>
26509  ? clear_flags(automagic_flags::all, automagic_flags::default_constructor)
26510  : automagic_flags::all;
26512  enrollments.default_constructor = !detail::any_is_constructor_v<Arg, Args...>;
26513  enrollments.destructor = !detail::any_is_destructor_v<Arg, Args...>;
26514  usertype<Class> ut = this->new_usertype<Class>(std::forward<Key>(key), std::move(enrollments));
26515  static_assert(sizeof...(Args) % 2 == static_cast<std::size_t>(!detail::any_is_constructor_v<Arg>),
26516  "you must pass an even number of arguments to new_usertype after first passing a constructor");
26517  if constexpr (detail::any_is_constructor_v<Arg>) {
26518  ut.set(meta_function::construct, std::forward<Arg>(arg));
26519  ut.tuple_set(std::make_index_sequence<(sizeof...(Args)) / 2>(), std::forward_as_tuple(std::forward<Args>(args)...));
26520  }
26521  else {
26522  ut.tuple_set(std::make_index_sequence<(sizeof...(Args) + 1) / 2>(), std::forward_as_tuple(std::forward<Arg>(arg), std::forward<Args>(args)...));
26523  }
26524  return ut;
26525  }
26526 
26527  template <typename base_type>
26528  template <typename Key, typename Value>
26530  this->push();
26531  lua_State* L = this->lua_state();
26532  int target = lua_gettop(L);
26533  optional<u_detail::usertype_storage_base&> maybe_uts = nullopt;
26534  maybe_uts = u_detail::maybe_get_usertype_storage_base(L, target);
26535  if (maybe_uts) {
26536  u_detail::usertype_storage_base& uts = *maybe_uts;
26537  uts.set(L, std::forward<Key>(key), std::forward<Value>(value));
26538  return *this;
26539  }
26540  else {
26541  base_t::set(std::forward<Key>(key), std::forward<Value>(value));
26542  }
26543  this->pop();
26544  return *this;
26545  }
26546 
26547  namespace stack {
26548  template <>
26550  static metatable get(lua_State* L, int index = -1) {
26551  if (lua_getmetatable(L, index) == 0) {
26552  return metatable(L, ref_index(LUA_REFNIL));
26553  }
26554  return metatable(L, -1);
26555  }
26556  };
26557  } // namespace stack
26558 } // namespace sol
26559 
26560 // end of sol/table.hpp
26561 
26562 // beginning of sol/state.hpp
26563 
26564 // beginning of sol/state_view.hpp
26565 
26566 // beginning of sol/environment.hpp
26567 
26568 namespace sol {
26569 
26570  template <typename base_type>
26571  struct basic_environment : basic_table<base_type> {
26572  private:
26573  typedef basic_table<base_type> base_t;
26574 
26575  public:
26576  using base_t::lua_state;
26577 
26578  basic_environment() noexcept = default;
26579  basic_environment(const basic_environment&) = default;
26580  basic_environment(basic_environment&&) = default;
26581  basic_environment& operator=(const basic_environment&) = default;
26582  basic_environment& operator=(basic_environment&&) = default;
26583  basic_environment(const stack_reference& r) : basic_environment(r.lua_state(), r.stack_index()) {
26584  }
26585  basic_environment(stack_reference&& r) : basic_environment(r.lua_state(), r.stack_index()) {
26586  }
26587 
26588  basic_environment(lua_State* L, new_table nt) : base_t(L, std::move(nt)) {
26589  }
26590  template <bool b>
26591  basic_environment(lua_State* L, new_table t, const basic_reference<b>& fallback) : basic_environment(L, std::move(t)) {
26592  stack_table mt(L, new_table(0, 1));
26593  mt.set(meta_function::index, fallback);
26594  this->set(metatable_key, mt);
26595  mt.pop();
26596  }
26597 
26598  basic_environment(env_key_t, const stack_reference& extraction_target)
26599  : base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
26600 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26601  constructor_handler handler {};
26602  stack::check<env_key_t>(this->lua_state(), -1, handler);
26603 #endif // Safety
26604  lua_pop(this->lua_state(), 1);
26605  }
26606  template <bool b>
26607  basic_environment(env_key_t, const basic_reference<b>& extraction_target)
26608  : base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
26609 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26610  constructor_handler handler {};
26611  stack::check<env_key_t>(this->lua_state(), -1, handler);
26612 #endif // Safety
26613  lua_pop(this->lua_state(), 1);
26614  }
26615  basic_environment(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
26616 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26617  constructor_handler handler {};
26618  stack::check<basic_environment>(L, index, handler);
26619 #endif // Safety
26620  }
26621  basic_environment(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
26622 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26623  auto pp = stack::push_pop(*this);
26624  constructor_handler handler {};
26625  stack::check<basic_environment>(L, -1, handler);
26626 #endif // Safety
26627  }
26628  template <typename T,
26629  meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_environment>>, meta::neg<std::is_same<base_type, stack_reference>>,
26630  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26631  basic_environment(T&& r) noexcept : base_t(detail::no_safety, std::forward<T>(r)) {
26632 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26633  if (!is_environment<meta::unqualified_t<T>>::value) {
26634  auto pp = stack::push_pop(*this);
26635  constructor_handler handler {};
26636  stack::check<basic_environment>(lua_state(), -1, handler);
26637  }
26638 #endif // Safety
26639  }
26640  basic_environment(lua_nil_t r) noexcept : base_t(detail::no_safety, r) {
26641  }
26642 
26643  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26644  basic_environment(lua_State* L, T&& r) noexcept : base_t(detail::no_safety, L, std::forward<T>(r)) {
26645 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26646  if (!is_environment<meta::unqualified_t<T>>::value) {
26647  auto pp = stack::push_pop(*this);
26648  constructor_handler handler {};
26649  stack::check<basic_environment>(lua_state(), -1, handler);
26650  }
26651 #endif // Safety
26652  }
26653 
26654  template <typename T>
26655  bool set_on(const T& target) const {
26656  lua_State* L = target.lua_state();
26657  auto pp = stack::push_pop(target);
26658  int target_index = pp.index_of(target);
26659 #if SOL_LUA_VERSION_I_ < 502
26660  // Use lua_setfenv
26661  this->push();
26662  int success_result = lua_setfenv(L, target_index);
26663  return success_result != 0;
26664 #else
26665  // If this is a C function, the environment is always placed in
26666  // the first value, as is expected of sol2 (all upvalues have an empty name, "")
26667  if (lua_iscfunction(L, target_index) != 0) {
26668  const char* maybe_upvalue_name = lua_getupvalue(L, target_index, 1);
26669  if (maybe_upvalue_name == nullptr) {
26670  return false;
26671  }
26672  string_view upvalue_name(maybe_upvalue_name);
26673  if (upvalue_name == "") {
26674  this->push();
26675  const char* success = lua_setupvalue(L, target_index, 1);
26676  if (success == nullptr) {
26677  // left things alone on the stack, pop them off
26678  lua_pop(L, 2);
26679  return false;
26680  }
26681  lua_pop(L, 1);
26682  return true;
26683  }
26684  lua_pop(L, 1);
26685  return false;
26686  }
26687  else {
26688  // Must search for the right upvalue target on index
26689  for (int upvalue_index = 1;; ++upvalue_index) {
26690  const char* maybe_upvalue_name = lua_getupvalue(L, target_index, upvalue_index);
26691  if (maybe_upvalue_name == nullptr) {
26692  break;
26693  }
26694  string_view upvalue_name(maybe_upvalue_name);
26695  if (upvalue_name == "_ENV") {
26696  lua_pop(L, 1);
26697  this->push();
26698  const char* success = lua_setupvalue(L, target_index, upvalue_index);
26699  if (success == nullptr) {
26700  // left things alone on the stack, pop them off
26701  lua_pop(L, 1);
26702  break;
26703  }
26704  // whether or not we succeeded, we found _ENV
26705  // so we need to break
26706  return true;
26707  }
26708  lua_pop(L, 1);
26709  }
26710  // if we get here,
26711  // we did not find an _ENV here...
26712  return false;
26713  }
26714 #endif
26715  }
26716  };
26717 
26718  template <typename T, typename E>
26719  bool set_environment(const basic_environment<E>& env, const T& target) {
26720  return env.set_on(target);
26721  }
26722 
26723  template <typename E = reference, typename T>
26724  basic_environment<E> get_environment(const T& target) {
26725  lua_State* L = target.lua_state();
26726  auto pp = stack::pop_n(L, stack::push_environment_of(target));
26727  return basic_environment<E>(L, -1);
26728  }
26729 
26732 
26733  this_environment() : env(nullopt) {
26734  }
26735  this_environment(environment e) : env(std::move(e)) {
26736  }
26737  this_environment(const this_environment&) = default;
26738  this_environment(this_environment&&) = default;
26739  this_environment& operator=(const this_environment&) = default;
26740  this_environment& operator=(this_environment&&) = default;
26741 
26742  explicit operator bool() const {
26743  return static_cast<bool>(env);
26744  }
26745 
26746  operator optional<environment>&() {
26747  return env;
26748  }
26749 
26750  operator const optional<environment>&() const {
26751  return env;
26752  }
26753 
26754  operator environment&() {
26755  return env.value();
26756  }
26757 
26758  operator const environment&() const {
26759  return env.value();
26760  }
26761  };
26762 
26763  namespace stack {
26764  template <>
26766  static environment get(lua_State* L, int index, record& tracking) {
26767  tracking.use(1);
26768  return get_environment(stack_reference(L, raw_index(index)));
26769  }
26770  };
26771 
26772  template <>
26774  static this_environment get(lua_State* L, int, record& tracking) {
26775  tracking.use(0);
26776  lua_Debug info;
26777  // Level 0 means current function (this C function, which may or may not be useful for us?)
26778  // Level 1 means next call frame up the stack. (Can be nothing if function called directly from C++ with lua_p/call)
26779  int pre_stack_size = lua_gettop(L);
26780  if (lua_getstack(L, 1, &info) != 1) {
26781  if (lua_getstack(L, 0, &info) != 1) {
26782  lua_settop(L, pre_stack_size);
26783  return this_environment();
26784  }
26785  }
26786  if (lua_getinfo(L, "f", &info) == 0) {
26787  lua_settop(L, pre_stack_size);
26788  return this_environment();
26789  }
26790 
26791  stack_reference f(L, -1);
26792  environment env(env_key, f);
26793  if (!env.valid()) {
26794  lua_settop(L, pre_stack_size);
26795  return this_environment();
26796  }
26797  return this_environment(std::move(env));
26798  }
26799  };
26800  } // namespace stack
26801 } // namespace sol
26802 
26803 // end of sol/environment.hpp
26804 
26805 // beginning of sol/load_result.hpp
26806 
26807 #include <cstdint>
26808 
26809 namespace sol {
26810  struct load_result : public proxy_base<load_result> {
26811  private:
26812  lua_State* L;
26813  int index;
26814  int returncount;
26815  int popcount;
26816  load_status err;
26817 
26818  public:
26819  load_result() noexcept : load_result(nullptr) {}
26820  load_result(lua_State* Ls, int stackindex = -1, int retnum = 0, int popnum = 0, load_status lerr = load_status::ok) noexcept
26821  : L(Ls), index(stackindex), returncount(retnum), popcount(popnum), err(lerr) {
26822  }
26823 
26824  // We do not want anyone to copy these around willy-nilly
26825  // Will likely break people, but also will probably get rid of quiet bugs that have
26826  // been lurking. (E.g., Vanilla Lua will just quietly discard over-pops and under-pops:
26827  // LuaJIT and other Lua engines will implode and segfault at random later times.)
26828  load_result(const load_result&) = delete;
26829  load_result& operator=(const load_result&) = delete;
26830 
26831  load_result(load_result&& o) noexcept : L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) {
26832  // Must be manual, otherwise destructor will screw us
26833  // return count being 0 is enough to keep things clean
26834  // but we will be thorough
26835  o.L = nullptr;
26836  o.index = 0;
26837  o.returncount = 0;
26838  o.popcount = 0;
26839  o.err = load_status::syntax;
26840  }
26841  load_result& operator=(load_result&& o) noexcept {
26842  L = o.L;
26843  index = o.index;
26844  returncount = o.returncount;
26845  popcount = o.popcount;
26846  err = o.err;
26847  // Must be manual, otherwise destructor will screw us
26848  // return count being 0 is enough to keep things clean
26849  // but we will be thorough
26850  o.L = nullptr;
26851  o.index = 0;
26852  o.returncount = 0;
26853  o.popcount = 0;
26854  o.err = load_status::syntax;
26855  return *this;
26856  }
26857 
26858  load_status status() const noexcept {
26859  return err;
26860  }
26861 
26862  bool valid() const noexcept {
26863  return status() == load_status::ok;
26864  }
26865 
26866  template <typename T>
26867  T get() const {
26868  using UT = meta::unqualified_t<T>;
26869  if constexpr (meta::is_optional_v<UT>) {
26870  using ValueType = typename UT::value_type;
26871  if constexpr (std::is_same_v<ValueType, error>) {
26872  if (valid()) {
26873  return UT(nullopt);
26874  }
26875  return error(detail::direct_error, stack::get<std::string>(L, index));
26876  }
26877  else {
26878  if (!valid()) {
26879  return UT(nullopt);
26880  }
26881  return stack::get<UT>(L, index);
26882  }
26883  }
26884  else {
26885  if constexpr (std::is_same_v<T, error>) {
26886 #if SOL_IS_ON(SOL_SAFE_PROXIES)
26887  if (valid()) {
26888  type_panic_c_str(L, index, type_of(L, index), type::none, "expecting an error type (a string, from Lua)");
26889  }
26890 #endif // Check proxy type's safety
26891  return error(detail::direct_error, stack::get<std::string>(L, index));
26892  }
26893  else {
26894 #if SOL_IS_ON(SOL_SAFE_PROXIES)
26895  if (!valid()) {
26896  type_panic_c_str(L, index, type_of(L, index), type::none);
26897  }
26898 #endif // Check proxy type's safety
26899  return stack::get<T>(L, index);
26900  }
26901  }
26902  }
26903 
26904  template <typename... Ret, typename... Args>
26905  decltype(auto) call(Args&&... args) {
26906  return get<protected_function>().template call<Ret...>(std::forward<Args>(args)...);
26907  }
26908 
26909  template <typename... Args>
26910  decltype(auto) operator()(Args&&... args) {
26911  return call<>(std::forward<Args>(args)...);
26912  }
26913 
26914  lua_State* lua_state() const noexcept {
26915  return L;
26916  };
26917  int stack_index() const noexcept {
26918  return index;
26919  };
26920 
26921  ~load_result() {
26922  if (L != nullptr) {
26923  stack::remove(L, index, popcount);
26924  }
26925  }
26926  };
26927 } // namespace sol
26928 
26929 // end of sol/load_result.hpp
26930 
26931 // beginning of sol/state_handling.hpp
26932 
26933 // beginning of sol/lua_value.hpp
26934 
26935 namespace sol {
26936  struct lua_value {
26937  public:
26938  struct arr : detail::ebco<std::initializer_list<lua_value>> {
26939  private:
26941 
26942  public:
26943  using base_t::base_t;
26944  };
26945 
26946  private:
26947  template <typename T>
26949  = meta::any<meta::is_specialization_of<T, std::initializer_list>, std::is_same<T, reference>, std::is_same<T, arr>>;
26950 
26951  template <typename T>
26953 
26954  static lua_State*& thread_local_lua_state() {
26955 #if SOL_IS_ON(SOL_USE_THREAD_LOCAL)
26956  static thread_local lua_State* L = nullptr;
26957 #else
26958  static lua_State* L = nullptr;
26959 #endif
26960  return L;
26961  }
26962 
26963  reference ref_value;
26964 
26965  public:
26966  static void set_lua_state(lua_State* L) {
26967  thread_local_lua_state() = L;
26968  }
26969 
26970  template <typename T, meta::disable<is_reference_or_lua_value_init_list<meta::unqualified_t<T>>> = meta::enabler>
26971  lua_value(lua_State* L_, T&& value) : lua_value(((set_lua_state(L_)), std::forward<T>(value))) {
26972  }
26973 
26974  template <typename T, meta::disable<is_lua_value_single_constructible<meta::unqualified_t<T>>> = meta::enabler>
26975  lua_value(T&& value) : ref_value(make_reference(thread_local_lua_state(), std::forward<T>(value))) {
26976  }
26977 
26978  lua_value(lua_State* L_, std::initializer_list<std::pair<lua_value, lua_value>> il)
26979  : lua_value([&L_, &il]() {
26980  set_lua_state(L_);
26981  return std::move(il);
26982  }()) {
26983  }
26984 
26985  lua_value(std::initializer_list<std::pair<lua_value, lua_value>> il) : ref_value(make_reference(thread_local_lua_state(), std::move(il))) {
26986  }
26987 
26988  lua_value(lua_State* L_, arr il)
26989  : lua_value([&L_, &il]() {
26990  set_lua_state(L_);
26991  return std::move(il);
26992  }()) {
26993  }
26994 
26995  lua_value(arr il) : ref_value(make_reference(thread_local_lua_state(), std::move(il.value()))) {
26996  }
26997 
26998  lua_value(lua_State* L_, reference r)
26999  : lua_value([&L_, &r]() {
27000  set_lua_state(L_);
27001  return std::move(r);
27002  }()) {
27003  }
27004 
27005  lua_value(reference r) : ref_value(std::move(r)) {
27006  }
27007 
27008  lua_value(const lua_value&) noexcept = default;
27009  lua_value(lua_value&&) = default;
27010  lua_value& operator=(const lua_value&) = default;
27011  lua_value& operator=(lua_value&&) = default;
27012 
27013  const reference& value() const& {
27014  return ref_value;
27015  }
27016 
27017  reference& value() & {
27018  return ref_value;
27019  }
27020 
27021  reference&& value() && {
27022  return std::move(ref_value);
27023  }
27024 
27025  template <typename T>
27026  decltype(auto) as() const {
27027  ref_value.push();
27028  return stack::pop<T>(ref_value.lua_state());
27029  }
27030 
27031  template <typename T>
27032  bool is() const {
27033  int r = ref_value.registry_index();
27034  if (r == LUA_REFNIL)
27035  return meta::any_same<meta::unqualified_t<T>, lua_nil_t, nullopt_t, std::nullptr_t>::value ? true : false;
27036  if (r == LUA_NOREF)
27037  return false;
27038  auto pp = stack::push_pop(ref_value);
27039  return stack::check<T>(ref_value.lua_state(), -1, &no_panic);
27040  }
27041  };
27042 
27043  using array_value = typename lua_value::arr;
27044 
27045  namespace stack {
27046  template <>
27048  static int push(lua_State* L, const lua_value& lv) {
27049  return stack::push(L, lv.value());
27050  }
27051 
27052  static int push(lua_State* L, lua_value&& lv) {
27053  return stack::push(L, std::move(lv).value());
27054  }
27055  };
27056 
27057  template <>
27059  static lua_value get(lua_State* L, int index, record& tracking) {
27060  return lua_value(L, stack::get<reference>(L, index, tracking));
27061  }
27062  };
27063  } // namespace stack
27064 } // namespace sol
27065 
27066 // end of sol/lua_value.hpp
27067 
27068 #if SOL_IS_ON(SOL_PRINT_ERRORS)
27069 #include <iostream>
27070 #endif
27071 
27072 namespace sol {
27073  inline void register_main_thread(lua_State* L) {
27074 #if SOL_LUA_VERSION_I_ < 502
27075  if (L == nullptr) {
27076  lua_pushnil(L);
27077  lua_setglobal(L, detail::default_main_thread_name());
27078  return;
27079  }
27080  lua_pushthread(L);
27081  lua_setglobal(L, detail::default_main_thread_name());
27082 #else
27083  (void)L;
27084 #endif
27085  }
27086 
27087  inline int default_at_panic(lua_State* L) {
27088 #if SOL_IS_OFF(SOL_EXCEPTIONS)
27089  (void)L;
27090  return -1;
27091 #else
27092  size_t messagesize;
27093  const char* message = lua_tolstring(L, -1, &messagesize);
27094  if (message) {
27095  std::string err(message, messagesize);
27096  lua_settop(L, 0);
27097 #if SOL_IS_ON(SOL_PRINT_ERRORS)
27098  std::cerr << "[sol2] An error occurred and panic has been invoked: ";
27099  std::cerr << err;
27100  std::cerr << std::endl;
27101 #endif
27102  throw error(err);
27103  }
27104  lua_settop(L, 0);
27105  throw error(std::string("An unexpected error occurred and panic has been invoked"));
27106 #endif // Printing Errors
27107  }
27108 
27109  inline int default_traceback_error_handler(lua_State* L) {
27110  std::string msg = "An unknown error has triggered the default error handler";
27111  optional<string_view> maybetopmsg = stack::unqualified_check_get<string_view>(L, 1, &no_panic);
27112  if (maybetopmsg) {
27113  const string_view& topmsg = maybetopmsg.value();
27114  msg.assign(topmsg.data(), topmsg.size());
27115  }
27116  luaL_traceback(L, L, msg.c_str(), 1);
27117  optional<string_view> maybetraceback = stack::unqualified_check_get<string_view>(L, -1, &no_panic);
27118  if (maybetraceback) {
27119  const string_view& traceback = maybetraceback.value();
27120  msg.assign(traceback.data(), traceback.size());
27121  }
27122 #if SOL_IS_ON(SOL_PRINT_ERRORS)
27123  // std::cerr << "[sol2] An error occurred and was caught in traceback: ";
27124  // std::cerr << msg;
27125  // std::cerr << std::endl;
27126 #endif // Printing
27127  return stack::push(L, msg);
27128  }
27129 
27130  inline void set_default_state(lua_State* L, lua_CFunction panic_function = &default_at_panic,
27131  lua_CFunction traceback_function = c_call<decltype(&default_traceback_error_handler), &default_traceback_error_handler>,
27132  exception_handler_function exf = detail::default_exception_handler) {
27133  lua_atpanic(L, panic_function);
27134  protected_function::set_default_handler(object(L, in_place, traceback_function));
27135  set_default_exception_handler(L, exf);
27136  register_main_thread(L);
27137  stack::luajit_exception_handler(L);
27138  lua_value::set_lua_state(L);
27139  }
27140 
27141  inline std::size_t total_memory_used(lua_State* L) {
27142  std::size_t kb = static_cast<std::size_t>(lua_gc(L, LUA_GCCOUNT, 0));
27143  kb *= 1024;
27144  kb += static_cast<std::size_t>(lua_gc(L, LUA_GCCOUNTB, 0));
27145  return kb;
27146  }
27147 
27148  inline protected_function_result script_pass_on_error(lua_State*, protected_function_result result) {
27149  return result;
27150  }
27151 
27152  inline protected_function_result script_throw_on_error(lua_State* L, protected_function_result result) {
27153  type t = type_of(L, result.stack_index());
27154  std::string err = "sol: ";
27155  err += to_string(result.status());
27156  err += " error";
27157 #if SOL_IS_ON(SOL_EXCEPTIONS)
27158  std::exception_ptr eptr = std::current_exception();
27159  if (eptr) {
27160  err += " with a ";
27161  try {
27162  std::rethrow_exception(eptr);
27163  }
27164  catch (const std::exception& ex) {
27165  err += "std::exception -- ";
27166  err.append(ex.what());
27167  }
27168  catch (const std::string& message) {
27169  err += "thrown message -- ";
27170  err.append(message);
27171  }
27172  catch (const char* message) {
27173  err += "thrown message -- ";
27174  err.append(message);
27175  }
27176  catch (...) {
27177  err.append("thrown but unknown type, cannot serialize into error message");
27178  }
27179  }
27180 #endif // serialize exception information if possible
27181  if (t == type::string) {
27182  err += ": ";
27183  string_view serr = stack::unqualified_get<string_view>(L, result.stack_index());
27184  err.append(serr.data(), serr.size());
27185  }
27186 #if SOL_IS_ON(SOL_PRINT_ERRORS)
27187  std::cerr << "[sol2] An error occurred and has been passed to an error handler: ";
27188  std::cerr << err;
27189  std::cerr << std::endl;
27190 #endif
27191  // replacing information of stack error into pfr
27192  int target = result.stack_index();
27193  if (result.pop_count() > 0) {
27194  stack::remove(L, target, result.pop_count());
27195  }
27196  stack::push(L, err);
27197  int top = lua_gettop(L);
27198  int towards = top - target;
27199  if (towards != 0) {
27200  lua_rotate(L, top, towards);
27201  }
27202 #if SOL_IS_OFF(SOL_EXCEPTIONS)
27203  return result;
27204 #else
27205  // just throw our error
27206  throw error(detail::direct_error, err);
27207 #endif // If exceptions are allowed
27208  }
27209 
27210  inline protected_function_result script_default_on_error(lua_State* L, protected_function_result pfr) {
27211 #if SOL_IS_ON(SOL_DEFAULT_PASS_ON_ERROR)
27212  return script_pass_on_error(L, std::move(pfr));
27213 #else
27214  return script_throw_on_error(L, std::move(pfr));
27215 #endif
27216  }
27217 
27218  namespace stack {
27219  inline error get_traceback_or_errors(lua_State* L) {
27220  int p = default_traceback_error_handler(L);
27221  sol::error err = stack::get<sol::error>(L, -p);
27222  lua_pop(L, p);
27223  return err;
27224  }
27225  } // namespace stack
27226 } // namespace sol
27227 
27228 // end of sol/state_handling.hpp
27229 
27230 #include <memory>
27231 #include <cstddef>
27232 
27233 namespace sol {
27234 
27235  class state_view {
27236  private:
27237  lua_State* L;
27238  table reg;
27239  global_table global;
27240 
27241  optional<object> is_loaded_package(const std::string& key) {
27242  auto loaded = reg.traverse_get<optional<object>>("_LOADED", key);
27243  bool is53mod = loaded && !(loaded->is<bool>() && !loaded->as<bool>());
27244  if (is53mod)
27245  return loaded;
27246 #if SOL_LUA_VERSION_I_ <= 501
27247  auto loaded51 = global.traverse_get<optional<object>>("package", "loaded", key);
27248  bool is51mod = loaded51 && !(loaded51->is<bool>() && !loaded51->as<bool>());
27249  if (is51mod)
27250  return loaded51;
27251 #endif
27252  return nullopt;
27253  }
27254 
27255  template <typename T>
27256  void ensure_package(const std::string& key, T&& sr) {
27257 #if SOL_LUA_VERSION_I_ <= 501
27258  auto pkg = global["package"];
27259  if (!pkg.valid()) {
27260  pkg = create_table_with("loaded", create_table_with(key, sr));
27261  }
27262  else {
27263  auto ld = pkg["loaded"];
27264  if (!ld.valid()) {
27265  ld = create_table_with(key, sr);
27266  }
27267  else {
27268  ld[key] = sr;
27269  }
27270  }
27271 #endif
27272  auto loaded = reg["_LOADED"];
27273  if (!loaded.valid()) {
27274  loaded = create_table_with(key, sr);
27275  }
27276  else {
27277  loaded[key] = sr;
27278  }
27279  }
27280 
27281  template <typename Fx>
27282  object require_core(const std::string& key, Fx&& action, bool create_global = true) {
27283  optional<object> loaded = is_loaded_package(key);
27284  if (loaded && loaded->valid())
27285  return std::move(*loaded);
27286  int before = lua_gettop(L);
27287  action();
27288  int after = lua_gettop(L);
27289  if (before == after) {
27290  // I mean, you were supposed to return
27291  // something, ANYTHING, from your requires script. I guess I'll just
27292  // but some trash in here, it's on you after that?
27293  ensure_package(key, static_cast<void*>(L));
27294  return object(L, lua_nil);
27295  }
27296  stack_reference sr(L, -1);
27297  if (create_global)
27298  set(key, sr);
27299  ensure_package(key, sr);
27300  return stack::pop<object>(L);
27301  }
27302 
27303  public:
27304  using iterator = typename global_table::iterator;
27305  using const_iterator = typename global_table::const_iterator;
27306 
27307  state_view(lua_State* Ls) : L(Ls), reg(Ls, LUA_REGISTRYINDEX), global(Ls, global_tag) {
27308  }
27309 
27310  state_view(this_state Ls) : state_view(Ls.L) {
27311  }
27312 
27313  lua_State* lua_state() const {
27314  return L;
27315  }
27316 
27317  template <typename... Args>
27318  void open_libraries(Args&&... args) {
27319  static_assert(meta::all_same<lib, meta::unqualified_t<Args>...>::value, "all types must be libraries");
27320  if constexpr (sizeof...(args) == 0) {
27321  luaL_openlibs(L);
27322  return;
27323  }
27324  else {
27325  lib libraries[1 + sizeof...(args)] = { lib::count, std::forward<Args>(args)... };
27326 
27327  for (auto&& library : libraries) {
27328  switch (library) {
27329 #if SOL_LUA_VERSION_I_ <= 501 && SOL_IS_ON(SOL_USE_LUAJIT)
27330  case lib::coroutine:
27331 #endif // luajit opens coroutine base stuff
27332  case lib::base:
27333  luaL_requiref(L, "base", luaopen_base, 1);
27334  lua_pop(L, 1);
27335  break;
27336  case lib::package:
27337  luaL_requiref(L, "package", luaopen_package, 1);
27338  lua_pop(L, 1);
27339  break;
27340 #if SOL_IS_OFF(SOL_USE_LUAJIT)
27341  case lib::coroutine:
27342 #if SOL_LUA_VERSION_I_ > 501
27343  luaL_requiref(L, "coroutine", luaopen_coroutine, 1);
27344  lua_pop(L, 1);
27345 #endif // Lua 5.2+ only
27346  break;
27347 #endif // Not LuaJIT - comes builtin
27348  case lib::string:
27349  luaL_requiref(L, "string", luaopen_string, 1);
27350  lua_pop(L, 1);
27351  break;
27352  case lib::table:
27353  luaL_requiref(L, "table", luaopen_table, 1);
27354  lua_pop(L, 1);
27355  break;
27356  case lib::math:
27357  luaL_requiref(L, "math", luaopen_math, 1);
27358  lua_pop(L, 1);
27359  break;
27360  case lib::bit32:
27361 #if SOL_IS_ON(SOL_USE_LUAJIT)
27362  luaL_requiref(L, "bit32", luaopen_bit, 1);
27363  lua_pop(L, 1);
27364 #elif SOL_IS_ON(SOL_LUA_BIT32_LIB)
27365  luaL_requiref(L, "bit32", luaopen_bit32, 1);
27366  lua_pop(L, 1);
27367 #else
27368 #endif
27369  break;
27370  case lib::io:
27371  luaL_requiref(L, "io", luaopen_io, 1);
27372  lua_pop(L, 1);
27373  break;
27374  case lib::os:
27375  luaL_requiref(L, "os", luaopen_os, 1);
27376  lua_pop(L, 1);
27377  break;
27378  case lib::debug:
27379  luaL_requiref(L, "debug", luaopen_debug, 1);
27380  lua_pop(L, 1);
27381  break;
27382  case lib::utf8:
27383 #if SOL_LUA_VERSION_I_ > 502 && SOL_IS_OFF(SOL_USE_LUAJIT)
27384  luaL_requiref(L, "utf8", luaopen_utf8, 1);
27385  lua_pop(L, 1);
27386 #endif // Lua 5.3+ only
27387  break;
27388  case lib::ffi:
27389 #if SOL_IS_ON(SOL_USE_LUAJIT) && SOL_IS_OFF(SOL_LUAJIT_FFI_DISABLED)
27390  luaL_requiref(L, "ffi", luaopen_ffi, 1);
27391  lua_pop(L, 1);
27392 #endif // LuaJIT only
27393  break;
27394  case lib::jit:
27395 #if SOL_IS_ON(SOL_USE_LUAJIT)
27396  luaL_requiref(L, "jit", luaopen_jit, 0);
27397  lua_pop(L, 1);
27398 #endif // LuaJIT Only
27399  break;
27400  case lib::count:
27401  default:
27402  break;
27403  }
27404  }
27405  }
27406  }
27407 
27408  object require(const std::string& key, lua_CFunction open_function, bool create_global = true) {
27409  luaL_requiref(L, key.c_str(), open_function, create_global ? 1 : 0);
27410  return stack::pop<object>(L);
27411  }
27412 
27413  object require_script(const std::string& key, const string_view& code, bool create_global = true,
27414  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27415  auto action = [this, &code, &chunkname, &mode]() { stack::script(L, code, chunkname, mode); };
27416  return require_core(key, action, create_global);
27417  }
27418 
27419  object require_file(const std::string& key, const std::string& filename, bool create_global = true, load_mode mode = load_mode::any) {
27420  auto action = [this, &filename, &mode]() { stack::script_file(L, filename, mode); };
27421  return require_core(key, action, create_global);
27422  }
27423 
27424  void clear_package_loaders() {
27425  optional<table> maybe_package = this->global["package"];
27426  if (!maybe_package) {
27427  // package lib wasn't opened
27428  // open package lib
27429  return;
27430  }
27431  table& package = *maybe_package;
27432  // yay for version differences...
27433  // one day Lua 5.1 will die a peaceful death
27434  // and its old bones will find blissful rest
27435  auto loaders_proxy = package
27436 #if SOL_LUA_VERSION_I_ < 502
27437  ["loaders"]
27438 #else
27439  ["searchers"]
27440 #endif
27441  ;
27442  if (!loaders_proxy.valid()) {
27443  // nothing to clear
27444  return;
27445  }
27446  // we need to create the table for loaders
27447  // table does not exist, so create and move forward
27448  loaders_proxy = new_table(1, 0);
27449  }
27450 
27451  template <typename Fx>
27452  void add_package_loader(Fx&& fx, bool clear_all_package_loaders = false) {
27453  optional<table> maybe_package = this->global["package"];
27454  if (!maybe_package) {
27455  // package lib wasn't opened
27456  // open package lib
27457  return;
27458  }
27459  table& package = *maybe_package;
27460  // yay for version differences...
27461  // one day Lua 5.1 will die a peaceful death
27462  // and its old bones will find blissful rest
27463  auto loaders_proxy = package
27464 #if SOL_LUA_VERSION_I_ < 502
27465  ["loaders"]
27466 #else
27467  ["searchers"]
27468 #endif
27469  ;
27470  bool make_new_table = clear_all_package_loaders || !loaders_proxy.valid();
27471  if (make_new_table) {
27472  // we need to create the table for loaders
27473  // table does not exist, so create and move forward
27474  loaders_proxy = new_table(1, 0);
27475  }
27476  optional<table> maybe_loaders = loaders_proxy;
27477  if (!maybe_loaders) {
27478  // loaders/searches
27479  // thing exists in package, but it
27480  // ain't a table or a table-alike...!
27481  return;
27482  }
27483  table loaders = loaders_proxy;
27484  loaders.add(std::forward<Fx>(fx));
27485  }
27486 
27487  template <typename E>
27488  protected_function_result do_reader(lua_Reader reader, void* data, const basic_environment<E>& env,
27489  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27490  detail::typical_chunk_name_t basechunkname = {};
27491  const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
27492  load_status x = static_cast<load_status>(lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()));
27493  if (x != load_status::ok) {
27494  return protected_function_result(L, absolute_index(L, -1), 0, 1, static_cast<call_status>(x));
27495  }
27497  set_environment(env, pf);
27498  return pf();
27499  }
27500 
27501  protected_function_result do_reader(
27502  lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27503  detail::typical_chunk_name_t basechunkname = {};
27504  const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
27505  load_status x = static_cast<load_status>(lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()));
27506  if (x != load_status::ok) {
27507  return protected_function_result(L, absolute_index(L, -1), 0, 1, static_cast<call_status>(x));
27508  }
27510  return pf();
27511  }
27512 
27513  template <typename E>
27514  protected_function_result do_string(const string_view& code, const basic_environment<E>& env,
27515  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27516  detail::typical_chunk_name_t basechunkname = {};
27517  const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
27518  load_status x = static_cast<load_status>(luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str()));
27519  if (x != load_status::ok) {
27520  return protected_function_result(L, absolute_index(L, -1), 0, 1, static_cast<call_status>(x));
27521  }
27523  set_environment(env, pf);
27524  return pf();
27525  }
27526 
27527  protected_function_result do_string(
27528  const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27529  detail::typical_chunk_name_t basechunkname = {};
27530  const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
27531  load_status x = static_cast<load_status>(luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str()));
27532  if (x != load_status::ok) {
27533  return protected_function_result(L, absolute_index(L, -1), 0, 1, static_cast<call_status>(x));
27534  }
27536  return pf();
27537  }
27538 
27539  template <typename E>
27540  protected_function_result do_file(const std::string& filename, const basic_environment<E>& env, load_mode mode = load_mode::any) {
27541  load_status x = static_cast<load_status>(luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str()));
27542  if (x != load_status::ok) {
27543  return protected_function_result(L, absolute_index(L, -1), 0, 1, static_cast<call_status>(x));
27544  }
27546  set_environment(env, pf);
27547  return pf();
27548  }
27549 
27550  protected_function_result do_file(const std::string& filename, load_mode mode = load_mode::any) {
27551  load_status x = static_cast<load_status>(luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str()));
27552  if (x != load_status::ok) {
27553  return protected_function_result(L, absolute_index(L, -1), 0, 1, static_cast<call_status>(x));
27554  }
27556  return pf();
27557  }
27558 
27559  template <typename Fx,
27560  meta::disable_any<meta::is_string_constructible<meta::unqualified_t<Fx>>,
27562  protected_function_result safe_script(
27563  lua_Reader reader, void* data, Fx&& on_error, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27564  protected_function_result pfr = do_reader(reader, data, chunkname, mode);
27565  if (!pfr.valid()) {
27566  return on_error(L, std::move(pfr));
27567  }
27568  return pfr;
27569  }
27570 
27571  protected_function_result safe_script(
27572  lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27573  return safe_script(reader, data, script_default_on_error, chunkname, mode);
27574  }
27575 
27576  template <typename Fx,
27577  meta::disable_any<meta::is_string_constructible<meta::unqualified_t<Fx>>,
27578  meta::is_specialization_of<meta::unqualified_t<Fx>, basic_environment>> = meta::enabler>
27579  protected_function_result safe_script(
27580  const string_view& code, Fx&& on_error, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27581  protected_function_result pfr = do_string(code, chunkname, mode);
27582  if (!pfr.valid()) {
27583  return on_error(L, std::move(pfr));
27584  }
27585  return pfr;
27586  }
27587 
27588  template <typename Fx, typename E>
27589  protected_function_result safe_script(const string_view& code, const basic_environment<E>& env, Fx&& on_error,
27590  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27591  protected_function_result pfr = do_string(code, env, chunkname, mode);
27592  if (!pfr.valid()) {
27593  return on_error(L, std::move(pfr));
27594  }
27595  return pfr;
27596  }
27597 
27598  template <typename E>
27599  protected_function_result safe_script(const string_view& code, const basic_environment<E>& env,
27600  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27601  return safe_script(code, env, script_default_on_error, chunkname, mode);
27602  }
27603 
27604  protected_function_result safe_script(
27605  const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27606  return safe_script(code, script_default_on_error, chunkname, mode);
27607  }
27608 
27609  template <typename Fx,
27610  meta::disable_any<meta::is_string_constructible<meta::unqualified_t<Fx>>,
27611  meta::is_specialization_of<meta::unqualified_t<Fx>, basic_environment>> = meta::enabler>
27612  protected_function_result safe_script_file(const std::string& filename, Fx&& on_error, load_mode mode = load_mode::any) {
27613  protected_function_result pfr = do_file(filename, mode);
27614  if (!pfr.valid()) {
27615  return on_error(L, std::move(pfr));
27616  }
27617  return pfr;
27618  }
27619 
27620  template <typename Fx, typename E>
27621  protected_function_result safe_script_file(
27622  const std::string& filename, const basic_environment<E>& env, Fx&& on_error, load_mode mode = load_mode::any) {
27623  protected_function_result pfr = do_file(filename, env, mode);
27624  if (!pfr.valid()) {
27625  return on_error(L, std::move(pfr));
27626  }
27627  return pfr;
27628  }
27629 
27630  template <typename E>
27631  protected_function_result safe_script_file(const std::string& filename, const basic_environment<E>& env, load_mode mode = load_mode::any) {
27632  return safe_script_file(filename, env, script_default_on_error, mode);
27633  }
27634 
27635  protected_function_result safe_script_file(const std::string& filename, load_mode mode = load_mode::any) {
27636  return safe_script_file(filename, script_default_on_error, mode);
27637  }
27638 
27639  template <typename E>
27640  unsafe_function_result unsafe_script(lua_Reader reader, void* data, const basic_environment<E>& env,
27641  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27642  detail::typical_chunk_name_t basechunkname = {};
27643  const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
27644  int index = lua_gettop(L);
27645  if (lua_load(L, reader, data, chunknametarget, to_string(mode).c_str())) {
27646  lua_error(L);
27647  }
27648  set_environment(env, stack_reference(L, raw_index(index + 1)));
27649  if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
27650  lua_error(L);
27651  }
27652  int postindex = lua_gettop(L);
27653  int returns = postindex - index;
27654  return unsafe_function_result(L, (std::max)(postindex - (returns - 1), 1), returns);
27655  }
27656 
27657  unsafe_function_result unsafe_script(
27658  lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27659  int index = lua_gettop(L);
27660  stack::script(L, reader, data, chunkname, mode);
27661  int postindex = lua_gettop(L);
27662  int returns = postindex - index;
27663  return unsafe_function_result(L, (std::max)(postindex - (returns - 1), 1), returns);
27664  }
27665 
27666  template <typename E>
27667  unsafe_function_result unsafe_script(const string_view& code, const basic_environment<E>& env,
27668  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27669  detail::typical_chunk_name_t basechunkname = {};
27670  const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
27671  int index = lua_gettop(L);
27672  if (luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str())) {
27673  lua_error(L);
27674  }
27675  set_environment(env, stack_reference(L, raw_index(index + 1)));
27676  if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
27677  lua_error(L);
27678  }
27679  int postindex = lua_gettop(L);
27680  int returns = postindex - index;
27681  return unsafe_function_result(L, (std::max)(postindex - (returns - 1), 1), returns);
27682  }
27683 
27684  unsafe_function_result unsafe_script(
27685  const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27686  int index = lua_gettop(L);
27687  stack::script(L, code, chunkname, mode);
27688  int postindex = lua_gettop(L);
27689  int returns = postindex - index;
27690  return unsafe_function_result(L, (std::max)(postindex - (returns - 1), 1), returns);
27691  }
27692 
27693  template <typename E>
27694  unsafe_function_result unsafe_script_file(const std::string& filename, const basic_environment<E>& env, load_mode mode = load_mode::any) {
27695  int index = lua_gettop(L);
27696  if (luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str())) {
27697  lua_error(L);
27698  }
27699  set_environment(env, stack_reference(L, raw_index(index + 1)));
27700  if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
27701  lua_error(L);
27702  }
27703  int postindex = lua_gettop(L);
27704  int returns = postindex - index;
27705  return unsafe_function_result(L, (std::max)(postindex - (returns - 1), 1), returns);
27706  }
27707 
27708  unsafe_function_result unsafe_script_file(const std::string& filename, load_mode mode = load_mode::any) {
27709  int index = lua_gettop(L);
27710  stack::script_file(L, filename, mode);
27711  int postindex = lua_gettop(L);
27712  int returns = postindex - index;
27713  return unsafe_function_result(L, (std::max)(postindex - (returns - 1), 1), returns);
27714  }
27715 
27716  template <typename Fx,
27717  meta::disable_any<meta::is_string_constructible<meta::unqualified_t<Fx>>,
27718  meta::is_specialization_of<meta::unqualified_t<Fx>, basic_environment>> = meta::enabler>
27720  const string_view& code, Fx&& on_error, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27721  return safe_script(code, std::forward<Fx>(on_error), chunkname, mode);
27722  }
27723 
27724  template <typename Fx,
27725  meta::disable_any<meta::is_string_constructible<meta::unqualified_t<Fx>>,
27726  meta::is_specialization_of<meta::unqualified_t<Fx>, basic_environment>> = meta::enabler>
27727  protected_function_result script_file(const std::string& filename, Fx&& on_error, load_mode mode = load_mode::any) {
27728  return safe_script_file(filename, std::forward<Fx>(on_error), mode);
27729  }
27730 
27731  template <typename Fx, typename E>
27732  protected_function_result script(const string_view& code, const basic_environment<E>& env, Fx&& on_error,
27733  const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27734  return safe_script(code, env, std::forward<Fx>(on_error), chunkname, mode);
27735  }
27736 
27737  template <typename Fx, typename E>
27738  protected_function_result script_file(const std::string& filename, const basic_environment<E>& env, Fx&& on_error, load_mode mode = load_mode::any) {
27739  return safe_script_file(filename, env, std::forward<Fx>(on_error), mode);
27740  }
27741 
27743  const string_view& code, const environment& env, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27744  return safe_script(code, env, script_default_on_error, chunkname, mode);
27745  }
27746 
27747  protected_function_result script_file(const std::string& filename, const environment& env, load_mode mode = load_mode::any) {
27748  return safe_script_file(filename, env, script_default_on_error, mode);
27749  }
27750 
27751 #if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS)
27753  lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27754  return safe_script(reader, data, chunkname, mode);
27755  }
27756 
27758  const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27759  return safe_script(code, chunkname, mode);
27760  }
27761 
27762  protected_function_result script_file(const std::string& filename, load_mode mode = load_mode::any) {
27763  return safe_script_file(filename, mode);
27764  }
27765 #else
27766  unsafe_function_result script(const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27767  return unsafe_script(code, chunkname, mode);
27768  }
27769 
27770  unsafe_function_result script_file(const std::string& filename, load_mode mode = load_mode::any) {
27771  return unsafe_script_file(filename, mode);
27772  }
27773 #endif
27774  load_result load(const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27775  detail::typical_chunk_name_t basechunkname = {};
27776  const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
27777  load_status x = static_cast<load_status>(luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str()));
27778  return load_result(L, absolute_index(L, -1), 1, 1, x);
27779  }
27780 
27781  load_result load_buffer(const char* buff, size_t size, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27782  return load(string_view(buff, size), chunkname, mode);
27783  }
27784 
27785  load_result load_buffer(
27786  const std::byte* buff, size_t size, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27787  return load(string_view(reinterpret_cast<const char*>(buff), size), chunkname, mode);
27788  }
27789 
27790  load_result load_file(const std::string& filename, load_mode mode = load_mode::any) {
27791  load_status x = static_cast<load_status>(luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str()));
27792  return load_result(L, absolute_index(L, -1), 1, 1, x);
27793  }
27794 
27795  load_result load(lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
27796  detail::typical_chunk_name_t basechunkname = {};
27797  const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
27798  load_status x = static_cast<load_status>(lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()));
27799  return load_result(L, absolute_index(L, -1), 1, 1, x);
27800  }
27801 
27802  iterator begin() const {
27803  return global.begin();
27804  }
27805 
27806  iterator end() const {
27807  return global.end();
27808  }
27809 
27810  const_iterator cbegin() const {
27811  return global.cbegin();
27812  }
27813 
27814  const_iterator cend() const {
27815  return global.cend();
27816  }
27817 
27818  global_table globals() const {
27819  // if we return a reference
27820  // we'll be screwed a bit
27821  return global;
27822  }
27823 
27824  global_table& globals() {
27825  return global;
27826  }
27827 
27828  table registry() const {
27829  return reg;
27830  }
27831 
27832  std::size_t memory_used() const {
27833  return total_memory_used(lua_state());
27834  }
27835 
27836  int stack_top() const {
27837  return stack::top(L);
27838  }
27839 
27840  int stack_clear() {
27841  int s = stack_top();
27842  lua_pop(L, s);
27843  return s;
27844  }
27845 
27846  bool supports_gc_mode(gc_mode mode) const noexcept {
27847 #if SOL_LUA_VERSION_I_ >= 504
27848  // supports all modes
27849  (void)mode;
27850  return true;
27851 #endif
27852  return mode == gc_mode::default_value;
27853  }
27854 
27855  bool is_gc_on() const {
27856 #if SOL_LUA_VERSION_I_ >= 502
27857  return lua_gc(lua_state(), LUA_GCISRUNNING, 0) == 1;
27858 #else
27859  // You cannot turn it off in Lua 5.1
27860  return true;
27861 #endif
27862  }
27863 
27864  void collect_garbage() {
27865  lua_gc(lua_state(), LUA_GCCOLLECT, 0);
27866  }
27867 
27868  void collect_gc() {
27869  collect_garbage();
27870  }
27871 
27872  bool step_gc(int step_size_kilobytes) {
27873  // THOUGHT: std::chrono-alikes to map "kilobyte size" here...?
27874  // Make it harder to give MB or KB to a B parameter...?
27875  // Probably overkill for now.
27876 #if SOL_LUA_VERSION_I_ >= 504
27877  // The manual implies that this function is almost always successful...
27878  // is it?? It could depend on the GC mode...
27879  return lua_gc(lua_state(), LUA_GCSTEP, step_size_kilobytes) != 0;
27880 #else
27881  return lua_gc(lua_state(), LUA_GCSTEP, step_size_kilobytes) == 1;
27882 #endif
27883  }
27884 
27885  void restart_gc() {
27886  lua_gc(lua_state(), LUA_GCRESTART, 0);
27887  }
27888 
27889  void stop_gc() {
27890  lua_gc(lua_state(), LUA_GCSTOP, 0);
27891  }
27892 
27893  // Returns the old GC mode. Check support using the supports_gc_mode function.
27894  gc_mode change_gc_mode_incremental(int pause, int step_multiplier, int step_byte_size) {
27895  // "What the fuck does any of this mean??"
27896  // http://www.lua.org/manual/5.4/manual.html#2.5.1
27897 
27898  // THOUGHT: std::chrono-alikes to map "byte size" here...?
27899  // Make it harder to give MB or KB to a B parameter...?
27900  // Probably overkill for now.
27901 #if SOL_LUA_VERSION_I_ >= 504
27902  int old_mode = lua_gc(lua_state(), LUA_GCINC, pause, step_multiplier, step_byte_size);
27903  if (old_mode == LUA_GCGEN) {
27904  return gc_mode::generational;
27905  }
27906  else if (old_mode == LUA_GCINC) {
27907  return gc_mode::incremental;
27908  }
27909 #else
27910  lua_gc(lua_state(), LUA_GCSETPAUSE, pause);
27911  lua_gc(lua_state(), LUA_GCSETSTEPMUL, step_multiplier);
27912  (void)step_byte_size; // means nothing in older versions
27913 #endif
27914  return gc_mode::default_value;
27915  }
27916 
27917  // Returns the old GC mode. Check support using the supports_gc_mode function.
27918  gc_mode change_gc_mode_generational(int minor_multiplier, int major_multiplier) {
27919 #if SOL_LUA_VERSION_I_ >= 504
27920  // "What does this shit mean?"
27921  // http://www.lua.org/manual/5.4/manual.html#2.5.2
27922  int old_mode = lua_gc(lua_state(), LUA_GCGEN, minor_multiplier, major_multiplier);
27923  if (old_mode == LUA_GCGEN) {
27924  return gc_mode::generational;
27925  }
27926  else if (old_mode == LUA_GCINC) {
27927  return gc_mode::incremental;
27928  }
27929 #else
27930  (void)minor_multiplier;
27931  (void)major_multiplier;
27932 #endif
27933  return gc_mode::default_value;
27934  }
27935 
27936  operator lua_State*() const {
27937  return lua_state();
27938  }
27939 
27940  void set_panic(lua_CFunction panic) {
27941  lua_atpanic(lua_state(), panic);
27942  }
27943 
27944  void set_exception_handler(exception_handler_function handler) {
27945  set_default_exception_handler(lua_state(), handler);
27946  }
27947 
27948  template <typename... Args, typename... Keys>
27949  decltype(auto) get(Keys&&... keys) const {
27950  return global.get<Args...>(std::forward<Keys>(keys)...);
27951  }
27952 
27953  template <typename T, typename Key>
27954  decltype(auto) get_or(Key&& key, T&& otherwise) const {
27955  return global.get_or(std::forward<Key>(key), std::forward<T>(otherwise));
27956  }
27957 
27958  template <typename T, typename Key, typename D>
27959  decltype(auto) get_or(Key&& key, D&& otherwise) const {
27960  return global.get_or<T>(std::forward<Key>(key), std::forward<D>(otherwise));
27961  }
27962 
27963  template <typename... Args>
27964  state_view& set(Args&&... args) {
27965  global.set(std::forward<Args>(args)...);
27966  return *this;
27967  }
27968 
27969  template <typename T, typename... Keys>
27970  decltype(auto) traverse_get(Keys&&... keys) const {
27971  return global.traverse_get<T>(std::forward<Keys>(keys)...);
27972  }
27973 
27974  template <typename... Args>
27975  state_view& traverse_set(Args&&... args) {
27976  global.traverse_set(std::forward<Args>(args)...);
27977  return *this;
27978  }
27979 
27980  template <typename Class, typename... Args>
27981  usertype<Class> new_usertype(Args&&... args) {
27982  return global.new_usertype<Class>(std::forward<Args>(args)...);
27983  }
27984 
27985  template <bool read_only = true, typename... Args>
27986  state_view& new_enum(const string_view& name, Args&&... args) {
27987  global.new_enum<read_only>(name, std::forward<Args>(args)...);
27988  return *this;
27989  }
27990 
27991  template <typename T, bool read_only = true>
27992  state_view& new_enum(const string_view& name, std::initializer_list<std::pair<string_view, T>> items) {
27993  global.new_enum<T, read_only>(name, std::move(items));
27994  return *this;
27995  }
27996 
27997  template <typename Fx>
27998  void for_each(Fx&& fx) {
27999  global.for_each(std::forward<Fx>(fx));
28000  }
28001 
28002  template <typename T>
28004  return global[std::forward<T>(key)];
28005  }
28006 
28007  template <typename T>
28008  table_proxy<const global_table&, detail::proxy_key_t<T>> operator[](T&& key) const {
28009  return global[std::forward<T>(key)];
28010  }
28011 
28012  template <typename Sig, typename... Args, typename Key>
28013  state_view& set_function(Key&& key, Args&&... args) {
28014  global.set_function<Sig>(std::forward<Key>(key), std::forward<Args>(args)...);
28015  return *this;
28016  }
28017 
28018  template <typename... Args, typename Key>
28019  state_view& set_function(Key&& key, Args&&... args) {
28020  global.set_function(std::forward<Key>(key), std::forward<Args>(args)...);
28021  return *this;
28022  }
28023 
28024  template <typename Name>
28025  table create_table(Name&& name, int narr = 0, int nrec = 0) {
28026  return global.create(std::forward<Name>(name), narr, nrec);
28027  }
28028 
28029  template <typename Name, typename Key, typename Value, typename... Args>
28030  table create_table(Name&& name, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
28031  return global.create(std::forward<Name>(name), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
28032  }
28033 
28034  template <typename Name, typename... Args>
28035  table create_named_table(Name&& name, Args&&... args) {
28036  table x = global.create_with(std::forward<Args>(args)...);
28037  global.set(std::forward<Name>(name), x);
28038  return x;
28039  }
28040 
28041  table create_table(int narr = 0, int nrec = 0) {
28042  return create_table(lua_state(), narr, nrec);
28043  }
28044 
28045  template <typename Key, typename Value, typename... Args>
28046  table create_table(int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
28047  return create_table(lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
28048  }
28049 
28050  template <typename... Args>
28051  table create_table_with(Args&&... args) {
28052  return create_table_with(lua_state(), std::forward<Args>(args)...);
28053  }
28054 
28055  static inline table create_table(lua_State* L, int narr = 0, int nrec = 0) {
28056  return global_table::create(L, narr, nrec);
28057  }
28058 
28059  template <typename Key, typename Value, typename... Args>
28060  static inline table create_table(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
28061  return global_table::create(L, narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
28062  }
28063 
28064  template <typename... Args>
28065  static inline table create_table_with(lua_State* L, Args&&... args) {
28066  return global_table::create_with(L, std::forward<Args>(args)...);
28067  }
28068  };
28069 } // namespace sol
28070 
28071 // end of sol/state_view.hpp
28072 
28073 // beginning of sol/thread.hpp
28074 
28075 namespace sol {
28077  lua_State* L;
28078 
28079  lua_thread_state(lua_State* Ls) : L(Ls) {
28080  }
28081 
28082  lua_State* lua_state() const noexcept {
28083  return L;
28084  }
28085  operator lua_State*() const noexcept {
28086  return lua_state();
28087  }
28088  lua_State* operator->() const noexcept {
28089  return lua_state();
28090  }
28091  };
28092 
28093  namespace stack {
28094  template <>
28096  int push(lua_State*, lua_thread_state lts) {
28097  lua_pushthread(lts.L);
28098  return 1;
28099  }
28100  };
28101 
28102  template <>
28104  lua_thread_state get(lua_State* L, int index, record& tracking) {
28105  tracking.use(1);
28106  lua_thread_state lts(lua_tothread(L, index));
28107  return lts;
28108  }
28109  };
28110 
28111  template <>
28113  template <typename Handler>
28114  optional<lua_thread_state> get(lua_State* L, int index, Handler&& handler, record& tracking) {
28115  lua_thread_state lts(lua_tothread(L, index));
28116  if (lts.lua_state() == nullptr) {
28117  handler(L, index, type::thread, type_of(L, index), "value is not a valid thread type");
28118  return nullopt;
28119  }
28120  tracking.use(1);
28121  return lts;
28122  }
28123  };
28124  } // namespace stack
28125 
28126  template <typename ref_t>
28127  class basic_thread : public basic_object<ref_t> {
28128  private:
28129  using base_t = basic_object<ref_t>;
28130 
28131  public:
28132  using base_t::lua_state;
28133 
28134  basic_thread() noexcept = default;
28135  basic_thread(const basic_thread&) = default;
28136  basic_thread(basic_thread&&) = default;
28137  template <typename T,
28138  meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_thread>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
28139  basic_thread(T&& r) : base_t(std::forward<T>(r)) {
28140 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28141  auto pp = stack::push_pop(*this);
28142  constructor_handler handler {};
28143  stack::check<basic_thread>(lua_state(), -1, handler);
28144 #endif // Safety
28145  }
28146  basic_thread(const stack_reference& r) : basic_thread(r.lua_state(), r.stack_index()) {};
28147  basic_thread(stack_reference&& r) : basic_thread(r.lua_state(), r.stack_index()) {};
28148  basic_thread& operator=(const basic_thread&) = default;
28149  basic_thread& operator=(basic_thread&&) = default;
28150  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
28151  basic_thread(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
28152 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28153  auto pp = stack::push_pop(*this);
28154  constructor_handler handler {};
28155  stack::check<basic_thread>(lua_state(), -1, handler);
28156 #endif // Safety
28157  }
28158  basic_thread(lua_State* L, int index = -1) : base_t(L, index) {
28159 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28160  constructor_handler handler {};
28161  stack::check<basic_thread>(L, index, handler);
28162 #endif // Safety
28163  }
28164  basic_thread(lua_State* L, ref_index index) : base_t(L, index) {
28165 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28166  auto pp = stack::push_pop(*this);
28167  constructor_handler handler {};
28168  stack::check<basic_thread>(lua_state(), -1, handler);
28169 #endif // Safety
28170  }
28171  basic_thread(lua_State* L, lua_State* actualthread) : basic_thread(L, lua_thread_state { actualthread }) {
28172  }
28173  basic_thread(lua_State* L, this_state actualthread) : basic_thread(L, lua_thread_state { actualthread.L }) {
28174  }
28175  basic_thread(lua_State* L, lua_thread_state actualthread) : base_t(L, -stack::push(L, actualthread)) {
28176 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28177  constructor_handler handler {};
28178  stack::check<basic_thread>(lua_state(), -1, handler);
28179 #endif // Safety
28181  lua_pop(lua_state(), 1);
28182  }
28183  }
28184 
28185  state_view state() const {
28186  return state_view(this->thread_state());
28187  }
28188 
28189  bool is_main_thread() const {
28190  return stack::is_main_thread(this->thread_state());
28191  }
28192 
28193  lua_State* thread_state() const {
28194  auto pp = stack::push_pop(*this);
28195  lua_State* lthread = lua_tothread(lua_state(), -1);
28196  return lthread;
28197  }
28198 
28199  thread_status status() const {
28200  lua_State* lthread = thread_state();
28201  auto lstat = static_cast<thread_status>(lua_status(lthread));
28202  if (lstat == thread_status::ok) {
28203  lua_Debug ar;
28204  if (lua_getstack(lthread, 0, &ar) > 0)
28205  return thread_status::ok;
28206  else if (lua_gettop(lthread) == 0)
28207  return thread_status::dead;
28208  else
28209  return thread_status::yielded;
28210  }
28211  return lstat;
28212  }
28213 
28214  basic_thread create() {
28215  return create(lua_state());
28216  }
28217 
28218  static basic_thread create(lua_State* L) {
28219  lua_newthread(L);
28220  basic_thread result(L);
28222  lua_pop(L, 1);
28223  }
28224  return result;
28225  }
28226  };
28227 
28230 } // namespace sol
28231 
28232 // end of sol/thread.hpp
28233 
28234 namespace sol {
28235 
28236  class state : private std::unique_ptr<lua_State, detail::state_deleter>, public state_view {
28237  private:
28238  typedef std::unique_ptr<lua_State, detail::state_deleter> unique_base;
28239 
28240  public:
28241  state(lua_CFunction panic = default_at_panic) : unique_base(luaL_newstate()), state_view(unique_base::get()) {
28242  set_default_state(unique_base::get(), panic);
28243  }
28244 
28245  state(lua_CFunction panic, lua_Alloc alfunc, void* alpointer = nullptr)
28246  : unique_base(lua_newstate(alfunc, alpointer)), state_view(unique_base::get()) {
28247  set_default_state(unique_base::get(), panic);
28248  }
28249 
28250  state(const state&) = delete;
28251  state(state&&) = default;
28252  state& operator=(const state&) = delete;
28253  state& operator=(state&& that) {
28254  state_view::operator=(std::move(that));
28255  unique_base::operator=(std::move(that));
28256  return *this;
28257  }
28258 
28259  using state_view::get;
28260 
28261  ~state() {
28262  }
28263  };
28264 } // namespace sol
28265 
28266 // end of sol/state.hpp
28267 
28268 // beginning of sol/coroutine.hpp
28269 
28270 namespace sol {
28271  template <typename Reference>
28272  class basic_coroutine : public basic_object<Reference> {
28273  private:
28274  using base_t = basic_object<Reference>;
28275  using handler_t = reference;
28276 
28277  private:
28278  call_status stats = call_status::yielded;
28279 
28280  void luacall(std::ptrdiff_t argcount, std::ptrdiff_t) {
28281 #if SOL_LUA_VERSION_I_ >= 504
28282  int nresults;
28283  stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount), &nresults));
28284 #else
28285  stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount)));
28286 #endif
28287  }
28288 
28289  template <std::size_t... I, typename... Ret>
28290  auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n) {
28291  luacall(n, sizeof...(Ret));
28292  return stack::pop<std::tuple<Ret...>>(lua_state());
28293  }
28294 
28295  template <std::size_t I, typename Ret>
28296  Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n) {
28297  luacall(n, 1);
28298  return stack::pop<Ret>(lua_state());
28299  }
28300 
28301  template <std::size_t I>
28302  void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n) {
28303  luacall(n, 0);
28304  }
28305 
28306  protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n) {
28307  int firstreturn = 1;
28308  luacall(n, LUA_MULTRET);
28309  int poststacksize = lua_gettop(this->lua_state());
28310  int returncount = poststacksize - (firstreturn - 1);
28311  if (error()) {
28312  if (m_error_handler.valid()) {
28313  string_view err = stack::get<string_view>(this->lua_state(), poststacksize);
28314  m_error_handler.push();
28315  stack::push(this->lua_state(), err);
28316  lua_call(lua_state(), 1, 1);
28317  }
28318  return protected_function_result(this->lua_state(), lua_absindex(this->lua_state(), -1), 1, returncount, status());
28319  }
28320  return protected_function_result(this->lua_state(), firstreturn, returncount, returncount, status());
28321  }
28322 
28323  public:
28324  using base_t::lua_state;
28325 
28326  basic_coroutine() = default;
28327  template <typename T,
28328  meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_coroutine>>,
28329  meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>,
28330  meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
28331  basic_coroutine(T&& r) noexcept
28332  : base_t(std::forward<T>(r)), m_error_handler(detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
28333 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28334  if (!is_function<meta::unqualified_t<T>>::value) {
28335  auto pp = stack::push_pop(*this);
28336  constructor_handler handler {};
28337  stack::check<basic_coroutine>(lua_state(), -1, handler);
28338  }
28339 #endif // Safety
28340  }
28341 
28342  basic_coroutine(const basic_coroutine& other) = default;
28343  basic_coroutine& operator=(const basic_coroutine&) = default;
28344 
28345  basic_coroutine(basic_coroutine&& other) noexcept : base_t(std::move(other)), m_error_handler(this->lua_state(), std::move(other.m_error_handler)) {
28346  }
28347 
28348  basic_coroutine& operator=(basic_coroutine&& other) noexcept {
28349  base_t::operator=(std::move(other));
28350  // must change the state, since it could change on the coroutine type
28351  m_error_handler = handler_t(this->lua_state(), std::move(other.m_error_handler));
28352  return *this;
28353  }
28354 
28355  basic_coroutine(const basic_function<base_t>& b) noexcept
28356  : basic_coroutine(b, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(b.lua_state())) {
28357  }
28358  basic_coroutine(basic_function<base_t>&& b) noexcept
28359  : basic_coroutine(std::move(b), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(b.lua_state())) {
28360  }
28361  basic_coroutine(const basic_function<base_t>& b, handler_t eh) noexcept : base_t(b), m_error_handler(std::move(eh)) {
28362  }
28363  basic_coroutine(basic_function<base_t>&& b, handler_t eh) noexcept : base_t(std::move(b)), m_error_handler(std::move(eh)) {
28364  }
28365  basic_coroutine(const stack_reference& r) noexcept
28366  : basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
28367  }
28368  basic_coroutine(stack_reference&& r) noexcept
28369  : basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
28370  }
28371  basic_coroutine(const stack_reference& r, handler_t eh) noexcept : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
28372  }
28373  basic_coroutine(stack_reference&& r, handler_t eh) noexcept : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
28374  }
28375 
28376  template <typename Super>
28377  basic_coroutine(const proxy_base<Super>& p)
28378  : basic_coroutine(p, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) {
28379  }
28380  template <typename Super>
28381  basic_coroutine(proxy_base<Super>&& p)
28382  : basic_coroutine(std::move(p), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) {
28383  }
28384  template <typename Proxy, typename HandlerReference,
28385  meta::enable<std::is_base_of<proxy_base_tag, meta::unqualified_t<Proxy>>,
28386  meta::neg<is_lua_index<meta::unqualified_t<HandlerReference>>>> = meta::enabler>
28387  basic_coroutine(Proxy&& p, HandlerReference&& eh) : basic_coroutine(detail::force_cast<base_t>(p), std::forward<HandlerReference>(eh)) {
28388  }
28389 
28390  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
28391  basic_coroutine(lua_State* L, T&& r) noexcept
28392  : basic_coroutine(L, std::forward<T>(r), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
28393  }
28394  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
28395  basic_coroutine(lua_State* L, T&& r, handler_t eh) : base_t(L, std::forward<T>(r)), m_error_handler(std::move(eh)) {
28396 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28397  auto pp = stack::push_pop(*this);
28398  constructor_handler handler {};
28399  stack::check<basic_coroutine>(lua_state(), -1, handler);
28400 #endif // Safety
28401  }
28402 
28403  basic_coroutine(lua_nil_t n) : base_t(n), m_error_handler(n) {
28404  }
28405 
28406  basic_coroutine(lua_State* L, int index = -1)
28407  : basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
28408  }
28409  basic_coroutine(lua_State* L, int index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
28410 #ifdef SOL_SAFE_REFERENCES
28411  constructor_handler handler {};
28412  stack::check<basic_coroutine>(L, index, handler);
28413 #endif // Safety
28414  }
28415  basic_coroutine(lua_State* L, absolute_index index)
28416  : basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
28417  }
28418  basic_coroutine(lua_State* L, absolute_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
28419 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28420  constructor_handler handler {};
28421  stack::check<basic_coroutine>(L, index, handler);
28422 #endif // Safety
28423  }
28424  basic_coroutine(lua_State* L, raw_index index)
28425  : basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
28426  }
28427  basic_coroutine(lua_State* L, raw_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
28428 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28429  constructor_handler handler {};
28430  stack::check<basic_coroutine>(L, index, handler);
28431 #endif // Safety
28432  }
28433  basic_coroutine(lua_State* L, ref_index index)
28434  : basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
28435  }
28436  basic_coroutine(lua_State* L, ref_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
28437 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28438  auto pp = stack::push_pop(*this);
28439  constructor_handler handler {};
28440  stack::check<basic_coroutine>(lua_state(), -1, handler);
28441 #endif // Safety
28442  }
28443 
28444  call_status status() const noexcept {
28445  return stats;
28446  }
28447 
28448  bool error() const noexcept {
28449  call_status cs = status();
28450  return cs != call_status::ok && cs != call_status::yielded;
28451  }
28452 
28453  bool runnable() const noexcept {
28454  return base_t::valid() && (status() == call_status::yielded);
28455  }
28456 
28457  explicit operator bool() const noexcept {
28458  return runnable();
28459  }
28460 
28461  template <typename... Args>
28462  protected_function_result operator()(Args&&... args) {
28463  return call<>(std::forward<Args>(args)...);
28464  }
28465 
28466  template <typename... Ret, typename... Args>
28467  decltype(auto) operator()(types<Ret...>, Args&&... args) {
28468  return call<Ret...>(std::forward<Args>(args)...);
28469  }
28470 
28471  template <typename... Ret, typename... Args>
28472  decltype(auto) call(Args&&... args) {
28473  // some users screw up coroutine.create
28474  // and try to use it with sol::coroutine without ever calling the first resume in Lua
28475  // this makes the stack incompatible with other kinds of stacks: protect against this
28476  // make sure coroutines don't screw us over
28477  base_t::push();
28478  int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
28479  return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount);
28480  }
28481 
28482  private:
28483  handler_t m_error_handler;
28484  };
28485 } // namespace sol
28486 
28487 // end of sol/coroutine.hpp
28488 
28489 // beginning of sol/userdata.hpp
28490 
28491 namespace sol {
28492  template <typename base_type>
28493  class basic_userdata : public basic_table<base_type> {
28494  private:
28495  using base_t = basic_table<base_type>;
28496 
28497  public:
28498  using base_t::lua_state;
28499 
28500  basic_userdata() noexcept = default;
28501  template <typename T,
28502  meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_userdata>>, meta::neg<std::is_same<base_t, stack_reference>>,
28503  is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
28504  basic_userdata(T&& r) noexcept : base_t(std::forward<T>(r)) {
28505 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28506  if (!is_userdata<meta::unqualified_t<T>>::value) {
28507  auto pp = stack::push_pop(*this);
28508  type_assert(lua_state(), -1, type::userdata);
28509  }
28510 #endif // Safety
28511  }
28512  basic_userdata(const basic_userdata&) = default;
28513  basic_userdata(basic_userdata&&) = default;
28514  basic_userdata& operator=(const basic_userdata&) = default;
28515  basic_userdata& operator=(basic_userdata&&) = default;
28516  basic_userdata(const stack_reference& r) : basic_userdata(r.lua_state(), r.stack_index()) {
28517  }
28518  basic_userdata(stack_reference&& r) : basic_userdata(r.lua_state(), r.stack_index()) {
28519  }
28520  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
28521  basic_userdata(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
28522 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28523  auto pp = stack::push_pop(*this);
28524  constructor_handler handler {};
28525  stack::check<basic_userdata>(L, -1, handler);
28526 #endif // Safety
28527  }
28528  basic_userdata(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
28529 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28530  constructor_handler handler {};
28531  stack::check<basic_userdata>(L, index, handler);
28532 #endif // Safety
28533  }
28534  basic_userdata(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
28535 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28536  auto pp = stack::push_pop(*this);
28537  constructor_handler handler {};
28538  stack::check<basic_userdata>(L, -1, handler);
28539 #endif // Safety
28540  }
28541  };
28542 
28543  template <typename base_type>
28544  class basic_lightuserdata : public basic_object_base<base_type> {
28545  typedef basic_object_base<base_type> base_t;
28546 
28547  public:
28548  using base_t::lua_state;
28549 
28550  basic_lightuserdata() noexcept = default;
28551  template <typename T,
28552  meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_lightuserdata>>, meta::neg<std::is_same<base_t, stack_reference>>,
28553  is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
28554  basic_lightuserdata(T&& r) noexcept : base_t(std::forward<T>(r)) {
28555 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28556  if (!is_lightuserdata<meta::unqualified_t<T>>::value) {
28557  auto pp = stack::push_pop(*this);
28558  type_assert(lua_state(), -1, type::lightuserdata);
28559  }
28560 #endif // Safety
28561  }
28562  basic_lightuserdata(const basic_lightuserdata&) = default;
28563  basic_lightuserdata(basic_lightuserdata&&) = default;
28564  basic_lightuserdata& operator=(const basic_lightuserdata&) = default;
28565  basic_lightuserdata& operator=(basic_lightuserdata&&) = default;
28566  basic_lightuserdata(const stack_reference& r) : basic_lightuserdata(r.lua_state(), r.stack_index()) {
28567  }
28568  basic_lightuserdata(stack_reference&& r) : basic_lightuserdata(r.lua_state(), r.stack_index()) {
28569  }
28570  template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
28571  basic_lightuserdata(lua_State* L, T&& r) : basic_lightuserdata(L, std::forward<T>(r)) {
28572 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28573  auto pp = stack::push_pop(*this);
28574  constructor_handler handler {};
28575  stack::check<basic_lightuserdata>(lua_state(), -1, handler);
28576 #endif // Safety
28577  }
28578  basic_lightuserdata(lua_State* L, int index = -1) : base_t(L, index) {
28579 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28580  constructor_handler handler {};
28581  stack::check<basic_lightuserdata>(L, index, handler);
28582 #endif // Safety
28583  }
28584  basic_lightuserdata(lua_State* L, ref_index index) : base_t(L, index) {
28585 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28586  auto pp = stack::push_pop(*this);
28587  constructor_handler handler {};
28588  stack::check<basic_lightuserdata>(lua_state(), index, handler);
28589 #endif // Safety
28590  }
28591  };
28592 
28593 } // namespace sol
28594 
28595 // end of sol/userdata.hpp
28596 
28597 // beginning of sol/as_args.hpp
28598 
28599 namespace sol {
28600  template <typename T>
28601  struct as_args_t {
28602  T src;
28603  };
28604 
28605  template <typename Source>
28606  auto as_args(Source&& source) {
28607  return as_args_t<Source> { std::forward<Source>(source) };
28608  }
28609 
28610  namespace stack {
28611  template <typename T>
28613  int push(lua_State* L, const as_args_t<T>& e) {
28614  int p = 0;
28615  for (const auto& i : e.src) {
28616  p += stack::push(L, i);
28617  }
28618  return p;
28619  }
28620  };
28621  } // namespace stack
28622 } // namespace sol
28623 
28624 // end of sol/as_args.hpp
28625 
28626 // beginning of sol/variadic_args.hpp
28627 
28628 #include <limits>
28629 #include <iterator>
28630 
28631 namespace sol {
28632  struct variadic_args {
28633  private:
28634  lua_State* L;
28635  int index;
28636  int stacktop;
28637 
28638  public:
28639  typedef stack_proxy reference_type;
28640  typedef stack_proxy value_type;
28641  typedef stack_proxy* pointer;
28642  typedef std::ptrdiff_t difference_type;
28643  typedef std::size_t size_type;
28646  typedef std::reverse_iterator<iterator> reverse_iterator;
28647  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
28648 
28649  variadic_args() = default;
28650  variadic_args(lua_State* luastate, int stackindex = -1) : L(luastate), index(lua_absindex(luastate, stackindex)), stacktop(lua_gettop(luastate)) {
28651  }
28652  variadic_args(lua_State* luastate, int stackindex, int lastindex) : L(luastate), index(lua_absindex(luastate, stackindex)), stacktop(lastindex) {
28653  }
28654  variadic_args(const variadic_args&) = default;
28655  variadic_args& operator=(const variadic_args&) = default;
28656  variadic_args(variadic_args&& o) : L(o.L), index(o.index), stacktop(o.stacktop) {
28657  // Must be manual, otherwise destructor will screw us
28658  // return count being 0 is enough to keep things clean
28659  // but will be thorough
28660  o.L = nullptr;
28661  o.index = 0;
28662  o.stacktop = 0;
28663  }
28664  variadic_args& operator=(variadic_args&& o) {
28665  L = o.L;
28666  index = o.index;
28667  stacktop = o.stacktop;
28668  // Must be manual, otherwise destructor will screw us
28669  // return count being 0 is enough to keep things clean
28670  // but will be thorough
28671  o.L = nullptr;
28672  o.index = 0;
28673  o.stacktop = 0;
28674  return *this;
28675  }
28676 
28677  iterator begin() {
28678  return iterator(L, index, stacktop + 1);
28679  }
28680  iterator end() {
28681  return iterator(L, stacktop + 1, stacktop + 1);
28682  }
28683  const_iterator begin() const {
28684  return const_iterator(L, index, stacktop + 1);
28685  }
28686  const_iterator end() const {
28687  return const_iterator(L, stacktop + 1, stacktop + 1);
28688  }
28689  const_iterator cbegin() const {
28690  return begin();
28691  }
28692  const_iterator cend() const {
28693  return end();
28694  }
28695 
28696  reverse_iterator rbegin() {
28697  return std::reverse_iterator<iterator>(begin());
28698  }
28699  reverse_iterator rend() {
28700  return std::reverse_iterator<iterator>(end());
28701  }
28702  const_reverse_iterator rbegin() const {
28703  return std::reverse_iterator<const_iterator>(begin());
28704  }
28705  const_reverse_iterator rend() const {
28706  return std::reverse_iterator<const_iterator>(end());
28707  }
28708  const_reverse_iterator crbegin() const {
28709  return std::reverse_iterator<const_iterator>(cbegin());
28710  }
28711  const_reverse_iterator crend() const {
28712  return std::reverse_iterator<const_iterator>(cend());
28713  }
28714 
28715  int push() const {
28716  return push(L);
28717  }
28718 
28719  int push(lua_State* target) const {
28720  int pushcount = 0;
28721  for (int i = index; i <= stacktop; ++i) {
28722  lua_pushvalue(L, i);
28723  pushcount += 1;
28724  }
28725  if (target != L) {
28726  lua_xmove(L, target, pushcount);
28727  }
28728  return pushcount;
28729  }
28730 
28731  template <typename T>
28732  decltype(auto) get(difference_type index_offset = 0) const {
28733  return stack::get<T>(L, index + static_cast<int>(index_offset));
28734  }
28735 
28736  type get_type(difference_type index_offset = 0) const noexcept {
28737  return type_of(L, index + static_cast<int>(index_offset));
28738  }
28739 
28740  stack_proxy operator[](difference_type index_offset) const {
28741  return stack_proxy(L, index + static_cast<int>(index_offset));
28742  }
28743 
28744  lua_State* lua_state() const {
28745  return L;
28746  };
28747  int stack_index() const {
28748  return index;
28749  };
28750  int leftover_count() const {
28751  return stacktop - (index - 1);
28752  }
28753  std::size_t size() const {
28754  return static_cast<std::size_t>(leftover_count());
28755  }
28756  int top() const {
28757  return stacktop;
28758  }
28759  };
28760 
28761  namespace stack {
28762  template <>
28764  static variadic_args get(lua_State* L, int index, record& tracking) {
28765  tracking.last = 0;
28766  return variadic_args(L, index);
28767  }
28768  };
28769 
28770  template <>
28772  static int push(lua_State* L, const variadic_args& ref) {
28773  return ref.push(L);
28774  }
28775  };
28776  } // namespace stack
28777 } // namespace sol
28778 
28779 // end of sol/variadic_args.hpp
28780 
28781 // beginning of sol/variadic_results.hpp
28782 
28783 // beginning of sol/as_returns.hpp
28784 
28785 namespace sol {
28786  template <typename T>
28787  struct as_returns_t : private detail::ebco<T> {
28788  private:
28789  using base_t = detail::ebco<T>;
28790 
28791  public:
28792  using base_t::base_t;
28793  using base_t::value;
28794  };
28795 
28796  template <typename Source>
28797  auto as_returns(Source&& source) {
28798  return as_returns_t<std::decay_t<Source>> { std::forward<Source>(source) };
28799  }
28800 
28801  namespace stack {
28802  template <typename T>
28804  int push(lua_State* L, const as_returns_t<T>& e) {
28805  auto& src = detail::unwrap(e.value());
28806  int p = 0;
28807  for (const auto& i : src) {
28808  p += stack::push(L, i);
28809  }
28810  return p;
28811  }
28812  };
28813  } // namespace stack
28814 } // namespace sol
28815 
28816 // end of sol/as_returns.hpp
28817 
28818 #include <vector>
28819 
28820 namespace sol {
28821 
28822  template <typename Al = typename std::allocator<object>>
28823  struct basic_variadic_results : public std::vector<object, Al> {
28824  private:
28825  using base_t = std::vector<object, Al>;
28826 
28827  public:
28828  basic_variadic_results() : base_t() {
28829  }
28830 
28832  this->reserve(fr.return_count());
28833  this->insert(this->cend(), fr.begin(), fr.end());
28834  }
28835 
28837  this->reserve(fr.return_count());
28838  this->insert(this->cend(), fr.begin(), fr.end());
28839  }
28840 
28841  template <typename Arg0, typename... Args,
28842  meta::disable_any<std::is_same<meta::unqualified_t<Arg0>, basic_variadic_results>, std::is_same<meta::unqualified_t<Arg0>, function_result>,
28843  std::is_same<meta::unqualified_t<Arg0>, protected_function_result>> = meta::enabler>
28844  basic_variadic_results(Arg0&& arg0, Args&&... args) : base_t(std::forward<Arg0>(arg0), std::forward<Args>(args)...) {
28845  }
28846 
28847  basic_variadic_results(const basic_variadic_results&) = default;
28848  basic_variadic_results(basic_variadic_results&&) = default;
28849  };
28850 
28852  private:
28854 
28855  public:
28856  using base_t::base_t;
28857  };
28858 
28859  template <typename Al>
28860  struct is_container<basic_variadic_results<Al>> : std::false_type { };
28861 
28862  template <>
28863  struct is_container<variadic_results> : std::false_type { };
28864 
28865  namespace stack {
28866  template <typename Al>
28868  int push(lua_State* L, const basic_variadic_results<Al>& e) {
28869  int p = 0;
28870  for (const auto& i : e) {
28871  p += stack::push(L, i);
28872  }
28873  return p;
28874  }
28875  };
28876 
28877  template <>
28878  struct unqualified_pusher<variadic_results> {
28879  int push(lua_State* L, const variadic_results& r) {
28880  using base_t = basic_variadic_results<>;
28881  return stack::push(L, static_cast<const base_t&>(r));
28882  }
28883  };
28884  } // namespace stack
28885 
28886 } // namespace sol
28887 
28888 // end of sol/variadic_results.hpp
28889 
28890 #if SOL_IS_ON(SOL_COMPILER_GCC)
28891 #pragma GCC diagnostic pop
28892 #elif SOL_IS_ON(SOL_COMPILER_CLANG)
28893 #elif SOL_IS_ON(SOL_COMPILER_VCXX)
28894 #pragma warning(pop)
28895 #endif // g++
28896 
28897 #if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE)
28898 #undef check
28899 #pragma pop_macro("check")
28900 #endif // Unreal Engine 4 Bullshit
28901 
28902 #endif // SOL_HPP
28903 // end of sol/sol.hpp
28904 
28905 #endif // SOL_SINGLE_INCLUDE_HPP
Definition: sol.hpp:28076
Definition: sol.hpp:6954
Definition: sol.hpp:17437
Definition: sol.hpp:7289
Definition: sol.hpp:14889
Definition: lua.h:441
Definition: sol.hpp:17226
Definition: sol.hpp:8107
SOL_TL_OPTIONAL_11_CONSTEXPR T & operator*() &
Definition: sol.hpp:5901
Definition: sol.hpp:17926
Definition: sol.hpp:12205
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:5854
void swap(optional &rhs) noexcept
Definition: sol.hpp:6762
Definition: sol.hpp:10157
Definition: sol.hpp:7341
Definition: sol.hpp:1226
Definition: sol.hpp:6887
Definition: sol.hpp:11413
Definition: sol.hpp:8449
Definition: sol.hpp:11462
optional< T > SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) const &
Definition: sol.hpp:6494
Definition: sol.hpp:18159
Definition: sol.hpp:13075
Definition: sol.hpp:1275
Definition: sol.hpp:1546
Definition: sol.hpp:16992
Definition: sol.hpp:8701
Definition: sol.hpp:19805
Definition: sol.hpp:10810
Definition: lobject.h:497
Definition: sol.hpp:1129
Definition: sol.hpp:1267
optional take() &&
take
Definition: sol.hpp:5643
constexpr const T * operator->() const
Definition: sol.hpp:6770
SOL_TL_OPTIONAL_11_CONSTEXPR T & operator*()
Definition: sol.hpp:6784
Definition: sol.hpp:9657
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) &&
disjunction
Definition: sol.hpp:6629
Definition: sol.hpp:8144
Definition: sol.hpp:19801
Definition: sol.hpp:4798
Definition: sol.hpp:8091
optional< T > or_else(F &&f) const &&
Definition: sol.hpp:6501
Definition: sol.hpp:4728
Definition: sol.hpp:20737
Definition: sol.hpp:8377
Definition: sol.hpp:21308
Definition: sol.hpp:13081
Definition: sol.hpp:4547
Definition: sol.hpp:25036
Definition: sol.hpp:1425
Definition: sol.hpp:8419
T & emplace(Args &&... args) noexcept
Definition: sol.hpp:6749
Definition: sol.hpp:4923
Definition: sol.hpp:10932
Definition: sol.hpp:7132
Definition: sol.hpp:23438
Definition: sol.hpp:17783
Definition: sol.hpp:7739
Definition: sol.hpp:18009
Definition: sol.hpp:2217
Definition: sol.hpp:10143
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) &&
Definition: sol.hpp:5553
Definition: sol.hpp:11429
Definition: sol.hpp:11442
Definition: sol.hpp:10002
Definition: sol.hpp:7331
Definition: sol.hpp:6934
U map_or(F &&f, U &&u) const &
map_or
Definition: sol.hpp:5523
Definition: sol.hpp:9590
Definition: sol.hpp:7392
void reset() noexcept
Destroys the stored value if one exists, making the optional empty.
Definition: sol.hpp:5998
Definition: sol.hpp:10820
Definition: sol.hpp:2269
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) &&
disjunction
Definition: sol.hpp:5594
Definition: sol.hpp:10050
Definition: sol.hpp:19100
constexpr const T & operator*() const &
Definition: sol.hpp:5907
Definition: sol.hpp:8552
constexpr detail::invoke_result_t< F, const T && > and_then(F &&f) const &&
Definition: sol.hpp:5344
Definition: sol.hpp:11450
Definition: sol.hpp:7428
Definition: sol.hpp:1283
optional take() &&
take
Definition: sol.hpp:6656
optional< T > SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) const &
Definition: sol.hpp:5481
Definition: sol.hpp:7382
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) &
disjunction
Definition: sol.hpp:5606
SOL_TL_OPTIONAL_11_CONSTEXPR T * operator->()
Definition: sol.hpp:6776
Definition: sol.hpp:8633
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) &&
Definition: sol.hpp:6566
Definition: sol.hpp:28851
Definition: sol.hpp:18506
Definition: sol.hpp:1174
U map_or(F &&f, U &&u) const &
map_or
Definition: sol.hpp:6536
Definition: sol.hpp:21369
Definition: sol.hpp:18984
Definition: sol.hpp:25390
Definition: sol.hpp:2223
Definition: sol.hpp:8542
SOL_TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t< F, T & > and_then(F &&f) &
Definition: sol.hpp:5313
Definition: sol.hpp:25442
Definition: sol.hpp:4730
Definition: json.hpp:16563
Definition: sol.hpp:10931
Definition: sol.hpp:4912
Definition: sol.hpp:7337
Definition: sol.hpp:1220
Definition: sol.hpp:2644
Definition: sol.hpp:17987
optional & operator=(U &&u)
Definition: sol.hpp:5781
optional(optional< U > &&rhs)
Definition: sol.hpp:5738
Definition: sol.hpp:2650
Definition: sol.hpp:1280
Definition: sol.hpp:1571
Definition: sol.hpp:1291
Definition: sol.hpp:1169
Definition: sol.hpp:1359
Definition: sol.hpp:6920
Definition: sol.hpp:12320
Definition: sol.hpp:10817
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) const &&
Definition: sol.hpp:6583
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:6558
Definition: sol.hpp:19562
Definition: sol.hpp:7532
SOL_TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t< F, T && > and_then(F &&f) &&
Definition: sol.hpp:5323
Definition: sol.hpp:1314
Definition: lauxlib.h:31
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) &
Definition: sol.hpp:6597
Definition: sol.hpp:17119
Definition: sol.hpp:28823
constexpr optional(const T &u)
Definition: sol.hpp:5714
Definition: sol.hpp:11439
Definition: sol.hpp:11455
Definition: sol.hpp:7210
Definition: sol.hpp:17758
Definition: sol.hpp:1224
Definition: sol.hpp:8534
Definition: lauxlib.h:193
U map_or(F &&f, U &&u) &
Maps the stored value with f if there is one, otherwise returns u.
Definition: sol.hpp:6524
Definition: sol.hpp:23455
Definition: sol.hpp:1182
Definition: sol.hpp:9208
Definition: sol.hpp:10938
Definition: sol.hpp:6997
Definition: sol.hpp:7735
Definition: lobject.h:100
Definition: sol.hpp:9328
Definition: sol.hpp:21208
Definition: sol.hpp:8120
Definition: sol.hpp:1397
Definition: sol.hpp:7772
U map_or(F &&f, U &&u) &&
map_or
Definition: sol.hpp:5517
Definition: sol.hpp:11554
Definition: sol.hpp:8082
Definition: sol.hpp:24555
Definition: sol.hpp:2196
Definition: sol.hpp:11431
constexpr detail::invoke_result_t< F, const T & > and_then(F &&f) const &
Definition: sol.hpp:6347
Definition: sol.hpp:23425
constexpr const T & operator*() const
Definition: sol.hpp:6790
Definition: sol.hpp:1230
Definition: sol.hpp:8524
Definition: sol.hpp:17775
Definition: sol.hpp:7037
constexpr optional disjunction(const optional &rhs) const &
disjunction
Definition: sol.hpp:6602
Definition: sol.hpp:7540
Definition: sol.hpp:26730
Definition: sol.hpp:2674
Definition: sol.hpp:7004
optional & operator=(const optional< U > &rhs)
Definition: sol.hpp:5798
optional< T > or_else(F &&f) &&
Definition: sol.hpp:6467
Definition: sol.hpp:2653
Definition: sol.hpp:13018
Definition: sol.hpp:8583
Definition: sol.hpp:14256
Definition: sol.hpp:25191
Definition: sol.hpp:2659
Definition: sol.hpp:19515
Definition: sol.hpp:7367
Definition: sol.hpp:18990
SOL_TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t< F, T & > and_then(F &&f) &&
Definition: sol.hpp:6337
Definition: sol.hpp:11437
Definition: sol.hpp:9969
Definition: sol.hpp:1271
Definition: sol.hpp:23643
optional< T > or_else(F &&f) const &
Definition: sol.hpp:5471
Definition: sol.hpp:17187
constexpr detail::invoke_result_t< F, const T & > and_then(F &&f) const &
Definition: sol.hpp:5333
Definition: sol.hpp:7737
Definition: sol.hpp:9122
Definition: sol.hpp:7063
Definition: sol.hpp:28787
SOL_TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t< F, T & > and_then(F &&f) &
Definition: sol.hpp:6327
Definition: sol.hpp:6177
constexpr detail::invoke_result_t< F, const T & > and_then(F &&f) const &&
Definition: sol.hpp:6358
Definition: sol.hpp:11453
Definition: sol.hpp:11474
Definition: sol.hpp:8371
Definition: sol.hpp:2647
Definition: sol.hpp:2272
Definition: sol.hpp:17648
optional & operator=(nullopt_t) noexcept
Definition: sol.hpp:5756
Definition: lstate.h:160
Definition: sol.hpp:2174
Definition: sol.hpp:2656
optional take() const &
take
Definition: sol.hpp:6649
Definition: sol.hpp:5053
Definition: sol.hpp:1381
Definition: sol.hpp:1122
Definition: sol.hpp:10814
Definition: sol.hpp:25433
Definition: sol.hpp:4821
optional take() const &
take
Definition: sol.hpp:5636
Definition: lobject.h:113
void swap(optional &rhs) noexcept(std::is_nothrow_move_constructible< T >::value &&detail::is_nothrow_swappable< T >::value)
Definition: sol.hpp:5866
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:5691
Definition: sol.hpp:1261
Definition: sol.hpp:8443
Definition: sol.hpp:1157
Definition: sol.hpp:10940
An exception for when an optional is accessed through specific methods while it is not engaged...
Definition: sol.hpp:5225
Definition: sol.hpp:8392
optional take() &
Definition: sol.hpp:6642
optional take() &
Definition: sol.hpp:5629
Definition: sol.hpp:6990
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) &&
disjunction
Definition: sol.hpp:6607
constexpr optional(const optional< U > &rhs)
Definition: sol.hpp:6703
constexpr optional(detail::enable_if_t< std::is_constructible< T, Args... >::value, in_place_t >, Args &&... args)
Definition: sol.hpp:5684
Definition: sol.hpp:8509
Definition: sol.hpp:2190
Definition: sol.hpp:2367
Definition: sol.hpp:9361
Definition: sol.hpp:22840
SOL_TL_OPTIONAL_11_CONSTEXPR T * operator->()
Definition: sol.hpp:5893
Definition: sol.hpp:1470
Definition: sol.hpp:1137
Definition: sol.hpp:6966
Definition: sol.hpp:1296
Definition: sol.hpp:9918
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) &
disjunction
Definition: sol.hpp:6619
constexpr optional< typename std::decay< U >::type > conjunction(U &&u) const
Definition: sol.hpp:5577
Definition: sol.hpp:7370
Definition: sol.hpp:9571
Definition: sol.hpp:23673
Definition: sol.hpp:13068
U map_or(F &&f, U &&u) &&
map_or
Definition: sol.hpp:6530
Definition: sol.hpp:20541
Definition: sol.hpp:27235
Definition: sol.hpp:7753
Definition: sol.hpp:10894
Definition: sol.hpp:1273
Definition: sol.hpp:1301
Definition: sol.hpp:7555
SOL_TL_OPTIONAL_11_CONSTEXPR T & value()
Definition: sol.hpp:6809
Definition: sol.hpp:26938
Definition: sol.hpp:10789
Definition: sol.hpp:7325
Definition: sol.hpp:11460
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) &&
disjunction
Definition: sol.hpp:5616
constexpr optional() noexcept
Definition: sol.hpp:6675
U map_or(F &&f, U &&u) const &&
map_or
Definition: sol.hpp:5530
optional & operator=(nullopt_t) noexcept
Definition: sol.hpp:6712
Definition: sol.hpp:4870
Definition: sol.hpp:7692
optional< T > or_else(F &&f) const &&
Definition: sol.hpp:5488
Definition: sol.hpp:7307
Definition: sol.hpp:8117
constexpr T & value_or(U &&u) const
Definition: sol.hpp:6833
optional< T > or_else(F &&f) const &
Definition: sol.hpp:6484
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) const &
Definition: sol.hpp:5561
Definition: sol.hpp:16947
Definition: sol.hpp:7017
Definition: sol.hpp:7640
constexpr optional(nullopt_t) noexcept
ctor_empty
Definition: sol.hpp:6679
Definition: sol.hpp:4806
constexpr optional< typename std::decay< U >::type > conjunction(U &&u) const
Definition: sol.hpp:6590
Definition: sol.hpp:28632
Definition: sol.hpp:12375
SOL_TL_OPTIONAL_11_CONSTEXPR const T & value() const
Definition: sol.hpp:6820
constexpr optional(U &&u)
Definition: sol.hpp:6697
Definition: sol.hpp:10746
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) const &&
Definition: sol.hpp:5570
optional & operator=(const optional< U > &rhs)
Definition: sol.hpp:6739
Definition: sol.hpp:10775
Definition: sol.hpp:7060
Definition: sol.hpp:1278
Definition: sol.hpp:1263
Definition: sol.hpp:7791
SOL_TL_OPTIONAL_11_CONSTEXPR T && operator*() &&
Definition: sol.hpp:5912
Definition: sol.hpp:12398
Definition: sol.hpp:10727
Definition: sol.hpp:17922
Definition: sol.hpp:28236
Definition: sol.hpp:7372
Definition: sol.hpp:7412
Definition: sol.hpp:1228
void reset() noexcept
Destroys the stored value if one exists, making the optional empty.
Definition: sol.hpp:6839
Definition: sol.hpp:9981
Definition: sol.hpp:2278
Definition: sol.hpp:5025
Definition: sol.hpp:7278
Definition: sol.hpp:7056
Definition: sol.hpp:19062
Definition: sol.hpp:23662
Definition: sol.hpp:4901
Definition: sol.hpp:1265
constexpr bool has_value() const noexcept
Definition: sol.hpp:5925
Definition: sol.hpp:9748
Definition: sol.hpp:8101
Definition: sol.hpp:4544
Definition: sol.hpp:8714
Definition: sol.hpp:23628
optional< T > or_else(F &&f) &&
Definition: sol.hpp:5454
Definition: sol.hpp:2318
Definition: sol.hpp:2168
Definition: sol.hpp:8137
Definition: sol.hpp:8130
Definition: sol.hpp:7311
constexpr optional disjunction(optional &&rhs) const &
disjunction
Definition: sol.hpp:6624
Definition: sol.hpp:9897
Definition: sol.hpp:11447
Definition: sol.hpp:4782
Definition: sol.hpp:7515
Definition: sol.hpp:17659
optional & operator=(U &&u)
Definition: sol.hpp:6728
optional & operator=(optional< U > &&rhs)
Definition: sol.hpp:5822
constexpr optional(nullopt_t) noexcept
ctor_empty
Definition: sol.hpp:5665
optional< T > SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) &&
Definition: sol.hpp:5464
Definition: sol.hpp:8384
SOL_TL_OPTIONAL_11_CONSTEXPR T && value() &&
Definition: sol.hpp:5959
Definition: sol.hpp:21320
Definition: sol.hpp:2254
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:5437
Definition: sol.hpp:9582
SOL_TL_OPTIONAL_11_CONSTEXPR T value_or(U &&u) &&
value_or
Definition: sol.hpp:5992
T & emplace(Args &&... args)
Definition: sol.hpp:5843
Definition: sol.hpp:7030
Definition: sol.hpp:7334
Definition: sol.hpp:18150
Definition: sol.hpp:7714
Definition: sol.hpp:6947
Definition: sol.hpp:9881
Definition: sol.hpp:8612
Definition: sol.hpp:1222
Definition: sol.hpp:4571
Definition: sol.hpp:1162
optional(const optional< U > &rhs)
Definition: sol.hpp:5721
Definition: sol.hpp:18959
Definition: sol.hpp:1218
Definition: sol.hpp:1135
Definition: sol.hpp:7419
constexpr optional disjunction(optional &&rhs) const &
disjunction
Definition: sol.hpp:5611
SOL_TL_OPTIONAL_11_CONSTEXPR T & value() &
Definition: sol.hpp:5938
Definition: sol.hpp:23444
Definition: sol.hpp:1269
Definition: sol.hpp:10936
Definition: sol.hpp:25193
Definition: sol.hpp:21289
optional< T > SOL_TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) &&
Definition: sol.hpp:6477
Definition: sol.hpp:10934
detail::invoke_result_t< U > map_or_else(F &&f, U &&u) const &
Definition: sol.hpp:6574
Used to represent an optional with no data; essentially a bool.
Definition: sol.hpp:4704
Definition: sol.hpp:1140
Definition: sol.hpp:9224
Definition: sol.hpp:7066
Definition: sol.hpp:2155
Definition: sol.hpp:8430
SOL_TL_OPTIONAL_11_CONSTEXPR const T & value() const &
Definition: sol.hpp:5949
constexpr const T * operator->() const
Definition: sol.hpp:5887
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:5545
constexpr T value_or(U &&u) const &
Definition: sol.hpp:5985
Definition: sol.hpp:2312
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:6450
Definition: sol.hpp:7328
Definition: sol.hpp:12304
Definition: sol.hpp:7000
Definition: sol.hpp:7402
U map_or(F &&f, U &&u) &
Maps the stored value with f if there is one, otherwise returns u.
Definition: sol.hpp:5511
Definition: sol.hpp:21345
Definition: sol.hpp:1116
U map_or(F &&f, U &&u) const &&
map_or
Definition: sol.hpp:6543
constexpr optional disjunction(const optional &rhs) const &
disjunction
Definition: sol.hpp:5589
Definition: sol.hpp:23448
constexpr bool has_value() const noexcept
Definition: sol.hpp:6796
Definition: sol.hpp:1484
Definition: sol.hpp:1180
Definition: sol.hpp:26810
const char * what() const noexcept override
Returns a pointer to a null-terminated string containing the reason for the exception.
Definition: sol.hpp:5230
Definition: sol.hpp:8498
SOL_TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) &
Definition: sol.hpp:5584
Definition: sol.hpp:21303
Definition: sol.hpp:11434
Definition: sol.hpp:11458
Definition: sol.hpp:26936