fix #673
make a full decision on #672; not worth the implementation effort
This commit is contained in:
ThePhD 2018-06-26 15:57:22 -04:00
parent c5079f8815
commit f85a5c0ae7
6 changed files with 28 additions and 29 deletions

View File

@ -25,27 +25,12 @@
#define SOL_STACK_CHECK_QUALIFIED_GET_HPP
#include "stack_core.hpp"
#include "stack_get.hpp"
#include "stack_check.hpp"
#include "optional.hpp"
#include <cstdlib>
#include <cmath>
#include "stack_check_get_unqualified.hpp"
namespace sol {
namespace stack {
template <typename T, typename C>
struct qualified_check_getter {
typedef decltype(stack_detail::unchecked_get<T>(nullptr, 0, std::declval<record&>())) R;
template <typename Handler>
static optional<R> get(lua_State* L, int index, Handler&& handler, record& tracking) {
if (!check<T>(L, index, std::forward<Handler>(handler))) {
tracking.use(static_cast<int>(!lua_isnone(L, index)));
return nullopt;
}
return stack_detail::unchecked_get<T>(L, index, tracking);
}
};
struct qualified_check_getter : check_getter<meta::unqualified_t<T>, C> {};
}
} // namespace sol::stack

View File

@ -53,7 +53,7 @@ namespace stack {
static optional<T> 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 = stack::check<T>(L, index, no_panic);
bool success = lua_isnoneornil(L, index) == 0 && stack::check<T>(L, index, no_panic);
if (!success) {
// expected type, actual type
tracking.use(static_cast<int>(success));
@ -64,14 +64,6 @@ namespace stack {
}
};
template <typename T>
struct check_getter<optional<T>> {
template <typename Handler>
static decltype(auto) get(lua_State* L, int index, Handler&&, record& tracking) {
return check_get<T>(L, index, no_panic, tracking);
}
};
template <typename T>
struct check_getter<T, std::enable_if_t<std::is_integral<T>::value && lua_type_of<T>::value == type::number>> {
template <typename Handler>

View File

@ -768,7 +768,8 @@ namespace sol {
template <typename T, typename Handler>
inline decltype(auto) unqualified_check_get(lua_State* L, int index, Handler&& handler, record& tracking) {
check_getter<T> cg{};
typedef meta::unqualified_t<T> Tu;
check_getter<Tu> cg{};
(void)cg;
return cg.get(L, index, std::forward<Handler>(handler), tracking);
}

View File

@ -1180,7 +1180,7 @@ namespace sol {
struct is_environment : std::integral_constant<bool, is_userdata<T>::value || is_table<T>::value> {};
template <typename T>
struct is_automagical : std::true_type {};
struct is_automagical : meta::neg<std::is_array<meta::unqualified_t<T>>> {};
template <typename T>
inline type type_of() {

View File

@ -92,7 +92,7 @@ namespace sol {
template <typename T, typename Op>
int comparsion_operator_wrap(lua_State* L) {
auto maybel = stack::unqualified_check_get<T>(L, 1);
auto maybel = stack::unqualified_check_get<T&>(L, 1);
if (maybel) {
auto mayber = stack::unqualified_check_get<T&>(L, 2);
if (mayber) {

View File

@ -542,6 +542,27 @@ TEST_CASE("optional/left out args", "Make sure arguments can be left out of opti
}());
}
TEST_CASE("optional/engaged versus unengaged", "solidify semantics for an engaged and unengaged optional") {
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.set_function("f", [](sol::optional<sol::object> optional_arg) {
if (optional_arg) {
return true;
}
return false;
});
auto valid0 = lua.safe_script("assert(not f())", sol::script_pass_on_error);
REQUIRE(valid0.valid());
auto valid1 = lua.safe_script("assert(not f(nil))", sol::script_pass_on_error);
REQUIRE(valid1.valid());
auto valid2 = lua.safe_script("assert(f(1))", sol::script_pass_on_error);
REQUIRE(valid2.valid());
auto valid3 = lua.safe_script("assert(f('hi'))", sol::script_pass_on_error);
REQUIRE(valid3.valid());
}
TEST_CASE("pusher/constness", "Make sure more types can handle being const and junk") {
struct Foo {
Foo(const sol::function& f)