mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
allow personal indexing function to catch rewrites to itself in usertypes statically and dynamically
This commit is contained in:
parent
6ceb715912
commit
7c29964339
|
@ -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-03-22 11:54:07.623956 UTC
|
||||
// This header was generated with sol v2.16.0 (revision a9644d0)
|
||||
// Generated 2017-03-23 14:12:13.335349 UTC
|
||||
// This header was generated with sol v2.16.0 (revision 6ceb715)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||
|
@ -10424,13 +10424,14 @@ namespace sol {
|
|||
bool haslessequals;
|
||||
|
||||
template <std::size_t Idx, meta::enable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, RawTuple>>> = meta::enabler>
|
||||
inline lua_CFunction make_func() {
|
||||
lua_CFunction make_func() const {
|
||||
return std::get<Idx + 1>(functions);
|
||||
}
|
||||
|
||||
template <std::size_t Idx, meta::disable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, RawTuple>>> = meta::enabler>
|
||||
inline lua_CFunction make_func() {
|
||||
return call<Idx + 1>;
|
||||
lua_CFunction make_func() const {
|
||||
const auto& name = std::get<Idx>(functions);
|
||||
return (usertype_detail::make_shim(name) == "__newindex") ? &call<Idx + 1, false> : &call<Idx + 1, true>;
|
||||
}
|
||||
|
||||
static bool contains_variable() {
|
||||
|
@ -10522,6 +10523,17 @@ namespace sol {
|
|||
++index;
|
||||
}
|
||||
|
||||
template <std::size_t Idx>
|
||||
static std::pair<std::string, usertype_detail::call_information> make_call_info(std::string n) {
|
||||
return{ n, (n == "__newindex" || n == "__index") ?
|
||||
usertype_detail::call_information(&usertype_metatable::real_meta_call<Idx * 2 + 1, false>,
|
||||
&usertype_metatable::real_meta_call<Idx * 2 + 1, true>)
|
||||
:
|
||||
usertype_detail::call_information(&usertype_metatable::real_find_call<Idx * 2, Idx * 2 + 1, false>,
|
||||
&usertype_metatable::real_find_call<Idx * 2, Idx * 2 + 1, true>)
|
||||
};
|
||||
}
|
||||
|
||||
template <typename... Args, typename = std::enable_if_t<sizeof...(Args) == sizeof...(Tn)>>
|
||||
usertype_metatable(Args&&... args) :
|
||||
mapping(),
|
||||
|
@ -10535,9 +10547,7 @@ namespace sol {
|
|||
hasequals(false), hasless(false), haslessequals(false) {
|
||||
std::initializer_list<typename usertype_detail::mapping_t::value_type> ilist{ {
|
||||
std::pair<std::string, usertype_detail::call_information>(
|
||||
usertype_detail::make_string(std::get<I * 2>(functions)),
|
||||
usertype_detail::call_information(&usertype_metatable::real_find_call<I * 2, I * 2 + 1, false>,
|
||||
&usertype_metatable::real_find_call<I * 2, I * 2 + 1, true>)
|
||||
make_call_info<I>(usertype_detail::make_string(std::get<I * 2>(functions)))
|
||||
)
|
||||
}... };
|
||||
mapping.insert(ilist);
|
||||
|
@ -10554,7 +10564,15 @@ namespace sol {
|
|||
if (is_variable_binding<decltype(std::get<I1>(f.functions))>::value) {
|
||||
return real_call_with<I1, is_index, true>(L, f);
|
||||
}
|
||||
return stack::push(L, c_closure(call<I1, is_index>, stack::push(L, light<usertype_metatable>(f))));
|
||||
int upvalues = stack::push(L, light<usertype_metatable>(f));
|
||||
auto cfunc = &call<I1, is_index>;
|
||||
return stack::push(L, c_closure(cfunc, upvalues));
|
||||
}
|
||||
|
||||
template <std::size_t I1, bool is_index>
|
||||
static int real_meta_call(lua_State* L, void* um, int) {
|
||||
auto& f = *static_cast<usertype_metatable*>(um);
|
||||
return real_call_with<I1, is_index>(L, f);
|
||||
}
|
||||
|
||||
template <bool is_index, bool toplevel = false>
|
||||
|
|
|
@ -334,13 +334,14 @@ namespace sol {
|
|||
bool haslessequals;
|
||||
|
||||
template <std::size_t Idx, meta::enable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, RawTuple>>> = meta::enabler>
|
||||
inline lua_CFunction make_func() {
|
||||
lua_CFunction make_func() const {
|
||||
return std::get<Idx + 1>(functions);
|
||||
}
|
||||
|
||||
template <std::size_t Idx, meta::disable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, RawTuple>>> = meta::enabler>
|
||||
inline lua_CFunction make_func() {
|
||||
return call<Idx + 1>;
|
||||
lua_CFunction make_func() const {
|
||||
const auto& name = std::get<Idx>(functions);
|
||||
return (usertype_detail::make_shim(name) == "__newindex") ? &call<Idx + 1, false> : &call<Idx + 1, true>;
|
||||
}
|
||||
|
||||
static bool contains_variable() {
|
||||
|
@ -432,6 +433,17 @@ namespace sol {
|
|||
++index;
|
||||
}
|
||||
|
||||
template <std::size_t Idx>
|
||||
static std::pair<std::string, usertype_detail::call_information> make_call_info(std::string n) {
|
||||
return{ n, (n == "__newindex" || n == "__index") ?
|
||||
usertype_detail::call_information(&usertype_metatable::real_meta_call<Idx * 2 + 1, false>,
|
||||
&usertype_metatable::real_meta_call<Idx * 2 + 1, true>)
|
||||
:
|
||||
usertype_detail::call_information(&usertype_metatable::real_find_call<Idx * 2, Idx * 2 + 1, false>,
|
||||
&usertype_metatable::real_find_call<Idx * 2, Idx * 2 + 1, true>)
|
||||
};
|
||||
}
|
||||
|
||||
template <typename... Args, typename = std::enable_if_t<sizeof...(Args) == sizeof...(Tn)>>
|
||||
usertype_metatable(Args&&... args) :
|
||||
mapping(),
|
||||
|
@ -445,9 +457,7 @@ namespace sol {
|
|||
hasequals(false), hasless(false), haslessequals(false) {
|
||||
std::initializer_list<typename usertype_detail::mapping_t::value_type> ilist{ {
|
||||
std::pair<std::string, usertype_detail::call_information>(
|
||||
usertype_detail::make_string(std::get<I * 2>(functions)),
|
||||
usertype_detail::call_information(&usertype_metatable::real_find_call<I * 2, I * 2 + 1, false>,
|
||||
&usertype_metatable::real_find_call<I * 2, I * 2 + 1, true>)
|
||||
make_call_info<I>(usertype_detail::make_string(std::get<I * 2>(functions)))
|
||||
)
|
||||
}... };
|
||||
mapping.insert(ilist);
|
||||
|
@ -464,7 +474,15 @@ namespace sol {
|
|||
if (is_variable_binding<decltype(std::get<I1>(f.functions))>::value) {
|
||||
return real_call_with<I1, is_index, true>(L, f);
|
||||
}
|
||||
return stack::push(L, c_closure(call<I1, is_index>, stack::push(L, light<usertype_metatable>(f))));
|
||||
int upvalues = stack::push(L, light<usertype_metatable>(f));
|
||||
auto cfunc = &call<I1, is_index>;
|
||||
return stack::push(L, c_closure(cfunc, upvalues));
|
||||
}
|
||||
|
||||
template <std::size_t I1, bool is_index>
|
||||
static int real_meta_call(lua_State* L, void* um, int) {
|
||||
auto& f = *static_cast<usertype_metatable*>(um);
|
||||
return real_call_with<I1, is_index>(L, f);
|
||||
}
|
||||
|
||||
template <bool is_index, bool toplevel = false>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
TEST_CASE("usertype/simple-usertypes", "Ensure that simple usertypes properly work here") {
|
||||
TEST_CASE("simple_usertype/usertypes", "Ensure that simple usertypes properly work here") {
|
||||
struct marker {
|
||||
bool value = false;
|
||||
};
|
||||
|
@ -87,7 +87,7 @@ TEST_CASE("usertype/simple-usertypes", "Ensure that simple usertypes properly wo
|
|||
REQUIRE(z == 29);
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/simple-usertypes-constructors", "Ensure that calls with specific arguments work") {
|
||||
TEST_CASE("simple_usertype/usertypes-constructors", "Ensure that calls with specific arguments work") {
|
||||
struct marker {
|
||||
bool value = false;
|
||||
};
|
||||
|
@ -173,7 +173,7 @@ TEST_CASE("usertype/simple-usertypes-constructors", "Ensure that calls with spec
|
|||
REQUIRE(z == 29);
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/simple-shared-ptr-regression", "simple usertype metatables should not screw over unique usertype metatables") {
|
||||
TEST_CASE("simple_usertype/shared-ptr-regression", "simple usertype metatables should not screw over unique usertype metatables") {
|
||||
static int created = 0;
|
||||
static int destroyed = 0;
|
||||
struct test {
|
||||
|
@ -211,7 +211,7 @@ TEST_CASE("usertype/simple-shared-ptr-regression", "simple usertype metatables s
|
|||
REQUIRE(destroyed == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/simple-vars", "simple usertype vars can bind various values (no ref)") {
|
||||
TEST_CASE("simple_usertype/vars", "simple usertype vars can bind various values (no ref)") {
|
||||
int muh_variable = 10;
|
||||
int through_variable = 25;
|
||||
|
||||
|
@ -249,7 +249,7 @@ g3 = test.global3
|
|||
REQUIRE(g3 == 20);
|
||||
}
|
||||
|
||||
TEST_CASE("usertypes/simple-variable-control", "test to see if usertypes respond to inheritance and variable controls") {
|
||||
TEST_CASE("simple_usertype/variable-control", "test to see if usertypes respond to inheritance and variable controls") {
|
||||
class A {
|
||||
public:
|
||||
virtual void a() { throw std::runtime_error("entered base pure virtual implementation"); };
|
||||
|
@ -322,7 +322,7 @@ TEST_CASE("usertypes/simple-variable-control", "test to see if usertypes respond
|
|||
lua.script("print(sw.pb)assert(sw.pb == 27)");
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/simple-factory-constructor-overload-usage", "simple usertypes should probably invoke types") {
|
||||
TEST_CASE("simple_usertype/factory-constructor-overload-usage", "simple usertypes should probably invoke types") {
|
||||
class A {
|
||||
public:
|
||||
virtual void a() { throw std::runtime_error("entered base pure virtual implementation"); };
|
||||
|
@ -378,7 +378,7 @@ TEST_CASE("usertype/simple-factory-constructor-overload-usage", "simple usertype
|
|||
REQUIRE(y4 == 3);
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/simple-runtime-append", "allow extra functions to be appended at runtime directly to the metatable itself") {
|
||||
TEST_CASE("simple_usertype/runtime-append", "allow extra functions to be appended at runtime directly to the metatable itself") {
|
||||
class A {
|
||||
};
|
||||
|
||||
|
@ -407,7 +407,7 @@ TEST_CASE("usertype/simple-runtime-append", "allow extra functions to be appende
|
|||
REQUIRE(w == 100);
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/simple-destruction-test", "make sure usertypes are properly destructed and don't double-delete memory or segfault") {
|
||||
TEST_CASE("simple_usertype/destruction-test", "make sure usertypes are properly destructed and don't double-delete memory or segfault") {
|
||||
sol::state lua;
|
||||
|
||||
class CrashClass {
|
||||
|
@ -438,7 +438,7 @@ TEST_CASE("usertype/simple-destruction-test", "make sure usertypes are properly
|
|||
}
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/simple-table-append", "Ensure that appending to the meta table also affects the internal function table for pointers as well") {
|
||||
TEST_CASE("simple_usertype/table-append", "Ensure that appending to the meta table also affects the internal function table for pointers as well") {
|
||||
struct A {
|
||||
int func() {
|
||||
return 5000;
|
||||
|
@ -462,7 +462,7 @@ TEST_CASE("usertype/simple-table-append", "Ensure that appending to the meta tab
|
|||
}());
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/simple-class-propogation", "make sure methods and variables from base classes work properly in SAFE_USERTYPE mode") {
|
||||
TEST_CASE("simple_usertype/class-propogation", "make sure methods and variables from base classes work properly in SAFE_USERTYPE mode") {
|
||||
class A {
|
||||
public:
|
||||
int var = 200;
|
||||
|
@ -488,7 +488,7 @@ 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("simple_usertype/call-constructor", "ensure that all kinds of call-based constructors can be serialized") {
|
||||
struct thing {};
|
||||
struct v_test {
|
||||
|
||||
|
@ -565,7 +565,7 @@ TEST_CASE("usertype/simple-call-constructor", "ensure that all kinds of call-bas
|
|||
}
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/simple-no_constructor", "make sure simple usertype errors when no-constructor types are called") {
|
||||
TEST_CASE("simple_usertype/no_constructor", "make sure simple usertype errors when no-constructor types are called") {
|
||||
struct thing {};
|
||||
|
||||
SECTION("new no_constructor") {
|
||||
|
@ -589,7 +589,7 @@ TEST_CASE("usertype/simple-no_constructor", "make sure simple usertype errors wh
|
|||
}
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/simple-missing-key", "make sure a missing key returns nil") {
|
||||
TEST_CASE("simple_usertype/missing-key", "make sure a missing key returns nil") {
|
||||
struct thing {};
|
||||
|
||||
sol::state lua;
|
||||
|
@ -599,7 +599,7 @@ TEST_CASE("usertype/simple-missing-key", "make sure a missing key returns nil")
|
|||
REQUIRE_NOTHROW(lua.script("print(thing.missingKey)"));
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/simple-runtime-extensibility", "Check if usertypes are runtime extensible") {
|
||||
TEST_CASE("simple_usertype/runtime-extensibility", "Check if usertypes are runtime extensible") {
|
||||
struct thing {
|
||||
int v = 20;
|
||||
int func(int a) { return a; }
|
||||
|
@ -696,3 +696,56 @@ end
|
|||
REQUIRE(val == 3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("simple_usertype/meta-key-retrievals", "allow for special meta keys (__index, __newindex) to trigger methods even if overwritten directly") {
|
||||
SECTION("dynamically") {
|
||||
static int writes = 0;
|
||||
static std::string keys[2] = {};
|
||||
static int values[2] = {};
|
||||
struct d_sample {
|
||||
void foo(std::string k, int v) {
|
||||
keys[writes] = k;
|
||||
values[writes] = v;
|
||||
++writes;
|
||||
}
|
||||
};
|
||||
|
||||
sol::state state;
|
||||
state.new_simple_usertype<d_sample>("sample");
|
||||
sol::table s = state["sample"]["new"]();
|
||||
s[sol::metatable_key][sol::meta_function::new_index] = &d_sample::foo;
|
||||
state["var"] = s;
|
||||
|
||||
|
||||
state.script("var.key = 2");
|
||||
state.script("var.__newindex = 4");
|
||||
REQUIRE(values[0] == 2);
|
||||
REQUIRE(keys[0] == "key");
|
||||
REQUIRE(values[1] == 4);
|
||||
REQUIRE(keys[1] == "__newindex");
|
||||
}
|
||||
|
||||
SECTION("statically") {
|
||||
static int writes = 0;
|
||||
static std::string keys[2] = {};
|
||||
static int values[2] = {};
|
||||
struct sample {
|
||||
void foo(std::string k, int v) {
|
||||
keys[writes] = k;
|
||||
values[writes] = v;
|
||||
++writes;
|
||||
}
|
||||
};
|
||||
|
||||
sol::state state;
|
||||
state.new_simple_usertype<sample>("sample", sol::meta_function::new_index, &sample::foo);
|
||||
|
||||
state.script("var = sample.new()");
|
||||
state.script("var.key = 2");
|
||||
state.script("var.__newindex = 4");
|
||||
REQUIRE(values[0] == 2);
|
||||
REQUIRE(keys[0] == "key");
|
||||
REQUIRE(values[1] == 4);
|
||||
REQUIRE(keys[1] == "__newindex");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1354,7 +1354,7 @@ print(test.ref_global2)
|
|||
REQUIRE(through_variable == 35);
|
||||
}
|
||||
|
||||
TEST_CASE("usertypes/var-and-property", "make sure const vars are readonly and properties can handle lambdas") {
|
||||
TEST_CASE("usertype/var-and-property", "make sure const vars are readonly and properties can handle lambdas") {
|
||||
const static int arf = 20;
|
||||
|
||||
struct test {
|
||||
|
@ -1622,3 +1622,56 @@ end
|
|||
REQUIRE(val == 3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/meta-key-retrievals", "allow for special meta keys (__index, __newindex) to trigger methods even if overwritten directly") {
|
||||
SECTION("dynamically") {
|
||||
static int writes = 0;
|
||||
static std::string keys[2] = {};
|
||||
static int values[2] = {};
|
||||
struct d_sample {
|
||||
void foo(std::string k, int v) {
|
||||
keys[writes] = k;
|
||||
values[writes] = v;
|
||||
++writes;
|
||||
}
|
||||
};
|
||||
|
||||
sol::state state;
|
||||
state.new_usertype<d_sample>("sample");
|
||||
sol::table s = state["sample"]["new"]();
|
||||
s[sol::metatable_key][sol::meta_function::new_index] = &d_sample::foo;
|
||||
state["var"] = s;
|
||||
|
||||
|
||||
state.script("var.key = 2");
|
||||
state.script("var.__newindex = 4");
|
||||
REQUIRE(values[0] == 2);
|
||||
REQUIRE(keys[0] == "key");
|
||||
REQUIRE(values[1] == 4);
|
||||
REQUIRE(keys[1] == "__newindex");
|
||||
}
|
||||
|
||||
SECTION("statically") {
|
||||
static int writes = 0;
|
||||
static std::string keys[2] = {};
|
||||
static int values[2] = {};
|
||||
struct sample {
|
||||
void foo(std::string k, int v) {
|
||||
keys[writes] = k;
|
||||
values[writes] = v;
|
||||
++writes;
|
||||
}
|
||||
};
|
||||
|
||||
sol::state state;
|
||||
state.new_usertype<sample>("sample", sol::meta_function::new_index, &sample::foo);
|
||||
|
||||
state.script("var = sample.new()");
|
||||
state.script("var.key = 2");
|
||||
state.script("var.__newindex = 4");
|
||||
REQUIRE(values[0] == 2);
|
||||
REQUIRE(keys[0] == "key");
|
||||
REQUIRE(values[1] == 4);
|
||||
REQUIRE(keys[1] == "__newindex");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user