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.
// This file was generated with a script.
// Generated 2017-02-19 02:59:41.608823 UTC
// This header was generated with sol v2.15.8 (revision a9cfe4b)
// Generated 2017-02-19 09:59:38.638408 UTC
// This header was generated with sol v2.15.8 (revision 0c8ec82)
// https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP
@ -8552,7 +8552,7 @@ namespace sol {
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) {
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) {
@ -10156,9 +10156,9 @@ namespace sol {
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)"));
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
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>
@ -10729,10 +10729,13 @@ namespace sol {
lua_settop(L, 0);
return 0;
}
lua_pop(L, 1);
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>
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);
@ -10840,7 +10843,7 @@ namespace sol {
}
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)...);
callconstructfunc = std::move(o);
}
@ -10956,7 +10959,7 @@ namespace sol {
template<std::size_t... I, typename Tuple>
simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
: 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>),
indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>),
baseclasscheck(nullptr), baseclasscast(nullptr),
@ -11186,15 +11189,15 @@ namespace sol {
stack::set_field(L, meta_function::index,
make_closure(&usertype_detail::simple_index_call,
make_light(varmap),
&usertype_detail::simple_index_call,
&usertype_detail::simple_metatable_newindex<T>,
umx.indexfunc,
umx.newindexfunc,
usertype_detail::toplevel_magic
), metabehind.stack_index());
stack::set_field(L, meta_function::new_index,
make_closure(&usertype_detail::simple_new_index_call,
make_light(varmap),
&usertype_detail::simple_index_call,
&usertype_detail::simple_metatable_newindex<T>,
umx.indexfunc,
umx.newindexfunc,
usertype_detail::toplevel_magic
), metabehind.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>
int call(types<Fx>, index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int) {
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) {

View File

@ -98,10 +98,13 @@ namespace sol {
lua_settop(L, 0);
return 0;
}
lua_pop(L, 1);
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>
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);
@ -209,7 +212,7 @@ namespace sol {
}
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)...);
callconstructfunc = std::move(o);
}
@ -325,7 +328,7 @@ namespace sol {
template<std::size_t... I, typename Tuple>
simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
: 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>),
indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>),
baseclasscheck(nullptr), baseclasscast(nullptr),
@ -555,15 +558,15 @@ namespace sol {
stack::set_field(L, meta_function::index,
make_closure(&usertype_detail::simple_index_call,
make_light(varmap),
&usertype_detail::simple_index_call,
&usertype_detail::simple_metatable_newindex<T>,
umx.indexfunc,
umx.newindexfunc,
usertype_detail::toplevel_magic
), metabehind.stack_index());
stack::set_field(L, meta_function::new_index,
make_closure(&usertype_detail::simple_new_index_call,
make_light(varmap),
&usertype_detail::simple_index_call,
&usertype_detail::simple_metatable_newindex<T>,
umx.indexfunc,
umx.newindexfunc,
usertype_detail::toplevel_magic
), metabehind.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);
string_detail::string_shim accessor = maybeaccessor.value_or(string_detail::string_shim("(unknown)"));
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
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>

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") {
struct thing {};
struct v_test {
};
struct f_test {
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);
auto f = sol::factories([]() {return f_test(30); });
lua.new_simple_usertype<f_test>("f_test",
sol::call_constructor, sol::factories([]() {
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(c.i == 22);
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"];
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)"));
}