Full-on optional support.

This commit is contained in:
ThePhD 2016-03-25 10:39:54 -04:00
parent 7efc577eea
commit a0fdaaaa7d
5 changed files with 60 additions and 2 deletions

View File

@ -282,6 +282,14 @@ struct checker<std::pair<A, B>, type::poly, C> {
return stack::check<A>(L, index, handler) && stack::check<B>(L, index + 1, handler); return stack::check<A>(L, index, handler) && stack::check<B>(L, index + 1, handler);
} }
}; };
template<typename T, typename C>
struct checker<optional<T>, type::poly, C> {
template <typename Handler>
static bool check(lua_State* L, int index, Handler&& handler) {
return stack::check<T>(L, index, std::forward<Handler>(handler));
}
};
} // stack } // stack
} // sol } // sol

View File

@ -42,6 +42,14 @@ struct check_getter {
} }
}; };
template <typename T>
struct check_getter<optional<T>> {
template <typename Handler>
static decltype(auto) get(lua_State* L, int index, Handler&&) {
return check_get<T>(L, index, no_panic);
}
};
template <typename T> template <typename T>
struct check_getter<T, std::enable_if_t<std::is_integral<T>::value && !std::is_same<T, bool>::value>> { struct check_getter<T, std::enable_if_t<std::is_integral<T>::value && !std::is_same<T, bool>::value>> {
template <typename Handler> template <typename Handler>
@ -69,6 +77,13 @@ struct check_getter<T, std::enable_if_t<std::is_floating_point<T>::value>> {
return static_cast<T>(value); return static_cast<T>(value);
} }
}; };
template <typename T>
struct getter<optional<T>> {
static decltype(auto) get(lua_State* L, int index) {
return check_get<T>(L, index);
}
};
} // stack } // stack
} // sol } // sol

View File

@ -158,8 +158,10 @@ inline decltype(auto) check_get(lua_State* L, int index = -1) {
return check_get<T>(L, index, handler); return check_get<T>(L, index, handler);
} }
template<typename T> namespace stack_detail {
inline decltype(auto) get(lua_State* L, int index = -1) {
template <typename T>
inline decltype(auto) tagged_get(types<T>, lua_State* L, int index = -1) {
#ifdef SOL_CHECK_ARGUMENTS #ifdef SOL_CHECK_ARGUMENTS
auto op = check_get<T>(L, index, type_panic); auto op = check_get<T>(L, index, type_panic);
typedef typename meta::Unqualified<decltype(op)>::value_type U; typedef typename meta::Unqualified<decltype(op)>::value_type U;
@ -169,6 +171,18 @@ inline decltype(auto) get(lua_State* L, int index = -1) {
#endif #endif
} }
template <typename T>
inline decltype(auto) tagged_get(types<optional<T>>, lua_State* L, int index = -1) {
return stack_detail::unchecked_get<optional<T>>(L, index);
}
} // stack_detail
template<typename T>
inline decltype(auto) get(lua_State* L, int index = -1) {
return stack_detail::tagged_get(types<T>(), L, index);
}
template<typename T> template<typename T>
inline decltype(auto) pop(lua_State* L) { inline decltype(auto) pop(lua_State* L) {
return popper<meta::Unqualified<T>>{}.pop(L); return popper<meta::Unqualified<T>>{}.pop(L);

View File

@ -24,6 +24,7 @@
#include "compatibility.hpp" #include "compatibility.hpp"
#include "traits.hpp" #include "traits.hpp"
#include "optional.hpp"
#include <string> #include <string>
namespace sol { namespace sol {
@ -274,6 +275,9 @@ struct lua_type_of<protected_function> : std::integral_constant<type, type::func
template <typename Signature> template <typename Signature>
struct lua_type_of<std::function<Signature>> : std::integral_constant<type, type::function>{}; struct lua_type_of<std::function<Signature>> : std::integral_constant<type, type::function>{};
template <typename T>
struct lua_type_of<optional<T>> : std::integral_constant<type, type::poly>{};
template <typename T> template <typename T>
struct lua_type_of<T*> : std::integral_constant<type, type::userdata> {}; struct lua_type_of<T*> : std::integral_constant<type, type::userdata> {};
@ -303,6 +307,9 @@ struct is_proxy_primitive : is_lua_primitive<T> { };
template <typename T> template <typename T>
struct is_proxy_primitive<std::reference_wrapper<T>> : std::true_type { }; struct is_proxy_primitive<std::reference_wrapper<T>> : std::true_type { };
template <typename T>
struct is_proxy_primitive<optional<T>> : std::true_type {};
template <typename... Args> template <typename... Args>
struct is_proxy_primitive<std::tuple<Args...>> : std::true_type { }; struct is_proxy_primitive<std::tuple<Args...>> : std::true_type { };

View File

@ -673,6 +673,20 @@ TEST_CASE("tables/operator[]-valid", "Test if proxies on tables can lazily evalu
REQUIRE_FALSE(isFullScreen); REQUIRE_FALSE(isFullScreen);
} }
TEST_CASE("tables/operator[]-optional", "Test if proxies on tables can lazily evaluate validity") {
sol::state lua;
sol::optional<int> test1 = lua["no_exist_yet"];
bool present = (bool)test1;
REQUIRE_FALSE(present);
lua["no_exist_yet"] = 262;
sol::optional<int> 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") { TEST_CASE("tables/usertype", "Show that we can create classes from usertype and use them") {
sol::state lua; sol::state lua;