simple_usertype now responds with nil on bad lookups and sets items into place properly when new_index'd

This commit is contained in:
ThePhD 2017-02-19 05:00:11 -05:00
parent 0c8ec828d5
commit dde4aa64fc
6 changed files with 82 additions and 25 deletions

View File

@ -20,8 +20,8 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script. // This file was generated with a script.
// Generated 2017-02-19 02:59:41.608823 UTC // Generated 2017-02-19 09:59:38.638408 UTC
// This header was generated with sol v2.15.8 (revision a9cfe4b) // This header was generated with sol v2.15.8 (revision 0c8ec82)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP #ifndef SOL_SINGLE_INCLUDE_HPP
@ -8552,7 +8552,7 @@ namespace sol {
template <typename Fx, std::size_t I, typename... R, typename... Args> template <typename Fx, std::size_t I, typename... R, typename... Args>
int call(types<Fx>, index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int) { int call(types<Fx>, index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int) {
auto& func = std::get<I>(overloads); auto& func = std::get<I>(overloads);
return call_detail::call_wrapped<void, true, false>(L, func); return call_detail::call_wrapped<void, true, false, start_skew>(L, func);
} }
int operator()(lua_State* L) { int operator()(lua_State* L) {
@ -10156,9 +10156,9 @@ namespace sol {
auto maybeaccessor = stack::get<optional<string_detail::string_shim>>(L, is_index ? -1 : -2); auto maybeaccessor = stack::get<optional<string_detail::string_shim>>(L, is_index ? -1 : -2);
string_detail::string_shim accessor = maybeaccessor.value_or(string_detail::string_shim("(unknown)")); string_detail::string_shim accessor = maybeaccessor.value_or(string_detail::string_shim("(unknown)"));
if (is_index) if (is_index)
return luaL_error(L, "sol: attempt to index (get) lua_nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str()); return luaL_error(L, "sol: attempt to index (get) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str());
else else
return luaL_error(L, "sol: attempt to index (set) lua_nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str()); return luaL_error(L, "sol: attempt to index (set) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str());
} }
template <bool is_index, typename Base> template <bool is_index, typename Base>
@ -10729,10 +10729,13 @@ namespace sol {
lua_settop(L, 0); lua_settop(L, 0);
return 0; return 0;
} }
lua_pop(L, 1);
return indexing_fail<false>(L); return indexing_fail<false>(L);
} }
inline int simple_indexing_fail(lua_State* L) {
return stack::push(L, sol::lua_nil);
}
template <bool is_index, bool toplevel = false> template <bool is_index, bool toplevel = false>
inline int simple_core_indexing_call(lua_State* L) { inline int simple_core_indexing_call(lua_State* L) {
simple_map& sm = toplevel ? stack::get<user<simple_map>>(L, upvalue_index(1)) : stack::pop<user<simple_map>>(L); simple_map& sm = toplevel ? stack::get<user<simple_map>>(L, upvalue_index(1)) : stack::pop<user<simple_map>>(L);
@ -10840,7 +10843,7 @@ namespace sol {
} }
template <typename N, typename F, typename... Args> template <typename N, typename F, typename... Args>
void insert_prepare(std::true_type, lua_State* L, N&& n, F&& f, Args&&... args) { void insert_prepare(std::true_type, lua_State* L, N&&, F&& f, Args&&... args) {
object o = make_object<F>(L, std::forward<F>(f), function_detail::call_indicator(), std::forward<Args>(args)...); object o = make_object<F>(L, std::forward<F>(f), function_detail::call_indicator(), std::forward<Args>(args)...);
callconstructfunc = std::move(o); callconstructfunc = std::move(o);
} }
@ -10956,7 +10959,7 @@ namespace sol {
template<std::size_t... I, typename Tuple> template<std::size_t... I, typename Tuple>
simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args) simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
: callconstructfunc(lua_nil), : callconstructfunc(lua_nil),
indexfunc(&usertype_detail::indexing_fail<true>), newindexfunc(&usertype_detail::indexing_fail<false>), indexfunc(&usertype_detail::simple_indexing_fail), newindexfunc(&usertype_detail::simple_metatable_newindex<T>),
indexbase(&usertype_detail::simple_core_indexing_call<true>), newindexbase(&usertype_detail::simple_core_indexing_call<false>), indexbase(&usertype_detail::simple_core_indexing_call<true>), newindexbase(&usertype_detail::simple_core_indexing_call<false>),
indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>), indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>),
baseclasscheck(nullptr), baseclasscast(nullptr), baseclasscheck(nullptr), baseclasscast(nullptr),
@ -11186,15 +11189,15 @@ namespace sol {
stack::set_field(L, meta_function::index, stack::set_field(L, meta_function::index,
make_closure(&usertype_detail::simple_index_call, make_closure(&usertype_detail::simple_index_call,
make_light(varmap), make_light(varmap),
&usertype_detail::simple_index_call, umx.indexfunc,
&usertype_detail::simple_metatable_newindex<T>, umx.newindexfunc,
usertype_detail::toplevel_magic usertype_detail::toplevel_magic
), metabehind.stack_index()); ), metabehind.stack_index());
stack::set_field(L, meta_function::new_index, stack::set_field(L, meta_function::new_index,
make_closure(&usertype_detail::simple_new_index_call, make_closure(&usertype_detail::simple_new_index_call,
make_light(varmap), make_light(varmap),
&usertype_detail::simple_index_call, umx.indexfunc,
&usertype_detail::simple_metatable_newindex<T>, umx.newindexfunc,
usertype_detail::toplevel_magic usertype_detail::toplevel_magic
), metabehind.stack_index()); ), metabehind.stack_index());
stack::set_field(L, metatable_key, metabehind, t.stack_index()); stack::set_field(L, metatable_key, metabehind, t.stack_index());

View File

@ -45,7 +45,7 @@ namespace sol {
template <typename Fx, std::size_t I, typename... R, typename... Args> template <typename Fx, std::size_t I, typename... R, typename... Args>
int call(types<Fx>, index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int) { int call(types<Fx>, index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int) {
auto& func = std::get<I>(overloads); auto& func = std::get<I>(overloads);
return call_detail::call_wrapped<void, true, false>(L, func); return call_detail::call_wrapped<void, true, false, start_skew>(L, func);
} }
int operator()(lua_State* L) { int operator()(lua_State* L) {

View File

@ -98,10 +98,13 @@ namespace sol {
lua_settop(L, 0); lua_settop(L, 0);
return 0; return 0;
} }
lua_pop(L, 1);
return indexing_fail<false>(L); return indexing_fail<false>(L);
} }
inline int simple_indexing_fail(lua_State* L) {
return stack::push(L, sol::lua_nil);
}
template <bool is_index, bool toplevel = false> template <bool is_index, bool toplevel = false>
inline int simple_core_indexing_call(lua_State* L) { inline int simple_core_indexing_call(lua_State* L) {
simple_map& sm = toplevel ? stack::get<user<simple_map>>(L, upvalue_index(1)) : stack::pop<user<simple_map>>(L); simple_map& sm = toplevel ? stack::get<user<simple_map>>(L, upvalue_index(1)) : stack::pop<user<simple_map>>(L);
@ -209,7 +212,7 @@ namespace sol {
} }
template <typename N, typename F, typename... Args> template <typename N, typename F, typename... Args>
void insert_prepare(std::true_type, lua_State* L, N&& n, F&& f, Args&&... args) { void insert_prepare(std::true_type, lua_State* L, N&&, F&& f, Args&&... args) {
object o = make_object<F>(L, std::forward<F>(f), function_detail::call_indicator(), std::forward<Args>(args)...); object o = make_object<F>(L, std::forward<F>(f), function_detail::call_indicator(), std::forward<Args>(args)...);
callconstructfunc = std::move(o); callconstructfunc = std::move(o);
} }
@ -325,7 +328,7 @@ namespace sol {
template<std::size_t... I, typename Tuple> template<std::size_t... I, typename Tuple>
simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args) simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
: callconstructfunc(lua_nil), : callconstructfunc(lua_nil),
indexfunc(&usertype_detail::indexing_fail<true>), newindexfunc(&usertype_detail::indexing_fail<false>), indexfunc(&usertype_detail::simple_indexing_fail), newindexfunc(&usertype_detail::simple_metatable_newindex<T>),
indexbase(&usertype_detail::simple_core_indexing_call<true>), newindexbase(&usertype_detail::simple_core_indexing_call<false>), indexbase(&usertype_detail::simple_core_indexing_call<true>), newindexbase(&usertype_detail::simple_core_indexing_call<false>),
indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>), indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>),
baseclasscheck(nullptr), baseclasscast(nullptr), baseclasscheck(nullptr), baseclasscast(nullptr),
@ -555,15 +558,15 @@ namespace sol {
stack::set_field(L, meta_function::index, stack::set_field(L, meta_function::index,
make_closure(&usertype_detail::simple_index_call, make_closure(&usertype_detail::simple_index_call,
make_light(varmap), make_light(varmap),
&usertype_detail::simple_index_call, umx.indexfunc,
&usertype_detail::simple_metatable_newindex<T>, umx.newindexfunc,
usertype_detail::toplevel_magic usertype_detail::toplevel_magic
), metabehind.stack_index()); ), metabehind.stack_index());
stack::set_field(L, meta_function::new_index, stack::set_field(L, meta_function::new_index,
make_closure(&usertype_detail::simple_new_index_call, make_closure(&usertype_detail::simple_new_index_call,
make_light(varmap), make_light(varmap),
&usertype_detail::simple_index_call, umx.indexfunc,
&usertype_detail::simple_metatable_newindex<T>, umx.newindexfunc,
usertype_detail::toplevel_magic usertype_detail::toplevel_magic
), metabehind.stack_index()); ), metabehind.stack_index());
stack::set_field(L, metatable_key, metabehind, t.stack_index()); stack::set_field(L, metatable_key, metabehind, t.stack_index());

View File

@ -107,9 +107,9 @@ namespace sol {
auto maybeaccessor = stack::get<optional<string_detail::string_shim>>(L, is_index ? -1 : -2); auto maybeaccessor = stack::get<optional<string_detail::string_shim>>(L, is_index ? -1 : -2);
string_detail::string_shim accessor = maybeaccessor.value_or(string_detail::string_shim("(unknown)")); string_detail::string_shim accessor = maybeaccessor.value_or(string_detail::string_shim("(unknown)"));
if (is_index) if (is_index)
return luaL_error(L, "sol: attempt to index (get) lua_nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str()); return luaL_error(L, "sol: attempt to index (get) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str());
else else
return luaL_error(L, "sol: attempt to index (set) lua_nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str()); return luaL_error(L, "sol: attempt to index (set) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str());
} }
template <bool is_index, typename Base> template <bool is_index, typename Base>

