mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
new checker for unique_usertype to ensure type safety, when SOL_CHECK_ARGUMENTS or a protected tag is used to protect a function
This commit is contained in:
parent
51a03b2b35
commit
85620df63c
|
@ -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-06-12 14:43:06.223161 UTC
|
// Generated 2017-06-13 20:34:08.313723 UTC
|
||||||
// This header was generated with sol v2.17.5 (revision 50935ae)
|
// This header was generated with sol v2.17.5 (revision 51a03b2)
|
||||||
// https://github.com/ThePhD/sol2
|
// https://github.com/ThePhD/sol2
|
||||||
|
|
||||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||||
|
@ -5482,11 +5482,26 @@ namespace sol {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename X>
|
||||||
struct checker<T, type::userdata, std::enable_if_t<is_unique_usertype<T>::value>> {
|
struct checker<X, type::userdata, std::enable_if_t<is_unique_usertype<X>::value>> {
|
||||||
|
typedef typename unique_usertype_traits<X>::type T;
|
||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||||
return checker<typename unique_usertype_traits<T>::type, type::userdata>{}.check(L, index, std::forward<Handler>(handler), tracking);
|
const type indextype = type_of(L, index);
|
||||||
|
tracking.use(1);
|
||||||
|
if (indextype != type::userdata) {
|
||||||
|
handler(L, index, type::userdata, indextype);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (lua_getmetatable(L, index) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int metatableindex = lua_gettop(L);
|
||||||
|
if (stack_detail::check_metatable<detail::unique_usertype<T>>(L, metatableindex))
|
||||||
|
return true;
|
||||||
|
lua_pop(L, 1);
|
||||||
|
handler(L, index, type::userdata, indextype);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8213,7 +8228,7 @@ namespace sol {
|
||||||
|
|
||||||
template <typename Fx, typename... Fxs, std::size_t I, std::size_t... In, std::size_t... M, typename Match, typename... Args>
|
template <typename Fx, typename... Fxs, std::size_t I, std::size_t... In, std::size_t... M, typename Match, typename... Args>
|
||||||
inline int overload_match_arity(types<Fx, Fxs...>, std::index_sequence<I, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
inline int overload_match_arity(types<Fx, Fxs...>, std::index_sequence<I, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||||
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits;
|
typedef lua_bind_traits<meta::unwrap_unqualified_t<Fx>> traits;
|
||||||
typedef meta::tuple_types<typename traits::return_type> return_types;
|
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||||
typedef typename traits::free_args_list args_list;
|
typedef typename traits::free_args_list args_list;
|
||||||
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||||
|
@ -8237,7 +8252,7 @@ namespace sol {
|
||||||
|
|
||||||
template <typename Fx, std::size_t I, std::size_t... M, typename Match, typename... Args>
|
template <typename Fx, std::size_t I, std::size_t... M, typename Match, typename... Args>
|
||||||
inline int overload_match_arity_single(types<Fx>, std::index_sequence<I>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
inline int overload_match_arity_single(types<Fx>, std::index_sequence<I>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||||
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits;
|
typedef lua_bind_traits<meta::unwrap_unqualified_t<Fx>> traits;
|
||||||
typedef meta::tuple_types<typename traits::return_type> return_types;
|
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||||
typedef typename traits::free_args_list args_list;
|
typedef typename traits::free_args_list args_list;
|
||||||
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||||
|
@ -8252,7 +8267,7 @@ namespace sol {
|
||||||
|
|
||||||
template <typename Fx, typename Fx1, typename... Fxs, std::size_t I, std::size_t I1, std::size_t... In, std::size_t... M, typename Match, typename... Args>
|
template <typename Fx, typename Fx1, typename... Fxs, std::size_t I, std::size_t I1, std::size_t... In, std::size_t... M, typename Match, typename... Args>
|
||||||
inline int overload_match_arity_single(types<Fx, Fx1, Fxs...>, std::index_sequence<I, I1, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
inline int overload_match_arity_single(types<Fx, Fx1, Fxs...>, std::index_sequence<I, I1, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||||
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits;
|
typedef lua_bind_traits<meta::unwrap_unqualified_t<Fx>> traits;
|
||||||
typedef meta::tuple_types<typename traits::return_type> return_types;
|
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||||
typedef typename traits::free_args_list args_list;
|
typedef typename traits::free_args_list args_list;
|
||||||
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||||
|
@ -8400,6 +8415,13 @@ namespace sol {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||||
|
struct agnostic_lua_call_wrapper<std::reference_wrapper<T>, is_index, is_variable, checked, boost, C> {
|
||||||
|
static int call(lua_State* L, std::reference_wrapper<T> f) {
|
||||||
|
return agnostic_lua_call_wrapper<T, is_index, is_variable, checked, boost>{}.call(L, f.get());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked = stack::stack_detail::default_check_arguments, int boost = 0, typename = void>
|
template <typename T, typename F, bool is_index, bool is_variable, bool checked = stack::stack_detail::default_check_arguments, int boost = 0, typename = void>
|
||||||
struct lua_call_wrapper : agnostic_lua_call_wrapper<F, is_index, is_variable, checked, boost> {};
|
struct lua_call_wrapper : agnostic_lua_call_wrapper<F, is_index, is_variable, checked, boost> {};
|
||||||
|
|
||||||
|
|
13
sol/call.hpp
13
sol/call.hpp
|
@ -75,7 +75,7 @@ namespace sol {
|
||||||
|
|
||||||
template <typename Fx, typename... Fxs, std::size_t I, std::size_t... In, std::size_t... M, typename Match, typename... Args>
|
template <typename Fx, typename... Fxs, std::size_t I, std::size_t... In, std::size_t... M, typename Match, typename... Args>
|
||||||
inline int overload_match_arity(types<Fx, Fxs...>, std::index_sequence<I, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
inline int overload_match_arity(types<Fx, Fxs...>, std::index_sequence<I, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||||
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits;
|
typedef lua_bind_traits<meta::unwrap_unqualified_t<Fx>> traits;
|
||||||
typedef meta::tuple_types<typename traits::return_type> return_types;
|
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||||
typedef typename traits::free_args_list args_list;
|
typedef typename traits::free_args_list args_list;
|
||||||
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||||
|
@ -99,7 +99,7 @@ namespace sol {
|
||||||
|
|
||||||
template <typename Fx, std::size_t I, std::size_t... M, typename Match, typename... Args>
|
template <typename Fx, std::size_t I, std::size_t... M, typename Match, typename... Args>
|
||||||
inline int overload_match_arity_single(types<Fx>, std::index_sequence<I>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
inline int overload_match_arity_single(types<Fx>, std::index_sequence<I>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||||
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits;
|
typedef lua_bind_traits<meta::unwrap_unqualified_t<Fx>> traits;
|
||||||
typedef meta::tuple_types<typename traits::return_type> return_types;
|
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||||
typedef typename traits::free_args_list args_list;
|
typedef typename traits::free_args_list args_list;
|
||||||
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||||
|
@ -114,7 +114,7 @@ namespace sol {
|
||||||
|
|
||||||
template <typename Fx, typename Fx1, typename... Fxs, std::size_t I, std::size_t I1, std::size_t... In, std::size_t... M, typename Match, typename... Args>
|
template <typename Fx, typename Fx1, typename... Fxs, std::size_t I, std::size_t I1, std::size_t... In, std::size_t... M, typename Match, typename... Args>
|
||||||
inline int overload_match_arity_single(types<Fx, Fx1, Fxs...>, std::index_sequence<I, I1, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
inline int overload_match_arity_single(types<Fx, Fx1, Fxs...>, std::index_sequence<I, I1, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||||
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits;
|
typedef lua_bind_traits<meta::unwrap_unqualified_t<Fx>> traits;
|
||||||
typedef meta::tuple_types<typename traits::return_type> return_types;
|
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||||
typedef typename traits::free_args_list args_list;
|
typedef typename traits::free_args_list args_list;
|
||||||
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||||
|
@ -262,6 +262,13 @@ namespace sol {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||||
|
struct agnostic_lua_call_wrapper<std::reference_wrapper<T>, is_index, is_variable, checked, boost, C> {
|
||||||
|
static int call(lua_State* L, std::reference_wrapper<T> f) {
|
||||||
|
return agnostic_lua_call_wrapper<T, is_index, is_variable, checked, boost>{}.call(L, f.get());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked = stack::stack_detail::default_check_arguments, int boost = 0, typename = void>
|
template <typename T, typename F, bool is_index, bool is_variable, bool checked = stack::stack_detail::default_check_arguments, int boost = 0, typename = void>
|
||||||
struct lua_call_wrapper : agnostic_lua_call_wrapper<F, is_index, is_variable, checked, boost> {};
|
struct lua_call_wrapper : agnostic_lua_call_wrapper<F, is_index, is_variable, checked, boost> {};
|
||||||
|
|
||||||
|
|
|
@ -414,11 +414,26 @@ namespace sol {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename X>
|
||||||
struct checker<T, type::userdata, std::enable_if_t<is_unique_usertype<T>::value>> {
|
struct checker<X, type::userdata, std::enable_if_t<is_unique_usertype<X>::value>> {
|
||||||
|
typedef typename unique_usertype_traits<X>::type T;
|
||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||||
return checker<typename unique_usertype_traits<T>::type, type::userdata>{}.check(L, index, std::forward<Handler>(handler), tracking);
|
const type indextype = type_of(L, index);
|
||||||
|
tracking.use(1);
|
||||||
|
if (indextype != type::userdata) {
|
||||||
|
handler(L, index, type::userdata, indextype);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (lua_getmetatable(L, index) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int metatableindex = lua_gettop(L);
|
||||||
|
if (stack_detail::check_metatable<detail::unique_usertype<T>>(L, metatableindex))
|
||||||
|
return true;
|
||||||
|
lua_pop(L, 1);
|
||||||
|
handler(L, index, type::userdata, indextype);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1135,3 +1135,37 @@ TEST_CASE("functions/set_function-already-wrapped", "setting a function returned
|
||||||
REQUIRE_NOTHROW(lua.script("assert(test() == 5)"));
|
REQUIRE_NOTHROW(lua.script("assert(test() == 5)"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("functions/unique-overloading", "make sure overloading can work with ptr vs. specifically asking for a unique usertype") {
|
||||||
|
sol::state lua;
|
||||||
|
|
||||||
|
struct test { int special_value = 17; };
|
||||||
|
auto print_up_test = [](std::unique_ptr<test>& x) {
|
||||||
|
REQUIRE(x->special_value == 17);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto print_ptr_test = [](test* x) {
|
||||||
|
REQUIRE(x->special_value == 17);
|
||||||
|
};
|
||||||
|
|
||||||
|
lua.set_function("f", print_up_test);
|
||||||
|
lua.set_function("g", sol::overload(
|
||||||
|
std::ref(print_up_test),
|
||||||
|
print_ptr_test
|
||||||
|
));
|
||||||
|
|
||||||
|
lua["v1"] = std::make_unique<test>();
|
||||||
|
lua["v2"] = test{};
|
||||||
|
REQUIRE_NOTHROW([&]() {
|
||||||
|
lua.script("g(v1)");
|
||||||
|
}());
|
||||||
|
REQUIRE_NOTHROW([&]() {
|
||||||
|
lua.script("g(v2)");
|
||||||
|
}());
|
||||||
|
REQUIRE_NOTHROW([&]() {
|
||||||
|
lua.script("f(v1)");
|
||||||
|
}());
|
||||||
|
REQUIRE_THROWS([&]() {
|
||||||
|
lua.script("f(v2)");
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user