hard errors for container usertypes if SOL_CHECK_ARGUMENTS is defined.

otherwise, as usual, we assume you know what you're doing
This commit is contained in:
ThePhD 2017-06-03 06:25:06 -04:00
parent 7168c3177b
commit ea895b4338
3 changed files with 91 additions and 30 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-05-29 17:06:19.842907 UTC // Generated 2017-06-03 10:24:17.749249 UTC
// This header was generated with sol v2.17.4 (revision fd8e2df) // This header was generated with sol v2.17.4 (revision 7168c31)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP #ifndef SOL_SINGLE_INCLUDE_HPP
@ -12291,39 +12291,55 @@ namespace sol {
static int real_new_index_call_const(std::true_type, std::true_type, lua_State* L) { static int real_new_index_call_const(std::true_type, std::true_type, lua_State* L) {
auto& src = get_src(L); auto& src = get_src(L);
auto k = stack::check_get<K>(L, 2); #ifdef SOL_CHECK_ARGUMENTS
if (k) { auto maybek = stack::check_get<K>(L, 2);
if (!maybek) {
return luaL_error(L, "sol: improper key of type %s to a %s", lua_typename(L, static_cast<int>(type_of(L, 2))), detail::demangle<T>().c_str());
}
K& k = *maybek;
#else
K k = stack::get<K>(L, 2);
#endif
using std::end; using std::end;
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;
v.second = stack::get<V>(L, 3); v.second = stack::get<V>(L, 3);
} }
else { else {
src.insert(it, { std::move(*k), stack::get<V>(L, 3) }); src.insert(it, { std::move(k), stack::get<V>(L, 3) });
}
} }
return 0; return 0;
} }
static int real_new_index_call_const(std::true_type, std::false_type, lua_State* L) { static int real_new_index_call_const(std::true_type, std::false_type, lua_State* L) {
auto& src = get_src(L); auto& src = get_src(L);
#ifdef SOL_SAFE_USERTYPE #ifdef SOL_CHECK_ARGUMENTS
auto maybek = stack::check_get<K>(L, 2); auto maybek = stack::check_get<K>(L, 2);
if (!maybek) { if (!maybek) {
return 0; return luaL_error(L, "sol: improper index of type %s to a %s", lua_typename(L, static_cast<int>(type_of(L, 2))), detail::demangle<T>().c_str());
} }
K k = *maybek; K& k = *maybek;
#else #else
K k = stack::get<K>(L, 2); K k = stack::get<K>(L, 2);
#endif #endif
using std::begin; using std::begin;
auto it = begin(src); auto it = begin(src);
#ifdef SOL_CHECK_ARGUMENTS
if (k < 1) {
return luaL_error(L, "sol: out of bounds index to a %s", detail::demangle<T>().c_str());
}
#endif
--k; --k;
if (k == src.size()) { if (k == src.size()) {
real_add_call_push(std::integral_constant<bool, detail::has_push_back<T>::value && std::is_copy_constructible<V>::value>(), L, src, 1); real_add_call_push(std::integral_constant<bool, detail::has_push_back<T>::value && std::is_copy_constructible<V>::value>(), L, src, 1);
return 0; return 0;
} }
#ifdef SOL_CHECK_ARGUMENTS
if (k > src.size()) {
return luaL_error(L, "sol: out of bounds index to a %s", detail::demangle<T>().c_str());
}
#endif
std::advance(it, k); std::advance(it, k);
*it = stack::get<V>(L, 3); *it = stack::get<V>(L, 3);
return 0; return 0;

View File

@ -225,39 +225,55 @@ namespace sol {
static int real_new_index_call_const(std::true_type, std::true_type, lua_State* L) { static int real_new_index_call_const(std::true_type, std::true_type, lua_State* L) {
auto& src = get_src(L); auto& src = get_src(L);
auto k = stack::check_get<K>(L, 2); #ifdef SOL_CHECK_ARGUMENTS
if (k) { auto maybek = stack::check_get<K>(L, 2);
if (!maybek) {
return luaL_error(L, "sol: improper key of type %s to a %s", lua_typename(L, static_cast<int>(type_of(L, 2))), detail::demangle<T>().c_str());
}
K& k = *maybek;
#else
K k = stack::get<K>(L, 2);
#endif
using std::end; using std::end;
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;
v.second = stack::get<V>(L, 3); v.second = stack::get<V>(L, 3);
} }
else { else {
src.insert(it, { std::move(*k), stack::get<V>(L, 3) }); src.insert(it, { std::move(k), stack::get<V>(L, 3) });
}
} }
return 0; return 0;
} }
static int real_new_index_call_const(std::true_type, std::false_type, lua_State* L) { static int real_new_index_call_const(std::true_type, std::false_type, lua_State* L) {
auto& src = get_src(L); auto& src = get_src(L);
#ifdef SOL_SAFE_USERTYPE #ifdef SOL_CHECK_ARGUMENTS
auto maybek = stack::check_get<K>(L, 2); auto maybek = stack::check_get<K>(L, 2);
if (!maybek) { if (!maybek) {
return 0; return luaL_error(L, "sol: improper index of type %s to a %s", lua_typename(L, static_cast<int>(type_of(L, 2))), detail::demangle<T>().c_str());
} }
K k = *maybek; K& k = *maybek;
#else #else
K k = stack::get<K>(L, 2); K k = stack::get<K>(L, 2);
#endif #endif
using std::begin; using std::begin;
auto it = begin(src); auto it = begin(src);
#ifdef SOL_CHECK_ARGUMENTS
if (k < 1) {
return luaL_error(L, "sol: out of bounds index to a %s", detail::demangle<T>().c_str());
}
#endif
--k; --k;
if (k == src.size()) { if (k == src.size()) {
real_add_call_push(std::integral_constant<bool, detail::has_push_back<T>::value && std::is_copy_constructible<V>::value>(), L, src, 1); real_add_call_push(std::integral_constant<bool, detail::has_push_back<T>::value && std::is_copy_constructible<V>::value>(), L, src, 1);
return 0; return 0;
} }
#ifdef SOL_CHECK_ARGUMENTS
if (k > src.size()) {
return luaL_error(L, "sol: out of bounds index to a %s", detail::demangle<T>().c_str());
}
#endif
std::advance(it, k); std::advance(it, k);
*it = stack::get<V>(L, 3); *it = stack::get<V>(L, 3);
return 0; return 0;

View File

@ -305,12 +305,15 @@ end
// Set a global variable called // Set a global variable called
// "arr" to be a vector of 5 lements // "arr" to be a vector of 5 lements
lua["c_arr"] = std::array<int, 5>{ { 2, 4, 6, 8, 10 } };
lua["arr"] = std::vector<int>{ 2, 4, 6, 8, 10 }; lua["arr"] = std::vector<int>{ 2, 4, 6, 8, 10 };
lua["map"] = std::map<int, int>{ { 1 , 2 },{ 2, 4 },{ 3, 6 },{ 4, 8 },{ 5, 10 } }; lua["map"] = std::map<int, int>{ { 1 , 2 },{ 2, 4 },{ 3, 6 },{ 4, 8 },{ 5, 10 } };
lua["set"] = std::set<int>{ 2, 4, 6, 8, 10 }; lua["set"] = std::set<int>{ 2, 4, 6, 8, 10 };
std::array<int, 5>& c_arr = lua["c_arr"];
std::vector<int>& arr = lua["arr"]; std::vector<int>& arr = lua["arr"];
std::map<int, int>& map = lua["map"]; std::map<int, int>& map = lua["map"];
std::set<int>& set = lua["set"]; std::set<int>& set = lua["set"];
REQUIRE(c_arr.size() == 5);
REQUIRE(arr.size() == 5); REQUIRE(arr.size() == 5);
REQUIRE(map.size() == 5); REQUIRE(map.size() == 5);
REQUIRE(set.size() == 5); REQUIRE(set.size() == 5);
@ -342,6 +345,32 @@ end
REQUIRE(arr.empty()); REQUIRE(arr.empty());
REQUIRE(map.empty()); REQUIRE(map.empty());
REQUIRE(set.empty()); REQUIRE(set.empty());
REQUIRE_NOTHROW([&]() {
lua.script(R"(
c_arr[1] = 7
c_arr[2] = 7
c_arr[3] = 7
)");
}());
SECTION("throw test") {
sol::state tlua;
tlua["c_arr"] = std::array<int, 5>{ { 2, 4, 6, 8, 10 } };
REQUIRE_THROWS([&]() {
tlua.script(R"(
c_arr[0] = 7
)");
}());
}
SECTION("throw test 2") {
sol::state tlua;
tlua["c_arr"] = std::array<int, 5>{ { 2, 4, 6, 8, 10 } };
REQUIRE_THROWS([&]() {
tlua.script(R"(
c_arr[-1] = 7
)");
}());
}
} }
TEST_CASE("containers/usertype-transparency", "Make sure containers pass their arguments through transparently and push the results as references, not new values") { TEST_CASE("containers/usertype-transparency", "Make sure containers pass their arguments through transparently and push the results as references, not new values") {