27 #ifndef SOL_SINGLE_INCLUDE_HPP
28 #define SOL_SINGLE_INCLUDE_HPP
39 #define SOL_VERSION_MAJOR 3
40 #define SOL_VERSION_MINOR 2
41 #define SOL_VERSION_PATCH 3
42 #define SOL_VERSION_STRING "3.2.3"
43 #define SOL_VERSION ((SOL_VERSION_MAJOR * 100000) + (SOL_VERSION_MINOR * 100) + (SOL_VERSION_PATCH))
45 #define SOL_TOKEN_TO_STRING_POST_EXPANSION_I_(_TOKEN) #_TOKEN
46 #define SOL_TOKEN_TO_STRING_I_(_TOKEN) SOL_TOKEN_TO_STRING_POST_EXPANSION_I_(_TOKEN)
48 #define SOL_CONCAT_TOKENS_POST_EXPANSION_I_(_LEFT, _RIGHT) _LEFT##_RIGHT
49 #define SOL_CONCAT_TOKENS_I_(_LEFT, _RIGHT) SOL_CONCAT_TOKENS_POST_EXPANSION_I_(_LEFT, _RIGHT)
51 #define SOL_RAW_IS_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) != 0)
52 #define SOL_RAW_IS_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3) == 0)
53 #define SOL_RAW_IS_DEFAULT_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) > 3)
54 #define SOL_RAW_IS_DEFAULT_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3 OP_SYMBOL 3) < 0)
56 #define SOL_IS_ON(OP_SYMBOL) SOL_RAW_IS_ON(OP_SYMBOL ## _I_)
57 #define SOL_IS_OFF(OP_SYMBOL) SOL_RAW_IS_OFF(OP_SYMBOL ## _I_)
58 #define SOL_IS_DEFAULT_ON(OP_SYMBOL) SOL_RAW_IS_DEFAULT_ON(OP_SYMBOL ## _I_)
59 #define SOL_IS_DEFAULT_OFF(OP_SYMBOL) SOL_RAW_IS_DEFAULT_OFF(OP_SYMBOL ## _I_)
63 #define SOL_DEFAULT_ON +
64 #define SOL_DEFAULT_OFF -
66 #if defined(SOL_BUILD_CXX_MODE)
67 #if (SOL_BUILD_CXX_MODE != 0)
68 #define SOL_BUILD_CXX_MODE_I_ SOL_ON
70 #define SOL_BUILD_CXX_MODE_I_ SOL_OFF
72 #elif defined(__cplusplus)
73 #define SOL_BUILD_CXX_MODE_I_ SOL_DEFAULT_ON
75 #define SOL_BUILD_CXX_MODE_I_ SOL_DEFAULT_OFF
78 #if defined(SOL_BUILD_C_MODE)
79 #if (SOL_BUILD_C_MODE != 0)
80 #define SOL_BUILD_C_MODE_I_ SOL_ON
82 #define SOL_BUILD_C_MODE_I_ SOL_OFF
84 #elif defined(__STDC__)
85 #define SOL_BUILD_C_MODE_I_ SOL_DEFAULT_ON
87 #define SOL_BUILD_C_MODE_I_ SOL_DEFAULT_OFF
90 #if SOL_IS_ON(SOL_BUILD_C_MODE)
100 #if defined(SOL_COMPILER_VCXX)
101 #if defined(SOL_COMPILER_VCXX != 0)
102 #define SOL_COMPILER_VCXX_I_ SOL_ON
104 #define SOL_COMPILER_VCXX_I_ SOL_OFF
106 #elif defined(_MSC_VER)
107 #define SOL_COMPILER_VCXX_I_ SOL_DEFAULT_ON
109 #define SOL_COMPILER_VCXX_I_ SOL_DEFAULT_OFF
112 #if defined(SOL_COMPILER_GCC)
113 #if defined(SOL_COMPILER_GCC != 0)
114 #define SOL_COMPILER_GCC_I_ SOL_ON
116 #define SOL_COMPILER_GCC_I_ SOL_OFF
118 #elif defined(__GNUC__)
119 #define SOL_COMPILER_GCC_I_ SOL_DEFAULT_ON
121 #define SOL_COMPILER_GCC_I_ SOL_DEFAULT_OFF
124 #if defined(SOL_COMPILER_CLANG)
125 #if defined(SOL_COMPILER_CLANG != 0)
126 #define SOL_COMPILER_CLANG_I_ SOL_ON
128 #define SOL_COMPILER_CLANG_I_ SOL_OFF
130 #elif defined(__clang__)
131 #define SOL_COMPILER_CLANG_I_ SOL_DEFAULT_ON
133 #define SOL_COMPILER_CLANG_I_ SOL_DEFAULT_OFF
136 #if defined(SOL_COMPILER_EDG)
137 #if defined(SOL_COMPILER_EDG != 0)
138 #define SOL_COMPILER_EDG_I_ SOL_ON
140 #define SOL_COMPILER_EDG_I_ SOL_OFF
143 #define SOL_COMPILER_EDG_I_ SOL_DEFAULT_OFF
146 #if defined(SOL_COMPILER_MINGW)
147 #if (SOL_COMPILER_MINGW != 0)
148 #define SOL_COMPILER_MINGW_I_ SOL_ON
150 #define SOL_COMPILER_MINGW_I_ SOL_OFF
152 #elif defined(__MINGW32__)
153 #define SOL_COMPILER_MINGW_I_ SOL_DEFAULT_ON
155 #define SOL_COMPILER_MINGW_I_ SOL_DEFAULT_OFF
158 #if SIZE_MAX <= 0xFFFFULL
159 #define SOL_PLATFORM_X16_I_ SOL_ON
160 #define SOL_PLATFORM_X86_I_ SOL_OFF
161 #define SOL_PLATFORM_X64_I_ SOL_OFF
162 #elif SIZE_MAX <= 0xFFFFFFFFULL
163 #define SOL_PLATFORM_X16_I_ SOL_OFF
164 #define SOL_PLATFORM_X86_I_ SOL_ON
165 #define SOL_PLATFORM_X64_I_ SOL_OFF
167 #define SOL_PLATFORM_X16_I_ SOL_OFF
168 #define SOL_PLATFORM_X86_I_ SOL_OFF
169 #define SOL_PLATFORM_X64_I_ SOL_ON
172 #define SOL_PLATFORM_ARM32_I_ SOL_OFF
173 #define SOL_PLATFORM_ARM64_I_ SOL_OFF
175 #if defined(SOL_PLATFORM_WINDOWS)
176 #if (SOL_PLATFORM_WINDOWS != 0)
177 #define SOL_PLATFORM_WINDOWS_I_ SOL_ON
179 #define SOL_PLATFORM_WINDOWS_I_ SOL_OFF
181 #elif defined(_WIN32)
182 #define SOL_PLATFORM_WINDOWS_I_ SOL_DEFAULT_ON
184 #define SOL_PLATFORM_WINDOWS_I_ SOL_DEFAULT_OFF
187 #if defined(SOL_PLATFORM_CYGWIN)
188 #if (SOL_PLATFORM_CYGWIN != 0)
189 #define SOL_PLATFORM_CYGWIN_I_ SOL_ON
191 #define SOL_PLATFORM_CYGWIN_I_ SOL_ON
193 #elif defined(__CYGWIN__)
194 #define SOL_PLATFORM_CYGWIN_I_ SOL_DEFAULT_ON
196 #define SOL_PLATFORM_CYGWIN_I_ SOL_DEFAULT_OFF
199 #if defined(SOL_PLATFORM_APPLE)
200 #if (SOL_PLATFORM_APPLE != 0)
201 #define SOL_PLATFORM_APPLE_I_ SOL_ON
203 #define SOL_PLATFORM_APPLE_I_ SOL_OFF
205 #elif defined(__APPLE__)
206 #define SOL_PLATFORM_APPLE_I_ SOL_DEFAULT_ON
208 #define SOL_PLATFORM_APPLE_I_ SOL_DEFAULT_OFF
211 #if defined(SOL_PLATFORM_UNIX)
212 #if (SOL_PLATFORM_UNIX != 0)
213 #define SOL_PLATFORM_UNIXLIKE_I_ SOL_ON
215 #define SOL_PLATFORM_UNIXLIKE_I_ SOL_OFF
217 #elif defined(__unix__)
218 #define SOL_PLATFORM_UNIXLIKE_I_ SOL_DEFAUKT_ON
220 #define SOL_PLATFORM_UNIXLIKE_I_ SOL_DEFAULT_OFF
223 #if defined(SOL_PLATFORM_LINUX)
224 #if (SOL_PLATFORM_LINUX != 0)
225 #define SOL_PLATFORM_LINUXLIKE_I_ SOL_ON
227 #define SOL_PLATFORM_LINUXLIKE_I_ SOL_OFF
229 #elif defined(__LINUX__)
230 #define SOL_PLATFORM_LINUXLIKE_I_ SOL_DEFAUKT_ON
232 #define SOL_PLATFORM_LINUXLIKE_I_ SOL_DEFAULT_OFF
235 #define SOL_PLATFORM_APPLE_IPHONE_I_ SOL_OFF
236 #define SOL_PLATFORM_BSDLIKE_I_ SOL_OFF
238 #if defined(SOL_IN_DEBUG_DETECTED)
239 #if SOL_IN_DEBUG_DETECTED != 0
240 #define SOL_DEBUG_BUILD_I_ SOL_ON
242 #define SOL_DEBUG_BUILD_I_ SOL_OFF
244 #elif !defined(NDEBUG)
245 #if SOL_IS_ON(SOL_COMPILER_VCXX) && defined(_DEBUG)
246 #define SOL_DEBUG_BUILD_I_ SOL_ON
247 #elif (SOL_IS_ON(SOL_COMPILER_CLANG) || SOL_IS_ON(SOL_COMPILER_GCC)) && !defined(__OPTIMIZE__)
248 #define SOL_DEBUG_BUILD_I_ SOL_ON
250 #define SOL_DEBUG_BUILD_I_ SOL_OFF
253 #define SOL_DEBUG_BUILD_I_ SOL_DEFAULT_OFF
254 #endif // We are in a debug mode of some sort
256 #if defined(SOL_NO_EXCEPTIONS)
257 #if (SOL_NO_EXCEPTIONS != 0)
258 #define SOL_EXCEPTIONS_I_ SOL_OFF
260 #define SOL_EXCEPTIONS_I_ SOL_ON
262 #elif SOL_IS_ON(SOL_COMPILER_VCXX)
263 #if !defined(_CPPUNWIND)
264 #define SOL_EXCEPTIONS_I_ SOL_OFF
266 #define SOL_EXCEPTIONS_I_ SOL_ON
268 #elif SOL_IS_ON(SOL_COMPILER_CLANG) || SOL_IS_ON(SOL_COMPILER_GCC)
269 #if !defined(__EXCEPTIONS)
270 #define SOL_EXCEPTIONS_I_ SOL_OFF
272 #define SOL_EXCEPTIONS_I_ SOL_ON
275 #define SOL_EXCEPTIONS_I_ SOL_DEFAULT_ON
278 #if defined(SOL_NO_RTTI)
279 #if (SOL_NO_RTTI != 0)
280 #define SOL_RTTI_I_ SOL_OFF
282 #define SOL_RTTI_I_ SOL_ON
284 #elif SOL_IS_ON(SOL_COMPILER_VCXX)
285 #if !defined(_CPPRTTI)
286 #define SOL_RTTI_I_ SOL_OFF
288 #define SOL_RTTI_I_ SOL_ON
290 #elif SOL_IS_ON(SOL_COMPILER_CLANG) || SOL_IS_ON(SOL_COMPILER_GCC)
291 #if !defined(__GXX_RTTI)
292 #define SOL_RTTI_I_ SOL_OFF
294 #define SOL_RTTI_I_ SOL_ON
297 #define SOL_RTTI_I_ SOL_DEFAULT_ON
300 #if defined(SOL_NO_THREAD_LOCAL)
301 #if SOL_NO_THREAD_LOCAL != 0
302 #define SOL_USE_THREAD_LOCAL_I_ SOL_OFF
304 #define SOL_USE_THREAD_LOCAL_I_ SOL_ON
307 #define SOL_USE_THREAD_LOCAL_I_ SOL_DEFAULT_ON
308 #endif // thread_local keyword is bjorked on some platforms
310 #if defined(SOL_ALL_SAFETIES_ON)
311 #if SOL_ALL_SAFETIES_ON != 0
312 #define SOL_ALL_SAFETIES_ON_I_ SOL_ON
314 #define SOL_ALL_SAFETIES_ON_I_ SOL_OFF
317 #define SOL_ALL_SAFETIES_ON_I_ SOL_DEFAULT_OFF
320 #if defined(SOL_SAFE_GETTER)
321 #if SOL_SAFE_GETTER != 0
322 #define SOL_SAFE_GETTER_I_ SOL_ON
324 #define SOL_SAFE_GETTER_I_ SOL_OFF
327 #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
328 #define SOL_SAFE_GETTER_I_ SOL_ON
329 #elif SOL_IS_ON(SOL_DEBUG_BUILD)
330 #define SOL_SAFE_GETTER_I_ SOL_DEFAULT_ON
332 #define SOL_SAFE_GETTER_I_ SOL_DEFAULT_OFF
336 #if defined(SOL_SAFE_USERTYPE)
337 #if SOL_SAFE_USERTYPE != 0
338 #define SOL_SAFE_USERTYPE_I_ SOL_ON
340 #define SOL_SAFE_USERTYPE_I_ SOL_OFF
343 #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
344 #define SOL_SAFE_USERTYPE_I_ SOL_ON
345 #elif SOL_IS_ON(SOL_DEBUG_BUILD)
346 #define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_ON
348 #define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_OFF
352 #if defined(SOL_SAFE_REFERENCES)
353 #if SOL_SAFE_REFERENCES != 0
354 #define SOL_SAFE_REFERENCES_I_ SOL_ON
356 #define SOL_SAFE_REFERENCES_I_ SOL_OFF
359 #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
360 #define SOL_SAFE_REFERENCES_I_ SOL_ON
361 #elif SOL_IS_ON(SOL_DEBUG_BUILD)
362 #define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_ON
364 #define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_OFF
368 #if defined(SOL_SAFE_FUNCTIONS)
369 #if SOL_SAFE_FUNCTIONS != 0
370 #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON
372 #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_OFF
374 #elif defined (SOL_SAFE_FUNCTION_OBJECTS)
375 #if SOL_SAFE_FUNCTION_OBJECTS != 0
376 #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON
378 #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_OFF
381 #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
382 #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON
383 #elif SOL_IS_ON(SOL_DEBUG_BUILD)
384 #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_ON
386 #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_OFF
390 #if defined(SOL_SAFE_FUNCTION_CALLS)
391 #if SOL_SAFE_FUNCTION_CALLS != 0
392 #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON
394 #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_OFF
397 #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
398 #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON
399 #elif SOL_IS_ON(SOL_DEBUG_BUILD)
400 #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_ON
402 #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_OFF
406 #if defined(SOL_SAFE_PROXIES)
407 #if SOL_SAFE_PROXIES != 0
408 #define SOL_SAFE_PROXIES_I_ SOL_ON
410 #define SOL_SAFE_PROXIES_I_ SOL_OFF
413 #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
414 #define SOL_SAFE_PROXIES_I_ SOL_ON
415 #elif SOL_IS_ON(SOL_DEBUG_BUILD)
416 #define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_ON
418 #define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_OFF
422 #if defined(SOL_SAFE_NUMERICS)
423 #if SOL_SAFE_NUMERICS != 0
424 #define SOL_SAFE_NUMERICS_I_ SOL_ON
426 #define SOL_SAFE_NUMERICS_I_ SOL_OFF
429 #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
430 #define SOL_SAFE_NUMERICS_I_ SOL_ON
431 #elif SOL_IS_ON(SOL_DEBUG_BUILD)
432 #define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_ON
434 #define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_OFF
438 #if defined(SOL_ALL_INTEGER_VALUES_FIT)
439 #if (SOL_ALL_INTEGER_VALUES_FIT != 0)
440 #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_ON
442 #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_OFF
444 #elif !SOL_IS_DEFAULT_OFF(SOL_SAFE_NUMERICS) && SOL_IS_OFF(SOL_SAFE_NUMERICS)
446 #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_DEFAULT_ON
449 #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_DEFAULT_OFF
452 #if defined(SOL_SAFE_STACK_CHECK)
453 #if SOL_SAFE_STACK_CHECK != 0
454 #define SOL_SAFE_STACK_CHECK_I_ SOL_ON
456 #define SOL_SAFE_STACK_CHECK_I_ SOL_OFF
459 #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
460 #define SOL_SAFE_STACK_CHECK_I_ SOL_ON
461 #elif SOL_IS_ON(SOL_DEBUG_BUILD)
462 #define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_ON
464 #define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_OFF
468 #if defined(SOL_NO_CHECK_NUMBER_PRECISION)
469 #if SOL_NO_CHECK_NUMBER_PRECISION != 0
470 #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_OFF
472 #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON
474 #elif defined(SOL_NO_CHECKING_NUMBER_PRECISION)
475 #if SOL_NO_CHECKING_NUMBER_PRECISION != 0
476 #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_OFF
478 #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON
481 #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
482 #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON
483 #elif SOL_IS_ON(SOL_SAFE_NUMERICS)
484 #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON
485 #elif SOL_IS_ON(SOL_DEBUG_BUILD)
486 #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_ON
488 #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_OFF
492 #if defined(SOL_STRINGS_ARE_NUMBERS)
493 #if (SOL_STRINGS_ARE_NUMBERS != 0)
494 #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_ON
496 #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_OFF
499 #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_DEFAULT_OFF
502 #if defined(SOL_ENABLE_INTEROP)
503 #if SOL_ENABLE_INTEROP != 0
504 #define SOL_USE_INTEROP_I_ SOL_ON
506 #define SOL_USE_INTEROP_I_ SOL_OFF
508 #elif defined(SOL_USE_INTEROP)
509 #if SOL_USE_INTEROP != 0
510 #define SOL_USE_INTEROP_I_ SOL_ON
512 #define SOL_USE_INTEROP_I_ SOL_OFF
515 #define SOL_USE_INTEROP_I_ SOL_DEFAULT_OFF
518 #if defined(SOL_NO_NIL)
519 #if (SOL_NO_NIL != 0)
520 #define SOL_NIL_I_ SOL_OFF
522 #define SOL_NIL_I_ SOL_ON
524 #elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) || defined(__OBJC__) || defined(nil)
525 #define SOL_NIL_I_ SOL_DEFAULT_OFF
527 #define SOL_NIL_I_ SOL_DEFAULT_ON
530 #if defined(SOL_USERTYPE_TYPE_BINDING_INFO)
531 #if (SOL_USERTYPE_TYPE_BINDING_INFO != 0)
532 #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_ON
534 #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_OFF
537 #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_DEFAULT_ON
538 #endif // We should generate a my_type.__type table with lots of class information for usertypes
540 #if defined(SOL_AUTOMAGICAL_TYPES_BY_DEFAULT)
541 #if (SOL_AUTOMAGICAL_TYPES_BY_DEFAULT != 0)
542 #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON
544 #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF
546 #elif defined(SOL_DEFAULT_AUTOMAGICAL_USERTYPES)
547 #if (SOL_DEFAULT_AUTOMAGICAL_USERTYPES != 0)
548 #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON
550 #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF
553 #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_DEFAULT_ON
554 #endif // make is_automagical on/off by default
556 #if defined(SOL_STD_VARIANT)
557 #if (SOL_STD_VARIANT != 0)
558 #define SOL_STD_VARIANT_I_ SOL_ON
560 #define SOL_STD_VARIANT_I_ SOL_OFF
563 #if SOL_IS_ON(SOL_COMPILER_CLANG) && SOL_IS_ON(SOL_PLATFORM_APPLE)
564 #if defined(__has_include)
565 #if __has_include(<variant>)
566 #define SOL_STD_VARIANT_I_ SOL_DEFAULT_ON
568 #define SOL_STD_VARIANT_I_ SOL_DEFAULT_OFF
571 #define SOL_STD_VARIANT_I_ SOL_DEFAULT_OFF
574 #define SOL_STD_VARIANT_I_ SOL_DEFAULT_ON
576 #endif // make is_automagical on/off by default
578 #if defined(SOL_NOEXCEPT_FUNCTION_TYPE)
579 #if (SOL_NOEXCEPT_FUNCTION_TYPE != 0)
580 #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON
582 #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF
585 #if defined(__cpp_noexcept_function_type)
586 #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON
587 #elif SOL_IS_ON(SOL_COMPILER_VCXX) && (defined(_MSVC_LANG) && (_MSVC_LANG < 201403L))
593 #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF
595 #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_DEFAULT_ON
597 #endif // noexcept is part of a function's type
599 #if defined(SOL_STACK_STRING_OPTIMIZATION_SIZE) && SOL_STACK_STRING_OPTIMIZATION_SIZE > 0
600 #define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ SOL_STACK_STRING_OPTIMIZATION_SIZE
602 #define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ 1024
605 #if defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0
606 #define SOL_ID_SIZE_I_ SOL_ID_SIZE
608 #define SOL_ID_SIZE_I_ 512
611 #if defined(LUA_IDSIZE) && LUA_IDSIZE > 0
612 #define SOL_FILE_ID_SIZE_I_ LUA_IDSIZE
613 #elif defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0
614 #define SOL_FILE_ID_SIZE_I_ SOL_FILE_ID_SIZE
616 #define SOL_FILE_ID_SIZE_I_ 2048
619 #if defined(SOL_PRINT_ERRORS)
620 #if (SOL_PRINT_ERRORS != 0)
621 #define SOL_PRINT_ERRORS_I_ SOL_ON
623 #define SOL_PRINT_ERRORS_I_ SOL_OFF
626 #if SOL_IS_ON(SOL_ALL_SAFETIES_ON)
627 #define SOL_PRINT_ERRORS_I_ SOL_ON
628 #elif SOL_IS_ON(SOL_DEBUG_BUILD)
629 #define SOL_PRINT_ERRORS_I_ SOL_DEFAULT_ON
631 #define SOL_PRINT_ERRORS_I_ SOL_OFF
635 #if defined(SOL_DEFAULT_PASS_ON_ERROR)
636 #if (SOL_DEFAULT_PASS_ON_ERROR != 0)
637 #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_ON
639 #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_OFF
642 #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_DEFAULT_OFF
645 #if defined(SOL_USING_CXX_LUA)
646 #if (SOL_USING_CXX_LUA != 0)
647 #define SOL_USE_CXX_LUA_I_ SOL_ON
649 #define SOL_USE_CXX_LUA_I_ SOL_OFF
651 #elif defined(SOL_USE_CXX_LUA)
652 #if (SOL_USE_CXX_LUA != 0)
653 #define SOL_USE_CXX_LUA_I_ SOL_ON
655 #define SOL_USE_CXX_LUA_I_ SOL_OFF
658 #define SOL_USE_CXX_LUA_I_ SOL_DEFAULT_OFF
661 #if defined(SOL_USING_CXX_LUAJIT)
662 #if (SOL_USING_CXX_LUA != 0)
663 #define SOL_USE_CXX_LUAJIT_I_ SOL_ON
665 #define SOL_USE_CXX_LUAJIT_I_ SOL_OFF
667 #elif defined(SOL_USE_CXX_LUAJIT)
668 #if (SOL_USE_CXX_LUA != 0)
669 #define SOL_USE_CXX_LUAJIT_I_ SOL_ON
671 #define SOL_USE_CXX_LUAJIT_I_ SOL_OFF
674 #define SOL_USE_CXX_LUAJIT_I_ SOL_DEFAULT_OFF
677 #if defined(SOL_NO_LUA_HPP)
678 #if (SOL_NO_LUA_HPP != 0)
679 #define SOL_USE_LUA_HPP_I_ SOL_OFF
681 #define SOL_USE_LUA_HPP_I_ SOL_ON
683 #elif defined(SOL_USING_CXX_LUA)
684 #define SOL_USE_LUA_HPP_I_ SOL_OFF
685 #elif defined(__has_include)
686 #if __has_include(<lua.hpp>)
687 #define SOL_USE_LUA_HPP_I_ SOL_ON
689 #define SOL_USE_LUA_HPP_I_ SOL_OFF
692 #define SOL_USE_LUA_HPP_I_ SOL_DEFAULT_ON
695 #if defined(SOL_CONTAINERS_START)
696 #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START
697 #elif defined(SOL_CONTAINERS_START_INDEX)
698 #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START_INDEX
699 #elif defined(SOL_CONTAINER_START_INDEX)
700 #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINER_START_INDEX
702 #define SOL_CONTAINER_START_INDEX_I_ 1
705 #if defined (SOL_NO_MEMORY_ALIGNMENT)
706 #if (SOL_NO_MEMORY_ALIGNMENT != 0)
707 #define SOL_ALIGN_MEMORY_I_ SOL_OFF
709 #define SOL_ALIGN_MEMORY_I_ SOL_ON
712 #define SOL_ALIGN_MEMORY_I_ SOL_DEFAULT_ON
715 #if defined(SOL_USE_BOOST)
716 #if (SOL_USE_BOOST != 0)
717 #define SOL_USE_BOOST_I_ SOL_ON
719 #define SOL_USE_BOOST_I_ SOL_OFF
722 #define SOL_USE_BOOST_I_ SOL_DEFAULT_OFF
725 #if defined(SOL_USE_UNSAFE_BASE_LOOKUP)
726 #if (SOL_USE_UNSAFE_BASE_LOOKUP != 0)
727 #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_ON
729 #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_OFF
732 #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_DEFAULT_OFF
735 #if defined(SOL_INSIDE_UNREAL)
736 #if (SOL_INSIDE_UNREAL != 0)
737 #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_ON
739 #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_OFF
742 #if defined(UE_BUILD_DEBUG) || defined(UE_BUILD_DEVELOPMENT) || defined(UE_BUILD_TEST) || defined(UE_BUILD_SHIPPING) || defined(UE_SERVER)
743 #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_DEFAULT_ON
745 #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_DEFAULT_OFF
749 #if defined(SOL_NO_COMPAT)
750 #if (SOL_NO_COMPAT != 0)
751 #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_OFF
753 #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_ON
756 #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_DEFAULT_ON
759 #if defined(SOL_GET_FUNCTION_POINTER_UNSAFE)
760 #if (SOL_GET_FUNCTION_POINTER_UNSAFE != 0)
761 #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_ON
763 #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_OFF
766 #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_DEFAULT_OFF
769 #if defined(SOL_FUNCTION_CALL_VALUE_SEMANTICS)
770 #if (SOL_FUNCTION_CALL_VALUE_SEMANTICS != 0)
771 #define SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_ SOL_ON
773 #define SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_ SOL_OFF
776 #define SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_ SOL_DEFAULT_OFF
779 #if defined(SOL_MINGW_CCTYPE_IS_POISONED)
780 #if (SOL_MINGW_CCTYPE_IS_POISONED != 0)
781 #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_ON
783 #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_OFF
785 #elif SOL_IS_ON(SOL_COMPILER_MINGW) && defined(__GNUC__) && (__GNUC__ < 6)
787 #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_DEFAULT_ON
789 #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_DEFAULT_OFF
792 #if defined(SOL_CHAR8_T)
793 #if (SOL_CHAR8_T != 0)
794 #define SOL_CHAR8_T_I_ SOL_ON
796 #define SOL_CHAR8_T_I_ SOL_OFF
799 #if defined(__cpp_char8_t)
800 #define SOL_CHAR8_T_I_ SOL_DEFAULT_ON
802 #define SOL_CHAR8_T_I_ SOL_DEFAULT_OFF
806 #if SOL_IS_ON(SOL_USE_BOOST)
807 #include <boost/version.hpp>
809 #if BOOST_VERSION >= 107500 // Since Boost 1.75.0 boost::none is constexpr
810 #define SOL_BOOST_NONE_CONSTEXPR_I_ constexpr
812 #define SOL_BOOST_NONE_CONSTEXPR_I_ const
813 #endif // BOOST_VERSION
816 #define SOL_BOOST_NONE_CONSTEXPR_I_ constexpr
821 #define SOL2_CI_I_ SOL_ON
823 #define SOL2_CI_I_ SOL_OFF
826 #define SOL2_CI_I_ SOL_DEFAULT_OFF
829 #if defined(SOL_C_ASSERT)
830 #define SOL_USER_C_ASSERT_I_ SOL_ON
832 #define SOL_USER_C_ASSERT_I_ SOL_DEFAULT_OFF
835 #if defined(SOL_M_ASSERT)
836 #define SOL_USER_M_ASSERT_I_ SOL_ON
838 #define SOL_USER_M_ASSERT_I_ SOL_DEFAULT_OFF
843 #if defined(SOL_PROLOGUE_I_)
844 #error "[sol2] Library Prologue was already included in translation unit and not properly ended with an epilogue."
847 #define SOL_PROLOGUE_I_ 1
849 #if SOL_IS_ON(SOL_BUILD_CXX_MODE)
850 #define _FWD(...) static_cast<decltype( __VA_ARGS__ )&&>( __VA_ARGS__ )
852 #if SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
853 #define _MOVE(...) static_cast<__typeof( __VA_ARGS__ )&&>( __VA_ARGS__ )
855 #include <type_traits>
857 #define _MOVE(...) static_cast<::std::remove_reference_t<( __VA_ARGS__ )>&&>( __VA_OPT__(,) )
865 #if !defined(SOL_PROLOGUE_I_)
866 #error "[sol2] Library Prologue is missing from this translation unit."
868 #undef SOL_PROLOGUE_I_
871 #if SOL_IS_ON(SOL_BUILD_CXX_MODE)
882 #define SOL_DLL_I_ SOL_ON
884 #define SOL_DLL_I_ SOL_OFF
886 #elif SOL_IS_ON(SOL_COMPILER_VCXX) && (defined(DLL_) || defined(_DLL))
887 #define SOL_DLL_I_ SOL_DEFAULT_ON
889 #define SOL_DLL_I_ SOL_DEFAULT_OFF
890 #endif // DLL definition
892 #if defined(SOL_HEADER_ONLY)
893 #if (SOL_HEADER_ONLY != 0)
894 #define SOL_HEADER_ONLY_I_ SOL_ON
896 #define SOL_HEADER_ONLY_I_ SOL_OFF
899 #define SOL_HEADER_ONLY_I_ SOL_DEFAULT_OFF
900 #endif // Header only library
902 #if defined(SOL_BUILD)
904 #define SOL_BUILD_I_ SOL_ON
906 #define SOL_BUILD_I_ SOL_OFF
908 #elif SOL_IS_ON(SOL_HEADER_ONLY)
909 #define SOL_BUILD_I_ SOL_DEFAULT_OFF
911 #define SOL_BUILD_I_ SOL_DEFAULT_ON
914 #if defined(SOL_UNITY_BUILD)
915 #if (SOL_UNITY_BUILD != 0)
916 #define SOL_UNITY_BUILD_I_ SOL_ON
918 #define SOL_UNITY_BUILD_I_ SOL_OFF
921 #define SOL_UNITY_BUILD_I_ SOL_DEFAULT_OFF
922 #endif // Header only library
924 #if defined(SOL_C_FUNCTION_LINKAGE)
925 #define SOL_C_FUNCTION_LINKAGE_I_ SOL_C_FUNCTION_LINKAGE
927 #if SOL_IS_ON(SOL_BUILD_CXX_MODE)
929 #define SOL_C_FUNCTION_LINKAGE_I_ extern "C"
932 #define SOL_C_FUNCTION_LINKAGE_I_
934 #endif // Linkage specification for C functions
936 #if defined(SOL_API_LINKAGE)
937 #define SOL_API_LINKAGE_I_ SOL_API_LINKAGE
939 #if SOL_IS_ON(SOL_DLL)
940 #if SOL_IS_ON(SOL_COMPILER_VCXX) || SOL_IS_ON(SOL_PLATFORM_WINDOWS) || SOL_IS_ON(SOL_PLATFORM_CYGWIN)
942 #if SOL_IS_ON(SOL_BUILD)
944 #if SOL_IS_ON(SOL_COMPILER_GCC)
946 #define SOL_API_LINKAGE_I_ __attribute__((dllexport))
949 #define SOL_API_LINKAGE_I_ __declspec(dllexport)
952 #if SOL_IS_ON(SOL_COMPILER_GCC)
953 #define SOL_API_LINKAGE_I_ __attribute__((dllimport))
955 #define SOL_API_LINKAGE_I_ __declspec(dllimport)
960 #define SOL_API_LINKAGE_I_ extern
962 #elif SOL_IS_ON(SOL_UNITY_BUILD)
964 #if SOL_IS_ON(SOL_HEADER_ONLY)
966 #define SOL_API_LINKAGE_I_ inline
969 #define SOL_API_LINKAGE_I_ extern
973 #if SOL_IS_ON(SOL_BUILD_CXX_MODE)
974 #define SOL_API_LINKAGE_I_
976 #define SOL_API_LINKAGE_I_ extern
979 #endif // Build definitions
981 #if defined(SOL_PUBLIC_FUNC_DECL)
982 #define SOL_PUBLIC_FUNC_DECL_I_ SOL_PUBLIC_FUNC_DECL
984 #define SOL_PUBLIC_FUNC_DECL_I_ SOL_API_LINKAGE_I_
987 #if defined(SOL_INTERNAL_FUNC_DECL_)
988 #define SOL_INTERNAL_FUNC_DECL_I_ SOL_INTERNAL_FUNC_DECL_
990 #define SOL_INTERNAL_FUNC_DECL_I_ SOL_API_LINKAGE_I_
993 #if defined(SOL_PUBLIC_FUNC_DEF)
994 #define SOL_PUBLIC_FUNC_DEF_I_ SOL_PUBLIC_FUNC_DEF
996 #define SOL_PUBLIC_FUNC_DEF_I_ SOL_API_LINKAGE_I_
999 #if defined(SOL_INTERNAL_FUNC_DEF)
1000 #define SOL_INTERNAL_FUNC_DEF_I_ SOL_INTERNAL_FUNC_DEF
1002 #define SOL_INTERNAL_FUNC_DEF_I_ SOL_API_LINKAGE_I_
1005 #if defined(SOL_FUNC_DECL)
1006 #define SOL_FUNC_DECL_I_ SOL_FUNC_DECL
1007 #elif SOL_IS_ON(SOL_HEADER_ONLY)
1008 #define SOL_FUNC_DECL_I_
1009 #elif SOL_IS_ON(SOL_DLL)
1010 #if SOL_IS_ON(SOL_COMPILER_VCXX)
1011 #if SOL_IS_ON(SOL_BUILD)
1012 #define SOL_FUNC_DECL_I_ extern __declspec(dllexport)
1014 #define SOL_FUNC_DECL_I_ extern __declspec(dllimport)
1016 #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
1017 #define SOL_FUNC_DECL_I_ extern __attribute__((visibility("default")))
1019 #define SOL_FUNC_DECL_I_ extern
1023 #if defined(SOL_FUNC_DEFN)
1024 #define SOL_FUNC_DEFN_I_ SOL_FUNC_DEFN
1025 #elif SOL_IS_ON(SOL_HEADER_ONLY)
1026 #define SOL_FUNC_DEFN_I_ inline
1027 #elif SOL_IS_ON(SOL_DLL)
1028 #if SOL_IS_ON(SOL_COMPILER_VCXX)
1029 #if SOL_IS_ON(SOL_BUILD)
1030 #define SOL_FUNC_DEFN_I_ __declspec(dllexport)
1032 #define SOL_FUNC_DEFN_I_ __declspec(dllimport)
1034 #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
1035 #define SOL_FUNC_DEFN_I_ __attribute__((visibility("default")))
1037 #define SOL_FUNC_DEFN_I_
1041 #if defined(SOL_HIDDEN_FUNC_DECL)
1042 #define SOL_HIDDEN_FUNC_DECL_I_ SOL_HIDDEN_FUNC_DECL
1043 #elif SOL_IS_ON(SOL_HEADER_ONLY)
1044 #define SOL_HIDDEN_FUNC_DECL_I_
1045 #elif SOL_IS_ON(SOL_DLL)
1046 #if SOL_IS_ON(SOL_COMPILER_VCXX)
1047 #if SOL_IS_ON(SOL_BUILD)
1048 #define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllexport)
1050 #define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllimport)
1052 #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
1053 #define SOL_HIDDEN_FUNC_DECL_I_ extern __attribute__((visibility("default")))
1055 #define SOL_HIDDEN_FUNC_DECL_I_ extern
1059 #if defined(SOL_HIDDEN_FUNC_DEFN)
1060 #define SOL_HIDDEN_FUNC_DEFN_I_ SOL_HIDDEN_FUNC_DEFN
1061 #elif SOL_IS_ON(SOL_HEADER_ONLY)
1062 #define SOL_HIDDEN_FUNC_DEFN_I_ inline
1063 #elif SOL_IS_ON(SOL_DLL)
1064 #if SOL_IS_ON(SOL_COMPILER_VCXX)
1065 #if SOL_IS_ON(SOL_BUILD)
1066 #define SOL_HIDDEN_FUNC_DEFN_I_
1068 #define SOL_HIDDEN_FUNC_DEFN_I_
1070 #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
1071 #define SOL_HIDDEN_FUNC_DEFN_I_ __attribute__((visibility("hidden")))
1073 #define SOL_HIDDEN_FUNC_DEFN_I_
1081 #if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE)
1083 #pragma push_macro("check")
1086 #endif // Unreal Engine 4 Bullshit
1088 #if SOL_IS_ON(SOL_COMPILER_GCC)
1089 #pragma GCC diagnostic push
1090 #pragma GCC diagnostic ignored "-Wshadow"
1091 #pragma GCC diagnostic ignored "-Wconversion"
1093 #pragma GCC diagnostic ignored "-Wnoexcept-type"
1095 #elif SOL_IS_ON(SOL_COMPILER_CLANG)
1096 #elif SOL_IS_ON(SOL_COMPILER_VCXX)
1097 #pragma warning(push)
1098 #pragma warning(disable : 4505) // unreferenced local function has been removed GEE THANKS
1099 #endif // clang++ vs. g++ vs. VC++
1103 #ifndef SOL_FORWARD_HPP
1104 #define SOL_FORWARD_HPP
1107 #include <type_traits>
1108 #include <string_view>
1110 #if SOL_IS_ON(SOL_USE_CXX_LUA) || SOL_IS_ON(SOL_USE_CXX_LUAJIT)
1116 #endif // C++ Mangling for Lua vs. Not
1122 class stateless_reference;
1124 class basic_reference;
1125 using reference = basic_reference<false>;
1127 class stateless_stack_reference;
1128 class stack_reference;
1130 template <
typename A>
1131 class basic_bytecode;
1135 struct proxy_base_tag;
1138 template <
typename,
typename>
1141 template <
bool,
typename>
1142 class basic_table_core;
1144 using table_core = basic_table_core<b, reference>;
1149 template <
typename base_type>
1150 using basic_table = basic_table_core<false, base_type>;
1151 using table = table_core<false>;
1159 struct basic_lua_table;
1160 using lua_table = basic_lua_table<reference>;
1163 template <
typename T,
typename base_type>
1164 class basic_usertype;
1165 template <
typename T>
1166 using usertype = basic_usertype<T, reference>;
1167 template <
typename T>
1170 template <
typename base_type>
1171 class basic_metatable;
1172 using metatable = basic_metatable<reference>;
1175 template <
typename base_t>
1176 struct basic_environment;
1181 template <
typename T,
bool>
1182 class basic_function;
1183 template <
typename T,
bool,
typename H>
1184 class basic_protected_function;
1186 using safe_function = basic_protected_function<reference, false, reference>;
1188 using main_safe_function = basic_protected_function<main_reference, false, reference>;
1197 #if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS)
1210 struct unsafe_function_result;
1211 struct protected_function_result;
1213 #if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS)
1219 template <
typename base_t>
1220 class basic_object_base;
1221 template <
typename base_t>
1223 template <
typename base_t>
1224 class basic_userdata;
1225 template <
typename base_t>
1226 class basic_lightuserdata;
1227 template <
typename base_t>
1228 class basic_coroutine;
1229 template <
typename base_t>
1230 class basic_packaged_coroutine;
1231 template <
typename base_t>
1234 using object = basic_object<reference>;
1235 using userdata = basic_userdata<reference>;
1237 using thread = basic_thread<reference>;
1238 using coroutine = basic_coroutine<reference>;
1250 struct stack_proxy_base;
1252 struct variadic_args;
1253 struct variadic_results;
1256 struct this_main_state;
1257 struct this_environment;
1262 template <
typename T>
1264 template <
typename T>
1265 struct as_container_t;
1266 template <
typename T>
1268 template <
typename T>
1270 template <
typename T>
1272 template <
typename T>
1274 template <
typename T>
1276 template <
typename F,
typename... Policies>
1277 struct policy_wrapper;
1279 template <
typename T>
1280 struct usertype_traits;
1281 template <
typename T>
1282 struct unique_usertype_traits;
1284 template <
typename... Args>
1288 return sizeof...(Args);
1292 template <
typename T>
1297 template <
typename T>
1302 template <
typename T>
1307 template <
typename T>
1314 #if SOL_IS_OFF(SOL_USE_BOOST)
1326 #define SOL_BASE_CLASSES(T, ...) \
1329 struct base<T> : std::true_type { \
1330 typedef ::sol::types<__VA_ARGS__> type; \
1333 void a_sol3_detail_function_decl_please_no_collide()
1334 #define SOL_DERIVED_CLASSES(T, ...) \
1337 struct derive<T> : std::true_type { \
1338 typedef ::sol::types<__VA_ARGS__> type; \
1341 void a_sol3_detail_function_decl_please_no_collide()
1343 #endif // SOL_FORWARD_HPP
1348 #ifndef SOL_FORWARD_DETAIL_HPP
1349 #define SOL_FORWARD_DETAIL_HPP
1357 #include <type_traits>
1369 template <
typename...>
1372 template <
typename T>
1375 template <
typename T>
1378 namespace meta_detail {
1379 template <
typename T>
1382 template <
template <
class...>
class Test,
class,
class... Args>
1385 template <
template <
class...>
class Test,
class... Args>
1389 template <
template <
class...>
class Trait,
class... Args>
1392 template <
template <
class...>
class Trait,
class... Args>
1395 template <std::
size_t I>
1400 template <
typename T,
typename U>
1406 template <
typename T,
typename U>
1410 template <
bool B,
typename T,
typename U>
1413 namespace meta_detail {
1414 template <
typename T,
template <
typename...>
class Templ>
1416 template <
typename... T,
template <
typename...>
class Templ>
1420 template <
typename T,
template <
typename...>
class Templ>
1423 template <
typename T,
template <
typename...>
class Templ>
1426 template <
typename T>
1431 template <
typename T>
1434 template <
typename T>
1435 using is_builtin_type = std::integral_constant<bool, std::is_arithmetic<T>::value || std::is_pointer<T>::value || std::is_array<T>::value>;
1437 namespace meta_detail {
1438 template <
typename T,
typename =
void>
1440 template <
typename T>
1443 template <
typename T>
1446 template <
typename T>
1464 template <
typename T>
1467 template <
typename T>
1471 template <
typename... Args>
1476 template <
typename... Args>
1482 template <
typename... Args>
1485 template <
typename Arg>
1488 template <
typename Arg>
1491 template <
typename... Args>
1497 template <
typename Arg,
typename... Args>
1503 template <std::
size_t N,
typename Tuple>
1506 template <std::
size_t N,
typename Tuple>
1509 template <std::
size_t N,
typename Tuple>
1512 template <std::
size_t N,
typename Tuple>
1522 namespace sol {
namespace meta {
1523 namespace meta_detail {
1524 template <
typename F>
1528 template <
typename F>
1531 template <
typename F>
1534 namespace meta_detail {
1536 template <std::
size_t I,
typename T>
1539 template <std::
size_t I>
1544 template <std::
size_t I,
typename T>
1547 template <
bool it_is_noexcept,
bool has_c_variadic,
typename T,
typename R,
typename... Args>
1568 template <std::
size_t i>
1572 template <typename Signature, bool b = call_operator_deducible<Signature>::value>
1576 template <
typename R,
typename... Args>
1578 typedef R (*function_pointer_type)(Args...);
1581 template <
typename R,
typename... Args>
1583 typedef R (*function_pointer_type)(Args...);
1586 template <
typename R,
typename... Args>
1588 typedef R (*function_pointer_type)(Args..., ...);
1591 template <
typename R,
typename... Args>
1593 typedef R (*function_pointer_type)(Args..., ...);
1598 template <
typename T,
typename R,
typename... Args>
1600 typedef R (T::*function_pointer_type)(Args...);
1603 template <
typename T,
typename R,
typename... Args>
1605 typedef R (T::*function_pointer_type)(Args..., ...);
1609 template <
typename T,
typename R,
typename... Args>
1611 typedef R (T::*function_pointer_type)(Args...)
const;
1614 template <
typename T,
typename R,
typename... Args>
1616 typedef R (T::*function_pointer_type)(Args..., ...)
const;
1619 template <
typename T,
typename R,
typename... Args>
1621 typedef R (T::*function_pointer_type)(Args...)
const volatile;
1624 template <
typename T,
typename R,
typename... Args>
1626 typedef R (T::*function_pointer_type)(Args..., ...)
const volatile;
1630 template <
typename T,
typename R,
typename... Args>
1632 typedef R (T::*function_pointer_type)(Args...) &;
1635 template <
typename T,
typename R,
typename... Args>
1637 typedef R (T::*function_pointer_type)(Args..., ...) &;
1640 template <
typename T,
typename R,
typename... Args>
1642 typedef R (T::*function_pointer_type)(Args...)
const&;
1645 template <
typename T,
typename R,
typename... Args>
1647 typedef R (T::*function_pointer_type)(Args..., ...)
const&;
1650 template <
typename T,
typename R,
typename... Args>
1652 typedef R (T::*function_pointer_type)(Args...)
const volatile&;
1655 template <
typename T,
typename R,
typename... Args>
1657 typedef R (T::*function_pointer_type)(Args..., ...)
const volatile&;
1660 template <
typename T,
typename R,
typename... Args>
1662 typedef R (T::*function_pointer_type)(Args...) &&;
1665 template <
typename T,
typename R,
typename... Args>
1667 typedef R (T::*function_pointer_type)(Args..., ...) &&;
1670 template <
typename T,
typename R,
typename... Args>
1672 typedef R (T::*function_pointer_type)(Args...)
const&&;
1675 template <
typename T,
typename R,
typename... Args>
1677 typedef R (T::*function_pointer_type)(Args..., ...)
const&&;
1680 template <
typename T,
typename R,
typename... Args>
1682 typedef R (T::*function_pointer_type)(Args...)
const volatile&&;
1685 template <
typename T,
typename R,
typename... Args>
1687 typedef R (T::*function_pointer_type)(Args..., ...)
const volatile&&;
1690 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
1692 template <
typename R,
typename... Args>
1694 typedef R (*function_pointer_type)(Args...) noexcept;
1697 template <
typename R,
typename... Args>
1699 typedef R (*function_pointer_type)(Args...) noexcept;
1702 template <
typename R,
typename... Args>
1704 typedef R (*function_pointer_type)(Args..., ...) noexcept;
1707 template <
typename R,
typename... Args>
1709 typedef R (*function_pointer_type)(Args..., ...) noexcept;
1712 template <
typename T,
typename R,
typename... Args>
1714 typedef R (T::*function_pointer_type)(Args...) noexcept;
1717 template <
typename T,
typename R,
typename... Args>
1719 typedef R (T::*function_pointer_type)(Args..., ...) noexcept;
1723 template <
typename T,
typename R,
typename... Args>
1725 typedef R (T::*function_pointer_type)(Args...)
const noexcept;
1728 template <
typename T,
typename R,
typename... Args>
1730 typedef R (T::*function_pointer_type)(Args..., ...)
const noexcept;
1733 template <
typename T,
typename R,
typename... Args>
1735 typedef R (T::*function_pointer_type)(Args...)
const volatile noexcept;
1738 template <
typename T,
typename R,
typename... Args>
1739 struct fx_traits<R (T::*)(Args..., ...) const volatile noexcept, false> :
public basic_traits<true, true, T, R, Args...> {
1740 typedef R (T::*function_pointer_type)(Args..., ...)
const volatile noexcept;
1743 template <
typename T,
typename R,
typename... Args>
1745 typedef R (T::*function_pointer_type)(Args...) & noexcept;
1748 template <
typename T,
typename R,
typename... Args>
1750 typedef R (T::*function_pointer_type)(Args..., ...) & noexcept;
1753 template <
typename T,
typename R,
typename... Args>
1755 typedef R (T::*function_pointer_type)(Args...)
const& noexcept;
1758 template <
typename T,
typename R,
typename... Args>
1760 typedef R (T::*function_pointer_type)(Args..., ...)
const& noexcept;
1763 template <
typename T,
typename R,
typename... Args>
1765 typedef R (T::*function_pointer_type)(Args...)
const volatile& noexcept;
1768 template <
typename T,
typename R,
typename... Args>
1769 struct fx_traits<R (T::*)(Args..., ...) const volatile& noexcept, false> :
public basic_traits<true, true, T, R, Args...> {
1770 typedef R (T::*function_pointer_type)(Args..., ...)
const volatile& noexcept;
1773 template <
typename T,
typename R,
typename... Args>
1775 typedef R (T::*function_pointer_type)(Args...) && noexcept;
1778 template <
typename T,
typename R,
typename... Args>
1780 typedef R (T::*function_pointer_type)(Args..., ...) && noexcept;
1783 template <
typename T,
typename R,
typename... Args>
1785 typedef R (T::*function_pointer_type)(Args...)
const&& noexcept;
1788 template <
typename T,
typename R,
typename... Args>
1790 typedef R (T::*function_pointer_type)(Args..., ...)
const&& noexcept;
1793 template <
typename T,
typename R,
typename... Args>
1794 struct fx_traits<R (T::*)(Args...) const volatile&& noexcept, false> :
public basic_traits<true, false, T, R, Args...> {
1795 typedef R (T::*function_pointer_type)(Args...)
const volatile&& noexcept;
1798 template <
typename T,
typename R,
typename... Args>
1799 struct fx_traits<R (T::*)(Args..., ...) const volatile&& noexcept, false> :
public basic_traits<true, true, T, R, Args...> {
1800 typedef R (T::*function_pointer_type)(Args..., ...)
const volatile&& noexcept;
1803 #endif // noexcept is part of a function's type
1805 #if SOL_IS_ON(SOL_COMPILER_VCXX) && SOL_IS_ON(SOL_PLATFORM_X86)
1806 template <
typename R,
typename... Args>
1807 struct fx_traits<R __stdcall(Args...), false> :
public basic_traits<false, false, void, R, Args...> {
1808 typedef R(__stdcall* function_pointer_type)(Args...);
1811 template <
typename R,
typename... Args>
1812 struct fx_traits<R(__stdcall*)(Args...),
false> :
public basic_traits<
false,
false,
void, R, Args...> {
1813 typedef R(__stdcall* function_pointer_type)(Args...);
1816 template <
typename T,
typename R,
typename... Args>
1817 struct fx_traits<R (__stdcall T::*)(Args...), false> :
public basic_traits<false, false, T, R, Args...> {
1818 typedef R (__stdcall T::*function_pointer_type)(Args...);
1822 template <
typename T,
typename R,
typename... Args>
1823 struct fx_traits<R (__stdcall T::*)(Args...) const, false> :
public basic_traits<false, false, T, R, Args...> {
1824 typedef R (__stdcall T::*function_pointer_type)(Args...)
const;
1827 template <
typename T,
typename R,
typename... Args>
1828 struct fx_traits<R (__stdcall T::*)(Args...) const volatile, false> :
public basic_traits<false, false, T, R, Args...> {
1829 typedef R (__stdcall T::*function_pointer_type)(Args...)
const volatile;
1833 template <
typename T,
typename R,
typename... Args>
1834 struct fx_traits<R (__stdcall T::*)(Args...)&, false> :
public basic_traits<false, false, T, R, Args...> {
1835 typedef R (__stdcall T::*function_pointer_type)(Args...) &;
1838 template <
typename T,
typename R,
typename... Args>
1839 struct fx_traits<R (__stdcall T::*)(Args...) const&, false> :
public basic_traits<false, false, T, R, Args...> {
1840 typedef R (__stdcall T::*function_pointer_type)(Args...)
const&;
1843 template <
typename T,
typename R,
typename... Args>
1844 struct fx_traits<R (__stdcall T::*)(Args...) const volatile&, false> :
public basic_traits<false, false, T, R, Args...> {
1845 typedef R (__stdcall T::*function_pointer_type)(Args...)
const volatile&;
1848 template <
typename T,
typename R,
typename... Args>
1849 struct fx_traits<R (__stdcall T::*)(Args...)&&, false> :
public basic_traits<false, false, T, R, Args...> {
1850 typedef R (__stdcall T::*function_pointer_type)(Args...) &&;
1853 template <
typename T,
typename R,
typename... Args>
1854 struct fx_traits<R (__stdcall T::*)(Args...) const&&, false> :
public basic_traits<false, false, T, R, Args...> {
1855 typedef R (__stdcall T::*function_pointer_type)(Args...)
const&&;
1858 template <
typename T,
typename R,
typename... Args>
1859 struct fx_traits<R (__stdcall T::*)(Args...) const volatile&&, false> :
public basic_traits<false, false, T, R, Args...> {
1860 typedef R (__stdcall T::*function_pointer_type)(Args...)
const volatile&&;
1863 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
1865 template <
typename R,
typename... Args>
1866 struct fx_traits<R __stdcall(Args...) noexcept, false> :
public basic_traits<true, false, void, R, Args...> {
1867 typedef R(__stdcall* function_pointer_type)(Args...) noexcept;
1870 template <
typename R,
typename... Args>
1871 struct fx_traits<R(__stdcall*)(Args...) noexcept, false> : public basic_traits<true, false,
void, R, Args...> {
1872 typedef R(__stdcall* function_pointer_type)(Args...) noexcept;
1886 template <
typename T,
typename R,
typename... Args>
1887 struct fx_traits<R (__stdcall T::*)(Args...) noexcept, false> :
public basic_traits<true, false, T, R, Args...> {
1888 typedef R (__stdcall T::*function_pointer_type)(Args...) noexcept;
1898 template <
typename T,
typename R,
typename... Args>
1899 struct fx_traits<R (__stdcall T::*)(Args...) const noexcept, false> :
public basic_traits<true, false, T, R, Args...> {
1900 typedef R (__stdcall T::*function_pointer_type)(Args...)
const noexcept;
1909 template <
typename T,
typename R,
typename... Args>
1910 struct fx_traits<R (__stdcall T::*)(Args...) const volatile noexcept, false> :
public basic_traits<true, false, T, R, Args...> {
1911 typedef R (__stdcall T::*function_pointer_type)(Args...)
const volatile noexcept;
1920 template <
typename T,
typename R,
typename... Args>
1921 struct fx_traits<R (__stdcall T::*)(Args...)& noexcept, false> :
public basic_traits<true, false, T, R, Args...> {
1922 typedef R (__stdcall T::*function_pointer_type)(Args...) & noexcept;
1931 template <
typename T,
typename R,
typename... Args>
1932 struct fx_traits<R (__stdcall T::*)(Args...) const& noexcept, false> :
public basic_traits<true, false, T, R, Args...> {
1933 typedef R (__stdcall T::*function_pointer_type)(Args...)
const& noexcept;
1942 template <
typename T,
typename R,
typename... Args>
1943 struct fx_traits<R (__stdcall T::*)(Args...) const volatile& noexcept, false> :
public basic_traits<true, false, T, R, Args...> {
1944 typedef R (__stdcall T::*function_pointer_type)(Args...)
const volatile& noexcept;
1953 template <
typename T,
typename R,
typename... Args>
1954 struct fx_traits<R (__stdcall T::*)(Args...)&& noexcept, false> :
public basic_traits<true, false, T, R, Args...> {
1955 typedef R (__stdcall T::*function_pointer_type)(Args...) && noexcept;
1964 template <
typename T,
typename R,
typename... Args>
1965 struct fx_traits<R (__stdcall T::*)(Args...) const&& noexcept, false> :
public basic_traits<true, false, T, R, Args...> {
1966 typedef R (__stdcall T::*function_pointer_type)(Args...)
const&& noexcept;
1975 template <
typename T,
typename R,
typename... Args>
1976 struct fx_traits<R (__stdcall T::*)(Args...) const volatile&& noexcept, false> :
public basic_traits<true, false, T, R, Args...> {
1977 typedef R (__stdcall T::*function_pointer_type)(Args...)
const volatile&& noexcept;
1985 #endif // noexcept is part of a function's type
1986 #endif // __stdcall x86 VC++ bug
1988 template <
typename Signature>
1989 struct fx_traits<Signature, true> :
public fx_traits<typename fx_traits<decltype(&Signature::operator())>::function_type, false> { };
1991 template <typename Signature, bool b = std::is_member_object_pointer<Signature>::value>
1994 template <
typename R,
typename T>
2011 template <std::
size_t i>
2017 template <
typename Signature>
2020 namespace meta_detail {
2021 template <
typename,
bool>
2024 template <
typename T>
2028 template <
typename T>
2031 template <
typename T>
2034 template <
typename Signature>
2037 template <
typename Signature>
2040 template <
typename Signature>
2049 #include <type_traits>
2055 namespace meta_detail {
2056 template <
typename T>
2059 template <
typename T>
2063 template <
typename T>
2065 !std::is_array_v<T> && (std::is_pointer_v<T> || is_detected_v<meta_detail::is_explicitly_dereferenceable_test, T>)>;
2067 template <
typename T>
2073 template <
typename T>
2074 auto unwrap(T&& item) -> decltype(std::forward<T>(item)) {
2075 return std::forward<T>(item);
2078 template <
typename T>
2083 template <
typename T>
2086 if constexpr (meta::is_pointer_like_v<Tu>) {
2087 return *std::forward<T>(item);
2090 return std::forward<T>(item);
2094 template <
typename T>
2097 if constexpr (meta::is_pointer_like_v<Tu> && !std::is_pointer_v<Tu> && !std::is_copy_constructible_v<Tu>) {
2098 return *std::forward<T>(item);
2101 return std::forward<T>(item);
2105 template <
typename T>
2107 return std::addressof(val);
2110 template <
typename T>
2111 inline T*
ptr(std::reference_wrapper<T> val) {
2112 return std::addressof(val.get());
2115 template <
typename T>
2128 #include <string_view>
2129 #include <functional>
2132 template <
typename C,
typename T = std::
char_traits<C>>
2144 #include <type_traits>
2147 #include <functional>
2151 #if SOL_IS_ON(SOL_STD_VARIANT)
2153 #endif // variant is weird on XCode, thanks XCode
2155 namespace sol {
namespace meta {
2156 template <
typename T>
2161 template <
typename T>
2166 template <
typename T>
2169 template <
typename T>
2172 template <
typename T>
2175 template <
typename T>
2178 template <
typename R,
typename T>
2183 template <
typename R,
typename T>
2188 template <
typename T>
2191 template <
typename T,
typename...>
2194 template <
typename T,
typename U,
typename... Args>
2195 struct all_same<T, U, Args...> : std::integral_constant<bool, std::is_same<T, U>::value && all_same<T, Args...>::value> { };
2197 template <
typename T,
typename...>
2200 template <
typename T,
typename U,
typename... Args>
2201 struct any_same<T, U, Args...> : std::integral_constant<bool, std::is_same<T, U>::value || any_same<T, Args...>::value> { };
2203 template <
typename T,
typename... Args>
2207 using boolean = std::integral_constant<bool, B>;
2212 template <
typename T>
2215 template <
typename T>
2218 template <
typename... Args>
2221 template <
typename T,
typename... Args>
2224 template <
typename... Args>
2227 template <
typename T,
typename... Args>
2230 template <
typename... Args>
2233 template <
typename... Args>
2240 template <
bool value,
typename T =
void>
2243 template <
typename... Args>
2246 template <
typename... Args>
2249 template <
typename... Args>
2252 template <
typename... Args>
2255 template <
typename V,
typename... Vs>
2258 template <
typename V,
typename Vs1,
typename... Vs>
2259 struct find_in_pack_v<V, Vs1, Vs...> :
any<boolean<(V::value == Vs1::value)>, find_in_pack_v<V, Vs...>> { };
2261 namespace meta_detail {
2262 template <
std::size_t I,
typename T,
typename... Args>
2265 template <
std::size_t I,
typename T,
typename T1,
typename... Args>
2267 :
conditional_t<std::is_same<T, T1>::value, std::integral_constant<std::ptrdiff_t, I>, index_in_pack<I + 1, T, Args...>> { };
2270 template <
typename T,
typename... Args>
2273 template <
typename T,
typename List>
2276 template <
typename T,
typename... Args>
2285 template <
std::size_t I,
typename Arg,
typename... Args>
2286 struct at_in_pack<I, Arg, Args...> : std::conditional<I == 0, Arg, at_in_pack_t<I - 1, Args...>> { };
2288 template <
typename Arg,
typename... Args>
2293 namespace meta_detail {
2294 template <
typename,
typename TI>
2297 template <
typename,
typename TI>
2300 template <
typename,
typename>
2303 template <
template <
typename...>
class When,
std::size_t Limit,
std::size_t I,
template <
typename...>
class Pred,
typename... Ts>
2305 template <
template <
typename...>
class When,
std::size_t Limit,
std::size_t I,
template <
typename...>
class Pred,
typename T,
typename... Ts>
2308 || Limit<2, std::integral_constant<std::size_t, I + static_cast<std::size_t>(Limit != 0 && Pred<T>::value)>,
2309 count_when_for_pack<When, Limit - static_cast<std::size_t>(When<T, std::integral_constant<std::size_t, I>>::value),
2310 I + static_cast<std::size_t>(When<T, std::integral_constant<std::size_t, I>>::value&& Pred<T>::value), Pred, Ts...>> { };
2313 template <template <typename...> class Pred, typename... Ts>
2314 struct count_for_pack : meta_detail::count_when_for_pack<meta_detail::on_always, sizeof...(Ts), 0, Pred, Ts...> { };
2316 template <template <typename...> class Pred, typename... Ts>
2317 inline constexpr std::size_t count_for_pack_v = count_for_pack<Pred, Ts...>::value;
2319 template <template <typename...> class Pred, typename List>
2322 template <template <typename...> class Pred, typename... Args>
2323 struct count_for<Pred, types<Args...>> : count_for_pack<Pred, Args...> { };
2325 template <std::size_t Limit, template <typename...> class Pred, typename... Ts>
2326 struct count_for_to_pack : meta_detail::count_when_for_pack<meta_detail::on_always, Limit, 0, Pred, Ts...> { };
2328 template <std::size_t Limit, template <typename...> class Pred, typename... Ts>
2329 inline constexpr std::size_t count_for_to_pack_v = count_for_to_pack<Limit, Pred, Ts...>::value;
2331 template <template <typename...> class When, std::size_t Limit, template <typename...> class Pred, typename... Ts>
2332 struct count_when_for_to_pack : meta_detail::count_when_for_pack<When, Limit, 0, Pred, Ts...> { };
2334 template <template <typename...> class When, std::size_t Limit, template <typename...> class Pred, typename... Ts>
2335 inline constexpr std::size_t count_when_for_to_pack_v = count_when_for_to_pack<When, Limit, Pred, Ts...>::value;
2337 template <template <typename...> class Pred, typename... Ts>
2338 using count_even_for_pack = count_when_for_to_pack<meta_detail::on_even, sizeof...(Ts), Pred, Ts...>;
2340 template <template <typename...> class Pred, typename... Ts>
2341 inline constexpr std::size_t count_even_for_pack_v = count_even_for_pack<Pred, Ts...>::value;
2343 template <template <typename...> class Pred, typename... Ts>
2344 using count_odd_for_pack = count_when_for_to_pack<meta_detail::on_odd, sizeof...(Ts), Pred, Ts...>;
2346 template <template <typename...> class Pred, typename... Ts>
2347 inline constexpr std::size_t count_odd_for_pack_v = count_odd_for_pack<Pred, Ts...>::value;
2349 template <typename... Args>
2350 struct return_type {
2351 typedef std::tuple<Args...> type;
2354 template <typename T>
2355 struct return_type<T> {
2360 struct return_type<> {
2364 template <typename... Args>
2365 using return_type_t = typename return_type<Args...>::type;
2367 namespace meta_detail {
2369 struct always_true : std::true_type { };
2370 struct is_invokable_tester {
2371 template <typename Fun, typename... Args>
2372 static always_true<decltype(std::declval<Fun>()(std::declval<Args>()...))> test(int);
2373 template <typename...>
2374 static std::false_type test(...);
2378 template <typename T>
2379 struct is_invokable;
2380 template <typename Fun, typename... Args>
2381 struct is_invokable<Fun(Args...)> : decltype(meta_detail::is_invokable_tester::test<Fun, Args...>(0)) { };
2383 namespace meta_detail {
2385 template <typename T, typename = void>
2386 struct is_invocable : std::is_function<std::remove_pointer_t<T>> { };
2388 template <typename T>
2389 struct is_invocable<T,
2390 std::enable_if_t<std::is_final<unqualified_t<T>>::value && std::is_class<unqualified_t<T>>::value
2391 && std::is_same<decltype(void(&T::operator())), void>::value>> { };
2393 template <typename T>
2394 struct is_invocable<T,
2395 std::enable_if_t<!std::is_final<unqualified_t<T>>::value && std::is_class<unqualified_t<T>>::value
2396 && std::is_destructible<unqualified_t<T>>::value>> {
2398 void operator()() {};
2400 struct Derived : T, F { };
2401 template <typename U, U>
2404 template <typename V>
2405 static sfinae_no_t test(Check<void (F::*)(), &V::operator()>*);
2408 static sfinae_yes_t test(...);
2410 static constexpr bool value = std::is_same_v<decltype(test<Derived>(0)), sfinae_yes_t>;
2413 template <typename T>
2414 struct is_invocable<T,
2415 std::enable_if_t<!std::is_final<unqualified_t<T>>::value && std::is_class<unqualified_t<T>>::value
2416 && !std::is_destructible<unqualified_t<T>>::value>> {
2418 void operator()() {};
2420 struct Derived : T, F {
2421 ~Derived() = delete;
2423 template <typename U, U>
2426 template <typename V>
2427 static sfinae_no_t test(Check<void (F::*)(), &V::operator()>*);
2430 static sfinae_yes_t test(...);
2432 static constexpr bool value = std::is_same_v<decltype(test<Derived>(0)), sfinae_yes_t>;
2435 struct has_begin_end_impl {
2436 template <typename T, typename U = unqualified_t<T>, typename B = decltype(std::declval<U&>().begin()),
2437 typename E = decltype(std::declval<U&>().end())>
2438 static std::true_type test(int);
2440 template <typename...>
2441 static std::false_type test(...);
2444 struct has_key_type_impl {
2445 template <typename T, typename U = unqualified_t<T>, typename V = typename U::key_type>
2446 static std::true_type test(int);
2448 template <typename...>
2449 static std::false_type test(...);
2452 struct has_key_comp_impl {
2453 template <typename T, typename V = decltype(std::declval<unqualified_t<T>>().key_comp())>
2454 static std::true_type test(int);
2456 template <typename...>
2457 static std::false_type test(...);
2460 struct has_load_factor_impl {
2461 template <typename T, typename V = decltype(std::declval<unqualified_t<T>>().load_factor())>
2462 static std::true_type test(int);
2464 template <typename...>
2465 static std::false_type test(...);
2468 struct has_mapped_type_impl {
2469 template <typename T, typename V = typename unqualified_t<T>::mapped_type>
2470 static std::true_type test(int);
2472 template <typename...>
2473 static std::false_type test(...);
2476 struct has_value_type_impl {
2477 template <typename T, typename V = typename unqualified_t<T>::value_type>
2478 static std::true_type test(int);
2480 template <typename...>
2481 static std::false_type test(...);
2484 struct has_iterator_impl {
2485 template <typename T, typename V = typename unqualified_t<T>::iterator>
2486 static std::true_type test(int);
2488 template <typename...>
2489 static std::false_type test(...);
2492 struct has_key_value_pair_impl {
2493 template <typename T, typename U = unqualified_t<T>, typename V = typename U::value_type, typename F = decltype(std::declval<V&>().first),
2494 typename S = decltype(std::declval<V&>().second)>
2495 static std::true_type test(int);
2497 template <typename...>
2498 static std::false_type test(...);
2501 template <typename T>
2502 struct has_push_back_test {
2504 template <typename C>
2505 static sfinae_yes_t test(decltype(std::declval<C>().push_back(std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
2506 template <typename C>
2507 static sfinae_no_t test(...);
2510 static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
2513 template <typename T>
2514 struct has_insert_with_iterator_test {
2516 template <typename C>
2517 static sfinae_yes_t test(decltype(std::declval<C>().insert(
2518 std::declval<std::add_rvalue_reference_t<typename C::iterator>>(), std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
2519 template <typename C>
2520 static sfinae_no_t test(...);
2523 static constexpr bool value = !std::is_same_v<decltype(test<T>(0)), sfinae_no_t>;
2526 template <typename T>
2527 struct has_insert_test {
2529 template <typename C>
2530 static sfinae_yes_t test(decltype(std::declval<C>().insert(std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
2531 template <typename C>
2532 static sfinae_no_t test(...);
2535 static constexpr bool value = !std::is_same_v<decltype(test<T>(0)), sfinae_no_t>;
2538 template <typename T>
2539 struct has_insert_after_test {
2541 template <typename C>
2542 static sfinae_yes_t test(decltype(std::declval<C>().insert_after(std::declval<std::add_rvalue_reference_t<typename C::const_iterator>>(),
2543 std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
2544 template <typename C>
2545 static sfinae_no_t test(...);
2548 static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
2551 template <typename T>
2552 struct has_size_test {
2554 template <typename C>
2555 static sfinae_yes_t test(decltype(std::declval<C>().size())*);
2556 template <typename C>
2557 static sfinae_no_t test(...);
2560 static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
2563 template <typename T>
2564 struct has_max_size_test {
2566 template <typename C>
2567 static sfinae_yes_t test(decltype(std::declval<C>().max_size())*);
2568 template <typename C>
2569 static sfinae_no_t test(...);
2572 static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
2575 template <typename T>
2576 struct has_to_string_test {
2578 template <typename C>
2579 static sfinae_yes_t test(decltype(std::declval<C>().to_string())*);
2580 template <typename C>
2581 static sfinae_no_t test(...);
2584 static constexpr bool value = std::is_same_v<decltype(test<T>(0)), sfinae_yes_t>;
2587 template <typename T, typename U, typename = void>
2588 class supports_op_less_test : public std::false_type { };
2589 template <typename T, typename U>
2590 class supports_op_less_test<T, U, void_t<decltype(std::declval<T&>() < std::declval<U&>())>>
2591 : public std::integral_constant<bool,
2592 #if SOL_IS_ON(SOL_STD_VARIANT)
2593 !is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>
2600 template <typename T, typename U, typename = void>
2601 class supports_op_equal_test : public std::false_type { };
2602 template <typename T, typename U>
2603 class supports_op_equal_test<T, U, void_t<decltype(std::declval<T&>() == std::declval<U&>())>>
2604 : public std::integral_constant<bool,
2605 #if SOL_IS_ON(SOL_STD_VARIANT)
2606 !is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>
2613 template <typename T, typename U, typename = void>
2614 class supports_op_less_equal_test : public std::false_type { };
2615 template <typename T, typename U>
2616 class supports_op_less_equal_test<T, U, void_t<decltype(std::declval<T&>() <= std::declval<U&>())>>
2617 : public std::integral_constant<bool,
2618 #if SOL_IS_ON(SOL_STD_VARIANT)
2619 !is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>
2626 template <typename T, typename U, typename = void>
2627 class supports_op_left_shift_test : public std::false_type { };
2628 template <typename T, typename U>
2629 class supports_op_left_shift_test<T, U, void_t<decltype(std::declval<T&>() << std::declval<U&>())>> : public std::true_type { };
2631 template <typename T, typename = void>
2632 class supports_adl_to_string_test : public std::false_type { };
2633 template <typename T>
2634 class supports_adl_to_string_test<T, void_t<decltype(to_string(std::declval<const T&>()))>> : public std::true_type { };
2636 template <typename T, bool b>
2637 struct is_matched_lookup_impl : std::false_type { };
2638 template <typename T>
2639 struct is_matched_lookup_impl<T, true> : std::is_same<typename T::key_type, typename T::value_type> { };
2641 template <typename T>
2642 using non_void_t = meta::conditional_t<std::is_void_v<T>, ::sol::detail::unchecked_t, T>;
2645 template <typename T, typename U = T>
2646 class supports_op_less : public meta_detail::supports_op_less_test<T, U> { };
2648 template <typename T, typename U = T>
2649 class supports_op_equal : public meta_detail::supports_op_equal_test<T, U> { };
2651 template <typename T, typename U = T>
2652 class supports_op_less_equal : public meta_detail::supports_op_less_equal_test<T, U> { };
2654 template <typename T, typename U = T>
2655 class supports_op_left_shift : public meta_detail::supports_op_left_shift_test<T, U> { };
2657 template <typename T>
2658 class supports_adl_to_string : public meta_detail::supports_adl_to_string_test<T> { };
2660 template <typename T>
2661 class supports_to_string_member : public meta::boolean<meta_detail::has_to_string_test<meta_detail::non_void_t<T>>::value> { };
2663 template <typename T>
2664 using is_invocable = boolean<meta_detail::is_invocable<T>::value>;
2666 template <typename T>
2667 constexpr inline bool is_invocable_v = is_invocable<T>::value;
2669 template <typename T>
2670 struct has_begin_end : decltype(meta_detail::has_begin_end_impl::test<T>(0)) { };
2672 template <typename T>
2673 constexpr inline bool has_begin_end_v = has_begin_end<T>::value;
2675 template <typename T>
2676 struct has_key_value_pair : decltype(meta_detail::has_key_value_pair_impl::test<T>(0)) { };
2678 template <typename T>
2679 struct has_key_type : decltype(meta_detail::has_key_type_impl::test<T>(0)) { };
2681 template <typename T>
2682 struct has_key_comp : decltype(meta_detail::has_key_comp_impl::test<T>(0)) { };
2684 template <typename T>
2685 struct has_load_factor : decltype(meta_detail::has_load_factor_impl::test<T>(0)) { };
2687 template <typename T>
2688 struct has_mapped_type : decltype(meta_detail::has_mapped_type_impl::test<T>(0)) { };
2690 template <typename T>
2691 struct has_iterator : decltype(meta_detail::has_iterator_impl::test<T>(0)) { };
2693 template <typename T>
2694 struct has_value_type : decltype(meta_detail::has_value_type_impl::test<T>(0)) { };
2696 template <typename T>
2697 using has_push_back = meta::boolean<meta_detail::has_push_back_test<T>::value>;
2699 template <typename T>
2700 using has_max_size = meta::boolean<meta_detail::has_max_size_test<T>::value>;
2702 template <typename T>
2703 using has_insert = meta::boolean<meta_detail::has_insert_test<T>::value>;
2705 template <typename T>
2706 using has_insert_with_iterator = meta::boolean<meta_detail::has_insert_with_iterator_test<T>::value>;
2708 template <typename T>
2709 using has_insert_after = meta::boolean<meta_detail::has_insert_after_test<T>::value>;
2711 template <typename T>
2712 using has_size = meta::boolean<meta_detail::has_size_test<T>::value>;
2714 template <typename T>
2715 using is_associative = meta::all<has_key_type<T>, has_key_value_pair<T>, has_mapped_type<T>>;
2717 template <typename T>
2718 using is_lookup = meta::all<has_key_type<T>, has_value_type<T>>;
2720 template <typename T>
2721 using is_ordered = meta::all<has_key_comp<T>, meta::neg<has_load_factor<T>>>;
2723 template <typename T>
2724 using is_matched_lookup = meta_detail::is_matched_lookup_impl<T, is_lookup<T>::value>;
2726 template <typename T>
2727 using is_initializer_list = meta::is_specialization_of<T, std::initializer_list>;
2729 template <typename T>
2730 constexpr inline bool is_initializer_list_v = is_initializer_list<T>::value;
2732 template <typename T, typename CharT = char>
2733 using is_string_literal_array_of = boolean<std::is_array_v<T> && std::is_same_v<std::remove_all_extents_t<T>, CharT>>;
2735 template <typename T, typename CharT = char>
2736 constexpr inline bool is_string_literal_array_of_v = is_string_literal_array_of<T, CharT>::value;
2738 template <typename T>
2739 using is_string_literal_array = boolean<std::is_array_v<T> && any_same_v<std::remove_all_extents_t<T>, char,
2740 #if SOL_IS_ON(SOL_CHAR8_T)
2743 char16_t, char32_t, wchar_t>>;
2745 template <typename T>
2746 constexpr inline bool is_string_literal_array_v = is_string_literal_array<T>::value;
2748 template <typename T, typename CharT>
2749 struct is_string_of : std::false_type { };
2751 template <typename CharT, typename CharTargetT, typename TraitsT, typename AllocT>
2752 struct is_string_of<std::basic_string<CharT, TraitsT, AllocT>, CharTargetT> : std::is_same<CharT, CharTargetT> { };
2754 template <typename T, typename CharT>
2755 constexpr inline bool is_string_of_v = is_string_of<T, CharT>::value;
2757 template <typename T, typename CharT>
2758 struct is_string_view_of : std::false_type { };
2760 template <typename CharT, typename CharTargetT, typename TraitsT>
2761 struct is_string_view_of<std::basic_string_view<CharT, TraitsT>, CharTargetT> : std::is_same<CharT, CharTargetT> { };
2763 template <typename T, typename CharT>
2764 constexpr inline bool is_string_view_of_v = is_string_view_of<T, CharT>::value;
2766 template <typename T>
2767 using is_string_like
2768 = 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>>;
2770 template <typename T>
2771 constexpr inline bool is_string_like_v = is_string_like<T>::value;
2773 template <typename T, typename CharT = char>
2774 using is_string_constructible = meta::boolean<
2775 is_string_literal_array_of_v<T,
2776 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>>;
2778 template <typename T, typename CharT = char>
2779 constexpr inline bool is_string_constructible_v = is_string_constructible<T, CharT>::value;
2781 template <typename T>
2782 using is_string_like_or_constructible = meta::boolean<is_string_like_v<T> || is_string_constructible_v<T>>;
2784 template <typename T>
2785 struct is_pair : std::false_type { };
2787 template <typename T1, typename T2>
2788 struct is_pair<std::pair<T1, T2>> : std::true_type { };
2790 template <typename T, typename Char>
2791 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>>;
2793 template <typename T, typename Char>
2794 constexpr inline bool is_c_str_of_v = is_c_str_of<T, Char>::value;
2796 template <typename T>
2797 using is_c_str = is_c_str_of<T, char>;
2799 template <typename T>
2800 constexpr inline bool is_c_str_v = is_c_str<T>::value;
2802 template <typename T, typename Char>
2803 using is_c_str_or_string_of = any<is_c_str_of<T, Char>, is_string_of<T, Char>>;
2805 template <typename T, typename Char>
2806 constexpr inline bool is_c_str_or_string_of_v = is_c_str_or_string_of<T, Char>::value;
2808 template <typename T>
2809 using is_c_str_or_string = is_c_str_or_string_of<T, char>;
2811 template <typename T>
2812 constexpr inline bool is_c_str_or_string_v = is_c_str_or_string<T>::value;
2814 template <typename T>
2815 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>>> { };
2817 template <typename T>
2818 using is_not_move_only = neg<is_move_only<T>>;
2820 namespace meta_detail {
2821 template <typename T>
2822 decltype(auto) force_tuple(T&& x) {
2823 if constexpr (meta::is_specialization_of_v<meta::unqualified_t<T>, std::tuple>) {
2824 return std::forward<T>(x);
2827 return std::tuple<T>(std::forward<T>(x));
2832 template <typename... X>
2833 decltype(auto) tuplefy(X&&... x) {
2834 return std::tuple_cat(meta_detail::force_tuple(std::forward<X>(x))...);
2837 template <typename T, typename = void>
2838 struct iterator_tag {
2839 using type = std::input_iterator_tag;
2842 template <typename T>
2843 struct iterator_tag<T, conditional_t<false, typename std::iterator_traits<T>::iterator_category, void>> {
2844 using type = typename std::iterator_traits<T>::iterator_category;
2853 const bool default_safe_function_calls =
2854 #if SOL_IS_ON(SOL_SAFE_FUNCTION_CALLS)
2861 namespace meta { namespace meta_detail {
2864 namespace stack { namespace stack_detail {
2865 using undefined_method_func = void (*)(stack_reference);
2867 template <typename T>
2868 void set_undefined_methods_on(stack_reference);
2870 struct undefined_metatable;
2879 #if SOL_IS_ON(SOL2_CI)
2884 _set_abort_behavior(0, _WRITE_ABORT_MSG);
2887 } inline sol2_ci_dont_lock_ci_please = {};
2891 #if SOL_IS_ON(SOL_USER_C_ASSERT)
2892 #define sol_c_assert(...) SOL_C_ASSERT(__VA_ARGS__)
2894 #if SOL_IS_ON(SOL_DEBUG_BUILD)
2895 #include <exception>
2899 #define sol_c_assert(...) \
2901 if (!(__VA_ARGS__)) { \
2902 std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << std::endl; \
2907 #define sol_c_assert(...) \
2910 (void)(__VA_ARGS__); \
2916 #if SOL_IS_ON(SOL_USER_M_ASSERT)
2917 #define sol_m_assert(message, ...) SOL_M_ASSERT(message, __VA_ARGS__)
2919 #if SOL_IS_ON(SOL_DEBUG_BUILD)
2920 #include <exception>
2924 #define sol_m_assert(message, ...) \
2926 if (!(__VA_ARGS__)) { \
2927 std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << ": " << message << std::endl; \
2932 #define sol_m_assert(message, ...) \
2935 (void)(__VA_ARGS__); \
2936 (void)sizeof(message); \
2950 #if SOL_IS_ON(SOL_USE_CXX_LUA)
2953 #include <lauxlib.h>
2954 #elif SOL_IS_ON(SOL_USE_LUA_HPP)
2959 #include <lauxlib.h>
2964 #if defined(SOL_LUAJIT)
2965 #if (SOL_LUAJIT != 0)
2966 #define SOL_USE_LUAJIT_I_ SOL_ON
2968 #define SOL_USE_LUAJIT_I_ SOL_OFF
2970 #elif defined(LUAJIT_VERSION)
2971 #define SOL_USE_LUAJIT_I_ SOL_ON
2973 #define SOL_USE_LUAJIT_I_ SOL_DEFAULT_OFF
2976 #if SOL_IS_ON(SOL_USE_CXX_LUAJIT)
2978 #elif SOL_IS_ON(SOL_USE_LUAJIT)
2984 #if defined(SOL_LUAJIT_VERSION)
2985 #define SOL_LUAJIT_VERSION_I_ SOL_LUAJIT_VERSION
2986 #elif SOL_IS_ON(SOL_USE_LUAJIT)
2987 #define SOL_LUAJIT_VERSION_I_ LUAJIT_VERSION_NUM
2989 #define SOL_LUAJIT_VERSION_I_ 0
2992 #if defined(SOL_LUAJIT_FFI_DISABLED)
2993 #define SOL_LUAJIT_FFI_DISABLED_I_ SOL_ON
2994 #elif defined(LUAJIT_DISABLE_FFI)
2995 #define SOL_LUAJIT_FFI_DISABLED_I_ SOL_ON
2997 #define SOL_LUAJIT_FFI_DISABLED_I_ SOL_DEFAULT_OFF
3000 #if defined(MOONJIT_VERSION)
3001 #define SOL_USE_MOONJIT_I_ SOL_ON
3003 #define SOL_USE_MOONJIT_I_ SOL_OFF
3006 #if !defined(SOL_LUA_VERSION)
3007 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 502
3008 #define SOL_LUA_VERSION LUA_VERSION_NUM
3009 #elif defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
3010 #define SOL_LUA_VERSION LUA_VERSION_NUM
3011 #elif !defined(LUA_VERSION_NUM) || !(LUA_VERSION_NUM)
3013 #define SOL_LUA_VERSION 500
3016 #define SOL_LUA_VERSION 504
3020 #if defined(SOL_LUA_VERSION)
3021 #define SOL_LUA_VERSION_I_ SOL_LUA_VERSION
3023 #define SOL_LUA_VERSION_I_ 504
3026 #if defined(SOL_EXCEPTIONS_ALWAYS_UNSAFE)
3027 #if (SOL_EXCEPTIONS_ALWAYS_UNSAFE != 0)
3028 #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF
3030 #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_ON
3032 #elif defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
3033 #if (SOL_EXCEPTIONS_SAFE_PROPAGATION != 0)
3034 #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_ON
3036 #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF
3038 #elif SOL_LUAJIT_VERSION_I_ >= 20100
3040 #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
3041 #elif SOL_LUAJIT_VERSION_I_ >= 20000
3043 #if SOL_IS_ON(SOL_PLATFORM_X64)
3044 #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
3046 #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF
3052 #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_OFF
3055 #if defined(SOL_EXCEPTIONS_CATCH_ALL)
3056 #if (SOL_EXCEPTIONS_CATCH_ALL != 0)
3057 #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_ON
3059 #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_OFF
3062 #if SOL_IS_ON(SOL_USE_LUAJIT)
3063 #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
3064 #elif SOL_IS_ON(SOL_USE_CXX_LUAJIT)
3065 #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
3066 #elif SOL_IS_ON(SOL_USE_CXX_LUA)
3067 #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
3069 #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_ON
3073 #if defined(SOL_LUAJIT_USE_EXCEPTION_TRAMPOLINE)
3074 #if (SOL_LUAJIT_USE_EXCEPTION_TRAMPOLINE != 0)
3075 #define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_ON
3077 #define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_OFF
3080 #if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS) && SOL_IS_ON(SOL_USE_LUAJIT)
3081 #define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_ON
3083 #define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_DEFAULT_OFF
3087 #if defined(SOL_LUAL_STREAM_HAS_CLOSE_FUNCTION)
3088 #if (SOL_LUAL_STREAM_HAS_CLOSE_FUNCTION != 0)
3089 #define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_ON
3091 #define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_OFF
3094 #if SOL_IS_OFF(SOL_USE_LUAJIT) && (SOL_LUA_VERSION > 501)
3095 #define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_ON
3097 #define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_DEFAULT_OFF
3101 #if defined (SOL_LUA_BIT32_LIB)
3102 #if SOL_LUA_BIT32_LIB != 0
3103 #define SOL_LUA_BIT32_LIB_I_ SOL_ON
3105 #define SOL_LUA_BIT32_LIB_I_ SOL_OFF
3110 #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)))
3111 #define SOL_LUA_BIT32_LIB_I_ SOL_ON
3113 #define SOL_LUA_BIT32_LIB_I_ SOL_DEFAULT_OFF
3117 #if defined (SOL_LUA_NIL_IN_TABLES)
3118 #if SOL_LUA_NIL_IN_TABLES != 0
3119 #define SOL_LUA_NIL_IN_TABLES_I_ SOL_ON
3121 #define SOL_LUA_NIL_IN_TABLES_I_ SOL_OFF
3124 #if defined(LUA_NILINTABLE) && (LUA_NILINTABLE != 0)
3125 #define SOL_LUA_NIL_IN_TABLES_I_ SOL_DEFAULT_ON
3127 #define SOL_LUA_NIL_IN_TABLES_I_ SOL_DEFAULT_OFF
3133 #if SOL_IS_ON(SOL_USE_COMPATIBILITY_LAYER)
3135 #if SOL_IS_ON(SOL_USE_CXX_LUA) || SOL_IS_ON(SOL_USE_CXX_LUAJIT)
3136 #ifndef COMPAT53_LUA_CPP
3137 #define COMPAT53_LUA_CPP 1
3140 #ifndef COMPAT53_INCLUDE_SOURCE
3141 #define COMPAT53_INCLUDE_SOURCE 1
3146 #ifndef KEPLER_PROJECT_COMPAT53_H_
3147 #define KEPLER_PROJECT_COMPAT53_H_
3152 #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
3156 #include <lauxlib.h>
3158 #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
3162 #ifndef COMPAT53_PREFIX
3167 # define COMPAT53_PREFIX kp_compat53
3170 #ifndef COMPAT53_API
3171 # if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE
3172 # if defined(__GNUC__) || defined(__clang__)
3173 # define COMPAT53_API __attribute__((__unused__)) static inline
3175 # define COMPAT53_API static inline
3179 # define COMPAT53_API extern
3183 #define COMPAT53_CONCAT_HELPER(a, b) a##b
3184 #define COMPAT53_CONCAT(a, b) COMPAT53_CONCAT_HELPER(a, b)
3187 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
3201 # define LUA_OPADD 0
3204 # define LUA_OPSUB 1
3207 # define LUA_OPMUL 2
3210 # define LUA_OPDIV 3
3213 # define LUA_OPMOD 4
3216 # define LUA_OPPOW 5
3219 # define LUA_OPUNM 6
3235 #if !defined(LUA_ERRGCMM)
3241 # define LUA_ERRGCMM (LUA_ERRERR + 2)
3244 #if !defined(MOONJIT_VERSION)
3245 typedef size_t lua_Unsigned;
3248 typedef struct luaL_Buffer_53 {
3255 #define luaL_Buffer luaL_Buffer_53
3261 typedef struct luaL_Stream {
3265 #define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex)
3266 COMPAT53_API int lua_absindex(lua_State *L, int i);
3268 #define lua_arith COMPAT53_CONCAT(COMPAT53_PREFIX, _arith)
3269 COMPAT53_API void lua_arith(lua_State *L, int op);
3271 #define lua_compare COMPAT53_CONCAT(COMPAT53_PREFIX, _compare)
3272 COMPAT53_API int lua_compare(lua_State *L, int idx1, int idx2, int op);
3274 #define lua_copy COMPAT53_CONCAT(COMPAT53_PREFIX, _copy)
3275 COMPAT53_API void lua_copy(lua_State *L, int from, int to);
3277 #define lua_getuservalue(L, i) \
3278 (lua_getfenv((L), (i)), lua_type((L), -1))
3279 #define lua_setuservalue(L, i) \
3280 (luaL_checktype((L), -1, LUA_TTABLE), lua_setfenv((L), (i)))
3282 #define lua_len COMPAT53_CONCAT(COMPAT53_PREFIX, _len)
3283 COMPAT53_API void lua_len(lua_State *L, int i);
3285 #define lua_pushstring(L, s) \
3286 (lua_pushstring((L), (s)), lua_tostring((L), -1))
3288 #define lua_pushlstring(L, s, len) \
3289 ((((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len))), lua_tostring((L), -1))
3291 #ifndef luaL_newlibtable
3292 # define luaL_newlibtable(L, l) \
3293 (lua_createtable((L), 0, sizeof((l))/sizeof(*(l))-1))
3296 # define luaL_newlib(L, l) \
3297 (luaL_newlibtable((L), (l)), luaL_register((L), NULL, (l)))
3300 #ifndef lua_pushglobaltable
3301 # define lua_pushglobaltable(L) \
3302 lua_pushvalue((L), LUA_GLOBALSINDEX)
3304 #define lua_rawgetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawgetp)
3305 COMPAT53_API int lua_rawgetp(lua_State *L, int i, const void *p);
3307 #define lua_rawsetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawsetp)
3308 COMPAT53_API void lua_rawsetp(lua_State *L, int i, const void *p);
3310 #define lua_rawlen(L, i) lua_objlen((L), (i))
3312 #define lua_tointeger(L, i) lua_tointegerx((L), (i), NULL)
3314 #define lua_tonumberx COMPAT53_CONCAT(COMPAT53_PREFIX, _tonumberx)
3315 COMPAT53_API lua_Number lua_tonumberx(lua_State *L, int i, int *isnum);
3317 #define luaL_checkversion COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkversion)
3318 COMPAT53_API void luaL_checkversion(lua_State *L);
3320 #define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
3321 COMPAT53_API int lua_load(lua_State *L, lua_Reader reader, void *data, const char* source, const char* mode);
3323 #define luaL_loadfilex COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadfilex)
3324 COMPAT53_API int luaL_loadfilex(lua_State *L, const char *filename, const char *mode);
3326 #define luaL_loadbufferx COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadbufferx)
3327 COMPAT53_API int luaL_loadbufferx(lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
3329 #define luaL_checkstack COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkstack_53)
3330 COMPAT53_API void luaL_checkstack(lua_State *L, int sp, const char *msg);
3332 #define luaL_getsubtable COMPAT53_CONCAT(COMPAT53_PREFIX, L_getsubtable)
3333 COMPAT53_API int luaL_getsubtable(lua_State* L, int i, const char *name);
3335 #define luaL_len COMPAT53_CONCAT(COMPAT53_PREFIX, L_len)
3336 COMPAT53_API lua_Integer luaL_len(lua_State *L, int i);
3338 #define luaL_setfuncs COMPAT53_CONCAT(COMPAT53_PREFIX, L_setfuncs)
3339 COMPAT53_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup);
3341 #define luaL_setmetatable COMPAT53_CONCAT(COMPAT53_PREFIX, L_setmetatable)
3342 COMPAT53_API void luaL_setmetatable(lua_State *L, const char *tname);
3344 #define luaL_testudata COMPAT53_CONCAT(COMPAT53_PREFIX, L_testudata)
3345 COMPAT53_API void *luaL_testudata(lua_State *L, int i, const char *tname);
3347 #define luaL_traceback COMPAT53_CONCAT(COMPAT53_PREFIX, L_traceback)
3348 COMPAT53_API void luaL_traceback(lua_State *L, lua_State *L1, const char *msg, int level);
3350 #define luaL_fileresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_fileresult)
3351 COMPAT53_API int luaL_fileresult(lua_State *L, int stat, const char *fname);
3353 #define luaL_execresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_execresult)
3354 COMPAT53_API int luaL_execresult(lua_State *L, int stat);
3356 #define lua_callk(L, na, nr, ctx, cont) \
3357 ((void)(ctx), (void)(cont), lua_call((L), (na), (nr)))
3358 #define lua_pcallk(L, na, nr, err, ctx, cont) \
3359 ((void)(ctx), (void)(cont), lua_pcall((L), (na), (nr), (err)))
3361 #define lua_resume(L, from, nargs) \
3362 ((void)(from), lua_resume((L), (nargs)))
3364 #define luaL_buffinit COMPAT53_CONCAT(COMPAT53_PREFIX, _buffinit_53)
3365 COMPAT53_API void luaL_buffinit(lua_State *L, luaL_Buffer_53 *B);
3367 #define luaL_prepbuffsize COMPAT53_CONCAT(COMPAT53_PREFIX, _prepbufsize_53)
3368 COMPAT53_API char *luaL_prepbuffsize(luaL_Buffer_53 *B, size_t s);
3370 #define luaL_addlstring COMPAT53_CONCAT(COMPAT53_PREFIX, _addlstring_53)
3371 COMPAT53_API void luaL_addlstring(luaL_Buffer_53 *B, const char *s, size_t l);
3373 #define luaL_addvalue COMPAT53_CONCAT(COMPAT53_PREFIX, _addvalue_53)
3374 COMPAT53_API void luaL_addvalue(luaL_Buffer_53 *B);
3376 #define luaL_pushresult COMPAT53_CONCAT(COMPAT53_PREFIX, _pushresult_53)
3377 COMPAT53_API void luaL_pushresult(luaL_Buffer_53 *B);
3379 #undef luaL_buffinitsize
3380 #define luaL_buffinitsize(L, B, s) \
3381 (luaL_buffinit((L), (B)), luaL_prepbuffsize((B), (s)))
3383 #undef luaL_prepbuffer
3384 #define luaL_prepbuffer(B) \
3385 luaL_prepbuffsize((B), LUAL_BUFFERSIZE)
3388 #define luaL_addchar(B, c) \
3389 ((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize((B), 1)), \
3390 ((B)->ptr[(B)->nelems++] = (c)))
3393 #define luaL_addsize(B, s) \
3394 ((B)->nelems += (s))
3396 #undef luaL_addstring
3397 #define luaL_addstring(B, s) \
3398 luaL_addlstring((B), (s), strlen((s)))
3400 #undef luaL_pushresultsize
3401 #define luaL_pushresultsize(B, s) \
3402 (luaL_addsize((B), (s)), luaL_pushresult((B)))
3404 #if defined(LUA_COMPAT_APIINTCASTS)
3405 #define lua_pushunsigned(L, n) \
3406 lua_pushinteger((L), (lua_Integer)(n))
3407 #define lua_tounsignedx(L, i, is) \
3408 ((lua_Unsigned)lua_tointegerx((L), (i), (is)))
3409 #define lua_tounsigned(L, i) \
3410 lua_tounsignedx((L), (i), NULL)
3411 #define luaL_checkunsigned(L, a) \
3412 ((lua_Unsigned)luaL_checkinteger((L), (a)))
3413 #define luaL_optunsigned(L, a, d) \
3414 ((lua_Unsigned)luaL_optinteger((L), (a), (lua_Integer)(d)))
3420 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 502
3422 typedef int lua_KContext;
3424 typedef int(*lua_KFunction)(lua_State *L, int status, lua_KContext ctx);
3426 #define lua_dump(L, w, d, s) \
3427 ((void)(s), lua_dump((L), (w), (d)))
3429 #define lua_getfield(L, i, k) \
3430 (lua_getfield((L), (i), (k)), lua_type((L), -1))
3432 #define lua_gettable(L, i) \
3433 (lua_gettable((L), (i)), lua_type((L), -1))
3435 #define lua_geti COMPAT53_CONCAT(COMPAT53_PREFIX, _geti)
3436 COMPAT53_API int lua_geti(lua_State *L, int index, lua_Integer i);
3438 #define lua_isinteger COMPAT53_CONCAT(COMPAT53_PREFIX, _isinteger)
3439 COMPAT53_API int lua_isinteger(lua_State *L, int index);
3441 #define lua_tointegerx COMPAT53_CONCAT(COMPAT53_PREFIX, _tointegerx_53)
3442 COMPAT53_API lua_Integer lua_tointegerx(lua_State *L, int i, int *isnum);
3444 #define lua_numbertointeger(n, p) \
3445 ((*(p) = (lua_Integer)(n)), 1)
3447 #define lua_rawget(L, i) \
3448 (lua_rawget((L), (i)), lua_type((L), -1))
3450 #define lua_rawgeti(L, i, n) \
3451 (lua_rawgeti((L), (i), (n)), lua_type((L), -1))
3453 #define lua_rotate COMPAT53_CONCAT(COMPAT53_PREFIX, _rotate)
3454 COMPAT53_API void lua_rotate(lua_State *L, int idx, int n);
3456 #define lua_seti COMPAT53_CONCAT(COMPAT53_PREFIX, _seti)
3457 COMPAT53_API void lua_seti(lua_State *L, int index, lua_Integer i);
3459 #define lua_stringtonumber COMPAT53_CONCAT(COMPAT53_PREFIX, _stringtonumber)
3460 COMPAT53_API size_t lua_stringtonumber(lua_State *L, const char *s);
3462 #define luaL_tolstring COMPAT53_CONCAT(COMPAT53_PREFIX, L_tolstring)
3463 COMPAT53_API const char *luaL_tolstring(lua_State *L, int idx, size_t *len);
3465 #define luaL_getmetafield(L, o, e) \
3466 (luaL_getmetafield((L), (o), (e)) ? lua_type((L), -1) : LUA_TNIL)
3468 #define luaL_newmetatable(L, tn) \
3469 (luaL_newmetatable((L), (tn)) ? (lua_pushstring((L), (tn)), lua_setfield((L), -2, "__name"), 1) : 0)
3471 #define luaL_requiref COMPAT53_CONCAT(COMPAT53_PREFIX, L_requiref_53)
3472 COMPAT53_API void luaL_requiref(lua_State *L, const char *modname,
3473 lua_CFunction openf, int glb);
3478 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 502
3487 #define lua_getglobal(L, n) \
3488 (lua_getglobal((L), (n)), lua_type((L), -1))
3490 #define lua_getuservalue(L, i) \
3491 (lua_getuservalue((L), (i)), lua_type((L), -1))
3493 #define lua_pushlstring(L, s, len) \
3494 (((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len)))
3496 #define lua_rawgetp(L, i, p) \
3497 (lua_rawgetp((L), (i), (p)), lua_type((L), -1))
3499 #define LUA_KFUNCTION(_name) \
3500 static int (_name)(lua_State *L, int status, lua_KContext ctx); \
3501 static int (_name ## _52)(lua_State *L) { \
3503 int status = lua_getctx(L, &ctx); \
3504 return (_name)(L, status, ctx); \
3506 static int (_name)(lua_State *L, int status, lua_KContext ctx)
3508 #define lua_pcallk(L, na, nr, err, ctx, cont) \
3509 lua_pcallk((L), (na), (nr), (err), (ctx), cont ## _52)
3511 #define lua_callk(L, na, nr, ctx, cont) \
3512 lua_callk((L), (na), (nr), (ctx), cont ## _52)
3514 #define lua_yieldk(L, nr, ctx, cont) \
3515 lua_yieldk((L), (nr), (ctx), cont ## _52)
3519 # define lua_call(L, na, nr) \
3520 (lua_callk)((L), (na), (nr), 0, NULL)
3525 # define lua_pcall(L, na, nr, err) \
3526 (lua_pcallk)((L), (na), (nr), (err), 0, NULL)
3531 # define lua_yield(L, nr) \
3532 (lua_yieldk)((L), (nr), 0, NULL)
3538 #if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 || LUA_VERSION_NUM > 504
3540 # error "unsupported Lua version (i.e. not Lua 5.1, 5.2, 5.3, or 5.4)"
3546 #ifndef LUA_KFUNCTION
3547 #define LUA_KFUNCTION(_name) \
3548 static int (_name)(lua_State *L, int status, lua_KContext ctx)
3551 #if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE == 1
3562 #ifndef KEPLER_PROJECT_COMPAT53_C_
3563 #define KEPLER_PROJECT_COMPAT53_C_
3566 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
3568 #ifndef COMPAT53_FOPEN_NO_LOCK
3569 #if defined(_MSC_VER)
3570 #define COMPAT53_FOPEN_NO_LOCK 1
3572 #define COMPAT53_FOPEN_NO_LOCK 0
3576 #if defined(_MSC_VER) && COMPAT53_FOPEN_NO_LOCK
3580 #ifndef COMPAT53_HAVE_STRERROR_R
3581 #if defined(__GLIBC__) || defined(_POSIX_VERSION) || defined(__APPLE__) || (!defined(__MINGW32__) && defined(__GNUC__) && (__GNUC__ < 6))
3582 #define COMPAT53_HAVE_STRERROR_R 1
3584 #define COMPAT53_HAVE_STRERROR_R 0
3588 #ifndef COMPAT53_HAVE_STRERROR_S
3589 #if defined(_MSC_VER) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || (defined(__STDC_LIB_EXT1__) && __STDC_LIB_EXT1__)
3590 #define COMPAT53_HAVE_STRERROR_S 1
3592 #define COMPAT53_HAVE_STRERROR_S 0
3596 #ifndef COMPAT53_LUA_FILE_BUFFER_SIZE
3597 #define COMPAT53_LUA_FILE_BUFFER_SIZE 4096
3600 static char* compat53_strerror(int en, char* buff, size_t sz) {
3601 #if COMPAT53_HAVE_STRERROR_R
3606 if (strerror_r(en, buff, sz)) {
3610 if (buff[0] == '\0') {
3614 return strerror(en);
3618 #elif COMPAT53_HAVE_STRERROR_S
3621 strerror_s(buff, sz, en);
3630 return strerror(en);
3634 COMPAT53_API int lua_absindex(lua_State* L, int i) {
3635 if (i < 0 && i > LUA_REGISTRYINDEX)
3636 i += lua_gettop(L) + 1;
3640 static void compat53_call_lua(lua_State* L, char const code[], size_t len, int nargs, int nret) {
3641 lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)code);
3642 if (lua_type(L, -1) != LUA_TFUNCTION) {
3644 if (luaL_loadbuffer(L, code, len, "=none"))
3646 lua_pushvalue(L, -1);
3647 lua_rawsetp(L, LUA_REGISTRYINDEX, (void*)code);
3649 lua_insert(L, -nargs - 1);
3650 lua_call(L, nargs, nret);
3653 COMPAT53_API void lua_arith(lua_State* L, int op) {
3654 static const char compat53_arith_code[]
3655 = "local op,a,b=...\n"
3656 "if op==0 then return a+b\n"
3657 "elseif op==1 then return a-b\n"
3658 "elseif op==2 then return a*b\n"
3659 "elseif op==3 then return a/b\n"
3660 "elseif op==4 then return a%b\n"
3661 "elseif op==5 then return a^b\n"
3662 "elseif op==6 then return -a\n"
3665 if (op < LUA_OPADD || op > LUA_OPUNM)
3666 luaL_error(L, "invalid 'op' argument for lua_arith");
3667 luaL_checkstack(L, 5, "not enough stack slots");
3668 if (op == LUA_OPUNM)
3669 lua_pushvalue(L, -1);
3670 lua_pushnumber(L, op);
3672 compat53_call_lua(L, compat53_arith_code, sizeof(compat53_arith_code) - 1, 3, 1);
3675 COMPAT53_API int lua_compare(lua_State* L, int idx1, int idx2, int op) {
3676 static const char compat53_compare_code[]
3683 return lua_equal(L, idx1, idx2);
3685 return lua_lessthan(L, idx1, idx2);
3687 luaL_checkstack(L, 5, "not enough stack slots");
3688 idx1 = lua_absindex(L, idx1);
3689 idx2 = lua_absindex(L, idx2);
3690 lua_pushvalue(L, idx1);
3691 lua_pushvalue(L, idx2);
3692 compat53_call_lua(L, compat53_compare_code, sizeof(compat53_compare_code) - 1, 2, 1);
3693 result = lua_toboolean(L, -1);
3697 luaL_error(L, "invalid 'op' argument for lua_compare");
3702 COMPAT53_API void lua_copy(lua_State* L, int from, int to) {
3703 int abs_to = lua_absindex(L, to);
3704 luaL_checkstack(L, 1, "not enough stack slots");
3705 lua_pushvalue(L, from);
3706 lua_replace(L, abs_to);
3709 COMPAT53_API void lua_len(lua_State* L, int i) {
3710 switch (lua_type(L, i)) {
3712 lua_pushnumber(L, (lua_Number)lua_objlen(L, i));
3715 if (!luaL_callmeta(L, i, "__len"))
3716 lua_pushnumber(L, (lua_Number)lua_objlen(L, i));
3719 if (luaL_callmeta(L, i, "__len"))
3723 luaL_error(L, "attempt to get length of a %s value", lua_typename(L, lua_type(L, i)));
3727 COMPAT53_API int lua_rawgetp(lua_State* L, int i, const void* p) {
3728 int abs_i = lua_absindex(L, i);
3729 lua_pushlightuserdata(L, (void*)p);
3730 lua_rawget(L, abs_i);
3731 return lua_type(L, -1);
3734 COMPAT53_API void lua_rawsetp(lua_State* L, int i, const void* p) {
3735 int abs_i = lua_absindex(L, i);
3736 luaL_checkstack(L, 1, "not enough stack slots");
3737 lua_pushlightuserdata(L, (void*)p);
3739 lua_rawset(L, abs_i);
3742 COMPAT53_API lua_Number lua_tonumberx(lua_State* L, int i, int* isnum) {
3743 lua_Number n = lua_tonumber(L, i);
3744 if (isnum != NULL) {
3745 *isnum = (n != 0 || lua_isnumber(L, i));
3750 COMPAT53_API void luaL_checkversion(lua_State* L) {
3754 COMPAT53_API void luaL_checkstack(lua_State* L, int sp, const char* msg) {
3755 if (!lua_checkstack(L, sp + LUA_MINSTACK)) {
3757 luaL_error(L, "stack overflow (%s)", msg);
3759 lua_pushliteral(L, "stack overflow");
3765 COMPAT53_API int luaL_getsubtable(lua_State* L, int i, const char* name) {
3766 int abs_i = lua_absindex(L, i);
3767 luaL_checkstack(L, 3, "not enough stack slots");
3768 lua_pushstring(L, name);
3769 lua_gettable(L, abs_i);
3770 if (lua_istable(L, -1))
3774 lua_pushstring(L, name);
3775 lua_pushvalue(L, -2);
3776 lua_settable(L, abs_i);
3780 COMPAT53_API lua_Integer luaL_len(lua_State* L, int i) {
3781 lua_Integer res = 0;
3783 luaL_checkstack(L, 1, "not enough stack slots");
3785 res = lua_tointegerx(L, -1, &isnum);
3788 luaL_error(L, "object length is not an integer");
3792 COMPAT53_API void luaL_setfuncs(lua_State* L, const luaL_Reg* l, int nup) {
3793 luaL_checkstack(L, nup + 1, "too many upvalues");
3794 for (; l->name != NULL; l++) {
3796 lua_pushstring(L, l->name);
3797 for (i = 0; i < nup; i++)
3798 lua_pushvalue(L, -(nup + 1));
3799 lua_pushcclosure(L, l->func, nup);
3800 lua_settable(L, -(nup + 3));
3805 COMPAT53_API void luaL_setmetatable(lua_State* L, const char* tname) {
3806 luaL_checkstack(L, 1, "not enough stack slots");
3807 luaL_getmetatable(L, tname);
3808 lua_setmetatable(L, -2);
3811 COMPAT53_API void* luaL_testudata(lua_State* L, int i, const char* tname) {
3812 void* p = lua_touserdata(L, i);
3813 luaL_checkstack(L, 2, "not enough stack slots");
3814 if (p == NULL || !lua_getmetatable(L, i))
3818 luaL_getmetatable(L, tname);
3819 res = lua_rawequal(L, -1, -2);
3827 static int compat53_countlevels(lua_State* L) {
3831 while (lua_getstack(L, le, &ar)) {
3837 int m = (li + le) / 2;
3838 if (lua_getstack(L, m, &ar))
3846 static int compat53_findfield(lua_State* L, int objidx, int level) {
3847 if (level == 0 || !lua_istable(L, -1))
3850 while (lua_next(L, -2)) {
3851 if (lua_type(L, -2) == LUA_TSTRING) {
3852 if (lua_rawequal(L, objidx, -1)) {
3856 else if (compat53_findfield(L, objidx, level - 1)) {
3858 lua_pushliteral(L, ".");
3869 static int compat53_pushglobalfuncname(lua_State* L, lua_Debug* ar) {
3870 int top = lua_gettop(L);
3871 lua_getinfo(L, "f", ar);
3872 lua_pushvalue(L, LUA_GLOBALSINDEX);
3873 if (compat53_findfield(L, top + 1, 2)) {
3874 lua_copy(L, -1, top + 1);
3884 static void compat53_pushfuncname(lua_State* L, lua_Debug* ar) {
3885 if (*ar->namewhat != '\0')
3886 lua_pushfstring(L, "function " LUA_QS, ar->name);
3887 else if (*ar->what == 'm')
3888 lua_pushliteral(L, "main chunk");
3889 else if (*ar->what == 'C') {
3890 if (compat53_pushglobalfuncname(L, ar)) {
3891 lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
3895 lua_pushliteral(L, "?");
3898 lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
3901 #define COMPAT53_LEVELS1 12
3902 #define COMPAT53_LEVELS2 10
3904 COMPAT53_API void luaL_traceback(lua_State* L, lua_State* L1, const char* msg, int level) {
3906 int top = lua_gettop(L);
3907 int numlevels = compat53_countlevels(L1);
3908 int mark = (numlevels > COMPAT53_LEVELS1 + COMPAT53_LEVELS2) ? COMPAT53_LEVELS1 : 0;
3910 lua_pushfstring(L, "%s\n", msg);
3911 lua_pushliteral(L, "stack traceback:");
3912 while (lua_getstack(L1, level++, &ar)) {
3913 if (level == mark) {
3914 lua_pushliteral(L, "\n\t...");
3915 level = numlevels - COMPAT53_LEVELS2;
3918 lua_getinfo(L1, "Slnt", &ar);
3919 lua_pushfstring(L, "\n\t%s:", ar.short_src);
3920 if (ar.currentline > 0)
3921 lua_pushfstring(L, "%d:", ar.currentline);
3922 lua_pushliteral(L, " in ");
3923 compat53_pushfuncname(L, &ar);
3924 lua_concat(L, lua_gettop(L) - top);
3927 lua_concat(L, lua_gettop(L) - top);
3930 COMPAT53_API int luaL_fileresult(lua_State* L, int stat, const char* fname) {
3931 const char* serr = NULL;
3933 char buf[512] = { 0 };
3935 lua_pushboolean(L, 1);
3940 serr = compat53_strerror(en, buf, sizeof(buf));
3942 lua_pushfstring(L, "%s: %s", fname, serr);
3944 lua_pushstring(L, serr);
3945 lua_pushnumber(L, (lua_Number)en);
3950 static int compat53_checkmode(lua_State* L, const char* mode, const char* modename, int err) {
3951 if (mode && strchr(mode, modename[0]) == NULL) {
3952 lua_pushfstring(L, "attempt to load a %s chunk (mode is '%s')", modename, mode);
3961 int has_peeked_data;
3962 const char* peeked_data;
3963 size_t peeked_data_size;
3964 } compat53_reader_data;
3966 static const char* compat53_reader(lua_State* L, void* ud, size_t* size) {
3967 compat53_reader_data* data = (compat53_reader_data*)ud;
3968 if (data->has_peeked_data) {
3969 data->has_peeked_data = 0;
3970 *size = data->peeked_data_size;
3971 return data->peeked_data;
3974 return data->reader(L, data->ud, size);
3977 COMPAT53_API int lua_load(lua_State* L, lua_Reader reader, void* data, const char* source, const char* mode) {
3978 int status = LUA_OK;
3979 compat53_reader_data compat53_data = { reader, data, 1, 0, 0 };
3980 compat53_data.peeked_data = reader(L, data, &(compat53_data.peeked_data_size));
3981 if (compat53_data.peeked_data && compat53_data.peeked_data_size && compat53_data.peeked_data[0] == LUA_SIGNATURE[0])
3982 status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX);
3984 status = compat53_checkmode(L, mode, "text", LUA_ERRSYNTAX);
3985 if (status != LUA_OK)
3989 return lua_load(L, compat53_reader, &compat53_data, source);
3990 #define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
3996 char buff[COMPAT53_LUA_FILE_BUFFER_SIZE];
3999 static const char* compat53_getF(lua_State* L, void* ud, size_t* size) {
4000 compat53_LoadF* lf = (compat53_LoadF*)ud;
4012 *size = fread(lf->buff, 1, sizeof(lf->buff), lf->
f);
4017 static
int compat53_errfile(lua_State* L, const char* what, int fnameindex) {
4018 char buf[512] = { 0 };
4019 const char* serr = compat53_strerror(errno, buf,
sizeof(buf));
4020 const char* filename =
lua_tostring(L, fnameindex) + 1;
4026 static int compat53_skipBOM(compat53_LoadF* lf) {
4027 const char* p =
"\xEF\xBB\xBF";
4032 if (c == EOF || c != *(
const unsigned char*)p++)
4034 lf->buff[lf->n++] = (char)c;
4035 }
while (*p !=
'\0');
4047 static int compat53_skipcomment(compat53_LoadF* lf,
int* cp) {
4048 int c = *cp = compat53_skipBOM(lf);
4052 }
while (c != EOF && c !=
'\n');
4062 int status, readstatus;
4065 if (filename == NULL) {
4071 #if defined(_MSC_VER)
4082 #if COMPAT53_FOPEN_NO_LOCK
4083 lf.f = _fsopen(filename,
"r", _SH_DENYNO);
4085 return compat53_errfile(L,
"open", fnameindex);
4087 if (fopen_s(&lf.f, filename,
"r") != 0)
4088 return compat53_errfile(L,
"open", fnameindex);
4091 lf.f = fopen(filename,
"r");
4093 return compat53_errfile(L,
"open", fnameindex);
4096 if (compat53_skipcomment(&lf, &c))
4097 lf.buff[lf.n++] =
'\n';
4099 #if defined(_MSC_VER)
4100 if (freopen_s(&lf.f, filename,
"rb", lf.f) != 0)
4101 return compat53_errfile(L,
"reopen", fnameindex);
4103 lf.f = freopen(filename,
"rb", lf.f);
4105 return compat53_errfile(L,
"reopen", fnameindex);
4107 compat53_skipcomment(&lf, &c);
4110 lf.buff[lf.n++] = (char)c;
4112 readstatus = ferror(lf.f);
4117 return compat53_errfile(L,
"read", fnameindex);
4126 status = compat53_checkmode(L, mode,
"binary",
LUA_ERRSYNTAX);
4129 status = compat53_checkmode(L, mode,
"text",
LUA_ERRSYNTAX);
4136 #if !defined(l_inspectstat) \
4137 && (defined(unix) || defined(__unix) || defined(__unix__) || defined(__TOS_AIX__) || defined(_SYSTYPE_BSD) || (defined(__APPLE__) && defined(__MACH__)))
4142 #if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
4143 #include <sys/wait.h>
4144 #define l_inspectstat(stat, what) \
4145 if (WIFEXITED(stat)) { \
4146 stat = WEXITSTATUS(stat); \
4148 else if (WIFSIGNALED(stat)) { \
4149 stat = WTERMSIG(stat); \
4156 #if !defined(l_inspectstat)
4157 #define l_inspectstat(stat, what) ((void)0)
4161 const char* what =
"exit";
4166 if (*what ==
'e' && stat == 0)
4182 B->ptr =
B->b.buffer;
4189 if (
B->capacity -
B->nelems < s) {
4190 char* newptr = NULL;
4191 size_t newcap =
B->capacity * 2;
4192 if (newcap -
B->nelems < s)
4193 newcap =
B->nelems +
s;
4194 if (newcap < B->capacity)
4196 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 504
4201 memcpy(newptr,
B->ptr,
B->nelems);
4202 if (
B->ptr !=
B->b.buffer)
4205 B->capacity = newcap;
4207 return B->ptr +
B->nelems;
4219 luaL_error(
B->L2,
"cannot convert value to string");
4220 if (
B->ptr !=
B->b.buffer)
4228 if (
B->ptr !=
B->b.buffer)
4235 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 502
4269 static void compat53_reverse(
lua_State* L,
int a,
int b) {
4270 for (; a < b; ++a, --b) {
4284 if (n > 0 && n < n_elems) {
4287 compat53_reverse(L, idx, idx + n - 1);
4288 compat53_reverse(L, idx + n, idx + n_elems - 1);
4289 compat53_reverse(L, idx, idx + n_elems - 1);
4301 #if !defined(lua_str2number)
4302 #define lua_str2number(s, p) strtod((s), (p))
4309 while (*endptr !=
'\0' && isspace((
unsigned char)*endptr))
4311 if (*endptr ==
'\0') {
4313 return endptr -
s + 1;
4322 char const*
name = NULL;
4348 luaL_error(L,
"'__tostring' must return a string");
4409 #ifndef NOT_KEPLER_PROJECT_COMPAT54_H_
4410 #define NOT_KEPLER_PROJECT_COMPAT54_H_
4412 #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
4418 #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
4422 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 504
4424 #if !defined(LUA_ERRGCMM)
4428 # define LUA_ERRGCMM (LUA_ERRERR + 2)
4431 #endif // Lua 5.4 only
4433 #endif // NOT_KEPLER_PROJECT_COMPAT54_H_// end of sol/compatibility/compat-5.4.h
4445 template <
typename Allocator = std::allocator<std::
byte>>
4446 class basic_bytecode :
private std::vector<std::byte, Allocator> {
4448 using base_t = std::vector<std::byte, Allocator>;
4451 using typename base_t::allocator_type;
4452 using typename base_t::const_iterator;
4453 using typename base_t::const_pointer;
4454 using typename base_t::const_reference;
4455 using typename base_t::const_reverse_iterator;
4456 using typename base_t::difference_type;
4457 using typename base_t::iterator;
4458 using typename base_t::pointer;
4460 using typename base_t::reverse_iterator;
4461 using typename base_t::size_type;
4462 using typename base_t::value_type;
4464 using base_t::base_t;
4465 using base_t::operator=;
4468 using base_t::empty;
4469 using base_t::max_size;
4473 using base_t::operator[];
4475 using base_t::front;
4477 using base_t::begin;
4478 using base_t::cbegin;
4482 using base_t::crbegin;
4483 using base_t::crend;
4484 using base_t::rbegin;
4487 using base_t::get_allocator;
4491 using base_t::emplace;
4492 using base_t::emplace_back;
4493 using base_t::erase;
4494 using base_t::insert;
4495 using base_t::pop_back;
4496 using base_t::push_back;
4498 using base_t::resize;
4499 using base_t::shrink_to_fit;
4506 template <
typename Container>
4508 using storage_t = Container;
4509 const std::byte* p_code =
static_cast<const std::byte*
>(
memory);
4510 storage_t& bc = *
static_cast<storage_t*
>(userdata_pointer);
4511 #if SOL_IS_OFF(SOL_EXCEPTIONS)
4512 bc.insert(bc.cend(), p_code, p_code + memory_size);
4515 bc.insert(bc.cend(), p_code, p_code + memory_size);
4540 #include <stdexcept>
4561 argument_strings[0] = first_message_;
4573 class error :
public std::runtime_error {
4593 virtual const char*
what() const noexcept
override {
4594 return what_reason.c_str();
4615 template <
typename T>
4617 template <
typename T>
4629 #if SOL_IS_ON(SOL_USE_BOOST)
4630 #include <boost/optional.hpp>
4634 #define SOL_TL_OPTIONAL_VERSION_MAJOR 0
4635 #define SOL_TL_OPTIONAL_VERSION_MINOR 5
4637 #include <exception>
4638 #include <functional>
4640 #include <type_traits>
4645 #if (defined(_MSC_VER) && _MSC_VER == 1900)
4646 #define SOL_TL_OPTIONAL_MSVC2015
4649 #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && !defined(__clang__))
4650 #define SOL_TL_OPTIONAL_GCC49
4653 #if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && !defined(__clang__))
4654 #define SOL_TL_OPTIONAL_GCC54
4657 #if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && !defined(__clang__))
4658 #define SOL_TL_OPTIONAL_GCC55
4661 #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && !defined(__clang__))
4662 #define SOL_TL_OPTIONAL_NO_CONSTRR
4664 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) std::has_trivial_copy_constructor<T>::value
4665 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::has_trivial_copy_assign<T>::value
4667 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
4669 #elif (defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__))
4670 #ifndef SOL_TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
4671 #define SOL_TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
4674 struct is_trivially_copy_constructible : std::is_trivially_copy_constructible<T> { };
4675 #ifdef _GLIBCXX_VECTOR
4676 template <
class T,
class A>
4677 struct is_trivially_copy_constructible<
std::vector<T, A>> : std::is_trivially_copy_constructible<T> { };
4682 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) sol::detail::is_trivially_copy_constructible<T>::value
4683 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::is_trivially_copy_assignable<T>::value
4684 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
4686 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) std::is_trivially_copy_constructible<T>::value
4687 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::is_trivially_copy_assignable<T>::value
4688 #define SOL_TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
4691 #if __cplusplus > 201103L
4692 #define SOL_TL_OPTIONAL_CXX14
4695 #if (__cplusplus == 201103L || defined(SOL_TL_OPTIONAL_MSVC2015) || defined(SOL_TL_OPTIONAL_GCC49))
4696 #define SOL_TL_OPTIONAL_11_CONSTEXPR
4698 #define SOL_TL_OPTIONAL_11_CONSTEXPR constexpr
4703 #ifndef SOL_TL_MONOSTATE_INPLACE_MUTEX
4704 #define SOL_TL_MONOSTATE_INPLACE_MUTEX
4714 #ifndef SOL_TL_TRAITS_MUTEX
4715 #define SOL_TL_TRAITS_MUTEX
4723 template <
bool E,
class T =
void>
4725 template <
bool B,
class T,
class F>
4733 template <
class B,
class... Bs>
4736 #if defined(_LIBCPP_VERSION) && __cplusplus == 201103L
4737 #define SOL_TL_OPTIONAL_LIBCXX_MEM_FN_WORKAROUND
4740 #ifdef SOL_TL_OPTIONAL_LIBCXX_MEM_FN_WORKAROUND
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...) &&> :
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 template <
class T,
class Ret,
class... Args>
4754 struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile&&> :
std::true_type { };
4766 template <
typename Fn,
typename... Args,
4767 #ifdef SOL_TL_OPTIONAL_LIBCXX_MEM_FN_WORKAROUND
4768 typename =
enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value && is_const_or_const_ref<Args...>::value)>,
4770 typename =
enable_if_t<std::is_member_pointer<decay_t<Fn>>::value>,
int = 0>
4771 constexpr
auto invoke(Fn&& f, Args&&...
args) noexcept(noexcept(std::mem_fn(f)(std::forward<Args>(
args)...)))
4772 -> decltype(std::mem_fn(f)(std::forward<Args>(
args)...)) {
4773 return std::mem_fn(
f)(std::forward<Args>(
args)...);
4777 constexpr
auto invoke(Fn&& f, Args&&...
args) noexcept(noexcept(std::forward<Fn>(f)(std::forward<Args>(
args)...)))
4778 -> decltype(std::forward<Fn>(f)(std::forward<Args>(
args)...)) {
4779 return std::forward<Fn>(
f)(std::forward<Args>(
args)...);
4783 template <
class F,
class,
class... Us>
4786 template <
class F,
class... Us>
4791 template <
class F,
class... Us>
4794 template <
class F,
class... Us>
4803 template <
class... Ts>
4818 template <
class F,
class U,
class = invoke_result_t<F, U>>
4822 template <
class F,
class =
void,
class... U>
4824 template <
class F,
class... U>
4826 template <
class F,
class... U>
4829 template <
class T,
class... U>
4832 template <
class T,
class... U>
4835 template <
class T,
class U>
4839 template <
class T,
class U,
class Other>
4841 && !std::is_constructible<T, optional<U>&&>::value && !std::is_constructible<T, const optional<U>&>::value
4842 && !std::is_constructible<T, const optional<U>&&>::value && !std::is_convertible<optional<U>&, T>::value
4843 && !std::is_convertible<optional<U>&&, T>::value && !std::is_convertible<const optional<U>&, T>::value
4844 && !std::is_convertible<const optional<U>&&, T>::value>;
4846 template <
class T,
class U>
4849 && std::is_assignable<T&, U>::value>;
4851 template <
class T,
class U,
class Other>
4853 && !std::is_constructible<T, optional<U>&>::value && !std::is_constructible<T, optional<U>&&>::value
4854 && !std::is_constructible<T, const optional<U>&>::value && !std::is_constructible<T, const optional<U>&&>::value
4855 && !std::is_convertible<optional<U>&, T>::value && !std::is_convertible<optional<U>&&, T>::value
4856 && !std::is_convertible<const optional<U>&, T>::value && !std::is_convertible<const optional<U>&&, T>::value
4857 && !std::is_assignable<T&, optional<U>&>::value && !std::is_assignable<T&, optional<U>&&>::value
4858 && !std::is_assignable<T&, const optional<U>&>::value && !std::is_assignable<T&, const optional<U>&&>::value>;
4862 template <
class T,
class U = T>
4865 template <
class T,
class U = T>
4869 namespace swap_adl_tests {
4876 template <
class T, std::
size_t N>
4877 tag swap(T (&a)[N], T (&b)[N]);
4881 template <
class,
class>
4883 template <class T, class U, class = decltype(
swap(
std::declval<T&>(),
std::declval<U&>()))>
4886 template <class, class>
4888 template <class T, class U>
4893 :
std::integral_constant<
bool,
std::is_nothrow_move_constructible<T>::value &&
std::is_nothrow_move_assignable<T>::value> { };
4895 template <
class T, std::
size_t N>
4898 template <
class T,
class U>
4902 template <
class T,
class U = T>
4904 decltype(detail::swap_adl_tests::can_swap<T, U>(0))::value
4905 && (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value
4906 || (std::is_move_assignable<T>::value && std::is_move_constructible<T>::value))> { };
4908 template <
class T, std::
size_t N>
4910 decltype(detail::swap_adl_tests::can_swap<T[N], T[N]>(0))::value
4911 && (!decltype(detail::swap_adl_tests::uses_std<T[N], T[N]>(0))::value || is_swappable<T, T>::value)> { };
4913 template <
class T,
class U = T>
4915 : std::integral_constant<bool,
4916 is_swappable<T, U>::value
4917 && ((decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value&& detail::swap_adl_tests::is_std_swap_noexcept<T>::value)
4918 || (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value&& detail::swap_adl_tests::is_adl_swap_noexcept<T, U>::value))> { };
4924 template <class T, bool = ::std::is_trivially_destructible<T>::value>
4929 template <
class... U>
4936 m_has_value =
false;
4955 template <
class... U>
4967 bool m_has_value =
false;
4978 this->m_has_value =
false;
4981 template <
class... Args>
4983 new (std::addressof(this->m_value)) T(std::forward<Args>(
args)...);
4984 this->m_has_value =
true;
4987 template <
class Opt>
4989 if (this->has_value()) {
4990 if (rhs.has_value()) {
4991 this->m_value = std::forward<Opt>(rhs).get();
4995 this->m_has_value =
false;
4999 else if (rhs.has_value()) {
5000 construct(std::forward<Opt>(rhs).
get());
5005 return this->m_has_value;
5009 return this->m_value;
5012 return this->m_value;
5017 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5018 constexpr
const T&&
get() const&& {
5026 template <
class T,
bool = SOL_TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)>
5036 using base_t::base_t;
5041 this->construct(rhs.
get());
5044 this->m_has_value =
false;
5053 #ifndef SOL_TL_OPTIONAL_GCC49
5054 template <class T, bool = std::is_trivially_move_constructible<T>::value>
5059 template <
class T,
bool = false>
5074 this->m_has_value =
false;
5104 #ifndef SOL_TL_OPTIONAL_GCC49
5106 bool = std::is_trivially_destructible<T>::value&& std::is_trivially_move_constructible<T>::value&& std::is_trivially_move_assignable<T>::value>
5111 template <
class T,
bool = false>
5127 std::is_nothrow_move_constructible<T>::value&& std::is_nothrow_move_assignable<T>::value) {
5135 template <class T, bool EnableCopy = std::is_copy_constructible<T>::value,
bool EnableMove = std::is_move_constructible<T>::value>
5173 template <
class T,
bool EnableCopy = (std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value),
5174 bool EnableMove = (std::is_move_constructible<T>::value && std::is_move_assignable<T>::value)>
5232 const char*
what() const noexcept
override {
5233 return "Optional has no value";
5244 class optional :
private detail::optional_move_assign_base<T>,
5245 private detail::optional_delete_ctor_base<T>,
5246 private detail::optional_delete_assign_base<T> {
5249 static_assert(!std::is_same<T, in_place_t>::value,
"instantiation of optional with in_place_t is ill-formed");
5253 #if defined(SOL_TL_OPTIONAL_CXX14) && !defined(SOL_TL_OPTIONAL_GCC49) && !defined(SOL_TL_OPTIONAL_GCC54) && !defined(SOL_TL_OPTIONAL_GCC55)
5285 constexpr
auto and_then(F&& f)
const& {
5286 using result = detail::invoke_result_t<F, const T&>;
5287 static_assert(detail::is_optional<result>::value,
"F must return an optional");
5292 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5296 constexpr
auto and_then(F&& f)
const&& {
5297 using result = detail::invoke_result_t<F, const T&&>;
5298 static_assert(detail::is_optional<result>::value,
"F must return an optional");
5342 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5355 #if defined(SOL_TL_OPTIONAL_CXX14) && !defined(SOL_TL_OPTIONAL_GCC49) && !defined(SOL_TL_OPTIONAL_GCC54) && !defined(SOL_TL_OPTIONAL_GCC55)
5380 constexpr
auto map(F&& f)
const& {
5387 constexpr
auto map(F&& f)
const&& {
5415 constexpr decltype(
optional_map_impl(std::declval<const optional&>(), std::declval<F&&>())) map(F&& f) const& {
5419 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5423 constexpr decltype(
optional_map_impl(std::declval<const optional&&>(), std::declval<F&&>())) map(F&& f) const&& {
5438 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr>
5443 std::forward<F>(
f)();
5448 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
5450 return has_value() ? *this : std::forward<F>(
f)();
5455 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr>
5460 std::forward<F>(
f)();
5465 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
5467 return has_value() ?
std::move(*
this) : std::forward<F>(
f)();
5472 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr>
5477 std::forward<F>(
f)();
5482 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
5484 return has_value() ? *this : std::forward<F>(
f)();
5487 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5488 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr>
5494 std::forward<F>(
f)();
5499 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
5501 return has_value() ?
std::move(*
this) : std::forward<F>(
f)();
5512 template <
class F,
class U>
5514 return has_value() ?
detail::invoke(std::forward<F>(
f), **
this) : std::forward<U>(u);
5518 template <
class F,
class U>
5524 template <
class F,
class U>
5526 return has_value() ?
detail::invoke(std::forward<F>(
f), **
this) : std::forward<U>(u);
5529 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5530 template <
class F,
class U>
5546 template <
class F,
class U>
5548 return has_value() ?
detail::invoke(std::forward<F>(
f), **
this) : std::forward<U>(u)();
5554 template <
class F,
class U>
5562 template <
class F,
class U>
5564 return has_value() ?
detail::invoke(std::forward<F>(
f), **
this) : std::forward<U>(u)();
5567 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5568 template <
class F,
class U>
5581 return has_value() ? result { u } : result {
nullopt };
5587 return has_value() ? *this : rhs;
5592 return has_value() ? *this : rhs;
5597 return has_value() ?
std::move(*
this) : rhs;
5600 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5603 return has_value() ?
std::move(*
this) : rhs;
5609 return has_value() ? *this :
std::move(rhs);
5614 return has_value() ? *this :
std::move(rhs);
5622 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5651 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5685 template <
class... Args>
5692 template <
class U,
class... Args>
5694 std::initializer_list<U> il, Args&&...
args) {
5695 this->construct(il, std::forward<Args>(
args)...);
5698 #if 0 // SOL_MODIFICATION
5706 template <class U = T, detail::enable_if_t<!std::is_convertible<U&&, T>::value>* =
nullptr, detail::enable_forward_value<T, U>* =
nullptr>
5707 constexpr
explicit optional(U&& u) : base(
in_place,
std::forward<U>(u)) {
5718 #endif // sol2 modification
5722 template <
class U, detail::enable_from_other<T, U, const U&>* =
nullptr, detail::enable_if_t<std::is_convertible<const U&, T>::value>* =
nullptr>
5724 if (rhs.has_value()) {
5725 this->construct(*rhs);
5730 template <
class U, detail::enable_from_other<T, U, const U&>* =
nullptr, detail::enable_if_t<!std::is_convertible<const U&, T>::value>* =
nullptr>
5732 if (rhs.has_value()) {
5733 this->construct(*rhs);
5739 template <
class U, detail::enable_from_other<T, U, U&&>* =
nullptr, detail::enable_if_t<std::is_convertible<U&&, T>::value>* =
nullptr>
5741 if (rhs.has_value()) {
5747 template <
class U, detail::enable_from_other<T, U, U&&>* =
nullptr, detail::enable_if_t<!std::is_convertible<U&&, T>::value>* =
nullptr>
5761 this->m_has_value =
false;
5782 template <
class U = T, detail::enable_assign_forward<T, U>* =
nullptr>
5785 this->m_value = std::forward<U>(u);
5788 this->construct(std::forward<U>(u));
5799 template <
class U, detail::enable_assign_from_other<T, U, const U&>* =
nullptr>
5802 if (rhs.has_value()) {
5803 this->m_value = *rhs;
5810 if (rhs.has_value()) {
5811 this->construct(*rhs);
5823 template <
class U, detail::enable_assign_from_other<T, U, U>* =
nullptr>
5826 if (rhs.has_value()) {
5834 if (rhs.has_value()) {
5844 template <
class... Args>
5846 static_assert(std::is_constructible<T, Args&&...>::value,
"T must be constructible with Args");
5849 this->construct(std::forward<Args>(
args)...);
5855 template <
class U,
class... Args>
5858 this->construct(il, std::forward<Args>(
args)...);
5870 if (rhs.has_value()) {
5875 new (std::addressof(rhs.m_value)) T(
std::move(this->m_value));
5876 this->m_value.T::~T();
5879 else if (rhs.has_value()) {
5880 new (std::addressof(this->m_value)) T(
std::move(rhs.m_value));
5881 rhs.m_value.T::~T();
5890 return std::addressof(this->m_value);
5896 return std::addressof(this->m_value);
5904 return this->m_value;
5910 return this->m_value;
5918 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5919 constexpr
const T&&
operator*() const&& {
5928 return this->m_has_value;
5932 constexpr
explicit operator bool() const noexcept {
5933 return this->m_has_value;
5942 return this->m_value;
5943 #if SOL_IS_OFF(SOL_EXCEPTIONS)
5947 #endif // No exceptions allowed
5953 return this->m_value;
5954 #if SOL_IS_OFF(SOL_EXCEPTIONS)
5958 #endif // No exceptions allowed
5964 #if SOL_IS_OFF(SOL_EXCEPTIONS)
5968 #endif // No exceptions allowed
5971 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
5976 #if SOL_IS_OFF(SOL_EXCEPTIONS)
5980 #endif // No exceptions allowed
5988 static_assert(std::is_copy_constructible<T>::value && std::is_convertible<U&&, T>::value,
"T must be copy constructible and convertible from U");
5989 return has_value() ? **this :
static_cast<T
>(std::forward<U>(u));
5995 static_assert(std::is_move_constructible<T>::value && std::is_convertible<U&&, T>::value,
"T must be move constructible and convertible from U");
5996 return has_value() ? **this :
static_cast<T
>(std::forward<U>(u));
6003 this->m_has_value =
false;
6014 template <
class T,
class U>
6016 return lhs.has_value() == rhs.has_value() && (!lhs.has_value() || *lhs == *rhs);
6019 template <
class T,
class U>
6021 return lhs.has_value() != rhs.has_value() || (lhs.has_value() && *lhs != *rhs);
6024 template <
class T,
class U>
6026 return rhs.has_value() && (!lhs.has_value() || *lhs < *rhs);
6029 template <
class T,
class U>
6031 return lhs.has_value() && (!rhs.has_value() || *lhs > *rhs);
6034 template <
class T,
class U>
6036 return !lhs.has_value() || (rhs.has_value() && *lhs <= *rhs);
6039 template <
class T,
class U>
6041 return !rhs.has_value() || (lhs.has_value() && *lhs >= *rhs);
6049 return !lhs.has_value();
6054 return !rhs.has_value();
6059 return lhs.has_value();
6064 return rhs.has_value();
6074 return rhs.has_value();
6079 return !lhs.has_value();
6089 return lhs.has_value();
6104 return !rhs.has_value();
6112 template <
class T,
class U>
6114 return lhs.has_value() ? *lhs == rhs :
false;
6117 template <
class T,
class U>
6119 return rhs.has_value() ? lhs == *rhs :
false;
6122 template <
class T,
class U>
6124 return lhs.has_value() ? *lhs != rhs :
true;
6127 template <
class T,
class U>
6129 return rhs.has_value() ? lhs != *rhs :
true;
6132 template <
class T,
class U>
6134 return lhs.has_value() ? *lhs < rhs :
true;
6137 template <
class T,
class U>
6139 return rhs.has_value() ? lhs < *rhs :
false;
6142 template <
class T,
class U>
6144 return lhs.has_value() ? *lhs <= rhs :
true;
6147 template <
class T,
class U>
6149 return rhs.has_value() ? lhs <= *rhs :
false;
6152 template <
class T,
class U>
6154 return lhs.has_value() ? *lhs > rhs :
false;
6157 template <
class T,
class U>
6159 return rhs.has_value() ? lhs > *rhs :
true;
6162 template <
class T,
class U>
6164 return lhs.has_value() ? *lhs >= rhs :
false;
6167 template <
class T,
class U>
6169 return rhs.has_value() ? lhs >= *rhs :
true;
6173 template <class T, detail::enable_if_t<std::is_move_constructible<T>::value>* =
nullptr, detail::enable_if_t<detail::is_swappable<T>::value>* =
nullptr>
6175 return lhs.swap(rhs);
6182 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>>
6187 template <
class T,
class... Args>
6191 template <
class T,
class U,
class... Args>
6196 #if __cplusplus >= 201703L
6198 optional(T) -> optional<T>;
6203 #ifdef SOL_TL_OPTIONAL_CXX14
6204 template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
6205 detail::enable_if_t<!std::is_void<Ret>::value>* =
nullptr>
6207 return opt.has_value() ?
detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt)) : optional<Ret>(
nullopt);
6210 template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
6211 detail::enable_if_t<std::is_void<Ret>::value>* =
nullptr>
6213 if (opt.has_value()) {
6218 return optional<monostate>(
nullopt);
6221 template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
6222 detail::enable_if_t<!std::is_void<Ret>::value>* =
nullptr>
6228 template <class Opt, class F, class Ret = decltype(detail::invoke(std::declval<F>(), *std::declval<Opt>())),
6232 if (opt.has_value()) {
6267 #if defined(SOL_TL_OPTIONAL_CXX14) && !defined(SOL_TL_OPTIONAL_GCC49) && !defined(SOL_TL_OPTIONAL_GCC54) && !defined(SOL_TL_OPTIONAL_GCC55)
6299 constexpr
auto and_then(F&&
f)
const& {
6306 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6310 constexpr
auto and_then(F&&
f)
const&& {
6356 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6369 #if defined(SOL_TL_OPTIONAL_CXX14) && !defined(SOL_TL_OPTIONAL_GCC49) && !defined(SOL_TL_OPTIONAL_GCC54) && !defined(SOL_TL_OPTIONAL_GCC55)
6394 constexpr
auto map(F&& f)
const& {
6401 constexpr
auto map(F&& f)
const&& {
6433 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6451 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr>
6456 std::forward<F>(
f)();
6461 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
6463 return has_value() ? *this : std::forward<F>(
f)();
6468 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr>
6473 std::forward<F>(
f)();
6478 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
6480 return has_value() ?
std::move(*
this) : std::forward<F>(
f)();
6485 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr>
6490 std::forward<F>(
f)();
6495 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
6497 return has_value() ? *this : std::forward<F>(
f)();
6500 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6501 template <
class F, detail::enable_if_ret_
void<F>* =
nullptr>
6507 std::forward<F>(
f)();
6512 template <
class F, detail::disable_if_ret_
void<F>* =
nullptr>
6514 return has_value() ?
std::move(*
this) : std::forward<F>(
f)();
6525 template <
class F,
class U>
6527 return has_value() ?
detail::invoke(std::forward<F>(
f), **
this) : std::forward<U>(u);
6531 template <
class F,
class U>
6537 template <
class F,
class U>
6539 return has_value() ?
detail::invoke(std::forward<F>(
f), **
this) : std::forward<U>(u);
6542 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6543 template <
class F,
class U>
6559 template <
class F,
class U>
6561 return has_value() ?
detail::invoke(std::forward<F>(
f), **
this) : std::forward<U>(u)();
6567 template <
class F,
class U>
6575 template <
class F,
class U>
6577 return has_value() ?
detail::invoke(std::forward<F>(
f), **
this) : std::forward<U>(u)();
6580 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6581 template <
class F,
class U>
6594 return has_value() ? result { u } : result {
nullopt };
6600 return has_value() ? *this : rhs;
6605 return has_value() ? *this : rhs;
6610 return has_value() ?
std::move(*
this) : rhs;
6613 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6616 return has_value() ?
std::move(*
this) : rhs;
6622 return has_value() ? *this :
std::move(rhs);
6627 return has_value() ? *this :
std::move(rhs);
6635 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6664 #ifndef SOL_TL_OPTIONAL_NO_CONSTRR
6698 template <
class U = T, detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>* =
nullptr>
6700 static_assert(std::is_lvalue_reference<U>::value,
"U must be an lvalue");
6729 template <
class U = T, detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>* =
nullptr>
6731 static_assert(std::is_lvalue_reference<U>::value,
"U must be an lvalue");
6732 m_value = std::addressof(u);
6742 m_value = std::addressof(rhs.value());
6750 template <
class... Args>
6752 static_assert(std::is_constructible<T, Args&&...>::value,
"T must be constructible with Args");
6799 return m_value !=
nullptr;
6803 constexpr
explicit operator bool() const noexcept {
6804 return m_value !=
nullptr;
6814 #if SOL_IS_OFF(SOL_EXCEPTIONS)
6818 #endif // No exceptions allowed
6825 #if SOL_IS_OFF(SOL_EXCEPTIONS)
6829 #endif // No exceptions allowed
6836 static_assert(std::is_convertible<U&&, T&>::value,
"T must be convertible from U");
6837 return has_value() ?
const_cast<T&
>(**this) :
static_cast<T&
>(std::forward<U>(u));
6859 return ::std::hash<::sol::detail::remove_const_t<T>>()(*o);
6866 #endif // Boost vs. Better optional
6872 #if SOL_IS_ON(SOL_USE_BOOST)
6873 template <
typename T>
6874 using optional = boost::optional<T>;
6877 #endif // Boost vs. Better optional
6880 template <
typename T>
6883 template <
typename T>
6888 template <
typename T>
6893 #if SOL_IS_ON(SOL_USE_BOOST)
6894 template <
typename T>
6898 #endif // Boost nullopt
6900 #if SOL_IS_ON(SOL_USE_BOOST)
6901 template <
typename T>
6904 template <
typename T>
6906 #endif // Boost continues to lag behind, to not many people's surprise...
6910 #if SOL_IS_ON(SOL_USE_BOOST)
6911 #undef SOL_BOOST_NONE_CONSTEXPR_I_
6923 template <
typename T,
typename... Args>
6927 std::allocator_traits<std::allocator<Tu>>::construct(alloc, std::forward<T>(obj), std::forward<Args>(
args)...);
6930 template <
typename T,
typename... Args>
6932 construct(std::forward<T>(obj), std::forward<Args>(
args)...);
6937 template <
typename T>
6943 template <
typename T>
6945 destroy(std::forward<T>(obj));
6950 template <
typename T>
6962 template <
typename T,
typename Dx,
typename... Args>
6964 return std::unique_ptr<T, Dx>(
new T(std::forward<Args>(
args)...));
6967 template <
typename Tag,
typename T>
6991 template <
typename... Args>
6994 template <
typename... Args>
7005 template <
typename... Functions>
7013 template <
typename... Functions>
7018 template <
typename... Functions>
7026 template <
typename... Functions>
7031 template <
typename Function>
7043 template <
typename Fx>
7061 template <
int Target,
int... In>
7064 template <
int... In>
7073 template <
typename... Args>
7080 return stack_indices[i];
7084 return stack_indices[i];
7092 template <
typename F,
typename... Policies>
7093 struct policy_wrapper {
7109 template <
typename F,
typename... Args>
7115 template <
typename T>
7118 template <
typename T>
7127 #include <type_traits>
7133 template <
typename T, std::
size_t tag = 0,
typename =
void>
7140 ebco& operator=(
const ebco&) =
default;
7142 ebco(
const T& v) noexcept(std::is_nothrow_copy_constructible_v<T>) : m_value(v) {};
7143 ebco(T&& v) noexcept(std::is_nothrow_move_constructible_v<T>) : m_value(
std::
move(v)) {};
7152 template <
typename Arg,
typename... Args,
7154 !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
7155 ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T> && (
sizeof...(Args) > 0 || !std::is_convertible_v<Arg, T>)>>
7156 ebco(Arg&&
arg, Args&&...
args) noexcept(std::is_nothrow_constructible_v<T, Arg, Args...>)
7157 : m_value(
std::forward<Arg>(
arg),
std::forward<Args>(
args)...) {
7173 template <
typename T, std::
size_t tag>
7174 struct ebco<T, tag,
std::
enable_if_t<!std::is_reference_v<T> && std::is_class_v<T> && !std::is_final_v<T>>> : T {
7178 ebco(
const T& v) noexcept(std::is_nothrow_copy_constructible_v<T>) : T(v) {};
7179 ebco(T&& v) noexcept(std::is_nothrow_move_constructible_v<T>) : T(
std::
move(v)) {};
7180 template <
typename Arg,
typename... Args,
7182 !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
7183 ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T> && (
sizeof...(Args) > 0 || !std::is_convertible_v<Arg, T>)>>
7184 ebco(Arg&&
arg, Args&&...
args) noexcept(std::is_nothrow_constructible_v<T, Arg, Args...>) : T(
std::forward<Arg>(
arg),
std::forward<Args>(
args)...) {
7187 ebco& operator=(
const ebco&) =
default;
7190 static_cast<T&
>(*this) = v;
7199 return static_cast<T&
>(*this);
7203 return static_cast<T const&
>(*this);
7207 return std::move(
static_cast<T&
>(*
this));
7211 template <
typename T, std::
size_t tag>
7220 ebco(T& v) noexcept : m_ref(std::addressof(v)) {};
7222 ebco& operator=(
const ebco&) =
default;
7225 m_ref = std::addressof(v);
7234 template <
typename T, std::
size_t tag>
7243 ebco& operator=(
const ebco&) =
delete;
7264 #include <initializer_list>
7266 #include <string_view>
7269 #if SOL_IS_ON(SOL_STD_VARIANT)
7271 #endif // variant shenanigans (thanks, Mac OSX)
7279 template <
typename T>
7284 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
7288 #endif // noexcept function type for lua_CFunction
7290 template <
typename T>
7305 return std::addressof(value);
7321 #if SOL_IS_ON(SOL_NIL)
7342 template <
typename T>
7351 template <
typename Arg,
7356 template <
typename Arg0,
typename Arg1,
typename... Args>
7361 template <
typename F>
7368 template <
typename T>
7371 template <
typename... Args>
7425 operator void*()
const {
7442 operator void*()
const {
7447 template <
typename T>
7450 static_assert(!std::is_void_v<T>,
"the type for light will never be void");
7458 explicit light(
void*
x) : m_value(static_cast<T*>(
x)) {
7465 operator T*()
const {
7468 operator T&()
const {
7477 template <
typename T>
7483 template <
typename T>
7484 struct user :
private detail::ebco<T> {
7489 using base_t::base_t;
7491 using base_t::value;
7493 operator std::add_pointer_t<std::remove_reference_t<T>>() {
7494 return std::addressof(this->base_t::value());
7497 operator std::add_pointer_t<std::add_const_t<std::remove_reference_t<T>>>()
const {
7498 return std::addressof(this->base_t::value());
7501 operator std::add_lvalue_reference_t<T>() {
7502 return this->base_t::value();
7505 operator std::add_const_t<std::add_lvalue_reference_t<T>>&()
const {
7506 return this->base_t::value();
7510 template <
typename T>
7513 return user<U>(std::forward<T>(u));
7516 template <
typename T>
7522 using base_t::base_t;
7524 using base_t::value;
7527 template <
typename T>
7533 template <
typename... Upvalues>
7551 template <
typename... Args>
7553 return closure<Args...>(
f, std::forward<Args>(
args)...);
7556 template <
typename Sig,
typename... Ps>
7564 template <
typename Sig = function_sig<>,
typename... Args>
7569 template <
typename Sig = function_sig<>,
typename... Args>
7574 template <
typename T>
7575 struct as_table_t :
private detail::ebco<T> {
7589 template <
typename Arg,
typename... Args,
7591 !std::is_same_v<as_table_t, meta::unqualified_t<Arg>> && !std::is_same_v<meta::unqualified_t<T>,
meta::unqualified_t<Arg>>>* =
nullptr>
7592 as_table_t(Arg&&
arg, Args&&...
args) noexcept(std::is_nothrow_constructible_v<base_t, Arg, Args...>)
7596 using base_t::value;
7598 operator std::add_lvalue_reference_t<T>() {
7599 return this->base_t::value();
7602 operator std::add_const_t<std::add_lvalue_reference_t<T>>()
const {
7603 return this->base_t::value();
7607 template <
typename T>
7608 struct nested :
private detail::ebco<T> {
7624 template <
typename Arg,
typename... Args,
7626 !std::is_same_v<nested, meta::unqualified_t<Arg>> && !std::is_same_v<meta::unqualified_t<T>,
meta::unqualified_t<Arg>>>* =
nullptr>
7627 nested(Arg&&
arg, Args&&...
args) noexcept(std::is_nothrow_constructible_v<base_t, Arg, Args...>)
7631 using base_t::value;
7633 operator std::add_lvalue_reference_t<T>() {
7634 return this->base_t::value();
7637 operator std::add_const_t<std::add_lvalue_reference_t<T>>()
const {
7638 return this->base_t::value();
7645 template <
typename T>
7650 template <
typename T>
7655 template <
typename T>
7657 return nested<T>(std::forward<T>(container));
7660 template <
typename T>
7665 template <
typename T>
7666 struct as_container_t :
private detail::ebco<T> {
7679 using base_t::base_t;
7681 using base_t::value;
7683 operator std::add_lvalue_reference_t<T>() {
7688 template <
typename T>
7693 template <
typename T>
7705 using base_t::base_t;
7707 using base_t::value;
7710 template <
typename Fx>
7715 template <
typename T>
7727 using base_t::base_t;
7729 using base_t::value;
7732 template <
typename T>
7747 template <
typename T,
typename...>
7749 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>>;
7751 template <
typename T,
typename...>
7794 int sequence_hint = 0;
7803 new_table(
int sequence_hint_,
int map_hint_ = 0) noexcept : sequence_hint(sequence_hint_), map_hint(map_hint_) {
7809 enum class lib : unsigned char {
7886 #if SOL_IS_ON(SOL_NIL)
7888 #endif // Objective C/C++ Keyword that's found in OSX SDK and OBJC -- check for all forms to protect
7901 static const std::array<std::string, 10> names { {
"ok",
7909 "CRITICAL_EXCEPTION_FAILURE",
7910 "CRITICAL_INDETERMINATE_STATE_FAILURE" } };
7929 if (
static_cast<std::ptrdiff_t
>(c) == -1) {
7952 static const std::array<std::string, 7> names {
7953 {
"ok",
"memory",
"gc",
"syntax",
"file",
"CRITICAL_EXCEPTION_FAILURE",
"CRITICAL_INDETERMINATE_STATE_FAILURE" }
7967 if (
static_cast<int>(c) == -1) {
7975 static const std::array<std::string, 3> names { {
8028 static const std::array<std::string, 37> names = { {
"new",
8066 "__sol.static_index",
8067 "__sol.static_new_index" } };
8083 template <
typename T>
8085 : std::integral_constant<bool,
8086 (std::is_base_of_v<stateless_stack_reference, T> || std::is_base_of_v<stateless_reference, T>)&&(
8087 !std::is_base_of_v<stack_reference, T> && !std::is_base_of_v<reference, T> && !std::is_base_of_v<main_reference, T>)> { };
8089 template <
typename T>
8092 template <
typename T>
8094 : std::integral_constant<bool,
8095 std::is_base_of_v<reference,
8096 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>> {
8099 template <
typename T>
8102 template <
typename T>
8105 template <
typename T>
8108 template <
typename T>
8110 : std::integral_constant<bool,
8111 std::is_same_v<meta::unqualified_t<T>,
8112 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>> {
8115 template <
typename T>
8118 template <
typename T>
8121 template <
typename T>
8123 : std::integral_constant<bool,
8124 !std::is_same_v<state_view,
8125 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>)> {
8128 template <
typename T>
8131 template <
typename T>
8132 struct is_to_stringable :
meta::any<meta::supports_to_string_member<meta::unqualified_t<T>>, meta::supports_adl_to_string<meta::unqualified_t<T>>,
8133 meta::supports_op_left_shift<std::ostream, meta::unqualified_t<T>>> { };
8135 template <
typename T>
8138 template <
typename T>
8141 template <
typename T>
8145 template <
typename T,
typename =
void>
8146 struct lua_type_of : std::integral_constant<type, type::userdata> { };
8148 template <
typename C,
typename T,
typename A>
8149 struct lua_type_of<
std::basic_string<C, T, A>> : std::integral_constant<type, type::string> { };
8151 template <
typename C,
typename T>
8154 template <std::
size_t N>
8155 struct lua_type_of<char[N]> : std::integral_constant<type, type::string> { };
8157 template <std::
size_t N>
8158 struct lua_type_of<wchar_t[N]> : std::integral_constant<type, type::string> { };
8160 #if SOL_IS_ON(SOL_CHAR8_T)
8161 template <std::
size_t N>
8162 struct lua_type_of<char8_t[N]> : std::integral_constant<type, type::string> { };
8165 template <std::
size_t N>
8166 struct lua_type_of<char16_t[N]> : std::integral_constant<type, type::string> { };
8168 template <std::
size_t N>
8169 struct lua_type_of<char32_t[N]> : std::integral_constant<type, type::string> { };
8172 struct lua_type_of<char> : std::integral_constant<type, type::string> { };
8175 struct lua_type_of<wchar_t> : std::integral_constant<type, type::string> { };
8177 #if SOL_IS_ON(SOL_CHAR8_T)
8179 struct lua_type_of<char8_t> : std::integral_constant<type, type::string> { };
8183 struct lua_type_of<char16_t> : std::integral_constant<type, type::string> { };
8186 struct lua_type_of<char32_t> : std::integral_constant<type, type::string> { };
8189 struct lua_type_of<const char*> : std::integral_constant<type, type::string> { };
8192 struct lua_type_of<const wchar_t*> : std::integral_constant<type, type::string> { };
8194 #if SOL_IS_ON(SOL_CHAR8_T)
8196 struct lua_type_of<const char8_t*> : std::integral_constant<type, type::string> { };
8200 struct lua_type_of<const char16_t*> : std::integral_constant<type, type::string> { };
8203 struct lua_type_of<const char32_t*> : std::integral_constant<type, type::string> { };
8206 struct lua_type_of<bool> : std::integral_constant<type, type::boolean> { };
8221 struct lua_type_of<
std::nullptr_t> : std::integral_constant<type, type::lua_nil> { };
8226 template <
bool b,
typename Base>
8229 template <
typename Base>
8232 template <
typename Base>
8235 template <
typename T,
typename Base>
8241 template <
typename B>
8250 template <
typename T>
8253 template <
typename T>
8254 struct lua_type_of<
std::initializer_list<T>> : std::integral_constant<type, type::table> { };
8262 template <
typename Base>
8265 template <
typename... Args>
8266 struct lua_type_of<
std::tuple<Args...>> : std::integral_constant<type, type::poly> { };
8268 template <
typename A,
typename B>
8283 template <
typename T>
8286 template <
typename T>
8289 template <
typename Base>
8292 template <
typename Base>
8299 struct lua_type_of<
std::remove_pointer_t<lua_CFunction>> : std::integral_constant<type, type::function> { };
8301 template <
typename Base,
bool aligned>
8304 template <
typename Base,
bool aligned,
typename Handler>
8307 template <
typename Base>
8310 template <
typename Base>
8313 template <
typename Signature>
8316 template <
typename T>
8319 template <
typename T>
8343 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
8344 template <
typename T>
8347 template <
typename T>
8348 struct lua_type_of<T*> : std::integral_constant<type, type::userdata> { };
8351 template <
typename T>
8353 : std::integral_constant<type, type::number> { };
8355 template <
typename T>
8358 template <
typename T>
8364 #if SOL_IS_ON(SOL_STD_VARIANT)
8365 template <
typename... Tn>
8366 struct lua_type_of<
std::variant<Tn...>> : std::integral_constant<type, type::poly> { };
8367 #endif // std::variant deployment sucks on Clang
8369 template <
typename T>
8372 template <
typename C,
C v,
template <
typename...>
class V,
typename... Args>
8375 template <
typename C,
C v,
template <
typename...>
class V,
typename T,
typename... Args>
8378 template <
typename C,
C v,
template <
typename...>
class V,
typename List>
8381 template <
typename C,
C v,
template <
typename...>
class V,
typename... Args>
8385 template <
typename T>
8390 template <
typename T>
8393 template <
typename T>
8398 template <
typename A,
typename B>
8399 struct lua_size<
std::pair<A, B>> : std::integral_constant<int, lua_size<A>::value + lua_size<B>::value> { };
8401 template <
typename... Args>
8402 struct lua_size<
std::tuple<Args...>> : std::integral_constant<int, detail::accumulate<int, 0, lua_size, Args...>::value> { };
8404 template <
typename T>
8411 template <
typename T>
8416 template <
typename T>
8420 template <
typename T>
8422 : std::integral_constant<bool,
8425 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>>)
8426 || is_lua_reference_or_proxy_v<T> || meta::is_specialization_of_v<T, std::tuple> || meta::is_specialization_of_v<T, std::pair>> { };
8428 template <
typename T>
8431 template <
typename T>
8433 #if
SOL_IS_ON(SOL_FUNCTION_CALL_VALUE_SEMANTICS)
8441 template <
typename T>
8444 template <
typename T>
8447 template <
typename T>
8450 template <
typename T>
8465 template <
typename T>
8468 template <
typename T>
8474 template <
typename T>
8476 template <
typename T>
8478 template <
typename T>
8480 template <
typename T>
8482 template <
typename T>
8484 template <
typename T>
8486 template <
typename T>
8496 template <
typename T>
8499 template <
typename T>
8510 template <
typename Signature>
8516 typedef std::integral_constant<bool, meta::count_for<is_variadic_arguments, typename base_t::args_list>::value != 0>
runtime_variadics_t;
8525 template <
typename T>
8527 template <
bool x,
typename T>
8529 template <
typename T>
8532 template <
typename T>
8535 template <
typename T>
8537 template <
typename T>
8540 template <
typename T>
8543 template <
typename T>
8545 template <
bool x,
typename T>
8547 template <
typename T>
8550 template <
typename T>
8553 template <
typename T>
8555 template <
typename T,
bool aligned>
8557 template <
typename T,
bool aligned,
typename Handler>
8560 template <
typename T>
8563 template <
typename T>
8566 template <
typename T>
8569 template <
typename T>
8572 template <
typename T>
8573 using is_environment = std::integral_constant<bool, is_userdata_v<T> || is_table_v<T> || meta::is_specialization_of_v<T, basic_environment>>;
8575 template <
typename T>
8578 template <
typename T>
8579 using is_table_like = std::integral_constant<bool, is_table_v<T> || is_environment_v<T> || is_userdata_v<T>>;
8581 template <
typename T>
8584 template <
typename T>
8586 : std::integral_constant<bool,
8587 (SOL_IS_ON(SOL_DEFAULT_AUTOMAGICAL_USERTYPES))
8588 || (std::is_array_v<
8589 meta::unqualified_t<T>> || (!std::is_same_v<meta::unqualified_t<T>, state> && !std::is_same_v<meta::unqualified_t<T>, state_view>))> {
8592 template <
typename T>
8598 template <
typename T>
8601 template <
typename... Args>
8604 template <
typename... Args>
8610 template <
typename T>
8613 template <
typename T>
8616 template <
typename... Args>
8619 template <
typename T>
8622 template <
typename F,
typename... Policies>
8625 template <
typename T>
8628 template <
typename... Args>
8631 template <
typename... Args>
8634 template <
typename T>
8637 template <
typename Fx>
8640 template <
typename... Args>
8643 template <
typename... Args>
8647 template <
typename T>
8650 template <
typename T>
8670 static_cast<std::underlying_type_t<automagic_flags>
>(
left) |
static_cast<std::underlying_type_t<automagic_flags>
>(
right));
8675 static_cast<std::underlying_type_t<automagic_flags>
>(
left) &
static_cast<std::underlying_type_t<automagic_flags>
>(
right));
8688 template <
typename Left,
typename Right>
8693 template <
typename Left,
typename Right>
8695 return (
left &
right) !=
static_cast<Left>(
static_cast<std::underlying_type_t<Left>
>(0));
8698 template <
typename Left,
typename Right>
8700 return static_cast<Left>(
static_cast<std::underlying_type_t<Left>
>(
left) & ~
static_cast<std::underlying_type_t<Right>
>(
right));
8715 template <automagic_flags compile_time_defaults = automagic_flags::all>
8722 #include <exception>
8725 #if SOL_IS_ON(SOL_PRINT_ERRORS)
8737 static const char name[11] =
"sol.\xE2\x98\xA2\xE2\x98\xA2";
8743 #if SOL_IS_ON(SOL_PRINT_ERRORS)
8744 std::cerr <<
"[sol2] An exception occurred: ";
8745 std::cerr.write(what.data(),
static_cast<std::streamsize
>(what.size()));
8746 std::cerr << std::endl;
8761 if (vfunc ==
nullptr) {
8768 #if SOL_IS_OFF(SOL_EXCEPTIONS)
8769 template <lua_CFunction f>
8774 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
8775 template <lua_CFunction_noexcept f>
8780 template <lua_CFunction f>
8786 template <
typename Fx,
typename... Args>
8788 return f(L, std::forward<Args>(
args)...);
8797 #if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS)
8803 catch (
const char* cs) {
8806 catch (
const std::string&
s) {
8809 catch (
const std::exception& e) {
8812 #if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL)
8819 #endif // LuaJIT cannot have the catchall, but we must catch std::exceps for it
8821 #endif // Safe exceptions
8824 template <lua_CFunction f>
8829 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
8830 template <lua_CFunction_noexcept f>
8835 template <lua_CFunction f>
8841 template <
typename Fx,
typename... Args>
8844 return f(L, std::forward<Args>(
args)...);
8847 #if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS)
8848 return f(L, std::forward<Args>(
args)...);
8851 return f(L, std::forward<Args>(
args)...);
8853 catch (
const char* cs) {
8856 catch (
const std::string&
s) {
8859 catch (
const std::exception& e) {
8862 #if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL)
8878 #endif // Exceptions vs. No Exceptions
8880 template <
typename F, F fx>
8889 return static_trampoline_noexcept<fx>(L);
8893 {
return static_trampoline<fx>(L); }
8899 "void* storage is too small to transport the exception handler: please file a bug on the sol2 issue tracker to get this looked at!");
8920 #if SOL_IS_ON(SOL_MINGW_CCTYPE_IS_POISONED)
8924 #endif // MinGW is on some stuff
8928 inline constexpr std::array<string_view, 9>
removals { {
"{anonymous}",
8929 "(anonymous namespace)",
8935 "`anonymous-namespace'",
8936 "`anonymous namespace'" } };
8938 #if SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
8939 inline std::string ctti_get_type_name_from_sig(std::string name) {
8941 using namespace std;
8943 start = name.find_first_of(
'=', start);
8945 if (end == std::string::npos)
8947 if (start == std::string::npos)
8949 if (start < name.size() - 1)
8951 name = name.substr(start, end - start);
8952 start = name.rfind(
"seperator_mark");
8953 if (start != std::string::npos) {
8954 name.erase(start - 2, name.length());
8956 while (!name.empty() && isblank(name.front()))
8957 name.erase(name.begin());
8958 while (!name.empty() && isblank(name.back()))
8962 auto found = name.find(
removals[r]);
8963 while (found != std::string::npos) {
8972 template <
typename T,
class seperator_mark =
int>
8973 inline std::string ctti_get_type_name() {
8974 return ctti_get_type_name_from_sig(__PRETTY_FUNCTION__);
8976 #elif SOL_IS_ON(SOL_COMPILER_VCXX)
8977 inline std::string ctti_get_type_name_from_sig(std::string name) {
8979 if (start == std::string::npos)
8983 if (start <
name.size() - 1)
8986 if (end == std::string::npos)
8988 name =
name.substr(start, end - start);
8989 if (
name.find(
"struct", 0) == 0)
8990 name.replace(0, 6,
"", 0);
8991 if (
name.find(
"class", 0) == 0)
8992 name.replace(0, 5,
"", 0);
8993 while (!
name.empty() && isblank(
name.front()))
8995 while (!
name.empty() && isblank(
name.back()))
9000 while (found != std::string::npos) {
9009 template <
typename T>
9010 std::string ctti_get_type_name() {
9011 return ctti_get_type_name_from_sig(__FUNCSIG__);
9014 #error Compiler not supported for demangling
9017 template <
typename T>
9019 std::string realname = ctti_get_type_name<T>();
9025 static const std::array<std::string, 10> ops = {
9026 {
"operator<",
"operator<<",
"operator<<=",
"operator<=",
"operator>",
"operator>>",
"operator>>=",
"operator>=",
"operator->",
"operator->*" }
9030 for (idx =
static_cast<std::size_t>(realname.empty() ? 0 : realname.size() - 1); idx > 0; --idx) {
9031 if (level == 0 && realname[idx] ==
':') {
9034 bool isleft = realname[idx] ==
'<';
9035 bool isright = realname[idx] ==
'>';
9036 if (!isleft && !isright)
9038 bool earlybreak =
false;
9039 for (
const auto&
op : ops) {
9041 if (nisop == std::string::npos)
9044 if (nisop == nisopidx) {
9053 level += isleft ? -1 : 1;
9056 realname.erase(0, realname.length() <
static_cast<std::size_t>(idx) ? realname.length() : idx + 1);
9061 template <
typename T>
9063 std::string realname = ctti_get_type_name<T>();
9067 template <
typename T>
9069 static const std::string
d = demangle_once<T>();
9073 template <
typename T>
9075 static const std::string
d = short_demangle_once<T>();
9084 template <
typename T>
9085 struct usertype_traits {
9087 static const std::string& n = detail::short_demangle<T>();
9091 static const std::string& q_n = detail::demangle<T>();
9095 static const std::string m = std::string(
"sol.").append(detail::demangle<T>());
9099 static const std::string u_m = std::string(
"sol.").append(detail::demangle<T>()).append(
".user");
9103 static const std::string u_g_m = std::string(
"sol.").append(detail::demangle<T>()).append(
".user\xE2\x99\xBB");
9107 static const std::string g_t = std::string(
"sol.").append(detail::demangle<T>()).append(
".\xE2\x99\xBB");
9123 template <
typename T>
9128 template <
typename T>
9131 using pointer =
typename std::pointer_traits<std::shared_ptr<T>>::element_type*;
9137 template <
typename X>
9141 return p ==
nullptr;
9149 template <
typename T,
typename D>
9152 using pointer =
typename std::unique_ptr<T, D>::pointer;
9156 return p ==
nullptr;
9165 namespace meta {
namespace meta_detail {
9166 template <
typename T,
typename =
void>
9169 template <
typename T>
9171 using type =
typename T::actual_type;
9174 template <
typename T,
typename... Rest,
template <
typename...>
class Templ>
9181 template <
typename T>
9184 namespace meta {
namespace meta_detail {
9185 template <
typename T>
9188 template <
typename T>
9191 template <
typename T>
9194 template <
typename T,
typename =
void>
9199 template <
typename T>
9201 using type =
typename T::element_type;
9204 template <
typename T>
9209 template <
typename T,
typename =
void>
9210 struct unique_valid : std::integral_constant<bool, !has_internal_marker_v<T>> { };
9212 template <
typename T>
9216 template <
typename T>
9219 template <
typename T,
typename Element =
void>
9222 template <
typename T>
9225 template <
typename T>
9226 struct is_unique_usertype : std::integral_constant<bool, meta::meta_detail::unique_valid<unique_usertype_traits<T>>::value> { };
9228 template <
typename T>
9231 namespace meta {
namespace meta_detail {
9232 template <
typename T>
9234 = decltype(sol_lua_check_access(
types<T>(),
static_cast<lua_State*
>(
nullptr), -1, std::declval<stack::record&>()));
9236 template <
typename T>
9239 template <
typename T>
9243 template <
typename T>
9246 template <
typename T>
9250 template <
typename T>
9255 template <
typename T>
9266 template <
typename T>
9268 using Tu = std::remove_cv_t<T>;
9269 if constexpr (meta::meta_detail::unique_usertype_is_null_with_state_v<Tu>) {
9277 template <
typename T>
9288 template <
typename T>
9290 using Tu = std::remove_cv_t<T>;
9291 if constexpr (meta::meta_detail::unique_usertype_get_with_state_v<Tu>) {
9300 namespace meta {
namespace meta_detail {
9301 template <
typename T,
typename Element =
void>
9304 template <
typename T,
typename Element =
void>
9307 template <
typename T,
typename Element =
void>
9310 template <
typename T,
typename Element,
bool = is_rebind_actual_type_v<T, Element>>
9313 template <
typename T,
typename Element>
9315 : std::integral_constant<bool, !std::is_void_v<typename T::template rebind_actual_type<Element>>> { };
9318 template <
typename T,
typename Element =
void>
9321 template <
typename T,
typename Element =
void>
9329 template <
typename... Args>
9331 template <
typename... Args>
9337 template <
typename... Args>
9343 static const auto& key =
"class_check";
9348 static const auto& key =
"class_cast";
9353 static const auto& key = u8
"\xF0\x9F\x8C\xB2.index";
9358 static const auto& key = u8
"\xF0\x9F\x8C\xB2.new_index";
9362 template <
typename T>
9370 template <
typename Base,
typename... Args>
9379 template <
typename... Bases>
9388 template <
typename Base,
typename... Args>
9392 :
static_cast<void*
>(
static_cast<Base*
>(
data));
9396 T*
data =
static_cast<T*
>(voiddata);
9400 template <
typename... Bases>
9402 T*
data =
static_cast<T*
>(voiddata);
9406 template <
typename U>
9411 template <
typename U,
typename Base,
typename... Args>
9414 using base_ptr =
typename uu_traits::template rebind_actual_type<Base>;
9416 if (base_ti == ti) {
9417 if (target_data !=
nullptr) {
9418 U*
source =
static_cast<U*
>(source_data);
9419 base_ptr* target =
static_cast<base_ptr*
>(target_data);
9425 return type_unique_cast_bases<U>(
types<Args...>(), source_data, target_data, ti);
9428 template <
typename U>
9430 if constexpr (is_actual_type_rebindable_for_v<U>) {
9434 if (rebind_ti != this_rebind_ti) {
9439 if (ti == this_ti) {
9443 return type_unique_cast_bases<U>(maybe_bases_or_empty(), source_data, target_data, ti);
9448 if (ti == this_ti) {
9452 return type_unique_cast_bases<U>(
types<>(), source_data, target_data, ti);
9456 template <
typename U,
typename... Bases>
9458 using uc_bases_t =
types<Bases...>;
9459 if constexpr (is_actual_type_rebindable_for_v<U>) {
9463 if (rebind_ti != this_rebind_ti) {
9468 if (ti == this_ti) {
9472 return type_unique_cast_bases<U>(cond_bases_t(), source_data, target_data, ti);
9477 if (ti == this_ti) {
9481 return type_unique_cast_bases<U>(
types<>(), source_data, target_data, ti);
9503 constexpr
const char*
not_a_number_integral =
"not a numeric type that fits exactly an integer (number maybe has significant decimals)";
9505 =
"not a numeric type or a numeric string that fits exactly an integer (e.g. number maybe has significant decimals)";
9519 aux_message +=
", ";
9531 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
9533 #endif // make sure stack doesn't overflow
9541 std::string tn(name,
static_cast<std::string::size_type
>(sz));
9552 const char* err = message.size() == 0
9553 ? (aux_message.size() == 0 ?
"stack index %d, expected %s, received %s" :
"stack index %d, expected %s, received %s: %s")
9554 :
"stack index %d, expected %s, received %s: %s %s";
9591 template <
typename F =
void>
9599 template <
typename R,
typename... Args>
9603 std::string aux_message =
"(bad argument into '";
9604 aux_message += detail::demangle<R>();
9608 aux_message +=
")')";
9625 type_error(L,
static_cast<int>(expected),
static_cast<int>(actual));
9629 if (expected !=
type::poly && expected != actual) {
9650 if (rightL ==
nullptr || leftL ==
nullptr || leftL == rightL) {
9655 return leftregistry == rightregistry;
9691 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
9692 luaL_checkstack(L_, 1,
"not enough Lua stack space to push a single reference value");
9693 #endif // make sure stack doesn't overflow
9712 int untyped_value =
lua_type(L_, stack_index());
9713 return static_cast<type>(untyped_value);
9717 type t = get_type(L);
9738 m_index =
right.m_index;
9772 int i = r.stack_index();
9774 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
9775 luaL_checkstack(L, 1,
"not enough Lua stack space to push a single reference value");
9776 #endif // make sure stack doesn't overflow
9789 return push(lua_state());
9834 return !lhs.
valid();
9838 return !rhs.
valid();
9868 return lhs.
equals(lua_state(), rhs);
9872 return rhs.
equals(lua_state(), lhs);
9876 return lhs.
equals(lua_state(), rhs);
9912 std::hash<const void*> h;
9913 return h(lhs.pointer(lua_state()));
9926 std::hash<const void*> h;
9927 return h(lhs.pointer());
9934 #include <functional>
9939 static const char name[9] =
"sol.\xF0\x9F\x93\x8C";
9952 if (rawindex == -count ||
top == rawindex) {
9954 lua_pop(L_,
static_cast<int>(count));
9965 int last =
index + count;
9966 for (
int i =
index; i < last; ++i) {
9982 template <
bool top_level>
10003 template <
bool,
typename T,
typename =
void>
10021 template <
typename T,
typename C>
10036 template <
typename T>
10044 return object_.stack_index();
10051 template <
bool,
typename T,
typename =
void>
10070 template <
typename T,
typename C>
10085 template <
typename T>
10094 return object_.stack_index();
10101 template <
bool top_level = false,
typename T>
10106 template <
bool top_level = false,
typename T>
10111 template <
typename T>
10113 int push_count = object_.push();
10118 template <
bool top_level = false>
10125 #if SOL_LUA_VERSION_I_ < 502
10127 return backup_if_unsupported_;
10133 return backup_if_unsupported_;
10136 return backup_if_unsupported_;
10141 #endif // Lua 5.2+ has the main thread unqualified_getter
10151 (
void)backup_if_unsupported;
10161 template <
bool o_main_only>
10196 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
10197 luaL_checkstack(L_, 1,
"not enough Lua stack space to push this reference value");
10198 #endif // make sure stack doesn't overflow
10219 if (r.ref ==
LUA_NOREF || L_ ==
nullptr) {
10223 ref = r.copy_ref(L_);
10231 if (r.ref ==
LUA_NOREF || L_ ==
nullptr) {
10240 if (L_ ==
nullptr || r.lua_state() ==
nullptr || r.get_type() ==
type::none) {
10259 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
10260 luaL_checkstack(L_, 1,
"not enough Lua stack space to push this reference value");
10261 #endif // make sure stack doesn't overflow
10290 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
10291 luaL_checkstack(L_, 1,
"not enough Lua stack space to push this reference value");
10292 #endif // make sure stack doesn't overflow
10314 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
10315 luaL_checkstack(L_, 1,
"not enough Lua stack space to push this reference value");
10316 #endif // make sure stack doesn't overflow
10336 return static_cast<type>(result);
10358 if (!
right.valid(L_)) {
10361 ref =
right.copy_ref(L_);
10380 template <
bool main_only = false>
10381 class basic_reference :
public stateless_reference {
10383 template <
bool o_main_only>
10387 template <
bool r_main_only>
10393 luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
10398 luastate = r.luastate;
10403 r.push(lua_state());
10407 luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
10408 ref = r.copy_ref();
10411 template <
bool r_main_only>
10417 luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
10422 luastate = r.luastate;
10427 r.push(lua_state());
10432 luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
10435 r.luastate =
nullptr;
10453 return copy_ref(lua_state());
10468 template <
bool r_main_only>
10474 if (r.ref ==
LUA_NOREF || lua_state() ==
nullptr) {
10479 r.push(lua_state());
10483 ref = r.copy_ref();
10486 template <
bool r_main_only>
10492 if (r.ref ==
LUA_NOREF || lua_state() ==
nullptr) {
10497 r.push(lua_state());
10503 r.luastate =
nullptr;
10507 if (lua_state() ==
nullptr || r.lua_state() ==
nullptr || r.get_type() ==
type::none) {
10515 if (lua_state() != r.lua_state() && !
detail::xmovable(lua_state(), r.lua_state())) {
10518 r.push(lua_state());
10523 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
10524 luaL_checkstack(L_, 1,
"not enough Lua stack space to push this reference value");
10525 #endif // make sure stack doesn't overflow
10537 if (lua_state() ==
nullptr || ref ==
LUA_NOREF)
10546 o.luastate =
nullptr;
10550 :
basic_reference(detail::pick_main_thread<main_only>(o.lua_state(), o.lua_state()), o) {
10555 o.luastate =
nullptr;
10565 copy_assign_complex(r);
10575 copy_assign_complex(r);
10584 template <
typename Super>
10587 template <
typename Super>
10591 return push(lua_state());
10596 luastate =
nullptr;
10600 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
10601 luaL_checkstack(L_, 1,
"not enough Lua stack space to push this reference value");
10602 #endif // make sure stack doesn't overflow
10603 if (lua_state() ==
nullptr) {
10608 if (L_ != lua_state()) {
10638 explicit operator bool() const noexcept {
10651 template <
bool lb,
bool rb>
10658 template <
bool lb,
bool rb>
10687 return !lhs.valid();
10692 return !rhs.valid();
10697 return lhs.valid();
10702 return rhs.valid();
10706 return l.registry_index() == r.registry_index();
10710 return l.registry_index() != r.registry_index();
10736 return rhs.equals(lua_state(), lhs);
10740 return lhs.equals(lua_state(), rhs);
10744 return lhs.equals(lua_state(), rhs);
10761 template <
bool lb,
bool rb>
10786 std::hash<const void*> h;
10787 return h(lhs.pointer(lua_state()));
10798 std::hash<const void*> h;
10799 return h(lhs.pointer());
10811 template <
typename T>
10815 template <
typename T>
10818 template <
typename T>
10819 struct is_tieable : std::integral_constant<bool, (::sol::tie_size<T>::value > 0)> { };
10821 template <
typename... Tn>
10822 struct tie_t :
public std::tuple<std::add_lvalue_reference_t<Tn>...> {
10824 typedef std::tuple<std::add_lvalue_reference_t<Tn>...>
base_t;
10826 template <
typename T>
10828 std::get<0>(*
this) = std::forward<T>(target);
10831 template <
typename T>
10835 typedef meta::conditional_t<(value_size::value < tie_size::value), value_size, tie_size> indices_size;
10836 typedef std::make_index_sequence<indices_size::value> indices;
10853 using base_t::base_t;
10855 template <
typename T>
10858 set(tieable(), std::forward<T>(value));
10863 template <
typename... Tn>
10866 namespace adl_barrier_detail {
10867 template <
typename... Tn>
10873 using namespace adl_barrier_detail;
10881 #include <functional>
10886 #if SOL_IS_ON(SOL_EXCEPTIONS)
10892 #endif // No Exceptions
10907 if (
top == bottom) {
10910 on_mismatch(
top, bottom);
10923 #include <forward_list>
10926 #include <algorithm>
10928 #include <optional>
10929 #include <type_traits>
10935 template <
typename T>
10937 template <
typename T>
10939 template <
typename T>
10941 template <
typename T>
10944 template <
typename Tag>
10948 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>;
10956 #if SOL_LUA_VERSION_I_ >= 504
10980 std::size_t space = (std::numeric_limits<std::size_t>::max)();
10984 template <
typename... Args>
10987 ((end =
align_one(
alignof(Args),
sizeof(Args), end)), ...);
10991 template <
typename... Args>
10993 static_assert(
sizeof...(Args) > 0);
10995 constexpr
std::size_t max_arg_alignment = (std::max)({
alignof(Args)... });
10996 if constexpr (max_arg_alignment <=
alignof(std::max_align_t)) {
11000 worst_required_size = (std::max)(worst_required_size, aligned_space_for<Args...>(
ptr));
11002 return worst_required_size;
11006 return (aligned_space_for<Args>(0x1) + ...);
11011 using use_align = std::integral_constant<bool,
11012 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11015 (std::alignment_of<void*>::value > 1)
11018 if (!use_align::value) {
11021 std::size_t space = (std::numeric_limits<std::size_t>::max)();
11022 return align(std::alignment_of<void*>::value,
ptr, space);
11025 template <
bool pre_aligned = false,
bool pre_shifted = false>
11027 using use_align = std::integral_constant<bool,
11028 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11031 (std::alignment_of<unique_destructor>::value > 1)
11034 if (!pre_aligned) {
11037 if (!pre_shifted) {
11038 ptr =
static_cast<void*
>(
static_cast<char*
>(
ptr) +
sizeof(
void*));
11040 if (!use_align::value) {
11041 return static_cast<void*
>(
static_cast<void**
>(
ptr) + 1);
11043 std::size_t space = (std::numeric_limits<std::size_t>::max)();
11044 return align(std::alignment_of<unique_destructor>::value,
ptr, space);
11047 template <
bool pre_aligned = false,
bool pre_shifted = false>
11049 using use_align = std::integral_constant<bool,
11050 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11053 (std::alignment_of<unique_tag>::value > 1)
11056 if (!pre_aligned) {
11059 if (!pre_shifted) {
11062 if (!use_align::value) {
11065 std::size_t space = (std::numeric_limits<std::size_t>::max)();
11066 return align(std::alignment_of<unique_tag>::value,
ptr, space);
11069 template <
typename T,
bool pre_aligned = false,
bool pre_shifted = false>
11071 typedef std::integral_constant<bool,
11072 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11075 (std::alignment_of_v<T> > 1)
11079 if (!pre_aligned) {
11082 if (!pre_shifted) {
11085 if (!use_align::value) {
11088 std::size_t space = (std::numeric_limits<std::size_t>::max)();
11089 return align(std::alignment_of_v<T>,
ptr, space);
11092 template <
typename T>
11094 typedef std::integral_constant<bool,
11095 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11098 (std::alignment_of_v<T> > 1)
11102 if (!use_align::value) {
11105 std::size_t space = (std::numeric_limits<std::size_t>::max)();
11106 return align(std::alignment_of_v<T>,
ptr, space);
11109 template <
typename T>
11111 typedef std::integral_constant<bool,
11112 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11115 (std::alignment_of<T*>::value > 1)
11119 if (!use_align::value) {
11121 return pointerpointer;
11123 constexpr
std::size_t initial_size = aligned_space_for<T*>();
11127 void* adjusted =
align(std::alignment_of<T*>::value, unadjusted, allocated_size);
11128 if (adjusted ==
nullptr) {
11133 luaL_error(L,
"cannot properly align memory for '%s'", detail::demangle<T*>().
data());
11135 return static_cast<T**
>(adjusted);
11139 std::size_t allocated_size,
void*& pointer_adjusted,
void*& data_adjusted) {
11141 pointer_adjusted =
align(ptr_align, adjusted, allocated_size);
11142 if (pointer_adjusted ==
nullptr) {
11147 allocated_size -= ptr_size;
11148 adjusted =
static_cast<void*
>(
static_cast<char*
>(pointer_adjusted) + ptr_size);
11149 data_adjusted =
align(value_align, adjusted, allocated_size);
11150 if (data_adjusted ==
nullptr) {
11158 std::size_t allocated_size,
void*& pointer_adjusted,
void*& dx_adjusted,
void*& id_adjusted,
void*& data_adjusted) {
11160 pointer_adjusted =
align(ptr_align, adjusted, allocated_size);
11161 if (pointer_adjusted ==
nullptr) {
11165 allocated_size -= ptr_size;
11167 adjusted =
static_cast<void*
>(
static_cast<char*
>(pointer_adjusted) + ptr_size);
11168 dx_adjusted =
align(std::alignment_of_v<unique_destructor>, adjusted, allocated_size);
11169 if (dx_adjusted ==
nullptr) {
11175 adjusted =
static_cast<void*
>(
static_cast<char*
>(dx_adjusted) +
sizeof(
unique_destructor));
11177 id_adjusted =
align(std::alignment_of_v<unique_tag>, adjusted, allocated_size);
11178 if (id_adjusted ==
nullptr) {
11184 adjusted =
static_cast<void*
>(
static_cast<char*
>(id_adjusted) +
sizeof(
unique_tag));
11185 data_adjusted =
align(real_align, adjusted, allocated_size);
11186 if (data_adjusted ==
nullptr) {
11193 template <
typename T>
11195 typedef std::integral_constant<bool,
11196 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11199 (std::alignment_of<T*>::value > 1 || std::alignment_of_v<T> > 1)
11203 if (!use_align::value) {
11204 T** pointerpointer =
static_cast<T**
>(
alloc_newuserdata(L,
sizeof(T*) +
sizeof(T)));
11205 T*& pointerreference = *pointerpointer;
11206 T* allocationtarget =
reinterpret_cast<T*
>(pointerpointer + 1);
11207 pointerreference = allocationtarget;
11208 return allocationtarget;
11211 constexpr
std::size_t initial_size = aligned_space_for<T*, T>();
11213 void* pointer_adjusted;
11214 void* data_adjusted;
11216 =
attempt_alloc(L, std::alignment_of_v<T*>,
sizeof(T*), std::alignment_of_v<T>, initial_size, pointer_adjusted, data_adjusted);
11218 if (pointer_adjusted ==
nullptr) {
11219 luaL_error(L,
"aligned allocation of userdata block (pointer section) for '%s' failed", detail::demangle<T>().c_str());
11222 luaL_error(L,
"aligned allocation of userdata block (data section) for '%s' failed", detail::demangle<T>().c_str());
11227 T** pointerpointer =
reinterpret_cast<T**
>(pointer_adjusted);
11228 T*& pointerreference = *pointerpointer;
11229 T* allocationtarget =
reinterpret_cast<T*
>(data_adjusted);
11230 pointerreference = allocationtarget;
11231 return allocationtarget;
11234 template <
typename T,
typename Real>
11236 typedef std::integral_constant<bool,
11237 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11240 (std::alignment_of<T*>::value > 1 || std::alignment_of<unique_tag>::value > 1 || std::alignment_of<unique_destructor>::value > 1
11241 || std::alignment_of<Real>::value > 1)
11245 if (!use_align::value) {
11248 id =
static_cast<unique_tag*
>(
static_cast<void*
>(dx + 1));
11249 Real* mem =
static_cast<Real*
>(
static_cast<void*
>(
id + 1));
11253 constexpr
std::size_t initial_size = aligned_space_for<T*, unique_destructor, unique_tag, Real>();
11255 void* pointer_adjusted;
11258 void* data_adjusted;
11260 std::alignment_of_v<T*>,
11262 std::alignment_of_v<Real>,
11269 if (pointer_adjusted ==
nullptr) {
11270 luaL_error(L,
"aligned allocation of userdata block (pointer section) for '%s' failed", detail::demangle<T>().c_str());
11272 else if (dx_adjusted ==
nullptr) {
11273 luaL_error(L,
"aligned allocation of userdata block (deleter section) for '%s' failed", detail::demangle<T>().c_str());
11276 luaL_error(L,
"aligned allocation of userdata block (data section) for '%s' failed", detail::demangle<T>().c_str());
11281 pref =
static_cast<T**
>(pointer_adjusted);
11284 Real* mem =
static_cast<Real*
>(data_adjusted);
11288 template <
typename T>
11290 typedef std::integral_constant<bool,
11291 #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
11294 (std::alignment_of_v<T> > 1)
11298 if (!use_align::value) {
11303 constexpr
std::size_t initial_size = aligned_space_for<T>();
11307 void* adjusted =
align(std::alignment_of_v<T>, unadjusted, allocated_size);
11308 if (adjusted ==
nullptr) {
11310 luaL_error(L,
"cannot properly align memory for '%s'", detail::demangle<T>().
data());
11312 return static_cast<T*
>(adjusted);
11315 template <
typename T>
11319 T** pdata =
static_cast<T**
>(
memory);
11322 std::allocator_traits<std::allocator<T>>::destroy(alloc,
data);
11326 template <
typename T>
11336 template <
typename T>
11339 void* aligned_memory = align_user<T>(
memory);
11340 T* typed_memory =
static_cast<T*
>(aligned_memory);
11342 std::allocator_traits<std::allocator<T>>::destroy(alloc, typed_memory);
11346 template <
typename T,
typename Real>
11348 void* aligned_memory = align_usertype_unique<Real, true>(
memory);
11349 Real* typed_memory =
static_cast<Real*
>(aligned_memory);
11351 std::allocator_traits<std::allocator<Real>>::destroy(alloc, typed_memory);
11354 template <
typename T>
11357 "cannot call the destructor for '%s': it is either hidden (protected/private) or removed with '= "
11358 "delete' and thusly this type is being destroyed without properly destroying, invoking undefined "
11359 "behavior: please bind a usertype and specify a custom destructor to define the behavior properly",
11360 detail::demangle<T>().
data());
11363 template <
typename T>
11367 template <
typename T,
typename Al>
11372 template <
typename T,
typename Tr,
typename Al>
11387 : times_through(times_through_), properties(properties_), enrollments(enrollments_) {
11391 bool p = properties[
static_cast<std::size_t>(mf)];
11392 if (times_through > 0) {
11422 registration_table[
index] =
luaL_Reg { to_string(meta_function_name_).c_str(), c_function_ };
11430 template <
typename T,
bool global = false,
bool raw = false,
typename =
void>
11432 template <
typename T,
typename P,
bool global = false,
bool raw = false,
typename =
void>
11435 template <
typename T,
bool global = false,
bool raw = false,
typename =
void>
11438 template <
typename T,
typename =
void>
11440 template <
typename T,
typename =
void>
11443 template <
typename T,
typename =
void>
11445 template <
typename T,
typename =
void>
11448 template <
typename T,
typename =
void>
11451 template <
typename T,
typename =
void>
11454 template <
typename T, type t,
typename =
void>
11456 template <
typename T, type t,
typename =
void>
11459 template <
typename T,
typename =
void>
11461 template <
typename T,
typename =
void>
11471 operator bool()
const {
11488 namespace stack_detail {
11489 template <
typename Function>
11491 template <
typename Function,
typename Handler>
11497 namespace meta {
namespace meta_detail {
11498 template <
typename T>
11501 template <
typename T>
11503 = decltype(sol_lua_interop_get(
types<T>(),
static_cast<lua_State*
>(
nullptr), -1,
static_cast<void*
>(
nullptr), std::declval<stack::record&>()));
11505 template <
typename T>
11508 template <
typename T>
11512 template <
typename T>
11516 template <
typename... Args>
11519 template <
typename T,
typename... Args>
11522 template <
typename T>
11525 template <
typename T>
11528 template <
typename T>
11531 template <
typename T>
11534 template <
typename T>
11537 template <
typename... Args>
11540 template <
typename T,
typename... Args>
11545 namespace stack_detail {
11555 template <
typename T>
11559 template <
typename T>
11563 template <
typename T>
11567 template <
typename T>
11571 template <
typename T>
11574 template <
typename C>
11576 return static_cast<int>(c.size());
11579 template <
typename V,
typename Al>
11582 return static_cast<int>(32);
11585 template <
typename T>
11588 if constexpr (meta::meta_detail::is_adl_sol_lua_get_v<Tu>) {
11597 template <
typename T>
11599 if constexpr (meta::meta_detail::is_adl_sol_lua_get_v<T>) {
11608 template <
typename T>
11611 if constexpr (meta::meta_detail::is_adl_sol_lua_interop_get_v<Tu>) {
11612 return sol_lua_interop_get(
types<Tu>(), L,
index, unadjusted_pointer, tracking);
11617 (
void)unadjusted_pointer;
11620 return std::pair<bool, Ti*> {
false,
nullptr };
11624 template <
typename T>
11626 if constexpr (meta::meta_detail::is_adl_sol_lua_interop_get_v<T>) {
11627 return sol_lua_interop_get(
types<T>(), L,
index, unadjusted_pointer, tracking);
11630 return unqualified_interop_get<T>(L,
index, unadjusted_pointer, tracking);
11634 template <
typename T,
typename Handler>
11637 if constexpr (meta::meta_detail::is_adl_sol_lua_interop_check_v<Tu>) {
11638 return sol_lua_interop_check(
types<Tu>(), L,
index, index_type, std::forward<Handler>(
handler), tracking);
11650 template <
typename T,
typename Handler>
11652 if constexpr (meta::meta_detail::is_adl_sol_lua_interop_check_v<T>) {
11653 return sol_lua_interop_check(
types<T>(), L,
index, index_type, std::forward<Handler>(
handler), tracking);
11656 return unqualified_interop_check<T>(L,
index, index_type, std::forward<Handler>(
handler), tracking);
11691 return ismainthread == 1;
11712 while (
lua_next(L, table_index) != 0) {
11725 auto pp = push_pop<false>(r);
11726 int stack_index = pp.index_of(r);
11737 clear(L_, stack_index);
11745 template <
typename T,
typename... Args>
11748 if constexpr (meta::meta_detail::is_adl_sol_lua_push_exact_v<T, T, Args...>) {
11749 return sol_lua_push(
types<T>(), L, std::forward<T>(t), std::forward<Args>(
args)...);
11751 else if constexpr (meta::meta_detail::is_adl_sol_lua_push_exact_v<Tu, T, Args...>) {
11752 return sol_lua_push(
types<Tu>(), L, std::forward<T>(t), std::forward<Args>(
args)...);
11754 else if constexpr (meta::meta_detail::is_adl_sol_lua_push_v<T, Args...>) {
11755 return sol_lua_push(L, std::forward<T>(t), std::forward<Args>(
args)...);
11759 return p.
push(L, std::forward<T>(t), std::forward<Args>(
args)...);
11764 template <
typename T,
typename Arg,
typename... Args,
typename = std::enable_if_t<!std::is_same<T, Arg>::value>>
11767 if constexpr (meta::meta_detail::is_adl_sol_lua_push_exact_v<T, Arg, Args...>) {
11768 return sol_lua_push(
types<T>(), L, std::forward<Arg>(
arg), std::forward<Args>(
args)...);
11770 else if constexpr (meta::meta_detail::is_adl_sol_lua_push_exact_v<Tu, Arg, Args...>) {
11771 return sol_lua_push(
types<Tu>(), L, std::forward<Arg>(
arg), std::forward<Args>(
args)...);
11773 else if constexpr (meta::meta_detail::is_adl_sol_lua_push_v<Arg, Args...> && !detail::is_tagged_v<Tu>) {
11774 return sol_lua_push(L, std::forward<Arg>(
arg), std::forward<Args>(
args)...);
11778 return p.
push(L, std::forward<Arg>(
arg), std::forward<Args>(
args)...);
11782 template <
typename T,
typename... Args>
11788 return stack::push<Tr>(L, std::forward<T>(t), std::forward<Args>(
args)...);
11791 template <
typename T,
typename Arg,
typename... Args>
11797 return stack::push<Tr>(L, std::forward<Arg>(
arg), std::forward<Args>(
args)...);
11800 namespace stack_detail {
11802 template <
typename T,
typename Arg,
typename... Args>
11805 using use_reference_tag =
11808 #if SOL_IS_OFF(SOL_FUNCTION_CALL_VALUE_SEMANTICS)
11809 , std::is_lvalue_reference<T>,
11817 return stack::push<Tr>(L, std::forward<Arg>(
arg), std::forward<Args>(
args)...);
11822 template <
typename T,
typename... Args>
11824 return stack_detail::push_reference<T>(L, std::forward<T>(t), std::forward<Args>(
args)...);
11827 template <
typename T,
typename Arg,
typename... Args>
11829 return stack_detail::push_reference<T>(L, std::forward<Arg>(
arg), std::forward<Args>(
args)...);
11837 template <
typename T,
typename... Args>
11839 int pushcount =
push(L, std::forward<T>(t));
11849 template <
typename T,
typename... Args>
11856 template <
typename T,
typename Handler>
11859 if constexpr (meta::meta_detail::is_adl_sol_lua_check_v<Tu>) {
11868 template <
typename T,
typename Handler>
11871 return unqualified_check<T>(L,
index, std::forward<Handler>(
handler), tracking);
11874 template <
typename T>
11880 template <
typename T,
typename Handler>
11882 if constexpr (meta::meta_detail::is_adl_sol_lua_check_v<T>) {
11892 template <
typename T,
typename Handler>
11895 return check<T>(L,
index, std::forward<Handler>(
handler), tracking);
11898 template <
typename T>
11904 template <
typename T,
typename Handler>
11908 return check<detail_t>(L,
index, std::forward<Handler>(
handler), tracking);
11911 template <
typename T,
typename Handler>
11915 return check<detail_t>(L,
index, std::forward<Handler>(
handler), tracking);
11918 template <
typename T,
typename Handler>
11921 return check_usertype<T>(L,
index, std::forward<Handler>(
handler), tracking);
11924 template <
typename T>
11930 template <
typename T,
typename Handler>
11933 if constexpr (meta::meta_detail::is_adl_sol_lua_check_get_v<T>) {
11936 else if constexpr (meta::meta_detail::is_adl_sol_lua_check_get_v<Tu>) {
11945 template <
typename T,
typename Handler>
11948 return unqualified_check_get<T>(L,
index,
handler, tracking);
11951 template <
typename T>
11957 template <
typename T,
typename Handler>
11959 if constexpr (meta::meta_detail::is_adl_sol_lua_check_get_v<T>) {
11968 template <
typename T,
typename Handler>
11974 template <
typename T>
11980 namespace stack_detail {
11982 template <
typename Handler>
11987 template <
typename T,
typename... Args,
typename Handler>
11989 if (!stack::check<T>(L, firstargument + tracking.
used,
handler, tracking))
11991 return check_types<Args...>(L, firstargument, std::forward<Handler>(
handler), tracking);
11994 template <
typename... Args,
typename Handler>
12001 template <
typename... Args,
typename Handler>
12006 template <
typename... Args,
typename Handler>
12012 template <
typename... Args>
12017 template <
typename T>
12019 #if SOL_IS_ON(SOL_SAFE_GETTER)
12020 static constexpr
bool is_op = meta::is_optional_v<T>;
12021 if constexpr (is_op) {
12022 return stack_detail::unchecked_unqualified_get<T>(L,
index, tracking);
12026 return stack_detail::unchecked_unqualified_get<T>(L,
index, tracking);
12032 return stack_detail::unchecked_unqualified_get<T>(L,
index, tracking);
12036 template <
typename T>
12039 return unqualified_get<T>(L,
index, tracking);
12042 template <
typename T>
12043 auto get(
lua_State* L,
int index,
record& tracking) -> decltype(stack_detail::unchecked_get<T>(L, index, tracking)) {
12044 #if SOL_IS_ON(SOL_SAFE_GETTER)
12045 static constexpr
bool is_op = meta::is_optional_v<T>;
12046 if constexpr (is_op) {
12047 return stack_detail::unchecked_get<T>(L,
index, tracking);
12051 return stack_detail::unchecked_get<T>(L,
index, tracking);
12057 return stack_detail::unchecked_get<T>(L,
index, tracking);
12061 template <
typename T>
12064 return get<T>(L,
index, tracking);
12067 template <
typename T>
12070 return get<UT>(L,
index, tracking);
12073 template <
typename T>
12076 return get_usertype<T>(L,
index, tracking);
12079 template <
typename T>
12084 template <
bool global = false,
bool raw = false,
typename Key>
12089 template <
bool global = false,
bool raw = false,
typename Key>
12094 template <
bool global = false,
typename Key>
12096 get_field<global, true>(L, std::forward<Key>(key));
12099 template <
bool global = false,
typename Key>
12101 get_field<global, true>(L, std::forward<Key>(key), tableindex);
12104 template <
bool global = false,
bool raw = false,
typename C = detail::non_lua_nil_t,
typename Key>
12109 template <
bool global = false,
bool raw = false,
typename C = detail::non_lua_nil_t,
typename Key>
12114 template <
bool global = false,
typename C = detail::non_lua_nil_t,
typename Key>
12116 return probe_get_field<global, true, C>(L, std::forward<Key>(key));
12119 template <
bool global = false,
typename C = detail::non_lua_nil_t,
typename Key>
12121 return probe_get_field<global, true, C>(L, std::forward<Key>(key), tableindex);
12124 template <
bool global = false,
bool raw = false,
typename Key,
typename Value>
12129 template <
bool global = false,
bool raw = false,
typename Key,
typename Value>
12134 template <
bool global = false,
typename Key,
typename Value>
12136 set_field<global, true>(L, std::forward<Key>(key), std::forward<Value>(value));
12139 template <
bool global = false,
typename Key,
typename Value>
12141 set_field<global, true>(L, std::forward<Key>(key), std::forward<Value>(value), tableindex);
12144 template <
typename T,
typename F>
12148 void* uu_memory = detail::align_usertype_unique<T>(raw);
12149 T& uu = *
static_cast<T*
>(uu_memory);
12154 template <
typename F>
12157 using T =
typename bt::template arg_at<0>;
12159 modify_unique_usertype_as<Tu>(obj, std::forward<F>(
f));
12162 namespace stack_detail {
12163 template <
typename T,
typename Handler>
12165 if constexpr (meta::meta_detail::is_adl_sol_lua_check_access_v<T>) {
12168 return check_get<T>(L_, index_, std::forward<Handler>(handler_), tracking_);
12171 template <
typename T>
12173 if constexpr (meta::meta_detail::is_adl_sol_lua_check_access_v<T>) {
12176 return unchecked_get<T>(L_, index_, tracking_);
12184 template <
typename T>
12186 if constexpr (is_unique_usertype_v<T>) {
12187 return &unique_destroy<T>;
12189 else if constexpr (!std::is_pointer_v<T>) {
12190 return &usertype_alloc_destroy<T>;
12193 return &cannot_destroy<T>;
12197 template <
typename T>
12199 return &cannot_destroy<T>;
12202 template <
typename T>
12204 return make_destructor<T>(std::is_destructible<T>());
12208 template <
typename A,
typename B>
12214 template <
typename T>
12219 template <
typename T>
12221 decltype(
auto) ts = stack::get<T>(L, 1).to_string();
12222 return stack::push(L, std::forward<decltype(ts)>(ts));
12225 template <
typename T>
12228 "cannot perform to_string on '%s': no 'to_string' overload in namespace, 'to_string' member "
12229 "function, or operator<<(ostream&, ...) present",
12230 detail::demangle<T>().
data());
12233 template <
typename T>
12235 using namespace std;
12236 decltype(
auto) ts = to_string(stack::get<T>(L, 1));
12237 return stack::push(L, std::forward<decltype(ts)>(ts));
12240 template <
typename T>
12245 template <
typename T>
12247 std::ostringstream oss;
12248 oss << stack::unqualified_get<T>(L, 1);
12252 template <
typename T>
12257 template <
typename T>
12262 template <
typename T>
12264 decltype(
auto)
self = stack::unqualified_get<T>(L, 1);
12268 template <
typename T,
typename Op>
12270 if constexpr (std::is_void_v<T>) {
12274 auto maybel = stack::unqualified_check_get<T>(L, 1);
12278 auto mayber = stack::unqualified_check_get<T>(L, 2);
12282 decltype(
auto) l = *maybel;
12283 decltype(
auto) r = *mayber;
12284 if constexpr (std::is_same_v<no_comp, Op>) {
12285 std::equal_to<>
op;
12289 if constexpr (std::is_same_v<std::equal_to<>, Op>
12290 || std::is_same_v<std::less_equal<>, Op>
12291 || std::is_same_v<std::less_equal<>, Op>) {
12302 template <
typename T,
typename IFx,
typename Fx>
12305 template <
typename T,
bool,
bool>
12308 template <
typename T>
12310 :
meta::neg<std::is_reference<decltype(sol_lua_get(types<T>(), nullptr, -1, std::declval<stack::record&>()))>> { };
12312 template <
typename T>
12314 :
meta::neg<std::is_reference<decltype(sol_lua_get(types<meta::unqualified_t<T>>(), nullptr, -1, std::declval<stack::record&>()))>> { };
12316 template <
typename T>
12321 template <
typename T>
12323 :
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>>> { };
12334 #include <functional>
12337 #include <optional>
12338 #if SOL_IS_ON(SOL_STD_VARIANT)
12340 #endif // variant shenanigans
12342 namespace sol {
namespace stack {
12343 template <
typename Handler>
12357 namespace stack_detail {
12363 lua_pop(L_, 1 +
static_cast<int>(poptable));
12371 template <
typename T,
bool poptable = true>
12376 template <type expected,
int (*check_func)(lua_State*,
int)>
12378 template <
typename Handler>
12381 bool success = check_func(L_,
index) == 1;
12391 template <
typename T,
typename>
12393 template <
typename Handler>
12399 template <
typename T,
typename>
12401 template <
typename Handler>
12403 return stack_detail::unqualified_interop_check<T>(L_,
index, index_type, std::forward<Handler>(
handler), tracking);
12407 template <
typename T, type expected,
typename>
12408 struct unqualified_checker {
12409 template <
typename Handler>
12411 if constexpr (std::is_same_v<T, bool>) {
12429 return stack::check<std::basic_string<T>>(L_,
index, std::forward<Handler>(
handler), tracking);
12431 else if constexpr (std::is_integral_v<T> || std::is_same_v<T, lua_Integer>) {
12433 #if SOL_LUA_VERSION_I_ >= 503
12435 #if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS)
12439 const bool success = isnum != 0;
12444 #elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
12449 const bool success =
false;
12466 #if SOL_IS_OFF(SOL_STRINGS_ARE_NUMBERS)
12474 #endif // Do not allow strings to be numbers
12476 #if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
12479 const bool success = isnum != 0 &&
static_cast<lua_Number>(llround(v)) == v;
12481 const bool success =
true;
12482 #endif // Safe numerics and number precision checking
12485 #if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS)
12487 #elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
12496 else if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, lua_Number>) {
12498 #if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS)
12513 #endif // Strings are Numbers
12515 else if constexpr (meta::any_same_v<T, type, this_state, this_main_state, this_environment, variadic_args>) {
12522 else if constexpr (is_unique_usertype_v<T>) {
12539 bool success = &detail::usertype_unique_alloc_destroy<element, actual> == pdx;
12541 memory = detail::align_usertype_unique_tag<true>(
memory);
12545 const char*& name_tag = *
static_cast<const char**
>(
memory);
12558 else if constexpr (meta::any_same_v<T, lua_nil_t, std::nullopt_t, nullopt_t>) {
12572 else if constexpr (std::is_same_v<T, env_key_t>) {
12581 else if constexpr (std::is_same_v<T, detail::non_lua_nil_t>) {
12582 return !stack::unqualified_check<lua_nil_t>(L_,
index, std::forward<Handler>(
handler), tracking);
12584 else if constexpr (meta::is_specialization_of_v<T, basic_lua_table>) {
12593 else if constexpr (meta::is_specialization_of_v<T, basic_bytecode>) {
12602 else if constexpr (meta::is_specialization_of_v<T, basic_environment>) {
12619 else if constexpr (std::is_same_v<T, metatable_key_t>) {
12631 handler(L_,
index, expected, t,
"value does not have a valid metatable");
12636 else if constexpr (std::is_same_v<T, luaL_Stream*> || std::is_same_v<T, luaL_Stream>) {
12639 handler(L_,
index, expected, t,
"value is not a valid luaL_Stream (has no metatable/is not a valid value)");
12650 "value is not a valid luaL_Stream (there is no metatable for luaL_Stream -- did you forget to "
12651 "my_lua_state.open_libraries(sol::lib::state) or equivalent?)");
12656 if (is_stream_table == 0) {
12658 handler(L_,
index, expected, t,
"value is not a valid luaL_Stream (incorrect metatable)");
12663 else if constexpr (meta::is_optional_v<T>) {
12664 using ValueType =
typename T::value_type;
12675 return stack::unqualified_check<ValueType>(L_,
index, &
no_panic, tracking);
12677 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
12678 else if constexpr (std::is_function_v<T> || (std::is_pointer_v<T> && std::is_function_v<std::remove_pointer_t<T>>)) {
12679 return stack_detail::check_function_pointer<std::remove_pointer_t<T>>(L_,
index, std::forward<Handler>(
handler), tracking);
12683 if constexpr (meta::any_same_v<T, userdata_value> || meta::is_specialization_of_v<T, basic_userdata>) {
12693 else if constexpr (meta::is_specialization_of_v<T, user>) {
12696 return c.check(L_,
index, std::forward<Handler>(
handler), tracking);
12699 if constexpr (std::is_pointer_v<T>) {
12700 return check_usertype<T>(L_,
index, std::forward<Handler>(
handler), tracking);
12702 else if constexpr (meta::is_specialization_of_v<T, std::reference_wrapper>) {
12703 using T_internal =
typename T::type;
12704 return stack::check<T_internal>(L_,
index, std::forward<Handler>(
handler), tracking);
12707 return check_usertype<T>(L_,
index, std::forward<Handler>(
handler), tracking);
12711 else if constexpr (expected ==
type::poly) {
12766 handler(L_,
index,
type::function, t,
"value's metatable does not have __call overridden in metatable, cannot call this type");
12780 bool success = expected == indextype;
12790 template <
typename T>
12793 template <
typename T>
12795 template <
typename Handler>
12801 template <
typename U,
typename Handler>
12805 lightuserdata_value> || std::is_same_v<T, userdata_value> || std::is_same_v<T, userdata> || std::is_same_v<T, lightuserdata>) {
12814 #if SOL_IS_ON(SOL_USE_INTEROP)
12815 if (stack_detail::interop_check<U>(L_,
index, indextype,
handler, tracking)) {
12818 #endif // interop extensibility
12820 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
12834 if (stack_detail::check_metatable<U>(L_, metatableindex))
12836 if (stack_detail::check_metatable<U*>(L_, metatableindex))
12842 bool success =
false;
12845 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
12847 #endif // make sure stack doesn't overflow
12867 template <
typename T>
12869 template <
typename Handler>
12875 return check_usertype<std::remove_pointer_t<T>>(L_,
index, std::forward<Handler>(
handler), tracking);
12878 template <
typename Handler>
12885 template <
typename... Args>
12887 template <
typename Handler>
12893 template <
typename A,
typename B>
12895 template <
typename Handler>
12897 return stack::multi_check<A, B>(L_,
index, std::forward<Handler>(
handler), tracking);
12901 #if SOL_IS_ON(SOL_STD_VARIANT)
12903 template <
typename... Tn>
12905 typedef std::variant<Tn...>
V;
12909 template <
typename Handler>
12911 if constexpr (V_is_empty::value) {
12921 template <std::
size_t I,
typename Handler>
12923 typedef std::variant_alternative_t<I - 1,
V> T;
12924 record temp_tracking = tracking;
12925 if (stack::check<T>(L_,
index, &
no_panic, temp_tracking)) {
12926 tracking = temp_tracking;
12929 return is_one(std::integral_constant<std::size_t, I - 1>(), L_,
index, std::forward<Handler>(
handler), tracking);
12932 template <
typename Handler>
12934 return is_one(std::integral_constant<std::size_t, V_size::value>(), L_,
index, std::forward<Handler>(
handler), tracking);
12938 #endif // variant shenanigans
12946 namespace sol {
namespace stack {
12948 template <
typename X, type expected,
typename>
12949 struct qualified_checker {
12950 template <
typename Handler>
12953 if constexpr (!std::is_reference_v<X> && is_unique_usertype_v<no_cv_X>) {
12955 if constexpr (is_actual_type_rebindable_for_v<no_cv_X>) {
12968 if (&detail::usertype_unique_alloc_destroy<element, no_cv_X> == pdx) {
12972 memory = detail::align_usertype_unique_tag<true, false>(
memory);
12976 if (ic(
nullptr,
nullptr, ti, rebind_ti) != 0) {
12984 return stack::unqualified_check<X>(L,
index, std::forward<Handler>(
handler), tracking);
12987 else if constexpr (!std::is_reference_v<X> && is_container_v<no_cv_X>) {
12989 return stack::unqualified_check<X>(L,
index, std::forward<Handler>(
handler), tracking);
12992 return stack::unqualified_check<nested<X>>(L,
index, std::forward<Handler>(
handler), tracking);
12995 else if constexpr (!std::is_reference_v<X> && meta::is_specialization_of_v<X, nested>) {
12997 return stack::check<NestedX>(L,
index, ::std::forward<Handler>(
handler), tracking);
13000 return stack::unqualified_check<X>(L,
index, std::forward<Handler>(
handler), tracking);
13019 template <
typename... Functions>
13031 template <
typename... Args>
13047 namespace unicode {
13050 invalid_code_point,
13060 "invalid code points",
13061 "invalid code unit",
13062 "invalid leading surrogate",
13063 "invalid trailing surrogate",
13064 "sequence too short",
13065 "overlong sequence" };
13069 template <
typename It>
13076 template <
typename C>
13085 static constexpr char32_t last_code_point = 0x10FFFF;
13087 static constexpr char32_t first_lead_surrogate = 0xD800;
13088 static constexpr char32_t last_lead_surrogate = 0xDBFF;
13090 static constexpr char32_t first_trail_surrogate = 0xDC00;
13091 static constexpr char32_t last_trail_surrogate = 0xDFFF;
13093 static constexpr char32_t first_surrogate = first_lead_surrogate;
13094 static constexpr char32_t last_surrogate = last_trail_surrogate;
13097 return u >= first_lead_surrogate && u <= last_lead_surrogate;
13100 return u >= first_trail_surrogate && u <= last_trail_surrogate;
13103 return u >= first_surrogate && u <= last_surrogate;
13107 static constexpr
auto last_1byte_value = 0x7Fu;
13108 static constexpr
auto last_2byte_value = 0x7FFu;
13109 static constexpr
auto last_3byte_value = 0xFFFFu;
13111 static constexpr
auto start_2byte_mask = 0x80u;
13112 static constexpr
auto start_3byte_mask = 0xE0u;
13113 static constexpr
auto start_4byte_mask = 0xF0u;
13115 static constexpr
auto continuation_mask = 0xC0u;
13116 static constexpr
auto continuation_signature = 0x80u;
13119 return b == 0xC0 || b == 0xC1 || b > 0xF4;
13123 return (b & unicode_detail::continuation_mask) == unicode_detail::continuation_signature;
13127 return u <= unicode_detail::last_1byte_value || (u <= unicode_detail::last_2byte_value && bytes > 2)
13128 || (u <= unicode_detail::last_3byte_value && bytes > 3);
13132 return (b & start_2byte_mask) == 0 ? 1
13133 : (b & start_3byte_mask) != start_3byte_mask ? 2
13134 : (b & start_4byte_mask) != start_4byte_mask ? 3
13138 static constexpr char32_t
decode(
unsigned char b0,
unsigned char b1) {
13139 return (
static_cast<char32_t
>((b0 & 0x1Fu) << 6u) |
static_cast<char32_t
>(b1 & 0x3Fu));
13141 static constexpr char32_t
decode(
unsigned char b0,
unsigned char b1,
unsigned char b2) {
13142 return static_cast<char32_t
>((b0 & 0x0Fu) << 12u) |
static_cast<char32_t
>((b1 & 0x3Fu) << 6u) |
static_cast<char32_t
>(b2 & 0x3Fu);
13144 static constexpr char32_t
decode(
unsigned char b0,
unsigned char b1,
unsigned char b2,
unsigned char b3) {
13145 return static_cast<char32_t
>(
static_cast<char32_t
>((b0 & 0x07u) << 18u) |
static_cast<char32_t
>((b1 & 0x3F) << 12)
13146 |
static_cast<char32_t
>((b2 & 0x3Fu) << 6u) |
static_cast<char32_t
>(b3 & 0x3Fu));
13150 static constexpr char32_t last_bmp_value = 0xFFFF;
13151 static constexpr char32_t normalizing_value = 0x10000;
13152 static constexpr
int lead_surrogate_bitmask = 0xFFC00;
13153 static constexpr
int trail_surrogate_bitmask = 0x3FF;
13154 static constexpr
int lead_shifted_bits = 10;
13155 static constexpr char32_t replacement = 0xFFFD;
13158 auto hi = lead - first_lead_surrogate;
13159 auto lo = trail - first_trail_surrogate;
13160 return normalizing_value + ((hi << lead_shifted_bits) | lo);
13166 er.
error = error_code::ok;
13167 if (
codepoint <= unicode_detail::last_1byte_value) {
13171 else if (
codepoint <= unicode_detail::last_2byte_value) {
13174 static_cast<char>(0xC0 | ((
codepoint & 0x7C0) >> 6)),
13175 static_cast<char>(0x80 | (
codepoint & 0x3F)),
13178 else if (
codepoint <= unicode_detail::last_3byte_value) {
13181 static_cast<char>(0xE0 | ((
codepoint & 0xF000) >> 12)),
13182 static_cast<char>(0x80 | ((
codepoint & 0xFC0) >> 6)),
13183 static_cast<char>(0x80 | (
codepoint & 0x3F)),
13189 static_cast<char>(0xF0 | ((
codepoint & 0x1C0000) >> 18)),
13190 static_cast<char>(0x80 | ((
codepoint & 0x3F000) >> 12)),
13191 static_cast<char>(0x80 | ((
codepoint & 0xFC0) >> 6)),
13192 static_cast<char>(0x80 | (
codepoint & 0x3F)),
13201 if (
codepoint <= unicode_detail::last_bmp_value) {
13204 er.
error = error_code::ok;
13207 auto normal =
codepoint - unicode_detail::normalizing_value;
13208 auto lead = unicode_detail::first_lead_surrogate + ((normal & unicode_detail::lead_surrogate_bitmask) >> unicode_detail::lead_shifted_bits);
13209 auto trail = unicode_detail::first_trail_surrogate + (normal & unicode_detail::trail_surrogate_bitmask);
13210 er.
code_units = std::array<char16_t, 4> { {
static_cast<char16_t
>(lead),
static_cast<char16_t
>(trail) } };
13212 er.
error = error_code::ok;
13221 er.
error = error_code::ok;
13225 template <
typename It>
13230 dr.
error = error_code::sequence_too_short;
13234 unsigned char b0 =
static_cast<unsigned char>(*it);
13238 dr.
codepoint =
static_cast<char32_t
>(b0);
13239 dr.
error = error_code::ok;
13245 if (unicode_detail::is_invalid(b0) || unicode_detail::is_continuation(b0)) {
13246 dr.
error = error_code::invalid_code_unit;
13252 std::array<unsigned char, 4> b;
13255 b[i] =
static_cast<unsigned char>(*it);
13256 if (!unicode_detail::is_continuation(b[i])) {
13257 dr.
error = error_code::invalid_code_unit;
13267 decoded = unicode_detail::decode(b[0], b[1]);
13270 decoded = unicode_detail::decode(b[0], b[1], b[2]);
13273 decoded = unicode_detail::decode(b[0], b[1], b[2], b[3]);
13277 if (unicode_detail::is_overlong(decoded,
length)) {
13278 dr.
error = error_code::overlong_sequence;
13281 if (unicode_detail::is_surrogate(decoded) || decoded > unicode_detail::last_code_point) {
13288 dr.
error = error_code::ok;
13293 template <
typename It>
13298 dr.
error = error_code::sequence_too_short;
13302 char16_t lead =
static_cast<char16_t
>(*it);
13304 if (!unicode_detail::is_surrogate(lead)) {
13306 dr.
codepoint =
static_cast<char32_t
>(lead);
13308 dr.
error = error_code::ok;
13311 if (!unicode_detail::is_lead_surrogate(lead)) {
13312 dr.
error = error_code::invalid_leading_surrogate;
13319 if (!unicode_detail::is_trail_surrogate(trail)) {
13320 dr.
error = error_code::invalid_trailing_surrogate;
13325 dr.
codepoint = unicode_detail::combine_surrogates(lead, trail);
13327 dr.
error = error_code::ok;
13331 template <
typename It>
13336 dr.
error = error_code::sequence_too_short;
13339 dr.
codepoint =
static_cast<char32_t
>(*it);
13341 dr.
error = error_code::ok;
13349 #include <functional>
13353 #include <string_view>
13354 #if SOL_IS_ON(SOL_STD_VARIANT)
13356 #endif // Apple clang screwed up
13358 namespace sol {
namespace stack {
13360 namespace stack_detail {
13361 template <
typename Ch>
13373 template <
typename Ch,
typename ErCh>
13386 template <
typename Ch,
typename F>
13387 inline void convert(
const char* strb,
const char* stre, F&& f) {
13389 for (
const char* strtarget = strb; strtarget < stre;) {
13397 strtarget = dr.next;
13399 if constexpr (std::is_same_v<Ch, char32_t>) {
13410 template <
typename BaseCh,
typename S>
13412 using Ch =
typename S::value_type;
13418 const char* strb = utf8p;
13419 const char* stre = utf8p + len;
13421 convert<BaseCh>(strb, stre, count_units);
13424 Ch* target = &r[0];
13426 convert<BaseCh>(strb, stre, copy_units);
13431 template <
typename T,
typename>
13432 struct unqualified_getter {
13434 if constexpr (std::is_same_v<T, bool>) {
13438 else if constexpr (std::is_enum_v<T>) {
13442 else if constexpr (std::is_integral_v<T> || std::is_same_v<T, lua_Integer>) {
13444 #if SOL_LUA_VERSION_I_ >= 503
13451 else if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, lua_Number>) {
13455 else if constexpr (is_lua_reference_v<T>) {
13456 if constexpr (is_global_table_v<T>) {
13462 return T(L,
index);
13465 else if constexpr (is_unique_usertype_v<T>) {
13470 void* aligned_memory = detail::align_usertype_unique<actual>(
memory);
13471 actual* typed_memory =
static_cast<actual*
>(aligned_memory);
13472 return *typed_memory;
13474 else if constexpr (meta::is_optional_v<T>) {
13475 using ValueType =
typename T::value_type;
13478 else if constexpr (std::is_same_v<T, luaL_Stream*>) {
13482 else if constexpr (std::is_same_v<T, luaL_Stream>) {
13486 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
13487 else if constexpr (std::is_function_v<T> || (std::is_pointer_v<T> && std::is_function_v<std::remove_pointer_t<T>>)) {
13488 return stack_detail::get_function_pointer<std::remove_pointer_t<T>>(L,
index, tracking);
13492 return stack_detail::unchecked_unqualified_get<detail::as_value_tag<T>>(L,
index, tracking);
13497 template <
typename X,
typename>
13498 struct qualified_getter {
13501 static constexpr
bool is_userdata_of_some_kind
13502 = !std::is_reference_v<
13503 X> && is_container_v<Tu> && std::is_default_constructible_v<Tu> && !is_lua_primitive_v<Tu> && !is_transparent_argument_v<Tu>;
13504 if constexpr (is_userdata_of_some_kind) {
13506 return static_cast<Tu
>(stack_detail::unchecked_unqualified_get<Tu>(L,
index, tracking));
13509 return stack_detail::unchecked_unqualified_get<sol::nested<Tu>>(L,
index, tracking);
13512 else if constexpr (!std::is_reference_v<X> && is_unique_usertype_v<Tu> && !is_actual_type_rebindable_for_v<Tu>) {
13519 if (&detail::usertype_unique_alloc_destroy<element, Tu> == pdx) {
13520 memory = detail::align_usertype_unique_tag<true, false>(
memory);
13521 memory = detail::align_usertype_unique<actual, true, false>(
memory);
13522 actual* mem =
static_cast<actual*
>(
memory);
13523 return static_cast<actual
>(*mem);
13527 #if SOL_IS_ON(SOL_DEBUG_BUILD)
13532 return static_cast<actual
>(
std::move(r));
13535 memory = detail::align_usertype_unique_tag<true, false>(
memory);
13537 memory = detail::align_usertype_unique<actual, true, false>(
memory);
13539 int cast_operation;
13540 if constexpr (is_actual_type_rebindable_for_v<Tu>) {
13543 cast_operation = ic(
memory, &r, ti, rebind_ti);
13547 cast_operation = ic(
memory, &r, ti, rebind_ti);
13549 switch (cast_operation) {
13553 actual* mem =
static_cast<actual*
>(
memory);
13554 return static_cast<actual
>(*mem);
13559 return static_cast<actual
>(
std::move(r));
13564 #if SOL_IS_ON(SOL_DEBUG_BUILD)
13569 return static_cast<actual
>(r);
13573 return stack_detail::unchecked_unqualified_get<Tu>(L,
index, tracking);
13578 template <
typename T>
13582 template <
typename V>
13587 template <
typename V>
13592 template <
typename V>
13598 template <
typename V>
13608 return idx >= cont.max_size();
13616 typedef typename Tu::value_type V;
13620 template <
typename V>
13661 #if SOL_LUA_VERSION_I_ >= 503
13670 bool isnil =
false;
13671 for (
int vi = 0; vi < lua_size<V>::value; ++vi) {
13672 #if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES) && SOL_LUA_VERSION_I_ >= 600
13673 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
13675 #endif // make sure stack doesn't overflow
13677 if (lua_keyin(L,
index) == 0) {
13693 #if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES) && SOL_LUA_VERSION_I_ >= 600
13703 #if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES) && SOL_LUA_VERSION_I_ >= 600
13717 if (idx >= cont.max_size()) {
13721 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
13723 #endif // make sure stack doesn't overflow
13724 bool isnil =
false;
13725 for (
int vi = 0; vi < lua_size<V>::value; ++vi) {
13750 typedef typename Tu::value_type P;
13751 typedef typename P::first_type K;
13752 typedef typename P::second_type V;
13756 template <
typename K,
typename V>
13760 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
13762 #endif // make sure stack doesn't overflow
13768 decltype(
auto) key = stack::check_get<K>(L, -2);
13773 associative.emplace(std::forward<decltype(*key)>(*key), stack::get<V>(L, -1));
13776 return associative;
13780 template <
typename T,
typename Al>
13782 typedef std::forward_list<T, Al>
C;
13789 typedef typename T::value_type P;
13790 typedef typename P::first_type K;
13791 typedef typename P::second_type V;
13796 typedef typename C::value_type V;
13800 template <
typename V>
13803 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
13805 #endif // make sure stack doesn't overflow
13809 auto at = cont.cbefore_begin();
13811 #if SOL_LUA_VERSION_I_ >= 503
13814 if (idx >= cont.max_size()) {
13817 bool isnil =
false;
13818 for (
int vi = 0; vi < lua_size<V>::value; ++vi) {
13837 if (idx >= cont.max_size()) {
13840 bool isnil =
false;
13841 for (
int vi = 0; vi < lua_size<V>::value; ++vi) {
13864 template <
typename K,
typename V>
13868 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
13870 #endif // make sure stack doesn't overflow
13873 auto at = associative.cbefore_begin();
13877 decltype(
auto) key = stack::check_get<K>(L, -2);
13882 at = associative.emplace_after(at, std::forward<decltype(*key)>(*key), stack::get<V>(L, -1));
13885 return associative;
13889 template <
typename T>
13893 if constexpr (is_container_v<Tu>) {
13895 typedef typename T::value_type P;
13896 typedef typename P::first_type K;
13897 typedef typename P::second_type V;
13902 typedef typename T::value_type V;
13914 template <
typename T>
13917 return stack::unqualified_get<T>(L,
index, tracking);
13921 template <
typename T>
13924 return stack::unqualified_get<T*>(L,
index, tracking);
13944 template <
typename T>
13953 template <
typename T>
13959 return *
static_cast<std::remove_reference_t<T>*
>(
memory);
13963 template <
typename T>
13969 return static_cast<T*
>(
memory);
13987 return std::string(str, len);
14006 return len > 0 ? str[0] :
'\0';
14010 template <
typename Traits>
14020 template <
typename Traits,
typename Al>
14022 using S = std::basic_string<wchar_t, Traits, Al>;
14025 return stack_detail::get_into<Ch, S>(L,
index, tracking);
14029 template <
typename Traits,
typename Al>
14032 return stack_detail::get_into<char16_t, std::basic_string<char16_t, Traits, Al>>(L,
index, tracking);
14036 template <
typename Traits,
typename Al>
14039 return stack_detail::get_into<char32_t, std::basic_string<char32_t, Traits, Al>>(L,
index, tracking);
14047 const char* strb =
utf8.data();
14048 const char* stre =
utf8.data() +
utf8.size();
14058 return er.code_units[0];
14066 const char* strb =
utf8.data();
14067 const char* stre =
utf8.data() +
utf8.size();
14077 return er.code_units[0];
14087 auto c = g.
get(L,
index, tracking);
14088 return static_cast<wchar_t>(c);
14099 if (mfnames[i] == name)
14167 if (err ==
nullptr) {
14190 template <
typename T>
14194 #if SOL_IS_ON(SOL_USE_INTEROP)
14195 auto ugr = stack_detail::interop_get<T>(L,
index,
memory, tracking);
14199 #endif // interop extensibility
14202 void** pudata =
static_cast<void**
>(rawdata);
14203 void* udata = *pudata;
14204 return get_no_lua_nil_from(L, udata,
index, tracking);
14221 if constexpr (std::is_function_v<T>) {
14222 T* func =
reinterpret_cast<T*
>(udata);
14226 T* obj =
static_cast<T*
>(udata);
14232 return *get_no_lua_nil(L,
index, tracking);
14236 template <
typename T>
14245 return g.get_no_lua_nil(L,
index, tracking);
14249 template <
typename T>
14253 return g.get_no_lua_nil(L,
index, tracking);
14257 template <
typename T>
14265 template <
typename T>
14273 template <
typename T>
14276 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
14277 if constexpr (std::is_function_v<T>) {
14278 return stack_detail::get_function_pointer<T>(L,
index, tracking);
14291 template <
typename... Tn>
14293 typedef std::tuple<decltype(stack::get<Tn>(
nullptr, 0))...>
R;
14295 template <
typename... Args>
14298 return R { std::forward<Args>(
args)... };
14305 return apply(std::index_sequence<Ix...>(), L,
index, tracking, std::forward<Args>(
args)..., stack::get<T>(L,
index + tracking.
used, tracking));
14313 template <
typename A,
typename B>
14316 return std::pair<decltype(stack::get<A>(L,
index)), decltype(stack::get<B>(L,
index))> { stack::get<A>(L,
index, tracking),
14317 stack::get<B>(L,
index + tracking.used, tracking) };
14321 #if SOL_IS_ON(SOL_STD_VARIANT)
14323 template <
typename... Tn>
14325 using V = std::variant<Tn...>;
14331 if constexpr (std::variant_size_v<V> == 0) {
14341 template <std::
size_t I>
14343 typedef std::variant_alternative_t<I, V> T;
14344 record temp_tracking = tracking;
14346 tracking = temp_tracking;
14347 return V(std::in_place_index<I>, stack::get<T>(L,
index));
14349 return get_one(std::integral_constant<std::size_t, I + 1>(), L,
index, tracking);
14353 return get_one(std::integral_constant<std::size_t, 0>(), L,
index, tracking);
14364 namespace sol {
namespace stack {
14382 #include <optional>
14383 #if SOL_IS_ON(SOL_STD_VARIANT)
14385 #endif // variant shenanigans (thanks, Mac OSX)
14387 namespace sol {
namespace stack {
14388 template <
typename T,
typename>
14389 struct unqualified_check_getter {
14390 typedef decltype(stack_detail::unchecked_unqualified_get<T>(
nullptr, -1, std::declval<record&>())) R;
14392 template <typename Optional, typename Handler>
14394 if constexpr (!meta::meta_detail::is_adl_sol_lua_check_v<T> && !meta::meta_detail::is_adl_sol_lua_get_v<T>) {
14395 if constexpr (is_lua_reference_v<T>) {
14396 if constexpr (is_global_table_v<T>) {
14409 tracking.use(
static_cast<int>(success));
14411 return detail::associated_nullopt_v<Optional>;
14413 return stack_detail::unchecked_get<T>(L,
index, tracking);
14416 else if constexpr ((std::is_integral_v<T> || std::is_same_v<T, lua_Integer>)&&!std::is_same_v<T, bool>) {
14417 #if SOL_LUA_VERSION_I_ >= 503
14426 #if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
14427 const auto integer_value = llround(value);
14428 if (
static_cast<lua_Number>(integer_value) == value) {
14430 return static_cast<T
>(integer_value);
14434 return static_cast<T
>(value);
14438 tracking.use(
static_cast<int>(t !=
type::none));
14440 return detail::associated_nullopt_v<Optional>;
14442 else if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, lua_Number>) {
14447 tracking.use(
static_cast<int>(t !=
type::none));
14449 return detail::associated_nullopt_v<Optional>;
14452 return static_cast<T
>(value);
14454 else if constexpr (std::is_enum_v<T> && !meta::any_same_v<T, meta_function, type>) {
14459 tracking.use(
static_cast<int>(t !=
type::none));
14461 return detail::associated_nullopt_v<Optional>;
14464 return static_cast<T
>(value);
14467 if (!unqualified_check<T>(L,
index, std::forward<Handler>(
handler))) {
14469 return detail::associated_nullopt_v<Optional>;
14471 return stack_detail::unchecked_unqualified_get<T>(L,
index, tracking);
14475 if (!unqualified_check<T>(L,
index, std::forward<Handler>(
handler))) {
14477 return detail::associated_nullopt_v<Optional>;
14479 return stack_detail::unchecked_unqualified_get<T>(L,
index, tracking);
14483 template <
typename Handler>
14485 return get_using<optional<R>>(L,
index, std::forward<Handler>(
handler), tracking);
14489 #if SOL_IS_ON(SOL_STD_VARIANT)
14490 template <
typename... Tn,
typename C>
14492 typedef std::variant<Tn...>
V;
14496 template <
typename Handler>
14501 template <
typename Handler>
14507 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");
14511 template <
typename Handler>
14516 template <std::
size_t I,
typename Handler>
14518 typedef std::variant_alternative_t<I - 1,
V> T;
14520 return V(std::in_place_index<I - 1>, stack::get<T>(L,
index));
14522 return get_one(std::integral_constant<std::size_t, I - 1>(), L,
index, std::forward<Handler>(
handler), tracking);
14525 template <
typename Handler>
14527 return get_one(std::integral_constant<std::size_t, V_size::value>(), L,
index, std::forward<Handler>(
handler), tracking);
14530 #endif // standard variant
14537 namespace sol {
namespace stack {
14539 #if SOL_IS_ON(SOL_COMPILER_GCC)
14540 #pragma GCC diagnostic push
14541 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
14544 namespace stack_detail {
14545 template <
typename OptionalType,
typename T,
typename Handler>
14549 if constexpr (is_lua_reference_v<T>) {
14550 if constexpr (is_global_table_v<Tu>) {
14563 tracking.
use(
static_cast<int>(success));
14567 return OptionalType(stack_detail::unchecked_get<T>(L,
index, tracking));
14570 else if constexpr (!std::is_reference_v<T> && is_unique_usertype_v<Tu> && !is_actual_type_rebindable_for_v<Tu>) {
14578 if (&detail::usertype_unique_alloc_destroy<element, Tu> == pdx) {
14579 memory = detail::align_usertype_unique_tag<true, false>(
memory);
14580 memory = detail::align_usertype_unique<actual, true, false>(
memory);
14581 actual* mem =
static_cast<actual*
>(
memory);
14582 return static_cast<actual
>(*mem);
14585 return OptionalType();
14588 memory = detail::align_usertype_unique_tag<true, false>(
memory);
14590 memory = detail::align_usertype_unique<actual, true, false>(
memory);
14592 int cast_operation;
14594 if constexpr (is_actual_type_rebindable_for_v<Tu>) {
14597 cast_operation = ic(
memory, &r, ti, rebind_ti);
14601 cast_operation = ic(
memory, &r, ti, rebind_ti);
14603 switch (cast_operation) {
14607 actual* mem =
static_cast<actual*
>(
memory);
14608 return OptionalType(*mem);
14617 return OptionalType();
14621 if (!check<T>(L,
index, std::forward<Handler>(
handler))) {
14623 return OptionalType();
14625 return OptionalType(stack_detail::unchecked_get<T>(L,
index, tracking));
14630 #if SOL_IS_ON(SOL_COMPILER_GCC)
14631 #pragma GCC diagnostic pop
14634 template <
typename T,
typename>
14635 struct qualified_check_getter {
14636 typedef decltype(stack_detail::unchecked_get<T>(
nullptr, -1, std::declval<record&>())) R;
14638 template <typename Handler>
14640 return stack_detail::get_optional<optional<R>, T>(L,
index, std::forward<Handler>(
handler), tracking);
14644 template <
typename Optional>
14648 return stack_detail::get_optional<Optional, T>(L,
index, &
no_panic, tracking);
14661 #include <type_traits>
14665 #include <string_view>
14666 #if SOL_IS_ON(SOL_STD_VARIANT)
14668 #endif // Can use variant
14672 #include <iostream>
14676 std::string visual;
14682 visual +=
type_name(L, stack::get<type>(L,
static_cast<int>(i)));
14692 std::cout <<
"-- " << message <<
" -- [ " <<
dump_types(L) <<
" ]" << std::endl;
14698 namespace sol {
namespace stack {
14699 namespace stack_detail {
14700 template <
typename T>
14706 constexpr
bool is_same_signedness
14707 = (std::is_signed_v<T> && std::is_signed_v<lua_Integer>) || (std::is_unsigned_v<T> && std::is_unsigned_v<lua_Integer>);
14708 constexpr
bool probaby_fits_within_lua_Integer =
sizeof(T) ==
sizeof(
lua_Integer)
14709 #if SOL_IS_ON(SOL_ALL_INTEGER_VALUES_FIT)
14710 && ((std::has_unique_object_representations_v<T> && std::has_unique_object_representations_v<lua_Integer>) ?
true : is_same_signedness)
14712 && is_same_signedness
14715 if constexpr (
sizeof(T) <
sizeof(
lua_Integer) || probaby_fits_within_lua_Integer) {
14720 auto u_min =
static_cast<std::intmax_t
>((std::numeric_limits<lua_Integer>::min)());
14721 auto u_max =
static_cast<std::uintmax_t
>((std::numeric_limits<lua_Integer>::max)());
14722 auto t_min =
static_cast<std::intmax_t
>((std::numeric_limits<T>::min)());
14723 auto t_max =
static_cast<std::uintmax_t
>((std::numeric_limits<T>::max)());
14724 return (u_min <= t_min || value >=
static_cast<T
>(u_min)) && (u_max >= t_max || value <=
static_cast<T
>(u_max));
14728 template <
typename T>
14739 if constexpr (std::is_signed_v<T>) {
14740 return stack::push(L,
static_cast<std::int_least32_t
>(value));
14743 return stack::push(L,
static_cast<std::uint_least32_t
>(value));
14747 return stack::push(L,
static_cast<std::underlying_type_t<T>
>(value));
14751 template <
typename T>
14758 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
14760 #endif // make sure stack doesn't overflow
14761 #if SOL_LUA_VERSION_I_ < 502
14763 lua_getfenv(L, target_index);
14767 const char* maybe_upvalue_name =
lua_getupvalue(L, target_index, 1);
14768 if (maybe_upvalue_name !=
nullptr) {
14777 if (maybe_upvalue_name ==
nullptr) {
14783 if (upvalue_name ==
"_ENV") {
14794 template <
typename T>
14796 lua_State* target_L = target.lua_state();
14805 template <
typename T>
14807 template <
typename F,
typename... Args>
14809 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
14811 #endif // make sure stack doesn't overflow
14817 T* obj = detail::usertype_allocate<T>(L);
14820 std::allocator_traits<std::allocator<T>>::construct(alloc, obj, std::forward<Args>(
args)...);
14824 template <
typename K,
typename... Args>
14827 return push_fx(L, fx, std::forward<Args>(
args)...);
14830 template <
typename Arg,
typename... Args>
14834 return push_fx(L, std::forward<Args>(
args)...);
14846 template <
typename T>
14850 template <
typename F>
14852 if (obj ==
nullptr)
14854 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
14856 #endif // make sure stack doesn't overflow
14857 T** pref = detail::usertype_allocate_pointer<T>(L);
14863 template <
typename K>
14866 return push_fx(L, fx, obj);
14869 template <
typename Arg,
typename... Args>
14873 return push_fx(L, std::forward<Args>(
args)...);
14883 template <
typename T>
14889 namespace stack_detail {
14890 template <
typename T>
14895 template <
typename Arg,
typename... Args>
14901 return push_deep(L, std::forward<Arg>(
arg), std::forward<Args>(
args)...);
14904 return push_deep(L, std::forward<Arg>(
arg), std::forward<Args>(
args)...);
14908 template <
typename... Args>
14910 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
14912 #endif // make sure stack doesn't overflow
14913 element** pointer_to_memory =
nullptr;
14916 actual* typed_memory = detail::usertype_unique_allocate<element, actual>(L, pointer_to_memory, fx,
id);
14926 *fx = detail::usertype_unique_alloc_destroy<element, actual>;
14929 *pointer_to_memory = detail::unique_get<T>(L, *typed_memory);
14935 template <
typename T>
14937 template <
typename... Args>
14941 return p.
push(L, std::forward<Args>(
args)...);
14945 template <
typename T,
typename>
14946 struct unqualified_pusher {
14947 template <
typename... Args>
14950 if constexpr (is_lua_reference_v<Tu>) {
14951 using int_arr =
int[];
14952 int_arr p { (std::forward<Args>(
args).push(L))... };
14955 else if constexpr (std::is_same_v<Tu, bool>) {
14956 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
14958 #endif // make sure stack doesn't overflow
14962 else if constexpr (std::is_integral_v<Tu> || std::is_same_v<Tu, lua_Integer>) {
14963 const Tu& value(std::forward<Args>(
args)...);
14964 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
14966 #endif // make sure stack doesn't overflow
14967 #if SOL_LUA_VERSION_I_ >= 503
14968 if (stack_detail::integer_value_fits<Tu>(value)) {
14972 #endif // Lua 5.3 and above
14973 #if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
14974 if (
static_cast<T
>(llround(
static_cast<lua_Number>(value))) != value) {
14975 #if SOL_IS_OFF(SOL_EXCEPTIONS)
14977 sol_m_assert(
false,
"integer value will be misrepresented in lua");
14982 #endif // No Exceptions
14984 #endif // Safe Numerics and Number Precision Check
14988 else if constexpr (std::is_floating_point_v<Tu> || std::is_same_v<Tu, lua_Number>) {
14989 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
14991 #endif // make sure stack doesn't overflow
14995 else if constexpr (std::is_same_v<Tu, luaL_Stream*>) {
14999 #if SOL_IS_ON(SOL_LUAL_STREAM_USE_CLOSE_FUNCTION)
15001 #endif // LuaJIT and Lua 5.1 and below do not have
15004 else if constexpr (std::is_same_v<Tu, luaL_Stream>) {
15008 #if SOL_IS_ON(SOL_LUAL_STREAM_USE_CLOSE_FUNCTION)
15010 #endif // LuaJIT and Lua 5.1 and below do not have
15013 else if constexpr (std::is_enum_v<Tu>) {
15016 else if constexpr (std::is_pointer_v<Tu>) {
15017 return stack::push<detail::as_pointer_tag<std::remove_pointer_t<T>>>(L, std::forward<Args>(
args)...);
15019 else if constexpr (is_unique_usertype_v<Tu>) {
15020 return stack::push<detail::as_unique_tag<T>>(L, std::forward<Args>(
args)...);
15023 return stack::push<detail::as_value_tag<T>>(L, std::forward<Args>(
args)...);
15028 template <
typename T>
15035 template <
typename T>
15055 template <
bool is_nested>
15060 for (
const auto& pair : cont) {
15065 set_field(L, pair.first, pair.second, tableindex);
15071 template <
bool is_nested>
15077 for (
const auto& i : cont) {
15078 #if SOL_LUA_VERSION_I_ >= 503
15080 for (
int pi = 0; pi < p; ++pi) {
15084 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15086 #endif // make sure stack doesn't overflow
15094 int firstindex = tableindex + 1 + 1;
15095 for (
int pi = 0; pi < p; ++pi) {
15097 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15099 #endif // make sure stack doesn't overflow
15107 #endif // Lua Version 5.3 and others
15115 template <
typename T>
15118 using inner_t = std::remove_pointer_t<meta::unwrap_unqualified_t<T>>;
15119 if constexpr (is_container_v<inner_t>) {
15120 return stack::push<detail::as_table_tag<T>>(L, value_.value());
15128 using inner_t = std::remove_pointer_t<meta::unwrap_unqualified_t<T>>;
15129 if constexpr (is_container_v<inner_t>) {
15130 return stack::push<detail::as_table_tag<T>>(L, value_);
15138 template <
typename T>
15142 using inner_t = std::remove_pointer_t<Tu>;
15143 if constexpr (is_container_v<inner_t>) {
15144 return stack::push<detail::as_table_tag<T>>(L, nested_value,
nested_tag);
15147 return stack::push<Tu>(L, nested_value);
15153 using inner_t = std::remove_pointer_t<Tu>;
15154 if constexpr (is_container_v<inner_t>) {
15155 return stack::push<detail::as_table_tag<T>>(L, nested_wrapper_.value(),
nested_tag);
15158 return stack::push<Tu>(L, nested_wrapper_.value());
15163 template <
typename T>
15167 return p.
push(L, il);
15174 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15176 #endif // make sure stack doesn't overflow
15192 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15194 #endif // make sure stack doesn't overflow
15203 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15205 #endif // make sure stack doesn't overflow
15214 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15216 #endif // make sure stack doesn't overflow
15222 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
15226 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15228 #endif // make sure stack doesn't overflow
15237 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15239 #endif // make sure stack doesn't overflow
15244 #endif // noexcept function type
15249 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15251 #endif // make sure stack doesn't overflow
15257 template <
typename Arg,
typename... Args>
15261 using f_tuple = decltype(std::forward<T>(c).upvalues);
15262 int pushcount =
multi_push(L, std::get<I>(std::forward<f_tuple>(std::forward<T>(c).upvalues))...);
15266 template <
typename T>
15275 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15277 #endif // make sure stack doesn't overflow
15286 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15288 #endif // make sure stack doesn't overflow
15297 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15299 #endif // make sure stack doesn't overflow
15305 template <
typename T>
15308 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15310 #endif // make sure stack doesn't overflow
15316 template <
typename T>
15318 template <
bool with_meta =
true,
typename Key,
typename... Args>
15320 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15322 #endif // make sure stack doesn't overflow
15324 T*
data = detail::user_allocate<T>(L);
15327 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15329 #endif // make sure stack doesn't overflow
15338 std::allocator_traits<std::allocator<T>>::construct(alloc,
data, std::forward<Args>(
args)...);
15342 template <
typename Arg,
typename... Args>
15345 const auto name = &
arg[0];
15346 return push_with<true>(L, name, std::forward<Args>(
args)...);
15351 return push_with<false>(L, name, std::forward<Args>(
args)...);
15355 return push_with(L, name, std::forward<Arg>(
arg), std::forward<Args>(
args)...);
15361 return push_with(L, name, u.value);
15366 return push_with(L, name,
std::move(u.value()));
15371 return push_with<false>(L, name, u.value());
15376 return push_with<false>(L, name,
std::move(u.value()));
15383 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15385 #endif // make sure stack doesn't overflow
15386 void** ud = detail::usertype_allocate_pointer<void>(L);
15387 *ud =
data.value();
15395 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15397 #endif // make sure stack doesn't overflow
15403 if (str ==
nullptr)
15405 return push_sized(L, str, std::char_traits<char>::length(str));
15409 return push_sized(L, strb,
static_cast<std::size_t>(stre - strb));
15413 return push_sized(L, str, len);
15428 return p.
push(L, str);
15434 return p.
push(L, strb, stre);
15440 return p.
push(L, str, len);
15444 template <
size_t N>
15447 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15449 #endif // make sure stack doesn't overflow
15455 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15457 #endif // make sure stack doesn't overflow
15466 const char str[2] = { c,
'\0' };
15467 return stack::push(L,
static_cast<const char*
>(str), 1u);
15471 #if SOL_IS_ON(SOL_CHAR8_T)
15473 struct unqualified_pusher<const char8_t*> {
15475 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15477 #endif // make sure stack doesn't overflow
15483 if (str ==
nullptr)
15485 return push_sized(L, str, std::char_traits<char>::length(
reinterpret_cast<const char*
>(str)));
15488 static int push(
lua_State* L,
const char8_t* strb,
const char8_t* stre) {
15489 return push_sized(L, strb,
static_cast<std::size_t>(stre - strb));
15493 return push_sized(L, str, len);
15498 struct unqualified_pusher<char8_t*> {
15500 unqualified_pusher<const char8_t*> p {};
15502 return p.push_sized(L, str, len);
15506 unqualified_pusher<const char8_t*> p {};
15508 return p.push(L, str);
15511 static int push(
lua_State* L,
const char8_t* strb,
const char8_t* stre) {
15512 unqualified_pusher<const char8_t*> p {};
15514 return p.push(L, strb, stre);
15518 unqualified_pusher<const char8_t*> p {};
15520 return p.push(L, str, len);
15524 template <
size_t N>
15525 struct unqualified_pusher<char8_t[N]> {
15527 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15529 #endif // make sure stack doesn't overflow
15530 const char* str_as_char =
reinterpret_cast<const char*
>(
static_cast<const char8_t*
>(str));
15531 lua_pushlstring(L, str_as_char, std::char_traits<char>::length(str_as_char));
15536 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15538 #endif // make sure stack doesn't overflow
15545 struct unqualified_pusher<char8_t> {
15547 const char8_t str[2] = { c,
'\0' };
15548 return stack::push(L,
static_cast<const char8_t*
>(str), 1u);
15553 template <
typename Ch,
typename Traits,
typename Al>
15556 if constexpr (!std::is_same_v<Ch, char>) {
15560 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15562 #endif // make sure stack doesn't overflow
15569 if constexpr (!std::is_same_v<Ch, char>) {
15573 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15575 #endif // make sure stack doesn't overflow
15582 template <
typename Ch,
typename Traits>
15596 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15598 #endif // make sure stack doesn't overflow
15599 const std::string& str = to_string(m);
15608 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15610 #endif // make sure stack doesn't overflow
15619 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15621 #endif // make sure stack doesn't overflow
15630 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15632 #endif // make sure stack doesn't overflow
15641 return push(L, wstr, std::char_traits<wchar_t>::length(wstr));
15645 return push(L, wstr, wstr + sz);
15649 if constexpr (
sizeof(
wchar_t) == 2) {
15650 const char16_t* sb =
reinterpret_cast<const char16_t*
>(strb);
15651 const char16_t* se =
reinterpret_cast<const char16_t*
>(stre);
15655 const char32_t* sb =
reinterpret_cast<const char32_t*
>(strb);
15656 const char32_t* se =
reinterpret_cast<const char32_t*
>(stre);
15667 return p.
push(L, str);
15673 return p.
push(L, strb, stre);
15679 return p.
push(L, str, len);
15686 char* target =
start;
15688 for (
const char16_t* strtarget = strb; strtarget < stre;) {
15697 const char* utf8data = er.code_units.data();
15698 std::memcpy(target, utf8data, er.code_units_size);
15699 target += er.code_units_size;
15700 strtarget = dr.next;
15707 return push(L, u16str, std::char_traits<char16_t>::length(u16str));
15711 return push(L, u16str, u16str + sz);
15720 return convert_into(L, sbo, max_possible_code_units, strb, stre);
15724 for (
const char16_t* strtarget = strb; strtarget < stre;) {
15727 needed_size += er.code_units_size;
15728 strtarget = dr.next;
15731 return convert_into(L, sbo, needed_size, strb, stre);
15733 std::string u8str(
"", 0);
15734 u8str.resize(needed_size);
15735 char* target =
const_cast<char*
>(u8str.data());
15736 return convert_into(L, target, needed_size, strb, stre);
15745 return p.
push(L, str);
15751 return p.
push(L, strb, stre);
15757 return p.
push(L, str, len);
15764 char* target =
start;
15766 for (
const char32_t* strtarget = strb; strtarget < stre;) {
15775 const char*
data = er.code_units.data();
15776 std::memcpy(target,
data, er.code_units_size);
15777 target += er.code_units_size;
15778 strtarget = dr.next;
15784 return push(L, u32str, u32str + std::char_traits<char32_t>::length(u32str));
15788 return push(L, u32str, u32str + sz);
15797 return convert_into(L, sbo, max_possible_code_units, strb, stre);
15801 for (
const char32_t* strtarget = strb; strtarget < stre;) {
15804 needed_size += er.code_units_size;
15805 strtarget = dr.next;
15808 return convert_into(L, sbo, needed_size, strb, stre);
15810 std::string u8str(
"", 0);
15811 u8str.resize(needed_size);
15812 char* target =
const_cast<char*
>(u8str.data());
15813 return convert_into(L, target, needed_size, strb, stre);
15822 return p.
push(L, str);
15828 return p.
push(L, strb, stre);
15834 return p.
push(L, str, len);
15838 template <
size_t N>
15841 return push(L, str, std::char_traits<wchar_t>::length(str));
15845 const wchar_t* str_ptr =
static_cast<const wchar_t*
>(str);
15846 return stack::push<const wchar_t*>(L, str_ptr, str_ptr + sz);
15850 template <
size_t N>
15853 return push(L, str, std::char_traits<char16_t>::length(str));
15857 const char16_t* str_ptr =
static_cast<const char16_t*
>(str);
15858 return stack::push<const char16_t*>(L, str_ptr, str_ptr + sz);
15862 template <
size_t N>
15865 return push(L, str, std::char_traits<char32_t>::length(str));
15869 const char32_t* str_ptr =
static_cast<const char32_t*
>(str);
15870 return stack::push<const char32_t*>(L, str_ptr, str_ptr + sz);
15877 const wchar_t str[2] = { c,
'\0' };
15878 return stack::push(L,
static_cast<const wchar_t*
>(str), 1u);
15885 const char16_t str[2] = { c,
'\0' };
15886 return stack::push(L,
static_cast<const char16_t*
>(str), 1u);
15893 const char32_t str[2] = { c,
'\0' };
15894 return stack::push(L,
static_cast<const char32_t*
>(str), 1u);
15898 template <
typename... Args>
15902 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
15904 #endif // make sure stack doesn't overflow
15910 template <
typename T>
15912 return push(std::index_sequence_for<Args...>(), L, std::forward<T>(t));
15916 template <
typename A,
typename B>
15918 template <
typename T>
15920 int pushcount =
stack::push(L, std::get<0>(std::forward<T>(t)));
15921 pushcount +=
stack::push(L, std::get<1>(std::forward<T>(t)));
15926 template <
typename T>
15930 template <
typename Optional>
15936 return stack::push(L,
static_cast<QualifiedValueType
>(
op.value()));
15940 template <
typename T>
15943 return stack::push<T>(L, value_.
value());
15947 return stack::push<T>(L,
std::move(value_).value());
15987 template <
typename Allocator>
15989 template <
typename T>
15991 const auto first = bc.data();
15992 const auto bcsize = bc.size();
15996 L,
reinterpret_cast<const char*
>(
first),
static_cast<std::size_t>(bcsize * (
sizeof(*first) /
sizeof(
const char))), bytecode_name);
16000 template <
typename T>
16002 return push(L, std::forward<bc>(bc),
"bytecode");
16006 #if SOL_IS_ON(SOL_STD_VARIANT)
16007 namespace stack_detail {
16015 template <
typename T>
16017 return stack::push<T>(L, std::forward<T>(value));
16023 template <
typename... Tn>
16033 #endif // Variant because Clang is terrible
16044 namespace sol {
namespace stack {
16045 template <
typename T,
typename>
16050 "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 "
16067 namespace sol {
namespace stack {
16069 namespace stack_detail {
16070 template <
typename T,
bool global,
bool raw>
16073 template <
typename T,
bool global,
bool raw>
16075 || (!global && !raw && (meta::is_c_str_or_string_v<T> || meta::is_string_of_v<T, char>))
16076 || (!global && raw && (std::is_integral_v<T> && !std::is_same_v<T, bool>))
16078 || (!global && !raw && (std::is_integral_v<T> && !std::is_same_v<T, bool>))
16081 || (!global && raw && std::is_pointer_v<T> && std::is_void_v<std::remove_pointer_t<T>>)
16082 #endif // void pointer keys 5.2 or better
16085 template <
typename T,
bool global,
bool raw>
16088 template <
typename T,
bool global,
bool raw>
16090 || (!global && !raw && (meta::is_c_str_or_string_v<T> || meta::is_string_of_v<T, char>))
16091 || (!global && raw && (std::is_integral_v<T> && !std::is_same_v<T, bool>))
16093 || (!global && !raw && (std::is_integral_v<T> && !std::is_same_v<T, bool>))
16096 || (!global && raw && (std::is_pointer_v<T> && std::is_void_v<std::remove_pointer_t<T>>))
16101 template <
typename T,
bool global,
bool raw,
typename>
16103 static inline constexpr
int default_table_index
16106 template <
typename Key>
16108 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>) {
16113 else if constexpr (std::is_same_v<T, env_key_t>) {
16115 #if SOL_LUA_VERSION_I_ < 502
16117 lua_getfenv(L, tableindex);
16125 else if constexpr (std::is_same_v<T, metatable_key_t>) {
16130 else if constexpr (raw) {
16131 if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
16134 #if SOL_LUA_VERSION_I_ >= 502
16135 else if constexpr (std::is_pointer_v<T> && std::is_void_v<std::remove_pointer_t<T>>) {
16138 #endif // Lua 5.2.x+
16140 push(L, std::forward<Key>(key));
16145 if constexpr (meta::is_c_str_or_string_v<T>) {
16146 if constexpr (global) {
16154 else if constexpr (std::is_same_v<T, meta_function>) {
16155 const auto& real_key = to_string(key);
16158 #if SOL_LUA_VERSION_I_ >= 503
16159 else if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
16162 #endif // Lua 5.3.x+
16164 push(L, std::forward<Key>(key));
16171 template <
typename... Args,
bool b,
bool raw,
typename C>
16175 get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)), tableindex);
16176 void(
detail::swallow { (get_field<false, raw>(L, std::get<I>(std::forward<Keys>(keys))), 0)... });
16178 lua_pop(L,
static_cast<int>(
sizeof...(I)));
16182 template <
typename Keys>
16187 template <
typename Keys>
16193 template <
typename A,
typename B,
bool b,
bool raw,
typename C>
16195 template <
typename Keys>
16197 get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)), tableindex);
16198 get_field<false, raw>(L, std::get<1>(std::forward<Keys>(keys)));
16200 lua_pop(L,
static_cast<int>(2));
16204 template <
typename Keys>
16206 get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)));
16207 get_field<false, raw>(L, std::get<1>(std::forward<Keys>(keys)));
16209 lua_pop(L,
static_cast<int>(2));
16214 template <
typename T,
bool global,
bool raw,
typename>
16215 struct field_setter {
16216 static constexpr
int default_table_index
16219 template <
typename Key,
typename Value>
16221 if constexpr (std::is_same_v<T, update_if_empty_t> || std::is_same_v<T, override_value_t>) {
16227 else if constexpr (std::is_same_v<T, metatable_key_t>) {
16229 push(L, std::forward<Value>(value));
16232 else if constexpr (raw) {
16233 if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
16234 push(L, std::forward<Value>(value));
16237 #if SOL_LUA_VERSION_I_ >= 502
16238 else if constexpr (std::is_pointer_v<T> && std::is_void_v<std::remove_pointer_t<T>>) {
16239 push(L, std::forward<Value>(value));
16240 lua_rawsetp(L, tableindex, std::forward<Key>(key));
16242 #endif // Lua 5.2.x
16244 push(L, std::forward<Key>(key));
16245 push(L, std::forward<Value>(value));
16250 if constexpr (meta::is_c_str_or_string_v<T>) {
16251 if constexpr (global) {
16252 push(L, std::forward<Value>(value));
16257 push(L, std::forward<Value>(value));
16261 #if SOL_LUA_VERSION_I_ >= 503
16262 else if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
16263 push(L, std::forward<Value>(value));
16266 #endif // Lua 5.3.x
16268 push(L, std::forward<Key>(key));
16269 push(L, std::forward<Value>(value));
16276 template <
typename... Args,
bool b,
bool raw,
typename C>
16278 template <
bool g, std::
size_t I,
typename Keys,
typename Value>
16280 I < 1 ? set_field<g, raw>(L, std::get<I>(std::forward<Keys>(keys)), std::forward<Value>(value), tableindex)
16281 : set_field<g, raw>(L, std::get<I>(std::forward<Keys>(keys)), std::forward<Value>(value));
16286 I0 < 1 ? get_field<g, raw>(L, std::get<I0>(std::forward<Keys>(keys)), tableindex)
16287 : get_field<g, raw>(L, std::get<I0>(std::forward<Keys>(keys)), -1);
16288 apply<false>(std::index_sequence<I1, I...>(), L, std::forward<Keys>(keys), std::forward<Value>(value), -1);
16293 apply<g>(std::index_sequence<I0, I...>(), L, std::forward<Keys>(keys), std::forward<Value>(value), tableindex);
16294 lua_pop(L,
static_cast<int>(
sizeof...(I)));
16297 template <
typename Keys,
typename Value>
16299 top_apply<b>(
std::make_index_sequence<
sizeof...(Args)>(), L, std::forward<Keys>(keys), std::forward<Value>(value), tableindex);
16303 template <
typename A,
typename B,
bool b,
bool raw,
typename C>
16305 template <
typename Keys,
typename Value>
16307 get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)), tableindex);
16308 set_field<false, raw>(L, std::get<1>(std::forward<Keys>(keys)), std::forward<Value>(value),
lua_gettop(L));
16318 namespace sol {
namespace stack {
16319 template <
typename T,
typename P,
bool b,
bool raw,
typename>
16320 struct probe_field_getter {
16321 template <
typename Key>
16323 if constexpr (!b) {
16325 return probe(
false, 0);
16328 get_field<b, raw>(L, std::forward<Key>(key), tableindex);
16329 return probe(check<P>(L), 1);
16333 template <
typename A,
typename B,
typename P,
bool b,
bool raw,
typename C>
16335 template <
typename Keys>
16338 return probe(
false, 0);
16340 get_field<b, raw>(L, std::get<0>(keys), tableindex);
16342 return probe(
false, 1);
16344 get_field<false, raw>(L, std::get<1>(keys), tableindex);
16345 return probe(check<P>(L), 2);
16349 template <
typename... Args,
typename P,
bool b,
bool raw,
typename C>
16351 template <std::
size_t I,
typename Keys>
16353 get_field<(I < 1) && b, raw>(L, std::get<I>(keys), tableindex);
16354 return probe(check<P>(L), sofar);
16359 get_field < I<1 && b, raw>(L, std::get<I>(keys), tableindex);
16361 return probe(
false, sofar);
16363 return apply(std::index_sequence<I1, In...>(), sofar + 1, L, std::forward<Keys>(keys), -1);
16366 template <
typename Keys>
16368 if constexpr (!b) {
16370 return probe(
false, 0);
16372 return apply(std::index_sequence_for<Args...>(), 1, L, std::forward<Keys>(keys), tableindex);
16375 return apply(std::index_sequence_for<Args...>(), 1, L, std::forward<Keys>(keys), tableindex);
16392 static const std::string name =
"";
16396 template <std::
size_t N>
16398 if (chunkname.empty()) {
16399 auto it = code.cbegin();
16400 auto e = code.cend();
16403 for (i = 0; i < n && it != e; ++i, ++it) {
16404 basechunkname[i] = *it;
16408 basechunkname[i] =
'.';
16411 basechunkname[i] =
'\0';
16412 return &basechunkname[0];
16415 return chunkname.c_str();
16436 namespace stack_detail {
16437 template <
typename T>
16439 typedef std::decay_t<T>
TValue;
16441 static const std::size_t voidsize =
sizeof(
void*);
16442 static const std::size_t voidsizem1 = voidsize - 1;
16443 static const std::size_t data_t_count = (
sizeof(
TValue) + voidsizem1) / voidsize;
16444 typedef std::array<void*, data_t_count> data_t;
16446 data_t
data { {} };
16447 std::memcpy(&
data[0], std::addressof(item), itemsize);
16449 for (
const auto& v :
data) {
16456 template <
typename T>
16458 static const std::size_t data_t_count = (
sizeof(T) + (
sizeof(
void*) - 1)) /
sizeof(
void*);
16459 typedef std::array<void*, data_t_count> data_t;
16460 data_t voiddata { {} };
16461 for (
std::size_t i = 0,
d = 0;
d <
sizeof(T); ++i,
d +=
sizeof(
void*)) {
16464 return std::pair<T, int>(*
reinterpret_cast<T*
>(
static_cast<void*
>(voiddata.data())),
index);
16467 template <
typename T>
16469 static const std::size_t data_t_count = (
sizeof(T) + (
sizeof(
void*) - 1)) /
sizeof(
void*);
16470 typedef std::array<void*, data_t_count> data_t;
16473 data_t voiddata { {} };
16478 if (upvalue_name ==
nullptr) {
16486 return std::pair<T, int>(*
reinterpret_cast<T*
>(
static_cast<void*
>(voiddata.data())),
index);
16489 template <
bool checked,
typename Handler,
typename Fx,
typename... Args>
16491 return std::forward<Fx>(fx)(std::forward<Args>(
args)...);
16494 template <
bool checked,
typename Arg,
typename... Args,
std::size_t I,
std::size_t... Is,
typename Handler,
typename Fx,
typename... FxArgs>
16496 record& tracking_, Fx&& fx_, FxArgs&&... fxargs_) {
16497 #if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS)
16500 if constexpr (checked) {
16502 std::index_sequence<Is...>(),
16505 std::forward<Handler>(handler_),
16507 std::forward<Fx>(fx_),
16508 std::forward<FxArgs>(fxargs_)...,
16509 *stack_detail::check_get_arg<Arg>(L_, start_index_ + tracking_.used, handler_, tracking_));
16515 std::index_sequence<Is...>(),
16518 std::forward<Handler>(handler_),
16520 std::forward<Fx>(fx_),
16521 std::forward<FxArgs>(fxargs_)...,
16522 stack_detail::unchecked_get_arg<Arg>(L_, start_index_ + tracking_.used, tracking_));
16528 int start_index_, Fx&& fx_, FxArgs&&... args_) {
16530 "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 "
16531 "a reference and std::move it manually if this was your intention.");
16534 #if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS)
16535 if constexpr (checkargs) {
16539 if constexpr (std::is_void_v<R>) {
16541 argument_types_, argument_indices_, L_, start_index_,
handler, tracking, std::forward<Fx>(fx_), std::forward<FxArgs>(args_)...);
16544 return eval<checkargs>(
16545 argument_types_, argument_indices_, L_, start_index_,
handler, tracking, std::forward<Fx>(fx_), std::forward<FxArgs>(args_)...);
16549 template <
typename T>
16551 int push_count =
push(L, std::forward<T>(
arg));
16559 template <
typename T>
16561 int push_count =
push(L, std::forward<T>(
arg));
16569 if constexpr (std::is_void_v<R>) {
16570 stack_detail::call<check_args>(tr, ta, args_indices(), L,
start, std::forward<Fx>(fx), std::forward<FxArgs>(
args)...);
16573 return stack_detail::call<check_args>(tr, ta, args_indices(), L,
start, std::forward<Fx>(fx), std::forward<FxArgs>(
args)...);
16579 if constexpr (std::is_void_v<R>) {
16580 call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(
args)...);
16583 return call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(
args)...);
16590 if constexpr (std::is_void_v<R>) {
16591 call<check_args>(tr,
16594 (std::max)(
static_cast<int>(
lua_gettop(L) - expected_count_t::value),
static_cast<int>(0)),
16595 std::forward<Fx>(fx),
16596 std::forward<FxArgs>(
args)...);
16599 return call<check_args>(tr,
16602 (std::max)(
static_cast<int>(
lua_gettop(L) - expected_count_t::value),
static_cast<int>(0)),
16603 std::forward<Fx>(fx),
16604 std::forward<FxArgs>(
args)...);
16609 typename Fx,
typename... FxArgs>
16611 if constexpr (std::is_void_v<Ret0>) {
16612 call<check_args>(tr, ta, L,
start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
16613 if constexpr (clean_stack) {
16623 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>>;
16624 if constexpr (clean_stack && !is_stack::value) {
16634 using args_list =
typename traits_type::args_list;
16635 using returns_list =
typename traits_type::returns_list;
16636 return call_into_lua<check_args, clean_stack>(returns_list(), args_list(), L,
start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
16644 auto pn =
pop_n(L, 1);
16677 #if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE)
16678 if (L ==
nullptr) {
16681 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
16683 #endif // make sure stack doesn't overflow
16685 auto pn =
pop_n(L, 1);
16686 luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON);
16694 #if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE)
16695 if (L ==
nullptr) {
16698 luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_OFF);
16714 template <
typename R = reference,
bool should_pop = !is_stack_based_v<R>,
typename T>
16716 int backpedal =
stack::push(L, std::forward<T>(value));
16717 R r = stack::get<R>(L, -backpedal);
16724 template <
typename T,
typename R = reference,
bool should_pop = !is_stack_based_v<R>,
typename... Args>
16726 int backpedal = stack::push<T>(L, std::forward<Args>(
args)...);
16727 R r = stack::get<R>(L, -backpedal);
16734 template <
typename R = reference,
bool should_pop = !is_stack_based_v<R>,
typename T>
16737 R r = stack::get<R>(L, -backpedal);
16744 template <
typename T,
typename R = reference,
bool should_pop = !is_stack_based_v<R>,
typename... Args>
16746 int backpedal = stack::push_userdata<T>(L, std::forward<Args>(
args)...);
16747 R r = stack::get<R>(L, -backpedal);
16762 template <
typename ref_t>
16763 class basic_object_base :
public ref_t {
16767 template <
typename T>
16769 return stack::get<T>(base_t::lua_state(), base_t::stack_index());
16772 template <
typename T>
16775 return stack::pop<T>(base_t::lua_state());
16778 template <
typename T>
16780 return stack::check<T>(base_t::lua_state(), base_t::stack_index(), &
no_panic);
16783 template <
typename T>
16785 int r = base_t::registry_index();
16791 return stack::check<T>(base_t::lua_state(), -1, &
no_panic);
16804 template <
typename T>
16805 decltype(
auto) as()
const {
16809 template <
typename T>
16820 template <
typename base_type>
16821 class basic_object :
public basic_object_base<base_type> {
16825 template <
bool invert_and_pop = false>
16827 if (invert_and_pop) {
16839 template <
typename T,
16845 template <
typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
16851 template <typename T,
16856 template <
typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
16869 template <
typename Super>
16872 template <
typename Super>
16885 template <
typename T,
typename... Args>
16889 template <
typename T,
typename... Args>
16891 :
basic_object(L_, in_place_type<T>, std::forward<T>(
arg), std::forward<Args>(
args)...) {
16896 base_t::operator=(b);
16903 template <
typename Super>
16908 template <
typename Super>
16915 template <
typename T>
16917 return make_reference<object, true>(L_, std::forward<T>(value));
16920 template <
typename T,
typename... Args>
16922 return make_reference<T, object, true>(L_, std::forward<Args>(
args)...);
16925 template <
typename T>
16927 return make_reference_userdata<object, true>(L_, std::forward<T>(value));
16930 template <
typename T,
typename... Args>
16932 return make_reference_userdata<T, object, true>(L_, std::forward<Args>(
args)...);
16952 template <
typename T>
16957 template <
typename Super>
16960 const Super& super = *
static_cast<const Super*
>(
static_cast<const void*
>(
this));
16961 return super.lua_state();
16964 operator std::string()
const {
16965 const Super& super = *
static_cast<const Super*
>(
static_cast<const void*
>(
this));
16966 return super.template get<std::string>();
16969 template <
typename T, meta::enable<meta::neg<meta::is_
string_constructible<T>>, is_proxy_primitive<meta::unqualified_t<T>>> = meta::enabler>
16970 operator T()
const {
16971 const Super& super = *
static_cast<const Super*
>(
static_cast<const void*
>(
this));
16972 return super.template get<T>();
16975 template <
typename T,
16977 operator T&()
const {
16978 const Super& super = *
static_cast<const Super*
>(
static_cast<const void*
>(
this));
16979 return super.template get<T&>();
16990 #include <iterator>
16993 template <
typename proxy_t,
bool is_const>
17013 return proxy_t(L,
index);
17017 return proxy_t(L,
index);
17021 sp = proxy_t(L,
index);
17026 const_cast<proxy_t&
>(sp) = proxy_t(L,
index);
17037 this->operator++();
17048 this->operator--();
17053 index +=
static_cast<int>(idx);
17058 index -=
static_cast<int>(idx);
17073 return proxy_t(L,
index +
static_cast<int>(idx));
17077 if (stacktop == (std::numeric_limits<int>::max)()) {
17080 else if (r.
stacktop == (std::numeric_limits<int>::max)()) {
17081 return index == stacktop;
17107 template <
typename proxy_t,
bool is_const>
17132 template <
typename T>
17134 return stack::get<T>(m_L, stack_index());
17137 template <
typename T>
17139 return stack::check<T>(m_L, stack_index());
17142 template <
typename T>
17143 decltype(
auto) as()
const {
17148 return type_of(lua_state(), stack_index());
17179 return proxy_reference.
push();
17196 template <
typename... Ret,
typename... Args>
17197 decltype(
auto) call(Args&&...
args);
17199 template <typename... Args>
17200 decltype(auto) operator()(Args&&...
args) {
17201 return call<>(std::forward<Args>(
args)...);
17249 : L(Ls),
index(idx), returncount(retnum), popcount(popped), err(pferr) {
17260 : L(o.L),
index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) {
17269 returncount = o.returncount;
17270 popcount = o.popcount;
17292 #if SOL_IS_ON(SOL_COMPILER_GCC)
17293 #pragma GCC diagnostic push
17294 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
17297 template <
typename T>
17298 decltype(
auto)
get(
int index_offset = 0)
const {
17300 int target =
index + index_offset;
17301 if constexpr (meta::is_optional_v<UT>) {
17302 using ValueType =
typename UT::value_type;
17303 if constexpr (std::is_same_v<ValueType, error>) {
17313 return stack::get<UT>(L, target);
17317 if constexpr (std::is_same_v<T, error>) {
17318 #if SOL_IS_ON(SOL_SAFE_PROXIES)
17323 #endif // Check Argument Safety
17327 #if SOL_IS_ON(SOL_SAFE_PROXIES)
17332 #endif // Check Argument Safety
17333 return stack::get<T>(L, target);
17338 #if SOL_IS_ON(SOL_COMPILER_GCC)
17339 #pragma GCC diagnostic pop
17343 return type_of(L,
index +
static_cast<int>(index_offset));
17354 return iterator(L, stack_index() + return_count(), stack_index() + return_count());
17360 return const_iterator(L, stack_index() + return_count(), stack_index() + return_count());
17370 return std::reverse_iterator<iterator>(begin());
17373 return std::reverse_iterator<iterator>(end());
17376 return std::reverse_iterator<const_iterator>(begin());
17379 return std::reverse_iterator<const_iterator>(end());
17382 return std::reverse_iterator<const_iterator>(cbegin());
17385 return std::reverse_iterator<const_iterator>(cend());
17395 return returncount;
17418 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
17420 #endif // make sure stack doesn't overflow
17422 for (
int i = 0; i < pfr.
pop_count(); ++i) {
17476 returncount = o.returncount;
17489 template <
typename T>
17491 return stack::get<T>(L,
index +
static_cast<int>(index_offset));
17495 return type_of(L,
index +
static_cast<int>(index_offset));
17506 return iterator(L, stack_index() + return_count(), stack_index() + return_count());
17512 return const_iterator(L, stack_index() + return_count(), stack_index() + return_count());
17522 return std::reverse_iterator<iterator>(begin());
17525 return std::reverse_iterator<iterator>(end());
17528 return std::reverse_iterator<const_iterator>(begin());
17531 return std::reverse_iterator<const_iterator>(end());
17534 return std::reverse_iterator<const_iterator>(cbegin());
17537 return std::reverse_iterator<const_iterator>(cend());
17555 return returncount;
17563 if (L !=
nullptr) {
17596 template <
std::size_t I,
typename... Args,
typename T>
17598 return stack_proxy(fr.lua_state(), fr.stack_index() +
static_cast<int>(I));
17613 template <std::
size_t I>
17623 template <std::
size_t I>
17645 template <
typename T>
17649 template <
typename F,
typename =
void>
17656 template <
typename... Args>
17657 static decltype(
auto) call(F& f, Args&&...
args) {
17658 return f(std::forward<Args>(
args)...);
17662 template <
typename... Args>
17663 decltype(
auto) operator()(F& fx, Args&&...
args)
const {
17664 return call(fx, std::forward<Args>(
args)...);
17669 template <
typename F>
17676 template <F fx,
typename... Args>
17678 return fx(std::forward<Args>(
args)...);
17681 template <
typename... Args>
17682 static decltype(
auto) call(F& fx, Args&&...
args) {
17683 return fx(std::forward<Args>(
args)...);
17687 template <
typename... Args>
17688 decltype(
auto) operator()(F& fx, Args&&...
args)
const {
17689 return call(fx, std::forward<Args>(
args)...);
17695 template <
typename... Args>
17696 decltype(
auto) operator()(Args&&...
args)
const {
17697 return invoke<fx>(std::forward<Args>(
args)...);
17702 template <
typename F>
17716 template <F fx,
typename Arg,
typename... Args>
17718 return mem.*fx = std::forward<Arg>(
arg);
17721 template <
typename Fx>
17726 template <
typename Fx,
typename Arg,
typename... Args>
17729 if constexpr (std::is_array_v<actual_type>) {
17733 auto last = cend(
arg);
17735 (mem.*fx)[i] = *
first;
17739 (mem.*fx) = std::forward<Arg>(
arg);
17744 template <
typename Fx,
typename... Args>
17746 return call(std::forward<Fx>(fx), mem, std::forward<Args>(
args)...);
17752 template <
typename... Args>
17753 decltype(
auto) operator()(Args&&...
args)
const {
17754 return invoke<fx>(std::forward<Args>(
args)...);
17759 template <
typename F,
typename R,
typename O,
typename... FArgs>
17767 template <F fx,
typename... Args>
17769 return (mem.*fx)(std::forward<Args>(
args)...);
17772 template <
typename Fx,
typename... Args>
17774 return (mem.*fx)(std::forward<Args>(
args)...);
17778 template <
typename Fx,
typename... Args>
17779 decltype(
auto) operator()(Fx&& fx, O& mem, Args&&...
args)
const {
17780 return call(std::forward<Fx>(fx), mem, std::forward<Args>(
args)...);
17786 template <
typename... Args>
17787 decltype(
auto) operator()(O& mem, Args&&...
args)
const {
17788 return invoke<fx>(mem, std::forward<Args>(
args)...);
17793 template <
typename R,
typename O,
typename... Args>
17796 template <
typename R,
typename O,
typename... Args>
17799 template <
typename R,
typename O,
typename... Args>
17802 template <
typename R,
typename O,
typename... Args>
17805 template <
typename R,
typename O,
typename... Args>
17808 template <
typename R,
typename O,
typename... Args>
17811 template <
typename R,
typename O,
typename... Args>
17814 template <
typename R,
typename O,
typename... Args>
17817 template <
typename R,
typename O,
typename... Args>
17820 template <
typename R,
typename O,
typename... Args>
17823 template <
typename R,
typename O,
typename... Args>
17826 template <
typename R,
typename O,
typename... Args>
17829 template <
typename R,
typename O,
typename... Args>
17832 template <
typename R,
typename O,
typename... Args>
17835 template <
typename R,
typename O,
typename... Args>
17838 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
17841 template <
typename R,
typename O,
typename... Args>
17844 template <
typename R,
typename O,
typename... Args>
17847 template <
typename R,
typename O,
typename... Args>
17850 template <
typename R,
typename O,
typename... Args>
17853 template <
typename R,
typename O,
typename... Args>
17856 template <
typename R,
typename O,
typename... Args>
17859 template <
typename R,
typename O,
typename... Args>
17862 template <
typename R,
typename O,
typename... Args>
17865 template <
typename R,
typename O,
typename... Args>
17866 struct wrapper<R (O::*)(Args..., ...) const volatile& noexcept>
17869 template <
typename R,
typename O,
typename... Args>
17872 template <
typename R,
typename O,
typename... Args>
17875 template <
typename R,
typename O,
typename... Args>
17879 template <
typename R,
typename O,
typename... Args>
17882 template <
typename R,
typename O,
typename... Args>
17885 template <
typename R,
typename O,
typename... Args>
17886 struct wrapper<R (O::*)(Args..., ...) const volatile&& noexcept>
17889 #endif // noexcept is part of a function's type
17897 namespace sol {
namespace function_detail {
17898 template <
typename Fx,
int start = 1,
bool is_yielding = false>
17919 #include <type_traits>
17927 template <
typename R,
typename W>
17934 template <
typename Rx,
typename Wx>
17939 return write_base_t::value();
17943 return write_base_t::value();
17947 return read_base_t::value();
17951 return read_base_t::value();
17955 template <
typename F,
typename G>
17959 if constexpr (left_traits::free_arity < right_traits::free_arity) {
17967 template <
typename F>
17970 if constexpr (left_traits::free_arity < 2) {
17978 template <
typename F>
17983 template <
typename F>
17988 template <
typename T>
17994 using base_t::base_t;
17997 return base_t::value();
17999 operator const T&()
const {
18000 return base_t::value();
18005 template <
typename R,
typename T>
18010 template <
typename T>
18016 using base_t::base_t;
18019 template <
typename V>
18021 typedef std::decay_t<V> T;
18026 template <
typename T>
18027 using is_member_object = std::integral_constant<bool, std::is_member_object_pointer_v<T> || is_specialization_of_v<T, readonly_wrapper>>;
18029 template <
typename T>
18032 template <
typename T>
18035 template <
typename T>
18049 template <
typename T>
18063 template <
typename T>
18073 namespace u_detail {
18077 namespace policy_detail {
18078 template <
int I,
int... In>
18080 if constexpr (
sizeof...(In) == 0) {
18091 auto per_dep = [&L, &deps](
int i) {
18092 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
18094 #endif // make sure stack doesn't overflow
18104 template <
int... In>
18117 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
18119 #endif // make sure stack doesn't overflow
18127 template <
typename P, meta::disable<std::is_base_of<detail::policy_base_tag, meta::unqualified_t<P>>> = meta::enabler>
18129 pushed = std::forward<P>(p)(L, pushed);
18133 namespace function_detail {
18135 return luaL_error(L,
"sol: cannot call this constructor (tagged as non-constructible)");
18139 namespace call_detail {
18141 template <
typename R,
typename W>
18146 template <
typename R,
typename W>
18151 template <
typename T,
typename List>
18154 template <
typename T,
typename... Args>
18160 template <
typename T,
bool checked,
bool clean_stack>
18167 : obj_(obj_ptr), obj_lua_ref_(&obj_lua_ref), p_umf_(&umf) {
18170 template <
typename Fx,
std::size_t I,
typename... R,
typename... Args>
18173 int result = stack::call_into_lua<checked, clean_stack>(r, a, L,
start, func, this->obj_);
18177 if constexpr (clean_stack) {
18178 obj_lua_ref_->
push();
18180 obj_lua_ref_->
pop();
18189 namespace overload_detail {
18190 template <
std::size_t... M,
typename Match,
typename... Args>
18192 return luaL_error(L,
"sol: no matching function call takes this number of arguments and the specified types");
18197 int fxarity,
int start, Args&&...
args) {
18200 typedef typename traits::free_args_list args_list;
18202 if constexpr (!traits::runtime_variadics_t::value
18205 std::index_sequence<In...>(),
18206 std::index_sequence<M...>(),
18207 std::forward<Match>(matchfx),
18211 std::forward<Args>(
args)...);
18214 if constexpr (!traits::runtime_variadics_t::value) {
18215 if (traits::free_arity != fxarity) {
18217 std::index_sequence<In...>(),
18218 std::index_sequence<traits::free_arity, M...>(),
18219 std::forward<Match>(matchfx),
18223 std::forward<Args>(
args)...);
18229 std::index_sequence<In...>(),
18230 std::index_sequence<M...>(),
18231 std::forward<Match>(matchfx),
18235 std::forward<Args>(
args)...);
18241 template <
std::size_t... M,
typename Match,
typename... Args>
18243 types<>, std::index_sequence<>, std::index_sequence<M...>, Match&& matchfx,
lua_State* L,
int fxarity,
int start, Args&&...
args) {
18245 std::index_sequence<>(),
18246 std::index_sequence<M...>(),
18247 std::forward<Match>(matchfx),
18251 std::forward<Args>(
args)...);
18256 types<Fx>, std::index_sequence<I>, std::index_sequence<M...>, Match&& matchfx,
lua_State* L,
int fxarity,
int start, Args&&...
args) {
18259 typedef typename traits::free_args_list args_list;
18261 if constexpr (!traits::runtime_variadics_t::value
18264 std::index_sequence<>(),
18265 std::index_sequence<M...>(),
18266 std::forward<Match>(matchfx),
18270 std::forward<Args>(
args)...);
18272 if constexpr (!traits::runtime_variadics_t::value) {
18273 if (traits::free_arity != fxarity) {
18275 std::index_sequence<>(),
18276 std::index_sequence<traits::free_arity, M...>(),
18277 std::forward<Match>(matchfx),
18281 std::forward<Args>(
args)...);
18293 typedef typename traits::free_args_list args_list;
18295 if constexpr (!traits::runtime_variadics_t::value
18298 std::index_sequence<I1, In...>(),
18299 std::index_sequence<M...>(),
18300 std::forward<Match>(matchfx),
18304 std::forward<Args>(
args)...);
18307 if constexpr (!traits::runtime_variadics_t::value) {
18308 if (traits::free_arity != fxarity) {
18310 std::index_sequence<I1, In...>(),
18311 std::index_sequence<traits::free_arity, M...>(),
18312 std::forward<Match>(matchfx),
18316 std::forward<Args>(
args)...);
18322 std::index_sequence<I1, In...>(),
18323 std::index_sequence<M...>(),
18324 std::forward<Match>(matchfx),
18328 std::forward<Args>(
args)...);
18335 template <
typename... Functions,
typename Match,
typename... Args>
18339 std::index_sequence<>(),
18340 std::forward<Match>(matchfx),
18344 std::forward<Args>(
args)...);
18347 template <
typename... Functions,
typename Match,
typename... Args>
18353 template <
typename T,
typename... TypeLists,
typename Match,
typename... Args>
18357 std::forward<Match>(matchfx), L, fxarity,
start, std::forward<Args>(
args)...);
18360 template <
typename T,
bool checked,
bool clean_stack,
typename... TypeLists>
18365 argcount -=
static_cast<int>(
syntax);
18367 T* obj = detail::usertype_allocate<T>(L);
18375 userdataref.
push();
18379 template <
typename T,
bool checked,
bool clean_stack,
typename... TypeLists>
18384 template <
typename F,
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename =
void>
18386 template <
typename Fx,
typename... Args>
18389 static constexpr
bool is_ref = is_lua_reference_v<uFx>;
18390 if constexpr (is_ref) {
18391 if constexpr (is_index) {
18395 std::forward<Fx>(
f) = stack::unqualified_get<F>(L,
boost + (is_variable ? 3 : 1));
18401 using traits_type =
typename wrap::traits_type;
18402 using fp_t =
typename traits_type::function_pointer_type;
18403 constexpr
bool is_function_pointer_convertible = std::is_class_v<uFx> && std::is_convertible_v<std::decay_t<Fx>, fp_t>;
18404 if constexpr (is_function_pointer_convertible) {
18407 L, fx, std::forward<Args>(
args)...);
18410 using returns_list =
typename wrap::returns_list;
18411 using args_list =
typename wrap::free_args_list;
18412 using caller =
typename wrap::caller;
18413 return stack::call_into_lua<checked, clean_stack>(
18414 returns_list(), args_list(), L,
boost + 1, caller(), std::forward<Fx>(
f), std::forward<Args>(
args)...);
18420 template <
typename T,
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18422 template <
typename F>
18424 if constexpr (is_index) {
18426 if constexpr (clean_stack && !is_stack) {
18434 return luaL_error(L,
"sol: cannot write to a readonly (const) variable");
18439 detail::unwrap(
f.value()) = stack::unqualified_get<meta::unwrapped_t<T>>(L,
boost + (is_variable ? 3 : 1));
18446 return luaL_error(L,
"sol: cannot write to this variable: copy assignment/constructor not available");
18453 template <
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18460 template <
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18467 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
18468 template <
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18474 #endif // noexcept function types
18476 template <
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18479 return luaL_error(L, is_index ?
"sol: cannot read from a writeonly property" :
"sol: cannot write to a readonly property");
18483 template <
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18490 template <
typename... Args,
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18498 template <
typename T,
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18502 return alcw.
call(L,
f.get());
18507 bool clean_stack =
true,
typename =
void>
18509 template <
typename Fx,
typename... Args>
18511 if constexpr (std::is_member_function_pointer_v<F>) {
18513 using object_type =
typename wrap::object_type;
18514 if constexpr (
sizeof...(Args) < 1) {
18516 static_assert(std::is_base_of_v<object_type, Ta>,
18517 "It seems like you might have accidentally bound a class type with a member function method that does not correspond to the "
18518 "class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one class \"T\" "
18519 "but then bind member methods from a complete unrelated class. Check things over!");
18520 #if SOL_IS_ON(SOL_SAFE_USERTYPE)
18521 auto maybeo = stack::check_get<Ta*>(L, 1);
18522 if (!maybeo || maybeo.value() ==
nullptr) {
18524 "sol: received nil for 'self' argument (use ':' for accessing member functions, make sure member variables are "
18525 "preceeded by the "
18526 "actual object with '.' syntax)");
18528 object_type* o =
static_cast<object_type*
>(maybeo.value());
18529 return call(L, std::forward<Fx>(fx), *o);
18531 object_type& o =
static_cast<object_type&
>(*stack::unqualified_get<non_null<Ta*>>(L, 1));
18532 return call(L, std::forward<Fx>(fx), o);
18536 using returns_list =
typename wrap::returns_list;
18537 using args_list =
typename wrap::args_list;
18538 using caller =
typename wrap::caller;
18539 return stack::call_into_lua<checked, clean_stack>(
18540 returns_list(), args_list(), L,
boost + (is_variable ? 3 : 2), caller(), std::forward<Fx>(fx), std::forward<Args>(
args)...);
18543 else if constexpr (std::is_member_object_pointer_v<F>) {
18545 using object_type =
typename wrap::object_type;
18546 if constexpr (is_index) {
18547 if constexpr (
sizeof...(Args) < 1) {
18549 static_assert(std::is_base_of_v<object_type, Ta>,
18550 "It seems like you might have accidentally bound a class type with a member function method that does not correspond "
18551 "to the class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one "
18552 "class \"T\" but then bind member methods from a complete unrelated class. Check things over!");
18553 #if SOL_IS_ON(SOL_SAFE_USERTYPE)
18554 auto maybeo = stack::check_get<Ta*>(L, 1);
18555 if (!maybeo || maybeo.value() ==
nullptr) {
18557 return luaL_error(L,
"sol: 'self' argument is lua_nil (bad '.' access?)");
18559 return luaL_error(L,
"sol: 'self' argument is lua_nil (pass 'self' as first argument)");
18561 object_type* o =
static_cast<object_type*
>(maybeo.value());
18562 return call(L, std::forward<Fx>(fx), *o);
18564 object_type& o =
static_cast<object_type&
>(*stack::get<non_null<Ta*>>(L, 1));
18565 return call(L, std::forward<Fx>(fx), o);
18569 using returns_list =
typename wrap::returns_list;
18570 using caller =
typename wrap::caller;
18571 return stack::call_into_lua<checked, clean_stack>(returns_list(),
18574 boost + (is_variable ? 3 : 2),
18576 std::forward<Fx>(fx),
18577 std::forward<Args>(
args)...);
18582 using return_type =
typename traits_type::return_type;
18583 constexpr
bool ret_is_const = std::is_const_v<std::remove_reference_t<return_type>>;
18584 if constexpr (ret_is_const) {
18587 return luaL_error(L,
"sol: cannot write to a readonly (const) variable");
18591 constexpr
bool is_assignable = std::is_copy_assignable_v<u_return_type> || std::is_array_v<u_return_type>;
18592 if constexpr (!is_assignable) {
18595 return luaL_error(L,
"sol: cannot write to this variable: copy assignment/constructor not available");
18598 using args_list =
typename wrap::args_list;
18599 using caller =
typename wrap::caller;
18600 if constexpr (
sizeof...(Args) > 0) {
18601 return stack::call_into_lua<checked, clean_stack>(
types<void>(),
18604 boost + (is_variable ? 3 : 2),
18606 std::forward<Fx>(fx),
18607 std::forward<Args>(
args)...);
18611 #if SOL_IS_ON(SOL_SAFE_USERTYPE)
18612 auto maybeo = stack::check_get<Ta*>(L, 1);
18613 if (!maybeo || maybeo.value() ==
nullptr) {
18615 return luaL_error(L,
"sol: received nil for 'self' argument (bad '.' access?)");
18617 return luaL_error(L,
"sol: received nil for 'self' argument (pass 'self' as first argument)");
18619 object_type* po =
static_cast<object_type*
>(maybeo.value());
18620 object_type& o = *po;
18622 object_type& o =
static_cast<object_type&
>(*stack::get<non_null<Ta*>>(L, 1));
18625 return stack::call_into_lua<checked, clean_stack>(
18626 types<void>(), args_list(), L,
boost + (is_variable ? 3 : 2), caller(), std::forward<Fx>(fx), o);
18634 return alcw.
call(L, std::forward<Fx>(fx), std::forward<Args>(
args)...);
18639 template <
typename T,
typename F,
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18646 if constexpr (!is_index) {
18648 return luaL_error(L,
"sol: cannot write to a sol::readonly variable");
18657 if constexpr (!is_index) {
18663 return lcw.
call(L, rw.value(), o);
18668 if constexpr (!is_index) {
18670 return luaL_error(L,
"sol: cannot write to a sol::readonly variable");
18679 if constexpr (!is_index) {
18681 return call(L, rw);
18690 template <
typename T,
typename... Args,
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18698 argcount -=
static_cast<int>(
syntax);
18700 T* obj = detail::usertype_allocate<T>(L);
18713 userdataref.
push();
18718 template <
typename T,
typename... Cxs,
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18723 template <
typename Fx,
std::size_t I,
typename... R,
typename... Args>
18726 T* obj = detail::usertype_allocate<T>(L);
18731 auto& func = std::get<I>(
f.functions);
18736 userdataref.
push();
18743 int syntaxval =
static_cast<int>(
syntax);
18745 return construct_match<T, meta::pop_front_type_t<meta::function_args_t<Cxs>>...>(onmatch(), L, argcount, 1 + syntaxval,
f);
18749 template <
typename T,
typename Fx,
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18752 template <
typename F>
18754 if constexpr (std::is_void_v<Fx>) {
18755 return detail::usertype_alloc_destroy<T>(L);
18760 return lcw.
call(L, std::forward<F>(
f).fx);
18765 template <
typename T,
typename... Fs,
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18770 template <
typename Fx,
std::size_t I,
typename... R,
typename... Args>
18782 template <
typename T,
typename... Fs,
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18787 template <
typename Fx,
std::size_t I,
typename... R,
typename... Args>
18799 template <
typename T,
typename R,
typename W,
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18807 template <
typename F,
typename... Args>
18813 std::is_member_pointer<U>>::value;
18814 if constexpr (is_specialized) {
18815 if constexpr (is_index) {
18816 decltype(
auto) p =
f.read();
18818 return lcw.call(L, p, std::forward<Args>(
args)...);
18821 decltype(
auto) p =
f.write();
18823 return lcw.call(L, p, std::forward<Args>(
args)...);
18829 if constexpr (non_class_object_type) {
18834 if constexpr (is_index) {
18835 decltype(
auto) pf =
f.read();
18836 return stack::call_into_lua<checked, clean_stack>(
18837 returns_list(), args_list(), L,
boost + (is_variable ? 3 : 2), caller(), pf);
18840 decltype(
auto) pf =
f.write();
18841 return stack::call_into_lua<checked, clean_stack>(
18842 returns_list(), args_list(), L,
boost + (is_variable ? 3 : 2), caller(), pf);
18848 using Oa = std::remove_pointer_t<object_type>;
18849 #if SOL_IS_ON(SOL_SAFE_USERTYPE)
18850 auto maybeo = stack::check_get<Ta*>(L, 1);
18851 if (!maybeo || maybeo.value() ==
nullptr) {
18853 return luaL_error(L,
"sol: 'self' argument is lua_nil (bad '.' access?)");
18855 return luaL_error(L,
"sol: 'self' argument is lua_nil (pass 'self' as first argument)");
18857 Oa* o =
static_cast<Oa*
>(maybeo.value());
18859 Oa* o =
static_cast<Oa*
>(stack::get<non_null<Ta*>>(L, 1));
18863 if constexpr (is_index) {
18864 decltype(
auto) pf =
f.read();
18865 return stack::call_into_lua<checked, clean_stack>(
18869 decltype(
auto) pf =
f.write();
18870 return stack::call_into_lua<checked, clean_stack>(
18878 template <
typename T,
typename V,
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18882 template <
typename... Args>
18888 template <
typename T,
typename F,
typename... Policies,
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18901 return call(indices(), L, fx);
18905 template <
typename T,
typename Y,
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18907 template <
typename F>
18913 template <
typename T,
typename Sig,
typename P,
bool is_index,
bool is_variable,
bool checked,
int boost,
bool clean_stack,
typename C>
18917 return lcw.call(L, std::get<0>(
f.arguments));
18922 return lcw.call(L, std::get<0>(
f.arguments));
18927 return lcw.call(L, std::get<0>(
std::move(
f.arguments)));
18932 typename Fx,
typename... Args>
18935 if constexpr (meta::is_specialization_of_v<uFx, yielding_t>) {
18938 return lcw.
call(L, std::forward<Fx>(fx).func, std::forward<Args>(
args)...);
18942 return lcw.
call(L, std::forward<Fx>(fx), std::forward<Args>(
args)...);
18947 bool clean_stack =
true>
18951 int nr = call_wrapped<T, is_index, is_variable, 0, checked, clean_stack>(L, fx);
18952 if constexpr (meta::is_specialization_of_v<uFx, yielding_t>) {
18960 template <
typename T,
typename =
void>
18963 template <
typename T>
18966 template <
typename T>
18972 template <
typename R,
typename W>
18975 template <
typename T>
18978 template <
typename T>
18981 template <
typename F,
typename... Policies>
18985 template <
typename T>
18988 template <
typename T>
18991 template <
typename T>
18999 namespace function_detail {
19000 template <
typename F, F fx>
19003 typedef typename traits_type::args_list args_list;
19008 template <
typename R,
typename V, V,
typename T>
19010 return luaL_error(L,
"cannot write to this type: copy assignment/constructor not available");
19013 template <
typename R,
typename V, V variable,
typename T>
19015 (mem.*variable) = stack::get<R>(L, 2);
19019 template <
typename R,
typename V, V,
typename T>
19021 return luaL_error(L,
"cannot write to a const variable");
19024 template <
typename R,
typename V, V variable,
typename T>
19026 return call_set_assignable<R, V, variable>(std::is_assignable<std::add_lvalue_reference_t<R>, R>(), L, std::forward<T>(mem));
19029 template <
typename V, V variable>
19032 typedef typename traits_type::object_type T;
19033 typedef typename traits_type::return_type R;
19034 auto& mem = stack::get<T>(L, 1);
19037 decltype(
auto) r = (mem.*variable);
19042 return call_set_variable<R, V, variable>(
meta::neg<std::is_const<R>>(), L, mem);
19044 return luaL_error(L,
"incorrect number of arguments to member variable function call");
19048 template <
typename F, F fx>
19050 return call_wrapper_variable<F, fx>(std::is_member_object_pointer<F>(), L);
19053 template <
typename F, F fx>
19055 return call_detail::call_wrapped<void, false, false>(L, fx);
19058 template <
typename F, F fx>
19063 template <
typename... Fxs>
19065 template <
typename Fx,
std::size_t I,
typename R,
typename... Args>
19072 template <
typename F, F fx>
19077 template <
typename F, F fx>
19083 #endif // fuck you clang :c
19088 template <
typename F, F fx>
19091 typedef std::integral_constant<bool,
19092 std::is_same<Fu, lua_CFunction>::value
19093 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
19094 || std::is_same<Fu, detail::lua_CFunction_noexcept>::value
19098 return function_detail::c_call_raw<F, fx>(is_raw(), L);
19101 template <
typename F, F f>
19106 return c_call<type, f>(L);
19110 template <
typename... Fxs>
19112 if constexpr (
sizeof...(Fxs) < 2) {
19127 namespace sol {
namespace function_detail {
19128 template <
typename Function>
19134 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19137 noexcept(traits_type::is_noexcept)
19140 auto udata = stack::stack_detail::get_as_upvalues<function_type*>(L);
19142 return call_detail::call_wrapped<void, true, false>(L, fx);
19145 template <
bool is_yielding,
bool no_trampoline>
19148 if constexpr (no_trampoline) {
19152 nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
19163 template <
typename T,
typename Function>
19169 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19172 noexcept(traits_type::is_noexcept)
19181 auto& item = *
static_cast<T*
>(stack::get<void*>(L,
upvalue_index(3)));
19185 template <
bool is_yielding,
bool no_trampoline>
19187 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19190 noexcept(traits_type::is_noexcept)
19194 if constexpr (no_trampoline) {
19198 nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
19209 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19212 noexcept(traits_type::is_noexcept)
19219 template <
typename T,
typename Function>
19225 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19228 noexcept(traits_type::is_noexcept)
19236 auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
19237 auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
19238 auto& mem = *objdata.first;
19246 return luaL_error(L,
"sol: incorrect number of arguments to member variable function");
19250 template <
bool is_yielding,
bool no_trampoline>
19252 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19255 noexcept(traits_type::is_noexcept)
19259 if constexpr (no_trampoline) {
19263 nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
19274 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19277 noexcept(traits_type::is_noexcept)
19284 template <
typename T,
typename Function>
19290 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19293 noexcept(traits_type::is_noexcept)
19301 auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
19302 auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
19303 auto& mem = *objdata.first;
19309 return luaL_error(L,
"sol: incorrect number of arguments to member variable function");
19313 template <
bool is_yielding,
bool no_trampoline>
19315 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19318 noexcept(traits_type::is_noexcept)
19322 if constexpr (no_trampoline) {
19326 nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
19337 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19340 noexcept(traits_type::is_noexcept)
19347 template <
typename T,
typename Function>
19353 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19356 noexcept(traits_type::is_noexcept)
19362 return call_detail::call_wrapped<T, false, false>(L, memfx);
19365 template <
bool is_yielding,
bool no_trampoline>
19367 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19370 noexcept(traits_type::is_noexcept)
19374 if constexpr (no_trampoline) {
19378 nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
19389 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19392 noexcept(traits_type::is_noexcept)
19399 template <
typename T,
typename Function>
19406 auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
19410 return call_detail::call_wrapped<T, true, false>(L,
var);
19412 return call_detail::call_wrapped<T, false, false>(L,
var);
19414 return luaL_error(L,
"sol: incorrect number of arguments to member variable function");
19418 template <
bool is_yielding,
bool no_trampoline>
19421 if constexpr (no_trampoline) {
19425 nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
19440 template <
typename T,
typename Function>
19448 auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
19452 return call_detail::call_wrapped<T, true, false>(L,
var);
19454 return luaL_error(L,
"sol: incorrect number of arguments to member variable function");
19458 template <
bool is_yielding,
bool no_trampoline>
19461 if constexpr (no_trampoline) {
19465 nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
19485 namespace sol {
namespace function_detail {
19486 template <
typename Func,
bool is_yielding,
bool no_trampoline>
19491 template <
typename... Args>
19497 int nr = call_detail::call_wrapped<void, true, false>(L,
self.invocation);
19507 if constexpr (no_trampoline) {
19508 return call(L, *
this);
19516 template <
typename T,
typename Function,
bool is_yielding,
bool no_trampoline>
19525 template <
typename... Args>
19527 std::is_nothrow_constructible_v<function_type, function_type>&& std::is_nothrow_constructible_v<T, Args...>)
19532 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19535 noexcept(traits_type::is_noexcept)
19548 #if SOL_IS_ON(SOL_COMPILER_VCXX)
19551 noexcept(traits_type::is_noexcept)
19554 if constexpr (no_trampoline) {
19555 return call(L, *
this);
19563 template <
typename T,
typename Function,
bool is_yielding,
bool no_trampoline>
19572 template <
typename... Args>
19574 std::is_nothrow_constructible_v<function_type, function_type>&& std::is_nothrow_constructible_v<T, Args...>)
19590 nr =
luaL_error(L,
"sol: incorrect number of arguments to member variable function");
19603 if constexpr (no_trampoline) {
19604 return call(L, *
this);
19617 namespace sol {
namespace function_detail {
19618 template <
int start_skew,
typename... Functions>
19630 template <
typename Fx,
std::size_t I,
typename... R,
typename... Args>
19632 auto& func = std::get<I>(ol);
19633 int nr = call_detail::call_wrapped<void, true, false, start_skew>(L, func);
19638 template <
typename... Args>
19640 return call(std::forward<Args>(
args)...);
19661 template <
typename R,
typename... Args,
typename F,
typename = std::invoke_result_t<meta::unqualified_t<F>, Args...>>
19663 using Sig = R(Args...);
19665 return static_cast<Sig Fu::*
>(&Fu::operator());
19668 template <
typename F,
typename U = meta::unqualified_t<F>>
19674 template <
typename F>
19676 static_assert(meta::call_operator_deducible_v<F>,
"Cannot use no-template-parameter call with an overloaded functor: specify the signature");
19679 template <
typename F,
typename U = meta::unqualified_t<F>>
19689 template <
typename Sig,
typename C>
19691 return mem_func_ptr;
19694 template <
typename Sig,
typename C>
19696 return mem_variable_ptr;
19700 template <
typename... Args,
typename R>
19701 inline constexpr
auto resolve(R fun_ptr(Args...)) -> R (*)(Args...) {
19705 template <
typename Sig>
19710 template <
typename... Args,
typename R,
typename C>
19711 inline constexpr
auto resolve(R (
C::*mem_ptr)(Args...)) -> R (
C::*)(Args...) {
19715 template <
typename Sig,
typename C>
19720 template <
typename... Sig,
typename F, meta::disable<std::is_function<meta::unqualified_t<F>>> =
meta::enabler>
19730 template <
typename R,
typename... Args,
typename F,
typename = std::invoke_result_t<meta::unqualified_t<F>, Args...>>
19731 inline auto resolve_i(types<R(Args...)>, F&&) -> R (meta::unqualified_t<F>::*)(Args...) {
19732 using Sig = R(Args...);
19733 typedef meta::unqualified_t<F> Fu;
19734 return static_cast<Sig Fu::*
>(&Fu::operator());
19737 template <
typename F,
typename U = meta::unqualified_t<F>>
19743 template <
typename F>
19745 static_assert(meta::call_operator_deducible_v<F>,
"Cannot use no-template-parameter call with an overloaded functor: specify the signature");
19748 template <
typename F,
typename U = meta::unqualified_t<F>>
19749 inline auto resolve_i(types<>, F&& f) -> decltype(
resolve_f(meta::call_operator_deducible<U>(), std::forward<F>(f))) {
19750 return resolve_f(meta::call_operator_deducible<U> {}, std::forward<F>(f));
19754 inline auto resolve_i(types<Args...>, F&& f) -> decltype(
resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
19755 return resolve_i(types<R(Args...)>(), std::forward<F>(f));
19758 template <
typename Sig,
typename C>
19760 return mem_func_ptr;
19763 template <
typename Sig,
typename C>
19765 return mem_variable_ptr;
19769 template <
typename... Args,
typename R>
19770 inline auto resolve(R fun_ptr(Args...)) -> R (*)(Args...) {
19774 template <
typename Sig>
19775 inline Sig*
resolve(Sig* fun_ptr) {
19779 template <
typename... Args,
typename R,
typename C>
19780 inline auto resolve(R (
C::*mem_ptr)(Args...)) -> R (
C::*)(Args...) {
19784 template <
typename Sig,
typename C>
19785 inline Sig
C::*
resolve(Sig
C::*mem_ptr) {
19789 template <
typename... Sig,
typename F>
19801 namespace function_detail {
19802 template <
typename T>
19809 template <
bool yielding>
19821 template <
bool yielding>
19835 template <
bool is_yielding,
bool no_trampoline,
typename Fx,
typename... Args>
19838 template <
bool is_yielding,
bool no_trampoline,
typename Fx,
typename... Args>
19840 lua_CFunction freefunc = no_trampoline ? function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>
19841 : detail::static_trampoline<function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>>;
19845 upvalues += stack::push<user<Fx>>(L, std::forward<Args>(
args)...);
19849 template <
bool is_yielding,
bool no_trampoline,
typename R,
typename... A,
typename Fx,
typename... Args>
19851 using dFx = std::decay_t<meta::unwrap_unqualified_t<Fx>>;
19852 using fx_ptr_t = R (*)(A...);
19853 constexpr
bool is_convertible = std::is_convertible_v<dFx, fx_ptr_t>;
19854 if constexpr (is_convertible) {
19856 select<is_yielding, no_trampoline>(L,
std::move(fxptr), std::forward<Args>(
args)...);
19860 select_set_fx<is_yielding, no_trampoline, F>(L, std::forward<Fx>(fx), std::forward<Args>(
args)...);
19864 template <
bool is_yielding,
bool no_trampoline,
typename Fx,
typename... Args>
19867 select_convertible<is_yielding, no_trampoline>(
types<Sig>(), L, std::forward<Fx>(fx), std::forward<Args>(
args)...);
19870 template <
bool is_yielding,
bool no_trampoline,
typename Fx,
typename... Args>
19873 if constexpr (
sizeof...(Args) < 1) {
19882 else if constexpr (
sizeof...(Args) < 2) {
19884 constexpr
bool is_reference = meta::is_specialization_of_v<Tu, std::reference_wrapper> || std::is_pointer_v<Tu>;
19885 if constexpr (meta::is_specialization_of_v<Tu, function_detail::class_indicator>) {
19894 else if constexpr (is_reference) {
19895 typedef std::decay_t<Fx> dFx;
19896 dFx memfxptr(std::forward<Fx>(fx));
19904 upvalues +=
stack::push(L,
static_cast<void const*
>(userptr));
19908 using clean_fx = std::remove_pointer_t<std::decay_t<Fx>>;
19910 select_set_fx<is_yielding, no_trampoline, F>(L, std::forward<Fx>(fx), std::forward<Args>(
args)...);
19915 using clean_fx = std::remove_pointer_t<std::decay_t<Fx>>;
19917 select_set_fx<is_yielding, no_trampoline, F>(L, std::forward<Fx>(fx), std::forward<Args>(
args)...);
19921 template <
bool is_yielding,
bool no_trampoline,
typename Fx,
typename T,
typename... Args>
19923 using dFx = std::decay_t<Fx>;
19925 if constexpr (meta::is_specialization_of_v<Tu, function_detail::class_indicator>) {
19932 upvalues += stack::push<user<dFx>>(L, std::forward<Fx>(fx), std::forward<Args>(
args)...);
19936 constexpr
bool is_reference = meta::is_specialization_of_v<Tu, std::reference_wrapper> || std::is_pointer_v<Tu>;
19937 if constexpr (is_reference) {
19938 auto userptr =
detail::ptr(std::forward<T>(obj));
19944 upvalues += stack::push<user<dFx>>(L, std::forward<Fx>(fx), std::forward<Args>(
args)...);
19950 select_set_fx<is_yielding, no_trampoline, F>(L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(
args)...);
19955 template <
bool is_yielding,
bool no_trampoline,
typename Fx,
typename... Args>
19957 using dFx = std::decay_t<Fx>;
19958 if constexpr (
sizeof...(Args) < 1) {
19964 upvalues += stack::push<user<dFx>>(L, std::forward<Fx>(fx));
19968 select_member_function_with<is_yielding, no_trampoline>(L, std::forward<Fx>(fx), std::forward<Args>(
args)...);
19972 template <
bool is_yielding,
bool no_trampoline,
typename Fx,
typename... Args>
19975 if constexpr (is_lua_reference_v<uFx>) {
19979 else if constexpr (is_lua_c_function_v<uFx>) {
19980 if constexpr (no_trampoline) {
19984 upvalues +=
stack::push(L, std::forward<Fx>(fx));
19985 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
19986 if constexpr (std::is_nothrow_invocable_r_v<int, uFx, lua_State*>) {
20004 upvalues +=
stack::push(L, std::forward<Fx>(fx));
20005 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
20006 if constexpr (std::is_nothrow_invocable_r_v<int, uFx, lua_State*>) {
20011 lua_CFunction cf = &function_detail::lua_c_wrapper<is_yielding>;
20015 lua_CFunction cf = &function_detail::lua_c_wrapper<is_yielding>;
20020 else if constexpr (std::is_function_v<std::remove_pointer_t<uFx>>) {
20021 std::decay_t<Fx> target(std::forward<Fx>(fx), std::forward<Args>(
args)...);
20029 else if constexpr (std::is_member_function_pointer_v<uFx>) {
20030 select_member_function<is_yielding, no_trampoline>(L, std::forward<Fx>(fx), std::forward<Args>(
args)...);
20032 else if constexpr (meta::is_member_object_v<uFx>) {
20033 select_member_variable<is_yielding, no_trampoline>(L, std::forward<Fx>(fx), std::forward<Args>(
args)...);
20036 select_convertible<is_yielding, no_trampoline>(
types<>(), L, std::forward<Fx>(fx), std::forward<Args>(
args)...);
20042 template <
typename... Sigs>
20044 template <
bool is_yielding,
typename Arg0,
typename... Args>
20047 if constexpr (is_yielding) {
20048 return stack::push<meta::unqualified_t<Arg0>>(L,
detail::yield_tag, std::forward<Arg0>(arg0), std::forward<Args>(
args)...);
20051 return stack::push(L, std::forward<Arg0>(arg0), std::forward<Args>(
args)...);
20055 function_detail::select<is_yielding, false>(L, std::forward<Arg0>(arg0), std::forward<Args>(
args)...);
20060 template <
typename Arg0,
typename... Args>
20063 push_yielding<true>(L, std::forward<Args>(
args)...);
20066 push_yielding<true>(L, std::forward<Arg0>(arg0).func, std::forward<Args>(
args)...);
20069 push_yielding<false>(L, std::forward<Arg0>(arg0), std::forward<Args>(
args)...);
20075 template <
typename T>
20077 template <
typename... Args>
20083 function_detail::select<true, false>(L,
f.func, std::forward<Args>(
args)...);
20088 template <
typename... Args>
20094 function_detail::select<true, false>(L,
std::move(
f.func), std::forward<Args>(
args)...);
20100 template <
typename T,
typename... Args>
20104 return stack::push<T>(L, std::get<I>(std::forward<FP>(
fp).arguments)...);
20116 template <
typename Signature>
20122 function_detail::select_set_fx<true, false, TargetFunctor>(L, fx);
20130 function_detail::select_set_fx<true, false, TargetFunctor>(L,
std::move(fx));
20138 function_detail::select_set_fx<false, false, TargetFunctor>(L, fx);
20146 function_detail::select_set_fx<false, false, TargetFunctor>(L,
std::move(fx));
20153 template <
typename Signature>
20155 template <
typename... Args>
20157 function_detail::select<false, false>(L, std::forward<Args>(
args)...);
20162 template <
typename Signature>
20164 std::
enable_if_t<meta::all<std::is_function<std::remove_pointer_t<Signature>>, meta::neg<std::is_same<Signature, lua_CFunction>>,
20165 meta::neg<std::is_same<Signature, std::remove_pointer_t<lua_CFunction>>>
20166 #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
20168 meta::neg<std::is_same<Signature, detail::lua_CFunction_noexcept>>,
20169 meta::neg<std::is_same<Signature, std::remove_pointer_t<detail::lua_CFunction_noexcept>>>
20172 template <
typename F>
20174 function_detail::select<false, true>(L, std::forward<F>(
f));
20179 template <
typename... Functions>
20183 function_detail::select_set_fx<false, false, F>(L,
std::move(
set.functions));
20189 function_detail::select_set_fx<false, false, F>(L,
set.functions);
20194 template <
typename T>
20197 lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>, 2>;
20200 upvalues += stack::push<user<protect_t<T>>>(L,
std::move(pw.value));
20205 lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>, 2>;
20208 upvalues += stack::push<user<protect_t<T>>>(L, pw.value);
20213 template <
typename F,
typename G>
20216 if constexpr (std::is_void_v<F>) {
20219 else if constexpr (std::is_void_v<G>) {
20228 if constexpr (std::is_void_v<F>) {
20231 else if constexpr (std::is_void_v<G>) {
20240 template <
typename T>
20250 template <
typename... Functions>
20254 function_detail::select_set_fx<false, false, F>(L, fw.
functions);
20260 function_detail::select_set_fx<false, false, F>(L,
std::move(fw.functions));
20266 function_detail::select_set_fx<false, false, F>(L, fw.
functions);
20272 function_detail::select_set_fx<false, false, F>(L,
std::move(fw.functions));
20289 template <
typename T>
20302 template <
typename T,
typename... Lists>
20315 template <
typename L0,
typename... Lists>
20320 return stack::push<detail::tagged<T, cl_t>>(L, cl);
20324 template <
typename T,
typename... Fxs>
20331 return push(L, c.value());
20351 template <
typename F,
typename... Fxs>
20366 template <
typename T>
20374 template <
typename T,
typename Fx>
20377 lua_CFunction cf = call_detail::call_user<T, false, false, destructor_wrapper<Fx>, 2>;
20380 upvalues += stack::push<user<destructor_wrapper<Fx>>>(L,
std::move(c));
20385 lua_CFunction cf = call_detail::call_user<T, false, false, destructor_wrapper<Fx>, 2>;
20388 upvalues += stack::push<user<destructor_wrapper<Fx>>>(L, c);
20393 template <
typename Fx>
20396 lua_CFunction cf = call_detail::call_user<void, false, false, destructor_wrapper<Fx>, 2>;
20399 upvalues += stack::push<user<destructor_wrapper<Fx>>>(L,
std::move(c));
20404 lua_CFunction cf = call_detail::call_user<void, false, false, destructor_wrapper<Fx>, 2>;
20407 upvalues += stack::push<user<destructor_wrapper<Fx>>>(L, c);
20412 template <
typename F,
typename... Policies>
20417 lua_CFunction cf = call_detail::call_user<void, false, false, P, 2>;
20420 upvalues += stack::push<user<P>>(L, p);
20425 lua_CFunction cf = call_detail::call_user<void, false, false, P, 2>;
20428 upvalues += stack::push<user<P>>(L,
std::move(p));
20433 template <
typename T,
typename F,
typename... Policies>
20439 lua_CFunction cf = call_detail::call_user<T, false, false, P, 2>;
20442 upvalues += stack::push<user<P>>(L, p.
value());
20447 lua_CFunction cf = call_detail::call_user<T, false, false, P, 2>;
20450 upvalues += stack::push<user<P>>(L,
std::move(p.value()));
20455 template <
typename T>
20467 if constexpr (std::is_invocable_v<const T, lua_State*>) {
20476 namespace stack_detail {
20477 template <
typename Function,
typename Handler>
20479 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
20486 success = upvalue_name !=
nullptr;
20503 template <
typename Function>
20505 #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
20507 auto udata = stack::stack_detail::get_as_upvalues_using_function<Function*>(L,
index);
20508 Function* fx = udata.first;
20516 "You are attempting to retrieve a function pointer type. "
20517 "This is inherently unsafe in sol2. In order to do this, you must turn on the "
20518 "SOL_GET_FUNCTION_POINTER_UNSAFE configuration macro, as detailed in the documentation. "
20519 "Please be careful!"
20521 "You are attempting to retrieve a function pointer type. "
20522 "You explicitly turned off the ability to do this by defining "
20523 "SOL_GET_FUNCTION_POINTER_UNSAFE or similar to be off. "
20524 "Please reconsider this!"
20539 #include <exception>
20548 dump_error(
int error_code_) :
error(
"dump returned non-zero error of " +
std::to_string(error_code_)), m_ec(error_code_) {
20558 (
void)writer_function;
20559 (
void)userdata_pointer_;
20561 return result_code;
20566 (
void)writer_function;
20567 (
void)userdata_pointer_;
20569 return luaL_error(L_,
"a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code);
20573 #if SOL_IS_OFF(SOL_EXCEPTIONS)
20577 (
void)writer_function;
20578 (
void)userdata_pointer_;
20581 #endif // no exceptions stuff
20591 template <
typename ref_t,
bool aligned = false>
20592 class basic_function :
public basic_object<ref_t> {
20596 void luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount)
const {
20597 lua_call(lua_state(),
static_cast<int>(argcount),
static_cast<int>(resultcount));
20602 luacall(n,
lua_size<std::tuple<Ret...>>::value);
20603 return stack::pop<std::tuple<Ret...>>(lua_state());
20606 template <std::
size_t I,
typename Ret, meta::enable<meta::neg<std::is_
void<Ret>>> = meta::enabler>
20609 return stack::pop<Ret>(lua_state());
20612 template <std::
size_t I>
20619 int firstreturn = (std::max)(1,
stacksize -
static_cast<int>(n));
20621 int poststacksize =
lua_gettop(lua_state());
20622 int returncount = poststacksize - (firstreturn - 1);
20627 using base_t::lua_state;
20630 template <
typename T,
20634 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20638 stack::check<basic_function>(lua_state(), -1,
handler);
20652 template <
typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
20654 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20657 stack::check<basic_function>(lua_state(), -1,
handler);
20661 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20667 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20670 stack::check<basic_function>(lua_state(), -1,
handler);
20674 template <
typename Fx>
20689 template <
typename Container =
bytecode>
20696 template <
typename Container =
bytecode,
typename Fx>
20699 (
void)dump(
static_cast<lua_Writer>(&basic_insert_dump_writer<Container>),
static_cast<void*
>(&bc),
false, std::forward<Fx>(on_error));
20703 template <
typename... Args>
20705 return call<>(std::forward<Args>(
args)...);
20708 template <
typename... Ret,
typename... Args>
20709 decltype(
auto) operator()(
types<Ret...>, Args&&...
args)
const {
20710 return call<Ret...>(std::forward<Args>(
args)...);
20713 template <
typename... Ret,
typename... Args>
20714 decltype(
auto) call(Args&&...
args)
const {
20734 static const char name[9] =
"sol.\xF0\x9F\x94\xA9";
20738 template <
bool ShouldPush,
typename Target = reference>
20753 stack_index = target.stack_index();
20765 if constexpr (!is_stack_based_v<Target>) {
20766 if (stack_index != 0) {
20773 template <
typename Base,
typename T>
20778 template <
typename Reference,
bool IsMainReference = false>
20780 if (is_stack_based_v<Reference> || L_ ==
nullptr)
20781 return Reference(L_,
lua_nil);
20785 return Reference(L_, -1);
20788 template <
typename T>
20790 if (L ==
nullptr) {
20793 if (!ref.valid()) {
20794 #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
20796 #endif // make sure stack doesn't overflow
20810 #include <algorithm>
20815 template <
bool ShouldPush_,
typename Handler_>
20820 handler_.
target.push(L_);
20830 template <
typename Reference,
bool Aligned = false,
typename Handler = reference>
20831 class basic_protected_function :
public basic_object<Reference> {
20835 inline static constexpr
bool is_stack_handler_v = is_stack_based_v<handler_t>;
20838 :
base_t(other_), m_error_handler(other_.m_error_handler.copy(lua_state())) {
20846 template <
typename T,
20851 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20855 stack::check<basic_protected_function>(lua_state(), -1,
handler);
20863 base_t::operator=(other_);
20864 if constexpr (is_stateless_lua_reference_v<Handler>) {
20865 m_error_handler.copy_assign(lua_state(), other_.m_error_handler);
20868 m_error_handler = other_.m_error_handler;
20891 template <
typename Super>
20894 template <
typename Super>
20897 template <
typename Proxy,
typename HandlerReference,
20904 template <
typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
20907 template <
typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
20909 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20912 stack::check<basic_protected_function>(lua_state(), -1,
handler);
20922 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20924 stack::check<basic_protected_function>(L_, index_,
handler);
20930 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20932 stack::check<basic_protected_function>(L_, index_,
handler);
20938 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20940 stack::check<basic_protected_function>(L_, index_,
handler);
20946 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
20949 stack::check<basic_protected_function>(lua_state(), -1,
handler);
20953 using base_t::lua_state;
20955 template <
typename Fx>
20959 int r =
lua_dump(this->lua_state(),
writer, userdata_pointer_, strip ? 1 : 0);
20961 return on_error(this->lua_state(), r,
writer, userdata_pointer_, strip);
20970 template <
typename Container =
bytecode>
20977 template <
typename Container =
bytecode,
typename Fx>
20980 (
void)dump(
static_cast<lua_Writer>(&basic_insert_dump_writer<Container>),
static_cast<void*
>(&bc),
false, std::forward<Fx>(on_error));
20984 template <
typename... Args>
20986 return call<>(std::forward<Args>(
args)...);
20989 template <
typename... Ret,
typename... Args>
20990 decltype(
auto) operator()(
types<Ret...>, Args&&...
args)
const {
20991 return call<Ret...>(std::forward<Args>(
args)...);
20994 template <
typename... Ret,
typename... Args>
20995 decltype(
auto) call(Args&&...
args)
const {
20996 if constexpr (!Aligned) {
20998 if (m_error_handler.valid(lua_state())) {
21013 if (m_error_handler.valid()) {
21017 if constexpr (!is_stack_handler_v) {
21022 if constexpr (!is_stack_handler_v) {
21038 if constexpr (is_stateless_lua_reference_v<handler_t>) {
21039 this->m_error_handler.reset(lua_state());
21044 return detail::get_default_handler<handler_t, is_main_threaded_v<base_t>>(L_);
21047 template <
typename T>
21053 if constexpr (is_stateless_lua_reference_v<handler_t>) {
21054 if constexpr (is_stack_based_v<handler_t>) {
21062 return m_error_handler;
21066 template <
typename ErrorHandler_>
21068 static_assert(!is_stack_based_v<handler_t> || is_stack_based_v<ErrorHandler_>,
21069 "A stack-based error handler can only be set from a parameter that is also stack-based.");
21070 if constexpr (std::is_rvalue_reference_v<ErrorHandler_>) {
21071 m_error_handler = std::forward<ErrorHandler_>(error_handler_);
21074 m_error_handler.copy_assign(lua_state(), std::forward<ErrorHandler_>(error_handler_));
21079 this->m_error_handler.abandon();
21091 template <
std::size_t... I,
bool b,
typename... Ret>
21093 luacall(n,
sizeof...(Ret), h);
21094 return stack::pop<std::tuple<Ret...>>(lua_state());
21097 template <std::
size_t I,
bool b,
typename Ret>
21100 return stack::pop<Ret>(lua_state());
21103 template <std::
size_t I,
bool b>
21112 int firstreturn = 1;
21113 int returncount = 0;
21115 #if SOL_IS_ON(SOL_EXCEPTIONS) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS)
21117 #endif // No Exceptions
21118 firstreturn = (std::max)(1,
static_cast<int>(
stacksize - n -
static_cast<int>(h.
valid() && !is_stack_handler_v)));
21120 poststacksize =
lua_gettop(lua_state()) -
static_cast<int>(h.
valid() && !is_stack_handler_v);
21121 returncount = poststacksize - (firstreturn - 1);
21122 #if SOL_IS_ON(SOL_EXCEPTIONS) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS)
21125 catch (
const char*
error) {
21130 catch (
const std::string&
error) {
21135 catch (
const std::exception&
error) {
21140 #if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL)
21149 #endif // Always catch edge case
21152 #endif // Exceptions vs. No Exceptions
21160 #include <functional>
21163 template <
typename... Ret,
typename... Args>
21164 decltype(
auto) stack_proxy::call(Args&&...
args) {
21166 return sf.template
call<Ret...>(std::forward<Args>(
args)...);
21170 : L(o.lua_state()),
index(o.stack_index()), returncount(o.return_count()), popcount(o.return_count()), err(o.status()) {
21179 index = o.stack_index();
21180 returncount = o.return_count();
21181 popcount = o.return_count();
21191 : L(o.lua_state()),
index(o.stack_index()), returncount(o.return_count()) {
21199 index = o.stack_index();
21200 returncount = o.return_count();
21209 template <
typename... R>
21216 template <
typename... Args>
21218 return lua_func_.
call<R...>(std::forward<Args>(
args)...);
21229 template <
typename... Args>
21231 lua_func_.
call<
void>(std::forward<Args>(
args)...);
21237 template <
typename Signature>
21243 template <
typename... R>
21259 template <
typename Allocator>
21279 #ifndef SOL_DEPRECATED
21281 #define SOL_DEPRECATED __declspec(deprecated)
21283 #define SOL_DEPRECATED __attribute__((deprecated))
21285 #define SOL_DEPRECATED [[deprecated]]
21286 #endif // compilers
21287 #endif // SOL_DEPRECATED
21290 template <
typename T>
21304 template <
typename T>
21307 namespace container_detail {
21309 template <
typename T>
21312 template <
typename C>
21314 template <
typename C>
21321 template <
typename T>
21324 template <
typename C>
21326 template <
typename C>
21333 template <
typename T>
21336 template <
typename C>
21338 decltype(std::declval<C>().erase_after(std::declval<std::add_rvalue_reference_t<typename C::const_iterator>>()))*);
21339 template <
typename C>
21346 template <
typename T,
typename =
void>
21349 template <
typename C>
21350 static meta::sfinae_yes_t test(decltype(std::declval<C>().
find(std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
21351 template <
typename C>
21358 template <
typename T>
21361 template <
typename C>
21362 static meta::sfinae_yes_t test(decltype(std::declval<C>().
find(std::declval<std::add_rvalue_reference_t<typename C::key_type>>()))*);
21363 template <
typename C>
21370 template <
typename T>
21373 template <
typename C>
21374 static meta::sfinae_yes_t test(decltype(std::declval<C>().erase(std::declval<typename C::iterator>()))*);
21375 template <
typename C>
21382 template <
typename T>
21385 template <
typename C>
21386 static meta::sfinae_yes_t test(decltype(std::declval<C>().erase(std::declval<typename C::key_type>()))*);
21387 template <
typename C>
21394 template <
typename T>
21397 template <
typename C>
21399 template <
typename C>
21406 template <
typename T>
21409 template <
typename C>
21411 template <
typename C>
21418 template <
typename T>
21421 template <
typename C>
21423 template <
typename C>
21430 template <
typename T>
21433 template <
typename C>
21435 template <
typename C>
21442 template <
typename T>
21445 template <
typename C>
21447 template <
typename C>
21454 template <
typename T>
21457 template <
typename C>
21459 template <
typename C>
21466 template <
typename T>
21469 template <
typename C>
21471 template <
typename C>
21478 template <
typename T>
21481 template <
typename C>
21483 template <
typename C>
21490 template <
typename T>
21493 template <
typename C>
21495 template <
typename C>
21502 template <
typename T>
21505 template <
typename C>
21507 template <
typename C>
21514 template <
typename T>
21517 template <
typename C>
21519 template <
typename C>
21526 template <
typename T>
21529 template <
typename C>
21531 template <
typename C>
21538 template <
typename T>
21541 template <
typename C>
21543 template <
typename C>
21550 template <
typename T>
21553 template <
typename C>
21555 template <
typename C>
21562 template <
typename T>
21565 template <
typename T>
21568 template <
typename T>
21571 template <
typename T>
21574 template <
typename T>
21577 template <
typename T>
21580 template <
typename T>
21583 template <
typename T>
21586 template <
typename T>
21589 template <
typename T>
21592 template <
typename T>
21595 template <
typename T>
21598 template <
typename T>
21601 template <
typename T>
21604 template <
typename T>
21607 template <
typename T>
21610 template <
typename T>
21613 template <
typename T>
21616 template <
typename T>
21619 template <
typename T>
21622 template <
typename T>
21625 template <
typename T>
21628 template <
typename T>
21631 template <
typename T>
21634 template <
typename T>
21639 template <
typename T>
21644 template <
typename T>
21647 template <
typename T>
21649 return std::forward<T>(t);
21652 template <
typename T>
21657 template <
typename T>
21659 return std::forward<T>(t);
21662 template <
typename T>
21667 template <
typename X,
typename =
void>
21670 typedef std::remove_pointer_t<meta::unwrap_unqualified_t<X>>
T;
21677 return luaL_error(L_,
"sol: cannot call 'at(index)' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21681 return luaL_error(L_,
"sol: cannot call 'get(key)' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21685 return luaL_error(L_,
"sol: cannot call 'container[key]' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21689 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());
21694 L_,
"sol: cannot call 'container[key] = value' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21698 return luaL_error(L_,
"sol: cannot call 'add' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21702 return luaL_error(L_,
"sol: cannot call 'insert' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21706 return luaL_error(L_,
"sol: cannot call 'find' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21710 return luaL_error(L_,
"sol: cannot call 'index_of' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21714 return luaL_error(L_,
"sol: cannot call 'end' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21718 return luaL_error(L_,
"sol: cannot call 'clear' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21722 return luaL_error(L_,
"sol: cannot call 'empty' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21726 return luaL_error(L_,
"sol: cannot call 'erase' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21730 return luaL_error(L_,
"sol: cannot call 'next' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21734 return luaL_error(L_,
"sol: cannot call '__pairs/pairs' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21738 return luaL_error(L_,
"sol: cannot call '__ipairs' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21742 luaL_error(L_,
"sol: cannot call 'being' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21747 luaL_error(L_,
"sol: cannot call 'end' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
21752 template <
typename X>
21754 std::
enable_if_t<meta::all<is_forced_container<meta::unqualified_t<X>>, meta::has_value_type<meta::unqualified_t<container_decay_t<X>>>,
21755 meta::has_iterator<meta::unqualified_t<container_decay_t<X>>>>::value>> {
21757 using T = std::remove_pointer_t<meta::unwrap_unqualified_t<container_decay_t<X>>>;
21770 typedef typename KV::first_type
K;
21771 typedef typename KV::second_type
V;
21773 typedef decltype(*std::declval<iterator&>()) iterator_return;
21799 #if SOL_IS_ON(SOL_SAFE_USERTYPE)
21800 auto p = stack::unqualified_check_get<T*>(L_, 1);
21803 "sol: 'self' is not of type '%s' (pass 'self' as first argument with ':' or call on proper type)",
21804 detail::demangle<T>().c_str());
21806 if (p.value() ==
nullptr) {
21808 L_,
"sol: 'self' argument is nil (pass 'self' as first argument with ':' or call on a '%s' type)", detail::demangle<T>().c_str());
21812 return stack::unqualified_get<T>(L_, 1);
21813 #endif // Safe getting with error
21817 pos += deferred_uc::index_adjustment(L_,
self);
21821 auto it = deferred_uc::begin(L_,
self);
21822 auto e = deferred_uc::end(L_,
self);
21837 std::ptrdiff_t len =
static_cast<std::ptrdiff_t
>(size_start(L_,
self));
21838 pos += deferred_uc::index_adjustment(L_,
self);
21839 if (pos < 0 || pos >= len) {
21842 auto it = std::next(deferred_uc::begin(L_,
self), pos);
21850 template <
typename Iter>
21852 decltype(
auto) v = *it;
21856 template <
typename Iter>
21862 key =
static_cast<K>(key + deferred_uc::index_adjustment(L_,
self));
21866 auto it = deferred_uc::begin(L_,
self);
21867 auto e = deferred_uc::end(L_,
self);
21882 std::ptrdiff_t len =
static_cast<std::ptrdiff_t
>(size_start(L_,
self));
21883 key =
static_cast<K>(
static_cast<std::ptrdiff_t
>(key) + deferred_uc::index_adjustment(L_,
self));
21884 if (key < 0 || key >= len) {
21887 auto it = std::next(deferred_uc::begin(L_,
self), key);
21897 auto e = deferred_uc::end(L_,
self);
21898 auto it = std::find_if(deferred_uc::begin(L_,
self), e, std::ref(fx));
21906 return detail::error_result(
"cannot get this key on '%s': no suitable way to increment iterator and compare to key value '%s'",
21907 detail::demangle<T>().
data(),
21908 detail::demangle<K>().
data());
21916 decltype(
auto) v = *it;
21917 v.second = value.as<
V>();
21922 decltype(
auto) v = *it;
21933 "cannot perform a 'set': '%s's iterator reference is not writable (non-copy-assignable or const)", detail::demangle<T>().
data());
21937 decltype(
auto) key = okey.as<
K>();
21938 key =
static_cast<K>(
static_cast<std::ptrdiff_t
>(key) + deferred_uc::index_adjustment(L_,
self));
21939 auto e = deferred_uc::end(L_,
self);
21940 auto it = deferred_uc::begin(L_,
self);
21942 for (; key > 0 && it != e; --key, ++it) {
21949 return detail::error_result(
"out of bounds (too big) for set on '%s'", detail::demangle<T>().c_str());
21955 decltype(
auto) key = okey.as<
K>();
21956 key =
static_cast<K>(
static_cast<std::ptrdiff_t
>(key) + deferred_uc::index_adjustment(L_,
self));
21958 return detail::error_result(
"sol: out of bounds (too small) for set on '%s'", detail::demangle<T>().c_str());
21960 std::ptrdiff_t len =
static_cast<std::ptrdiff_t
>(size_start(L_,
self));
21964 else if (key >= len) {
21965 return detail::error_result(
"sol: out of bounds (too big) for set on '%s'", detail::demangle<T>().c_str());
21967 auto it = std::next(deferred_uc::begin(L_,
self), key);
21972 decltype(
auto) key = okey.as<
K>();
21973 if (!is_writable::value) {
21975 "cannot perform a 'set': '%s's iterator reference is not writable (non-copy-assignable or const)", detail::demangle<T>().
data());
21978 auto e = deferred_uc::end(L_,
self);
21979 auto it = std::find_if(deferred_uc::begin(L_,
self), e, std::ref(fx));
21987 return detail::error_result(
"cannot set this value on '%s': no suitable way to increment iterator or compare to '%s' key",
21988 detail::demangle<T>().
data(),
21989 detail::demangle<K>().
data());
21992 template <
typename Iter>
22007 "cannot call 'set' on '%s': there is no 'insert' function on this associative type", detail::demangle<T>().c_str());
22011 template <
typename Iter>
22014 self.insert(it, key);
22026 "cannot call 'set' on '%s': there is no 'insert' function on this non-associative type", detail::demangle<T>().c_str());
22031 decltype(
auto) key = okey.as<
K>();
22032 auto it =
self.find(key);
22033 if (it == deferred_uc::end(L_,
self)) {
22051 template <
bool idx_of = false>
22053 if constexpr (!is_ordered::value && idx_of) {
22056 return detail::error_result(
"cannot perform an 'index_of': '%s's is not an ordered container", detail::demangle<T>().
data());
22059 decltype(
auto) key = stack::unqualified_get<K>(L_, 2);
22060 auto it =
self.find(key);
22061 if (it == deferred_uc::end(L_,
self)) {
22064 if constexpr (idx_of) {
22065 auto dist = std::distance(deferred_uc::begin(L_,
self), it);
22066 dist -= deferred_uc::index_adjustment(L_,
self);
22075 template <
bool idx_of = false>
22077 if constexpr (!is_ordered::value && idx_of) {
22080 return detail::error_result(
"cannot perform an 'index_of': '%s's is not an ordered container", detail::demangle<T>().
data());
22083 decltype(
auto) value = stack::unqualified_get<V>(L_, 2);
22084 auto it =
self.find(value);
22085 if (it == deferred_uc::end(L_,
self)) {
22088 if constexpr (idx_of) {
22089 auto dist = std::distance(deferred_uc::begin(L_,
self), it);
22090 dist -= deferred_uc::index_adjustment(L_,
self);
22099 template <
bool idx_of = false>
22104 template <
typename Iter>
22109 template <
typename Iter>
22111 idx =
static_cast<std::size_t>(
static_cast<std::ptrdiff_t
>(idx) - deferred_uc::index_adjustment(L_,
self));
22115 template <
bool = false>
22117 return detail::error_result(
"cannot call 'find' on '%s': there is no 'find' function and the value_type is not equality comparable",
22118 detail::demangle<T>().c_str());
22121 template <
bool idx_of = false>
22123 decltype(
auto) value = stack::unqualified_get<V>(L_, 2);
22124 auto it = deferred_uc::begin(L_,
self);
22125 auto e = deferred_uc::end(L_,
self);
22127 for (;; ++it, ++idx) {
22138 template <
bool idx_of = false>
22143 template <
typename Iter>
22149 return detail::error_result(
"cannot call 'add' on type '%s': no suitable insert/push_back C++ functions", detail::demangle<T>().
data());
22152 template <
typename Iter>
22154 self.insert_after(pos, value.as<
V>());
22159 auto backit =
self.before_begin();
22161 auto e = deferred_uc::end(L_,
self);
22162 for (
auto it = deferred_uc::begin(L_,
self); it != e; ++backit, ++it) { }
22164 return add_insert_after(
std::true_type(), L_,
self, value, backit);
22167 template <
typename Iter>
22169 self.insert(pos, value.as<
V>());
22174 auto pos = deferred_uc::end(L_,
self);
22178 template <
typename Iter>
22187 template <
typename Iter>
22189 self.push_back(value.as<
V>());
22194 self.push_back(value.as<
V>());
22198 template <
typename Iter>
22209 template <
typename Iter>
22212 self.insert(pos,
value_type(key.as<
K>(), stack::unqualified_get<V>(L_, 3)));
22216 self.insert(
value_type(key.as<
K>(), stack::unqualified_get<V>(L_, 3)));
22225 "cannot call 'insert' on '%s': there is no 'insert' function on this associative type", detail::demangle<T>().c_str());
22230 auto pos = deferred_uc::end(L_,
self);
22234 template <
typename Iter>
22243 template <
typename Iter>
22252 template <
typename Iter>
22258 return detail::error_result(
"cannot call 'add' on '%s': value_type is non-copyable", detail::demangle<T>().
data());
22267 auto it = deferred_uc::begin(L_,
self);
22268 auto key = where.as<
K>();
22269 key =
static_cast<K>(
static_cast<std::ptrdiff_t
>(key) + deferred_uc::index_adjustment(L_,
self));
22270 std::advance(it, key);
22271 self.insert(it, value.as<
V>());
22276 auto key = where.as<
K>();
22277 auto backit =
self.before_begin();
22279 key =
static_cast<K>(
static_cast<std::ptrdiff_t
>(key) + deferred_uc::index_adjustment(L_,
self));
22280 auto e = deferred_uc::end(L_,
self);
22281 for (
auto it = deferred_uc::begin(L_,
self); key > 0; ++backit, ++it, --key) {
22283 return detail::error_result(
"sol: out of bounds (too big) for set on '%s'", detail::demangle<T>().c_str());
22287 self.insert_after(backit, value.as<
V>());
22293 "cannot call 'insert' on '%s': no suitable or similar functionality detected on this container", detail::demangle<T>().
data());
22305 return insert_has(std::integral_constant <
bool,
22314 return detail::error_result(
"cannot call 'insert' on '%s': value_type is non-copyable", detail::demangle<T>().
data());
22318 auto it = deferred_uc::begin(L_,
self);
22319 key = (
static_cast<std::ptrdiff_t
>(key) + deferred_uc::index_adjustment(L_,
self));
22320 std::advance(it, key);
22327 auto fx = [&](
const value_type& r) ->
bool {
return key == r; };
22328 auto e = deferred_uc::end(L_,
self);
22329 auto it = std::find_if(deferred_uc::begin(L_,
self), e, std::ref(fx));
22344 return erase_integral(std::is_integral<K>(), L_,
self, key);
22348 auto backit =
self.before_begin();
22350 key =
static_cast<K>(
static_cast<std::ptrdiff_t
>(key) + deferred_uc::index_adjustment(L_,
self));
22351 auto e = deferred_uc::end(L_,
self);
22352 for (
auto it = deferred_uc::begin(L_,
self); key > 0; ++backit, ++it, --key) {
22354 return detail::error_result(
"sol: out of bounds for erase on '%s'", detail::demangle<T>().c_str());
22358 self.erase_after(backit);
22383 return std::distance(deferred_uc::begin(L_,
self), deferred_uc::end(L_,
self));
22387 return self.size();
22395 luaL_error(L_,
"sol: cannot call clear on '%s'", detail::demangle<T>().c_str());
22399 return self.empty();
22403 return deferred_uc::begin(L_,
self) == deferred_uc::end(L_,
self);
22407 auto it =
self.find(key);
22408 if (it == deferred_uc::end(L_,
self)) {
22420 return get_associative_find(std::integral_constant <
bool, is_associative::value&&
has_find<T>::value > (), L_,
self, key);
22445 iter& i = stack::unqualified_get<user<iter>>(L_, 1);
22446 auto&
source = i.source;
22448 if (it == deferred_uc::end(L_,
source)) {
22452 if constexpr (
ip) {
22460 std::advance(it, 1);
22466 iter& i = stack::unqualified_get<user<iter>>(L_, 1);
22467 auto&
source = i.source;
22469 next_K k = stack::unqualified_get<next_K>(L_, 2);
22470 if (it == deferred_uc::end(L_,
source)) {
22474 if constexpr (std::is_integral_v<next_K>) {
22481 std::advance(it, 1);
22488 return next_associative<ip>(is_assoc(), L_);
22493 auto& src = get_src(L_);
22495 stack::push<user<iter>>(L_, L_, 1, src, deferred_uc::begin(L_, src));
22502 auto& src = get_src(L_);
22504 stack::push<user<iter>>(L_, L_, 1, src, deferred_uc::begin(L_, src));
22511 auto&
self = get_src(L_);
22514 std::ptrdiff_t pos = stack::unqualified_get<std::ptrdiff_t>(L_, 2);
22515 er = at_start(L_,
self, pos);
22521 auto&
self = get_src(L_);
22524 decltype(
auto) key = stack::unqualified_get<K>(L_);
22525 er = get_start(L_,
self, key);
22536 if constexpr (is_linear_integral::value) {
22540 auto key = stack::get<K>(L_, 2);
22542 if (key ==
static_cast<K>(self_size)) {
22553 auto&
self = get_src(L_);
22563 auto&
self = get_src(L_);
22569 auto&
self = get_src(L_);
22575 auto&
self = get_src(L_);
22581 auto&
self = get_src(L_);
22587 if constexpr (meta::has_begin_end_v<T>) {
22588 return self.begin();
22592 return begin(
self);
22597 if constexpr (meta::has_begin_end_v<T>) {
22607 auto&
self = get_src(L_);
22613 auto&
self = get_src(L_);
22614 clear_start(L_,
self);
22619 auto&
self = get_src(L_);
22622 decltype(
auto) key = stack::unqualified_get<K>(L_, 2);
22623 er = erase_start(L_,
self, key);
22629 auto&
self = get_src(L_);
22639 return pairs_associative<false>(is_assoc(), L_);
22644 return pairs_associative<true>(is_assoc(), L_);
22652 template <
typename X>
22655 typedef std::remove_pointer_t<meta::unwrap_unqualified_t<X>>
T;
22678 auto p = stack::unqualified_check_get<T*>(L_, 1);
22679 #if SOL_IS_ON(SOL_SAFE_USERTYPE)
22682 "sol: 'self' is not of type '%s' (pass 'self' as first argument with ':' or call on proper type)",
22683 detail::demangle<T>().c_str());
22685 if (p.value() ==
nullptr) {
22687 L_,
"sol: 'self' argument is nil (pass 'self' as first argument with ':' or call on a '%s' type)", detail::demangle<T>().c_str());
22689 #endif // Safe getting with error
22694 T&
self = get_src(L_);
22695 decltype(
auto) value = stack::unqualified_get<value_type>(L_, 2);
22698 using v_t = std::add_const_t<decltype(
self[idx])>;
22701 idx =
static_cast<std::size_t>(
static_cast<std::ptrdiff_t
>(idx) - deferred_uc::index_adjustment(L_,
self));
22709 return luaL_error(L_,
"sol: cannot call 'find' on '%s': no supported comparison operator for the value type", detail::demangle<T>().c_str());
22713 iter& i = stack::unqualified_get<user<iter>>(L_, 1);
22714 auto&
source = i.source;
22716 std::size_t k = stack::unqualified_get<std::size_t>(L_, 2);
22717 if (it == deferred_uc::end(L_,
source)) {
22723 std::advance(it, 1);
22729 return luaL_error(L_,
"sol: cannot call 'clear' on type '%s': cannot remove all items from a fixed array", detail::demangle<T>().c_str());
22733 return luaL_error(L_,
"sol: cannot call 'erase' on type '%s': cannot remove an item from fixed arrays", detail::demangle<T>().c_str());
22737 return luaL_error(L_,
"sol: cannot call 'add' on type '%s': cannot add to fixed arrays", detail::demangle<T>().c_str());
22741 return luaL_error(L_,
"sol: cannot call 'insert' on type '%s': cannot insert new entries into fixed arrays", detail::demangle<T>().c_str());
22749 T&
self = get_src(L_);
22750 std::ptrdiff_t idx = stack::unqualified_get<std::ptrdiff_t>(L_, 2);
22751 idx += deferred_uc::index_adjustment(L_,
self);
22752 if (idx >=
static_cast<std::ptrdiff_t
>(std::extent<T>::value) || idx < 0) {
22763 T&
self = get_src(L_);
22764 std::ptrdiff_t idx = stack::unqualified_get<std::ptrdiff_t>(L_, 2);
22765 idx += deferred_uc::index_adjustment(L_,
self);
22766 if (idx >=
static_cast<std::ptrdiff_t
>(std::extent<T>::value)) {
22767 return luaL_error(L_,
"sol: index out of bounds (too big) for set on '%s'", detail::demangle<T>().c_str());
22770 return luaL_error(L_,
"sol: index out of bounds (too small) for set on '%s'", detail::demangle<T>().c_str());
22772 self[idx] = stack::unqualified_get<value_type>(L_, 3);
22793 return stack::push(L_, std::extent<T>::value > 0);
22797 auto& src = get_src(L_);
22799 stack::push<user<iter>>(L_, L_, 1, src, deferred_uc::begin(L_, src));
22817 return std::addressof(
self[0]);
22821 return std::addressof(
self[0]) + std::extent<T>::value;
22825 template <
typename X>
22829 template <
typename T>
22836 #include <unordered_map>
22840 namespace container_detail {
22841 template <
typename X>
22843 using T = std::remove_pointer_t<meta::unqualified_t<X>>;
22848 return uc::index_get(L);
22852 return default_uc::index_get(L);
22856 static const std::unordered_map<string_view, lua_CFunction> calls {
22857 {
"at", &real_at_call },
22858 {
"get", &real_get_call },
22859 {
"set", &real_set_call },
22860 {
"size", &real_length_call },
22861 {
"add", &real_add_call },
22862 {
"empty", &real_empty_call },
22863 {
"insert", &real_insert_call },
22864 {
"clear", &real_clear_call },
22865 {
"find", &real_find_call },
22866 {
"index_of", &real_index_of_call },
22867 {
"erase", &real_erase_call },
22868 {
"pairs", &pairs_call },
22869 {
"next", &next_call },
22871 auto maybenameview = stack::unqualified_check_get<string_view>(L, 2);
22872 if (maybenameview) {
22874 auto it = calls.find(name);
22875 if (it != calls.cend()) {
22887 return default_uc::at(L);
22919 return uc::index_set(L);
22923 return default_uc::index_set(L);
22931 return uc::pairs(L);
22935 return default_uc::pairs(L);
22943 return uc::ipairs(L);
22947 return default_uc::ipairs(L);
22983 return default_uc::add(L);
22991 return uc::insert(L);
22995 return default_uc::insert(L);
23015 return uc::empty(L);
23019 return default_uc::empty(L);
23027 return uc::erase(L);
23031 return default_uc::erase(L);
23052 return uc::index_of(L);
23055 return default_uc::index_of(L);
23060 return detail::typed_static_trampoline<decltype(&real_add_call), (&real_add_call)>(L);
23064 return detail::typed_static_trampoline<decltype(&real_erase_call), (&real_erase_call)>(L);
23068 return detail::typed_static_trampoline<decltype(&real_insert_call), (&real_insert_call)>(L);
23072 return detail::typed_static_trampoline<decltype(&real_clear_call), (&real_clear_call)>(L);
23076 return detail::typed_static_trampoline<decltype(&real_empty_call), (&real_empty_call)>(L);
23080 return detail::typed_static_trampoline<decltype(&real_find_call), (&real_find_call)>(L);
23084 return detail::typed_static_trampoline<decltype(&real_index_of_call), (&real_index_of_call)>(L);
23088 return detail::typed_static_trampoline<decltype(&real_length_call), (&real_length_call)>(L);
23092 return detail::typed_static_trampoline<decltype(&real_pairs_call), (&real_pairs_call)>(L);
23096 return detail::typed_static_trampoline<decltype(&real_ipairs_call), (&real_ipairs_call)>(L);
23100 return detail::typed_static_trampoline<decltype(&real_next_call), (&real_next_call)>(L);
23104 return detail::typed_static_trampoline<decltype(&real_at_call), (&real_at_call)>(L);
23108 return detail::typed_static_trampoline<decltype(&real_get_call), (&real_get_call)>(L);
23112 return detail::typed_static_trampoline<decltype(&real_set_call), (&real_set_call)>(L);
23116 return detail::typed_static_trampoline<decltype(&real_index_call), (&real_index_call)>(L);
23120 return detail::typed_static_trampoline<decltype(&real_new_index_call), (&real_new_index_call)>(L);
23126 namespace stack_detail {
23127 template <
typename T,
bool is_shim = false>
23135 using meta_usertype_container
23137 static const char* metakey
23139 static const std::array<luaL_Reg, 20> reg = { {
23141 {
"__pairs", &meta_usertype_container::pairs_call },
23142 {
"__ipairs", &meta_usertype_container::ipairs_call },
23143 {
"__len", &meta_usertype_container::length_call },
23144 {
"__index", &meta_usertype_container::index_call },
23145 {
"__newindex", &meta_usertype_container::new_index_call },
23146 {
"pairs", &meta_usertype_container::pairs_call },
23147 {
"next", &meta_usertype_container::next_call },
23148 {
"at", &meta_usertype_container::at_call },
23149 {
"get", &meta_usertype_container::get_call },
23150 {
"set", &meta_usertype_container::set_call },
23151 {
"size", &meta_usertype_container::length_call },
23152 {
"empty", &meta_usertype_container::empty_call },
23153 {
"clear", &meta_usertype_container::clear_call },
23154 {
"insert", &meta_usertype_container::insert_call },
23155 {
"add", &meta_usertype_container::add_call },
23156 {
"find", &meta_usertype_container::find_call },
23157 {
"index_of", &meta_usertype_container::index_of_call },
23158 {
"erase", &meta_usertype_container::erase_call },
23159 std::is_pointer<T>::value ?
luaL_Reg{
nullptr,
nullptr } :
luaL_Reg{
"__gc", &detail::usertype_alloc_destroy<T> },
23160 {
nullptr,
nullptr }
23172 template <
typename T>
23192 return push_lvalue(std::is_lvalue_reference<T>(), L, cont);
23196 return push_lvalue(std::is_lvalue_reference<T>(), L, as_cont.value());
23200 return push_rvalue(
meta::all<std::is_rvalue_reference<T>,
meta::neg<std::is_lvalue_reference<T>>>(), L, std::forward<T>(as_cont.value()));
23204 template <
typename T>
23206 using C = std::add_pointer_t<meta::unqualified_t<std::remove_pointer_t<T>>>;
23214 template <
typename T>
23218 template <
typename... Args>
23225 template <
typename T>
23227 using C = std::add_pointer_t<meta::unqualified_t<std::remove_pointer_t<T>>>;
23241 #include <type_traits>
23244 namespace u_detail {
23275 #if SOL_IS_ON(SOL_CHAR8_T)
23277 return string_view(
reinterpret_cast<const char*
>(s));
23293 template <
typename Arg>
23296 return std::string(
s.data(),
s.size());
23326 template <
typename T,
typename IFx,
typename Fx>
23339 lua_CFunction f = &comparsion_operator_wrap<T, std::less_equal<>>;
23345 lua_CFunction f = &comparsion_operator_wrap<T, std::equal_to<>>;
23358 auto f = &default_size<T>;
23363 if constexpr (is_to_stringable_v<T>) {
23364 if constexpr (!meta::is_probably_stateless_lambda_v<T> && !std::is_member_pointer_v<T>) {
23365 auto f = &detail::static_trampoline<&default_to_string<T>>;
23371 if constexpr (is_callable_v<T>) {
23372 if constexpr (meta::call_operator_deducible_v<T>) {
23373 auto f = &
c_call<decltype(&T::operator()), &T::operator()>;
23382 namespace stack {
namespace stack_detail {
23383 template <
typename X>
23385 using T = std::remove_pointer_t<X>;
23395 if constexpr (!std::is_pointer_v<X>) {
23402 const std::string& name = detail::demangle<T>();
23420 #include <unordered_map>
23423 namespace sol {
namespace u_detail {
23425 struct usertype_storage_base;
23426 template <
typename T>
23431 template <
typename T>
23433 template <
typename T>
23451 virtual void*
data() = 0;
23456 template <
typename K,
typename Fq,
typename T =
void>
23460 #if SOL_IS_ON(SOL_CHAR8_T)
23461 || meta::is_c_str_of_v<uF, char8_t>
23463 || 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>,
23464 std::add_pointer_t<std::add_const_t<std::remove_all_extents_t<Fq>>>, std::decay_t<Fq>>;
23467 template <
typename... Args>
23472 return static_cast<void*
>(std::addressof(data_));
23475 template <
bool is_index = true,
bool is_variable = false>
23478 auto&
f = *
static_cast<F*
>(target);
23479 return call_detail::call_wrapped<T, is_index, is_variable, boost>(L_,
f);
23482 template <
bool is_index = true,
bool is_variable = false>
23485 return call_with_<is_index, is_variable>(L_,
f);
23488 template <
bool is_index = true,
bool is_variable = false>
23491 if constexpr (meta::is_specialization_of_v<uF, yielding_t>) {
23499 template <
bool is_index = true,
bool is_variable = false>
23501 if constexpr (!is_variable) {
23503 auto&
f = *
static_cast<std::decay_t<F>*
>(target);
23512 auto cfunc = &call<is_index, is_variable>;
23518 auto&
f = *
static_cast<F*
>(target);
23519 return call_detail::call_wrapped<T, is_index, is_variable, boost>(L_,
f);
23523 template <
bool is_index = true,
bool is_variable = false>
23526 return index_call_with_<is_index, is_variable>(L_,
f);
23529 template <
bool is_index = true,
bool is_variable = false>
23532 if constexpr (meta::is_specialization_of_v<uF, yielding_t>) {
23558 return luaL_error(L_,
"sol: cannot set (new_index) into this object: no defined new_index operation on usertype");
23566 bool is_destruction =
false;
23567 bool is_index =
false;
23568 bool is_new_index =
false;
23569 bool is_static_index =
false;
23570 bool is_static_new_index =
false;
23571 bool poison_indexing =
false;
23572 bool is_unqualified_lua_CFunction =
false;
23573 bool is_unqualified_lua_reference =
false;
23574 std::string* p_key =
nullptr;
23579 void* p_derived_usb =
nullptr;
23580 lua_CFunction idx_call =
nullptr, new_idx_call =
nullptr, meta_idx_call =
nullptr, meta_new_idx_call =
nullptr;
23584 std::string& key = *p_key;
23588 if (smt_ == submetatable_type::named) {
23595 int fast_index_table_push = fast_index_table_.
push(L_);
23597 if (poison_indexing) {
23598 (usb.*change_indexing)(L_, smt_, p_derived_usb, t, idx_call, new_idx_call, meta_idx_call, meta_new_idx_call);
23602 || smt_ == submetatable_type::unique)) {
23610 if (is_index || is_new_index || is_static_index || is_static_new_index) {
23616 if (is_unqualified_lua_CFunction) {
23617 stack::set_field<false, true>(L_, key, call_func, t.
stack_index());
23619 else if (is_unqualified_lua_reference) {
23620 reference& binding_ref = *p_binding_ref;
23621 stack::set_field<false, true>(L_, key, binding_ref, t.
stack_index());
23635 if (smt_ == submetatable_type::named) {
23638 int fast_index_table_push = fast_index_table_.
push(L_);
23640 stack::set_field<false, true>(L_, key, value, t.
stack_index());
23654 int fast_index_table_push = fast_index_table_.
push(L_);
23659 (p_usb->*change_indexing)(L_, smt_, p_derived_usb, t, idx_call, new_idx_call, meta_idx_call, meta_new_idx_call);
23671 return binding_data ==
ptr->data();
23681 std::unordered_map<stateless_reference, stateless_reference, stateless_reference_hash, stateless_reference_equals>
auxiliary_keys;
23700 , string_keys_storage()
23703 , value_index_table()
23704 , reference_index_table()
23705 , unique_index_table()
23706 , const_reference_index_table()
23707 , const_value_index_table()
23708 , named_index_table()
23713 , static_base_index()
23714 , is_using_index(false)
23715 , is_using_new_index(false)
23724 static_base_index.
new_index = new_index_target_set;
23727 template <
typename Fx>
23729 for (
int i = 0; i < 6; ++i) {
23733 case submetatable_type::const_value:
23734 p_fast_index_table = &this->const_value_index_table;
23737 p_fast_index_table = &this->reference_index_table;
23739 case submetatable_type::unique:
23740 p_fast_index_table = &this->unique_index_table;
23742 case submetatable_type::const_reference:
23743 p_fast_index_table = &this->const_reference_index_table;
23745 case submetatable_type::named:
23746 p_fast_index_table = &this->named_index_table;
23748 case submetatable_type::value:
23750 p_fast_index_table = &this->value_index_table;
23753 fx(L_, smt, *p_fast_index_table);
23758 string_keys_storage.emplace_back(
new char[sv.size()]);
23759 std::unique_ptr<char[]>& sv_storage = string_keys_storage.back();
23760 std::memcpy(sv_storage.get(), sv.data(), sv.size());
23761 string_view stored_sv(sv_storage.get(), sv.size());
23765 template <
typename T,
typename... Bases>
23768 "The size of this data pointer is too small to fit the inheritance checking function: Please file "
23771 "The size of this data pointer is too small to fit the inheritance checking function: Please file "
23774 if constexpr (
sizeof...(Bases) > 0) {
23786 for_each_fx.
p_usb =
this;
23788 for_each_fx.
change_indexing = &usertype_storage_base::change_indexing;
23790 this->for_each_table(L_, for_each_fx);
23798 if (value_index_table.
valid(m_L)) {
23801 if (reference_index_table.
valid(m_L)) {
23804 if (unique_index_table.
valid(m_L)) {
23807 if (const_reference_index_table.
valid(m_L)) {
23810 if (const_value_index_table.
valid(m_L)) {
23813 if (named_index_table.
valid(m_L)) {
23816 if (type_table.
valid(m_L)) {
23819 if (gc_names_table.
valid(m_L)) {
23822 if (named_metatable.
valid(m_L)) {
23824 int named_metatable_index = pp.index_of(named_metatable);
23831 value_index_table.
reset(m_L);
23832 reference_index_table.
reset(m_L);
23833 unique_index_table.
reset(m_L);
23834 const_reference_index_table.
reset(m_L);
23835 const_value_index_table.
reset(m_L);
23836 named_index_table.
reset(m_L);
23837 type_table.
reset(m_L);
23838 gc_names_table.
reset(m_L);
23839 named_metatable.
reset(m_L);
23842 string_keys.clear();
23843 auxiliary_keys.clear();
23844 string_keys_storage.clear();
23847 template <
bool is_new_index,
typename Base>
23855 #if SOL_IS_ON(SOL_USE_UNSAFE_BASE_LOOKUP)
23857 base_result = self_index_call<is_new_index, true>(
bases(), L_, base_storage);
23860 if (
static_cast<bool>(maybe_base_storage)) {
23861 base_result = self_index_call<is_new_index, true>(
bases(), L_, *maybe_base_storage);
23864 #endif // Fast versus slow, safe base lookup
23867 template <
bool is_new_index =
false,
bool base_walking =
false,
bool from_named_metatable =
false,
typename... Bases>
23869 if constexpr (!from_named_metatable || !is_new_index) {
23870 type k_type = stack::get<type>(L, 2);
23875 auto it =
self.string_keys.find(k);
23876 if (it !=
self.string_keys.cend()) {
23877 target = &it->second;
23880 if (target !=
nullptr) {
23882 if constexpr (is_new_index) {
23894 auto it =
self.auxiliary_keys.find(k);
23895 if (it !=
self.auxiliary_keys.cend()) {
23896 target = &it->second;
23899 if (target !=
nullptr) {
23900 if constexpr (is_new_index) {
23902 target->
reset(L, 3);
23915 bool keep_going =
true;
23919 (
void)
detail::swallow { 1, (base_walk_index<is_new_index, Bases>(L,
self, keep_going, base_result), 1)... };
23920 if constexpr (
sizeof...(Bases) > 0) {
23922 return base_result;
23925 if constexpr (base_walking) {
23930 else if constexpr (from_named_metatable) {
23931 if constexpr (is_new_index) {
23932 return self.static_base_index.new_index(L,
self.static_base_index.
new_binding_data);
23935 return self.static_base_index.index(L,
self.static_base_index.
binding_data);
23939 if constexpr (is_new_index) {
23943 return self.base_index.index(L,
self.base_index.
binding_data);
23951 void* base_this =
static_cast<void*
>(&this_base);
23953 this->is_using_index |=
true;
23954 this->is_using_new_index |=
true;
23955 if (submetatable_ == submetatable_type::named) {
23958 stack::set_field<false, true>(L_,
23962 stack::set_field<false, true>(L_,
23966 stack_metametatable.
pop(L_);
23969 stack::set_field<false, true>(
23971 stack::set_field<false, true>(
23976 template <
typename T =
void,
typename Key,
typename Value>
23986 value_index_table.
reset(m_L);
23987 reference_index_table.
reset(m_L);
23988 unique_index_table.
reset(m_L);
23989 const_reference_index_table.
reset(m_L);
23990 const_value_index_table.
reset(m_L);
23991 named_index_table.
reset(m_L);
23992 type_table.
reset(m_L);
23993 gc_names_table.
reset(m_L);
23994 named_metatable.
reset(m_L);
23996 auto auxiliary_first = auxiliary_keys.cbegin();
23997 auto auxiliary_last = auxiliary_keys.cend();
23998 while (auxiliary_first != auxiliary_last) {
24000 auto auxiliary_target = auxiliary_first;
24004 auto extracted_node = auxiliary_keys.extract(auxiliary_target);
24005 extracted_node.key().reset(m_L);
24006 extracted_node.mapped().reset(m_L);
24012 template <
typename T>
24013 struct usertype_storage : usertype_storage_base {
24015 using usertype_storage_base::usertype_storage_base;
24017 template <
bool is_new_index,
bool from_named_metatable>
24021 return self_index_call<is_new_index, false, from_named_metatable>(
bases(), L,
self);
24024 template <
bool is_new_index,
bool from_named_metatable,
typename... Bases>
24028 return self_index_call<is_new_index, false, from_named_metatable>(
bases(), L,
self);
24031 template <
bool is_new_index>
24033 return detail::static_trampoline<&index_call_<is_new_index, false>>(L);
24036 template <
bool is_new_index,
typename... Bases>
24041 template <
bool is_new_index>
24043 return detail::static_trampoline<&index_call_<is_new_index, true>>(L);
24046 template <
bool is_new_index,
typename... Bases>
24051 template <
typename Key,
typename Value>
24055 template <
typename T,
typename Key,
typename Value>
24061 if constexpr (std::is_same_v<KeyU, call_construction>) {
24063 std::unique_ptr<Binding> p_binding = std::make_unique<Binding>(std::forward<Value>(value));
24064 Binding& b = *p_binding;
24067 this->named_index_table.push(L);
24070 lua_pushlstring(L, call_metamethod_name.data(), call_metamethod_name.size());
24073 lua_CFunction target_func = &b.template call<false, false>;
24076 this->named_index_table.pop(L);
24078 else if constexpr (std::is_same_v<KeyU, base_classes_tag>) {
24080 this->update_bases<T>(L, std::forward<Value>(value));
24084 auto storage_it = this->
storage.end();
24085 auto string_it = this->string_keys.find(
s);
24086 if (string_it != this->string_keys.cend()) {
24087 const auto& binding_data = string_it->second.binding_data;
24089 this->string_keys.erase(string_it);
24092 std::unique_ptr<Binding> p_binding = std::make_unique<Binding>(std::forward<Value>(value));
24093 Binding& b = *p_binding;
24094 if (storage_it != this->
storage.cend()) {
24106 bool poison_indexing = (!is_using_index || !is_using_new_index) && (is_var_bind::value || is_index || is_new_index);
24110 ics.
index = is_index || is_static_index ? &Binding::template call_with_<true, is_var_bind::value>
24111 : &Binding::template index_call_with_<true, is_var_bind::value>;
24112 ics.
new_index = is_new_index || is_static_new_index ? &Binding::template call_with_<false, is_var_bind::value>
24113 : &Binding::template index_call_with_<false, is_var_bind::value>;
24123 for_each_fx.
p_ics = &ics;
24124 if constexpr (is_lua_c_function_v<ValueU>) {
24128 else if constexpr (is_lua_reference_or_proxy_v<ValueU>) {
24133 for_each_fx.
call_func = &b.template call<false, is_var_bind::value>;
24135 for_each_fx.
p_usb =
this;
24141 for_each_fx.
change_indexing = &usertype_storage_base::change_indexing;
24145 this->base_index.index = ics.
index;
24148 if (is_new_index) {
24149 this->base_index.new_index = ics.
new_index;
24152 if (is_static_index) {
24153 this->static_base_index.index = ics.
index;
24154 this->static_base_index.binding_data = ics.
binding_data;
24156 if (is_static_new_index) {
24157 this->static_base_index.new_index = ics.
new_index;
24158 this->static_base_index.new_binding_data = ics.
binding_data;
24160 this->for_each_table(L, for_each_fx);
24166 if constexpr (is_lua_reference_v<KeyU> && is_lua_reference_v<ValueU>) {
24169 std::string string_key = stack::pop<std::string>(L);
24170 this->set<T>(L, string_key, std::forward<Value>(value));
24175 this->for_each_table(L, ref_additions_fx);
24176 this->auxiliary_keys.insert_or_assign(std::forward<Key>(key), std::forward<Value>(value));
24184 this->for_each_table(L, ref_additions_fx);
24190 template <
typename T>
24191 template <
typename Key,
typename Value>
24196 template <
typename T>
24218 template <
typename T>
24220 clear_usertype_registry_names<T>(L);
24221 return detail::user_alloc_destroy<usertype_storage<T>>(L);
24224 template <
typename T>
24230 int usertype_storage_push_count = stack::push<user<usertype_storage<T>>>(L,
no_metatable, L);
24231 stack_reference usertype_storage_ref(L, -usertype_storage_push_count);
24237 stack_reference usertype_storage_metatable(L, -usertype_storage_metatabe_count);
24242 usertype_storage_metatable.
pop();
24246 stack::set_field<true>(L, gcmetakey, usertype_storage_ref);
24247 usertype_storage_ref.pop();
24251 stack::get_field<true>(L, gcmetakey);
24261 return base_storage;
24272 return maybe_storage_base;
24278 if (maybe_already_is_usertype_storage_base) {
24279 return maybe_already_is_usertype_storage_base;
24285 stack::get_field<true>(L, gcmetakey);
24288 return maybe_storage;
24292 stack::get_field<true>(L, gcmetakey);
24294 usertype_storage_base& target_umt = stack::stack_detail::unchecked_unqualified_get<user<usertype_storage_base>>(L, -1, tracking);
24299 template <
typename T>
24302 stack::get_field<true>(L, gcmetakey);
24311 template <
typename T>
24314 stack::get_field<true>(L, gcmetakey);
24319 template <
typename T>
24323 const char* gcmetakey = &u_traits::gc_table()[0];
24324 stack::get_field<true>(L, gcmetakey);
24330 target_umt.clear();
24332 clear_usertype_registry_names<T>(L);
24334 stack::set_field<true>(L, gcmetakey,
lua_nil);
24337 template <
typename T, automagic_flags enrollment_flags>
24344 using uts = usertype_storage<T>;
24380 clear_usertype_storage<T>(L_);
24386 usertype_storage<T>&
storage = create_usertype_storage<T>(L_);
24387 usertype_storage_base& base_storage =
storage;
24388 void* light_storage =
static_cast<void*
>(&
storage);
24389 void* light_base_storage =
static_cast<void*
>(&base_storage);
24392 storage.gc_names_table.push(L_);
24394 stack::set_field(L_, submetatable_type::named, &u_traits::gc_table()[0], gnt.stack_index());
24404 stack::set_field(L_,
"name", detail::demangle<T>(), stacked_type_table.stack_index());
24405 stack::set_field(L_,
"is", &detail::is_check<T>, stacked_type_table.stack_index());
24406 stacked_type_table.pop(L_);
24412 int for_each_backing_metatable_calls = 0;
24415 const char* metakey =
nullptr;
24417 case submetatable_type::const_value:
24423 case submetatable_type::unique:
24426 case submetatable_type::const_reference:
24429 case submetatable_type::named:
24430 metakey = &u_traits::user_metatable()[0];
24432 case submetatable_type::value:
24439 if (smt_ == submetatable_type::named) {
24442 storage.named_metatable.reset(L_, -1);
24449 stateless_stack_reference t(L_, -1);
24450 fast_index_table_.reset(L_, t.stack_index());
24455 case submetatable_type::const_reference:
24457 case submetatable_type::named:
24459 case submetatable_type::unique:
24460 if constexpr (std::is_destructible_v<T>) {
24467 case submetatable_type::value:
24468 case submetatable_type::const_value:
24470 if constexpr (std::is_destructible_v<T>) {
24480 "The size of this data pointer is too small to fit the inheritance checking function: file a bug "
24483 "The size of this data pointer is too small to fit the inheritance checking function: file a bug "
24488 auto prop_fx = detail::properties_enrollment_allowed(for_each_backing_metatable_calls,
storage.properties, enrollments_);
24490 stack::set_field<false, true>(L_, mf, reg, t.stack_index());
24493 detail::insert_default_registrations<T>(insert_fx, prop_fx);
24498 if (smt_ == submetatable_type::named) {
24505 absolute_index named_metatable_index(L_, -
storage.named_metatable.push(L_));
24506 stack::set_field<false, true>(L_,
metatable_key, t, named_metatable_index);
24507 storage.named_metatable.pop(L_);
24509 stack_reference stack_metametatable(L_, -
storage.named_index_table.push(L_));
24510 stack::set_field<false, true>(L_,
24513 stack_metametatable.stack_index());
24514 stack::set_field<false, true>(L_,
24517 stack_metametatable.stack_index());
24518 stack_metametatable.pop();
24524 stack::set_field<false, true>(L_,
24528 storage.is_using_new_index =
true;
24531 ++for_each_backing_metatable_calls;
24532 fast_index_table_.reset(L_, t.stack_index());
24536 storage.for_each_table(L_, for_each_backing_metatable);
24540 if (enrollments_.default_constructor) {
24546 storage.named_metatable.push(L_);
24556 template <
typename Table,
typename Key>
24563 return tbl.template traverse_get<T>(std::get<I>(key)...);
24568 return tbl.template traverse_get<T>(std::get<I>(
std::move(key))...);
24573 if constexpr (
sizeof...(I) > 1) {
24574 tbl.traverse_set(std::get<I>(key)..., std::forward<T>(value));
24577 tbl.set(std::get<I>(key)..., std::forward<T>(value));
24583 if constexpr (
sizeof...(I) > 1) {
24584 tbl.traverse_set(std::get<I>(
std::move(key))..., std::forward<T>(value));
24587 tbl.set(std::get<I>(
std::move(key))..., std::forward<T>(value));
24595 template <
typename T>
24599 template <
typename T>
24601 using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
24602 tuple_set(idx_seq(), std::forward<T>(item));
24606 template <
typename T>
24608 using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
24609 std::move(*this).tuple_set(idx_seq(), std::forward<T>(item));
24613 template <
typename T>
24615 return set(std::forward<T>(other));
24618 template <
typename T>
24620 return std::move(*this).set(std::forward<T>(other));
24623 template <
typename T>
24628 template <
typename T>
24633 template <
typename T>
24635 using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
24636 return tuple_get<T>(idx_seq());
24639 template <
typename T>
24641 using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
24642 return std::move(*this).template tuple_get<T>(idx_seq());
24645 template <
typename K>
24646 decltype(
auto) operator[](K&& k) const& {
24651 template <
typename K>
24652 decltype(
auto) operator[](K&& k) & {
24657 template <
typename K>
24658 decltype(
auto) operator[](K&& k) && {
24663 template <
typename... Ret,
typename... Args>
24665 #if !defined(__clang__) && defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 191200000
24667 return get<function>().call<Ret...>(std::forward<Args>(
args)...);
24669 return get<function>().template
call<Ret...>(std::forward<Args>(
args)...);
24673 template <
typename... Args>
24674 decltype(
auto) operator()(Args&&...
args) {
24675 return call<>(std::forward<Args>(
args)...);
24680 auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>,
global_table>::value>(lua_state(), key,
lua_gettop(lua_state()));
24681 lua_pop(lua_state(), p.levels);
24686 return push(this->lua_state());
24690 return get<reference>().push(L);
24696 auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>,
global_table>::value>(lua_state(), key,
lua_gettop(lua_state()));
24698 t =
type_of(lua_state(), -1);
24700 lua_pop(lua_state(), p.levels);
24705 return tbl.lua_state();
24720 template <
typename Table,
typename Key>
24721 struct table_proxy :
public proxy_base<table_proxy<Table, Key>> {
24727 return tbl.template traverse_get<T>(std::get<I>(key)...);
24732 return tbl.template traverse_get<T>(std::get<I>(
std::move(key))...);
24737 tbl.traverse_set(std::get<I>(key)..., std::forward<T>(value));
24742 tbl.traverse_set(std::get<I>(
std::move(key))..., std::forward<T>(value));
24746 auto p = stack::probe_get_field<std::is_same_v<meta::unqualified_t<Table>,
global_table>>(lua_state(), key, tbl.stack_index());
24747 lua_pop(lua_state(), p.levels);
24753 auto p = stack::probe_get_field<std::is_same_v<meta::unqualified_t<Table>,
global_table>>(lua_state(), key,
lua_gettop(lua_state()));
24754 lua_pop(lua_state(), p.levels);
24762 template <
typename T>
24766 template <
typename T>
24772 template <
typename T>
24778 template <
typename... Args>
24780 tbl.set_function(key, std::forward<Args>(
args)...);
24784 template <
typename... Args>
24786 tbl.set_function(
std::move(key), std::forward<Args>(
args)...);
24790 template <
typename T>
24793 if constexpr (!is_lua_reference_or_proxy_v<Tu> && meta::is_invocable_v<Tu>) {
24794 return set_function(std::forward<T>(other));
24797 return set(std::forward<T>(other));
24801 template <
typename T>
24804 if constexpr (!is_lua_reference_or_proxy_v<Tu> && meta::is_invocable_v<Tu> && !detail::is_msvc_callable_rigged_v<T>) {
24805 return std::move(*this).set_function(std::forward<T>(other));
24808 return std::move(*this).set(std::forward<T>(other));
24812 template <
typename T>
24817 template <
typename T>
24822 template <
typename T>
24824 typedef decltype(get<T>()) U;
24826 return option.has_value();
24829 template <
typename T>
24831 using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
24832 return tuple_get<T>(idx_seq());
24835 template <
typename T>
24837 using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;
24838 return std::move(*this).template tuple_get<T>(idx_seq());
24841 template <
typename T>
24842 decltype(
auto) get_or(T&& otherwise)
const {
24843 typedef decltype(get<T>()) U;
24846 return static_cast<U
>(option.value());
24848 return static_cast<U
>(std::forward<T>(otherwise));
24851 template <
typename T,
typename D>
24852 decltype(
auto) get_or(
D&& otherwise)
const {
24855 return static_cast<T
>(option.value());
24857 return static_cast<T
>(std::forward<D>(otherwise));
24860 template <
typename T>
24861 decltype(
auto) get_or_create() {
24865 template <
typename T,
typename Otherwise>
24866 decltype(
auto) get_or_create(Otherwise&& other) {
24867 if (!this->valid()) {
24868 this->
set(std::forward<Otherwise>(other));
24873 template <
typename K>
24874 decltype(
auto) operator[](K&& k) const& {
24879 template <
typename K>
24880 decltype(
auto) operator[](K&& k) & {
24885 template <
typename K>
24886 decltype(
auto) operator[](K&& k) && {
24891 template <
typename... Ret,
typename... Args>
24897 return func.
call<Ret...>(std::forward<Args>(
args)...);
24900 template <
typename... Args>
24901 decltype(
auto) operator()(Args&&...
args) {
24902 return call<>(std::forward<Args>(
args)...);
24907 auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>,
global_table>::value>(lua_state(), key,
lua_gettop(lua_state()));
24908 lua_pop(lua_state(), p.levels);
24913 return push(this->lua_state());
24918 auto pp = stack::push_pop<true>(tbl);
24919 int tableindex = pp.index_of(tbl);
24921 stack::get_field<true>(lua_state(), key, tableindex);
24926 auto pp = stack::push_pop<false>(tbl);
24927 int tableindex = pp.index_of(tbl);
24929 stack::get_field<false>(lua_state(), key, tableindex);
24939 auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>,
global_table>::value>(lua_state(), key,
lua_gettop(lua_state()));
24941 t =
type_of(lua_state(), -1);
24943 lua_pop(lua_state(), p.levels);
24948 return tbl.lua_state();
24952 if (!this->valid()) {
24959 template <
typename Table,
typename Key,
typename T>
24961 using G = decltype(stack::get<T>(
nullptr, 0));
24962 return right.template get<optional<G>>() ==
left;
24965 template <
typename Table,
typename Key,
typename T>
24967 using G = decltype(stack::get<T>(
nullptr, 0));
24968 return right.template get<optional<G>>() ==
left;
24971 template <
typename Table,
typename Key,
typename T>
24973 using G = decltype(stack::get<T>(
nullptr, 0));
24974 return right.template get<optional<G>>() !=
left;
24977 template <
typename Table,
typename Key,
typename T>
24979 using G = decltype(stack::get<T>(
nullptr, 0));
24980 return right.template get<optional<G>>() !=
left;
24983 template <
typename Table,
typename Key>
24985 return !
right.valid();
24988 template <
typename Table,
typename Key>
24990 return !
right.valid();
24993 template <
typename Table,
typename Key>
24995 return right.valid();
24998 template <
typename Table,
typename Key>
25000 return right.valid();
25004 template <
typename Super>
25012 template <
typename Super>
25020 template <
typename Table,
typename Key>
25033 #include <iterator>
25037 template <
typename reference_type>
25054 std::ptrdiff_t idx = 0;
25064 this->operator++();
25075 if (
lua_next(ref.lua_state(), tableidx) == 0) {
25081 kvp.first =
object(ref.lua_state(), -2);
25082 kvp.second =
object(ref.lua_state(), -1);
25090 auto saved = *
this;
25091 this->operator++();
25100 return idx ==
right.idx;
25104 return idx !=
right.idx;
25108 if (keyidx != -1) {
25111 if (ref.lua_state() !=
nullptr && ref.valid()) {
25125 #include <optional>
25127 namespace sol {
namespace stack {
namespace stack_detail {
25130 stack::get_field<true, false>(L_,
"next");
25131 bool is_next = stack::check<protected_function>(L_);
25135 stack::get_field<true, false>(L_,
"table");
25141 bool is_table_next_func = stack::check<protected_function>(L_, -1);
25142 if (is_table_next_func) {
25151 return stack::pop<protected_function>(L_);
25197 inline static constexpr
int empty_key_index = -1;
25212 , m_next_function_ref(lua_nil)
25213 , m_table_ref(lua_nil)
25215 , m_key_index(empty_key_index)
25216 , m_iteration_index(0) {
25219 pairs_iterator(
const pairs_iterator&) =
delete;
25220 pairs_iterator& operator=(
const pairs_iterator&) =
delete;
25226 , m_cached_key_value_pair(
std::move(
right.m_cached_key_value_pair))
25227 , m_key_index(
right.m_key_index)
25228 , m_iteration_index(
right.m_iteration_index) {
25229 right.m_key_index = empty_key_index;
25236 m_cached_key_value_pair =
std::move(
right.m_cached_key_value_pair);
25237 m_key_index =
right.m_key_index;
25238 m_iteration_index =
right.m_iteration_index;
25239 right.m_key_index = empty_key_index;
25243 template <
typename Source>
25244 pairs_iterator(
const Source& source_) noexcept : m_L(source_.lua_state()), m_key_index(empty_key_index), m_iteration_index(0) {
25245 if (m_L ==
nullptr || !source_.valid()) {
25246 m_key_index = empty_key_index;
25249 int source_index = -source_.push(m_L);
25250 int abs_source_index =
lua_absindex(m_L, source_index);
25253 if (metatable_exists == 1) {
25258 if (maybe_pairs_function.has_value()) {
25261 if (next_fn_and_table_and_first_key.
valid()) {
25264 m_key_index = next_fn_and_table_and_first_key.
stack_index() - 1;
25268 next_fn_and_table_and_first_key.
abandon();
25270 this->operator++();
25271 m_iteration_index = 0;
25279 if (maybe_next.has_value()) {
25280 m_next_function_ref =
std::move(*maybe_next);
25281 m_table_ref = source_;
25285 this->operator++();
25286 m_iteration_index = 0;
25294 m_next_function_ref = stack::pop<protected_function>(m_L);
25295 m_table_ref = source_;
25298 this->operator++();
25299 m_iteration_index = 0;
25303 if (m_key_index == empty_key_index) {
25308 if (!next_results.
valid()) {
25311 m_key_index = empty_key_index;
25315 if (next_results_count < 2) {
25319 m_key_index = empty_key_index;
25320 ++m_iteration_index;
25326 m_cached_key_value_pair.first = stack::get<object>(m_L, m_key_index);
25327 m_cached_key_value_pair.second = stack::get<object>(m_L, m_key_index + 1);
25332 ++m_iteration_index;
25337 return static_cast<std::ptrdiff_t
>(m_iteration_index);
25341 return m_cached_key_value_pair;
25345 return m_cached_key_value_pair;
25349 return left.m_table_ref ==
right.m_table_ref &&
left.m_iteration_index ==
right.m_iteration_index;
25353 return left.m_table_ref !=
right.m_table_ref ||
left.m_iteration_index !=
right.m_iteration_index;
25357 return left.m_key_index == empty_key_index;
25361 return left.m_key_index != empty_key_index;
25365 return left.m_key_index == empty_key_index;
25369 return left.m_key_index != empty_key_index;
25373 if (m_key_index != empty_key_index) {
25391 template <
typename Source>
25434 template <std::
size_t n>
25440 lua_pop(L,
static_cast<int>(n));
25451 lua_pop(L,
static_cast<int>(pop_count));
25456 return luaL_error(L_,
"sol: cannot modify the elements of an enumeration table");
25461 template <
bool top_level,
typename ref_t>
25462 class basic_table_core :
public basic_object<ref_t> {
25468 template <
typename,
typename>
25470 template <
typename>
25473 template <
typename T>
25476 template <
typename T>
25479 template <
typename T>
25482 template <
typename T>
25485 template <
bool raw,
typename... Ret,
typename... Keys>
25486 decltype(
auto) tuple_get(
int table_index, Keys&&... keys)
const {
25487 if constexpr (
sizeof...(Ret) < 2) {
25488 return traverse_get_single_maybe_tuple<raw, Ret...>(table_index, std::forward<Keys>(keys)...);
25491 using multi_ret = decltype(
stack::pop<std::tuple<Ret...>>(
nullptr));
25492 return multi_ret(traverse_get_single_maybe_tuple<raw, Ret>(table_index, std::forward<Keys>(keys))...);
25496 template <
bool raw,
typename Ret,
size_t... I,
typename Key>
25498 return traverse_get_single<raw, Ret>(table_index, std::get<I>(std::forward<Key>(key))...);
25501 template <
bool raw,
typename Ret,
typename Key>
25502 decltype(
auto) traverse_get_single_maybe_tuple(
int table_index, Key&& key)
const {
25504 return traverse_get_single_tuple<raw, Ret>(
25508 return traverse_get_single<raw, Ret>(table_index, std::forward<Key>(key));
25512 template <
bool raw,
typename Ret,
typename... Keys>
25513 decltype(
auto) traverse_get_single(
int table_index, Keys&&... keys)
const {
25514 constexpr
static bool global = (meta::count_for_to_pack_v < 1, is_get_direct_tableless, meta::unqualified_t<Keys>... >> 0);
25518 return traverse_get_deep_optional<global, raw, detail::insert_mode::none, Ret>(popcount, table_index, std::forward<Keys>(keys)...);
25522 return traverse_get_deep<global, raw, detail::insert_mode::none, Ret>(table_index, std::forward<Keys>(keys)...);
25526 template <
bool raw,
typename Pairs,
std::size_t... I>
25530 auto pp = stack::push_pop<global>(*
this);
25531 int table_index = pp.index_of(*
this);
25536 L, std::get<I * 2>(std::forward<Pairs>(
pairs)), std::get<I * 2 + 1>(std::forward<Pairs>(
pairs)), table_index),
25541 decltype(
auto) traverse_get_deep(
int table_index, Key&& key, Keys&&... keys)
const {
25545 table_index, std::forward<Keys>(keys)...);
25549 stack::get_field<global, raw>(L, std::forward<Key>(key), table_index);
25550 if constexpr (
sizeof...(Keys) > 0) {
25558 return traverse_get_deep<false, raw, mode, T>(
lua_gettop(L), std::forward<Keys>(keys)...);
25568 return stack::get<T>(L);
25574 decltype(
auto) traverse_get_deep_optional(
int& popcount,
int table_index, Key&& key, Keys&&... keys)
const {
25578 return traverse_get_deep_optional<global, raw, new_mode, T>(popcount, table_index, std::forward<Keys>(keys)...);
25583 return traverse_get_deep_optional<global, raw, new_mode, T>(popcount, table_index, std::forward<Keys>(keys)...);
25588 return traverse_get_deep_optional<global, raw, new_mode, T>(popcount, table_index, std::forward<Keys>(keys)...);
25591 if constexpr (
sizeof...(Keys) > 0) {
25593 auto p = stack::probe_get_field<global, raw>(L, std::forward<Key>(key), table_index);
25594 popcount += p.levels;
25600 stack::set_field<global, raw>(L, std::forward<Key>(key),
stack_reference(L, -1), table_index);
25606 return traverse_get_deep_optional<false, raw, mode, T>(popcount,
lua_gettop(L), std::forward<Keys>(keys)...);
25609 using R = decltype(stack::get<T>(
nullptr));
25612 auto p = stack::probe_get_field<global, raw, value_type>(L, key, table_index);
25613 popcount += p.levels;
25618 stack::set_field<global, raw>(L, std::forward<Key>(key),
stack_reference(L, -1), table_index);
25620 return stack::get<T>(L);
25625 return stack::get<T>(L);
25633 if constexpr (std::is_same_v<KeyU, update_if_empty_t>) {
25636 table_index, std::forward<Keys>(keys)...);
25638 else if constexpr (std::is_same_v<KeyU, create_if_nil_t>) {
25641 table_index, std::forward<Keys>(keys)...);
25643 else if constexpr (std::is_same_v<KeyU, override_value_t>) {
25646 table_index, std::forward<Keys>(keys)...);
25650 if constexpr (
sizeof...(Keys) == 1) {
25652 auto p = stack::probe_get_field<global, raw>(L, key, table_index);
25655 stack::set_field<global, raw>(L, std::forward<Key>(key), std::forward<Keys>(keys)..., table_index);
25659 stack::set_field<global, raw>(L, std::forward<Key>(key), std::forward<Keys>(keys)..., table_index);
25663 if constexpr (
mode != detail::insert_mode::none) {
25664 stack::get_field<global, raw>(L, key, table_index);
25672 stack::set_field<global, raw>(L, std::forward<Key>(key),
stack_reference(L, -1), table_index);
25680 stack::set_field<global, raw>(L, std::forward<Key>(key),
stack_reference(L, -1), table_index);
25685 stack::get_field<global, raw>(L, std::forward<Key>(key), table_index);
25687 traverse_set_deep<false, raw, mode>(
lua_gettop(L), std::forward<Keys>(keys)...);
25699 template <
typename T,
25704 template <
typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
25712 using base_t::lua_state;
25726 template <
typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
25728 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
25730 int table_index = pp.index_of(*
this);
25732 stack::check<basic_table_core>(lua_state(), table_index,
handler);
25743 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
25750 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
25752 int table_index = pp.index_of(*
this);
25754 stack::check<basic_table_core>(lua_state(), table_index,
handler);
25758 template <
typename T,
25762 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
25765 int table_index = pp.index_of(*
this);
25767 stack::check<basic_table_core>(lua_state(), table_index,
handler);
25806 auto pp = stack::push_pop<false>(*
this);
25807 int table_index = pp.index_of(*
this);
25811 template <
typename... Ret,
typename... Keys>
25812 decltype(
auto)
get(Keys&&... keys)
const {
25813 static_assert(
sizeof...(Keys) ==
sizeof...(Ret),
"number of keys and number of return types do not match");
25815 auto pp = stack::push_pop<global>(*
this);
25816 int table_index = pp.index_of(*
this);
25817 return tuple_get<
false, Ret...>(table_index, std::forward<Keys>(keys)...);
25820 template <
typename T,
typename Key>
25821 decltype(
auto) get_or(Key&& key, T&& otherwise)
const {
25822 typedef decltype(get<T>(
"")) U;
25823 optional<U> option = get<optional<U>>(std::forward<Key>(key));
25825 return static_cast<U
>(option.value());
25827 return static_cast<U
>(std::forward<T>(otherwise));
25830 template <
typename T,
typename Key,
typename D>
25831 decltype(
auto) get_or(Key&& key,
D&& otherwise)
const {
25832 optional<T> option = get<optional<T>>(std::forward<Key>(key));
25834 return static_cast<T
>(option.value());
25836 return static_cast<T
>(std::forward<D>(otherwise));
25839 template <
typename T,
typename... Keys>
25840 decltype(
auto) traverse_get(Keys&&... keys)
const {
25841 static_assert(
sizeof...(Keys) > 0,
"must pass at least 1 key to get");
25842 constexpr
static bool global = (meta::count_for_to_pack_v < 1, is_get_direct_tableless, meta::unqualified_t<Keys>... >> 0);
25843 auto pp = stack::push_pop<global>(*
this);
25844 int table_index = pp.index_of(*
this);
25845 return traverse_get_single<false, T>(table_index, std::forward<Keys>(keys)...);
25848 template <
typename... Keys>
25850 static_assert(
sizeof...(Keys) > 1,
"must pass at least 1 key and 1 value to set");
25851 constexpr
static bool global
25852 = (meta::count_when_for_to_pack_v < detail::is_not_insert_mode, 1, is_set_direct_tableless, meta::unqualified_t<Keys>... >> 0);
25853 auto pp = stack::push_pop<global>(*
this);
25854 int table_index = pp.index_of(*
this);
25857 traverse_set_deep<top_level, false, detail::insert_mode::none>(table_index, std::forward<Keys>(keys)...);
25861 template <
typename... Args>
25863 if constexpr (
sizeof...(Args) == 2) {
25864 traverse_set(std::forward<Args>(
args)...);
25872 template <
typename... Ret,
typename... Keys>
25873 decltype(
auto) raw_get(Keys&&... keys)
const {
25874 static_assert(
sizeof...(Keys) ==
sizeof...(Ret),
"number of keys and number of return types do not match");
25875 constexpr
static bool global = (meta::count_for_to_pack_v < 1, is_raw_get_direct_tableless, meta::unqualified_t<Keys>... >> 0);
25876 auto pp = stack::push_pop<global>(*
this);
25877 int table_index = pp.index_of(*
this);
25878 return tuple_get<
true, Ret...>(table_index, std::forward<Keys>(keys)...);
25881 template <
typename T,
typename Key>
25882 decltype(
auto) raw_get_or(Key&& key, T&& otherwise)
const {
25883 typedef decltype(raw_get<T>(
"")) U;
25884 optional<U> option = raw_get<optional<U>>(std::forward<Key>(key));
25886 return static_cast<U
>(option.value());
25888 return static_cast<U
>(std::forward<T>(otherwise));
25891 template <
typename T,
typename Key,
typename D>
25892 decltype(
auto) raw_get_or(Key&& key,
D&& otherwise)
const {
25893 optional<T> option = raw_get<optional<T>>(std::forward<Key>(key));
25895 return static_cast<T
>(option.value());
25897 return static_cast<T
>(std::forward<D>(otherwise));
25900 template <
typename T,
typename... Keys>
25901 decltype(
auto) traverse_raw_get(Keys&&... keys)
const {
25902 constexpr
static bool global = (meta::count_for_to_pack_v < 1, is_raw_get_direct_tableless, meta::unqualified_t<Keys>... >> 0);
25903 auto pp = stack::push_pop<global>(*
this);
25904 int table_index = pp.index_of(*
this);
25905 return traverse_get_single<true, T>(table_index, std::forward<Keys>(keys)...);
25908 template <
typename... Keys>
25910 constexpr
static bool global = (meta::count_for_to_pack_v < 1, is_raw_set_direct_tableless, meta::unqualified_t<Keys>... >> 0);
25911 auto pp = stack::push_pop<global>(*
this);
25914 traverse_set_deep<top_level, true, false>(std::forward<Keys>(keys)...);
25918 template <
typename... Args>
25924 template <
typename Class,
typename Key>
25927 template <
typename Class,
typename Key, automagic_flags enrollment_flags>
25930 template <
typename Class,
typename Key>
25933 template <
typename Class,
typename Key,
typename Arg,
typename... Args,
25934 typename = std::enable_if_t<!std::is_base_of_v<automagic_enrollments, meta::unqualified_t<Arg>>>>
25937 template <
bool read_only =
true,
typename... Args>
25939 table target = create_with(std::forward<Args>(
args)...);
25940 if constexpr (read_only) {
25953 template <
typename T,
bool read_only = true>
25955 table target =
create(
static_cast<int>(items.size()),
static_cast<int>(0));
25956 for (
const auto& kvp : items) {
25957 target.
set(kvp.first, kvp.second);
25959 if constexpr (read_only) {
25970 template <
typename Key =
object,
typename Value =
object,
typename Fx>
25973 if constexpr (std::is_invocable_v<Fx, Key, Value>) {
25975 int table_index = pp.index_of(*
this);
25977 while (
lua_next(L, table_index)) {
25979 Value value(L, -1);
25986 int table_index = pp.index_of(*
this);
25988 while (
lua_next(L, table_index)) {
25990 Value value(L, -1);
25992 std::pair<Key&, Value&> keyvalue(key, value);
26000 int table_index = pp.index_of(*
this);
26003 return stack::pop<size_t>(L);
26007 return cbegin() == cend();
26010 template <
typename T>
26015 template <
typename T>
26020 template <
typename T>
26025 template <
typename Sig,
typename Key,
typename... Args>
26027 set_fx(
types<Sig>(), std::forward<Key>(key), std::forward<Args>(
args)...);
26031 template <
typename Key,
typename... Args>
26033 set_fx(
types<>(), std::forward<Key>(key), std::forward<Args>(
args)...);
26037 template <
typename... Args>
26040 int table_index = pp.index_of(*
this);
26047 template <
typename R,
typename... Args,
typename Fx,
typename Key,
typename =
std::invoke_result_t<Fx, Args...>>
26049 set_resolved_function<R(Args...)>(std::forward<Key>(key), std::forward<Fx>(fx));
26052 template <
typename Fx,
typename Key, meta::enable<meta::is_specialization_of<meta::unqualified_t<Fx>, overload_set>> = meta::enabler>
26054 set(std::forward<Key>(key), std::forward<Fx>(fx));
26057 template <
typename Fx,
typename Key,
typename... Args,
26063 template <
typename... Sig,
typename... Args,
typename Key>
26076 template <
typename Key,
typename Value,
typename... Args>
26080 result.
set(std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(
args)...);
26085 template <
typename... Args>
26087 static_assert(
sizeof...(Args) % 2 == 0,
"You must have an even number of arguments for a key, value ... list.");
26089 return create(L, narr,
static_cast<int>((
sizeof...(Args) / 2) - narr), std::forward<Args>(
args)...);
26093 return create(base_t::lua_state(), narr, nrec);
26096 template <
typename Key,
typename Value,
typename... Args>
26098 return create(base_t::lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(
args)...);
26101 template <
typename Name>
26104 this->
set(std::forward<Name>(name),
x);
26108 template <
typename Name,
typename Key,
typename Value,
typename... Args>
26110 table x =
create(base_t::lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(
args)...);
26111 this->
set(std::forward<Name>(name),
x);
26115 template <
typename... Args>
26117 return create_with(base_t::lua_state(), std::forward<Args>(
args)...);
26120 template <
typename Name,
typename... Args>
26123 return create(std::forward<Name>(name), narr, (
sizeof...(Args) / 2) - narr, std::forward<Args>(
args)...);
26132 template <
typename base_type>
26133 class basic_metatable :
public basic_table<base_type> {
26145 template <
typename T,
26150 template <
typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26154 template <
typename R,
typename... Args,
typename Fx,
typename Key,
typename =
std::invoke_result_t<Fx, Args...>>
26156 set_resolved_function<R(Args...)>(std::forward<Key>(key), std::forward<Fx>(fx));
26159 template <
typename Fx,
typename Key, meta::enable<meta::is_specialization_of<meta::unqualified_t<Fx>, overload_set>> = meta::enabler>
26161 set(std::forward<Key>(key), std::forward<Fx>(fx));
26164 template <
typename Fx,
typename Key,
typename... Args,
26170 template <
typename... Sig,
typename... Args,
typename Key>
26176 using base_t::lua_state;
26187 template <
typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26189 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26192 stack::check<basic_metatable>(lua_state(), -1,
handler);
26196 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26202 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26205 stack::check<basic_metatable>(lua_state(), -1,
handler);
26208 template <
typename T,
26212 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26216 stack::check<basic_metatable>(base_t::lua_state(), -1,
handler);
26223 template <
typename Key,
typename Value>
26226 template <
typename Sig,
typename Key,
typename... Args>
26228 set_fx(
types<Sig>(), std::forward<Key>(key), std::forward<Args>(
args)...);
26232 template <
typename Key,
typename... Args>
26234 set_fx(
types<>(), std::forward<Key>(key), std::forward<Args>(
args)...);
26238 void unregister() {
26258 ustorage_base& base_storage = *
static_cast<ustorage_base*
>(stack::get<void*>(L, -1));
26259 std::array<string_view, 6> registry_traits;
26260 for (
std::size_t i = 0; i < registry_traits.size(); ++i) {
26262 stack::get_field<false, true>(L, smt, gc_names_table.
stack_index());
26263 registry_traits[i] = stack::get<string_view>(L, -1);
26273 for (
std::size_t i = 0; i < registry_traits.size(); ++i) {
26275 const string_view& gcmetakey = registry_traits[i];
26279 stack::set_field<true>(L, gcmetakey.data(),
lua_nil);
26289 base_storage.clear();
26307 template <
typename T,
typename base_type>
26308 class basic_usertype :
private basic_metatable<base_type> {
26313 template <
typename>
26316 template <
bool,
typename>
26325 template <
typename R,
typename... Args,
typename Fx,
typename Key,
typename =
std::invoke_result_t<Fx, Args...>>
26327 set_resolved_function<R(Args...)>(std::forward<Key>(key), std::forward<Fx>(fx));
26330 template <
typename Fx,
typename Key, meta::enable<meta::is_specialization_of<meta::unqualified_t<Fx>, overload_set>> = meta::enabler>
26332 set(std::forward<Key>(key), std::forward<Fx>(fx));
26335 template <
typename Fx,
typename Key,
typename... Args,
26341 template <
typename... Sig,
typename... Args,
typename Key>
26347 using base_t::base_t;
26350 using base_t::lua_state;
26353 using base_t::traverse_get;
26354 using base_t::traverse_set;
26355 using base_t::unregister;
26357 template <
typename Key,
typename Value>
26362 uts.
set(this->lua_state(), std::forward<Key>(key), std::forward<Value>(value));
26367 if constexpr (detail::is_non_factory_constructor_v<ValueU> || detail::is_policy_v<ValueU>) {
26378 template <
typename Sig,
typename Key,
typename... Args>
26380 set_fx(
types<Sig>(), std::forward<Key>(key), std::forward<Args>(
args)...);
26384 template <
typename Key,
typename... Args>
26386 set_fx(
types<>(), std::forward<Key>(key), std::forward<Args>(
args)...);
26390 template <
typename Key>
26395 template <
typename Key>
26411 template <
typename ref_t>
26412 struct basic_lua_table : basic_table_core<false, ref_t> {
26420 using base_t::lua_state;
26431 template <
typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26433 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26436 stack::check<basic_lua_table>(lua_state(), -1,
handler);
26445 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26451 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26454 stack::check<basic_lua_table>(lua_state(), -1,
handler);
26457 template <
typename T,
26461 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26465 stack::check<basic_lua_table>(lua_state(), -1,
handler);
26478 typedef table_core<false>
table;
26480 template <
bool is_global,
typename base_type>
26481 template <
typename Class,
typename Key>
26484 return this->new_usertype<Class>(std::forward<Key>(key),
std::move(enrollments));
26487 template <
bool is_global,
typename base_type>
26488 template <
typename Class,
typename Key, automagic_flags enrollment_flags>
26490 int mt_index = u_detail::register_usertype<Class, enrollment_flags>(this->lua_state(),
std::move(enrollments));
26492 lua_pop(this->lua_state(), 1);
26493 set(std::forward<Key>(key), mt);
26497 template <
bool is_global,
typename base_type>
26498 template <
typename Class,
typename Key>
26500 int mt_index = u_detail::register_usertype<Class, automagic_flags::all>(this->lua_state(),
std::move(enrollments));
26502 lua_pop(this->lua_state(), 1);
26503 set(std::forward<Key>(key), mt);
26507 template <
bool is_global,
typename base_type>
26508 template <
typename Class,
typename Key,
typename Arg,
typename... Args,
typename>
26517 static_assert(
sizeof...(Args) % 2 ==
static_cast<std::size_t>(!detail::any_is_constructor_v<Arg>),
26518 "you must pass an even number of arguments to new_usertype after first passing a constructor");
26519 if constexpr (detail::any_is_constructor_v<Arg>) {
26529 template <
typename base_type>
26530 template <
typename Key,
typename Value>
26539 uts.
set(L, std::forward<Key>(key), std::forward<Value>(value));
26543 base_t::set(std::forward<Key>(key), std::forward<Value>(value));
26572 template <
typename base_type>
26573 struct basic_environment :
basic_table<base_type> {
26578 using base_t::lua_state;
26602 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26604 stack::check<env_key_t>(this->lua_state(), -1,
handler);
26606 lua_pop(this->lua_state(), 1);
26611 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26613 stack::check<env_key_t>(this->lua_state(), -1,
handler);
26615 lua_pop(this->lua_state(), 1);
26618 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26624 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26627 stack::check<basic_environment>(L, -1,
handler);
26630 template <
typename T,
26634 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26638 stack::check<basic_environment>(lua_state(), -1,
handler);
26645 template <
typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
26647 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
26651 stack::check<basic_environment>(lua_state(), -1,
handler);
26656 template <
typename T>
26660 int target_index = pp.index_of(target);
26661 #if SOL_LUA_VERSION_I_ < 502
26664 int success_result = lua_setfenv(L, target_index);
26665 return success_result != 0;
26670 const char* maybe_upvalue_name =
lua_getupvalue(L, target_index, 1);
26671 if (maybe_upvalue_name ==
nullptr) {
26675 if (upvalue_name ==
"") {
26678 if (success ==
nullptr) {
26693 if (maybe_upvalue_name ==
nullptr) {
26697 if (upvalue_name ==
"_ENV") {
26701 if (success ==
nullptr) {
26720 template <
typename T,
typename E>
26722 return env.set_on(target);
26725 template <
typename E = reference,
typename T>
26744 explicit operator bool()
const {
26745 return static_cast<bool>(env);
26757 return env.value();
26761 return env.value();
26795 if (!env.valid()) {
26823 : L(Ls),
index(stackindex), returncount(retnum), popcount(popnum), err(lerr) {
26846 returncount = o.returncount;
26847 popcount = o.popcount;
26868 template <
typename T>
26871 if constexpr (meta::is_optional_v<UT>) {
26872 using ValueType =
typename UT::value_type;
26873 if constexpr (std::is_same_v<ValueType, error>) {
26883 return stack::get<UT>(L,
index);
26887 if constexpr (std::is_same_v<T, error>) {
26888 #if SOL_IS_ON(SOL_SAFE_PROXIES)
26892 #endif // Check proxy type's safety
26896 #if SOL_IS_ON(SOL_SAFE_PROXIES)
26900 #endif // Check proxy type's safety
26901 return stack::get<T>(L,
index);
26906 template <
typename... Ret,
typename... Args>
26908 return get<protected_function>().template
call<Ret...>(std::forward<Args>(
args)...);
26911 template <
typename... Args>
26912 decltype(
auto) operator()(Args&&...
args) {
26913 return call<>(std::forward<Args>(
args)...);
26924 if (L !=
nullptr) {
26945 using base_t::base_t;
26949 template <
typename T>
26953 template <
typename T>
26957 #if SOL_IS_ON(SOL_USE_THREAD_LOCAL)
26958 static thread_local
lua_State* L =
nullptr;
26969 thread_local_lua_state() = L;
26972 template <
typename T, meta::disable<is_reference_or_lua_value_init_list<meta::unqualified_t<T>>> = meta::enabler>
26976 template <
typename T, meta::disable<is_lua_value_single_constructible<meta::unqualified_t<T>>> = meta::enabler>
27027 template <
typename T>
27028 decltype(
auto) as()
const {
27030 return stack::pop<T>(ref_value.lua_state());
27033 template <
typename T>
27035 int r = ref_value.registry_index();
27041 return stack::check<T>(ref_value.lua_state(), -1, &
no_panic);
27070 #if SOL_IS_ON(SOL_PRINT_ERRORS)
27071 #include <iostream>
27076 #if SOL_LUA_VERSION_I_ < 502
27077 if (L ==
nullptr) {
27090 #if SOL_IS_OFF(SOL_EXCEPTIONS)
27094 size_t messagesize;
27097 std::string err(message, messagesize);
27099 #if SOL_IS_ON(SOL_PRINT_ERRORS)
27100 std::cerr <<
"[sol2] An error occurred and panic has been invoked: ";
27102 std::cerr << std::endl;
27107 throw error(std::string(
"An unexpected error occurred and panic has been invoked"));
27108 #endif // Printing Errors
27112 std::string
msg =
"An unknown error has triggered the default error handler";
27116 msg.assign(topmsg.data(), topmsg.size());
27120 if (maybetraceback) {
27121 const string_view& traceback = maybetraceback.value();
27122 msg.assign(traceback.data(), traceback.size());
27124 #if SOL_IS_ON(SOL_PRINT_ERRORS)
27156 std::string err =
"sol: ";
27157 err += to_string(result.
status());
27159 #if SOL_IS_ON(SOL_EXCEPTIONS)
27160 std::exception_ptr eptr = std::current_exception();
27164 std::rethrow_exception(eptr);
27166 catch (
const std::exception& ex) {
27167 err +=
"std::exception -- ";
27168 err.append(ex.what());
27170 catch (
const std::string& message) {
27171 err +=
"thrown message -- ";
27172 err.append(message);
27174 catch (
const char* message) {
27175 err +=
"thrown message -- ";
27176 err.append(message);
27179 err.append(
"thrown but unknown type, cannot serialize into error message");
27182 #endif // serialize exception information if possible
27186 err.append(serr.data(), serr.size());
27188 #if SOL_IS_ON(SOL_PRINT_ERRORS)
27189 std::cerr <<
"[sol2] An error occurred and has been passed to an error handler: ";
27191 std::cerr << std::endl;
27200 int towards =
top - target;
27201 if (towards != 0) {
27204 #if SOL_IS_OFF(SOL_EXCEPTIONS)
27209 #endif // If exceptions are allowed
27213 #if SOL_IS_ON(SOL_DEFAULT_PASS_ON_ERROR)
27223 sol::error err = stack::get<sol::error>(L, -p);
27245 bool is53mod = loaded && !(loaded->is<
bool>() && !loaded->as<
bool>());
27248 #if SOL_LUA_VERSION_I_ <= 501
27250 bool is51mod = loaded51 && !(loaded51->is<
bool>() && !loaded51->as<
bool>());
27257 template <
typename T>
27259 #if SOL_LUA_VERSION_I_ <= 501
27260 auto pkg = global[
"package"];
27261 if (!pkg.valid()) {
27262 pkg = create_table_with(
"loaded", create_table_with(key, sr));
27265 auto ld = pkg[
"loaded"];
27267 ld = create_table_with(key, sr);
27274 auto loaded = reg[
"_LOADED"];
27275 if (!loaded.valid()) {
27276 loaded = create_table_with(key, sr);
27283 template <
typename Fx>
27284 object require_core(
const std::string& key, Fx&& action,
bool create_global =
true) {
27286 if (loaded && loaded->valid())
27291 if (before == after) {
27295 ensure_package(key,
static_cast<void*
>(L));
27301 ensure_package(key, sr);
27302 return stack::pop<object>(L);
27319 template <
typename... Args>
27322 if constexpr (
sizeof...(
args) == 0) {
27327 lib libraries[1 +
sizeof...(args)] = {
lib::count, std::forward<Args>(
args)... };
27329 for (
auto&& library : libraries) {
27331 #if SOL_LUA_VERSION_I_ <= 501 && SOL_IS_ON(SOL_USE_LUAJIT)
27333 #endif // luajit opens coroutine base stuff
27342 #if SOL_IS_OFF(SOL_USE_LUAJIT)
27344 #if SOL_LUA_VERSION_I_ > 501
27347 #endif // Lua 5.2+ only
27349 #endif // Not LuaJIT - comes builtin
27363 #if SOL_IS_ON(SOL_USE_LUAJIT)
27366 #elif SOL_IS_ON(SOL_LUA_BIT32_LIB)
27385 #if SOL_LUA_VERSION_I_ > 502 && SOL_IS_OFF(SOL_USE_LUAJIT)
27388 #endif // Lua 5.3+ only
27391 #if SOL_IS_ON(SOL_USE_LUAJIT) && SOL_IS_OFF(SOL_LUAJIT_FFI_DISABLED)
27394 #endif // LuaJIT only
27397 #if SOL_IS_ON(SOL_USE_LUAJIT)
27400 #endif // LuaJIT Only
27411 luaL_requiref(L, key.c_str(), open_function, create_global ? 1 : 0);
27412 return stack::pop<object>(L);
27418 return require_core(key, action, create_global);
27423 return require_core(key, action, create_global);
27428 if (!maybe_package) {
27433 table&
package = *maybe_package;
27437 auto loaders_proxy =
package
27438 #if SOL_LUA_VERSION_I_ < 502
27444 if (!loaders_proxy.valid()) {
27453 template <
typename Fx>
27456 if (!maybe_package) {
27461 table&
package = *maybe_package;
27465 auto loaders_proxy =
package
27466 #if SOL_LUA_VERSION_I_ < 502
27472 bool make_new_table = clear_all_package_loaders || !loaders_proxy.valid();
27473 if (make_new_table) {
27479 if (!maybe_loaders) {
27485 table loaders = loaders_proxy;
27486 loaders.
add(std::forward<Fx>(fx));
27489 template <
typename E>
27515 template <
typename E>
27541 template <
typename E>
27561 template <
typename Fx,
27567 if (!pfr.
valid()) {
27578 template <
typename Fx,
27584 if (!pfr.
valid()) {
27590 template <
typename Fx,
typename E>
27594 if (!pfr.
valid()) {
27600 template <
typename E>
27611 template <
typename Fx,
27616 if (!pfr.
valid()) {
27622 template <
typename Fx,
typename E>
27626 if (!pfr.
valid()) {
27632 template <
typename E>
27641 template <
typename E>
27655 int returns = postindex -
index;
27664 int returns = postindex -
index;
27668 template <
typename E>
27674 if (
luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(
mode).c_str())) {
27682 int returns = postindex -
index;
27691 int returns = postindex -
index;
27695 template <
typename E>
27706 int returns = postindex -
index;
27714 int returns = postindex -
index;
27718 template <
typename Fx,
27723 return safe_script(code, std::forward<Fx>(on_error), chunkname,
mode);
27726 template <
typename Fx,
27730 return safe_script_file(filename, std::forward<Fx>(on_error),
mode);
27733 template <
typename Fx,
typename E>
27736 return safe_script(code, env, std::forward<Fx>(on_error), chunkname,
mode);
27739 template <
typename Fx,
typename E>
27741 return safe_script_file(filename, env, std::forward<Fx>(on_error),
mode);
27753 #if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS)
27756 return safe_script(
reader,
data, chunkname, mode);
27759 protected_function_result
script(
27761 return safe_script(code, chunkname, mode);
27765 return safe_script_file(filename, mode);
27769 return unsafe_script(code, chunkname,
mode);
27773 return unsafe_script_file(filename,
mode);
27805 return global.
begin();
27809 return global.
end();
27817 return global.
cend();
27843 int s = stack_top();
27849 #if SOL_LUA_VERSION_I_ >= 504
27858 #if SOL_LUA_VERSION_I_ >= 502
27878 #if SOL_LUA_VERSION_I_ >= 504
27903 #if SOL_LUA_VERSION_I_ >= 504
27904 int old_mode =
lua_gc(lua_state(),
LUA_GCINC, pause, step_multiplier, step_byte_size);
27914 (
void)step_byte_size;
27921 #if SOL_LUA_VERSION_I_ >= 504
27924 int old_mode =
lua_gc(lua_state(),
LUA_GCGEN, minor_multiplier, major_multiplier);
27932 (
void)minor_multiplier;
27933 (
void)major_multiplier;
27939 return lua_state();
27950 template <
typename... Args,
typename... Keys>
27951 decltype(
auto)
get(Keys&&... keys)
const {
27952 return global.
get<Args...>(std::forward<Keys>(keys)...);
27955 template <
typename T,
typename Key>
27956 decltype(
auto) get_or(Key&& key, T&& otherwise)
const {
27957 return global.
get_or(std::forward<Key>(key), std::forward<T>(otherwise));
27960 template <
typename T,
typename Key,
typename D>
27961 decltype(
auto) get_or(Key&& key,
D&& otherwise)
const {
27962 return global.
get_or<T>(std::forward<Key>(key), std::forward<D>(otherwise));
27965 template <
typename... Args>
27967 global.
set(std::forward<Args>(
args)...);
27971 template <
typename T,
typename... Keys>
27972 decltype(
auto) traverse_get(Keys&&... keys)
const {
27973 return global.
traverse_get<T>(std::forward<Keys>(keys)...);
27976 template <
typename... Args>
27982 template <
typename Class,
typename... Args>
27987 template <
bool read_only =
true,
typename... Args>
27989 global.
new_enum<read_only>(name, std::forward<Args>(
args)...);
27993 template <
typename T,
bool read_only = true>
27999 template <
typename Fx>
28001 global.
for_each(std::forward<Fx>(fx));
28004 template <
typename T>
28006 return global[std::forward<T>(key)];
28009 template <
typename T>
28011 return global[std::forward<T>(key)];
28014 template <
typename Sig,
typename... Args,
typename Key>
28016 global.
set_function<Sig>(std::forward<Key>(key), std::forward<Args>(
args)...);
28020 template <
typename... Args,
typename Key>
28026 template <
typename Name>
28028 return global.
create(std::forward<Name>(name), narr, nrec);
28031 template <
typename Name,
typename Key,
typename Value,
typename... Args>
28033 return global.
create(std::forward<Name>(name), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(
args)...);
28036 template <
typename Name,
typename... Args>
28039 global.
set(std::forward<Name>(name),
x);
28044 return create_table(lua_state(), narr, nrec);
28047 template <
typename Key,
typename Value,
typename... Args>
28049 return create_table(lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(
args)...);
28052 template <
typename... Args>
28054 return create_table_with(lua_state(), std::forward<Args>(
args)...);
28061 template <
typename Key,
typename Value,
typename... Args>
28063 return global_table::create(L, narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(
args)...);
28066 template <
typename... Args>
28088 return lua_state();
28091 return lua_state();
28115 template <
typename Handler>
28128 template <
typename ref_t>
28129 class basic_thread :
public basic_object<ref_t> {
28134 using base_t::lua_state;
28139 template <typename T,
28142 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28145 stack::check<basic_thread>(lua_state(), -1,
handler);
28152 template <
typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
28154 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28157 stack::check<basic_thread>(lua_state(), -1,
handler);
28161 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28167 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28170 stack::check<basic_thread>(lua_state(), -1,
handler);
28178 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28180 stack::check<basic_thread>(lua_state(), -1,
handler);
28217 return create(lua_state());
28230 typedef basic_thread<reference> thread;
28256 state_view::operator=(
std::move(that));
28257 unique_base::operator=(
std::move(that));
28273 template <
typename Reference>
28274 class basic_coroutine :
public basic_object<Reference> {
28282 void luacall(std::ptrdiff_t argcount, std::ptrdiff_t) {
28283 #if SOL_LUA_VERSION_I_ >= 504
28285 stats =
static_cast<call_status>(
lua_resume(lua_state(),
nullptr,
static_cast<int>(argcount), &nresults));
28293 luacall(n,
sizeof...(Ret));
28294 return stack::pop<std::tuple<Ret...>>(lua_state());
28297 template <std::
size_t I,
typename Ret>
28300 return stack::pop<Ret>(lua_state());
28303 template <std::
size_t I>
28309 int firstreturn = 1;
28311 int poststacksize =
lua_gettop(this->lua_state());
28312 int returncount = poststacksize - (firstreturn - 1);
28314 if (m_error_handler.valid()) {
28315 string_view err = stack::get<string_view>(this->lua_state(), poststacksize);
28316 m_error_handler.push();
28326 using base_t::lua_state;
28329 template <
typename T,
28335 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28339 stack::check<basic_coroutine>(lua_state(), -1,
handler);
28378 template <
typename Super>
28382 template <
typename Super>
28386 template <
typename Proxy,
typename HandlerReference,
28392 template <
typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
28396 template <
typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
28398 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28401 stack::check<basic_coroutine>(lua_state(), -1,
handler);
28412 #ifdef SOL_SAFE_REFERENCES
28421 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28430 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28439 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28442 stack::check<basic_coroutine>(lua_state(), -1,
handler);
28459 explicit operator bool() const noexcept {
28463 template <
typename... Args>
28465 return call<>(std::forward<Args>(
args)...);
28468 template <
typename... Ret,
typename... Args>
28470 return call<Ret...>(std::forward<Args>(
args)...);
28473 template <
typename... Ret,
typename... Args>
28494 template <
typename base_type>
28495 class basic_userdata :
public basic_table<base_type> {
28500 using base_t::lua_state;
28503 template <typename T,
28507 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28522 template <
typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
28524 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28527 stack::check<basic_userdata>(L, -1,
handler);
28531 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28537 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28540 stack::check<basic_userdata>(L, -1,
handler);
28545 template <
typename base_type>
28546 class basic_lightuserdata :
public basic_object_base<base_type> {
28550 using base_t::lua_state;
28553 template <typename T,
28557 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28572 template <
typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
28574 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28577 stack::check<basic_lightuserdata>(lua_state(), -1,
handler);
28581 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28587 #if SOL_IS_ON(SOL_SAFE_REFERENCES)
28590 stack::check<basic_lightuserdata>(lua_state(),
index,
handler);
28602 template <
typename T>
28607 template <
typename Source>
28613 template <
typename T>
28617 for (
const auto& i : e.src) {
28631 #include <iterator>
28669 stacktop = o.stacktop;
28683 return iterator(L, stacktop + 1, stacktop + 1);
28699 return std::reverse_iterator<iterator>(begin());
28702 return std::reverse_iterator<iterator>(end());
28705 return std::reverse_iterator<const_iterator>(begin());
28708 return std::reverse_iterator<const_iterator>(end());
28711 return std::reverse_iterator<const_iterator>(cbegin());
28714 return std::reverse_iterator<const_iterator>(cend());
28723 for (
int i =
index; i <= stacktop; ++i) {
28733 template <
typename T>
28735 return stack::get<T>(L,
index +
static_cast<int>(index_offset));
28739 return type_of(L,
index +
static_cast<int>(index_offset));
28753 return stacktop - (
index - 1);
28756 return static_cast<std::size_t>(leftover_count());
28775 return ref.
push(L);
28788 template <
typename T>
28794 using base_t::base_t;
28795 using base_t::value;
28798 template <
typename Source>
28804 template <
typename T>
28809 for (
const auto& i : src) {
28824 template <
typename Al =
typename std::allocator<
object>>
28835 this->insert(this->cend(), fr.
begin(), fr.
end());
28840 this->insert(this->cend(), fr.
begin(), fr.
end());
28843 template <
typename Arg0,
typename... Args,
28861 template <
typename Al>
28868 template <
typename Al>
28872 for (
const auto& i : e) {
28883 return stack::push(L,
static_cast<const base_t&
>(r));
28892 #if SOL_IS_ON(SOL_COMPILER_GCC)
28893 #pragma GCC diagnostic pop
28894 #elif SOL_IS_ON(SOL_COMPILER_CLANG)
28895 #elif SOL_IS_ON(SOL_COMPILER_VCXX)
28896 #pragma warning(pop)
28899 #if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE)
28901 #pragma pop_macro("check")
28902 #endif // Unreal Engine 4 Bullshit
28907 #endif // SOL_SINGLE_INCLUDE_HPP