From a6abc0a0d9583f5799e9b4dbc68da69c5f2b8586 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Sat, 22 Dec 2018 15:36:42 -0500 Subject: [PATCH] update everything --- cmake/Modules/FindLuaBuild/LuaJIT.cmake | 45 +- docs/source/api/stack.rst | 2 +- docs/source/tutorial/customization.rst | 2 +- examples/source/customization.cpp | 98 ---- ...omization_global_transparent_argument.cpp} | 2 +- examples/source/customization_multiple.cpp | 70 +++ include/sol/as_args.hpp | 2 +- include/sol/as_returns.hpp | 2 +- include/sol/compatibility/version.hpp | 6 + include/sol/forward.hpp | 4 + include/sol/function_types.hpp | 68 +-- include/sol/protected_function_result.hpp | 2 +- include/sol/proxy.hpp | 2 +- include/sol/stack.hpp | 2 +- include/sol/stack_check_get_qualified.hpp | 55 ++- include/sol/stack_check_get_unqualified.hpp | 12 +- include/sol/stack_check_unqualified.hpp | 18 +- include/sol/stack_core.hpp | 27 +- include/sol/stack_proxy.hpp | 2 +- include/sol/stack_proxy_base.hpp | 2 +- include/sol/stack_push.hpp | 191 ++++---- include/sol/thread.hpp | 4 +- include/sol/unsafe_function_result.hpp | 2 +- include/sol/usertype_container.hpp | 22 +- include/sol/variadic_args.hpp | 2 +- include/sol/variadic_results.hpp | 2 +- single/include/sol/forward.hpp | 8 +- single/include/sol/sol.hpp | 428 ++++++++++-------- tests/runtime_tests/source/customizations.cpp | 34 +- .../source/customizations_private.cpp | 15 +- 30 files changed, 630 insertions(+), 501 deletions(-) delete mode 100644 examples/source/customization.cpp rename examples/source/{custom_global_transparent_argument.cpp => customization_global_transparent_argument.cpp} (91%) create mode 100644 examples/source/customization_multiple.cpp diff --git a/cmake/Modules/FindLuaBuild/LuaJIT.cmake b/cmake/Modules/FindLuaBuild/LuaJIT.cmake index d7c35cdb..7327f8f6 100644 --- a/cmake/Modules/FindLuaBuild/LuaJIT.cmake +++ b/cmake/Modules/FindLuaBuild/LuaJIT.cmake @@ -230,11 +230,11 @@ file(TO_CMAKE_PATH "${LUA_JIT_SOURCE_DIR}/${LUA_JIT_PREBUILT_EXE}" LUA_JIT_SOURC file(TO_CMAKE_PATH "${LUA_JIT_SOURCE_DIR}/${LUA_JIT_PREBUILT_DLL}" LUA_JIT_SOURCE_LUA_DLL) file(TO_CMAKE_PATH "${LUA_JIT_SOURCE_DIR}/${LUA_JIT_PREBUILT_EXP}" LUA_JIT_SOURCE_LUA_LIB_EXP) -file(TO_CMAKE_PATH "${LUA_JIT_LIB_FILE}" LUA_JIT_DESTINATION_LUA_LIB) -file(TO_CMAKE_PATH "${LUA_JIT_IMP_LIB_FILE}" LUA_JIT_DESTINATION_LUA_IMP_LIB) -file(TO_CMAKE_PATH "${LUA_JIT_EXE_FILE}" LUA_JIT_DESTINATION_LUA_INTERPRETER) file(TO_CMAKE_PATH "${LUA_JIT_DLL_FILE}" LUA_JIT_DESTINATION_LUA_DLL) file(TO_CMAKE_PATH "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${LUA_JIT_LIB_EXP_FILENAME}" LUA_JIT_DESTINATION_LUA_LIB_EXP) +file(TO_CMAKE_PATH "${LUA_JIT_IMP_LIB_FILE}" LUA_JIT_DESTINATION_LUA_IMP_LIB) +file(TO_CMAKE_PATH "${LUA_JIT_LIB_FILE}" LUA_JIT_DESTINATION_LUA_LIB) +file(TO_CMAKE_PATH "${LUA_JIT_EXE_FILE}" LUA_JIT_DESTINATION_LUA_INTERPRETER) if (WIN32 AND NOT MSVC) string(COMPARE EQUAL ${LUA_JIT_VERSION} ${LUA_JIT_2.0_LATEST_VERSION} lua_jit_same_version_20) @@ -247,21 +247,14 @@ elseif(LUA_JIT_NORMALIZED_LUA_VERSION MATCHES "latest") set(LUA_JIT_PULL_LATEST TRUE) endif() -set(LUA_JIT_BYPRODUCTS "${LUA_JIT_SOURCE_LUA_LIB}" +set(LUA_JIT_BYPRODUCTS "${LUA_JIT_SOURCE_LUA_LIB}" "${LUA_JIT_SOURCE_LUA_LIB_EXP}" "${LUA_JIT_SOURCE_LUA_DLL}" "${LUA_JIT_SOURCE_LUA_INTERPRETER}") -set(LUA_JIT_INSTALL_BYPRODUCTS "${LUA_JIT_DESTINATION_LUA_LIB}" +set(LUA_JIT_INSTALL_BYPRODUCTS "${LUA_JIT_DESTINATION_LUA_LIB}" "${LUA_JIT_DESTINATION_LUA_LIB_EXP}" "${LUA_JIT_DESTINATION_LUA_DLL}" "${LUA_JIT_DESTINATION_LUA_INTERPRETER}") -if (MSVC) - set(LUA_JIT_BYPRODUCTS "${LUA_JIT_BYPRODUCTS}" "${LUA_JIT_SOURCE_LUA_LIB_EXP}") - set(LUA_JIT_INSTALL_BYPRODUCTS "${LUA_JIT_INSTALL_BYPRODUCTS}" "${LUA_JIT_DESTINATION_LUA_LIB_EXP}") -endif() - if (CMAKE_IMPORT_LIBRARY_SUFFIX) - if (NOT MSVC) - set(LUA_JIT_BYPRODUCTS "${LUA_JIT_BYPRODUCTS}" "${LUA_JIT_SOURCE_LUA_IMP_LIB}") - endif() + set(LUA_JIT_BYPRODUCTS "${LUA_JIT_BYPRODUCTS}" "${LUA_JIT_SOURCE_LUA_IMP_LIB}") set(LUA_JIT_INSTALL_BYPRODUCTS "${LUA_JIT_INSTALL_BYPRODUCTS}" "${LUA_JIT_DESTINATION_LUA_IMP_LIB}") endif() @@ -271,16 +264,16 @@ set(LUA_JIT_POSTBUILD_COMMENTS "Executable - Moving \"${LUA_JIT_SOURCE_LUA_INTER set(LUA_JIT_POSTBUILD_COMMANDS COMMAND "${CMAKE_COMMAND}" -E copy "${LUA_JIT_SOURCE_LUA_INTERPRETER}" "${LUA_JIT_DESTINATION_LUA_INTERPRETER}") if (BUILD_LUA_AS_DLL) if (MSVC) - set(LUA_JIT_POSTBUILD_COMMENTS "${LUA_JIT_POSTBUILD_COMMENTS}\nImport Library - Moving \"${LUA_JIT_SOURCE_LUA_IMP_LIB}\" to \"${LUA_JIT_DESTINATION_LUA_IMP_LIB}\"...") + set(LUA_JIT_POSTBUILD_COMMENTS "${LUA_JIT_POSTBUILD_COMMENTS} | Import Library - Moving \"${LUA_JIT_SOURCE_LUA_IMP_LIB}\" to \"${LUA_JIT_DESTINATION_LUA_IMP_LIB}\"...") set(LUA_JIT_POSTBUILD_COMMANDS ${LUA_JIT_POSTBUILD_COMMANDS} COMMAND "${CMAKE_COMMAND}" -E copy "${LUA_JIT_SOURCE_LUA_IMP_LIB}" "${LUA_JIT_DESTINATION_LUA_IMP_LIB}") - set(LUA_JIT_POSTBUILD_COMMENTS "${LUA_JIT_POSTBUILD_COMMENTS}\nLibrary - Moving \"${LUA_JIT_SOURCE_LUA_LIB_EXP}\" to \"${LUA_JIT_DESTINATION_LUA_LIB_EXP}\"...") + set(LUA_JIT_POSTBUILD_COMMENTS "${LUA_JIT_POSTBUILD_COMMENTS} | Library - Moving \"${LUA_JIT_SOURCE_LUA_LIB_EXP}\" to \"${LUA_JIT_DESTINATION_LUA_LIB_EXP}\"...") set(LUA_JIT_POSTBUILD_COMMANDS ${LUA_JIT_POSTBUILD_COMMANDS} && "${CMAKE_COMMAND}" -E copy "${LUA_JIT_SOURCE_LUA_LIB_EXP}" "${LUA_JIT_DESTINATION_LUA_LIB_EXP}") endif() - set(LUA_JIT_POSTBUILD_COMMENTS "${LUA_JIT_POSTBUILD_COMMENTS}\nDynamic Library - Moving \"${LUA_JIT_SOURCE_LUA_DLL}\" to \"${LUA_JIT_DESTINATION_LUA_DLL}\"...") + set(LUA_JIT_POSTBUILD_COMMENTS "${LUA_JIT_POSTBUILD_COMMENTS} | Dynamic Library - Moving \"${LUA_JIT_SOURCE_LUA_DLL}\" to \"${LUA_JIT_DESTINATION_LUA_DLL}\"...") set(LUA_JIT_POSTBUILD_COMMANDS ${LUA_JIT_POSTBUILD_COMMANDS} COMMAND "${CMAKE_COMMAND}" -E copy "${LUA_JIT_SOURCE_LUA_DLL}" "${LUA_JIT_DESTINATION_LUA_DLL}") else() - set(LUA_JIT_POSTBUILD_COMMENTS "${LUA_JIT_POSTBUILD_COMMENTS}\nLibrary - Moving \"${LUA_JIT_SOURCE_LUA_LIB}\" to \"${LUA_JIT_DESTINATION_LUA_LIB}\"...") + set(LUA_JIT_POSTBUILD_COMMENTS "${LUA_JIT_POSTBUILD_COMMENTS} | Library - Moving \"${LUA_JIT_SOURCE_LUA_LIB}\" to \"${LUA_JIT_DESTINATION_LUA_LIB}\"...") set(LUA_JIT_POSTBUILD_COMMANDS ${LUA_JIT_POSTBUILD_COMMANDS} COMMAND "${CMAKE_COMMAND}" -E copy "${LUA_JIT_SOURCE_LUA_LIB}" "${LUA_JIT_DESTINATION_LUA_LIB}") endif() @@ -307,7 +300,7 @@ if (LUA_JIT_GIT_COMMIT OR LUA_JIT_PULL_LATEST) ${LUA_JIT_BUILD_COMMAND} INSTALL_COMMAND "" TEST_COMMAND "" - BUILD_BYPRODUCTS "${LUA_JIT_BYPRODUCTS}") + BUILD_BYPRODUCTS "${LUA_JIT_BYPRODUCTS}" "${LUA_JIT_BYPRODUCTS}") else() ExternalProject_Add(LUA_JIT BUILD_IN_SOURCE TRUE @@ -326,25 +319,25 @@ else() CONFIGURE_COMMAND "" ${LUA_JIT_BUILD_COMMAND} INSTALL_COMMAND "" - TEST_COMMAND "" - BUILD_BYPRODUCTS "${LUA_JIT_BYPRODUCTS}") + TEST_COMMAND "") endif() # # MAYBE?: # Add additional post-build step to move all necessary headers/lua files # for now, we just point directly to the `src` directory... -add_custom_target(luajit_postbuild +ExternalProject_Add_Step(LUA_JIT move ${LUA_JIT_POSTBUILD_COMMANDS} + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMENT ${LUA_JIT_POSTBUILD_COMMENTS} - DEPENDS "${LUA_JIT_BYPRODUCTS}" -) - + DEPENDS build + ALWAYS TRUE) +ExternalProject_Add_StepTargets(LUA_JIT move) # # Lua Library add_library(${lualib} ${LUA_BUILD_LIBRARY_TYPE} IMPORTED) # make sure the library we export really does depend on Lua JIT's external project -add_dependencies(${lualib} luajit_postbuild) +add_dependencies(${lualib} LUA_JIT-move) # Configure properties if (BUILD_LUA_AS_DLL) if (MSVC) @@ -380,7 +373,7 @@ add_executable(${luainterpreter} IMPORTED) set_target_properties(${luainterpreter} PROPERTIES IMPORTED_LOCATION "${LUA_JIT_DESTINATION_LUA_INTERPRETER}") -add_dependencies(${luainterpreter} luajit_postbuild) +add_dependencies(${luainterpreter} LUA_JIT-move) # # set externally-visible target indicator set(LUA_LIBRARIES ${lualib}) diff --git a/docs/source/api/stack.rst b/docs/source/api/stack.rst index cfa4b179..d9695d82 100644 --- a/docs/source/api/stack.rst +++ b/docs/source/api/stack.rst @@ -241,7 +241,7 @@ This is an SFINAE-friendly struct that is meant to expose static function ``get` :name: pusher template - struct pusher { + struct unqualified_pusher { template static int push ( lua_State* L, T&&, ... ) { // can optionally take more than just 1 argument diff --git a/docs/source/tutorial/customization.rst b/docs/source/tutorial/customization.rst index 5140cedd..9cdf7714 100644 --- a/docs/source/tutorial/customization.rst +++ b/docs/source/tutorial/customization.rst @@ -1,7 +1,7 @@ adding your own types ===================== -Sometimes, overriding Sol to make it handle certain ``struct``'s and ``class``'es as something other than just userdata is desirable. The way to do this is to take advantage of the 4 customization points for Sol. These are ``sol::lua_size``, ``sol::stack::pusher``, ``sol::stack::getter``, ``sol::stack::checker``. +Sometimes, overriding Sol to make it handle certain ``struct``'s and ``class``'es as something other than just userdata is desirable. The way to do this is to take advantage of the 4 customization points for Sol. These are ``sol::lua_size``, ``sol::stack::unqualified_pusher``, ``sol::stack::getter``, ``sol::stack::checker``. These are template class/structs, so you'll override them using a technique C++ calls *class/struct specialization*. Below is an example of a struct that gets broken apart into 2 pieces when going in the C++ --> Lua direction, and then pulled back into a struct when going in the Lua --> C++: diff --git a/examples/source/customization.cpp b/examples/source/customization.cpp deleted file mode 100644 index 32832c11..00000000 --- a/examples/source/customization.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#define SOL_CHECK_ARGUMENTS 1 -#include - -#include -#include "assert.hpp" - -struct two_things { - int a; - bool b; -}; - -namespace sol { - - // First, the expected size - // Specialization of a struct - template <> - struct lua_size : std::integral_constant {}; - - // Then, specialize the type - // this makes sure Sol can return it properly - template <> - struct lua_type_of : std::integral_constant {}; - - // Now, specialize various stack structures - namespace stack { - - template <> - struct unqualified_checker { - template - static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { - // indices can be negative to count backwards from the top of the stack, - // rather than the bottom up - // to deal with this, we adjust the index to - // its absolute position using the lua_absindex function - int absolute_index = lua_absindex(L, index); - // Check first and second second index for being the proper types - bool success = stack::check(L, absolute_index, handler) - && stack::check(L, absolute_index + 1, handler); - tracking.use(2); - return success; - } - }; - - template <> - struct unqualified_getter { - static two_things get(lua_State* L, int index, record& tracking) { - int absolute_index = lua_absindex(L, index); - // Get the first element - int a = stack::get(L, absolute_index); - // Get the second element, - // in the +1 position from the first - bool b = stack::get(L, absolute_index + 1); - // we use 2 slots, each of the previous takes 1 - tracking.use(2); - return two_things{ a, b }; - } - }; - - template <> - struct pusher { - static int push(lua_State* L, const two_things& things) { - int amount = stack::push(L, things.a); - // amount will be 1: int pushes 1 item - amount += stack::push(L, things.b); - // amount 2 now, since bool pushes a single item - // Return 2 things - return amount; - } - }; - - } -} - -int main() { - std::cout << "=== customization ===" << std::endl; - std::cout << std::boolalpha; - - sol::state lua; - lua.open_libraries(sol::lib::base); - - // Create a pass-through style of function - lua.script("function f ( a, b ) print(a, b) return a, b end"); - - // get the function out of Lua - sol::function f = lua["f"]; - - two_things things = f(two_things{ 24, false }); - c_assert(things.a == 24); - c_assert(things.b == false); - // things.a == 24 - // things.b == true - - std::cout << "things.a: " << things.a << std::endl; - std::cout << "things.b: " << things.b << std::endl; - std::cout << std::endl; - - return 0; -} diff --git a/examples/source/custom_global_transparent_argument.cpp b/examples/source/customization_global_transparent_argument.cpp similarity index 91% rename from examples/source/custom_global_transparent_argument.cpp rename to examples/source/customization_global_transparent_argument.cpp index 3ebdfae4..2ab95073 100644 --- a/examples/source/custom_global_transparent_argument.cpp +++ b/examples/source/customization_global_transparent_argument.cpp @@ -37,7 +37,7 @@ GlobalResource* sol_lua_get(sol::types, lua_State* L, int /*ind return ls; } -int sol_lua_push(lua_State* L, GlobalResource* ls) { +int sol_lua_push(sol::types, lua_State* L, GlobalResource* ls) { // push light userdata return sol::stack::push(L, static_cast(ls)); } diff --git a/examples/source/customization_multiple.cpp b/examples/source/customization_multiple.cpp new file mode 100644 index 00000000..9a8d1321 --- /dev/null +++ b/examples/source/customization_multiple.cpp @@ -0,0 +1,70 @@ +#define SOL_CHECK_ARGUMENTS 1 +#include + +#include +#include "assert.hpp" + +struct two_things { + int a; + bool b; +}; + +template +bool check(sol::types, lua_State* L, int index, Handler&& handler, sol::stack::record& tracking) { + // indices can be negative to count backwards from the top of the stack, + // rather than the bottom up + // to deal with this, we adjust the index to + // its absolute position using the lua_absindex function + int absolute_index = lua_absindex(L, index); + // Check first and second second index for being the proper types + bool success = sol::stack::check(L, absolute_index, handler) && sol::stack::check(L, absolute_index + 1, handler); + tracking.use(2); + return success; +} + +two_things get(sol::types, lua_State* L, int index, sol::stack::record& tracking) { + int absolute_index = lua_absindex(L, index); + // Get the first element + int a = sol::stack::get(L, absolute_index); + // Get the second element, + // in the +1 position from the first + bool b = sol::stack::get(L, absolute_index + 1); + // we use 2 slots, each of the previous takes 1 + tracking.use(2); + return two_things{ a, b }; +} + +int push(sol::types, lua_State* L, const two_things& things) { + int amount = sol::stack::push(L, things.a); + // amount will be 1: int pushes 1 item + amount += sol::stack::push(L, things.b); + // amount 2 now, since bool pushes a single item + // Return 2 things + return amount; +} + +int main() { + std::cout << "=== customization ===" << std::endl; + std::cout << std::boolalpha; + + sol::state lua; + lua.open_libraries(sol::lib::base); + + // Create a pass-through style of function + lua.script("function f ( a, b ) print(a, b) return a, b end"); + + // get the function out of Lua + sol::function f = lua["f"]; + + two_things things = f(two_things{ 24, false }); + c_assert(things.a == 24); + c_assert(things.b == false); + // things.a == 24 + // things.b == true + + std::cout << "things.a: " << things.a << std::endl; + std::cout << "things.b: " << things.b << std::endl; + std::cout << std::endl; + + return 0; +} diff --git a/include/sol/as_args.hpp b/include/sol/as_args.hpp index 2c96680d..40311d67 100644 --- a/include/sol/as_args.hpp +++ b/include/sol/as_args.hpp @@ -39,7 +39,7 @@ namespace sol { namespace stack { template - struct pusher> { + struct unqualified_pusher> { int push(lua_State* L, const as_args_t& e) { int p = 0; for (const auto& i : e.src) { diff --git a/include/sol/as_returns.hpp b/include/sol/as_returns.hpp index 01821752..f4688da0 100644 --- a/include/sol/as_returns.hpp +++ b/include/sol/as_returns.hpp @@ -40,7 +40,7 @@ namespace sol { namespace stack { template - struct pusher> { + struct unqualified_pusher> { int push(lua_State* L, const as_returns_t& e) { auto& src = detail::unwrap(e.src); int p = 0; diff --git a/include/sol/compatibility/version.hpp b/include/sol/compatibility/version.hpp index b551b144..e367f95b 100644 --- a/include/sol/compatibility/version.hpp +++ b/include/sol/compatibility/version.hpp @@ -49,6 +49,12 @@ #endif // sol luajit #endif // luajit +#if SOL_LUAJIT && SOL_LUAJIT_VERSION >= 20100 +#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) && (!defined(SOL_EXCEPTIONS_ALWAYS_UNSAFE) && !(SOL_EXCEPTIONS_ALWAYS_UNSAFE)) +#define SOL_EXCEPTIONS_SAFE_PROPAGATION 1 +#endif // Do not catch (...) clauses +#endif // LuaJIT beta 02.01.00 have better exception handling on all platforms since beta3 + #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 502 #define SOL_LUA_VERSION LUA_VERSION_NUM #elif defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501 diff --git a/include/sol/forward.hpp b/include/sol/forward.hpp index 9d745b57..edc987fd 100644 --- a/include/sol/forward.hpp +++ b/include/sol/forward.hpp @@ -198,6 +198,10 @@ namespace sol { template bool weak_derive::value = false; + namespace stack { + struct record; + } + } // namespace sol #define SOL_BASE_CLASSES(T, ...) \ diff --git a/include/sol/function_types.hpp b/include/sol/function_types.hpp index d8df2fad..770f81a4 100644 --- a/include/sol/function_types.hpp +++ b/include/sol/function_types.hpp @@ -42,7 +42,7 @@ namespace sol { namespace stack { template - struct pusher> { + struct unqualified_pusher> { template static void select_convertible(std::false_type, types, lua_State* L, Fx&& fx, Args&&... args) { typedef std::remove_pointer_t> clean_fx; @@ -244,24 +244,24 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { template static int push(lua_State* L, const yielding_t& f, Args&&... args) { - pusher> p{}; + unqualified_pusher> p{}; (void)p; return p.push(L, detail::yield_tag, f.func, std::forward(args)...); } template static int push(lua_State* L, yielding_t&& f, Args&&... args) { - pusher> p{}; + unqualified_pusher> p{}; (void)p; return p.push(L, detail::yield_tag, f.func, std::forward(args)...); } }; template - struct pusher> { + struct unqualified_pusher> { template static int push_func(std::index_sequence, lua_State* L, FP&& fp) { return stack::push(L, std::get(std::forward(fp).arguments)...); @@ -277,28 +277,28 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const std::function& fx) { - return pusher>{}.push(L, fx); + return unqualified_pusher>{}.push(L, fx); } static int push(lua_State* L, std::function&& fx) { - return pusher>{}.push(L, std::move(fx)); + return unqualified_pusher>{}.push(L, std::move(fx)); } }; template - struct pusher::value>> { + struct unqualified_pusher::value>> { template static int push(lua_State* L, F&& f, Args&&... args) { - pusher> p{}; + unqualified_pusher> p{}; (void)p; return p.push(L, std::forward(f), std::forward(args)...); } }; template - struct pusher>, meta::neg>, meta::neg>> + struct unqualified_pusher>, meta::neg>, meta::neg>> #if defined(SOL_NOEXCEPT_FUNCTION_TYPE) && SOL_NOEXCEPT_FUNCTION_TYPE , meta::neg>, meta::neg>> @@ -306,29 +306,29 @@ namespace sol { >::value>> { template static int push(lua_State* L, F&& f) { - return pusher>{}.push(L, std::forward(f)); + return unqualified_pusher>{}.push(L, std::forward(f)); } }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, overload_set&& set) { // TODO: yielding typedef function_detail::overloaded_function<0, Functions...> F; - pusher>{}.set_fx(L, std::move(set.functions)); + unqualified_pusher>{}.set_fx(L, std::move(set.functions)); return 1; } static int push(lua_State* L, const overload_set& set) { // TODO: yielding typedef function_detail::overloaded_function<0, Functions...> F; - pusher>{}.set_fx(L, set.functions); + unqualified_pusher>{}.set_fx(L, set.functions); return 1; } }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, protect_t&& pw) { lua_CFunction cf = call_detail::call_user, 2>; int upvalues = 0; @@ -347,7 +347,7 @@ namespace sol { }; template - struct pusher, std::enable_if_t::value && !std::is_void::value>> { + struct unqualified_pusher, std::enable_if_t::value && !std::is_void::value>> { static int push(lua_State* L, property_wrapper&& pw) { return stack::push(L, overload(std::move(pw.read), std::move(pw.write))); } @@ -357,7 +357,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, property_wrapper&& pw) { return stack::push(L, std::move(pw.read)); } @@ -367,7 +367,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, property_wrapper&& pw) { return stack::push(L, std::move(pw.write)); } @@ -377,7 +377,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, var_wrapper&& vw) { return stack::push(L, std::move(vw.value)); } @@ -387,34 +387,34 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const factory_wrapper& fw) { typedef function_detail::overloaded_function<0, Functions...> F; - pusher>{}.set_fx(L, fw.functions); + unqualified_pusher>{}.set_fx(L, fw.functions); return 1; } static int push(lua_State* L, factory_wrapper&& fw) { typedef function_detail::overloaded_function<0, Functions...> F; - pusher>{}.set_fx(L, std::move(fw.functions)); + unqualified_pusher>{}.set_fx(L, std::move(fw.functions)); return 1; } static int push(lua_State* L, const factory_wrapper& set, function_detail::call_indicator) { typedef function_detail::overloaded_function<1, Functions...> F; - pusher>{}.set_fx(L, set.functions); + unqualified_pusher>{}.set_fx(L, set.functions); return 1; } static int push(lua_State* L, factory_wrapper&& set, function_detail::call_indicator) { typedef function_detail::overloaded_function<1, Functions...> F; - pusher>{}.set_fx(L, std::move(set.functions)); + unqualified_pusher>{}.set_fx(L, std::move(set.functions)); return 1; } }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, no_construction) { lua_CFunction cf = &function_detail::no_construction_error; return stack::push(L, cf); @@ -426,7 +426,7 @@ namespace sol { }; template - struct pusher>> { + struct unqualified_pusher>> { static int push(lua_State* L, detail::tagged>) { lua_CFunction cf = call_detail::construct; return stack::push(L, cf); @@ -439,7 +439,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { typedef constructor_list cl_t; static int push(lua_State* L, cl_t cl) { typedef typename meta::bind_traits::return_type T; @@ -448,7 +448,7 @@ namespace sol { }; template - struct pusher>> { + struct unqualified_pusher>> { template static int push(lua_State* L, C&& c) { lua_CFunction cf = call_detail::call_user, 2>; @@ -460,7 +460,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { template static int push(lua_State* L, C&& c) { typedef typename meta::bind_traits::template arg_at<0> arg0; @@ -470,7 +470,7 @@ namespace sol { }; template - struct pusher>> { + struct unqualified_pusher>> { static int push(lua_State* L, destructor_wrapper) { lua_CFunction cf = detail::usertype_alloc_destruct; return stack::push(L, cf); @@ -478,7 +478,7 @@ namespace sol { }; template - struct pusher>> { + struct unqualified_pusher>> { static int push(lua_State* L, destructor_wrapper&& c) { lua_CFunction cf = call_detail::call_user, 2>; int upvalues = 0; @@ -497,7 +497,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, destructor_wrapper&& c) { lua_CFunction cf = call_detail::call_user, 2>; int upvalues = 0; @@ -516,7 +516,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { typedef filter_wrapper P; static int push(lua_State* L, const P& p) { diff --git a/include/sol/protected_function_result.hpp b/include/sol/protected_function_result.hpp index 7313cea4..9a2123f2 100644 --- a/include/sol/protected_function_result.hpp +++ b/include/sol/protected_function_result.hpp @@ -211,7 +211,7 @@ namespace sol { namespace stack { template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const protected_function_result& pfr) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, static_cast(pfr.pop_count()), detail::not_enough_stack_space_generic); diff --git a/include/sol/proxy.hpp b/include/sol/proxy.hpp index 99f0f0c6..da48cb7e 100644 --- a/include/sol/proxy.hpp +++ b/include/sol/proxy.hpp @@ -253,7 +253,7 @@ namespace sol { namespace stack { template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const proxy& p) { reference r = p; return r.push(L); diff --git a/include/sol/stack.hpp b/include/sol/stack.hpp index 632ce894..1cf5f81e 100644 --- a/include/sol/stack.hpp +++ b/include/sol/stack.hpp @@ -244,7 +244,7 @@ namespace sol { } inline void luajit_exception_handler(lua_State* L, int (*handler)(lua_State*, lua_CFunction) = detail::c_trampoline) { -#if defined(SOL_LUAJIT) && !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) +#if defined(SOL_LUAJIT) && (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !(SOL_EXCEPTIONS_SAFE_PROPAGATION)) if (L == nullptr) { return; } diff --git a/include/sol/stack_check_get_qualified.hpp b/include/sol/stack_check_get_qualified.hpp index fc3c4f87..5f9866a0 100644 --- a/include/sol/stack_check_get_qualified.hpp +++ b/include/sol/stack_check_get_qualified.hpp @@ -26,17 +26,60 @@ #include "stack_core.hpp" #include "stack_check_get_unqualified.hpp" +#include "optional.hpp" -namespace sol { -namespace stack { +namespace sol { namespace stack { template struct qualified_check_getter { + typedef decltype(stack_detail::unchecked_get(nullptr, -1, std::declval())) R; + template - static decltype(auto) get(lua_State* L, int index, Handler&& handler, record& tracking) { - return stack::unqualified_check_get(L, index, std::forward(handler), tracking); + static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { + if (!check(L, index, std::forward(handler))) { + tracking.use(static_cast(!lua_isnone(L, index))); + return nullopt; + } + return stack_detail::unchecked_get(L, index, tracking); } }; -} -} // namespace sol::stack + + template + struct qualified_check_getter::value>> { + template + static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { + // actually check if it's none here, otherwise + // we'll have a none object inside an optional! + bool success = lua_isnoneornil(L, index) == 0 && stack::check(L, index, no_panic); + if (!success) { + // expected type, actual type + tracking.use(static_cast(success)); + handler(L, index, type::poly, type_of(L, index), ""); + return nullopt; + } + return stack_detail::unchecked_get(L, index, tracking); + } + }; + + template + struct qualified_getter> { + static decltype(auto) get(lua_State* L, int index, record& tracking) { + return check_get(L, index, no_panic, tracking); + } + }; + +#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES + template + struct qualified_getter> { + static std::optional get(lua_State* L, int index, record& tracking) { + if (!check(L, index, no_panic)) { + tracking.use(static_cast(!lua_isnone(L, index))); + return std::nullopt; + } + return stack_detail::unchecked_get(L, index, tracking); + } + }; +#endif // C++17 features + +}} // namespace sol::stack #endif // SOL_STACK_CHECK_QUALIFIED_GET_HPP diff --git a/include/sol/stack_check_get_unqualified.hpp b/include/sol/stack_check_get_unqualified.hpp index a9325495..e36c35b1 100644 --- a/include/sol/stack_check_get_unqualified.hpp +++ b/include/sol/stack_check_get_unqualified.hpp @@ -40,7 +40,7 @@ namespace sol { namespace stack { template - struct check_getter { + struct unqualified_check_getter { typedef decltype(stack_detail::unchecked_unqualified_get(nullptr, -1, std::declval())) R; template @@ -54,7 +54,7 @@ namespace stack { }; template - struct check_getter::value>> { + struct unqualified_check_getter::value>> { template static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { // actually check if it's none here, otherwise @@ -71,7 +71,7 @@ namespace stack { }; template - struct check_getter::value && lua_type_of::value == type::number>> { + struct unqualified_check_getter::value && lua_type_of::value == type::number>> { template static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { #if SOL_LUA_VERSION >= 503 @@ -102,7 +102,7 @@ namespace stack { }; template - struct check_getter::value && !meta::any_same::value>> { + struct unqualified_check_getter::value && !meta::any_same::value>> { template static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { int isnum = 0; @@ -119,7 +119,7 @@ namespace stack { }; template - struct check_getter::value>> { + struct unqualified_check_getter::value>> { template static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { int isnum = 0; @@ -156,7 +156,7 @@ namespace stack { #if defined(SOL_STD_VARIANT) && SOL_STD_VARIANT template - struct check_getter> { + struct unqualified_check_getter> { typedef std::variant V; typedef std::variant_size V_size; typedef std::integral_constant V_is_empty; diff --git a/include/sol/stack_check_unqualified.hpp b/include/sol/stack_check_unqualified.hpp index 6f9cc746..8cd539a2 100644 --- a/include/sol/stack_check_unqualified.hpp +++ b/include/sol/stack_check_unqualified.hpp @@ -1,4 +1,4 @@ -// sol3 +// sol3 // The MIT License (MIT) @@ -38,8 +38,7 @@ #endif // SOL_STD_VARIANT #endif // SOL_CXX17_FEATURES -namespace sol { -namespace stack { +namespace sol { namespace stack { namespace stack_detail { template inline bool check_metatable(lua_State* L, int index = -2) { @@ -95,7 +94,12 @@ namespace stack { }; template - struct qualified_checker : unqualified_checker, lua_type_of>::value, C> {}; + struct qualified_checker { + template + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + return stack::unqualified_check(L, index, std::forward(handler), tracking); + } + }; template struct unqualified_checker::value>> { @@ -459,7 +463,8 @@ namespace stack { handler(L, index, type::userdata, indextype, "value is not a valid userdata"); return false; } - if (meta::any, std::is_same, std::is_same, std::is_same>::value) + if (meta::any, std::is_same, std::is_same, std::is_same>:: + value) return true; if (lua_getmetatable(L, index) == 0) { return true; @@ -668,7 +673,6 @@ namespace stack { #endif // SOL_STD_VARIANT #endif // SOL_CXX17_FEATURES -} -} // namespace sol::stack +}} // namespace sol::stack #endif // SOL_STACK_CHECK_UNQUALIFIED_HPP diff --git a/include/sol/stack_core.hpp b/include/sol/stack_core.hpp index 465f592b..8bfc6fe6 100644 --- a/include/sol/stack_core.hpp +++ b/include/sol/stack_core.hpp @@ -48,6 +48,7 @@ namespace sol { namespace detail { + struct with_function_tag {}; struct as_reference_tag {}; template struct as_pointer_tag {}; @@ -570,7 +571,7 @@ namespace sol { template struct popper; template - struct pusher; + struct unqualified_pusher; template ::value, typename = void> struct unqualified_checker; template ::value, typename = void> @@ -578,7 +579,7 @@ namespace sol { template struct userdata_checker; template - struct check_getter; + struct unqualified_check_getter; template struct qualified_check_getter; @@ -613,7 +614,8 @@ namespace sol { struct is_adl_sol_lua_get { private: template - static meta::sfinae_yes_t test(decltype(sol_lua_get(types(), static_cast(nullptr), -1, std::declval()))*); + static meta::sfinae_yes_t test( + std::remove_reference_t(), static_cast(nullptr), -1, std::declval()))>*); template static meta::sfinae_no_t test(...); @@ -625,8 +627,8 @@ namespace sol { struct is_adl_sol_lua_check { private: template - static meta::sfinae_yes_t test( - decltype(sol_lua_check(types(), static_cast(nullptr), -1, no_panic, std::declval()))*); + static meta::sfinae_yes_t test(std::remove_reference_t(), static_cast(nullptr), -1, no_panic, std::declval()))>*); template static meta::sfinae_no_t test(...); @@ -638,8 +640,8 @@ namespace sol { struct is_adl_sol_lua_check_get { private: template - static meta::sfinae_yes_t test( - decltype(sol_lua_check_get(types(), static_cast(nullptr), -1, no_panic, std::declval()))*); + static meta::sfinae_yes_t test(std::remove_reference_t(), static_cast(nullptr), -1, no_panic, std::declval()))>*); template static meta::sfinae_no_t test(...); @@ -651,7 +653,7 @@ namespace sol { struct is_adl_sol_lua_push { private: template - static meta::sfinae_yes_t test(decltype(sol_lua_push(static_cast(nullptr), std::declval()...))*); + static meta::sfinae_yes_t test(std::remove_reference_t(nullptr), std::declval()...))>*); template static meta::sfinae_no_t test(...); @@ -663,7 +665,8 @@ namespace sol { struct is_adl_sol_lua_push_exact { private: template - static meta::sfinae_yes_t test(decltype(sol_lua_push(types(), static_cast(nullptr), std::declval()...))*); + static meta::sfinae_yes_t test( + std::remove_reference_t(), static_cast(nullptr), std::declval()...))>*); template static meta::sfinae_no_t test(...); @@ -812,7 +815,7 @@ namespace sol { return sol_lua_push(L, std::forward(t), std::forward(args)...); } else { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, std::forward(t), std::forward(args)...); } @@ -832,7 +835,7 @@ namespace sol { return sol_lua_push(L, std::forward(arg), std::forward(args)...); } else { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, std::forward(arg), std::forward(args)...); } @@ -974,7 +977,7 @@ namespace sol { return sol_lua_check_get(types(), L, index, std::forward(handler), tracking); } else { - check_getter cg{}; + unqualified_check_getter cg{}; (void)cg; return cg.get(L, index, std::forward(handler), tracking); } diff --git a/include/sol/stack_proxy.hpp b/include/sol/stack_proxy.hpp index fce516c9..e23161c4 100644 --- a/include/sol/stack_proxy.hpp +++ b/include/sol/stack_proxy.hpp @@ -54,7 +54,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State*, const stack_proxy& ref) { return ref.push(); } diff --git a/include/sol/stack_proxy_base.hpp b/include/sol/stack_proxy_base.hpp index 71d954d0..7823d4a6 100644 --- a/include/sol/stack_proxy_base.hpp +++ b/include/sol/stack_proxy_base.hpp @@ -86,7 +86,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State*, const stack_proxy_base& ref) { return ref.push(); } diff --git a/include/sol/stack_push.hpp b/include/sol/stack_push.hpp index 9d9eedc3..912430fd 100644 --- a/include/sol/stack_push.hpp +++ b/include/sol/stack_push.hpp @@ -71,7 +71,7 @@ namespace sol { } template - struct pusher> { + struct unqualified_pusher> { template static int push_fx(lua_State* L, F&& f, Args&&... args) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK @@ -95,14 +95,23 @@ namespace sol { return push_fx(L, fx, std::forward(args)...); } + template , detail::with_function_tag>>> + static int push(lua_State* L, Arg&& arg, Args&&... args) { + return push_keyed(L, usertype_traits::metatable(), std::forward(arg), std::forward(args)...); + } + + static int push(lua_State* L) { + return push_keyed(L, usertype_traits::metatable()); + } + template - static int push(lua_State* L, Args&&... args) { - return push_keyed(L, usertype_traits::metatable(), std::forward(args)...); + static int push(lua_State* L, detail::with_function_tag, Args&&... args) { + return push_fx(L, std::forward(args)...); } }; template - struct pusher> { + struct unqualified_pusher> { typedef meta::unqualified_t U; template @@ -124,13 +133,19 @@ namespace sol { return push_fx(L, fx, obj); } - static int push(lua_State* L, T* obj) { - return push_keyed(L, usertype_traits::metatable(), obj); + template , detail::with_function_tag>>> + static int push(lua_State* L, Arg&& arg, Args&&... args) { + return push_keyed(L, usertype_traits::metatable(), std::forward(arg), std::forward(args)...); + } + + template + static int push(lua_State* L, detail::with_function_tag, Args&&... args) { + return push_fx(L, std::forward(args)...); } }; template <> - struct pusher { + struct unqualified_pusher { template static int push(lua_State* L, T&& obj) { return stack::push(L, detail::ptr(obj)); @@ -138,25 +153,25 @@ namespace sol { }; template - struct pusher { + struct unqualified_pusher { template static int push(lua_State* L, Args&&... args) { - return pusher>{}.push(L, std::forward(args)...); + return stack::push>(L, std::forward(args)...); } }; template - struct pusher>, std::is_function>, is_lua_reference>>::value>> { template static int push(lua_State* L, Args&&... args) { - return pusher>{}.push(L, std::forward(args)...); + return stack::push>(L, std::forward(args)...); } }; template - struct pusher::value>> { + struct unqualified_pusher::value>> { typedef unique_usertype_traits u_traits; typedef typename u_traits::type P; typedef typename u_traits::actual_type Real; @@ -202,14 +217,14 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const std::reference_wrapper& t) { return stack::push(L, std::addressof(detail::deref(t.get()))); } }; template - struct pusher::value>> { + struct unqualified_pusher::value>> { static int push(lua_State* L, const T& value) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_floating); @@ -220,7 +235,7 @@ namespace sol { }; template - struct pusher::value>> { + struct unqualified_pusher::value>> { static int push(lua_State* L, const T& value) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_integral); @@ -259,7 +274,7 @@ namespace sol { }; template - struct pusher::value>> { + struct unqualified_pusher::value>> { static int push(lua_State* L, const T& value) { if (std::is_same>::value) { return stack::push(L, static_cast(value)); @@ -269,7 +284,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const T& tablecont) { typedef meta::has_key_value_pair>> has_kvp; return push(has_kvp(), std::false_type(), L, tablecont); @@ -346,23 +361,23 @@ namespace sol { }; template - struct pusher, std::enable_if_t>>::value>> { + struct unqualified_pusher, std::enable_if_t>>::value>> { static int push(lua_State* L, const T& tablecont) { return stack::push>(L, tablecont); } }; template - struct pusher, std::enable_if_t>>::value>> { + struct unqualified_pusher, std::enable_if_t>>::value>> { static int push(lua_State* L, const T& v) { return stack::push(L, v); } }; template - struct pusher, std::enable_if_t>>::value>> { + struct unqualified_pusher, std::enable_if_t>>::value>> { static int push(lua_State* L, const T& tablecont) { - pusher> p{}; + unqualified_pusher> p{}; // silence annoying VC++ warning (void)p; return p.push(std::true_type(), L, tablecont); @@ -370,9 +385,9 @@ namespace sol { }; template - struct pusher, std::enable_if_t>>::value>> { + struct unqualified_pusher, std::enable_if_t>>::value>> { static int push(lua_State* L, const T& tablecont) { - pusher> p{}; + unqualified_pusher> p{}; // silence annoying VC++ warning (void)p; return p.push(L, tablecont); @@ -380,9 +395,9 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const std::initializer_list& il) { - pusher>> p{}; + unqualified_pusher>> p{}; // silence annoying VC++ warning (void)p; return p.push(L, il); @@ -390,7 +405,7 @@ namespace sol { }; template - struct pusher::value>> { + struct unqualified_pusher::value>> { static int push(lua_State* L, const T& ref) { return ref.push(L); } @@ -401,7 +416,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, bool b) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -412,7 +427,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, lua_nil_t) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -423,14 +438,14 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State*, stack_count st) { return st.count; } }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, metatable_t) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -441,7 +456,7 @@ namespace sol { }; template <> - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, lua_CFunction func, int n = 0) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -452,7 +467,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, lua_CFunction func, int n = 0) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -464,7 +479,7 @@ namespace sol { #if defined(SOL_NOEXCEPT_FUNCTION_TYPE) && SOL_NOEXCEPT_FUNCTION_TYPE template <> - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, detail::lua_CFunction_noexcept func, int n = 0) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -475,7 +490,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, detail::lua_CFunction_noexcept func, int n = 0) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -487,7 +502,7 @@ namespace sol { #endif // noexcept function type template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, c_closure cc) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -498,7 +513,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { template static int push(std::index_sequence, lua_State* L, T&& c) { using f_tuple = decltype(std::forward(c).upvalues); @@ -513,7 +528,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, void* userdata) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -524,7 +539,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const void* userdata) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -535,7 +550,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, lightuserdata_value userdata) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -546,7 +561,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, light l) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -557,7 +572,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { template static int push_with(lua_State* L, Key&& name, Args&&... args) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK @@ -622,7 +637,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, userdata_value data) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata); @@ -634,7 +649,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push_sized(lua_State* L, const char* str, std::size_t len) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_string); @@ -659,34 +674,34 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push_sized(lua_State* L, const char* str, std::size_t len) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push_sized(L, str, len); } static int push(lua_State* L, const char* str) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str); } static int push(lua_State* L, const char* strb, const char* stre) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, strb, stre); } static int push(lua_State* L, const char* str, std::size_t len) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str, len); } }; template - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const char (&str)[N]) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_string); @@ -705,7 +720,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, char c) { const char str[2] = { c, '\0' }; return stack::push(L, str, 1); @@ -713,7 +728,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const std::basic_string& str) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_string); @@ -732,7 +747,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const basic_string_view& sv) { return stack::push(L, sv.data(), sv.length()); } @@ -743,7 +758,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, meta_function m) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_meta_function_name); @@ -755,7 +770,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, absolute_index ai) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -766,7 +781,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, raw_index ri) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -777,7 +792,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, ref_index ri) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -788,7 +803,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const wchar_t* wstr) { return push(L, wstr, std::char_traits::length(wstr)); } @@ -810,28 +825,28 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const wchar_t* str) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str); } static int push(lua_State* L, const wchar_t* strb, const wchar_t* stre) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, strb, stre); } static int push(lua_State* L, const wchar_t* str, std::size_t len) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str, len); } }; template <> - struct pusher { + struct unqualified_pusher { static int convert_into(lua_State* L, char* start, std::size_t, const char16_t* strb, const char16_t* stre) { char* target = start; char32_t cp = 0; @@ -888,28 +903,28 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const char16_t* str) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str); } static int push(lua_State* L, const char16_t* strb, const char16_t* stre) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, strb, stre); } static int push(lua_State* L, const char16_t* str, std::size_t len) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str, len); } }; template <> - struct pusher { + struct unqualified_pusher { static int convert_into(lua_State* L, char* start, std::size_t, const char32_t* strb, const char32_t* stre) { char* target = start; char32_t cp = 0; @@ -965,28 +980,28 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const char32_t* str) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str); } static int push(lua_State* L, const char32_t* strb, const char32_t* stre) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, strb, stre); } static int push(lua_State* L, const char32_t* str, std::size_t len) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str, len); } }; template - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const wchar_t (&str)[N]) { return push(L, str, std::char_traits::length(str)); } @@ -997,7 +1012,7 @@ namespace sol { }; template - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const char16_t (&str)[N]) { return push(L, str, std::char_traits::length(str)); } @@ -1008,7 +1023,7 @@ namespace sol { }; template - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const char32_t (&str)[N]) { return push(L, str, std::char_traits::length(str)); } @@ -1019,7 +1034,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, wchar_t c) { const wchar_t str[2] = { c, '\0' }; return stack::push(L, &str[0], 1); @@ -1027,7 +1042,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, char16_t c) { const char16_t str[2] = { c, '\0' }; return stack::push(L, &str[0], 1); @@ -1035,7 +1050,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, char32_t c) { const char32_t str[2] = { c, '\0' }; return stack::push(L, &str[0], 1); @@ -1043,7 +1058,7 @@ namespace sol { }; template - struct pusher, std::enable_if_t::value>> { + struct unqualified_pusher, std::enable_if_t::value>> { static int push(lua_State* L, const std::basic_string& wstr) { return push(L, wstr, wstr.size()); } @@ -1054,7 +1069,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { template static int push(std::index_sequence, lua_State* L, T&& t) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK @@ -1072,7 +1087,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { template static int push(lua_State* L, T&& t) { int pushcount = stack::push(L, std::get<0>(std::forward(t))); @@ -1082,7 +1097,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { template static int push(lua_State* L, T&& t) { if (t == nullopt) { @@ -1093,35 +1108,35 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, nullopt_t) { return stack::push(L, lua_nil); } }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, std::nullptr_t) { return stack::push(L, lua_nil); } }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State*, const this_state&) { return 0; } }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State*, const this_main_state&) { return 0; } }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const new_table& nt) { lua_createtable(L, nt.sequence_hint, nt.map_hint); return 1; @@ -1130,7 +1145,7 @@ namespace sol { #if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES template - struct pusher> { + struct unqualified_pusher> { template static int push(lua_State* L, T&& t) { if (t == std::nullopt) { @@ -1158,7 +1173,7 @@ namespace sol { } // namespace stack_detail template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const std::variant& v) { return std::visit(stack_detail::push_function(L), v); } diff --git a/include/sol/thread.hpp b/include/sol/thread.hpp index 78176077..e1704b03 100644 --- a/include/sol/thread.hpp +++ b/include/sol/thread.hpp @@ -49,7 +49,7 @@ namespace sol { namespace stack { template <> - struct pusher { + struct unqualified_pusher { int push(lua_State*, lua_thread_state lts) { lua_pushthread(lts.L); return 1; @@ -66,7 +66,7 @@ namespace sol { }; template <> - struct check_getter { + struct unqualified_check_getter { template optional get(lua_State* L, int index, Handler&& handler, record& tracking) { lua_thread_state lts( lua_tothread(L, index) ); diff --git a/include/sol/unsafe_function_result.hpp b/include/sol/unsafe_function_result.hpp index 2e0f560c..5c74106e 100644 --- a/include/sol/unsafe_function_result.hpp +++ b/include/sol/unsafe_function_result.hpp @@ -159,7 +159,7 @@ namespace sol { namespace stack { template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const unsafe_function_result& fr) { int p = 0; for (int i = 0; i < fr.return_count(); ++i) { diff --git a/include/sol/usertype_container.hpp b/include/sol/usertype_container.hpp index 9bd7dcb4..ea87a611 100644 --- a/include/sol/usertype_container.hpp +++ b/include/sol/usertype_container.hpp @@ -372,22 +372,22 @@ namespace sol { } // namespace stack_detail template - struct pusher> { + struct unqualified_pusher> { typedef meta::unqualified_t C; static int push_lvalue(std::true_type, lua_State* L, const C& cont) { stack_detail::metatable_setup fx(L); - return pusher>{}.push_fx(L, fx, detail::ptr(cont)); + return stack::push>(L, detail::with_function_tag(), fx, detail::ptr(cont)); } static int push_lvalue(std::false_type, lua_State* L, const C& cont) { stack_detail::metatable_setup fx(L); - return pusher>{}.push_fx(L, fx, cont); + return stack::push>(L, detail::with_function_tag(), fx, cont); } static int push_rvalue(std::true_type, lua_State* L, C&& cont) { stack_detail::metatable_setup fx(L); - return pusher>{}.push_fx(L, fx, std::move(cont)); + return stack::push>(L, detail::with_function_tag(), fx, std::move(cont)); } static int push_rvalue(std::false_type, lua_State* L, const C& cont) { @@ -404,37 +404,37 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { typedef std::add_pointer_t>> C; static int push(lua_State* L, T* cont) { stack_detail::metatable_setup fx(L); - return pusher>{}.push_fx(L, fx, cont); + return stack::push>(L, detail::with_function_tag(), fx, cont); } }; template - struct pusher>, meta::neg>>>::value>> { + struct unqualified_pusher>, meta::neg>>>::value>> { typedef meta::unqualified_t C; static int push(lua_State* L, const T& cont) { stack_detail::metatable_setup fx(L); - return pusher>{}.push_fx(L, fx, cont); + return stack::push>(L, detail::with_function_tag(), fx, cont); } static int push(lua_State* L, T&& cont) { stack_detail::metatable_setup fx(L); - return pusher>{}.push_fx(L, fx, std::move(cont)); + return stack::push>(L, detail::with_function_tag(), fx, std::move(cont)); } }; template - struct pusher>, meta::neg>>>::value>> { + struct unqualified_pusher>, meta::neg>>>::value>> { typedef std::add_pointer_t>> C; static int push(lua_State* L, T* cont) { stack_detail::metatable_setup fx(L); - return pusher>{}.push_fx(L, fx, cont); + return stack::push>(L, detail::with_function_tag(), fx, cont); } }; diff --git a/include/sol/variadic_args.hpp b/include/sol/variadic_args.hpp index e6c491fb..10b7cb27 100644 --- a/include/sol/variadic_args.hpp +++ b/include/sol/variadic_args.hpp @@ -173,7 +173,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const variadic_args& ref) { return ref.push(L); } diff --git a/include/sol/variadic_results.hpp b/include/sol/variadic_results.hpp index 61366a37..38c6dbc4 100644 --- a/include/sol/variadic_results.hpp +++ b/include/sol/variadic_results.hpp @@ -37,7 +37,7 @@ namespace sol { namespace stack { template <> - struct pusher { + struct unqualified_pusher { int push(lua_State* L, const variadic_results& e) { int p = 0; for (const auto& i : e) { diff --git a/single/include/sol/forward.hpp b/single/include/sol/forward.hpp index 1ec77882..9a8355e1 100644 --- a/single/include/sol/forward.hpp +++ b/single/include/sol/forward.hpp @@ -20,8 +20,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // This file was generated with a script. -// Generated 2018-12-21 06:03:11.681784 UTC -// This header was generated with sol v2.20.6 (revision c35c66b) +// Generated 2018-12-22 20:32:42.897539 UTC +// This header was generated with sol v2.20.6 (revision 88cafb2) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP @@ -414,6 +414,10 @@ namespace sol { template bool weak_derive::value = false; + namespace stack { + struct record; + } + } // namespace sol #define SOL_BASE_CLASSES(T, ...) \ diff --git a/single/include/sol/sol.hpp b/single/include/sol/sol.hpp index 85151e88..c816d83a 100644 --- a/single/include/sol/sol.hpp +++ b/single/include/sol/sol.hpp @@ -20,8 +20,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // This file was generated with a script. -// Generated 2018-12-21 06:03:11.212386 UTC -// This header was generated with sol v2.20.6 (revision c35c66b) +// Generated 2018-12-22 20:32:28.534178 UTC +// This header was generated with sol v2.20.6 (revision 88cafb2) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -447,6 +447,10 @@ namespace sol { template bool weak_derive::value = false; + namespace stack { + struct record; + } + } // namespace sol #define SOL_BASE_CLASSES(T, ...) \ @@ -506,6 +510,12 @@ namespace sol { #endif // sol luajit #endif // luajit +#if SOL_LUAJIT && SOL_LUAJIT_VERSION >= 20100 +#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) && (!defined(SOL_EXCEPTIONS_ALWAYS_UNSAFE) && !(SOL_EXCEPTIONS_ALWAYS_UNSAFE)) +#define SOL_EXCEPTIONS_SAFE_PROPAGATION 1 +#endif // Do not catch (...) clauses +#endif // LuaJIT beta 02.01.00 have better exception handling on all platforms since beta3 + #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 502 #define SOL_LUA_VERSION LUA_VERSION_NUM #elif defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501 @@ -7426,6 +7436,7 @@ namespace sol { namespace sol { namespace detail { + struct with_function_tag {}; struct as_reference_tag {}; template struct as_pointer_tag {}; @@ -7948,7 +7959,7 @@ namespace sol { template struct popper; template - struct pusher; + struct unqualified_pusher; template ::value, typename = void> struct unqualified_checker; template ::value, typename = void> @@ -7956,7 +7967,7 @@ namespace sol { template struct userdata_checker; template - struct check_getter; + struct unqualified_check_getter; template struct qualified_check_getter; @@ -7991,7 +8002,8 @@ namespace sol { struct is_adl_sol_lua_get { private: template - static meta::sfinae_yes_t test(decltype(sol_lua_get(types(), static_cast(nullptr), -1, std::declval()))*); + static meta::sfinae_yes_t test( + std::remove_reference_t(), static_cast(nullptr), -1, std::declval()))>*); template static meta::sfinae_no_t test(...); @@ -8003,8 +8015,8 @@ namespace sol { struct is_adl_sol_lua_check { private: template - static meta::sfinae_yes_t test( - decltype(sol_lua_check(types(), static_cast(nullptr), -1, no_panic, std::declval()))*); + static meta::sfinae_yes_t test(std::remove_reference_t(), static_cast(nullptr), -1, no_panic, std::declval()))>*); template static meta::sfinae_no_t test(...); @@ -8016,8 +8028,8 @@ namespace sol { struct is_adl_sol_lua_check_get { private: template - static meta::sfinae_yes_t test( - decltype(sol_lua_check_get(types(), static_cast(nullptr), -1, no_panic, std::declval()))*); + static meta::sfinae_yes_t test(std::remove_reference_t(), static_cast(nullptr), -1, no_panic, std::declval()))>*); template static meta::sfinae_no_t test(...); @@ -8029,7 +8041,7 @@ namespace sol { struct is_adl_sol_lua_push { private: template - static meta::sfinae_yes_t test(decltype(sol_lua_push(static_cast(nullptr), std::declval()...))*); + static meta::sfinae_yes_t test(std::remove_reference_t(nullptr), std::declval()...))>*); template static meta::sfinae_no_t test(...); @@ -8041,7 +8053,8 @@ namespace sol { struct is_adl_sol_lua_push_exact { private: template - static meta::sfinae_yes_t test(decltype(sol_lua_push(types(), static_cast(nullptr), std::declval()...))*); + static meta::sfinae_yes_t test( + std::remove_reference_t(), static_cast(nullptr), std::declval()...))>*); template static meta::sfinae_no_t test(...); @@ -8189,7 +8202,7 @@ namespace sol { return sol_lua_push(L, std::forward(t), std::forward(args)...); } else { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, std::forward(t), std::forward(args)...); } @@ -8209,7 +8222,7 @@ namespace sol { return sol_lua_push(L, std::forward(arg), std::forward(args)...); } else { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, std::forward(arg), std::forward(args)...); } @@ -8351,7 +8364,7 @@ namespace sol { return sol_lua_check_get(types(), L, index, std::forward(handler), tracking); } else { - check_getter cg{}; + unqualified_check_getter cg{}; (void)cg; return cg.get(L, index, std::forward(handler), tracking); } @@ -8754,8 +8767,7 @@ namespace sol { #endif // SOL_STD_VARIANT #endif // SOL_CXX17_FEATURES -namespace sol { -namespace stack { +namespace sol { namespace stack { namespace stack_detail { template inline bool check_metatable(lua_State* L, int index = -2) { @@ -8811,7 +8823,12 @@ namespace stack { }; template - struct qualified_checker : unqualified_checker, lua_type_of>::value, C> {}; + struct qualified_checker { + template + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + return stack::unqualified_check(L, index, std::forward(handler), tracking); + } + }; template struct unqualified_checker::value>> { @@ -9175,7 +9192,8 @@ namespace stack { handler(L, index, type::userdata, indextype, "value is not a valid userdata"); return false; } - if (meta::any, std::is_same, std::is_same, std::is_same>::value) + if (meta::any, std::is_same, std::is_same, std::is_same>:: + value) return true; if (lua_getmetatable(L, index) == 0) { return true; @@ -9384,8 +9402,7 @@ namespace stack { #endif // SOL_STD_VARIANT #endif // SOL_CXX17_FEATURES -} -} // namespace sol::stack +}} // namespace sol::stack // end of sol/stack_check_unqualified.hpp @@ -10808,7 +10825,7 @@ namespace stack { namespace sol { namespace stack { template - struct check_getter { + struct unqualified_check_getter { typedef decltype(stack_detail::unchecked_unqualified_get(nullptr, -1, std::declval())) R; template @@ -10822,7 +10839,7 @@ namespace stack { }; template - struct check_getter::value>> { + struct unqualified_check_getter::value>> { template static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { // actually check if it's none here, otherwise @@ -10839,7 +10856,7 @@ namespace stack { }; template - struct check_getter::value && lua_type_of::value == type::number>> { + struct unqualified_check_getter::value && lua_type_of::value == type::number>> { template static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { #if SOL_LUA_VERSION >= 503 @@ -10870,7 +10887,7 @@ namespace stack { }; template - struct check_getter::value && !meta::any_same::value>> { + struct unqualified_check_getter::value && !meta::any_same::value>> { template static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { int isnum = 0; @@ -10887,7 +10904,7 @@ namespace stack { }; template - struct check_getter::value>> { + struct unqualified_check_getter::value>> { template static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { int isnum = 0; @@ -10924,7 +10941,7 @@ namespace stack { #if defined(SOL_STD_VARIANT) && SOL_STD_VARIANT template - struct check_getter> { + struct unqualified_check_getter> { typedef std::variant V; typedef std::variant_size V_size; typedef std::integral_constant V_is_empty; @@ -10971,17 +10988,59 @@ namespace stack { // beginning of sol/stack_check_get_qualified.hpp -namespace sol { -namespace stack { +namespace sol { namespace stack { template struct qualified_check_getter { + typedef decltype(stack_detail::unchecked_get(nullptr, -1, std::declval())) R; + template - static decltype(auto) get(lua_State* L, int index, Handler&& handler, record& tracking) { - return stack::unqualified_check_get(L, index, std::forward(handler), tracking); + static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { + if (!check(L, index, std::forward(handler))) { + tracking.use(static_cast(!lua_isnone(L, index))); + return nullopt; + } + return stack_detail::unchecked_get(L, index, tracking); } }; -} -} // namespace sol::stack + + template + struct qualified_check_getter::value>> { + template + static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { + // actually check if it's none here, otherwise + // we'll have a none object inside an optional! + bool success = lua_isnoneornil(L, index) == 0 && stack::check(L, index, no_panic); + if (!success) { + // expected type, actual type + tracking.use(static_cast(success)); + handler(L, index, type::poly, type_of(L, index), ""); + return nullopt; + } + return stack_detail::unchecked_get(L, index, tracking); + } + }; + + template + struct qualified_getter> { + static decltype(auto) get(lua_State* L, int index, record& tracking) { + return check_get(L, index, no_panic, tracking); + } + }; + +#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES + template + struct qualified_getter> { + static std::optional get(lua_State* L, int index, record& tracking) { + if (!check(L, index, no_panic)) { + tracking.use(static_cast(!lua_isnone(L, index))); + return std::nullopt; + } + return stack_detail::unchecked_get(L, index, tracking); + } + }; +#endif // C++17 features + +}} // namespace sol::stack // end of sol/stack_check_get_qualified.hpp @@ -11022,7 +11081,7 @@ namespace sol { } template - struct pusher> { + struct unqualified_pusher> { template static int push_fx(lua_State* L, F&& f, Args&&... args) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK @@ -11046,14 +11105,23 @@ namespace sol { return push_fx(L, fx, std::forward(args)...); } + template , detail::with_function_tag>>> + static int push(lua_State* L, Arg&& arg, Args&&... args) { + return push_keyed(L, usertype_traits::metatable(), std::forward(arg), std::forward(args)...); + } + + static int push(lua_State* L) { + return push_keyed(L, usertype_traits::metatable()); + } + template - static int push(lua_State* L, Args&&... args) { - return push_keyed(L, usertype_traits::metatable(), std::forward(args)...); + static int push(lua_State* L, detail::with_function_tag, Args&&... args) { + return push_fx(L, std::forward(args)...); } }; template - struct pusher> { + struct unqualified_pusher> { typedef meta::unqualified_t U; template @@ -11075,13 +11143,19 @@ namespace sol { return push_fx(L, fx, obj); } - static int push(lua_State* L, T* obj) { - return push_keyed(L, usertype_traits::metatable(), obj); + template , detail::with_function_tag>>> + static int push(lua_State* L, Arg&& arg, Args&&... args) { + return push_keyed(L, usertype_traits::metatable(), std::forward(arg), std::forward(args)...); + } + + template + static int push(lua_State* L, detail::with_function_tag, Args&&... args) { + return push_fx(L, std::forward(args)...); } }; template <> - struct pusher { + struct unqualified_pusher { template static int push(lua_State* L, T&& obj) { return stack::push(L, detail::ptr(obj)); @@ -11089,25 +11163,25 @@ namespace sol { }; template - struct pusher { + struct unqualified_pusher { template static int push(lua_State* L, Args&&... args) { - return pusher>{}.push(L, std::forward(args)...); + return stack::push>(L, std::forward(args)...); } }; template - struct pusher>, std::is_function>, is_lua_reference>>::value>> { template static int push(lua_State* L, Args&&... args) { - return pusher>{}.push(L, std::forward(args)...); + return stack::push>(L, std::forward(args)...); } }; template - struct pusher::value>> { + struct unqualified_pusher::value>> { typedef unique_usertype_traits u_traits; typedef typename u_traits::type P; typedef typename u_traits::actual_type Real; @@ -11153,14 +11227,14 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const std::reference_wrapper& t) { return stack::push(L, std::addressof(detail::deref(t.get()))); } }; template - struct pusher::value>> { + struct unqualified_pusher::value>> { static int push(lua_State* L, const T& value) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_floating); @@ -11171,7 +11245,7 @@ namespace sol { }; template - struct pusher::value>> { + struct unqualified_pusher::value>> { static int push(lua_State* L, const T& value) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_integral); @@ -11210,7 +11284,7 @@ namespace sol { }; template - struct pusher::value>> { + struct unqualified_pusher::value>> { static int push(lua_State* L, const T& value) { if (std::is_same>::value) { return stack::push(L, static_cast(value)); @@ -11220,7 +11294,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const T& tablecont) { typedef meta::has_key_value_pair>> has_kvp; return push(has_kvp(), std::false_type(), L, tablecont); @@ -11297,23 +11371,23 @@ namespace sol { }; template - struct pusher, std::enable_if_t>>::value>> { + struct unqualified_pusher, std::enable_if_t>>::value>> { static int push(lua_State* L, const T& tablecont) { return stack::push>(L, tablecont); } }; template - struct pusher, std::enable_if_t>>::value>> { + struct unqualified_pusher, std::enable_if_t>>::value>> { static int push(lua_State* L, const T& v) { return stack::push(L, v); } }; template - struct pusher, std::enable_if_t>>::value>> { + struct unqualified_pusher, std::enable_if_t>>::value>> { static int push(lua_State* L, const T& tablecont) { - pusher> p{}; + unqualified_pusher> p{}; // silence annoying VC++ warning (void)p; return p.push(std::true_type(), L, tablecont); @@ -11321,9 +11395,9 @@ namespace sol { }; template - struct pusher, std::enable_if_t>>::value>> { + struct unqualified_pusher, std::enable_if_t>>::value>> { static int push(lua_State* L, const T& tablecont) { - pusher> p{}; + unqualified_pusher> p{}; // silence annoying VC++ warning (void)p; return p.push(L, tablecont); @@ -11331,9 +11405,9 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const std::initializer_list& il) { - pusher>> p{}; + unqualified_pusher>> p{}; // silence annoying VC++ warning (void)p; return p.push(L, il); @@ -11341,7 +11415,7 @@ namespace sol { }; template - struct pusher::value>> { + struct unqualified_pusher::value>> { static int push(lua_State* L, const T& ref) { return ref.push(L); } @@ -11352,7 +11426,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, bool b) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -11363,7 +11437,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, lua_nil_t) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -11374,14 +11448,14 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State*, stack_count st) { return st.count; } }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, metatable_t) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -11392,7 +11466,7 @@ namespace sol { }; template <> - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, lua_CFunction func, int n = 0) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -11403,7 +11477,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, lua_CFunction func, int n = 0) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -11415,7 +11489,7 @@ namespace sol { #if defined(SOL_NOEXCEPT_FUNCTION_TYPE) && SOL_NOEXCEPT_FUNCTION_TYPE template <> - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, detail::lua_CFunction_noexcept func, int n = 0) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -11426,7 +11500,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, detail::lua_CFunction_noexcept func, int n = 0) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -11438,7 +11512,7 @@ namespace sol { #endif // noexcept function type template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, c_closure cc) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -11449,7 +11523,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { template static int push(std::index_sequence, lua_State* L, T&& c) { using f_tuple = decltype(std::forward(c).upvalues); @@ -11464,7 +11538,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, void* userdata) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -11475,7 +11549,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const void* userdata) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -11486,7 +11560,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, lightuserdata_value userdata) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -11497,7 +11571,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, light l) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -11508,7 +11582,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { template static int push_with(lua_State* L, Key&& name, Args&&... args) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK @@ -11573,7 +11647,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, userdata_value data) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata); @@ -11585,7 +11659,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push_sized(lua_State* L, const char* str, std::size_t len) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_string); @@ -11610,34 +11684,34 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push_sized(lua_State* L, const char* str, std::size_t len) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push_sized(L, str, len); } static int push(lua_State* L, const char* str) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str); } static int push(lua_State* L, const char* strb, const char* stre) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, strb, stre); } static int push(lua_State* L, const char* str, std::size_t len) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str, len); } }; template - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const char (&str)[N]) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_string); @@ -11656,7 +11730,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, char c) { const char str[2] = { c, '\0' }; return stack::push(L, str, 1); @@ -11664,7 +11738,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const std::basic_string& str) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_string); @@ -11683,7 +11757,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const basic_string_view& sv) { return stack::push(L, sv.data(), sv.length()); } @@ -11694,7 +11768,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, meta_function m) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_meta_function_name); @@ -11706,7 +11780,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, absolute_index ai) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -11717,7 +11791,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, raw_index ri) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -11728,7 +11802,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, ref_index ri) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); @@ -11739,7 +11813,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const wchar_t* wstr) { return push(L, wstr, std::char_traits::length(wstr)); } @@ -11761,28 +11835,28 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const wchar_t* str) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str); } static int push(lua_State* L, const wchar_t* strb, const wchar_t* stre) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, strb, stre); } static int push(lua_State* L, const wchar_t* str, std::size_t len) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str, len); } }; template <> - struct pusher { + struct unqualified_pusher { static int convert_into(lua_State* L, char* start, std::size_t, const char16_t* strb, const char16_t* stre) { char* target = start; char32_t cp = 0; @@ -11839,28 +11913,28 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const char16_t* str) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str); } static int push(lua_State* L, const char16_t* strb, const char16_t* stre) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, strb, stre); } static int push(lua_State* L, const char16_t* str, std::size_t len) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str, len); } }; template <> - struct pusher { + struct unqualified_pusher { static int convert_into(lua_State* L, char* start, std::size_t, const char32_t* strb, const char32_t* stre) { char* target = start; char32_t cp = 0; @@ -11916,28 +11990,28 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const char32_t* str) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str); } static int push(lua_State* L, const char32_t* strb, const char32_t* stre) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, strb, stre); } static int push(lua_State* L, const char32_t* str, std::size_t len) { - pusher p{}; + unqualified_pusher p{}; (void)p; return p.push(L, str, len); } }; template - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const wchar_t (&str)[N]) { return push(L, str, std::char_traits::length(str)); } @@ -11948,7 +12022,7 @@ namespace sol { }; template - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const char16_t (&str)[N]) { return push(L, str, std::char_traits::length(str)); } @@ -11959,7 +12033,7 @@ namespace sol { }; template - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const char32_t (&str)[N]) { return push(L, str, std::char_traits::length(str)); } @@ -11970,7 +12044,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, wchar_t c) { const wchar_t str[2] = { c, '\0' }; return stack::push(L, &str[0], 1); @@ -11978,7 +12052,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, char16_t c) { const char16_t str[2] = { c, '\0' }; return stack::push(L, &str[0], 1); @@ -11986,7 +12060,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, char32_t c) { const char32_t str[2] = { c, '\0' }; return stack::push(L, &str[0], 1); @@ -11994,7 +12068,7 @@ namespace sol { }; template - struct pusher, std::enable_if_t::value>> { + struct unqualified_pusher, std::enable_if_t::value>> { static int push(lua_State* L, const std::basic_string& wstr) { return push(L, wstr, wstr.size()); } @@ -12005,7 +12079,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { template static int push(std::index_sequence, lua_State* L, T&& t) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK @@ -12023,7 +12097,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { template static int push(lua_State* L, T&& t) { int pushcount = stack::push(L, std::get<0>(std::forward(t))); @@ -12033,7 +12107,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { template static int push(lua_State* L, T&& t) { if (t == nullopt) { @@ -12044,35 +12118,35 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, nullopt_t) { return stack::push(L, lua_nil); } }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, std::nullptr_t) { return stack::push(L, lua_nil); } }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State*, const this_state&) { return 0; } }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State*, const this_main_state&) { return 0; } }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const new_table& nt) { lua_createtable(L, nt.sequence_hint, nt.map_hint); return 1; @@ -12081,7 +12155,7 @@ namespace sol { #if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES template - struct pusher> { + struct unqualified_pusher> { template static int push(lua_State* L, T&& t) { if (t == std::nullopt) { @@ -12109,7 +12183,7 @@ namespace sol { } // namespace stack_detail template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const std::variant& v) { return std::visit(stack_detail::push_function(L), v); } @@ -12670,7 +12744,7 @@ namespace sol { } inline void luajit_exception_handler(lua_State* L, int (*handler)(lua_State*, lua_CFunction) = detail::c_trampoline) { -#if defined(SOL_LUAJIT) && !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) +#if defined(SOL_LUAJIT) && (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !(SOL_EXCEPTIONS_SAFE_PROPAGATION)) if (L == nullptr) { return; } @@ -13120,7 +13194,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State*, const stack_proxy_base& ref) { return ref.push(); } @@ -13159,7 +13233,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State*, const stack_proxy& ref) { return ref.push(); } @@ -13346,7 +13420,7 @@ namespace sol { namespace stack { template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const protected_function_result& pfr) { #if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK luaL_checkstack(L, static_cast(pfr.pop_count()), detail::not_enough_stack_space_generic); @@ -13493,7 +13567,7 @@ namespace sol { namespace stack { template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const unsafe_function_result& fr) { int p = 0; for (int i = 0; i < fr.return_count(); ++i) { @@ -15429,7 +15503,7 @@ namespace sol { namespace stack { template - struct pusher> { + struct unqualified_pusher> { template static void select_convertible(std::false_type, types, lua_State* L, Fx&& fx, Args&&... args) { typedef std::remove_pointer_t> clean_fx; @@ -15631,24 +15705,24 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { template static int push(lua_State* L, const yielding_t& f, Args&&... args) { - pusher> p{}; + unqualified_pusher> p{}; (void)p; return p.push(L, detail::yield_tag, f.func, std::forward(args)...); } template static int push(lua_State* L, yielding_t&& f, Args&&... args) { - pusher> p{}; + unqualified_pusher> p{}; (void)p; return p.push(L, detail::yield_tag, f.func, std::forward(args)...); } }; template - struct pusher> { + struct unqualified_pusher> { template static int push_func(std::index_sequence, lua_State* L, FP&& fp) { return stack::push(L, std::get(std::forward(fp).arguments)...); @@ -15664,28 +15738,28 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const std::function& fx) { - return pusher>{}.push(L, fx); + return unqualified_pusher>{}.push(L, fx); } static int push(lua_State* L, std::function&& fx) { - return pusher>{}.push(L, std::move(fx)); + return unqualified_pusher>{}.push(L, std::move(fx)); } }; template - struct pusher::value>> { + struct unqualified_pusher::value>> { template static int push(lua_State* L, F&& f, Args&&... args) { - pusher> p{}; + unqualified_pusher> p{}; (void)p; return p.push(L, std::forward(f), std::forward(args)...); } }; template - struct pusher>, meta::neg>, meta::neg>> + struct unqualified_pusher>, meta::neg>, meta::neg>> #if defined(SOL_NOEXCEPT_FUNCTION_TYPE) && SOL_NOEXCEPT_FUNCTION_TYPE , meta::neg>, meta::neg>> @@ -15693,29 +15767,29 @@ namespace sol { >::value>> { template static int push(lua_State* L, F&& f) { - return pusher>{}.push(L, std::forward(f)); + return unqualified_pusher>{}.push(L, std::forward(f)); } }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, overload_set&& set) { // TODO: yielding typedef function_detail::overloaded_function<0, Functions...> F; - pusher>{}.set_fx(L, std::move(set.functions)); + unqualified_pusher>{}.set_fx(L, std::move(set.functions)); return 1; } static int push(lua_State* L, const overload_set& set) { // TODO: yielding typedef function_detail::overloaded_function<0, Functions...> F; - pusher>{}.set_fx(L, set.functions); + unqualified_pusher>{}.set_fx(L, set.functions); return 1; } }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, protect_t&& pw) { lua_CFunction cf = call_detail::call_user, 2>; int upvalues = 0; @@ -15734,7 +15808,7 @@ namespace sol { }; template - struct pusher, std::enable_if_t::value && !std::is_void::value>> { + struct unqualified_pusher, std::enable_if_t::value && !std::is_void::value>> { static int push(lua_State* L, property_wrapper&& pw) { return stack::push(L, overload(std::move(pw.read), std::move(pw.write))); } @@ -15744,7 +15818,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, property_wrapper&& pw) { return stack::push(L, std::move(pw.read)); } @@ -15754,7 +15828,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, property_wrapper&& pw) { return stack::push(L, std::move(pw.write)); } @@ -15764,7 +15838,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, var_wrapper&& vw) { return stack::push(L, std::move(vw.value)); } @@ -15774,34 +15848,34 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const factory_wrapper& fw) { typedef function_detail::overloaded_function<0, Functions...> F; - pusher>{}.set_fx(L, fw.functions); + unqualified_pusher>{}.set_fx(L, fw.functions); return 1; } static int push(lua_State* L, factory_wrapper&& fw) { typedef function_detail::overloaded_function<0, Functions...> F; - pusher>{}.set_fx(L, std::move(fw.functions)); + unqualified_pusher>{}.set_fx(L, std::move(fw.functions)); return 1; } static int push(lua_State* L, const factory_wrapper& set, function_detail::call_indicator) { typedef function_detail::overloaded_function<1, Functions...> F; - pusher>{}.set_fx(L, set.functions); + unqualified_pusher>{}.set_fx(L, set.functions); return 1; } static int push(lua_State* L, factory_wrapper&& set, function_detail::call_indicator) { typedef function_detail::overloaded_function<1, Functions...> F; - pusher>{}.set_fx(L, std::move(set.functions)); + unqualified_pusher>{}.set_fx(L, std::move(set.functions)); return 1; } }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, no_construction) { lua_CFunction cf = &function_detail::no_construction_error; return stack::push(L, cf); @@ -15813,7 +15887,7 @@ namespace sol { }; template - struct pusher>> { + struct unqualified_pusher>> { static int push(lua_State* L, detail::tagged>) { lua_CFunction cf = call_detail::construct; return stack::push(L, cf); @@ -15826,7 +15900,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { typedef constructor_list cl_t; static int push(lua_State* L, cl_t cl) { typedef typename meta::bind_traits::return_type T; @@ -15835,7 +15909,7 @@ namespace sol { }; template - struct pusher>> { + struct unqualified_pusher>> { template static int push(lua_State* L, C&& c) { lua_CFunction cf = call_detail::call_user, 2>; @@ -15847,7 +15921,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { template static int push(lua_State* L, C&& c) { typedef typename meta::bind_traits::template arg_at<0> arg0; @@ -15857,7 +15931,7 @@ namespace sol { }; template - struct pusher>> { + struct unqualified_pusher>> { static int push(lua_State* L, destructor_wrapper) { lua_CFunction cf = detail::usertype_alloc_destruct; return stack::push(L, cf); @@ -15865,7 +15939,7 @@ namespace sol { }; template - struct pusher>> { + struct unqualified_pusher>> { static int push(lua_State* L, destructor_wrapper&& c) { lua_CFunction cf = call_detail::call_user, 2>; int upvalues = 0; @@ -15884,7 +15958,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, destructor_wrapper&& c) { lua_CFunction cf = call_detail::call_user, 2>; int upvalues = 0; @@ -15903,7 +15977,7 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { typedef filter_wrapper P; static int push(lua_State* L, const P& p) { @@ -16724,7 +16798,7 @@ namespace sol { namespace stack { template - struct pusher> { + struct unqualified_pusher> { static int push(lua_State* L, const proxy& p) { reference r = p; return r.push(L); @@ -18665,22 +18739,22 @@ namespace sol { } // namespace stack_detail template - struct pusher> { + struct unqualified_pusher> { typedef meta::unqualified_t C; static int push_lvalue(std::true_type, lua_State* L, const C& cont) { stack_detail::metatable_setup fx(L); - return pusher>{}.push_fx(L, fx, detail::ptr(cont)); + return stack::push>(L, detail::with_function_tag(), fx, detail::ptr(cont)); } static int push_lvalue(std::false_type, lua_State* L, const C& cont) { stack_detail::metatable_setup fx(L); - return pusher>{}.push_fx(L, fx, cont); + return stack::push>(L, detail::with_function_tag(), fx, cont); } static int push_rvalue(std::true_type, lua_State* L, C&& cont) { stack_detail::metatable_setup fx(L); - return pusher>{}.push_fx(L, fx, std::move(cont)); + return stack::push>(L, detail::with_function_tag(), fx, std::move(cont)); } static int push_rvalue(std::false_type, lua_State* L, const C& cont) { @@ -18697,37 +18771,37 @@ namespace sol { }; template - struct pusher> { + struct unqualified_pusher> { typedef std::add_pointer_t>> C; static int push(lua_State* L, T* cont) { stack_detail::metatable_setup fx(L); - return pusher>{}.push_fx(L, fx, cont); + return stack::push>(L, detail::with_function_tag(), fx, cont); } }; template - struct pusher>, meta::neg>>>::value>> { + struct unqualified_pusher>, meta::neg>>>::value>> { typedef meta::unqualified_t C; static int push(lua_State* L, const T& cont) { stack_detail::metatable_setup fx(L); - return pusher>{}.push_fx(L, fx, cont); + return stack::push>(L, detail::with_function_tag(), fx, cont); } static int push(lua_State* L, T&& cont) { stack_detail::metatable_setup fx(L); - return pusher>{}.push_fx(L, fx, std::move(cont)); + return stack::push>(L, detail::with_function_tag(), fx, std::move(cont)); } }; template - struct pusher>, meta::neg>>>::value>> { + struct unqualified_pusher>, meta::neg>>>::value>> { typedef std::add_pointer_t>> C; static int push(lua_State* L, T* cont) { stack_detail::metatable_setup fx(L); - return pusher>{}.push_fx(L, fx, cont); + return stack::push>(L, detail::with_function_tag(), fx, cont); } }; @@ -21896,7 +21970,7 @@ namespace sol { namespace stack { template <> - struct pusher { + struct unqualified_pusher { int push(lua_State*, lua_thread_state lts) { lua_pushthread(lts.L); return 1; @@ -21913,7 +21987,7 @@ namespace sol { }; template <> - struct check_getter { + struct unqualified_check_getter { template optional get(lua_State* L, int index, Handler&& handler, record& tracking) { lua_thread_state lts( lua_tothread(L, index) ); @@ -22420,7 +22494,7 @@ namespace sol { namespace stack { template - struct pusher> { + struct unqualified_pusher> { int push(lua_State* L, const as_args_t& e) { int p = 0; for (const auto& i : e.src) { @@ -22579,7 +22653,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const variadic_args& ref) { return ref.push(L); } @@ -22606,7 +22680,7 @@ namespace sol { namespace stack { template - struct pusher> { + struct unqualified_pusher> { int push(lua_State* L, const as_returns_t& e) { auto& src = detail::unwrap(e.src); int p = 0; @@ -22629,7 +22703,7 @@ namespace sol { namespace stack { template <> - struct pusher { + struct unqualified_pusher { int push(lua_State* L, const variadic_results& e) { int p = 0; for (const auto& i : e) { diff --git a/tests/runtime_tests/source/customizations.cpp b/tests/runtime_tests/source/customizations.cpp index ea750e31..fbcd0d3b 100644 --- a/tests/runtime_tests/source/customizations.cpp +++ b/tests/runtime_tests/source/customizations.cpp @@ -66,19 +66,11 @@ sol::optional sol_lua_check_get(sol::types type_tag, lua_State* int sol_lua_push(lua_State* L, const custom& c) { ++custom::push_calls; - // ensure there's enough space for 1 more thing on the stack - lua_checkstack(L, 1); - // tell Lua we've left something on - // the stack: return what comes from pushing an integer return sol::stack::push(L, c.bweh); } int sol_lua_push(sol::types, lua_State* L, const custom& c) { ++custom::exact_push_calls; - // ensure there's enough space for 1 more thing on the stack - lua_checkstack(L, 1); - // tell Lua we've left something on - // the stack: return what comes from pushing an integer return sol::stack::push(L, c.bweh); } @@ -118,13 +110,9 @@ bool sol_lua_check(sol::types, lua_State* L, int index, Handler&& int sol_lua_push(lua_State* L, const multi_custom& c) { ++multi_custom::push_calls; - // ensure there's enough space for 1 more thing on the stack - lua_checkstack(L, 3); int p = sol::stack::push(L, c.bweh); p += sol::stack::push(L, c.bwuh); p += sol::stack::push(L, c.blah); - // tell Lua we've left something on - // the stack: return what comes from pushing an integer return p; } @@ -136,12 +124,14 @@ struct super_custom { static int check_get_calls; static int push_calls; static int exact_push_calls; + static int pointer_push_calls; }; int super_custom::get_calls = 0; int super_custom::check_calls = 0; int super_custom::check_get_calls = 0; int super_custom::push_calls = 0; +int super_custom::pointer_push_calls = 0; int super_custom::exact_push_calls = 0; super_custom* sol_lua_get(sol::types, lua_State* L, int index, sol::stack::record& tracking) { @@ -169,6 +159,11 @@ bool sol_lua_check(sol::types, lua_State* L, int index, Handler&& return true; } +template +bool sol_lua_check(sol::types, lua_State* L, int index, Handler&& handler, sol::stack::record& tracking) { + return sol_lua_check(sol::types(), L, index, std::forward(handler), tracking); +} + int sol_lua_push(lua_State* L, const super_custom& c) { ++super_custom::push_calls; // ensure there's enough space for 1 more thing on the stack @@ -185,7 +180,7 @@ int sol_lua_push(lua_State* L, const super_custom& c) { } int sol_lua_push(lua_State* L, super_custom* c) { - ++super_custom::push_calls; + ++super_custom::pointer_push_calls; // ensure there's enough space for 1 more thing on the stack lua_checkstack(L, 1); // tell Lua we've left something on @@ -197,7 +192,8 @@ int sol_lua_push(lua_State* L, super_custom* c) { return 1; } -int sol_lua_push(lua_State* L, std::reference_wrapper c) { +int sol_lua_push(sol::types>, lua_State* L, std::reference_wrapper c) { + ++super_custom::exact_push_calls; return sol::stack::push(L, std::addressof(c.get())); } @@ -248,20 +244,26 @@ TEST_CASE("customization/adl", "using the ADL customization points in various si super_custom::check_calls = 0; super_custom::check_get_calls = 0; super_custom::push_calls = 0; + super_custom::pointer_push_calls = 0; super_custom::exact_push_calls = 0; super_custom meow_original{ 50 }; lua["meow"] = std::ref(meow_original); super_custom& meow = lua["meow"]; + super_custom* p_meow = lua["meow"]; + std::reference_wrapper ref_meow = lua["meow"]; super_custom meow_copy = lua["meow"]; REQUIRE(meow.bweh == 50); REQUIRE(&meow == &meow_original); + REQUIRE(p_meow == &meow_original); + REQUIRE(&ref_meow.get() == &meow_original); REQUIRE(meow_copy.bweh == 50); REQUIRE(super_custom::get_calls > 0); REQUIRE(super_custom::check_calls > 0); - REQUIRE(super_custom::push_calls > 0); REQUIRE(super_custom::check_get_calls == 0); - REQUIRE(super_custom::exact_push_calls == 0); + REQUIRE(super_custom::push_calls == 0); + REQUIRE(super_custom::pointer_push_calls > 0); + REQUIRE(super_custom::exact_push_calls > 0); } } diff --git a/tests/runtime_tests/source/customizations_private.cpp b/tests/runtime_tests/source/customizations_private.cpp index 1826b7af..d3c10907 100644 --- a/tests/runtime_tests/source/customizations_private.cpp +++ b/tests/runtime_tests/source/customizations_private.cpp @@ -37,6 +37,15 @@ struct number_shim { double num = 0; }; + +// HEY: +// Don't do this. +// The code below is for sol3 to specialize things, +// not for YOU to specialize things. +// If you customize things in this fashion, +// I will break your code sometime in the future when fixing things. +// Do. Not. Use the designated ADL customization points, or file +// a bug. namespace sol { template <> @@ -71,7 +80,7 @@ namespace sol { }; template <> - struct pusher { + struct unqualified_pusher { static int push(lua_State* L, const two_things& things) { int amount = stack::push(L, things.a); amount += stack::push(L, things.b); @@ -108,7 +117,7 @@ namespace sol { } // namespace stack } // namespace sol -TEST_CASE("customization/split struct", "using the newly documented customization points to handle different kinds of classes") { +TEST_CASE("customization/split struct", "using the old customization points to handle different kinds of classes") { sol::state lua; // Create a pass-through style of function @@ -132,7 +141,7 @@ TEST_CASE("customization/split struct", "using the newly documented customizatio REQUIRE(d == 36.5); } -TEST_CASE("customization/usertype", "using the newly documented customization points to handle different kinds of classes") { +TEST_CASE("customization/usertype", "using the old customization points to handle different kinds of classes") { sol::state lua; // Create a pass-through style of function