View File

@ -489,6 +489,10 @@ TEST_CASE("usertype/simple-class-propogation", "make sure methods and variables
} }
TEST_CASE("usertype/simple-call-constructor", "ensure that all kinds of call-based constructors can be serialized") { TEST_CASE("usertype/simple-call-constructor", "ensure that all kinds of call-based constructors can be serialized") {
struct thing {};
struct v_test {
};
struct f_test { struct f_test {
int i; f_test(int i) : i(i) {} int i; f_test(int i) : i(i) {}
}; };
@ -503,7 +507,6 @@ TEST_CASE("usertype/simple-call-constructor", "ensure that all kinds of call-bas
lua.open_libraries(sol::lib::base); lua.open_libraries(sol::lib::base);
auto f = sol::factories([]() {return f_test(30); }); auto f = sol::factories([]() {return f_test(30); });
lua.new_simple_usertype<f_test>("f_test", lua.new_simple_usertype<f_test>("f_test",
sol::call_constructor, sol::factories([]() { sol::call_constructor, sol::factories([]() {
return f_test(20); return f_test(20);
@ -535,4 +538,42 @@ TEST_CASE("usertype/simple-call-constructor", "ensure that all kinds of call-bas
REQUIRE(b.i == 21); REQUIRE(b.i == 21);
REQUIRE(c.i == 22); REQUIRE(c.i == 22);
REQUIRE(d.i == 30); REQUIRE(d.i == 30);
auto vfactories = sol::factories(
[](const sol::table& tbl) {
for (auto v : tbl)
{
REQUIRE(v.second.valid());
// This fails only when the call_constructor is used:
REQUIRE(v.second.is<thing>());
}
return v_test();
}
);
lua.new_simple_usertype<v_test>("v_test",
sol::meta_function::construct, vfactories,
sol::call_constructor, vfactories
);
lua.new_simple_usertype<thing>("thing");
lua.script("things = {thing.new(), thing.new()}");
SECTION("new") {
REQUIRE_NOTHROW(lua.script("a = v_test.new(things)"));
}
SECTION("call_constructor") {
REQUIRE_NOTHROW(lua.script("b = v_test(things)"));
}
}
TEST_CASE("usertype/simple-missing-key", "make sure a missing key returns nil") {
struct thing {};
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_simple_usertype<thing>("thing");
REQUIRE_NOTHROW(lua.script("print(thing.missingKey)"));
} }

View File

@ -1493,3 +1493,13 @@ a = A(24.3)
A& a = lua["a"]; A& a = lua["a"];
REQUIRE(a.f == 24.3); REQUIRE(a.f == 24.3);
} }
TEST_CASE("usertype/missing-key", "make sure a missing key returns nil") {
struct thing {};
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<thing>("thing");
REQUIRE_NOTHROW(lua.script("print(thing.missingKey)"));
}