diff --git a/sol/stack_check.hpp b/sol/stack_check.hpp index 8a798310..60bc9c7d 100644 --- a/sol/stack_check.hpp +++ b/sol/stack_check.hpp @@ -282,6 +282,14 @@ struct checker, type::poly, C> { return stack::check(L, index, handler) && stack::check(L, index + 1, handler); } }; + +template +struct checker, type::poly, C> { + template + static bool check(lua_State* L, int index, Handler&& handler) { + return stack::check(L, index, std::forward(handler)); + } +}; } // stack } // sol diff --git a/sol/stack_check_get.hpp b/sol/stack_check_get.hpp index efc93305..30cae43e 100644 --- a/sol/stack_check_get.hpp +++ b/sol/stack_check_get.hpp @@ -42,6 +42,14 @@ struct check_getter { } }; +template +struct check_getter> { + template + static decltype(auto) get(lua_State* L, int index, Handler&&) { + return check_get(L, index, no_panic); + } +}; + template struct check_getter::value && !std::is_same::value>> { template @@ -69,6 +77,13 @@ struct check_getter::value>> { return static_cast(value); } }; + +template +struct getter> { + static decltype(auto) get(lua_State* L, int index) { + return check_get(L, index); + } +}; } // stack } // sol diff --git a/sol/stack_core.hpp b/sol/stack_core.hpp index d4c580a2..e7a468eb 100644 --- a/sol/stack_core.hpp +++ b/sol/stack_core.hpp @@ -158,8 +158,10 @@ inline decltype(auto) check_get(lua_State* L, int index = -1) { return check_get(L, index, handler); } -template -inline decltype(auto) get(lua_State* L, int index = -1) { +namespace stack_detail { + +template +inline decltype(auto) tagged_get(types, lua_State* L, int index = -1) { #ifdef SOL_CHECK_ARGUMENTS auto op = check_get(L, index, type_panic); typedef typename meta::Unqualified::value_type U; @@ -169,6 +171,18 @@ inline decltype(auto) get(lua_State* L, int index = -1) { #endif } +template +inline decltype(auto) tagged_get(types>, lua_State* L, int index = -1) { + return stack_detail::unchecked_get>(L, index); +} + +} // stack_detail + +template +inline decltype(auto) get(lua_State* L, int index = -1) { + return stack_detail::tagged_get(types(), L, index); +} + template inline decltype(auto) pop(lua_State* L) { return popper>{}.pop(L); diff --git a/sol/types.hpp b/sol/types.hpp index 271fdf34..baef5dcb 100644 --- a/sol/types.hpp +++ b/sol/types.hpp @@ -24,6 +24,7 @@ #include "compatibility.hpp" #include "traits.hpp" +#include "optional.hpp" #include namespace sol { @@ -274,6 +275,9 @@ struct lua_type_of : std::integral_constant struct lua_type_of> : std::integral_constant{}; +template +struct lua_type_of> : std::integral_constant{}; + template struct lua_type_of : std::integral_constant {}; @@ -303,6 +307,9 @@ struct is_proxy_primitive : is_lua_primitive { }; template struct is_proxy_primitive> : std::true_type { }; +template +struct is_proxy_primitive> : std::true_type {}; + template struct is_proxy_primitive> : std::true_type { }; diff --git a/tests.cpp b/tests.cpp index 7155ed2e..8f95ffc5 100644 --- a/tests.cpp +++ b/tests.cpp @@ -673,6 +673,20 @@ TEST_CASE("tables/operator[]-valid", "Test if proxies on tables can lazily evalu REQUIRE_FALSE(isFullScreen); } +TEST_CASE("tables/operator[]-optional", "Test if proxies on tables can lazily evaluate validity") { + sol::state lua; + + sol::optional test1 = lua["no_exist_yet"]; + bool present = (bool)test1; + REQUIRE_FALSE(present); + + lua["no_exist_yet"] = 262; + sol::optional test2 = lua["no_exist_yet"]; + present = (bool)test2; + REQUIRE(present); + REQUIRE(test2.value() == 262); +} + TEST_CASE("tables/usertype", "Show that we can create classes from usertype and use them") { sol::state lua;