mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Referential transparency is important.
This commit is contained in:
parent
d7b037da73
commit
cbe599a901
|
@ -105,7 +105,7 @@ namespace sol {
|
||||||
if (k <= src.size() && k > 0) {
|
if (k <= src.size() && k > 0) {
|
||||||
--k;
|
--k;
|
||||||
std::advance(it, k);
|
std::advance(it, k);
|
||||||
return stack::push(L, *it);
|
return stack::push_reference(L, *it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stack::push(L, nil);
|
return stack::push(L, nil);
|
||||||
|
@ -115,7 +115,7 @@ namespace sol {
|
||||||
K k = stack::get<K>(L, 2);
|
K k = stack::get<K>(L, 2);
|
||||||
--k;
|
--k;
|
||||||
std::advance(it, k);
|
std::advance(it, k);
|
||||||
return stack::push(L, *it);
|
return stack::push_reference(L, *it);
|
||||||
#endif // Safety
|
#endif // Safety
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,8 +164,7 @@ namespace sol {
|
||||||
if (it == end(source)) {
|
if (it == end(source)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int p = stack::push(L, k + 1);
|
int p = stack::multi_push_reference(L, k + 1, *it);
|
||||||
p += stack::push(L, *it);
|
|
||||||
std::advance(it, 1);
|
std::advance(it, 1);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -262,7 +261,7 @@ namespace sol {
|
||||||
auto it = detail::find(src, *k);
|
auto it = detail::find(src, *k);
|
||||||
if (it != end(src)) {
|
if (it != end(src)) {
|
||||||
auto& v = *it;
|
auto& v = *it;
|
||||||
return stack::push(L, v.second);
|
return stack::push_reference(L, v.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stack::push(L, nil);
|
return stack::push(L, nil);
|
||||||
|
|
|
@ -282,7 +282,7 @@ namespace sol {
|
||||||
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),
|
||||||
mustindex(false), secondarymeta(false) {
|
mustindex(true), secondarymeta(true) {
|
||||||
(void)detail::swallow{ 0,
|
(void)detail::swallow{ 0,
|
||||||
(add(L, detail::forward_get<I * 2>(args), detail::forward_get<I * 2 + 1>(args)),0)...
|
(add(L, detail::forward_get<I * 2>(args), detail::forward_get<I * 2 + 1>(args)),0)...
|
||||||
};
|
};
|
||||||
|
|
|
@ -272,3 +272,39 @@ TEST_CASE("containers/arbitrary-creation", "userdata and tables should be usable
|
||||||
REQUIRE(c.get<std::string>("name") == "Rapptz");
|
REQUIRE(c.get<std::string>("name") == "Rapptz");
|
||||||
REQUIRE(c.get<std::string>("project") == "sol");
|
REQUIRE(c.get<std::string>("project") == "sol");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("containers/usertype-transparency", "Make sure containers pass their arguments through transparently and push the results as references, not new values") {
|
||||||
|
class A {
|
||||||
|
public:
|
||||||
|
int a;
|
||||||
|
A(int b = 2) : a(b) {};
|
||||||
|
|
||||||
|
void func() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct B {
|
||||||
|
|
||||||
|
B() {
|
||||||
|
for (std::size_t i = 0; i < 20; ++i) {
|
||||||
|
a_list.emplace_back(static_cast<int>(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<A> a_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
sol::state lua;
|
||||||
|
lua.new_usertype<B>("B",
|
||||||
|
"a_list", &B::a_list
|
||||||
|
);
|
||||||
|
|
||||||
|
lua.script(R"(
|
||||||
|
b = B.new()
|
||||||
|
a_ref = b.a_list[2]
|
||||||
|
)");
|
||||||
|
|
||||||
|
B& b = lua["b"];
|
||||||
|
A& a_ref = lua["a_ref"];
|
||||||
|
REQUIRE(&b.a_list[1] == &a_ref);
|
||||||
|
REQUIRE(b.a_list[1].a == a_ref.a);
|
||||||
|
}
|
||||||
|
|
|
@ -437,3 +437,23 @@ TEST_CASE("usertype/simple-destruction-test", "make sure usertypes are properly
|
||||||
lua["testCrash"]();
|
lua["testCrash"]();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("usertype/simple-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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sol::state lua;
|
||||||
|
lua.open_libraries();
|
||||||
|
|
||||||
|
lua.new_simple_usertype<A>("A");
|
||||||
|
sol::table table = lua["A"];
|
||||||
|
table["func"] = &A::func;
|
||||||
|
A a;
|
||||||
|
lua.set("a", &a);
|
||||||
|
REQUIRE_NOTHROW(
|
||||||
|
lua.script("assert(a:func() == 5000)")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user