diff --git a/include/sol/stack_check_unqualified.hpp b/include/sol/stack_check_unqualified.hpp index f9ed6b11..02af4e69 100644 --- a/include/sol/stack_check_unqualified.hpp +++ b/include/sol/stack_check_unqualified.hpp @@ -31,8 +31,9 @@ #include #include #include -#ifdef SOL_CXX17_FEATURES -#ifdef SOL_STD_VARIANT +#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES +#include +#if defined(SOL_STD_VARIANT) && SOL_STD_VARIANT #include #endif // SOL_STD_VARIANT #endif // SOL_CXX17_FEATURES @@ -609,7 +610,26 @@ namespace stack { }; #if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES + + template + struct checker, type::poly, C> { + template + static bool check(lua_State* L, int index, Handler&&, record& tracking) { + type t = type_of(L, index); + if (t == type::none) { + tracking.use(0); + return true; + } + if (t == type::lua_nil) { + tracking.use(1); + return true; + } + return stack::check(L, index, no_panic, tracking); + } + }; + #if defined(SOL_STD_VARIANT) && SOL_STD_VARIANT + template struct checker, type::poly, C> { typedef std::variant V; @@ -640,7 +660,9 @@ namespace stack { return is_one(std::integral_constant(), L, index, std::forward(handler), tracking); } }; + #endif // SOL_STD_VARIANT + #endif // SOL_CXX17_FEATURES } } // namespace sol::stack diff --git a/include/sol/types.hpp b/include/sol/types.hpp index c5a73e81..4976241f 100644 --- a/include/sol/types.hpp +++ b/include/sol/types.hpp @@ -39,6 +39,7 @@ #include #if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES #include +#include #ifdef SOL_STD_VARIANT #include #endif @@ -981,6 +982,9 @@ namespace sol { template struct lua_type_of> : std::integral_constant {}; + template + struct lua_type_of> : std::integral_constant {}; + template <> struct lua_type_of : std::integral_constant {}; diff --git a/tests/test_utility.cpp b/tests/test_utility.cpp index 5b1bbad6..b60d17d8 100644 --- a/tests/test_utility.cpp +++ b/tests/test_utility.cpp @@ -36,7 +36,6 @@ std::mutex basic_init_require_mutex; void basic_initialization_and_lib_open() { - sol::state lua; try { lua.open_libraries(); @@ -149,6 +148,25 @@ TEST_CASE("utility/optional", "test that shit optional can be round-tripped") { REQUIRE_FALSE(result.valid()); }; } + SECTION("in classes") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + struct opt_c { + std::optional member; + }; + + auto uto = lua.new_usertype("opt_c", + "value", &opt_c::member); + + opt_c obj; + lua["obj"] = std::ref(obj); + + lua.safe_script("print(obj.value) obj.value = 20 print(obj.value)"); + REQUIRE(obj.member == 20); + lua.safe_script("print(obj.value) obj.value = nil print(obj.value)"); + REQUIRE(obj.member == std::nullopt); + } #else REQUIRE(true); #endif // C++17