mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
"automatic usertypes" are now applied everywhere, regardless of what happens
new sol::filters (currently undocumented) new gc tests, new plain_type tests core abstractions over usertypes streamlined SOL_STRINGS_ARE_NUMBERS triggers added update single
This commit is contained in:
parent
488edd9cd1
commit
0c9d567d0a
|
@ -121,6 +121,7 @@ Thanks to `Eric (EToreo) for the suggestion on this one`_!
|
|||
|
||||
sol::load_result load(lua_Reader reader, void* data, const std::string& chunk_name = "[string]", load_mode mode = load_mode::any);
|
||||
sol::load_result load(const string_view& code, const std::string& chunk_name = "[string]", load_mode mode = load_mode::any);
|
||||
sol::load_result load_buffer(const char* buff, std::size_t buffsize, const std::string& chunk_name = "[string]", load_mode mode = load_mode::any);
|
||||
sol::load_result load_file(const std::string& filename, load_mode mode = load_mode::any);
|
||||
|
||||
These functions *load* the desired blob of either code that is in a string, or code that comes from a filename, on the ``lua_State*``. That blob will be turned into a Lua Function. It will not be run: it returns a ``load_result`` proxy that can be called to actually run the code, when you are ready. It can also be turned into a ``sol::function``, a ``sol::protected_function``, or some other abstraction that can serve to call the function. If it is called, it will run on the object's current ``lua_State*``: it is not isolated. If you need isolation, consider using :doc:`sol::environment<environment>`, creating a new state, or other Lua sandboxing techniques.
|
||||
|
|
|
@ -16,7 +16,14 @@ Note that you can obtain safety with regards to functions you bind by using the
|
|||
|
||||
``SOL_SAFE_FUNCTION`` triggers the following change:
|
||||
* All uses of ``sol::function`` and ``sol::stack_function`` will default to ``sol::protected_function`` and ``sol::stack_protected_function``, respectively, rather than ``sol::unsafe_function`` and ``sol::stack_unsafe_function``.
|
||||
* **Not** turned on by default under any detectible compiler settings: *you must turn this one on manually*
|
||||
* **Not** turned on by default under any detectible compiler settings: *you MUST turn this one on manually*
|
||||
|
||||
``SOL_STRINGS_ARE_NUMBERS`` triggers the following changes:
|
||||
* ``sol::stack::get`` and ``sol::stack::check_get`` will allow anything that Lua thinks is number-worthy to be number-worthy
|
||||
* This includes: integers, numbers, and strings
|
||||
* Does **not** include: booleans, types with ``__tostring`` enabled, and everything else
|
||||
* Overrides ``SOL_CHECK_ARGUMENTS`` and always applies if it is turned on
|
||||
* **Not** turned on by default under any settings: *you MUST be turned on manually*
|
||||
|
||||
``SOL_CHECK_ARGUMENTS`` triggers the following changes:
|
||||
* ``sol::stack::get`` (used everywhere) defaults to using ``sol::stack::check_get`` and dereferencing the argument. It uses ``sol::type_panic`` as the handler if something goes wrong
|
||||
|
|
1596
single/sol/sol.hpp
1596
single/sol/sol.hpp
File diff suppressed because it is too large
Load Diff
225
sol/call.hpp
225
sol/call.hpp
|
@ -25,14 +25,66 @@
|
|||
#include "protect.hpp"
|
||||
#include "wrapper.hpp"
|
||||
#include "property.hpp"
|
||||
#include "filters.hpp"
|
||||
#include "stack.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace usertype_detail {
|
||||
|
||||
} // usertype_detail
|
||||
|
||||
namespace filter_detail {
|
||||
template <int I, int... In>
|
||||
inline void handle_filter(static_stack_dependencies<I, In...>, lua_State* L, int&) {
|
||||
if (sizeof...(In) == 0) {
|
||||
return;
|
||||
}
|
||||
absolute_index ai(L, I);
|
||||
if (type_of(L, ai) != type::userdata) {
|
||||
return;
|
||||
}
|
||||
lua_createtable(L, static_cast<int>(sizeof...(In)), 0);
|
||||
stack_reference deps(L, -1);
|
||||
auto per_dep = [&L, &deps](int i) {
|
||||
lua_pushvalue(L, i);
|
||||
luaL_ref(L, deps.stack_index());
|
||||
};
|
||||
(void)per_dep;
|
||||
(void)detail::swallow{ int(), (per_dep(In), int())... };
|
||||
lua_setuservalue(L, ai);
|
||||
}
|
||||
|
||||
template <int... In>
|
||||
inline void handle_filter(returns_self_with<In...>, lua_State* L, int& pushed) {
|
||||
pushed = stack::push(L, raw_index(1));
|
||||
handle_filter(static_stack_dependencies<-1, In...>(), L, pushed);
|
||||
}
|
||||
|
||||
inline void handle_filter(const stack_dependencies& sdeps, lua_State* L, int&) {
|
||||
absolute_index ai(L, sdeps.target);
|
||||
if (type_of(L, ai) != type::userdata) {
|
||||
return;
|
||||
}
|
||||
lua_createtable(L, static_cast<int>(sdeps.size()), 0);
|
||||
stack_reference deps(L, -1);
|
||||
for (std::size_t i = 0; i < sdeps.size(); ++i) {
|
||||
lua_pushvalue(L, sdeps.stack_indices[i]);
|
||||
luaL_ref(L, deps.stack_index());
|
||||
}
|
||||
lua_setuservalue(L, ai);
|
||||
}
|
||||
|
||||
template <typename P, meta::disable<std::is_base_of<detail::filter_base_tag, meta::unqualified_t<P>>> = meta::enabler>
|
||||
inline void handle_filter(P&& p, lua_State* L, int& pushed) {
|
||||
pushed = std::forward<P>(p)(L, pushed);
|
||||
}
|
||||
} // filter_detail
|
||||
|
||||
namespace function_detail {
|
||||
inline int no_construction_error(lua_State* L) {
|
||||
return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)");
|
||||
}
|
||||
}
|
||||
} // function_detail
|
||||
|
||||
namespace call_detail {
|
||||
|
||||
|
@ -54,7 +106,7 @@ namespace sol {
|
|||
static void call(Args...) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
template <typename T, bool checked, bool clean_stack>
|
||||
struct constructor_match {
|
||||
T* obj;
|
||||
|
||||
|
@ -63,7 +115,7 @@ namespace sol {
|
|||
template <typename Fx, std::size_t I, typename... R, typename... Args>
|
||||
int operator()(types<Fx>, index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) const {
|
||||
detail::default_construct func{};
|
||||
return stack::call_into_lua<stack::stack_detail::default_check_arguments>(r, a, L, start, func, obj);
|
||||
return stack::call_into_lua<checked, clean_stack>(r, a, L, start, func, obj);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -149,7 +201,7 @@ namespace sol {
|
|||
return overload_match_arity<decltype(void_call<T, TypeLists>::call)...>(std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T, typename... TypeLists>
|
||||
template <typename T, bool checked, bool clean_stack, typename... TypeLists>
|
||||
inline int construct(lua_State* L) {
|
||||
static const auto& meta = usertype_traits<T>::metatable();
|
||||
int argcount = lua_gettop(L);
|
||||
|
@ -163,7 +215,7 @@ namespace sol {
|
|||
reference userdataref(L, -1);
|
||||
userdataref.pop();
|
||||
|
||||
construct_match<T, TypeLists...>(constructor_match<T>(obj), L, argcount, 1 + static_cast<int>(syntax));
|
||||
construct_match<T, TypeLists...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, 1 + static_cast<int>(syntax));
|
||||
|
||||
userdataref.push();
|
||||
luaL_getmetatable(L, &meta[0]);
|
||||
|
@ -176,7 +228,7 @@ namespace sol {
|
|||
return 1;
|
||||
}
|
||||
|
||||
template <typename F, bool is_index, bool is_variable, bool checked, int boost, typename = void>
|
||||
template <typename F, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename = void>
|
||||
struct agnostic_lua_call_wrapper {
|
||||
template <typename Fx, typename... Args>
|
||||
static int call(lua_State* L, Fx&& f, Args&&... args) {
|
||||
|
@ -184,23 +236,30 @@ namespace sol {
|
|||
typedef typename wrap::returns_list returns_list;
|
||||
typedef typename wrap::free_args_list args_list;
|
||||
typedef typename wrap::caller caller;
|
||||
return stack::call_into_lua<checked>(returns_list(), args_list(), L, boost + 1, caller(), std::forward<Fx>(f), std::forward<Args>(args)...);
|
||||
return stack::call_into_lua<checked, clean_stack>(returns_list(), args_list(), L, boost + 1, caller(), std::forward<Fx>(f), std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<var_wrapper<T>, true, is_variable, checked, boost, C> {
|
||||
template <typename T, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<var_wrapper<T>, true, is_variable, checked, boost, clean_stack, C> {
|
||||
template <typename F>
|
||||
static int call(lua_State* L, F&& f) {
|
||||
typedef is_stack_based<meta::unqualified_t<decltype(detail::unwrap(f.value))>> is_stack;
|
||||
if (clean_stack && !is_stack::value) {
|
||||
lua_settop(L, 0);
|
||||
}
|
||||
return stack::push_reference(L, detail::unwrap(f.value));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<var_wrapper<T>, false, is_variable, checked, boost, C> {
|
||||
template <typename T, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<var_wrapper<T>, false, is_variable, checked, boost, clean_stack, C> {
|
||||
template <typename V>
|
||||
static int call_assign(std::true_type, lua_State* L, V&& f) {
|
||||
detail::unwrap(f.value) = stack::get<meta::unwrapped_t<T>>(L, boost + (is_variable ? 3 : 1));
|
||||
if (clean_stack) {
|
||||
lua_settop(L, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -226,63 +285,63 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<lua_r_CFunction, is_index, is_variable, checked, boost, C> {
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<lua_r_CFunction, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
static int call(lua_State* L, lua_r_CFunction f) {
|
||||
return f(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<lua_CFunction, is_index, is_variable, checked, boost, C> {
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<lua_CFunction, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
static int call(lua_State* L, lua_CFunction f) {
|
||||
return f(L);
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<detail::lua_CFunction_noexcept, is_index, is_variable, checked, boost, C> {
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<detail::lua_CFunction_noexcept, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
static int call(lua_State* L, detail::lua_CFunction_noexcept f) {
|
||||
return f(L);
|
||||
}
|
||||
};
|
||||
#endif // noexcept function types
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<no_prop, is_index, is_variable, checked, boost, C> {
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<no_prop, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
static int call(lua_State* L, const no_prop&) {
|
||||
return luaL_error(L, is_index ? "sol: cannot read from a writeonly property" : "sol: cannot write to a readonly property");
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, checked, boost, C> {
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
static int call(lua_State* L, const no_construction&) {
|
||||
return function_detail::no_construction_error(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, checked, boost, C> {
|
||||
template <typename... Args, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
static int call(lua_State*, const bases<Args...>&) {
|
||||
// Uh. How did you even call this, lul
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
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> {
|
||||
template <typename T, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<std::reference_wrapper<T>, is_index, is_variable, checked, boost, clean_stack, 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());
|
||||
return agnostic_lua_call_wrapper<T, is_index, is_variable, checked, boost, clean_stack>{}.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>
|
||||
struct lua_call_wrapper : agnostic_lua_call_wrapper<F, is_index, is_variable, checked, boost> {};
|
||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked = stack::stack_detail::default_check_arguments, int boost = 0, bool clean_stack = true, typename = void>
|
||||
struct lua_call_wrapper : agnostic_lua_call_wrapper<F, is_index, is_variable, checked, boost, clean_stack> {};
|
||||
|
||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked, int boost>
|
||||
struct lua_call_wrapper<T, F, is_index, is_variable, checked, boost, std::enable_if_t<std::is_member_function_pointer<F>::value>> {
|
||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack>
|
||||
struct lua_call_wrapper<T, F, is_index, is_variable, checked, boost, clean_stack, std::enable_if_t<std::is_member_function_pointer<F>::value>> {
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::object_type object_type;
|
||||
|
||||
|
@ -291,7 +350,7 @@ namespace sol {
|
|||
typedef typename wrap::returns_list returns_list;
|
||||
typedef typename wrap::args_list args_list;
|
||||
typedef typename wrap::caller caller;
|
||||
return stack::call_into_lua<checked>(returns_list(), args_list(), L, boost + ( is_variable ? 3 : 2 ), caller(), std::forward<Fx>(f), o);
|
||||
return stack::call_into_lua<checked, clean_stack>(returns_list(), args_list(), L, boost + ( is_variable ? 3 : 2 ), caller(), std::forward<Fx>(f), o);
|
||||
}
|
||||
|
||||
template <typename Fx>
|
||||
|
@ -311,8 +370,8 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename F, bool is_variable, bool checked, int boost>
|
||||
struct lua_call_wrapper<T, F, false, is_variable, checked, boost, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
||||
template <typename T, typename F, bool is_variable, bool checked, int boost, bool clean_stack>
|
||||
struct lua_call_wrapper<T, F, false, is_variable, checked, boost, clean_stack, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
||||
typedef lua_bind_traits<F> traits_type;
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::object_type object_type;
|
||||
|
@ -321,7 +380,7 @@ namespace sol {
|
|||
static int call_assign(std::true_type, lua_State* L, V&& f, object_type& o) {
|
||||
typedef typename wrap::args_list args_list;
|
||||
typedef typename wrap::caller caller;
|
||||
return stack::call_into_lua<checked>(types<void>(), args_list(), L, boost + ( is_variable ? 3 : 2 ), caller(), f, o);
|
||||
return stack::call_into_lua<checked, clean_stack>(types<void>(), args_list(), L, boost + ( is_variable ? 3 : 2 ), caller(), f, o);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
|
@ -370,8 +429,8 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename F, bool is_variable, bool checked, int boost>
|
||||
struct lua_call_wrapper<T, F, true, is_variable, checked, boost, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
||||
template <typename T, typename F, bool is_variable, bool checked, int boost, bool clean_stack>
|
||||
struct lua_call_wrapper<T, F, true, is_variable, checked, boost, clean_stack, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
|
||||
typedef lua_bind_traits<F> traits_type;
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::object_type object_type;
|
||||
|
@ -381,7 +440,7 @@ namespace sol {
|
|||
typedef typename wrap::returns_list returns_list;
|
||||
typedef typename wrap::caller caller;
|
||||
F f(std::forward<V>(v));
|
||||
return stack::call_into_lua<checked>(returns_list(), types<>(), L, boost + ( is_variable ? 3 : 2 ), caller(), f, o);
|
||||
return stack::call_into_lua<checked, clean_stack>(returns_list(), types<>(), L, boost + ( is_variable ? 3 : 2 ), caller(), f, o);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
|
@ -404,8 +463,8 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename F, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, readonly_wrapper<F>, false, is_variable, checked, boost, C> {
|
||||
template <typename T, typename F, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, readonly_wrapper<F>, false, is_variable, checked, boost, clean_stack, C> {
|
||||
typedef lua_bind_traits<F> traits_type;
|
||||
typedef wrapper<meta::unqualified_t<F>> wrap;
|
||||
typedef typename wrap::object_type object_type;
|
||||
|
@ -421,13 +480,13 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename F, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, readonly_wrapper<F>, true, is_variable, checked, boost, C> : lua_call_wrapper<T, F, true, is_variable, checked, boost, C> {
|
||||
template <typename T, typename F, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, readonly_wrapper<F>, true, is_variable, checked, boost, clean_stack, C> : lua_call_wrapper<T, F, true, is_variable, checked, boost, clean_stack, C> {
|
||||
|
||||
};
|
||||
|
||||
template <typename T, typename... Args, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, constructor_list<Args...>, is_index, is_variable, checked, boost, C> {
|
||||
template <typename T, typename... Args, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, constructor_list<Args...>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
typedef constructor_list<Args...> F;
|
||||
|
||||
static int call(lua_State* L, F&) {
|
||||
|
@ -442,7 +501,7 @@ namespace sol {
|
|||
T* obj = reinterpret_cast<T*>(pointerpointer + 1);
|
||||
referencepointer = obj;
|
||||
|
||||
construct_match<T, Args...>(constructor_match<T>(obj), L, argcount, boost + 1 + static_cast<int>(syntax));
|
||||
construct_match<T, Args...>(constructor_match<T, false, clean_stack>(obj), L, argcount, boost + 1 + static_cast<int>(syntax));
|
||||
|
||||
userdataref.push();
|
||||
luaL_getmetatable(L, &metakey[0]);
|
||||
|
@ -456,8 +515,8 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Cxs, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, constructor_wrapper<Cxs...>, is_index, is_variable, checked, boost, C> {
|
||||
template <typename T, typename... Cxs, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, constructor_wrapper<Cxs...>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
typedef constructor_wrapper<Cxs...> F;
|
||||
|
||||
struct onmatch {
|
||||
|
@ -471,7 +530,7 @@ namespace sol {
|
|||
referencepointer = obj;
|
||||
|
||||
auto& func = std::get<I>(f.functions);
|
||||
stack::call_into_lua<checked>(r, a, L, boost + start, func, detail::implicit_wrapper<T>(obj));
|
||||
stack::call_into_lua<checked, clean_stack>(r, a, L, boost + start, func, detail::implicit_wrapper<T>(obj));
|
||||
|
||||
userdataref.push();
|
||||
luaL_getmetatable(L, &metakey[0]);
|
||||
|
@ -496,17 +555,17 @@ namespace sol {
|
|||
|
||||
};
|
||||
|
||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost>
|
||||
struct lua_call_wrapper<T, destructor_wrapper<Fx>, is_index, is_variable, checked, boost, std::enable_if_t<std::is_void<Fx>::value>> {
|
||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack>
|
||||
struct lua_call_wrapper<T, destructor_wrapper<Fx>, is_index, is_variable, checked, boost, clean_stack, std::enable_if_t<std::is_void<Fx>::value>> {
|
||||
typedef destructor_wrapper<Fx> F;
|
||||
|
||||
static int call(lua_State* L, const F&) {
|
||||
return detail::usertype_alloc_destroy<T>(L);
|
||||
return detail::usertype_alloc_destruct<T>(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost>
|
||||
struct lua_call_wrapper<T, destructor_wrapper<Fx>, is_index, is_variable, checked, boost, std::enable_if_t<!std::is_void<Fx>::value>> {
|
||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack>
|
||||
struct lua_call_wrapper<T, destructor_wrapper<Fx>, is_index, is_variable, checked, boost, clean_stack, std::enable_if_t<!std::is_void<Fx>::value>> {
|
||||
typedef destructor_wrapper<Fx> F;
|
||||
|
||||
static int call(lua_State* L, const F& f) {
|
||||
|
@ -516,8 +575,8 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, overload_set<Fs...>, is_index, is_variable, checked, boost, C> {
|
||||
template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, overload_set<Fs...>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
typedef overload_set<Fs...> F;
|
||||
|
||||
struct on_match {
|
||||
|
@ -533,15 +592,15 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, factory_wrapper<Fs...>, is_index, is_variable, checked, boost, C> {
|
||||
template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, factory_wrapper<Fs...>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
typedef factory_wrapper<Fs...> F;
|
||||
|
||||
struct on_match {
|
||||
template <typename Fx, std::size_t I, typename... R, typename... Args>
|
||||
int operator()(types<Fx>, index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int, F& fx) {
|
||||
auto& f = std::get<I>(fx.functions);
|
||||
return lua_call_wrapper<T, Fx, is_index, is_variable, checked, boost>{}.call(L, f);
|
||||
return lua_call_wrapper<T, Fx, is_index, is_variable, checked, boost, clean_stack>{}.call(L, f);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -550,8 +609,8 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename W, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, property_wrapper<R, W>, is_index, is_variable, checked, boost, C> {
|
||||
template <typename T, typename R, typename W, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, property_wrapper<R, W>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
typedef std::conditional_t<is_index, R, W> P;
|
||||
typedef meta::unqualified_t<P> U;
|
||||
typedef wrapper<U> wrap;
|
||||
|
@ -564,7 +623,7 @@ namespace sol {
|
|||
typedef typename traits_type::free_args_list args_list;
|
||||
typedef typename wrap::returns_list returns_list;
|
||||
typedef typename wrap::caller caller;
|
||||
return stack::call_into_lua<checked>(returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), f);
|
||||
return stack::call_into_lua<checked, clean_stack>(returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), f);
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
|
@ -585,7 +644,7 @@ namespace sol {
|
|||
#endif // Safety
|
||||
typedef typename wrap::returns_list returns_list;
|
||||
typedef typename wrap::caller caller;
|
||||
return stack::call_into_lua<checked>(returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), f, *o);
|
||||
return stack::call_into_lua<checked, clean_stack>(returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), f, *o);
|
||||
}
|
||||
|
||||
template <typename F, typename... Args>
|
||||
|
@ -596,7 +655,7 @@ namespace sol {
|
|||
template <typename F, typename... Args>
|
||||
static int defer_call(std::true_type, lua_State* L, F&& f, Args&&... args) {
|
||||
auto& p = pick(meta::boolean<is_index>(), std::forward<F>(f));
|
||||
return lua_call_wrapper<T, meta::unqualified_t<decltype(p)>, is_index, is_variable, checked, boost>{}.call(L, p, std::forward<Args>(args)...);
|
||||
return lua_call_wrapper<T, meta::unqualified_t<decltype(p)>, is_index, is_variable, checked, boost, clean_stack>{}.call(L, p, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename F, typename... Args>
|
||||
|
@ -613,33 +672,50 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename V, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, protect_t<V>, is_index, is_variable, checked, boost, C> {
|
||||
template <typename T, typename V, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, protect_t<V>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
typedef protect_t<V> F;
|
||||
|
||||
template <typename... Args>
|
||||
static int call(lua_State* L, F& fx, Args&&... args) {
|
||||
return lua_call_wrapper<T, V, is_index, is_variable, true, boost>{}.call(L, fx.value, std::forward<Args>(args)...);
|
||||
return lua_call_wrapper<T, V, is_index, is_variable, true, boost, clean_stack>{}.call(L, fx.value, std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Sig, typename P, bool is_index, bool is_variable, bool checked, int boost, typename C>
|
||||
struct lua_call_wrapper<T, function_arguments<Sig, P>, is_index, is_variable, checked, boost, C> {
|
||||
template <typename T, typename F, typename... Filters, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, filter_wrapper<F, Filters...>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
typedef filter_wrapper<F, Filters...> P;
|
||||
|
||||
template <std::size_t... In>
|
||||
static int call(std::index_sequence<In...>, lua_State* L, P& fx) {
|
||||
int pushed = lua_call_wrapper<T, F, is_index, is_variable, checked, boost, false, C>{}.call(L, fx.value);
|
||||
(void)detail::swallow{ int(), (filter_detail::handle_filter(std::get<In>(fx.filters), L, pushed), int())... };
|
||||
return pushed;
|
||||
}
|
||||
|
||||
static int call(lua_State* L, P& fx) {
|
||||
typedef typename P::indices indices;
|
||||
return call(indices(), L, fx);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Sig, typename P, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, function_arguments<Sig, P>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
template <typename F>
|
||||
static int call(lua_State* L, F&& f) {
|
||||
return lua_call_wrapper<T, meta::unqualified_t<P>, is_index, is_variable, stack::stack_detail::default_check_arguments, boost>{}.call(L, std::get<0>(f.arguments));
|
||||
return lua_call_wrapper<T, meta::unqualified_t<P>, is_index, is_variable, checked, boost, clean_stack>{}.call(L, std::get<0>(f.arguments));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool is_index, bool is_variable, int boost = 0, typename Fx, typename... Args>
|
||||
template <typename T, bool is_index, bool is_variable, int boost = 0, bool checked = stack::stack_detail::default_check_arguments, bool clean_stack = true, typename Fx, typename... Args>
|
||||
inline int call_wrapped(lua_State* L, Fx&& fx, Args&&... args) {
|
||||
return lua_call_wrapper<T, meta::unqualified_t<Fx>, is_index, is_variable, stack::stack_detail::default_check_arguments, boost>{}.call(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
return lua_call_wrapper<T, meta::unqualified_t<Fx>, is_index, is_variable, checked, boost, clean_stack>{}.call(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T, bool is_index, bool is_variable, typename F, int start = 1>
|
||||
template <typename T, bool is_index, bool is_variable, typename F, int start = 1, bool checked = stack::stack_detail::default_check_arguments, bool clean_stack = true>
|
||||
inline int call_user(lua_State* L) {
|
||||
auto& fx = stack::get<user<F>>(L, upvalue_index(start));
|
||||
return call_wrapped<T, is_index, is_variable>(L, fx);
|
||||
return call_wrapped<T, is_index, is_variable, 0, checked, clean_stack>(L, fx);
|
||||
}
|
||||
|
||||
template <typename T, typename = void>
|
||||
|
@ -658,7 +734,10 @@ namespace sol {
|
|||
struct is_var_bind<var_wrapper<T>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_var_bind<readonly_wrapper<T>> : is_var_bind<T> {};
|
||||
struct is_var_bind<readonly_wrapper<T>> : is_var_bind<meta::unqualified_t<T>> {};
|
||||
|
||||
template <typename F, typename... Filters>
|
||||
struct is_var_bind<filter_wrapper<F, Filters...>> : is_var_bind<meta::unqualified_t<F>> {};
|
||||
} // call_detail
|
||||
|
||||
template <typename T>
|
||||
|
|
|
@ -276,7 +276,7 @@ namespace sol {
|
|||
{ "add", &meta_cumt::add_call },
|
||||
{ "find", &meta_cumt::find_call },
|
||||
{ "erase", &meta_cumt::erase_call },
|
||||
std::is_pointer<T>::value ? luaL_Reg{ nullptr, nullptr } : luaL_Reg{ "__gc", &detail::usertype_alloc_destroy<T> },
|
||||
std::is_pointer<T>::value ? luaL_Reg{ nullptr, nullptr } : luaL_Reg{ "__gc", &detail::usertype_alloc_destruct<T> },
|
||||
{ nullptr, nullptr }
|
||||
} };
|
||||
|
||||
|
|
|
@ -88,8 +88,8 @@ namespace sol {
|
|||
name.replace(0, 6, "", 0);
|
||||
if (name.find("class", 0) == 0)
|
||||
name.replace(0, 5, "", 0);
|
||||
while (!name.empty() && std::isblank(name.front())) name.erase(name.begin());
|
||||
while (!name.empty() && std::isblank(name.back())) name.pop_back();
|
||||
while (!name.empty() && isblank(name.front())) name.erase(name.begin());
|
||||
while (!name.empty() && isblank(name.back())) name.pop_back();
|
||||
|
||||
for (std::size_t r = 0; r < removals.size(); ++r) {
|
||||
auto found = name.find(removals[r]);
|
||||
|
|
86
sol/filters.hpp
Normal file
86
sol/filters.hpp
Normal file
|
@ -0,0 +1,86 @@
|
|||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2017 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_FILTERS_HPP
|
||||
#define SOL_FILTERS_HPP
|
||||
|
||||
#include "traits.hpp"
|
||||
#include <array>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
struct filter_base_tag {};
|
||||
} // detail
|
||||
|
||||
template <int Target, int... In>
|
||||
struct static_stack_dependencies : detail::filter_base_tag {};
|
||||
typedef static_stack_dependencies<-1, 1> self_dependency;
|
||||
template <int... In>
|
||||
struct returns_self_with : detail::filter_base_tag {};
|
||||
typedef returns_self_with<> returns_self;
|
||||
|
||||
struct stack_dependencies : detail::filter_base_tag {
|
||||
int target;
|
||||
std::array<int, 64> stack_indices;
|
||||
std::size_t len;
|
||||
|
||||
template <typename... Args>
|
||||
stack_dependencies(int stack_target, Args&&... args) : target(stack_target), stack_indices(), len(sizeof...(Args)) {
|
||||
std::size_t i = 0;
|
||||
(void)detail::swallow{ int(), (stack_indices[i++] = static_cast<int>(std::forward<Args>(args)), int() )... };
|
||||
}
|
||||
|
||||
int& operator[] (std::size_t i) {
|
||||
return stack_indices[i];
|
||||
}
|
||||
|
||||
const int& operator[] (std::size_t i) const {
|
||||
return stack_indices[i];
|
||||
}
|
||||
|
||||
std::size_t size() const {
|
||||
return len;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F, typename... Filters>
|
||||
struct filter_wrapper {
|
||||
typedef std::make_integer_sequence<std::size_t, sizeof...(Filters)> indices;
|
||||
|
||||
F value;
|
||||
std::tuple<Filters...> filters;
|
||||
|
||||
template <typename Fx, typename... Args, meta::enable<meta::neg<std::is_same<meta::unqualified_t<Fx>, filter_wrapper>>> = meta::enabler>
|
||||
filter_wrapper(Fx&& fx, Args&&... args) : value(std::forward<Fx>(fx)), filters(std::forward<Args>(args)...) {}
|
||||
|
||||
filter_wrapper(const filter_wrapper&) = default;
|
||||
filter_wrapper& operator=(const filter_wrapper&) = default;
|
||||
filter_wrapper(filter_wrapper&&) = default;
|
||||
filter_wrapper& operator=(filter_wrapper&&) = default;
|
||||
};
|
||||
|
||||
template <typename F, typename... Args>
|
||||
auto filters(F&& f, Args&&... args) {
|
||||
return filter_wrapper<std::decay_t<F>, std::decay_t<Args>...>( std::forward<F>(f), std::forward<Args>(args)... );
|
||||
}
|
||||
} // sol
|
||||
|
||||
#endif // SOL_FILTERS_HPP
|
|
@ -110,7 +110,10 @@ namespace sol {
|
|||
struct user;
|
||||
template <typename T>
|
||||
struct as_args_t;
|
||||
|
||||
template <typename T>
|
||||
struct protect_t;
|
||||
template <typename F, typename... Filters>
|
||||
struct filter_wrapper;
|
||||
} // sol
|
||||
|
||||
#endif // SOL_FORWARD_HPP
|
||||
|
|
54
sol/forward_detail.hpp
Normal file
54
sol/forward_detail.hpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2017 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_FORWARD_DETAIL_HPP
|
||||
#define SOL_FORWARD_DETAIL_HPP
|
||||
|
||||
#include "feature_test.hpp"
|
||||
#include "forward.hpp"
|
||||
#include "traits.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace meta {
|
||||
namespace meta_detail {
|
||||
|
||||
} // meta_detail
|
||||
} // meta
|
||||
|
||||
namespace stack {
|
||||
namespace stack_detail {
|
||||
template <typename T>
|
||||
struct undefined_metatable;
|
||||
} // stack_detail
|
||||
} // stack
|
||||
|
||||
namespace usertype_detail {
|
||||
template <typename T, typename Regs, typename Fx>
|
||||
void insert_default_registrations(Regs& l, int& index, Fx&& fx);
|
||||
|
||||
template <typename T, typename Regs, meta::enable<meta::neg<std::is_pointer<T>>, std::is_destructible<T>> = meta::enabler>
|
||||
void make_destructor(Regs& l, int& index);
|
||||
template <typename T, typename Regs, meta::disable<meta::neg<std::is_pointer<T>>, std::is_destructible<T>> = meta::enabler>
|
||||
void make_destructor(Regs& l, int& index);
|
||||
} // usertype_detail
|
||||
} // sol
|
||||
|
||||
#endif // SOL_FORWARD_DETAIL_HPP
|
|
@ -391,7 +391,7 @@ namespace sol {
|
|||
template <typename T, typename... Lists>
|
||||
struct pusher<detail::tagged<T, constructor_list<Lists...>>> {
|
||||
static int push(lua_State* L, detail::tagged<T, constructor_list<Lists...>>) {
|
||||
lua_CFunction cf = call_detail::construct<T, Lists...>;
|
||||
lua_CFunction cf = call_detail::construct<T, stack_detail::default_check_arguments, true, Lists...>;
|
||||
return stack::push(L, cf);
|
||||
}
|
||||
};
|
||||
|
@ -411,7 +411,7 @@ namespace sol {
|
|||
template <typename T>
|
||||
struct pusher<detail::tagged<T, destructor_wrapper<void>>> {
|
||||
static int push(lua_State* L, destructor_wrapper<void>) {
|
||||
lua_CFunction cf = detail::usertype_alloc_destroy<T>;
|
||||
lua_CFunction cf = detail::usertype_alloc_destruct<T>;
|
||||
return stack::push(L, cf);
|
||||
}
|
||||
};
|
||||
|
@ -427,6 +427,26 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename F, typename... Filters>
|
||||
struct pusher<filter_wrapper<F, Filters...>> {
|
||||
typedef filter_wrapper<F, Filters...> P;
|
||||
|
||||
static int push(lua_State* L, const P& p) {
|
||||
lua_CFunction cf = call_detail::call_user<void, false, false, P, 2>;
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<P>>(L, p);
|
||||
return stack::push(L, c_closure(cf, upvalues));
|
||||
}
|
||||
|
||||
static int push(lua_State* L, P&& p) {
|
||||
lua_CFunction cf = call_detail::call_user<void, false, false, P, 2>;
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<P>>(L, std::move(p));
|
||||
return stack::push(L, c_closure(cf, upvalues));
|
||||
}
|
||||
};
|
||||
} // stack
|
||||
} // sol
|
||||
|
||||
|
|
|
@ -43,6 +43,19 @@ namespace sol {
|
|||
tbl.traverse_set(std::get<I>(key)..., std::forward<T>(value));
|
||||
}
|
||||
|
||||
auto setup_table(std::true_type) {
|
||||
auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(lua_state(), key, tbl.stack_index());
|
||||
lua_pop(lua_state(), p.levels);
|
||||
return p;
|
||||
}
|
||||
|
||||
bool is_valid(std::false_type) {
|
||||
auto pp = stack::push_pop(tbl);
|
||||
auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(lua_state(), key, lua_gettop(lua_state()));
|
||||
lua_pop(lua_state(), p.levels);
|
||||
return p;
|
||||
}
|
||||
|
||||
public:
|
||||
Table tbl;
|
||||
key_type key;
|
||||
|
|
|
@ -22,9 +22,10 @@
|
|||
#ifndef SOL_RAII_HPP
|
||||
#define SOL_RAII_HPP
|
||||
|
||||
#include <memory>
|
||||
#include "traits.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
struct default_construct {
|
||||
|
|
|
@ -69,17 +69,23 @@ namespace sol {
|
|||
struct push_popper_n<true> {
|
||||
push_popper_n(lua_State*, int) { }
|
||||
};
|
||||
template <bool top_level, typename T>
|
||||
template <bool, typename T, typename = void>
|
||||
struct push_popper {
|
||||
T t;
|
||||
push_popper(T x) : t(x) { t.push(); }
|
||||
~push_popper() { t.pop(); }
|
||||
};
|
||||
template <typename T>
|
||||
struct push_popper<true, T> {
|
||||
template <typename T, typename C>
|
||||
struct push_popper<true, T, C> {
|
||||
push_popper(T) {}
|
||||
~push_popper() {}
|
||||
};
|
||||
template <typename T>
|
||||
struct push_popper<false, T, std::enable_if_t<std::is_base_of<stack_reference, meta::unqualified_t<T>>::value>> {
|
||||
push_popper(T) {}
|
||||
~push_popper() {}
|
||||
};
|
||||
|
||||
template <bool top_level = false, typename T>
|
||||
push_popper<top_level, T> push_pop(T&& x) {
|
||||
return push_popper<top_level, T>(std::forward<T>(x));
|
||||
|
|
|
@ -322,7 +322,7 @@ namespace sol {
|
|||
|
||||
private:
|
||||
template<std::size_t... I, typename Tuple>
|
||||
simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
|
||||
simple_usertype_metatable(detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
|
||||
: callconstructfunc(lua_nil),
|
||||
indexfunc(lua_nil), newindexfunc(lua_nil),
|
||||
indexbase(&usertype_detail::simple_core_indexing_call<T, true>), newindexbase(&usertype_detail::simple_core_indexing_call<T, false>),
|
||||
|
@ -337,33 +337,33 @@ namespace sol {
|
|||
}
|
||||
|
||||
template<typename... Args>
|
||||
simple_usertype_metatable(lua_State* L, usertype_detail::verified_tag v, Args&&... args) : simple_usertype_metatable(v, std::make_index_sequence<sizeof...(Args) / 2>(), L, std::forward_as_tuple(std::forward<Args>(args)...)) {}
|
||||
simple_usertype_metatable(lua_State* L, detail::verified_tag v, Args&&... args) : simple_usertype_metatable(v, std::make_index_sequence<sizeof...(Args) / 2>(), L, std::forward_as_tuple(std::forward<Args>(args)...)) {}
|
||||
|
||||
template<typename... Args>
|
||||
simple_usertype_metatable(lua_State* L, usertype_detail::add_destructor_tag, Args&&... args) : simple_usertype_metatable(L, usertype_detail::verified, std::forward<Args>(args)..., "__gc", default_destructor) {}
|
||||
simple_usertype_metatable(lua_State* L, detail::add_destructor_tag, Args&&... args) : simple_usertype_metatable(L, detail::verified, std::forward<Args>(args)..., "__gc", default_destructor) {}
|
||||
|
||||
template<typename... Args>
|
||||
simple_usertype_metatable(lua_State* L, usertype_detail::check_destructor_tag, Args&&... args) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_destructible<T>, meta::neg<usertype_detail::has_destructor<Args...>>>, usertype_detail::add_destructor_tag, usertype_detail::verified_tag>(), std::forward<Args>(args)...) {}
|
||||
simple_usertype_metatable(lua_State* L, detail::check_destructor_tag, Args&&... args) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_destructible<T>, meta::neg<detail::has_destructor<Args...>>>, detail::add_destructor_tag, detail::verified_tag>(), std::forward<Args>(args)...) {}
|
||||
|
||||
public:
|
||||
simple_usertype_metatable(lua_State* L) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_default_constructible<T>>, decltype(default_constructor), usertype_detail::check_destructor_tag>()) {}
|
||||
simple_usertype_metatable(lua_State* L) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_default_constructible<T>>, decltype(default_constructor), detail::check_destructor_tag>()) {}
|
||||
|
||||
template<typename Arg, typename... Args, meta::disable_any<
|
||||
meta::any_same<meta::unqualified_t<Arg>,
|
||||
usertype_detail::verified_tag,
|
||||
usertype_detail::add_destructor_tag,
|
||||
usertype_detail::check_destructor_tag
|
||||
detail::verified_tag,
|
||||
detail::add_destructor_tag,
|
||||
detail::check_destructor_tag
|
||||
>,
|
||||
meta::is_specialization_of<constructors, meta::unqualified_t<Arg>>,
|
||||
meta::is_specialization_of<constructor_wrapper, meta::unqualified_t<Arg>>
|
||||
> = meta::enabler>
|
||||
simple_usertype_metatable(lua_State* L, Arg&& arg, Args&&... args) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_default_constructible<T>, meta::neg<usertype_detail::has_constructor<Args...>>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), std::forward<Arg>(arg), std::forward<Args>(args)...) {}
|
||||
simple_usertype_metatable(lua_State* L, Arg&& arg, Args&&... args) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_default_constructible<T>, meta::neg<detail::has_constructor<Args...>>>, decltype(default_constructor), detail::check_destructor_tag>(), std::forward<Arg>(arg), std::forward<Args>(args)...) {}
|
||||
|
||||
template<typename... Args, typename... CArgs>
|
||||
simple_usertype_metatable(lua_State* L, constructors<CArgs...> constructorlist, Args&&... args) : simple_usertype_metatable(L, usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
simple_usertype_metatable(lua_State* L, constructors<CArgs...> constructorlist, Args&&... args) : simple_usertype_metatable(L, detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
|
||||
template<typename... Args, typename... Fxs>
|
||||
simple_usertype_metatable(lua_State* L, constructor_wrapper<Fxs...> constructorlist, Args&&... args) : simple_usertype_metatable(L, usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
simple_usertype_metatable(lua_State* L, constructor_wrapper<Fxs...> constructorlist, Args&&... args) : simple_usertype_metatable(L, detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
|
||||
simple_usertype_metatable(const simple_usertype_metatable&) = default;
|
||||
simple_usertype_metatable(simple_usertype_metatable&&) = default;
|
||||
|
@ -420,18 +420,18 @@ namespace sol {
|
|||
for (std::size_t i = 1; i < properties.size(); ++i) {
|
||||
mf = static_cast<meta_function>(i);
|
||||
const std::string& mfname = to_string(mf);
|
||||
if (mfname == first) {
|
||||
properties[i] = true;
|
||||
switch (mf) {
|
||||
case meta_function::index:
|
||||
umx.indexfunc = second;
|
||||
break;
|
||||
case meta_function::new_index:
|
||||
umx.newindexfunc = second;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (mfname != first)
|
||||
continue;
|
||||
properties[i] = true;
|
||||
switch (mf) {
|
||||
case meta_function::index:
|
||||
umx.indexfunc = second;
|
||||
break;
|
||||
case meta_function::new_index:
|
||||
umx.newindexfunc = second;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -474,34 +474,10 @@ namespace sol {
|
|||
auto& second = std::get<1>(kvp);
|
||||
register_kvp(i, t, first, second);
|
||||
}
|
||||
luaL_Reg opregs[29]{};
|
||||
luaL_Reg opregs[32]{};
|
||||
int opregsindex = 0;
|
||||
if (!properties[static_cast<int>(meta_function::less_than)]) {
|
||||
const char* name = to_string(meta_function::less_than).c_str();
|
||||
usertype_detail::make_reg_op<T, std::less<>, meta::supports_op_less<T>>(opregs, opregsindex, name);
|
||||
}
|
||||
if (!properties[static_cast<int>(meta_function::less_than_or_equal_to)]) {
|
||||
const char* name = to_string(meta_function::less_than_or_equal_to).c_str();
|
||||
usertype_detail::make_reg_op<T, std::less_equal<>, meta::supports_op_less_equal<T>>(opregs, opregsindex, name);
|
||||
}
|
||||
if (!properties[static_cast<int>(meta_function::equal_to)]) {
|
||||
const char* name = to_string(meta_function::equal_to).c_str();
|
||||
usertype_detail::make_reg_op<T, std::conditional_t<meta::supports_op_equal<T>::value, std::equal_to<>, usertype_detail::no_comp>, std::true_type>(opregs, opregsindex, name);
|
||||
}
|
||||
if (!properties[static_cast<int>(meta_function::pairs)]) {
|
||||
const char* name = to_string(meta_function::pairs).c_str();
|
||||
opregs[opregsindex] = { name, container_usertype_metatable<as_container_t<T>>::pairs_call };
|
||||
++opregsindex;
|
||||
}
|
||||
if (!properties[static_cast<int>(meta_function::length)]) {
|
||||
usertype_detail::make_length_op<T>(opregs, opregsindex);
|
||||
}
|
||||
if (!properties[static_cast<int>(meta_function::to_string)]) {
|
||||
usertype_detail::make_to_string_op<T, meta::supports_ostream_op<T>>(opregs, opregsindex);
|
||||
}
|
||||
if (!properties[static_cast<int>(meta_function::call)]) {
|
||||
usertype_detail::make_call_op<T>(opregs, opregsindex);
|
||||
}
|
||||
auto prop_fx = [&](meta_function mf) { return !properties[static_cast<int>(mf)]; };
|
||||
usertype_detail::insert_default_registrations<T>(opregs, opregsindex, prop_fx);
|
||||
t.push();
|
||||
luaL_setfuncs(L, opregs, 0);
|
||||
t.pop();
|
||||
|
|
|
@ -159,34 +159,41 @@ namespace sol {
|
|||
|
||||
template <bool check_args = stack_detail::default_check_arguments, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
|
||||
inline decltype(auto) call_from_top(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
|
||||
return call<check_args>(tr, ta, L, static_cast<int>(lua_gettop(L) - sizeof...(Args)), std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
||||
typedef meta::count_for_pack<lua_size, Args...> expected_count;
|
||||
return call<check_args>(tr, ta, L, (std::max)(static_cast<int>(lua_gettop(L) - expected_count::value), static_cast<int>(0)), std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
||||
}
|
||||
|
||||
template <bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
|
||||
inline void call_from_top(types<void> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
|
||||
call<check_args>(tr, ta, L, static_cast<int>(lua_gettop(L) - sizeof...(Args)), std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
||||
typedef meta::count_for_pack<lua_size, Args...> expected_count;
|
||||
call<check_args>(tr, ta, L, (std::max)(static_cast<int>(lua_gettop(L) - expected_count::value), static_cast<int>(0)), std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
||||
}
|
||||
|
||||
template<bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
|
||||
template<bool check_args = stack_detail::default_check_arguments, bool clean_stack = true, typename... Args, typename Fx, typename... FxArgs>
|
||||
inline int call_into_lua(types<void> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
|
||||
call<check_args>(tr, ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
||||
lua_settop(L, 0);
|
||||
if (clean_stack) {
|
||||
lua_settop(L, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<bool check_args = stack_detail::default_check_arguments, typename Ret0, typename... Ret, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<meta::neg<std::is_void<Ret0>>::value>>
|
||||
template<bool check_args = stack_detail::default_check_arguments, bool clean_stack = true, typename Ret0, typename... Ret, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<meta::neg<std::is_void<Ret0>>::value>>
|
||||
inline int call_into_lua(types<Ret0, Ret...>, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
|
||||
decltype(auto) r = call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
||||
lua_settop(L, 0);
|
||||
typedef is_stack_based<meta::unqualified_t<decltype(r)>> is_stack;
|
||||
if (clean_stack && !is_stack::value) {
|
||||
lua_settop(L, 0);
|
||||
}
|
||||
return push_reference(L, std::forward<decltype(r)>(r));
|
||||
}
|
||||
|
||||
template<bool check_args = stack_detail::default_check_arguments, typename Fx, typename... FxArgs>
|
||||
template<bool check_args = stack_detail::default_check_arguments, bool clean_stack = true, typename Fx, typename... FxArgs>
|
||||
inline int call_lua(lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
|
||||
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits_type;
|
||||
typedef typename traits_type::args_list args_list;
|
||||
typedef typename traits_type::returns_list returns_list;
|
||||
return call_into_lua<check_args>(returns_list(), args_list(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
||||
return call_into_lua<check_args, clean_stack>(returns_list(), args_list(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
||||
}
|
||||
|
||||
inline call_syntax get_call_syntax(lua_State* L, const std::string& key, int index) {
|
||||
|
|
|
@ -87,18 +87,45 @@ namespace sol {
|
|||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
if (lua_isinteger(L, index) != 0) {
|
||||
#ifdef SOL_STRINGS_ARE_NUMBERS
|
||||
int isnum = 0;
|
||||
lua_tointegerx(L, index, &isnum);
|
||||
const bool success = isnum != 0;
|
||||
#else
|
||||
// this check is precise, does not convert
|
||||
if (lua_isinteger(L, index) == 1) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
int isnum = 0;
|
||||
const lua_Number v = lua_tonumberx(L, index, &isnum);
|
||||
const bool success = isnum != 0 && static_cast<lua_Number>(std::llround(v)) == v;
|
||||
const bool success = false;
|
||||
#endif // If numbers are enabled, use the imprecise check
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, type_of(L, index));
|
||||
}
|
||||
return success;
|
||||
#else
|
||||
#ifndef SOL_STRINGS_ARE_NUMBERS
|
||||
// must pre-check, because it will convert
|
||||
type t = type_of(L, index);
|
||||
if (t != type::number) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, t);
|
||||
return false;
|
||||
}
|
||||
#endif // Do not allow strings to be numbers
|
||||
int isnum = 0;
|
||||
const lua_Number v = lua_tonumberx(L, index, &isnum);
|
||||
const bool success = isnum != 0 && static_cast<lua_Number>(llround(v)) == v;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
#ifndef SOL_STRINGS_ARE_NUMBERS
|
||||
handler(L, index, type::number, t);
|
||||
#else
|
||||
handler(L, index, type::number, type_of(L, index));
|
||||
#endif
|
||||
}
|
||||
return success;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -107,12 +134,22 @@ namespace sol {
|
|||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
#ifdef SOL_STRINGS_ARE_NUMBERS
|
||||
type t = type_of(L, index);
|
||||
bool success = t == type::number;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, t);
|
||||
}
|
||||
return success;
|
||||
#else
|
||||
bool success = lua_isnumber(L, index) == 1;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, type_of(L, index));
|
||||
}
|
||||
return success;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace sol {
|
|||
const lua_Number value = lua_tonumberx(L, index, &isnum);
|
||||
if (isnum != 0) {
|
||||
#if 1 // defined(SOL_CHECK_ARGUMENTS) && !defined(SOL_NO_CHECK_NUMBER_PRECISION)
|
||||
const auto integer_value = std::llround(value);
|
||||
const auto integer_value = llround(value);
|
||||
if (static_cast<lua_Number>(integer_value) == value) {
|
||||
tracking.use(1);
|
||||
return static_cast<T>(integer_value);
|
||||
|
|
|
@ -29,9 +29,13 @@
|
|||
#include "traits.hpp"
|
||||
#include "tie.hpp"
|
||||
#include "stack_guard.hpp"
|
||||
#include "demangle.hpp"
|
||||
#include "forward_detail.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <forward_list>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
|
@ -52,17 +56,8 @@ namespace sol {
|
|||
return 0;
|
||||
}
|
||||
|
||||
template <typename T, typename Real>
|
||||
inline void usertype_unique_alloc_destroy(void* memory) {
|
||||
T** pointerpointer = static_cast<T**>(memory);
|
||||
unique_destructor* dx = static_cast<unique_destructor*>(static_cast<void*>(pointerpointer + 1));
|
||||
Real* target = static_cast<Real*>(static_cast<void*>(dx + 1));
|
||||
std::allocator<Real> alloc;
|
||||
alloc.destroy(target);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline int user_alloc_destroy(lua_State* L) {
|
||||
inline int user_alloc_destruct(lua_State* L) {
|
||||
void* rawdata = lua_touserdata(L, 1);
|
||||
T* data = static_cast<T*>(rawdata);
|
||||
std::allocator<T> alloc;
|
||||
|
@ -71,7 +66,7 @@ namespace sol {
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
inline int usertype_alloc_destroy(lua_State* L) {
|
||||
inline int usertype_alloc_destruct(lua_State* L) {
|
||||
void* rawdata = lua_touserdata(L, 1);
|
||||
T** pdata = static_cast<T**>(rawdata);
|
||||
T* data = *pdata;
|
||||
|
@ -80,6 +75,20 @@ namespace sol {
|
|||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline int cannot_destruct(lua_State* L) {
|
||||
return luaL_error(L, "cannot call the destructor for '%s': it is either hidden (protected/private) or removed with '= delete' and thusly this type is being destroyed without properly destructing, invoking undefined behavior", detail::demangle<T>().data());
|
||||
}
|
||||
|
||||
template <typename T, typename Real>
|
||||
inline void usertype_unique_alloc_destroy(void* memory) {
|
||||
T** pointerpointer = static_cast<T**>(memory);
|
||||
unique_destructor* dx = static_cast<unique_destructor*>(static_cast<void*>(pointerpointer + 1));
|
||||
Real* target = static_cast<Real*>(static_cast<void*>(dx + 1));
|
||||
std::allocator<Real> alloc;
|
||||
alloc.destroy(target);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void reserve(T&, std::size_t) {}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace sol {
|
|||
return static_cast<T>(lua_tointeger(L, index));
|
||||
}
|
||||
#endif
|
||||
return static_cast<T>(std::llround(lua_tonumber(L, index)));
|
||||
return static_cast<T>(llround(lua_tonumber(L, index)));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "raii.hpp"
|
||||
#include "optional.hpp"
|
||||
#include "usertype_traits.hpp"
|
||||
#include "filters.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
@ -83,10 +85,8 @@ namespace sol {
|
|||
|
||||
template <typename K, typename... Args>
|
||||
static int push_keyed(lua_State* L, K&& k, Args&&... args) {
|
||||
return push_fx(L, [&L, &k]() {
|
||||
luaL_newmetatable(L, &k[0]);
|
||||
lua_setmetatable(L, -2);
|
||||
}, std::forward<Args>(args)...);
|
||||
stack_detail::undefined_metatable<T> fx(L, &k[0]);
|
||||
return push_fx(L, fx, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
|
@ -97,6 +97,8 @@ namespace sol {
|
|||
|
||||
template <typename T>
|
||||
struct pusher<detail::as_pointer_tag<T>> {
|
||||
typedef meta::unqualified_t<T> U;
|
||||
|
||||
template <typename F>
|
||||
static int push_fx(lua_State* L, F&& f, T* obj) {
|
||||
if (obj == nullptr)
|
||||
|
@ -109,14 +111,12 @@ namespace sol {
|
|||
|
||||
template <typename K>
|
||||
static int push_keyed(lua_State* L, K&& k, T* obj) {
|
||||
return push_fx(L, [&L, &k]() {
|
||||
luaL_newmetatable(L, &k[0]);
|
||||
lua_setmetatable(L, -2);
|
||||
}, obj);
|
||||
stack_detail::undefined_metatable<U*> fx(L, &k[0]);
|
||||
return push_fx(L, fx, obj);
|
||||
}
|
||||
|
||||
static int push(lua_State* L, T* obj) {
|
||||
return push_keyed(L, usertype_traits<meta::unqualified_t<T>*>::metatable(), obj);
|
||||
return push_keyed(L, usertype_traits<U*>::metatable(), obj);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -171,7 +171,12 @@ namespace sol {
|
|||
detail::default_construct::construct(mem, std::forward<Args>(args)...);
|
||||
*pref = unique_usertype_traits<T>::get(*mem);
|
||||
if (luaL_newmetatable(L, &usertype_traits<detail::unique_usertype<P>>::metatable()[0]) == 1) {
|
||||
set_field(L, "__gc", detail::unique_destruct<P>);
|
||||
luaL_Reg l[32]{};
|
||||
int index = 0;
|
||||
auto prop_fx = [](meta_function) { return true; };
|
||||
usertype_detail::insert_default_registrations<P>(l, index, prop_fx);
|
||||
usertype_detail::make_destructor<T>(l, index);
|
||||
luaL_setfuncs(L, l, 0);
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
|
@ -213,7 +218,7 @@ namespace sol {
|
|||
}
|
||||
#endif
|
||||
#if defined(SOL_CHECK_ARGUMENTS) && !defined(SOL_NO_CHECK_NUMBER_PRECISION)
|
||||
if (static_cast<T>(std::llround(static_cast<lua_Number>(value))) != value) {
|
||||
if (static_cast<T>(llround(static_cast<lua_Number>(value))) != value) {
|
||||
#ifndef SOL_NO_EXCEPTIONS
|
||||
throw sol::error("The integer will be misrepresented in lua.");
|
||||
#else
|
||||
|
@ -437,7 +442,7 @@ namespace sol {
|
|||
std::allocator<T> alloc;
|
||||
alloc.construct(data, std::forward<Args>(args)...);
|
||||
if (with_meta) {
|
||||
lua_CFunction cdel = detail::user_alloc_destroy<T>;
|
||||
lua_CFunction cdel = detail::user_alloc_destruct<T>;
|
||||
// Make sure we have a plain GC set for this data
|
||||
if (luaL_newmetatable(L, name) != 0) {
|
||||
lua_pushcclosure(L, cdel, 0);
|
||||
|
@ -561,6 +566,30 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pusher<absolute_index> {
|
||||
static int push(lua_State* L, absolute_index ai) {
|
||||
lua_pushvalue(L, ai);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pusher<raw_index> {
|
||||
static int push(lua_State* L, raw_index ri) {
|
||||
lua_pushvalue(L, ri);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pusher<ref_index> {
|
||||
static int push(lua_State* L, ref_index ri) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ri);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef SOL_CODECVT_SUPPORT
|
||||
template<>
|
||||
struct pusher<const wchar_t*> {
|
||||
|
|
|
@ -32,9 +32,10 @@ namespace sol {
|
|||
(void)L;
|
||||
return -1;
|
||||
#else
|
||||
const char* message = lua_tostring(L, -1);
|
||||
size_t messagesize;
|
||||
const char* message = lua_tolstring(L, -1, &messagesize);
|
||||
if (message) {
|
||||
std::string err = message;
|
||||
std::string err(message, messagesize);
|
||||
lua_settop(L, 0);
|
||||
throw error(err);
|
||||
}
|
||||
|
|
|
@ -450,6 +450,10 @@ namespace sol {
|
|||
return load_result(L, absolute_index(L, -1), 1, 1, x);
|
||||
}
|
||||
|
||||
load_result load_buffer(const char* buff, size_t size, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
|
||||
return load(string_view(buff, size), chunkname, mode);
|
||||
}
|
||||
|
||||
load_result load_file(const std::string& filename, load_mode mode = load_mode::any) {
|
||||
load_status x = static_cast<load_status>(luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str()));
|
||||
return load_result(L, absolute_index(L, -1), 1, 1, x);
|
||||
|
@ -457,7 +461,7 @@ namespace sol {
|
|||
|
||||
load_result load(lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
|
||||
char basechunkname[17] = {};
|
||||
const char* chunknametarget = detail::make_chunk_name("lua_reader", chunkname, basechunkname);
|
||||
const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
|
||||
#if SOL_LUA_VERSION > 501
|
||||
load_status x = static_cast<load_status>(lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()));
|
||||
#else
|
||||
|
|
|
@ -176,7 +176,7 @@ namespace sol {
|
|||
basic_table_core& operator=(basic_table_core&&) = default;
|
||||
basic_table_core(const stack_reference& r) : basic_table_core(r.lua_state(), r.stack_index()) {}
|
||||
basic_table_core(stack_reference&& r) : basic_table_core(r.lua_state(), r.stack_index()) {}
|
||||
template <typename T, meta::enable<meta::neg<std::is_integral<meta::unqualified_t<T>>>, meta::neg<std::is_same<meta::unqualified_t<T>, ref_index>>> = meta::enabler>
|
||||
template <typename T, meta::enable<meta::neg<is_lua_index<meta::unqualified_t<T>>>> = meta::enabler>
|
||||
basic_table_core(lua_State* L, T&& r) : basic_table_core(L, sol::ref_index(r.registry_index())) {}
|
||||
basic_table_core(lua_State* L, new_table nt) : base_t(L, (lua_createtable(L, nt.sequence_hint, nt.map_hint), -1)) {
|
||||
if (!std::is_base_of<stack_reference, base_type>::value) {
|
||||
|
|
|
@ -261,7 +261,7 @@ namespace sol {
|
|||
using no = struct { char s[2]; };
|
||||
|
||||
struct F { void operator()(); };
|
||||
struct Derived : T, F {};
|
||||
struct Derived : T, F { ~Derived() = delete; };
|
||||
template<typename U, U> struct Check;
|
||||
|
||||
template<typename V>
|
||||
|
@ -382,6 +382,35 @@ namespace sol {
|
|||
static const bool value = sizeof(test<T>(0)) == sizeof(char);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_to_string_test {
|
||||
private:
|
||||
typedef std::array<char, 1> one;
|
||||
typedef std::array<char, 2> two;
|
||||
|
||||
template <typename C> static one test(decltype(std::declval<C>().to_string())*);
|
||||
template <typename C> static two test(...);
|
||||
|
||||
public:
|
||||
static const bool value = sizeof(test<T>(0)) == sizeof(char);
|
||||
};
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1910
|
||||
template <typename T, typename U, typename = decltype(std::declval<T&>() < std::declval<U&>())>
|
||||
std::true_type supports_op_less_test(std::reference_wrapper<T>, std::reference_wrapper<U>);
|
||||
std::false_type supports_op_less_test(...);
|
||||
template <typename T, typename U, typename = decltype(std::declval<T&>() == std::declval<U&>())>
|
||||
std::true_type supports_op_equal_test(std::reference_wrapper<T>, std::reference_wrapper<U>);
|
||||
std::false_type supports_op_equal_test(...);
|
||||
template <typename T, typename U, typename = decltype(std::declval<T&>() <= std::declval<U&>())>
|
||||
std::true_type supports_op_less_equal_test(std::reference_wrapper<T>, std::reference_wrapper<U>);
|
||||
std::false_type supports_op_less_equal_test(...);
|
||||
template <typename T, typename OS, typename = decltype(std::declval<OS&>() << std::declval<T&>())>
|
||||
std::true_type supports_ostream_op(std::reference_wrapper<T>, std::reference_wrapper<OS>);
|
||||
std::false_type supports_ostream_op(...);
|
||||
template <typename T, typename = decltype(to_string(std::declval<T&>()))>
|
||||
std::true_type supports_adl_to_string(std::reference_wrapper<T>);
|
||||
std::false_type supports_adl_to_string(...);
|
||||
#else
|
||||
template <typename T, typename U, typename = decltype(std::declval<T&>() < std::declval<U&>())>
|
||||
std::true_type supports_op_less_test(const T&, const U&);
|
||||
std::false_type supports_op_less_test(...);
|
||||
|
@ -394,9 +423,24 @@ namespace sol {
|
|||
template <typename T, typename OS, typename = decltype(std::declval<OS&>() << std::declval<T&>())>
|
||||
std::true_type supports_ostream_op(const T&, const OS&);
|
||||
std::false_type supports_ostream_op(...);
|
||||
|
||||
template <typename T, typename = decltype(to_string(std::declval<T&>()))>
|
||||
std::true_type supports_adl_to_string(const T&);
|
||||
std::false_type supports_adl_to_string(...);
|
||||
#endif
|
||||
} // meta_detail
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1910
|
||||
template <typename T, typename U = T>
|
||||
using supports_op_less = decltype(meta_detail::supports_op_less_test(std::ref(std::declval<T&>()), std::ref(std::declval<U&>())));
|
||||
template <typename T, typename U = T>
|
||||
using supports_op_equal = decltype(meta_detail::supports_op_equal_test(std::ref(std::declval<T&>()), std::ref(std::declval<U&>())));
|
||||
template <typename T, typename U = T>
|
||||
using supports_op_less_equal = decltype(meta_detail::supports_op_less_equal_test(std::ref(std::declval<T&>()), std::ref(std::declval<U&>())));
|
||||
template <typename T, typename U = std::ostream>
|
||||
using supports_ostream_op = decltype(meta_detail::supports_ostream_op(std::ref(std::declval<T&>()), std::ref(std::declval<U&>())));
|
||||
template <typename T>
|
||||
using supports_adl_to_string = decltype(meta_detail::supports_adl_to_string(std::ref(std::declval<T&>())));
|
||||
#else
|
||||
template <typename T, typename U = T>
|
||||
using supports_op_less = decltype(meta_detail::supports_op_less_test(std::declval<T&>(), std::declval<U&>()));
|
||||
template <typename T, typename U = T>
|
||||
|
@ -405,6 +449,11 @@ namespace sol {
|
|||
using supports_op_less_equal = decltype(meta_detail::supports_op_less_equal_test(std::declval<T&>(), std::declval<U&>()));
|
||||
template <typename T, typename U = std::ostream>
|
||||
using supports_ostream_op = decltype(meta_detail::supports_ostream_op(std::declval<T&>(), std::declval<U&>()));
|
||||
template <typename T>
|
||||
using supports_adl_to_string = decltype(meta_detail::supports_adl_to_string(std::declval<T&>()));
|
||||
#endif
|
||||
template <typename T>
|
||||
using supports_to_string_member = meta::boolean<meta_detail::has_to_string_test<T>::value>;
|
||||
|
||||
template<typename T>
|
||||
struct is_callable : boolean<meta_detail::is_callable<T>::value> {};
|
||||
|
|
|
@ -26,8 +26,12 @@
|
|||
#include "optional.hpp"
|
||||
#include "compatibility.hpp"
|
||||
#include "forward.hpp"
|
||||
#include "forward_detail.hpp"
|
||||
#include "traits.hpp"
|
||||
#include "string_shim.hpp"
|
||||
#include "raii.hpp"
|
||||
#include "filters.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#ifdef SOL_CXX17_FEATURES
|
||||
|
@ -1042,6 +1046,13 @@ namespace sol {
|
|||
template <>
|
||||
struct is_lua_index<upvalue_index> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_stack_based : std::is_base_of<stack_reference, T> {};
|
||||
template <>
|
||||
struct is_stack_based<raw_index> : std::true_type {};
|
||||
template <>
|
||||
struct is_stack_based<absolute_index> : std::true_type {};
|
||||
|
||||
template <typename Signature>
|
||||
struct lua_bind_traits : meta::bind_traits<Signature> {
|
||||
private:
|
||||
|
@ -1083,6 +1094,48 @@ namespace sol {
|
|||
inline type type_of() {
|
||||
return lua_type_of<meta::unqualified_t<T>>::value;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
struct is_non_factory_constructor : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_non_factory_constructor<constructors<Args...>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_non_factory_constructor<constructor_wrapper<Args...>> : std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_non_factory_constructor<no_construction> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_constructor : is_non_factory_constructor<T> {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_constructor<factory_wrapper<Args...>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_constructor<protect_t<T>> : is_constructor<meta::unqualified_t<T>> {};
|
||||
|
||||
template <typename F, typename... Filters>
|
||||
struct is_constructor<filter_wrapper<F, Filters...>> : is_constructor<meta::unqualified_t<F>> {};
|
||||
|
||||
template <typename... Args>
|
||||
using has_constructor = meta::any<is_constructor<meta::unqualified_t<Args>>...>;
|
||||
|
||||
template <typename T>
|
||||
struct is_destructor : std::false_type {};
|
||||
|
||||
template <typename Fx>
|
||||
struct is_destructor<destructor_wrapper<Fx>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
using has_destructor = meta::any<is_destructor<meta::unqualified_t<Args>>...>;
|
||||
|
||||
struct add_destructor_tag {};
|
||||
struct check_destructor_tag {};
|
||||
struct verified_tag {} const verified{};
|
||||
} // detail
|
||||
} // sol
|
||||
|
||||
#endif // SOL_TYPES_HPP
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace sol {
|
|||
basic_function& operator=(basic_function&&) = default;
|
||||
basic_function(const stack_reference& r) : basic_function(r.lua_state(), r.stack_index()) {}
|
||||
basic_function(stack_reference&& r) : basic_function(r.lua_state(), r.stack_index()) {}
|
||||
template <typename T, meta::enable<meta::neg<std::is_integral<meta::unqualified_t<T>>>, meta::neg<std::is_same<T, ref_index>>> = meta::enabler>
|
||||
template <typename T, meta::enable<meta::neg<is_lua_index<meta::unqualified_t<T>>>> = meta::enabler>
|
||||
basic_function(lua_State* L, T&& r) : basic_function(L, sol::ref_index(r.registry_index())) {}
|
||||
basic_function(lua_State* L, int index = -1) : base_t(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace sol {
|
|||
basic_userdata& operator=(basic_userdata&&) = default;
|
||||
basic_userdata(const stack_reference& r) : basic_userdata(r.lua_state(), r.stack_index()) {}
|
||||
basic_userdata(stack_reference&& r) : basic_userdata(r.lua_state(), r.stack_index()) {}
|
||||
template <typename T, meta::enable<meta::neg<std::is_integral<meta::unqualified_t<T>>>, meta::neg<std::is_same<meta::unqualified_t<T>, ref_index>>> = meta::enabler>
|
||||
template <typename T, meta::enable<meta::neg<is_lua_index<meta::unqualified_t<T>>>> = meta::enabler>
|
||||
basic_userdata(lua_State* L, T&& r) : basic_userdata(L, sol::ref_index(r.registry_index())) {}
|
||||
basic_userdata(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
|
@ -85,7 +85,7 @@ namespace sol {
|
|||
basic_lightuserdata& operator=(basic_lightuserdata&&) = default;
|
||||
basic_lightuserdata(const stack_reference& r) : basic_lightuserdata(r.lua_state(), r.stack_index()) {}
|
||||
basic_lightuserdata(stack_reference&& r) : basic_lightuserdata(r.lua_state(), r.stack_index()) {}
|
||||
template <typename T, meta::enable<meta::neg<std::is_integral<meta::unqualified_t<T>>>, meta::neg<std::is_same<meta::unqualified_t<T>, ref_index>>> = meta::enabler>
|
||||
template <typename T, meta::enable<meta::neg<is_lua_index<T>>> = meta::enabler>
|
||||
basic_lightuserdata(lua_State* L, T&& r) : basic_lightuserdata(L, sol::ref_index(r.registry_index())) {}
|
||||
basic_lightuserdata(lua_State* L, int index = -1) : base_t(L, index) {
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
|
|
|
@ -36,24 +36,26 @@ namespace sol {
|
|||
std::unique_ptr<usertype_detail::registrar, detail::deleter> metatableregister;
|
||||
|
||||
template<typename... Args>
|
||||
usertype(usertype_detail::verified_tag, Args&&... args) : metatableregister(detail::make_unique_deleter<usertype_metatable<T, std::make_index_sequence<sizeof...(Args) / 2>, Args...>, detail::deleter>(std::forward<Args>(args)...)) {}
|
||||
usertype(detail::verified_tag, Args&&... args) : metatableregister(detail::make_unique_deleter<usertype_metatable<T, std::make_index_sequence<sizeof...(Args) / 2>, Args...>, detail::deleter>(std::forward<Args>(args)...)) {
|
||||
static_assert(detail::has_destructor<Args...>::value, "this type does not have an explicit destructor declared; please pass a custom destructor function wrapped in sol::destruct, especially if the type does not have an accessible (private) destructor");
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
usertype(usertype_detail::add_destructor_tag, Args&&... args) : usertype(usertype_detail::verified, std::forward<Args>(args)..., "__gc", default_destructor) {}
|
||||
usertype(detail::add_destructor_tag, Args&&... args) : usertype(detail::verified, std::forward<Args>(args)..., "__gc", default_destructor) {}
|
||||
|
||||
template<typename... Args>
|
||||
usertype(usertype_detail::check_destructor_tag, Args&&... args) : usertype(meta::condition<meta::all<std::is_destructible<T>, meta::neg<usertype_detail::has_destructor<Args...>>>, usertype_detail::add_destructor_tag, usertype_detail::verified_tag>(), std::forward<Args>(args)...) {}
|
||||
usertype(detail::check_destructor_tag, Args&&... args) : usertype(meta::condition<meta::all<std::is_destructible<T>, meta::neg<detail::has_destructor<Args...>>>, detail::add_destructor_tag, detail::verified_tag>(), std::forward<Args>(args)...) {}
|
||||
|
||||
public:
|
||||
|
||||
template<typename... Args>
|
||||
usertype(Args&&... args) : usertype(meta::condition<meta::all<std::is_default_constructible<T>, meta::neg<usertype_detail::has_constructor<Args...>>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), std::forward<Args>(args)...) {}
|
||||
usertype(Args&&... args) : usertype(meta::condition<meta::all<std::is_default_constructible<T>, meta::neg<detail::has_constructor<Args...>>>, decltype(default_constructor), detail::check_destructor_tag>(), std::forward<Args>(args)...) {}
|
||||
|
||||
template<typename... Args, typename... CArgs>
|
||||
usertype(constructors<CArgs...> constructorlist, Args&&... args) : usertype(usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
usertype(constructors<CArgs...> constructorlist, Args&&... args) : usertype(detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
|
||||
template<typename... Args, typename... Fxs>
|
||||
usertype(constructor_wrapper<Fxs...> constructorlist, Args&&... args) : usertype(usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
usertype(constructor_wrapper<Fxs...> constructorlist, Args&&... args) : usertype(detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
|
||||
|
||||
template<typename... Args>
|
||||
usertype(simple_tag, lua_State* L, Args&&... args) : metatableregister(detail::make_unique_deleter<simple_usertype_metatable<T>, detail::deleter>(L, std::forward<Args>(args)...)) {}
|
||||
|
|
235
sol/usertype_core.hpp
Normal file
235
sol/usertype_core.hpp
Normal file
|
@ -0,0 +1,235 @@
|
|||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2017 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_USERTYPE_CORE_HPP
|
||||
#define SOL_USERTYPE_CORE_HPP
|
||||
|
||||
#include "wrapper.hpp"
|
||||
#include "call.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "types.hpp"
|
||||
#include "stack_reference.hpp"
|
||||
#include "usertype_traits.hpp"
|
||||
#include "inheritance.hpp"
|
||||
#include "raii.hpp"
|
||||
#include "deprecate.hpp"
|
||||
#include "object.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace sol {
|
||||
namespace usertype_detail {
|
||||
struct no_comp {
|
||||
template <typename A, typename B>
|
||||
bool operator()(A&&, B&&) const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline int member_default_to_string(std::true_type, lua_State* L) {
|
||||
std::string ts = stack::get<T>(L, 1).to_string();
|
||||
return stack::push(L, std::move(ts));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline int member_default_to_string(std::false_type, lua_State* L) {
|
||||
return luaL_error(L, "cannot perform to_string on '%s': no 'to_string' overload in namespace, 'to_string' member function, or operator<<(ostream&, ...) present", detail::demangle<T>().data());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline int adl_default_to_string(std::true_type, lua_State* L) {
|
||||
using std::to_string;
|
||||
std::string ts = to_string(stack::get<T>(L, 1));
|
||||
return stack::push(L, std::move(ts));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline int adl_default_to_string(std::false_type, lua_State* L) {
|
||||
return member_default_to_string<T>(meta::supports_to_string_member<T>(), L);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline int oss_default_to_string(std::true_type, lua_State* L) {
|
||||
std::ostringstream oss;
|
||||
oss << stack::get<T>(L, 1);
|
||||
return stack::push(L, oss.str());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline int oss_default_to_string(std::false_type, lua_State* L) {
|
||||
return adl_default_to_string<T>(meta::supports_adl_to_string<T>(), L);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline int default_to_string(lua_State* L) {
|
||||
return oss_default_to_string<T>(meta::supports_ostream_op<T>(), L);
|
||||
}
|
||||
|
||||
template <typename T, typename Op>
|
||||
int comparsion_operator_wrap(lua_State* L) {
|
||||
auto maybel = stack::check_get<T>(L, 1);
|
||||
if (maybel) {
|
||||
auto mayber = stack::check_get<T>(L, 2);
|
||||
if (mayber) {
|
||||
auto& l = *maybel;
|
||||
auto& r = *mayber;
|
||||
if (std::is_same<no_comp, Op>::value) {
|
||||
return stack::push(L, detail::ptr(l) == detail::ptr(r));
|
||||
}
|
||||
else {
|
||||
Op op;
|
||||
return stack::push(L, (detail::ptr(l) == detail::ptr(r)) || op(detail::deref(l), detail::deref(r)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return stack::push(L, false);
|
||||
}
|
||||
|
||||
template <typename T, typename Op, typename Supports, typename Regs, meta::enable<Supports> = meta::enabler>
|
||||
inline void make_reg_op(Regs& l, int& index, const char* name) {
|
||||
lua_CFunction f = &comparsion_operator_wrap<T, Op>;
|
||||
l[index] = luaL_Reg{ name, f };
|
||||
++index;
|
||||
}
|
||||
|
||||
template <typename T, typename Op, typename Supports, typename Regs, meta::disable<Supports> = meta::enabler>
|
||||
inline void make_reg_op(Regs&, int&, const char*) {
|
||||
// Do nothing if there's no support
|
||||
}
|
||||
|
||||
template <typename T, typename Supports, typename Regs, meta::enable<Supports> = meta::enabler>
|
||||
inline void make_to_string_op(Regs& l, int& index) {
|
||||
const char* name = to_string(meta_function::to_string).c_str();
|
||||
lua_CFunction f = &detail::static_trampoline<&default_to_string<T>>;
|
||||
l[index] = luaL_Reg{ name, f };
|
||||
++index;
|
||||
}
|
||||
|
||||
template <typename T, typename Supports, typename Regs, meta::disable<Supports> = meta::enabler>
|
||||
inline void make_to_string_op(Regs&, int&) {
|
||||
// Do nothing if there's no support
|
||||
}
|
||||
|
||||
template <typename T, typename Regs, meta::enable<meta::has_deducible_signature<T>> = meta::enabler>
|
||||
inline void make_call_op(Regs& l, int& index) {
|
||||
const char* name = to_string(meta_function::call).c_str();
|
||||
lua_CFunction f = &c_call<decltype(&T::operator()), &T::operator()>;
|
||||
l[index] = luaL_Reg{ name, f };
|
||||
++index;
|
||||
}
|
||||
|
||||
template <typename T, typename Regs, meta::disable<meta::has_deducible_signature<T>> = meta::enabler>
|
||||
inline void make_call_op(Regs&, int&) {
|
||||
// Do nothing if there's no support
|
||||
}
|
||||
|
||||
template <typename T, typename Regs, meta::enable<meta::has_size<T>> = meta::enabler>
|
||||
inline void make_length_op(Regs& l, int& index) {
|
||||
const char* name = to_string(meta_function::length).c_str();
|
||||
l[index] = luaL_Reg{ name, &c_call<decltype(&T::size), &T::size> };
|
||||
++index;
|
||||
}
|
||||
|
||||
template <typename T, typename Regs, meta::disable<meta::has_size<T>> = meta::enabler>
|
||||
inline void make_length_op(Regs&, int&) {
|
||||
// Do nothing if there's no support
|
||||
}
|
||||
|
||||
template <typename T, typename Regs, meta::enable<meta::neg<std::is_pointer<T>>, std::is_destructible<T>>>
|
||||
void make_destructor(Regs& l, int& index) {
|
||||
const char* name = to_string(meta_function::garbage_collect).c_str();
|
||||
l[index] = luaL_Reg{ name, is_unique_usertype<T>::value ? &detail::unique_destruct<T> : &detail::usertype_alloc_destruct<T> };
|
||||
++index;
|
||||
}
|
||||
|
||||
template <typename T, typename Regs, meta::disable<meta::neg<std::is_pointer<T>>, std::is_destructible<T>>>
|
||||
void make_destructor(Regs& l, int& index) {
|
||||
if (!std::is_destructible<T>::value) {
|
||||
// if the value is not destructible, plant an erroring __gc method
|
||||
// to warn the user of a problem when it comes around
|
||||
// this won't trigger if the user performs `new_usertype` / `new_simple_usertype` and
|
||||
// rigs the class up properly
|
||||
const char* name = to_string(meta_function::garbage_collect).c_str();
|
||||
l[index] = luaL_Reg{ name, &detail::cannot_destruct<T> };
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Regs, typename Fx>
|
||||
void insert_default_registrations(Regs& l, int& index, Fx&& fx) {
|
||||
if (fx(meta_function::less_than)) {
|
||||
const char* name = to_string(meta_function::less_than).c_str();
|
||||
usertype_detail::make_reg_op<T, std::less<>, meta::supports_op_less<T>>(l, index, name);
|
||||
}
|
||||
if (fx(meta_function::less_than_or_equal_to)) {
|
||||
const char* name = to_string(meta_function::less_than_or_equal_to).c_str();
|
||||
usertype_detail::make_reg_op<T, std::less_equal<>, meta::supports_op_less_equal<T>>(l, index, name);
|
||||
}
|
||||
if (fx(meta_function::equal_to)) {
|
||||
const char* name = to_string(meta_function::equal_to).c_str();
|
||||
usertype_detail::make_reg_op<T, std::conditional_t<meta::supports_op_equal<T>::value, std::equal_to<>, usertype_detail::no_comp>, std::true_type>(l, index, name);
|
||||
}
|
||||
if (fx(meta_function::pairs)) {
|
||||
const char* name = to_string(meta_function::pairs).c_str();
|
||||
l[index] = luaL_Reg{ name, container_usertype_metatable<as_container_t<T>>::pairs_call };
|
||||
++index;
|
||||
}
|
||||
if (fx(meta_function::length)) {
|
||||
usertype_detail::make_length_op<T>(l, index);
|
||||
}
|
||||
if (fx(meta_function::to_string)) {
|
||||
usertype_detail::make_to_string_op<T, meta::any<meta::supports_to_string_member<T>, meta::supports_adl_to_string<T>, meta::supports_ostream_op<T>>>(l, index);
|
||||
}
|
||||
if (fx(meta_function::call_function)) {
|
||||
usertype_detail::make_call_op<T>(l, index);
|
||||
}
|
||||
}
|
||||
} // usertype_detail
|
||||
|
||||
namespace stack {
|
||||
namespace stack_detail {
|
||||
template <typename T>
|
||||
struct undefined_metatable {
|
||||
typedef meta::all<meta::neg<std::is_pointer<T>>, std::is_destructible<T>> is_destructible;
|
||||
typedef std::remove_pointer_t<T> P;
|
||||
lua_State* L;
|
||||
const char* key;
|
||||
|
||||
undefined_metatable(lua_State* l, const char* k) : L(l), key(k) {}
|
||||
|
||||
void operator () () const {
|
||||
if (luaL_newmetatable(L, key) == 1) {
|
||||
luaL_Reg l[32]{};
|
||||
int index = 0;
|
||||
auto fx = [](meta_function) { return true; };
|
||||
usertype_detail::insert_default_registrations<P>(l, index, fx);
|
||||
usertype_detail::make_destructor<T>(l, index);
|
||||
luaL_setfuncs(L, l, 0);
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
};
|
||||
} // stack_detail
|
||||
} // stack
|
||||
} // sol
|
||||
|
||||
#endif // SOL_USERTYPE_CORE_HPP
|
|
@ -33,6 +33,7 @@
|
|||
#include "deprecate.hpp"
|
||||
#include "object.hpp"
|
||||
#include "container_usertype_metatable.hpp"
|
||||
#include "usertype_core.hpp"
|
||||
#include <unordered_map>
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
|
@ -102,13 +103,6 @@ namespace sol {
|
|||
index(std::move(i)), newindex(std::move(ni)),
|
||||
indexbaseclasspropogation(index), newindexbaseclasspropogation(newindex) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline int default_to_string(lua_State* L) {
|
||||
std::ostringstream oss;
|
||||
oss << stack::get<T>(L, 1);
|
||||
return stack::push(L, oss.str());
|
||||
}
|
||||
} // usertype_detail
|
||||
|
||||
struct usertype_metatable_core {
|
||||
|
@ -134,47 +128,6 @@ namespace sol {
|
|||
namespace usertype_detail {
|
||||
const lua_Integer toplevel_magic = static_cast<lua_Integer>(0xCCC2CCC1);
|
||||
|
||||
struct add_destructor_tag {};
|
||||
struct check_destructor_tag {};
|
||||
struct verified_tag {} const verified{};
|
||||
|
||||
template <typename T>
|
||||
struct is_non_factory_constructor : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_non_factory_constructor<constructors<Args...>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_non_factory_constructor<constructor_wrapper<Args...>> : std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_non_factory_constructor<no_construction> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_constructor : is_non_factory_constructor<T> {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_constructor<factory_wrapper<Args...>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
using has_constructor = meta::any<is_constructor<meta::unqualified_t<Args>>...>;
|
||||
|
||||
template <typename T>
|
||||
struct is_destructor : std::false_type {};
|
||||
|
||||
template <typename Fx>
|
||||
struct is_destructor<destructor_wrapper<Fx>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
using has_destructor = meta::any<is_destructor<meta::unqualified_t<Args>>...>;
|
||||
|
||||
struct no_comp {
|
||||
template <typename A, typename B>
|
||||
bool operator()(A&&, B&&) const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
inline int is_indexer(string_detail::string_shim s) {
|
||||
if (s == to_string(meta_function::index)) {
|
||||
return 1;
|
||||
|
@ -409,76 +362,6 @@ namespace sol {
|
|||
(void)accessor;
|
||||
(void)detail::swallow{ 0, (walk_single_base<is_index, Bases>(L, found, ret, accessor), 0)... };
|
||||
}
|
||||
|
||||
template <typename T, typename Op>
|
||||
int operator_wrap(lua_State* L) {
|
||||
auto maybel = stack::check_get<T>(L, 1);
|
||||
if (maybel) {
|
||||
auto mayber = stack::check_get<T>(L, 2);
|
||||
if (mayber) {
|
||||
auto& l = *maybel;
|
||||
auto& r = *mayber;
|
||||
if (std::is_same<no_comp, Op>::value) {
|
||||
return stack::push(L, detail::ptr(l) == detail::ptr(r));
|
||||
}
|
||||
else {
|
||||
Op op;
|
||||
return stack::push(L, (detail::ptr(l) == detail::ptr(r)) || op(detail::deref(l), detail::deref(r)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return stack::push(L, false);
|
||||
}
|
||||
|
||||
template <typename T, typename Op, typename Supports, typename Regs, meta::enable<Supports> = meta::enabler>
|
||||
inline void make_reg_op(Regs& l, int& index, const char* name) {
|
||||
lua_CFunction f = &operator_wrap<T, Op>;
|
||||
l[index] = luaL_Reg{ name, f };
|
||||
++index;
|
||||
}
|
||||
|
||||
template <typename T, typename Op, typename Supports, typename Regs, meta::disable<Supports> = meta::enabler>
|
||||
inline void make_reg_op(Regs&, int&, const char*) {
|
||||
// Do nothing if there's no support
|
||||
}
|
||||
|
||||
template <typename T, typename Supports, typename Regs, meta::enable<Supports> = meta::enabler>
|
||||
inline void make_to_string_op(Regs& l, int& index) {
|
||||
const char* name = to_string(meta_function::to_string).c_str();
|
||||
lua_CFunction f = &detail::static_trampoline<&default_to_string<T>>;
|
||||
l[index] = luaL_Reg{ name, f };
|
||||
++index;
|
||||
}
|
||||
|
||||
template <typename T, typename Supports, typename Regs, meta::disable<Supports> = meta::enabler>
|
||||
inline void make_to_string_op(Regs&, int&) {
|
||||
// Do nothing if there's no support
|
||||
}
|
||||
|
||||
template <typename T, typename Regs, meta::enable<meta::has_deducible_signature<T>> = meta::enabler>
|
||||
inline void make_call_op(Regs& l, int& index) {
|
||||
const char* name = to_string(meta_function::call).c_str();
|
||||
lua_CFunction f = &c_call<decltype(&T::operator()), &T::operator()>;
|
||||
l[index] = luaL_Reg{ name, f };
|
||||
++index;
|
||||
}
|
||||
|
||||
template <typename T, typename Regs, meta::disable<meta::has_deducible_signature<T>> = meta::enabler>
|
||||
inline void make_call_op(Regs&, int&) {
|
||||
// Do nothing if there's no support
|
||||
}
|
||||
|
||||
template <typename T, typename Regs, meta::enable<meta::has_size<T>> = meta::enabler>
|
||||
inline void make_length_op(Regs& l, int& index) {
|
||||
const char* name = to_string(meta_function::length).c_str();
|
||||
l[index] = luaL_Reg{ name, &c_call<decltype(&T::size), &T::size> };
|
||||
++index;
|
||||
}
|
||||
|
||||
template <typename T, typename Regs, meta::disable<meta::has_size<T>> = meta::enabler>
|
||||
inline void make_length_op(Regs&, int&) {
|
||||
// Do nothing if there's no support
|
||||
}
|
||||
} // usertype_detail
|
||||
|
||||
template <typename T>
|
||||
|
@ -536,32 +419,8 @@ namespace sol {
|
|||
}
|
||||
|
||||
int finish_regs(regs_t& l, int& index) {
|
||||
if (!properties[static_cast<int>(meta_function::less_than)]) {
|
||||
const char* name = to_string(meta_function::less_than).c_str();
|
||||
usertype_detail::make_reg_op<T, std::less<>, meta::supports_op_less<T>>(l, index, name);
|
||||
}
|
||||
if (!properties[static_cast<int>(meta_function::less_than_or_equal_to)]) {
|
||||
const char* name = to_string(meta_function::less_than_or_equal_to).c_str();
|
||||
usertype_detail::make_reg_op<T, std::less_equal<>, meta::supports_op_less_equal<T>>(l, index, name);
|
||||
}
|
||||
if (!properties[static_cast<int>(meta_function::equal_to)]) {
|
||||
const char* name = to_string(meta_function::equal_to).c_str();
|
||||
usertype_detail::make_reg_op<T, std::conditional_t<meta::supports_op_equal<T>::value, std::equal_to<>, usertype_detail::no_comp>, std::true_type>(l, index, name);
|
||||
}
|
||||
if (!properties[static_cast<int>(meta_function::pairs)]) {
|
||||
const char* name = to_string(meta_function::pairs).c_str();
|
||||
l[index] = luaL_Reg{ name, container_usertype_metatable<as_container_t<T>>::pairs_call };
|
||||
++index;
|
||||
}
|
||||
if (!properties[static_cast<int>(meta_function::length)]) {
|
||||
usertype_detail::make_length_op<T>(l, index);
|
||||
}
|
||||
if (!properties[static_cast<int>(meta_function::to_string)]) {
|
||||
usertype_detail::make_to_string_op<T, meta::supports_ostream_op<T>>(l, index);
|
||||
}
|
||||
if (!properties[static_cast<int>(meta_function::call)]) {
|
||||
usertype_detail::make_call_op<T>(l, index);
|
||||
}
|
||||
auto prop_fx = [&](meta_function mf) { return !properties[static_cast<int>(mf)]; };
|
||||
usertype_detail::insert_default_registrations<T>(l, index, prop_fx);
|
||||
if (destructfunc != nullptr) {
|
||||
l[index] = luaL_Reg{ to_string(meta_function::garbage_collect).c_str(), destructfunc };
|
||||
++index;
|
||||
|
@ -732,7 +591,7 @@ namespace sol {
|
|||
typedef meta::unqualified_tuple_element_t<Idx - 1, Tuple> K;
|
||||
typedef meta::unqualified_tuple_element_t<Idx, Tuple> F;
|
||||
static const int boost =
|
||||
!usertype_detail::is_non_factory_constructor<F>::value
|
||||
!detail::is_non_factory_constructor<F>::value
|
||||
&& std::is_same<K, call_construction>::value ?
|
||||
1 : 0;
|
||||
auto& f = std::get<Idx>(um.functions);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
|
||||
#include <sol.hpp>
|
||||
#include <catch.hpp>
|
||||
|
@ -94,7 +94,7 @@ namespace sol {
|
|||
template <typename T>
|
||||
void sequence_container_check(sol::state& lua, T& items) {
|
||||
{
|
||||
auto r1 = lua.script(R"(
|
||||
auto r1 = lua.safe_script(R"(
|
||||
for i=1,#c do
|
||||
v = c[i]
|
||||
assert(v == (i + 10))
|
||||
|
@ -104,45 +104,45 @@ end
|
|||
}
|
||||
{
|
||||
auto ffind = [&]() {
|
||||
auto r1 = lua.script("i1 = c:find(11)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("i1 = c:find(11)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("i2 = c:find(14)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("i2 = c:find(14)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
};
|
||||
auto fget = [&]() {
|
||||
auto r1 = lua.script("v1 = c:get(1)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("v1 = c:get(1)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("v2 = c:get(3)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("v2 = c:get(3)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
};
|
||||
auto fset = [&]() {
|
||||
auto r1 = lua.script("c:set(2, 20)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("c:set(2, 20)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("c:set(6, 16)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("c:set(6, 16)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
};
|
||||
auto ferase = [&]() {
|
||||
auto r5 = lua.script("s1 = #c", sol::script_pass_on_error);
|
||||
auto r5 = lua.safe_script("s1 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r5.valid());
|
||||
auto r1 = lua.script("c:erase(i1)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("c:erase(i1)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r3 = lua.script("s2 = #c", sol::script_pass_on_error);
|
||||
auto r3 = lua.safe_script("s2 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r3.valid());
|
||||
auto r2 = lua.script("c:erase(i2)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("c:erase(i2)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
auto r4 = lua.script("s3 = #c", sol::script_pass_on_error);
|
||||
auto r4 = lua.safe_script("s3 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r4.valid());
|
||||
};
|
||||
auto fadd = [&]() {
|
||||
auto r = lua.script("c:add(17)", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("c:add(17)", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
auto fopset = [&]() {
|
||||
auto r = lua.script("c[#c + 1] = 18", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("c[#c + 1] = 18", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
auto fopget = [&]() {
|
||||
auto r = lua.script("v3 = c[#c]", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("v3 = c[#c]", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
REQUIRE_NOTHROW(ffind());
|
||||
|
@ -203,7 +203,7 @@ end
|
|||
template <typename T>
|
||||
void ordered_container_check(sol::state& lua, T& items) {
|
||||
{
|
||||
auto r1 = lua.script(R"(
|
||||
auto r1 = lua.safe_script(R"(
|
||||
for i=1,#c do
|
||||
v = c[(i + 10)]
|
||||
assert(v == (i + 10))
|
||||
|
@ -213,45 +213,45 @@ end
|
|||
}
|
||||
{
|
||||
auto ffind = [&]() {
|
||||
auto r1 = lua.script("i1 = c:find(11)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("i1 = c:find(11)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("i2 = c:find(14)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("i2 = c:find(14)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
};
|
||||
auto fget = [&]() {
|
||||
auto r1 = lua.script("v1 = c:get(11)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("v1 = c:get(11)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("v2 = c:get(13)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("v2 = c:get(13)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
};
|
||||
auto fset = [&]() {
|
||||
auto r1 = lua.script("c:set(20)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("c:set(20)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("c:set(16)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("c:set(16)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
};
|
||||
auto ferase = [&]() {
|
||||
auto r5 = lua.script("s1 = #c", sol::script_pass_on_error);
|
||||
auto r5 = lua.safe_script("s1 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r5.valid());
|
||||
auto r1 = lua.script("c:erase(i1)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("c:erase(i1)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r3 = lua.script("s2 = #c", sol::script_pass_on_error);
|
||||
auto r3 = lua.safe_script("s2 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r3.valid());
|
||||
auto r2 = lua.script("c:erase(i2)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("c:erase(i2)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
auto r4 = lua.script("s3 = #c", sol::script_pass_on_error);
|
||||
auto r4 = lua.safe_script("s3 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r4.valid());
|
||||
};
|
||||
auto fadd = [&]() {
|
||||
auto r = lua.script("c:add(17)", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("c:add(17)", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
auto fopset = [&]() {
|
||||
auto r = lua.script("c[18] = true", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("c[18] = true", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
auto fopget = [&]() {
|
||||
auto r = lua.script("v3 = c[20]", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("v3 = c[20]", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
REQUIRE_NOTHROW(ffind());
|
||||
|
@ -313,45 +313,45 @@ template <typename T>
|
|||
void unordered_container_check(sol::state& lua, T& items) {
|
||||
{
|
||||
auto ffind = [&]() {
|
||||
auto r1 = lua.script("i1 = c:find(11)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("i1 = c:find(11)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("i2 = c:find(14)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("i2 = c:find(14)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
};
|
||||
auto fget = [&]() {
|
||||
auto r1 = lua.script("v1 = c:get(11)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("v1 = c:get(11)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("v2 = c:get(13)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("v2 = c:get(13)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
};
|
||||
auto fset = [&]() {
|
||||
auto r1 = lua.script("c:set(20)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("c:set(20)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("c:set(16)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("c:set(16)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
};
|
||||
auto ferase = [&]() {
|
||||
auto r5 = lua.script("s1 = #c", sol::script_pass_on_error);
|
||||
auto r5 = lua.safe_script("s1 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r5.valid());
|
||||
auto r1 = lua.script("c:erase(i1)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("c:erase(i1)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r3 = lua.script("s2 = #c", sol::script_pass_on_error);
|
||||
auto r3 = lua.safe_script("s2 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r3.valid());
|
||||
auto r2 = lua.script("c:erase(i2)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("c:erase(i2)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
auto r4 = lua.script("s3 = #c", sol::script_pass_on_error);
|
||||
auto r4 = lua.safe_script("s3 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r4.valid());
|
||||
};
|
||||
auto fadd = [&]() {
|
||||
auto r = lua.script("c:add(17)", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("c:add(17)", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
auto fopset = [&]() {
|
||||
auto r = lua.script("c[18] = true", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("c[18] = true", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
auto fopget = [&]() {
|
||||
auto r = lua.script("v3 = c[20]", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("v3 = c[20]", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
REQUIRE_NOTHROW(ffind());
|
||||
|
@ -398,7 +398,7 @@ void unordered_container_check(sol::state& lua, T& items) {
|
|||
template <typename T>
|
||||
void associative_ordered_container_check(sol::state& lua, T& items) {
|
||||
{
|
||||
auto r1 = lua.script(R"(
|
||||
auto r1 = lua.safe_script(R"(
|
||||
for i=1,#c do
|
||||
v = c[(i + 10)]
|
||||
assert(v == (i + 20))
|
||||
|
@ -408,47 +408,47 @@ end
|
|||
}
|
||||
{
|
||||
auto ffind = [&]() {
|
||||
auto r1 = lua.script("i1 = c:find(11)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("i1 = c:find(11)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("i2 = c:find(14)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("i2 = c:find(14)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
};
|
||||
auto fget = [&]() {
|
||||
auto r1 = lua.script("v1 = c:get(11)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("v1 = c:get(11)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("v2 = c:get(13)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("v2 = c:get(13)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
};
|
||||
auto fset = [&]() {
|
||||
auto r1 = lua.script("c:set(20, 30)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("c:set(20, 30)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("c:set(16, 26)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("c:set(16, 26)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
auto r3 = lua.script("c:set(12, 31)", sol::script_pass_on_error);
|
||||
auto r3 = lua.safe_script("c:set(12, 31)", sol::script_pass_on_error);
|
||||
REQUIRE(r3.valid());
|
||||
};
|
||||
auto ferase = [&]() {
|
||||
auto r5 = lua.script("s1 = #c", sol::script_pass_on_error);
|
||||
auto r5 = lua.safe_script("s1 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r5.valid());
|
||||
auto r1 = lua.script("c:erase(11)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("c:erase(11)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r3 = lua.script("s2 = #c", sol::script_pass_on_error);
|
||||
auto r3 = lua.safe_script("s2 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r3.valid());
|
||||
auto r2 = lua.script("c:erase(14)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("c:erase(14)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
auto r4 = lua.script("s3 = #c", sol::script_pass_on_error);
|
||||
auto r4 = lua.safe_script("s3 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r4.valid());
|
||||
};
|
||||
auto fadd = [&]() {
|
||||
auto r = lua.script("c:add(17, 27)", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("c:add(17, 27)", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
auto fopset = [&]() {
|
||||
auto r = lua.script("c[18] = 28", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("c[18] = 28", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
auto fopget = [&]() {
|
||||
auto r = lua.script("v3 = c[20]", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("v3 = c[20]", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
REQUIRE_NOTHROW(ffind());
|
||||
|
@ -518,47 +518,47 @@ template <typename T>
|
|||
void associative_unordered_container_check(sol::state& lua, T& items) {
|
||||
{
|
||||
auto ffind = [&]() {
|
||||
auto r1 = lua.script("i1 = c:find(11)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("i1 = c:find(11)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("i2 = c:find(14)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("i2 = c:find(14)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
};
|
||||
auto fget = [&]() {
|
||||
auto r1 = lua.script("v1 = c:get(11)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("v1 = c:get(11)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("v2 = c:get(13)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("v2 = c:get(13)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
};
|
||||
auto fset = [&]() {
|
||||
auto r1 = lua.script("c:set(20, 30)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("c:set(20, 30)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("c:set(16, 26)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("c:set(16, 26)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
auto r3 = lua.script("c:set(12, 31)", sol::script_pass_on_error);
|
||||
auto r3 = lua.safe_script("c:set(12, 31)", sol::script_pass_on_error);
|
||||
REQUIRE(r3.valid());
|
||||
};
|
||||
auto ferase = [&]() {
|
||||
auto r5 = lua.script("s1 = #c", sol::script_pass_on_error);
|
||||
auto r5 = lua.safe_script("s1 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r5.valid());
|
||||
auto r1 = lua.script("c:erase(11)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("c:erase(11)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r3 = lua.script("s2 = #c", sol::script_pass_on_error);
|
||||
auto r3 = lua.safe_script("s2 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r3.valid());
|
||||
auto r2 = lua.script("c:erase(14)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("c:erase(14)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
auto r4 = lua.script("s3 = #c", sol::script_pass_on_error);
|
||||
auto r4 = lua.safe_script("s3 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r4.valid());
|
||||
};
|
||||
auto fadd = [&]() {
|
||||
auto r = lua.script("c:add(17, 27)", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("c:add(17, 27)", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
auto fopset = [&]() {
|
||||
auto r = lua.script("c[18] = 28", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("c[18] = 28", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
auto fopget = [&]() {
|
||||
auto r = lua.script("v3 = c[20]", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("v3 = c[20]", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
REQUIRE_NOTHROW(ffind());
|
||||
|
@ -612,7 +612,7 @@ void associative_unordered_container_check(sol::state& lua, T& items) {
|
|||
template <typename T>
|
||||
void fixed_container_check(sol::state& lua, T& items) {
|
||||
{
|
||||
auto r1 = lua.script(R"(
|
||||
auto r1 = lua.safe_script(R"(
|
||||
for i=1,#c do
|
||||
v = c[i]
|
||||
assert(v == (i + 10))
|
||||
|
@ -622,45 +622,45 @@ end
|
|||
}
|
||||
{
|
||||
auto ffind = [&]() {
|
||||
auto r1 = lua.script("i1 = c:find(11)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("i1 = c:find(11)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("i2 = c:find(14)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("i2 = c:find(14)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
};
|
||||
auto fget = [&]() {
|
||||
auto r1 = lua.script("v1 = c:get(2)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("v1 = c:get(2)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("v2 = c:get(5)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("v2 = c:get(5)", sol::script_pass_on_error);
|
||||
REQUIRE(r2.valid());
|
||||
};
|
||||
auto fset = [&]() {
|
||||
auto r1 = lua.script("c:set(2, 20)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("c:set(2, 20)", sol::script_pass_on_error);
|
||||
REQUIRE(r1.valid());
|
||||
auto r2 = lua.script("c:set(6, 16)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("c:set(6, 16)", sol::script_pass_on_error);
|
||||
REQUIRE_FALSE(r2.valid());
|
||||
};
|
||||
auto ferase = [&]() {
|
||||
auto r5 = lua.script("s1 = #c", sol::script_pass_on_error);
|
||||
auto r5 = lua.safe_script("s1 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r5.valid());
|
||||
auto r1 = lua.script("c:erase(i1)", sol::script_pass_on_error);
|
||||
auto r1 = lua.safe_script("c:erase(i1)", sol::script_pass_on_error);
|
||||
REQUIRE_FALSE(r1.valid());
|
||||
auto r3 = lua.script("s2 = #c", sol::script_pass_on_error);
|
||||
auto r3 = lua.safe_script("s2 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r3.valid());
|
||||
auto r2 = lua.script("c:erase(i2)", sol::script_pass_on_error);
|
||||
auto r2 = lua.safe_script("c:erase(i2)", sol::script_pass_on_error);
|
||||
REQUIRE_FALSE(r2.valid());
|
||||
auto r4 = lua.script("s3 = #c", sol::script_pass_on_error);
|
||||
auto r4 = lua.safe_script("s3 = #c", sol::script_pass_on_error);
|
||||
REQUIRE(r4.valid());
|
||||
};
|
||||
auto fadd = [&]() {
|
||||
auto r = lua.script("c:add(17)", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("c:add(17)", sol::script_pass_on_error);
|
||||
REQUIRE_FALSE(r.valid());
|
||||
};
|
||||
auto fopset = [&]() {
|
||||
auto r = lua.script("c[5] = 18", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("c[5] = 18", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
auto fopget = [&]() {
|
||||
auto r = lua.script("v3 = c[4]", sol::script_pass_on_error);
|
||||
auto r = lua.safe_script("v3 = c[4]", sol::script_pass_on_error);
|
||||
REQUIRE(r.valid());
|
||||
};
|
||||
REQUIRE_NOTHROW(ffind());
|
||||
|
@ -892,7 +892,7 @@ TEST_CASE("containers/auxiliary functions test", "make sure the manipulation fun
|
|||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
function g (x)
|
||||
x:add(20)
|
||||
end
|
||||
|
@ -962,7 +962,7 @@ end
|
|||
REQUIRE(set.empty());
|
||||
|
||||
REQUIRE_NOTHROW([&]() {
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
c_arr[1] = 7
|
||||
c_arr[2] = 7
|
||||
c_arr[3] = 7
|
||||
|
|
|
@ -36,7 +36,7 @@ TEST_CASE("containers/returns", "make sure that even references to vectors are b
|
|||
lua.set_function("f", [&]() -> std::vector<int>& {
|
||||
return v;
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
sol::object x = lua["x"];
|
||||
sol::type xt = x.get_type();
|
||||
REQUIRE(xt == sol::type::userdata);
|
||||
|
@ -62,8 +62,8 @@ TEST_CASE("containers/table conversion", "test table conversions with as_table a
|
|||
return sol::as_nested(std::vector<std::string>{"bark", "woof"});
|
||||
});
|
||||
|
||||
lua.script("v1 = bark()");
|
||||
lua.script("v2 = woof()");
|
||||
lua.safe_script("v1 = bark()");
|
||||
lua.safe_script("v2 = woof()");
|
||||
|
||||
sol::as_table_t<std::vector<std::string>> as_table_strings = lua["v1"];
|
||||
sol::nested<std::vector<std::string>> nested_strings = lua["v2"];
|
||||
|
@ -79,7 +79,7 @@ TEST_CASE("containers/vector roundtrip", "make sure vectors can be round-tripped
|
|||
lua.set_function("f", [&]() -> std::vector<int>& {
|
||||
return v;
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
std::vector<int> x = lua["x"];
|
||||
bool areequal = x == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -91,7 +91,7 @@ TEST_CASE("containers/deque roundtrip", "make sure deques can be round-tripped")
|
|||
lua.set_function("f", [&]() -> std::deque<int>& {
|
||||
return v;
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
std::deque<int> x = lua["x"];
|
||||
bool areequal = x == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -103,7 +103,7 @@ TEST_CASE("containers/array roundtrip", "make sure arrays can be round-tripped")
|
|||
lua.set_function("f", [&]() -> std::array<int, 3>& {
|
||||
return v;
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
std::array<int, 3> x = lua["x"];
|
||||
bool areequal = x == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -115,7 +115,7 @@ TEST_CASE("containers/list roundtrip", "make sure lists can be round-tripped") {
|
|||
lua.set_function("f", [&]() -> std::list<int>& {
|
||||
return v;
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
std::list <int> x = lua["x"];
|
||||
bool areequal = x == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -127,7 +127,7 @@ TEST_CASE("containers/forward_list roundtrip", "make sure forward_lists can be r
|
|||
lua.set_function("f", [&]() -> std::forward_list<int>& {
|
||||
return v;
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
std::forward_list <int> x = lua["x"];
|
||||
bool areequal = x == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -139,7 +139,7 @@ TEST_CASE("containers/map roundtrip", "make sure maps can be round-tripped") {
|
|||
lua.set_function("f", [&]() -> std::map<std::string, int>& {
|
||||
return v;
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
std::map<std::string, int> x = lua["x"];
|
||||
bool areequal = x == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -151,7 +151,7 @@ TEST_CASE("containers/unordered_map roundtrip", "make sure unordered_maps can be
|
|||
lua.set_function("f", [&]() -> std::unordered_map<std::string, int>& {
|
||||
return v;
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
std::unordered_map<std::string, int> x = lua["x"];
|
||||
bool areequal = x == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -163,7 +163,7 @@ TEST_CASE("containers/unordered_set roundtrip", "make sure unordered_sets can be
|
|||
lua.set_function("f", [&]() -> std::unordered_set<int>& {
|
||||
return v;
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
std::unordered_set<int> x = lua["x"];
|
||||
bool areequal = x == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -175,7 +175,7 @@ TEST_CASE("containers/set roundtrip", "make sure sets can be round-tripped") {
|
|||
lua.set_function("f", [&]() -> std::set<int>& {
|
||||
return v;
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
std::set<int> x = lua["x"];
|
||||
bool areequal = x == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -187,7 +187,7 @@ TEST_CASE("containers/vector table roundtrip", "make sure vectors can be round-t
|
|||
lua.set_function("f", [&]() {
|
||||
return sol::as_table(v);
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
sol::as_table_t<std::vector<int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -199,7 +199,7 @@ TEST_CASE("containers/deque table roundtrip", "make sure deques can be round-tri
|
|||
lua.set_function("f", [&]() {
|
||||
return sol::as_table(v);
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
sol::as_table_t<std::deque<int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -211,7 +211,7 @@ TEST_CASE("containers/array table roundtrip", "make sure arrays can be round-tri
|
|||
lua.set_function("f", [&]() {
|
||||
return sol::as_table(v);
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
sol::as_table_t<std::array<int, 3>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -223,7 +223,7 @@ TEST_CASE("containers/list table roundtrip", "make sure lists can be round-tripp
|
|||
lua.set_function("f", [&]() {
|
||||
return sol::as_table(v);
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
sol::as_table_t<std::list <int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -235,7 +235,7 @@ TEST_CASE("containers/forward_list table roundtrip", "make sure forward_lists ca
|
|||
lua.set_function("f", [&]() {
|
||||
return sol::as_table(v);
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
sol::as_table_t<std::forward_list<int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -247,7 +247,7 @@ TEST_CASE("containers/map table roundtrip", "make sure maps can be round-tripped
|
|||
lua.set_function("f", [&]() {
|
||||
return sol::as_table(v);
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
sol::as_table_t<std::map<std::string, int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -259,7 +259,7 @@ TEST_CASE("containers/unordered_map table roundtrip", "make sure unordered_maps
|
|||
lua.set_function("f", [&]() {
|
||||
return sol::as_table(v);
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
sol::as_table_t<std::unordered_map<std::string, int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -271,7 +271,7 @@ TEST_CASE("containers/unordered_set table roundtrip", "make sure unordered_sets
|
|||
lua.set_function("f", [&]() {
|
||||
return sol::as_table(v);
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
sol::as_table_t<std::unordered_set<int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -283,7 +283,7 @@ TEST_CASE("containers/set table roundtrip", "make sure sets can be round-tripped
|
|||
lua.set_function("f", [&]() {
|
||||
return sol::as_table(v);
|
||||
});
|
||||
lua.script("x = f()");
|
||||
lua.safe_script("x = f()");
|
||||
sol::as_table_t<std::set<int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
REQUIRE(areequal);
|
||||
|
@ -304,11 +304,11 @@ TEST_CASE("containers/custom usertype", "make sure container usertype metatables
|
|||
);
|
||||
bark obj{ { 24, 50 } };
|
||||
lua.set("a", &obj);
|
||||
REQUIRE_NOTHROW(lua.script("assert(a:at(24) == 50)"));
|
||||
REQUIRE_NOTHROW(lua.script("a:something()"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(a:at(24) == 50)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("a:something()"));
|
||||
lua.set("a", obj);
|
||||
REQUIRE_NOTHROW(lua.script("assert(a:at(24) == 50)"));
|
||||
REQUIRE_NOTHROW(lua.script("a:something()"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(a:at(24) == 50)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("a:something()"));
|
||||
}
|
||||
|
||||
TEST_CASE("containers/const serialization kvp", "make sure const keys / values are respected") {
|
||||
|
@ -318,10 +318,10 @@ TEST_CASE("containers/const serialization kvp", "make sure const keys / values a
|
|||
lua.open_libraries();
|
||||
bark obj{ { 24, 50 } };
|
||||
lua.set("a", &obj);
|
||||
REQUIRE_NOTHROW(lua.script("assert(a[24] == 50)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(a[24] == 50)"));
|
||||
auto result = lua.safe_script("a[24] = 51", sol::script_pass_on_error);
|
||||
REQUIRE_FALSE(result.valid());
|
||||
REQUIRE_NOTHROW(lua.script("assert(a[24] == 50)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(a[24] == 50)"));
|
||||
}
|
||||
|
||||
TEST_CASE("containers/basic serialization", "make sure containers are turned into proper userdata and have basic hooks established") {
|
||||
|
@ -330,20 +330,20 @@ TEST_CASE("containers/basic serialization", "make sure containers are turned int
|
|||
lua.open_libraries();
|
||||
lua.set("b", woof{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 });
|
||||
REQUIRE_NOTHROW(
|
||||
lua.script("for k = 1, #b do assert(k == b[k]) end")
|
||||
lua.safe_script("for k = 1, #b do assert(k == b[k]) end")
|
||||
);
|
||||
woof w{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };
|
||||
lua.set("b", w);
|
||||
REQUIRE_NOTHROW(
|
||||
lua.script("for k = 1, #b do assert(k == b[k]) end")
|
||||
lua.safe_script("for k = 1, #b do assert(k == b[k]) end")
|
||||
);
|
||||
lua.set("b", &w);
|
||||
REQUIRE_NOTHROW(
|
||||
lua.script("for k = 1, #b do assert(k == b[k]) end")
|
||||
lua.safe_script("for k = 1, #b do assert(k == b[k]) end")
|
||||
);
|
||||
lua.set("b", std::ref(w));
|
||||
REQUIRE_NOTHROW(
|
||||
lua.script("for k = 1, #b do assert(k == b[k]) end")
|
||||
lua.safe_script("for k = 1, #b do assert(k == b[k]) end")
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -354,7 +354,7 @@ TEST_CASE("containers/const serialization", "make sure containers are turned int
|
|||
lua.open_libraries();
|
||||
lua.set("b", woof{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 });
|
||||
REQUIRE_NOTHROW(
|
||||
lua.script("for k, v in pairs(b) do assert(k == v) end");
|
||||
lua.safe_script("for k, v in pairs(b) do assert(k == v) end");
|
||||
);
|
||||
auto result = lua.safe_script("b[1] = 20", sol::script_pass_on_error);
|
||||
REQUIRE_FALSE(result.valid());
|
||||
|
@ -367,20 +367,20 @@ TEST_CASE("containers/table serialization", "ensure types can be serialized as t
|
|||
lua.open_libraries();
|
||||
lua.set("b", sol::as_table(woof{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }));
|
||||
REQUIRE_NOTHROW(
|
||||
lua.script("for k, v in ipairs(b) do assert(k == v) end")
|
||||
lua.safe_script("for k, v in ipairs(b) do assert(k == v) end")
|
||||
);
|
||||
woof w{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };
|
||||
lua.set("b", sol::as_table(w));
|
||||
REQUIRE_NOTHROW(
|
||||
lua.script("for k, v in ipairs(b) do assert(k == v) end")
|
||||
lua.safe_script("for k, v in ipairs(b) do assert(k == v) end")
|
||||
);
|
||||
lua.set("b", sol::as_table(&w));
|
||||
REQUIRE_NOTHROW(
|
||||
lua.script("for k, v in ipairs(b) do assert(k == v) end")
|
||||
lua.safe_script("for k, v in ipairs(b) do assert(k == v) end")
|
||||
);
|
||||
lua.set("b", sol::as_table(std::ref(w)));
|
||||
REQUIRE_NOTHROW(
|
||||
lua.script("for k, v in ipairs(b) do assert(k == v) end")
|
||||
lua.safe_script("for k, v in ipairs(b) do assert(k == v) end")
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -404,7 +404,7 @@ TEST_CASE("containers/const correctness", "usertype metatable names should reaso
|
|||
std::vector<Vec const *> bar;
|
||||
bar.push_back(&vec);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
func = function(vecs)
|
||||
for i = 1, #vecs do
|
||||
vec = vecs[i]
|
||||
|
@ -427,20 +427,20 @@ TEST_CASE("containers/arbitrary creation", "userdata and tables should be usable
|
|||
lua.set_function("test_three", test_table_return_three);
|
||||
lua.set_function("test_four", test_table_return_four);
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("a = test_one()"));
|
||||
REQUIRE_NOTHROW(lua.script("b = test_two()"));
|
||||
REQUIRE_NOTHROW(lua.script("c = test_three()"));
|
||||
REQUIRE_NOTHROW(lua.script("d = test_four()"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("a = test_one()"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("b = test_two()"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("c = test_three()"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("d = test_four()"));
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("assert(#a == 10, 'error')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(a[3] == 3, 'error')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(b.one == 1, 'error')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(b.three == 3, 'error')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(c.name == 'Rapptz', 'error')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(c.project == 'sol', 'error')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(d.one == 1, 'error')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(d.three == 3, 'error')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(d.four == 4, 'error')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(#a == 10, 'error')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(a[3] == 3, 'error')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(b.one == 1, 'error')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(b.three == 3, 'error')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(c.name == 'Rapptz', 'error')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(c.project == 'sol', 'error')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(d.one == 1, 'error')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(d.three == 3, 'error')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(d.four == 4, 'error')"));
|
||||
|
||||
sol::table a = lua.get<sol::table>("a");
|
||||
sol::table b = lua.get<sol::table>("b");
|
||||
|
@ -483,7 +483,7 @@ TEST_CASE("containers/usertype transparency", "Make sure containers pass their a
|
|||
"a_list", &B::a_list
|
||||
);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
b = B.new()
|
||||
a_ref = b.a_list[2]
|
||||
)");
|
||||
|
@ -548,7 +548,7 @@ TEST_CASE("containers/is container", "make sure the is_container trait behaves p
|
|||
machine m;
|
||||
lua["machine"] = &m;
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
machine:opt():output_help()
|
||||
)");
|
||||
|
||||
|
@ -577,7 +577,7 @@ TEST_CASE("containers/readonly", "make sure readonly members are stored appropri
|
|||
);
|
||||
lua["value"] = std::list<bar>{ {},{},{} };
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
a = foo.new()
|
||||
x = a.seq
|
||||
a.seq = value
|
||||
|
@ -597,7 +597,7 @@ TEST_CASE("containers/to_args", "Test that the to_args abstractions works") {
|
|||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
|
||||
lua.script("function f (a, b, c, d) print(a, b, c, d) return a, b, c, d end");
|
||||
lua.safe_script("function f (a, b, c, d) print(a, b, c, d) return a, b, c, d end");
|
||||
|
||||
sol::function f = lua["f"];
|
||||
int a, b, c, d;
|
||||
|
@ -637,11 +637,11 @@ TEST_CASE("containers/ipairs test", "ensure that abstractions roundtrip properly
|
|||
return std::vector<thing*>(5, &t);
|
||||
});
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
c = f()
|
||||
)");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
check = {}
|
||||
local i = 1
|
||||
while c[i] do
|
||||
|
@ -660,7 +660,7 @@ end
|
|||
TEST_CASE("containers/append idiom", "ensure the append-idiom works as intended") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
lua.script(
|
||||
lua.safe_script(
|
||||
R"(
|
||||
function f_fill(vec)
|
||||
print("#vec in lua: " .. #vec)
|
||||
|
@ -817,13 +817,13 @@ TEST_CASE("containers/input iterators", "test shitty input iterators that are al
|
|||
not_really_a_container c;
|
||||
lua["c"] = &c;
|
||||
#if SOL_LUA_VERSION > 502
|
||||
lua.script(R"lua(
|
||||
lua.safe_script(R"lua(
|
||||
for k, v in pairs(c) do
|
||||
assert((k - 1) == v:val())
|
||||
end
|
||||
)lua");
|
||||
#endif
|
||||
lua.script(R"lua(
|
||||
lua.safe_script(R"lua(
|
||||
for k=1,#c do
|
||||
v = c[k]
|
||||
assert((k - 1) == v:val())
|
||||
|
@ -849,10 +849,10 @@ TEST_CASE("containers/pairs", "test how well pairs work with the underlying syst
|
|||
lua["c"] = std::ref(c);
|
||||
lua["d"] = &d;
|
||||
|
||||
lua.script("av1, av2 = a:get(1)");
|
||||
lua.script("bv1, bv2 = b:get(1)");
|
||||
lua.script("cv1, cv2 = c:get(1)");
|
||||
lua.script("dv1, dv2 = d:get(1)");
|
||||
lua.safe_script("av1, av2 = a:get(1)");
|
||||
lua.safe_script("bv1, bv2 = b:get(1)");
|
||||
lua.safe_script("cv1, cv2 = c:get(1)");
|
||||
lua.safe_script("dv1, dv2 = d:get(1)");
|
||||
|
||||
std::vector<std::pair<std::string, int>>& la = lua["a"];
|
||||
std::array<std::pair<std::string, int>, 5>& lb = lua["b"];
|
||||
|
|
|
@ -18,7 +18,7 @@ end
|
|||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base, sol::lib::coroutine);
|
||||
lua.script(script);
|
||||
lua.safe_script(script);
|
||||
sol::coroutine cr = lua["loop"];
|
||||
|
||||
int counter;
|
||||
|
@ -47,7 +47,7 @@ end
|
|||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base, sol::lib::coroutine);
|
||||
lua.script(script);
|
||||
lua.safe_script(script);
|
||||
sol::thread runner = sol::thread::create(lua.lua_state());
|
||||
sol::state_view runnerstate = runner.state();
|
||||
sol::coroutine cr = runnerstate["loop"];
|
||||
|
|
|
@ -68,7 +68,7 @@ TEST_CASE("customization/split struct", "using the newly documented customizatio
|
|||
sol::state lua;
|
||||
|
||||
// Create a pass-through style of function
|
||||
lua.script("function f ( a, b, c ) return a + c, b end");
|
||||
lua.safe_script("function f ( a, b, c ) return a + c, b end");
|
||||
lua.set_function("g", [](int a, bool b, int c, double d) {
|
||||
return std::make_tuple(a + c, b, d + 2.5);
|
||||
});
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <sol.hpp>
|
||||
#include <iostream>
|
||||
#include "test_stack_guard.hpp"
|
||||
|
||||
|
@ -11,7 +12,7 @@ TEST_CASE("environments/get", "Envronments can be taken out of things like Lua f
|
|||
sol::stack_guard luasg(lua);
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.script("f = function() return test end");
|
||||
lua.safe_script("f = function() return test end");
|
||||
sol::function f = lua["f"];
|
||||
|
||||
sol::environment env_f(lua, sol::create);
|
||||
|
@ -21,7 +22,7 @@ TEST_CASE("environments/get", "Envronments can be taken out of things like Lua f
|
|||
int result = f();
|
||||
REQUIRE(result == 31);
|
||||
|
||||
lua.script("g = function() test = 5 end");
|
||||
lua.safe_script("g = function() test = 5 end");
|
||||
sol::function g = lua["g"];
|
||||
sol::environment env_g(lua, sol::create);
|
||||
env_g.set_on(g);
|
||||
|
@ -35,7 +36,7 @@ TEST_CASE("environments/get", "Envronments can be taken out of things like Lua f
|
|||
sol::object global_test = lua["test"];
|
||||
REQUIRE(!global_test.valid());
|
||||
|
||||
lua.script("h = function() end");
|
||||
lua.safe_script("h = function() end");
|
||||
|
||||
lua.set_function("check_f_env",
|
||||
[&lua, &env_f](sol::object target) {
|
||||
|
@ -67,9 +68,9 @@ TEST_CASE("environments/get", "Envronments can be taken out of things like Lua f
|
|||
);
|
||||
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("check_f_env(f)");
|
||||
lua.script("check_g_env(g)");
|
||||
lua.script("check_h_env(h)");
|
||||
lua.safe_script("check_f_env(f)");
|
||||
lua.safe_script("check_g_env(g)");
|
||||
lua.safe_script("check_h_env(h)");
|
||||
}());
|
||||
}
|
||||
|
||||
|
@ -80,7 +81,7 @@ TEST_CASE("environments/shadowing", "Environments can properly shadow and fallba
|
|||
|
||||
SECTION("no fallback") {
|
||||
sol::environment plain_env(lua, sol::create);
|
||||
lua.script("a = 24", plain_env);
|
||||
lua.safe_script("a = 24", plain_env);
|
||||
sol::optional<int> maybe_env_a = plain_env["a"];
|
||||
sol::optional<int> maybe_global_a = lua["a"];
|
||||
sol::optional<int> maybe_env_b = plain_env["b"];
|
||||
|
@ -96,7 +97,7 @@ TEST_CASE("environments/shadowing", "Environments can properly shadow and fallba
|
|||
}
|
||||
SECTION("fallback") {
|
||||
sol::environment env_with_fallback(lua, sol::create, lua.globals());
|
||||
lua.script("a = 56", env_with_fallback, sol::script_default_on_error);
|
||||
lua.safe_script("a = 56", env_with_fallback, sol::script_default_on_error);
|
||||
sol::optional<int> maybe_env_a = env_with_fallback["a"];
|
||||
sol::optional<int> maybe_global_a = lua["a"];
|
||||
sol::optional<int> maybe_env_b = env_with_fallback["b"];
|
||||
|
@ -115,7 +116,7 @@ TEST_CASE("environments/shadowing", "Environments can properly shadow and fallba
|
|||
sol::environment env_with_fallback(lua, sol::create, lua.globals());
|
||||
lua["env"] = env_with_fallback;
|
||||
sol::environment env = lua["env"];
|
||||
lua.script("a = 56", env, sol::script_default_on_error);
|
||||
lua.safe_script("a = 56", env, sol::script_default_on_error);
|
||||
sol::optional<int> maybe_env_a = env["a"];
|
||||
sol::optional<int> maybe_global_a = lua["a"];
|
||||
sol::optional<int> maybe_env_b = env["b"];
|
||||
|
@ -133,7 +134,7 @@ TEST_CASE("environments/shadowing", "Environments can properly shadow and fallba
|
|||
SECTION("name with newtable") {
|
||||
lua["blank_env"] = sol::new_table(0, 1);
|
||||
sol::environment plain_env = lua["blank_env"];
|
||||
lua.script("a = 24", plain_env);
|
||||
lua.safe_script("a = 24", plain_env);
|
||||
sol::optional<int> maybe_env_a = plain_env["a"];
|
||||
sol::optional<int> maybe_global_a = lua["a"];
|
||||
sol::optional<int> maybe_env_b = plain_env["b"];
|
||||
|
@ -154,7 +155,7 @@ TEST_CASE("environments/functions", "see if environments on functions are workin
|
|||
SECTION("basic") {
|
||||
sol::state lua;
|
||||
|
||||
lua.script("a = function() return 5 end");
|
||||
lua.safe_script("a = function() return 5 end");
|
||||
|
||||
sol::function a = lua["a"];
|
||||
|
||||
|
@ -170,7 +171,7 @@ TEST_CASE("environments/functions", "see if environments on functions are workin
|
|||
SECTION("return environment value") {
|
||||
sol::state lua;
|
||||
|
||||
lua.script("a = function() return test end");
|
||||
lua.safe_script("a = function() return test end");
|
||||
|
||||
sol::function a = lua["a"];
|
||||
sol::environment env(lua, sol::create);
|
||||
|
@ -184,7 +185,7 @@ TEST_CASE("environments/functions", "see if environments on functions are workin
|
|||
|
||||
SECTION("set environment value") {
|
||||
sol::state lua;
|
||||
lua.script("a = function() test = 5 end");
|
||||
lua.safe_script("a = function() test = 5 end");
|
||||
|
||||
sol::function a = lua["a"];
|
||||
sol::environment env(lua, sol::create);
|
||||
|
@ -220,7 +221,7 @@ TEST_CASE("environments/this_environment", "test various situations of pulling o
|
|||
lua["x"] = 5;
|
||||
e["x"] = 20;
|
||||
SECTION("from Lua script") {
|
||||
int value = lua.script(code, e);
|
||||
int value = lua.safe_script(code, e);
|
||||
REQUIRE(value == 30);
|
||||
}
|
||||
SECTION("from C++") {
|
||||
|
|
236
test_filters.cpp
Normal file
236
test_filters.cpp
Normal file
|
@ -0,0 +1,236 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
|
||||
#include <sol.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
TEST_CASE("filters/self", "ensure we return a direct reference to the lua userdata rather than creating a new one") {
|
||||
struct vec2 {
|
||||
float x = 20.f;
|
||||
float y = 20.f;
|
||||
|
||||
vec2& normalize() {
|
||||
float len2 = x * x + y * y;
|
||||
if (len2 != 0) {
|
||||
float len = sqrtf(len2);
|
||||
x /= len;
|
||||
y /= len;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~vec2() {
|
||||
x = std::numeric_limits<float>::lowest();
|
||||
y = std::numeric_limits<float>::lowest();
|
||||
}
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.new_usertype<vec2>("vec2",
|
||||
"x", &vec2::x,
|
||||
"y", &vec2::y,
|
||||
"normalize", sol::filters(&vec2::normalize, sol::returns_self())
|
||||
);
|
||||
REQUIRE_NOTHROW([&]() {
|
||||
lua.safe_script(R"(
|
||||
v1 = vec2.new()
|
||||
print('v1:', v1.x, v1.y)
|
||||
v2 = v1:normalize()
|
||||
print('v1:', v1.x, v1.y)
|
||||
print('v2:', v2.x, v2.y)
|
||||
print(v1, v2)
|
||||
assert(rawequal(v1, v2))
|
||||
v1 = nil
|
||||
collectgarbage()
|
||||
print(v2) -- v2 points to same, is not destroyed
|
||||
)");
|
||||
}());
|
||||
}
|
||||
|
||||
TEST_CASE("filters/self_dependency", "ensure we can keep a userdata instance alive by attaching it to the lifetime of another userdata") {
|
||||
struct dep;
|
||||
struct gc_test;
|
||||
static std::vector<dep*> deps_destroyed;
|
||||
static std::vector<gc_test*> gc_tests_destroyed;
|
||||
|
||||
struct dep {
|
||||
int value = 20;
|
||||
~dep() {
|
||||
std::cout << "\t" << "[C++] ~dep" << std::endl;
|
||||
value = std::numeric_limits<int>::max();
|
||||
deps_destroyed.push_back(this);
|
||||
}
|
||||
};
|
||||
|
||||
struct gc_test {
|
||||
|
||||
dep d;
|
||||
|
||||
~gc_test() {
|
||||
std::cout << "\t" << "[C++] ~gc_test" << std::endl;
|
||||
gc_tests_destroyed.push_back(this);
|
||||
}
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.new_usertype<dep>("dep",
|
||||
"value", &dep::value,
|
||||
sol::meta_function::to_string, [](dep& d) {
|
||||
return "{ " + std::to_string(d.value) + " }";
|
||||
}
|
||||
);
|
||||
lua.new_usertype<gc_test>("gc_test",
|
||||
"d", sol::filters(&gc_test::d, sol::self_dependency()),
|
||||
sol::meta_function::to_string, [](gc_test& g) {
|
||||
return "{ d: { " + std::to_string(g.d.value) + " } }";
|
||||
}
|
||||
);
|
||||
|
||||
lua.safe_script(R"(
|
||||
g = gc_test.new()
|
||||
d = g.d
|
||||
print("new gc_test, d = g.d")
|
||||
print("", g)
|
||||
)");
|
||||
REQUIRE(deps_destroyed.empty());
|
||||
REQUIRE(gc_tests_destroyed.empty());
|
||||
|
||||
gc_test* g = lua["g"];
|
||||
dep* d = lua["d"];
|
||||
|
||||
lua.safe_script(R"(
|
||||
print("g = nil, collectgarbage")
|
||||
g = nil
|
||||
collectgarbage()
|
||||
print("", d)
|
||||
)");
|
||||
REQUIRE(deps_destroyed.empty());
|
||||
REQUIRE(gc_tests_destroyed.empty());
|
||||
|
||||
lua.safe_script(R"(
|
||||
print("d = nil, collectgarbage")
|
||||
d = nil
|
||||
collectgarbage()
|
||||
)");
|
||||
|
||||
REQUIRE(deps_destroyed.size() == 1);
|
||||
REQUIRE(gc_tests_destroyed.size() == 1);
|
||||
REQUIRE(deps_destroyed[0] == d);
|
||||
REQUIRE(gc_tests_destroyed[0] == g);
|
||||
}
|
||||
|
||||
TEST_CASE("filters/stack_dependencies", "ensure we can take dependencies even to arguments pushed on the stack") {
|
||||
struct holder;
|
||||
struct depends_on_reference;
|
||||
struct composition_related;
|
||||
static std::vector<composition_related*> composition_relateds_destroyed;
|
||||
static std::vector<holder*> holders_destroyed;
|
||||
static std::vector<depends_on_reference*> depends_on_references_destroyed;
|
||||
|
||||
struct composition_related {
|
||||
std::string text = "bark";
|
||||
|
||||
~composition_related() {
|
||||
std::cout << "[C++] ~composition_related" << std::endl;
|
||||
text = "";
|
||||
composition_relateds_destroyed.push_back(this);
|
||||
}
|
||||
};
|
||||
|
||||
struct holder {
|
||||
int value = 20;
|
||||
~holder() {
|
||||
std::cout << "[C++] ~holder" << std::endl;
|
||||
value = std::numeric_limits<int>::max();
|
||||
holders_destroyed.push_back(this);
|
||||
}
|
||||
};
|
||||
|
||||
struct depends_on_reference {
|
||||
|
||||
std::reference_wrapper<holder> href;
|
||||
composition_related comp;
|
||||
|
||||
depends_on_reference(holder& h) : href(h) {}
|
||||
|
||||
~depends_on_reference() {
|
||||
std::cout << "[C++] ~depends_on_reference" << std::endl;
|
||||
depends_on_references_destroyed.push_back(this);
|
||||
}
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.new_usertype<holder>("holder",
|
||||
"value", &holder::value
|
||||
);
|
||||
lua.new_usertype<depends_on_reference>("depends_on_reference",
|
||||
"new", sol::filters(sol::constructors<depends_on_reference(holder&)>(), sol::stack_dependencies(-1, 1)),
|
||||
"comp", &depends_on_reference::comp
|
||||
);
|
||||
|
||||
lua.safe_script(R"(
|
||||
h = holder.new()
|
||||
dor = depends_on_reference.new(h)
|
||||
c = dor.comp
|
||||
)");
|
||||
REQUIRE(composition_relateds_destroyed.empty());
|
||||
REQUIRE(holders_destroyed.empty());
|
||||
REQUIRE(depends_on_references_destroyed.empty());
|
||||
|
||||
holder* h = lua["h"];
|
||||
composition_related* c = lua["c"];
|
||||
depends_on_reference* dor = lua["dor"];
|
||||
|
||||
REQUIRE(h == &dor->href.get());
|
||||
REQUIRE(c == &dor->comp);
|
||||
|
||||
lua.safe_script(R"(
|
||||
h = nil
|
||||
collectgarbage()
|
||||
)");
|
||||
REQUIRE(composition_relateds_destroyed.empty());
|
||||
REQUIRE(holders_destroyed.empty());
|
||||
REQUIRE(depends_on_references_destroyed.empty());
|
||||
|
||||
lua.safe_script(R"(
|
||||
c = nil
|
||||
collectgarbage()
|
||||
)");
|
||||
|
||||
REQUIRE(composition_relateds_destroyed.empty());
|
||||
REQUIRE(holders_destroyed.empty());
|
||||
REQUIRE(depends_on_references_destroyed.empty());
|
||||
|
||||
lua.safe_script(R"(
|
||||
dor = nil
|
||||
collectgarbage()
|
||||
)");
|
||||
|
||||
REQUIRE(composition_relateds_destroyed.size() == 1);
|
||||
REQUIRE(holders_destroyed.size() == 1);
|
||||
REQUIRE(depends_on_references_destroyed.size() == 1);
|
||||
REQUIRE(composition_relateds_destroyed[0] == c);
|
||||
REQUIRE(holders_destroyed[0] == h);
|
||||
REQUIRE(depends_on_references_destroyed[0] == dor);
|
||||
}
|
||||
|
||||
int always_return_24(lua_State* L, int) {
|
||||
return sol::stack::push(L, 24);
|
||||
}
|
||||
|
||||
TEST_CASE("filters/custom", "ensure we can return dependencies on multiple things in the stack") {
|
||||
|
||||
sol::state lua;
|
||||
lua.set_function("f", sol::filters([]() { return std::string("hi there"); }, always_return_24));
|
||||
|
||||
int value = lua["f"]();
|
||||
REQUIRE(value == 24);
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include "test_stack_guard.hpp"
|
||||
|
||||
|
@ -105,7 +107,7 @@ static int raw_noexcept_function(lua_State* L) noexcept {
|
|||
|
||||
TEST_CASE("functions/tuple returns", "Make sure tuple returns are ordered properly") {
|
||||
sol::state lua;
|
||||
lua.script("function f() return '3', 4 end");
|
||||
lua.safe_script("function f() return '3', 4 end");
|
||||
|
||||
std::tuple<std::string, int> result = lua["f"]();
|
||||
auto s = std::get<0>(result);
|
||||
|
@ -119,28 +121,28 @@ TEST_CASE("functions/overload resolution", "Check if overloaded function resolut
|
|||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.set_function("non_overloaded", non_overloaded);
|
||||
REQUIRE_NOTHROW(lua.script("x = non_overloaded(1, 2, 3)\nprint(x)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("x = non_overloaded(1, 2, 3)\nprint(x)"));
|
||||
|
||||
/*
|
||||
// Cannot reasonably support: clang++ refuses to try enough
|
||||
// deductions to make this work
|
||||
lua.set_function<int>("overloaded", overloaded);
|
||||
REQUIRE_NOTHROW(lua.script("print(overloaded(1))"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("print(overloaded(1))"));
|
||||
|
||||
lua.set_function<int, int>("overloaded", overloaded);
|
||||
REQUIRE_NOTHROW(lua.script("print(overloaded(1, 2))"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("print(overloaded(1, 2))"));
|
||||
|
||||
lua.set_function<int, int, int>("overloaded", overloaded);
|
||||
REQUIRE_NOTHROW(lua.script("print(overloaded(1, 2, 3))"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("print(overloaded(1, 2, 3))"));
|
||||
*/
|
||||
lua.set_function("overloaded", sol::resolve<int(int)>(overloaded));
|
||||
REQUIRE_NOTHROW(lua.script("print(overloaded(1))"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("print(overloaded(1))"));
|
||||
|
||||
lua.set_function("overloaded", sol::resolve<int(int, int)>(overloaded));
|
||||
REQUIRE_NOTHROW(lua.script("print(overloaded(1, 2))"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("print(overloaded(1, 2))"));
|
||||
|
||||
lua.set_function("overloaded", sol::resolve<int(int, int, int)>(overloaded));
|
||||
REQUIRE_NOTHROW(lua.script("print(overloaded(1, 2, 3))"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("print(overloaded(1, 2, 3))"));
|
||||
}
|
||||
|
||||
TEST_CASE("functions/return order and multi get", "Check if return order is in the same reading order specified in Lua") {
|
||||
|
@ -154,7 +156,7 @@ TEST_CASE("functions/return order and multi get", "Check if return order is in t
|
|||
lua.set_function("h", []() {
|
||||
return std::make_tuple(10, 10.0f);
|
||||
});
|
||||
lua.script("function g() return 10, 11, 12 end\nx,y,z = g()");
|
||||
lua.safe_script("function g() return 10, 11, 12 end\nx,y,z = g()");
|
||||
auto tcpp = lua.get<sol::function>("f").call<int, int, int>();
|
||||
auto tlua = lua.get<sol::function>("g").call<int, int, int>();
|
||||
auto tcpp2 = lua.get<sol::function>("h").call<int, float>();
|
||||
|
@ -180,7 +182,7 @@ TEST_CASE("functions/deducing return order and multi get", "Check if return orde
|
|||
lua.set_function("f", [] {
|
||||
return std::make_tuple(10, 11, 12);
|
||||
});
|
||||
lua.script("function g() return 10, 11, 12 end\nx,y,z = g()");
|
||||
lua.safe_script("function g() return 10, 11, 12 end\nx,y,z = g()");
|
||||
std::tuple<int, int, int> tcpp = lua.get<sol::function>("f")();
|
||||
std::tuple<int, int, int> tlua = lua.get<sol::function>("g")();
|
||||
std::tuple<int, int, int> tluaget = lua.get<int, int, int>("x", "y", "z");
|
||||
|
@ -197,7 +199,7 @@ TEST_CASE("functions/optional values", "check if optionals can be passed in to b
|
|||
int v;
|
||||
};
|
||||
sol::state lua;
|
||||
lua.script(R"( function f (a)
|
||||
lua.safe_script(R"( function f (a)
|
||||
return a
|
||||
end )");
|
||||
|
||||
|
@ -217,7 +219,7 @@ TEST_CASE("functions/pair and tuple and proxy tests", "Check if sol::reference a
|
|||
sol::state lua;
|
||||
lua.new_usertype<A>("A",
|
||||
"bark", &A::bark);
|
||||
lua.script(R"( function f (num_value, a)
|
||||
lua.safe_script(R"( function f (num_value, a)
|
||||
return num_value * 2, a:bark()
|
||||
end
|
||||
function h (num_value, a, b)
|
||||
|
@ -259,10 +261,10 @@ TEST_CASE("functions/sol::function to std::function", "check if conversion to st
|
|||
|
||||
lua.set_function("testFunc", test_free_func);
|
||||
lua.set_function("testFunc2", test_free_func2);
|
||||
lua.script(
|
||||
lua.safe_script(
|
||||
"testFunc(function() print(\"hello std::function\") end)"
|
||||
);
|
||||
REQUIRE_NOTHROW(lua.script(
|
||||
REQUIRE_NOTHROW(lua.safe_script(
|
||||
"function m(a)\n"
|
||||
" print(\"hello std::function with arg \", a)\n"
|
||||
" return a\n"
|
||||
|
@ -278,7 +280,7 @@ TEST_CASE("functions/returning functions from C++", "check to see if returning a
|
|||
|
||||
lua.set_function("makefn", makefn);
|
||||
lua.set_function("takefn", takefn);
|
||||
lua.script("afx = makefn()\n"
|
||||
lua.safe_script("afx = makefn()\n"
|
||||
"print(afx())\n"
|
||||
"takefn(afx)\n");
|
||||
}
|
||||
|
@ -308,7 +310,7 @@ TEST_CASE("functions/function_result and protected_function_result", "Function r
|
|||
return handlederrormessage;
|
||||
};
|
||||
lua.set_function("cpphandler", cpphandlerfx);
|
||||
lua.script(
|
||||
lua.safe_script(
|
||||
std::string("function luahandler ( message )")
|
||||
+ " print('lua handler called with: ' .. message)"
|
||||
+ " return '" + handlederrormessage + "'"
|
||||
|
@ -392,85 +394,6 @@ TEST_CASE("functions/function_result and protected_function_result", "Function r
|
|||
}
|
||||
}
|
||||
|
||||
TEST_CASE("functions/destructor tests", "Show that proper copies / destruction happens") {
|
||||
static int created = 0;
|
||||
static int destroyed = 0;
|
||||
static void* last_call = nullptr;
|
||||
static void* static_call = reinterpret_cast<void*>(0x01);
|
||||
typedef void(*fptr)();
|
||||
struct x {
|
||||
x() { ++created; }
|
||||
x(const x&) { ++created; }
|
||||
x(x&&) { ++created; }
|
||||
x& operator=(const x&) { return *this; }
|
||||
x& operator=(x&&) { return *this; }
|
||||
void func() { last_call = static_cast<void*>(this); };
|
||||
~x() { ++destroyed; }
|
||||
};
|
||||
struct y {
|
||||
y() { ++created; }
|
||||
y(const x&) { ++created; }
|
||||
y(x&&) { ++created; }
|
||||
y& operator=(const x&) { return *this; }
|
||||
y& operator=(x&&) { return *this; }
|
||||
static void func() { last_call = static_call; };
|
||||
void operator()() { func(); }
|
||||
operator fptr () { return func; }
|
||||
~y() { ++destroyed; }
|
||||
};
|
||||
|
||||
// stateful functors/member functions should always copy unless specified
|
||||
{
|
||||
created = 0;
|
||||
destroyed = 0;
|
||||
last_call = nullptr;
|
||||
{
|
||||
sol::state lua;
|
||||
x x1;
|
||||
lua.set_function("x1copy", &x::func, x1);
|
||||
lua.script("x1copy()");
|
||||
REQUIRE(created == 2);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE_FALSE(last_call == &x1);
|
||||
|
||||
lua.set_function("x1ref", &x::func, std::ref(x1));
|
||||
lua.script("x1ref()");
|
||||
REQUIRE(created == 2);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE(last_call == &x1);
|
||||
}
|
||||
REQUIRE(created == 2);
|
||||
REQUIRE(destroyed == 2);
|
||||
}
|
||||
|
||||
// things convertible to a static function should _never_ be forced to make copies
|
||||
// therefore, pass through untouched
|
||||
{
|
||||
created = 0;
|
||||
destroyed = 0;
|
||||
last_call = nullptr;
|
||||
{
|
||||
sol::state lua;
|
||||
y y1;
|
||||
lua.set_function("y1copy", y1);
|
||||
lua.script("y1copy()");
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE(last_call == static_call);
|
||||
|
||||
last_call = nullptr;
|
||||
lua.set_function("y1ref", std::ref(y1));
|
||||
lua.script("y1ref()");
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE(last_call == static_call);
|
||||
}
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("functions/all kinds", "Register all kinds of functions, make sure they all compile and work") {
|
||||
sol::state lua;
|
||||
|
||||
|
@ -531,12 +454,12 @@ TEST_CASE("functions/all kinds", "Register all kinds of functions, make sure the
|
|||
lua.set_function("m", &test_2::a, &t2);
|
||||
lua.set_function("n", sol::c_call<decltype(&non_overloaded), &non_overloaded>);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
o1 = test_1.new()
|
||||
o2 = test_2.new()
|
||||
)");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
ob = o1:bark()
|
||||
|
||||
A = a()
|
||||
|
@ -551,32 +474,32 @@ I = i(o1)
|
|||
)");
|
||||
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
J0 = j()
|
||||
j(24)
|
||||
J1 = j()
|
||||
)");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
K0 = k(o2)
|
||||
k(o2, 1024)
|
||||
K1 = k(o2)
|
||||
)");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
L0 = l(o1)
|
||||
l(o1, 678)
|
||||
L1 = l(o1)
|
||||
)");
|
||||
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
M0 = m()
|
||||
m(256)
|
||||
M1 = m()
|
||||
)");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
N = n(1, 2, 3)
|
||||
)");
|
||||
int ob, A, B, C, D, F, G0, G1, H, I, J0, J1, K0, K1, L0, L1, M0, M1, N;
|
||||
|
@ -677,9 +600,9 @@ N = n(1, 2, 3)
|
|||
TEST_CASE("simple/call with parameters", "Lua function is called with a few parameters from C++") {
|
||||
sol::state lua;
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("function my_add(i, j, k) return i + j + k end"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("function my_add(i, j, k) return i + j + k end"));
|
||||
auto f = lua.get<sol::function>("my_add");
|
||||
REQUIRE_NOTHROW(lua.script("function my_nothing(i, j, k) end"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("function my_nothing(i, j, k) end"));
|
||||
auto fvoid = lua.get<sol::function>("my_nothing");
|
||||
REQUIRE_NOTHROW([&]() {
|
||||
fvoid(1, 2, 3);
|
||||
|
@ -699,7 +622,7 @@ TEST_CASE("simple/call c++ function", "C++ function is called from lua") {
|
|||
sol::state lua;
|
||||
|
||||
lua.set_function("plop_xyz", sep::plop_xyz);
|
||||
lua.script("x = plop_xyz(2, 6, 'hello')");
|
||||
lua.safe_script("x = plop_xyz(2, 6, 'hello')");
|
||||
|
||||
REQUIRE(lua.get<int>("x") == 11);
|
||||
}
|
||||
|
@ -711,7 +634,7 @@ TEST_CASE("simple/call lambda", "A C++ lambda is exposed to lua and called") {
|
|||
|
||||
lua.set_function("foo", [&a] { a = 1; });
|
||||
|
||||
lua.script("foo()");
|
||||
lua.safe_script("foo()");
|
||||
|
||||
REQUIRE(a == 1);
|
||||
}
|
||||
|
@ -795,7 +718,7 @@ TEST_CASE("advanced/call lambdas", "A C++ lambda is exposed to lua and called")
|
|||
return 0;
|
||||
});
|
||||
|
||||
lua.script("set_x(9)");
|
||||
lua.safe_script("set_x(9)");
|
||||
REQUIRE(x == 9);
|
||||
}
|
||||
|
||||
|
@ -816,8 +739,8 @@ TEST_CASE("advanced/call referenced obj", "A C++ object is passed by pointer/ref
|
|||
};
|
||||
lua.set_function("set_y", &decltype(objy)::operator(), std::ref(objy));
|
||||
|
||||
lua.script("set_x(9)");
|
||||
lua.script("set_y(9)");
|
||||
lua.safe_script("set_x(9)");
|
||||
lua.safe_script("set_y(9)");
|
||||
REQUIRE(x == 9);
|
||||
REQUIRE(y == 9);
|
||||
}
|
||||
|
@ -825,7 +748,7 @@ TEST_CASE("advanced/call referenced obj", "A C++ object is passed by pointer/ref
|
|||
TEST_CASE("functions/tie", "make sure advanced syntax with 'tie' works") {
|
||||
sol::state lua;
|
||||
|
||||
lua.script(R"(function f ()
|
||||
lua.safe_script(R"(function f ()
|
||||
return 1, 2, 3
|
||||
end)");
|
||||
sol::function f = lua["f"];
|
||||
|
@ -846,7 +769,7 @@ TEST_CASE("functions/overloading", "Check if overloading works properly for regu
|
|||
|
||||
const std::string string_bark = "string: bark";
|
||||
|
||||
REQUIRE_NOTHROW(lua.script(
|
||||
REQUIRE_NOTHROW(lua.safe_script(
|
||||
"a = func(1)\n"
|
||||
"b = func('bark')\n"
|
||||
"c = func(1,2)\n"
|
||||
|
@ -868,11 +791,11 @@ TEST_CASE("overloading/c_call", "Make sure that overloading works with c_call fu
|
|||
lua.set("h", sol::c_call<decltype(&f2), &f2>);
|
||||
lua.set("obj", fer());
|
||||
|
||||
lua.script("r1 = f(1)");
|
||||
lua.script("r2 = f(1, 2)");
|
||||
lua.script("r3 = f(obj, 1, 2)");
|
||||
lua.script("r4 = g(1)");
|
||||
lua.script("r5 = h(1, 2)");
|
||||
lua.safe_script("r1 = f(1)");
|
||||
lua.safe_script("r2 = f(1, 2)");
|
||||
lua.safe_script("r3 = f(obj, 1, 2)");
|
||||
lua.safe_script("r4 = g(1)");
|
||||
lua.safe_script("r5 = h(1, 2)");
|
||||
|
||||
int r1 = lua["r1"];
|
||||
int r2 = lua["r2"];
|
||||
|
@ -892,8 +815,8 @@ TEST_CASE("functions/stack atomic", "make sure functions don't impede on the sta
|
|||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base, sol::lib::string);
|
||||
|
||||
lua.script("function ErrorHandler(msg) print('Lua created error msg : ' .. msg) return msg end");
|
||||
lua.script("function stringtest(a) if a == nil then error('fuck') end print('Lua recieved content : ' .. a) return a end");
|
||||
lua.safe_script("function ErrorHandler(msg) print('Lua created error msg : ' .. msg) return msg end");
|
||||
lua.safe_script("function stringtest(a) if a == nil then error('fuck') end print('Lua recieved content : ' .. a) return a end");
|
||||
|
||||
// test normal function
|
||||
{
|
||||
|
@ -941,48 +864,9 @@ TEST_CASE("functions/stack atomic", "make sure functions don't impede on the sta
|
|||
REQUIRE(sg.check_stack());
|
||||
}
|
||||
|
||||
TEST_CASE("functions/same type closures", "make sure destructions are per-object, not per-type, by destroying one type multiple times") {
|
||||
static std::set<void*> last_my_closures;
|
||||
static bool checking_closures = false;
|
||||
static bool check_failed = false;
|
||||
|
||||
struct my_closure {
|
||||
int& n;
|
||||
|
||||
my_closure(int& n) : n(n) {}
|
||||
~my_closure() noexcept(false) {
|
||||
if (!checking_closures)
|
||||
return;
|
||||
void* addr = static_cast<void*>(this);
|
||||
auto f = last_my_closures.find(addr);
|
||||
if (f != last_my_closures.cend()) {
|
||||
check_failed = true;
|
||||
}
|
||||
last_my_closures.insert(f, addr);
|
||||
}
|
||||
|
||||
int operator() () {
|
||||
++n; return n;
|
||||
}
|
||||
};
|
||||
|
||||
int n = 250;
|
||||
my_closure a(n);
|
||||
my_closure b(n);
|
||||
{
|
||||
sol::state lua;
|
||||
|
||||
lua.set_function("f", a);
|
||||
lua.set_function("g", b);
|
||||
checking_closures = true;
|
||||
}
|
||||
REQUIRE_FALSE(check_failed);
|
||||
REQUIRE(last_my_closures.size() == 2);
|
||||
}
|
||||
|
||||
TEST_CASE("functions/stack multi-return", "Make sure the stack is protected after multi-returns") {
|
||||
sol::state lua;
|
||||
lua.script("function f () return 1, 2, 3, 4, 5 end");
|
||||
lua.safe_script("function f () return 1, 2, 3, 4, 5 end");
|
||||
|
||||
{
|
||||
sol::stack_guard sg(lua);
|
||||
|
@ -1005,7 +889,7 @@ TEST_CASE("functions/stack multi-return", "Make sure the stack is protected afte
|
|||
|
||||
TEST_CASE("functions/protected stack multi-return", "Make sure the stack is protected after multi-returns") {
|
||||
sol::state lua;
|
||||
lua.script("function f () return 1, 2, 3, 4, 5 end");
|
||||
lua.safe_script("function f () return 1, 2, 3, 4, 5 end");
|
||||
|
||||
{
|
||||
sol::stack_guard sg(lua);
|
||||
|
@ -1030,8 +914,8 @@ TEST_CASE("functions/function_result as arguments", "ensure that function_result
|
|||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
|
||||
lua.script("function f () return 1, 2, 3, 4, 5 end");
|
||||
lua.script("function g (a, b, c, d, e) assert(a == 1) assert(b == 2) assert(c == 3) assert(d == 4) assert(e == 5) end");
|
||||
lua.safe_script("function f () return 1, 2, 3, 4, 5 end");
|
||||
lua.safe_script("function g (a, b, c, d, e) assert(a == 1) assert(b == 2) assert(c == 3) assert(d == 4) assert(e == 5) end");
|
||||
|
||||
{
|
||||
sol::stack_guard sg(lua);
|
||||
|
@ -1059,8 +943,8 @@ TEST_CASE("functions/protected_function_result as arguments", "ensure that prote
|
|||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
|
||||
lua.script("function f () return 1, 2, 3, 4, 5 end");
|
||||
lua.script("function g (a, b, c, d, e) assert(a == 1) assert(b == 2) assert(c == 3) assert(d == 4) assert(e == 5) end");
|
||||
lua.safe_script("function f () return 1, 2, 3, 4, 5 end");
|
||||
lua.safe_script("function g (a, b, c, d, e) assert(a == 1) assert(b == 2) assert(c == 3) assert(d == 4) assert(e == 5) end");
|
||||
|
||||
{
|
||||
sol::stack_guard sg(lua);
|
||||
|
@ -1091,9 +975,9 @@ TEST_CASE("functions/overloaded variadic", "make sure variadics work to some deg
|
|||
sol::table ssl = lua.create_named_table("ssl");
|
||||
ssl.set_function("test", sol::overload(&va_func<int>, &va_func<double>));
|
||||
|
||||
lua.script("a = ssl.test(1, 2, 3)");
|
||||
lua.script("b = ssl.test(1, 2)");
|
||||
lua.script("c = ssl.test(2.2)");
|
||||
lua.safe_script("a = ssl.test(1, 2, 3)");
|
||||
lua.safe_script("b = ssl.test(1, 2)");
|
||||
lua.safe_script("c = ssl.test(2.2)");
|
||||
|
||||
int a = lua["a"];
|
||||
int b = lua["b"];
|
||||
|
@ -1117,20 +1001,20 @@ TEST_CASE("functions/sectioning variadic", "make sure variadics can bite off chu
|
|||
return r;
|
||||
});
|
||||
|
||||
lua.script("x = f(1, 2, 3, 4)");
|
||||
lua.script("x2 = f(8, 200, 3, 4)");
|
||||
lua.script("x3 = f(1, 2, 3, 4, 5, 6)");
|
||||
lua.safe_script("x = f(1, 2, 3, 4)");
|
||||
lua.safe_script("x2 = f(8, 200, 3, 4)");
|
||||
lua.safe_script("x3 = f(1, 2, 3, 4, 5, 6)");
|
||||
|
||||
lua.script("print(x) assert(x == 7)");
|
||||
lua.script("print(x2) assert(x2 == 7)");
|
||||
lua.script("print(x3) assert(x3 == 18)");
|
||||
lua.safe_script("print(x) assert(x == 7)");
|
||||
lua.safe_script("print(x2) assert(x2 == 7)");
|
||||
lua.safe_script("print(x3) assert(x3 == 18)");
|
||||
}
|
||||
|
||||
TEST_CASE("functions/set_function already wrapped", "setting a function returned from Lua code that is already wrapped into a sol::function or similar") {
|
||||
SECTION("test different types") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
sol::function fn = lua.script("return function() return 5 end");
|
||||
sol::function fn = lua.safe_script("return function() return 5 end");
|
||||
sol::protected_function pfn = fn;
|
||||
std::function<int()> sfn = fn;
|
||||
|
||||
|
@ -1138,23 +1022,23 @@ TEST_CASE("functions/set_function already wrapped", "setting a function returned
|
|||
lua.set_function("test2", pfn);
|
||||
lua.set_function("test3", sfn);
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("assert(type(test) == 'function')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(test() ~= nil)"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(test() == 5)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(type(test) == 'function')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(test() ~= nil)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(test() == 5)"));
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("assert(type(test2) == 'function')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(test2() ~= nil)"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(test2() == 5)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(type(test2) == 'function')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(test2() ~= nil)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(test2() == 5)"));
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("assert(type(test3) == 'function')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(test3() ~= nil)"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(test3() == 5)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(type(test3) == 'function')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(test3() ~= nil)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(test3() == 5)"));
|
||||
}
|
||||
|
||||
SECTION("getting the value from C++") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
sol::function fn = lua.script("return function() return 5 end");
|
||||
sol::function fn = lua.safe_script("return function() return 5 end");
|
||||
|
||||
int result = fn();
|
||||
REQUIRE(result == 5);
|
||||
|
@ -1163,13 +1047,13 @@ TEST_CASE("functions/set_function already wrapped", "setting a function returned
|
|||
SECTION("setting the function directly") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
sol::function fn = lua.script("return function() return 5 end");
|
||||
sol::function fn = lua.safe_script("return function() return 5 end");
|
||||
|
||||
lua.set_function("test", fn);
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("assert(type(test) == 'function')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(test() ~= nil)"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(test() == 5)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(type(test) == 'function')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(test() ~= nil)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(test() == 5)"));
|
||||
|
||||
}
|
||||
|
||||
|
@ -1177,23 +1061,23 @@ TEST_CASE("functions/set_function already wrapped", "setting a function returned
|
|||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
sol::function fn2 = lua.script("return function() print('this was executed') end");
|
||||
sol::function fn2 = lua.safe_script("return function() print('this was executed') end");
|
||||
lua.set_function("test", fn2);
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("assert(type(test) == 'function')"));
|
||||
REQUIRE_NOTHROW(lua.script("test()"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(type(test) == 'function')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("test()"));
|
||||
}
|
||||
|
||||
SECTION("setting the function indirectly, with the return value cast explicitly") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
sol::function fn = lua.script("return function() return 5 end");
|
||||
sol::function fn = lua.safe_script("return function() return 5 end");
|
||||
|
||||
lua.set_function("test", [&fn]() { return fn.call<int>(); });
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("assert(type(test) == 'function')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(test() ~= nil)"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(test() == 5)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(type(test) == 'function')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(test() ~= nil)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(test() == 5)"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1252,15 +1136,15 @@ TEST_CASE("functions/pointer nullptr + nil", "ensure specific semantics for hand
|
|||
lua["h"] = &nil_test::h;
|
||||
|
||||
REQUIRE_NOTHROW([&]() {
|
||||
lua.script("f(v1)");
|
||||
lua.script("f(v2)");
|
||||
lua.script("f(v3)");
|
||||
lua.script("f(v4)");
|
||||
lua.safe_script("f(v1)");
|
||||
lua.safe_script("f(v2)");
|
||||
lua.safe_script("f(v3)");
|
||||
lua.safe_script("f(v4)");
|
||||
|
||||
lua.script("assert(v1 == nil)");
|
||||
lua.script("assert(v2 == nil)");
|
||||
lua.script("assert(v3 == nil)");
|
||||
lua.script("assert(v4 == nil)");
|
||||
lua.safe_script("assert(v1 == nil)");
|
||||
lua.safe_script("assert(v2 == nil)");
|
||||
lua.safe_script("assert(v3 == nil)");
|
||||
lua.safe_script("assert(v4 == nil)");
|
||||
}());
|
||||
}
|
||||
SECTION("throw unique argument") {
|
||||
|
@ -1405,16 +1289,16 @@ TEST_CASE("functions/unique_usertype overloading", "make sure overloading can wo
|
|||
lua["v4"] = ut.get();
|
||||
|
||||
REQUIRE_NOTHROW([&]() {
|
||||
lua.script("f(v1)");
|
||||
lua.script("g(v1)");
|
||||
lua.script("g(v2)");
|
||||
lua.script("g(v3)");
|
||||
lua.script("g(v4)");
|
||||
lua.script("h(v1)");
|
||||
lua.script("h(v2)");
|
||||
lua.script("h(v3)");
|
||||
lua.script("h(v4)");
|
||||
lua.script("i(20, v1)");
|
||||
lua.safe_script("f(v1)");
|
||||
lua.safe_script("g(v1)");
|
||||
lua.safe_script("g(v2)");
|
||||
lua.safe_script("g(v3)");
|
||||
lua.safe_script("g(v4)");
|
||||
lua.safe_script("h(v1)");
|
||||
lua.safe_script("h(v2)");
|
||||
lua.safe_script("h(v3)");
|
||||
lua.safe_script("h(v4)");
|
||||
lua.safe_script("i(20, v1)");
|
||||
}());
|
||||
};
|
||||
// LuaJIT segfaults hard on some Linux machines
|
||||
|
@ -1473,14 +1357,14 @@ TEST_CASE("functions/noexcept", "allow noexcept functions to be serialized prope
|
|||
lua.set_function("m", ccall);
|
||||
|
||||
lua["t"] = T();
|
||||
lua.script("v1 = f()");
|
||||
lua.script("v2 = g(t)");
|
||||
lua.script("v3 = h()");
|
||||
lua.script("v4 = i()");
|
||||
lua.script("v5 = j()");
|
||||
lua.script("v6 = k()");
|
||||
lua.script("v7 = l()");
|
||||
lua.script("v8 = m()");
|
||||
lua.safe_script("v1 = f()");
|
||||
lua.safe_script("v2 = g(t)");
|
||||
lua.safe_script("v3 = h()");
|
||||
lua.safe_script("v4 = i()");
|
||||
lua.safe_script("v5 = j()");
|
||||
lua.safe_script("v6 = k()");
|
||||
lua.safe_script("v7 = l()");
|
||||
lua.safe_script("v8 = m()");
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
int v3 = lua["v3"];
|
||||
|
|
504
test_gc.cpp
Normal file
504
test_gc.cpp
Normal file
|
@ -0,0 +1,504 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
|
||||
#include <sol.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
TEST_CASE("gc/destructors", "test if destructors are fired properly through gc of unbound usertypes") {
|
||||
struct test;
|
||||
static std::vector<test*> tests_destroyed;
|
||||
struct test {
|
||||
int v = 10;
|
||||
~test() {
|
||||
tests_destroyed.push_back(this);
|
||||
}
|
||||
};
|
||||
test t;
|
||||
test* pt = nullptr;
|
||||
{
|
||||
sol::state lua;
|
||||
|
||||
lua["t"] = test{};
|
||||
pt = lua["t"];
|
||||
}
|
||||
|
||||
REQUIRE(tests_destroyed.size() == 2);
|
||||
REQUIRE(tests_destroyed.back() == pt);
|
||||
|
||||
{
|
||||
sol::state lua;
|
||||
|
||||
lua["t"] = &t;
|
||||
pt = lua["t"];
|
||||
}
|
||||
|
||||
REQUIRE(tests_destroyed.size() == 2);
|
||||
REQUIRE(&t == pt);
|
||||
|
||||
{
|
||||
sol::state lua;
|
||||
|
||||
lua["t"] = std::ref(t);
|
||||
pt = lua["t"];
|
||||
}
|
||||
|
||||
REQUIRE(tests_destroyed.size() == 2);
|
||||
REQUIRE(&t == pt);
|
||||
|
||||
{
|
||||
sol::state lua;
|
||||
|
||||
lua["t"] = t;
|
||||
pt = lua["t"];
|
||||
}
|
||||
|
||||
REQUIRE(tests_destroyed.size() == 3);
|
||||
REQUIRE(&t != pt);
|
||||
REQUIRE(nullptr != pt);
|
||||
}
|
||||
|
||||
TEST_CASE("gc/function argument storage", "ensure functions take references on their types, not ownership, when specified") {
|
||||
class gc_entity;
|
||||
static std::vector<gc_entity*> entities;
|
||||
|
||||
class gc_entity {
|
||||
public:
|
||||
~gc_entity() { entities.push_back(this); }
|
||||
};
|
||||
SECTION("plain") {
|
||||
entities.clear();
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
sol::function f = lua.safe_script(R"(
|
||||
return function(e)
|
||||
end
|
||||
)");
|
||||
gc_entity* target = nullptr;
|
||||
{
|
||||
gc_entity e;
|
||||
target = &e;
|
||||
{
|
||||
f(e); // same with std::ref(e)!
|
||||
lua.collect_garbage(); // destroys e for some reason
|
||||
}
|
||||
{
|
||||
f(&e); // same with std::ref(e)!
|
||||
lua.collect_garbage(); // destroys e for some reason
|
||||
}
|
||||
{
|
||||
f(std::ref(e)); // same with std::ref(e)!
|
||||
lua.collect_garbage(); // destroys e for some reason
|
||||
}
|
||||
|
||||
}
|
||||
REQUIRE(entities.size() == 1);
|
||||
REQUIRE(entities.back() == target);
|
||||
}
|
||||
SECTION("regular") {
|
||||
entities.clear();
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
lua.new_usertype<gc_entity>("entity");
|
||||
sol::function f = lua.safe_script(R"(
|
||||
return function(e)
|
||||
end
|
||||
)");
|
||||
gc_entity* target = nullptr;
|
||||
{
|
||||
gc_entity e;
|
||||
target = &e;
|
||||
{
|
||||
f(e); // same with std::ref(e)!
|
||||
lua.collect_garbage(); // destroys e for some reason
|
||||
}
|
||||
{
|
||||
f(&e); // same with std::ref(e)!
|
||||
lua.collect_garbage(); // destroys e for some reason
|
||||
}
|
||||
{
|
||||
f(std::ref(e)); // same with std::ref(e)!
|
||||
lua.collect_garbage(); // destroys e for some reason
|
||||
}
|
||||
|
||||
}
|
||||
REQUIRE(entities.size() == 1);
|
||||
REQUIRE(entities.back() == target);
|
||||
}
|
||||
SECTION("simple") {
|
||||
entities.clear();
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
lua.new_simple_usertype<gc_entity>("entity");
|
||||
sol::function f = lua.safe_script(R"(
|
||||
return function(e)
|
||||
end
|
||||
)");
|
||||
gc_entity* target = nullptr;
|
||||
{
|
||||
gc_entity e;
|
||||
target = &e;
|
||||
{
|
||||
f(e); // same with std::ref(e)!
|
||||
lua.collect_garbage(); // destroys e for some reason
|
||||
}
|
||||
{
|
||||
f(&e); // same with std::ref(e)!
|
||||
lua.collect_garbage(); // destroys e for some reason
|
||||
}
|
||||
{
|
||||
f(std::ref(e)); // same with std::ref(e)!
|
||||
lua.collect_garbage(); // destroys e for some reason
|
||||
}
|
||||
|
||||
}
|
||||
REQUIRE(entities.size() == 1);
|
||||
REQUIRE(entities.back() == target);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("gc/function storage", "show that proper copies / destruction happens for function storage (or not)") {
|
||||
static int created = 0;
|
||||
static int destroyed = 0;
|
||||
static void* last_call = nullptr;
|
||||
static void* static_call = reinterpret_cast<void*>(0x01);
|
||||
typedef void(*fptr)();
|
||||
struct x {
|
||||
x() { ++created; }
|
||||
x(const x&) { ++created; }
|
||||
x(x&&) { ++created; }
|
||||
x& operator=(const x&) { return *this; }
|
||||
x& operator=(x&&) { return *this; }
|
||||
void func() { last_call = static_cast<void*>(this); };
|
||||
~x() { ++destroyed; }
|
||||
};
|
||||
struct y {
|
||||
y() { ++created; }
|
||||
y(const x&) { ++created; }
|
||||
y(x&&) { ++created; }
|
||||
y& operator=(const x&) { return *this; }
|
||||
y& operator=(x&&) { return *this; }
|
||||
static void func() { last_call = static_call; };
|
||||
void operator()() { func(); }
|
||||
operator fptr () { return func; }
|
||||
~y() { ++destroyed; }
|
||||
};
|
||||
|
||||
// stateful functors/member functions should always copy unless specified
|
||||
{
|
||||
created = 0;
|
||||
destroyed = 0;
|
||||
last_call = nullptr;
|
||||
{
|
||||
sol::state lua;
|
||||
x x1;
|
||||
lua.set_function("x1copy", &x::func, x1);
|
||||
lua.safe_script("x1copy()");
|
||||
REQUIRE(created == 2);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE_FALSE(last_call == &x1);
|
||||
|
||||
lua.set_function("x1ref", &x::func, std::ref(x1));
|
||||
lua.safe_script("x1ref()");
|
||||
REQUIRE(created == 2);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE(last_call == &x1);
|
||||
}
|
||||
REQUIRE(created == 2);
|
||||
REQUIRE(destroyed == 2);
|
||||
}
|
||||
|
||||
// things convertible to a static function should _never_ be forced to make copies
|
||||
// therefore, pass through untouched
|
||||
{
|
||||
created = 0;
|
||||
destroyed = 0;
|
||||
last_call = nullptr;
|
||||
{
|
||||
sol::state lua;
|
||||
y y1;
|
||||
lua.set_function("y1copy", y1);
|
||||
lua.safe_script("y1copy()");
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE(last_call == static_call);
|
||||
|
||||
last_call = nullptr;
|
||||
lua.set_function("y1ref", std::ref(y1));
|
||||
lua.safe_script("y1ref()");
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE(last_call == static_call);
|
||||
}
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("gc/same type closures", "make sure destructions are per-object, not per-type, by destroying one type multiple times") {
|
||||
static std::set<void*> last_my_closures;
|
||||
static bool checking_closures = false;
|
||||
static bool check_failed = false;
|
||||
|
||||
struct my_closure {
|
||||
int& n;
|
||||
|
||||
my_closure(int& n) : n(n) {}
|
||||
~my_closure() noexcept(false) {
|
||||
if (!checking_closures)
|
||||
return;
|
||||
void* addr = static_cast<void*>(this);
|
||||
auto f = last_my_closures.find(addr);
|
||||
if (f != last_my_closures.cend()) {
|
||||
check_failed = true;
|
||||
}
|
||||
last_my_closures.insert(f, addr);
|
||||
}
|
||||
|
||||
int operator() () {
|
||||
++n; return n;
|
||||
}
|
||||
};
|
||||
|
||||
int n = 250;
|
||||
my_closure a(n);
|
||||
my_closure b(n);
|
||||
{
|
||||
sol::state lua;
|
||||
|
||||
lua.set_function("f", a);
|
||||
lua.set_function("g", b);
|
||||
checking_closures = true;
|
||||
}
|
||||
REQUIRE_FALSE(check_failed);
|
||||
REQUIRE(last_my_closures.size() == 2);
|
||||
}
|
||||
|
||||
TEST_CASE("gc/usertypes", "show that proper copies / destruction happens for usertypes") {
|
||||
static int created = 0;
|
||||
static int destroyed = 0;
|
||||
struct x {
|
||||
x() { ++created; }
|
||||
x(const x&) { ++created; }
|
||||
x(x&&) { ++created; }
|
||||
x& operator=(const x&) { return *this; }
|
||||
x& operator=(x&&) { return *this; }
|
||||
~x() { ++destroyed; }
|
||||
};
|
||||
SECTION("plain") {
|
||||
created = 0;
|
||||
destroyed = 0;
|
||||
{
|
||||
sol::state lua;
|
||||
x x1;
|
||||
x x2;
|
||||
lua.set("x1copy", x1, "x2copy", x2, "x1ref", std::ref(x1));
|
||||
x& x1copyref = lua["x1copy"];
|
||||
x& x2copyref = lua["x2copy"];
|
||||
x& x1ref = lua["x1ref"];
|
||||
REQUIRE(created == 4);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE(std::addressof(x1) == std::addressof(x1ref));
|
||||
REQUIRE(std::addressof(x1copyref) != std::addressof(x1));
|
||||
REQUIRE(std::addressof(x2copyref) != std::addressof(x2));
|
||||
}
|
||||
REQUIRE(created == 4);
|
||||
REQUIRE(destroyed == 4);
|
||||
}
|
||||
SECTION("regular") {
|
||||
created = 0;
|
||||
destroyed = 0;
|
||||
{
|
||||
sol::state lua;
|
||||
lua.new_usertype<x>("x");
|
||||
x x1;
|
||||
x x2;
|
||||
lua.set("x1copy", x1, "x2copy", x2, "x1ref", std::ref(x1));
|
||||
x& x1copyref = lua["x1copy"];
|
||||
x& x2copyref = lua["x2copy"];
|
||||
x& x1ref = lua["x1ref"];
|
||||
REQUIRE(created == 4);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE(std::addressof(x1) == std::addressof(x1ref));
|
||||
REQUIRE(std::addressof(x1copyref) != std::addressof(x1));
|
||||
REQUIRE(std::addressof(x2copyref) != std::addressof(x2));
|
||||
}
|
||||
REQUIRE(created == 4);
|
||||
REQUIRE(destroyed == 4);
|
||||
}
|
||||
SECTION("simple") {
|
||||
created = 0;
|
||||
destroyed = 0;
|
||||
{
|
||||
sol::state lua;
|
||||
lua.new_simple_usertype<x>("x");
|
||||
x x1;
|
||||
x x2;
|
||||
lua.set("x1copy", x1, "x2copy", x2, "x1ref", std::ref(x1));
|
||||
x& x1copyref = lua["x1copy"];
|
||||
x& x2copyref = lua["x2copy"];
|
||||
x& x1ref = lua["x1ref"];
|
||||
REQUIRE(created == 4);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE(std::addressof(x1) == std::addressof(x1ref));
|
||||
REQUIRE(std::addressof(x1copyref) != std::addressof(x1));
|
||||
REQUIRE(std::addressof(x2copyref) != std::addressof(x2));
|
||||
}
|
||||
REQUIRE(created == 4);
|
||||
REQUIRE(destroyed == 4);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("gc/double-deletion tests", "make sure usertypes are properly destructed and don't double-delete memory or segfault") {
|
||||
class crash_class {
|
||||
public:
|
||||
crash_class() {}
|
||||
~crash_class() { a = 10; }
|
||||
private:
|
||||
int a;
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
|
||||
SECTION("regular") {
|
||||
lua.new_usertype<crash_class>("CrashClass",
|
||||
sol::call_constructor, sol::constructors<sol::types<>>()
|
||||
);
|
||||
|
||||
lua.safe_script(R"(
|
||||
function testCrash()
|
||||
local x = CrashClass()
|
||||
end
|
||||
)");
|
||||
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
lua["testCrash"]();
|
||||
}
|
||||
}
|
||||
SECTION("simple") {
|
||||
lua.new_simple_usertype<crash_class>("CrashClass",
|
||||
sol::call_constructor, sol::constructors<sol::types<>>()
|
||||
);
|
||||
|
||||
lua.safe_script(R"(
|
||||
function testCrash()
|
||||
local x = CrashClass()
|
||||
end
|
||||
)");
|
||||
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
lua["testCrash"]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("gc/shared_ptr regression", "metatables should not screw over unique usertype metatables") {
|
||||
static int created = 0;
|
||||
static int destroyed = 0;
|
||||
struct test {
|
||||
test() {
|
||||
++created;
|
||||
}
|
||||
|
||||
~test() {
|
||||
++destroyed;
|
||||
}
|
||||
};
|
||||
|
||||
SECTION("regular") {
|
||||
created = 0;
|
||||
destroyed = 0;
|
||||
{
|
||||
std::list<std::shared_ptr<test>> tests;
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
|
||||
lua.new_usertype<test>("test",
|
||||
"create", [&]() -> std::shared_ptr<test> {
|
||||
tests.push_back(std::make_shared<test>());
|
||||
return tests.back();
|
||||
}
|
||||
);
|
||||
REQUIRE(created == 0);
|
||||
REQUIRE(destroyed == 0);
|
||||
lua.safe_script("x = test.create()");
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE_FALSE(tests.empty());
|
||||
std::shared_ptr<test>& x = lua["x"];
|
||||
std::size_t xuse = x.use_count();
|
||||
std::size_t tuse = tests.back().use_count();
|
||||
REQUIRE(xuse == tuse);
|
||||
}
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 1);
|
||||
}
|
||||
SECTION("simple") {
|
||||
created = 0;
|
||||
destroyed = 0;
|
||||
{
|
||||
std::list<std::shared_ptr<test>> tests;
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
|
||||
lua.new_simple_usertype<test>("test",
|
||||
"create", [&]() -> std::shared_ptr<test> {
|
||||
tests.push_back(std::make_shared<test>());
|
||||
return tests.back();
|
||||
}
|
||||
);
|
||||
REQUIRE(created == 0);
|
||||
REQUIRE(destroyed == 0);
|
||||
lua.safe_script("x = test.create()");
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE_FALSE(tests.empty());
|
||||
std::shared_ptr<test>& x = lua["x"];
|
||||
std::size_t xuse = x.use_count();
|
||||
std::size_t tuse = tests.back().use_count();
|
||||
REQUIRE(xuse == tuse);
|
||||
}
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("gc/double deleter guards", "usertype metatables internally must not rely on C++ state") {
|
||||
SECTION("regular") {
|
||||
struct c_a { int xv; };
|
||||
struct c_b { int yv; };
|
||||
auto routine = []() {
|
||||
sol::state lua;
|
||||
lua.new_usertype<c_a>("c_a", "x", &c_a::xv);
|
||||
lua.new_usertype<c_b>("c_b", "y", &c_b::yv);
|
||||
lua = sol::state();
|
||||
lua.new_usertype<c_a>("c_a", "x", &c_a::xv);
|
||||
lua.new_usertype<c_b>("c_b", "y", &c_b::yv);
|
||||
lua = sol::state();
|
||||
};
|
||||
REQUIRE_NOTHROW(routine());
|
||||
}
|
||||
SECTION("simple") {
|
||||
struct sc_a { int xv; };
|
||||
struct sc_b { int yv; };
|
||||
auto routine = []() {
|
||||
sol::state lua;
|
||||
lua.new_simple_usertype<sc_a>("c_a", "x", &sc_a::xv);
|
||||
lua.new_simple_usertype<sc_b>("c_b", "y", &sc_b::yv);
|
||||
lua = sol::state();
|
||||
lua.new_simple_usertype<sc_a>("c_a", "x", &sc_a::xv);
|
||||
lua.new_simple_usertype<sc_b>("c_b", "y", &sc_b::yv);
|
||||
lua = sol::state();
|
||||
};
|
||||
REQUIRE_NOTHROW(routine());
|
||||
}
|
||||
}
|
|
@ -42,14 +42,14 @@ TEST_CASE("inheritance/basic", "test that metatables are properly inherited") {
|
|||
sol::base_classes, sol::bases<C, B, A>()
|
||||
);
|
||||
|
||||
lua.script("obj = D.new()");
|
||||
lua.script("d = obj:d()");
|
||||
lua.safe_script("obj = D.new()");
|
||||
lua.safe_script("d = obj:d()");
|
||||
bool d = lua["d"];
|
||||
lua.script("c = obj.c");
|
||||
lua.safe_script("c = obj.c");
|
||||
double c = lua["c"];
|
||||
lua.script("b = obj:b()");
|
||||
lua.safe_script("b = obj:b()");
|
||||
int b = lua["b"];
|
||||
lua.script("a = obj.a");
|
||||
lua.safe_script("a = obj.a");
|
||||
int a = lua["a"];
|
||||
|
||||
REQUIRE(d);
|
||||
|
@ -124,19 +124,19 @@ TEST_CASE("inheritance/multi base", "test that multiple bases all work and overl
|
|||
|
||||
lua.set_usertype("TestClass03", s_TestUsertype03);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
tc0 = TestClass00()
|
||||
)");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
tc2 = TestClass02(tc0)
|
||||
)");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
tc1 = TestClass01()
|
||||
)");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
tc3 = TestClass03(tc1)
|
||||
)");
|
||||
|
||||
|
@ -219,19 +219,19 @@ TEST_CASE("inheritance/simple multi base", "test that multiple bases all work an
|
|||
|
||||
lua.set_usertype("TestClass03", s_TestUsertype03);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
tc0 = TestClass00()
|
||||
)");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
tc2 = TestClass02(tc0)
|
||||
)");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
tc1 = TestClass01()
|
||||
)");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
tc3 = TestClass03(tc1)
|
||||
)");
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ TEST_CASE("large_integer/bool", "pass bool integral value to and from lua") {
|
|||
REQUIRE(num == true);
|
||||
return num;
|
||||
});
|
||||
lua.script("x = f(true)");
|
||||
lua.script("assert(x == true)");
|
||||
lua.safe_script("x = f(true)");
|
||||
lua.safe_script("assert(x == true)");
|
||||
sol::object x = lua["x"];
|
||||
REQUIRE(x.is<bool>());
|
||||
REQUIRE(x.as<bool>() == true);
|
||||
|
@ -32,8 +32,8 @@ TEST_CASE("large_integers/unsigned32", "pass large unsigned 32bit values to and
|
|||
REQUIRE(num == 0xFFFFFFFF);
|
||||
return num;
|
||||
});
|
||||
lua.script("x = f(0xFFFFFFFF)");
|
||||
lua.script("assert(x == 0xFFFFFFFF)");
|
||||
lua.safe_script("x = f(0xFFFFFFFF)");
|
||||
lua.safe_script("assert(x == 0xFFFFFFFF)");
|
||||
sol::object x = lua["x"];
|
||||
REQUIRE(x.is<T>());
|
||||
REQUIRE(x.as<T>() == 0xFFFFFFFF);
|
||||
|
@ -47,8 +47,8 @@ TEST_CASE("large_integer/unsigned53", "pass large unsigned 53bit value to and fr
|
|||
REQUIRE(num == 0x1FFFFFFFFFFFFFull);
|
||||
return num;
|
||||
});
|
||||
lua.script("x = f(0x1FFFFFFFFFFFFF)");
|
||||
lua.script("assert(x == 0x1FFFFFFFFFFFFF)");
|
||||
lua.safe_script("x = f(0x1FFFFFFFFFFFFF)");
|
||||
lua.safe_script("assert(x == 0x1FFFFFFFFFFFFF)");
|
||||
sol::object x = lua["x"];
|
||||
REQUIRE(x.is<T>());
|
||||
REQUIRE(x.as<T>() == 0x1FFFFFFFFFFFFFull);
|
||||
|
@ -83,10 +83,10 @@ TEST_CASE("large_integer/double", "pass negative and large positive values as si
|
|||
});
|
||||
//signed 32bit
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("x = s32(-1)");
|
||||
lua.script("assert(x == -1)");
|
||||
lua.script("x = s32(0xFFFFFFFF)");
|
||||
lua.script("assert(x == -1)");
|
||||
lua.safe_script("x = s32(-1)");
|
||||
lua.safe_script("assert(x == -1)");
|
||||
lua.safe_script("x = s32(0xFFFFFFFF)");
|
||||
lua.safe_script("assert(x == -1)");
|
||||
sol::object x = lua["x"];
|
||||
REQUIRE(x.is<std::int32_t>());
|
||||
REQUIRE(x.as<std::int32_t>() == -1);
|
||||
|
@ -95,10 +95,10 @@ TEST_CASE("large_integer/double", "pass negative and large positive values as si
|
|||
}());
|
||||
//unsigned 32bit
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("x = u32(0xFFFFFFFF)");
|
||||
lua.script("assert(x == 0xFFFFFFFF)");
|
||||
lua.script("x = u32(-1)");
|
||||
lua.script("assert(x == 0xFFFFFFFF)");
|
||||
lua.safe_script("x = u32(0xFFFFFFFF)");
|
||||
lua.safe_script("assert(x == 0xFFFFFFFF)");
|
||||
lua.safe_script("x = u32(-1)");
|
||||
lua.safe_script("assert(x == 0xFFFFFFFF)");
|
||||
sol::object x = lua["x"];
|
||||
REQUIRE(x.is<std::int32_t>());
|
||||
REQUIRE(x.as<std::int32_t>() == -1);
|
||||
|
@ -107,8 +107,8 @@ TEST_CASE("large_integer/double", "pass negative and large positive values as si
|
|||
}());
|
||||
//signed 64bit
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("x = s64(-1)");
|
||||
lua.script("assert(x == -1)");
|
||||
lua.safe_script("x = s64(-1)");
|
||||
lua.safe_script("assert(x == -1)");
|
||||
sol::object x = lua["x"];
|
||||
REQUIRE(x.is<std::int64_t>());
|
||||
REQUIRE(x.as<std::int64_t>() == -1);
|
||||
|
|
|
@ -47,6 +47,43 @@ TEST_CASE("operators/default", "test that generic equality operators and all sor
|
|||
lua["v2"] = &v2;
|
||||
lua["v3"] = &v3;
|
||||
|
||||
SECTION("plain") {
|
||||
// Can only compare identity here
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.safe_script("assert(t1 == t1)");
|
||||
lua.safe_script("assert(t2 == t2)");
|
||||
lua.safe_script("assert(t3 == t3)");
|
||||
}());
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.safe_script("assert(t1 == t2)");
|
||||
lua.safe_script("assert(not (t1 == t3))");
|
||||
lua.safe_script("assert(not (t2 == t3))");
|
||||
}());
|
||||
// Object should compare equal to themselves
|
||||
// (and not invoke operator==; pointer test should be sufficient)
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.safe_script("assert(u1 == u1)");
|
||||
lua.safe_script("assert(u2 == u2)");
|
||||
lua.safe_script("assert(u3 == u3)");
|
||||
}());
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.safe_script("assert(not (u1 == u2))");
|
||||
lua.safe_script("assert(u1 == u3)");
|
||||
lua.safe_script("assert(not (u2 == u3))");
|
||||
}());
|
||||
// Object should compare equal to themselves
|
||||
// (and not invoke operator==; pointer test should be sufficient)
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.safe_script("assert(v1 == v1)");
|
||||
lua.safe_script("assert(v2 == v2)");
|
||||
lua.safe_script("assert(v3 == v3)");
|
||||
}());
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.safe_script("assert(not (v1 == v2))");
|
||||
lua.safe_script("assert(v1 == v3)");
|
||||
lua.safe_script("assert(not (v2 == v3))");
|
||||
}());
|
||||
}
|
||||
SECTION("regular") {
|
||||
lua.new_usertype<T>("T");
|
||||
lua.new_usertype<U>("U");
|
||||
|
@ -54,38 +91,38 @@ TEST_CASE("operators/default", "test that generic equality operators and all sor
|
|||
|
||||
// Can only compare identity here
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.script("assert(t1 == t1)");
|
||||
lua.script("assert(t2 == t2)");
|
||||
lua.script("assert(t3 == t3)");
|
||||
lua.safe_script("assert(t1 == t1)");
|
||||
lua.safe_script("assert(t2 == t2)");
|
||||
lua.safe_script("assert(t3 == t3)");
|
||||
}());
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.script("assert(t1 == t2)");
|
||||
lua.script("assert(not (t1 == t3))");
|
||||
lua.script("assert(not (t2 == t3))");
|
||||
lua.safe_script("assert(t1 == t2)");
|
||||
lua.safe_script("assert(not (t1 == t3))");
|
||||
lua.safe_script("assert(not (t2 == t3))");
|
||||
}());
|
||||
// Object should compare equal to themselves
|
||||
// (and not invoke operator==; pointer test should be sufficient)
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.script("assert(u1 == u1)");
|
||||
lua.script("assert(u2 == u2)");
|
||||
lua.script("assert(u3 == u3)");
|
||||
lua.safe_script("assert(u1 == u1)");
|
||||
lua.safe_script("assert(u2 == u2)");
|
||||
lua.safe_script("assert(u3 == u3)");
|
||||
}());
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.script("assert(not (u1 == u2))");
|
||||
lua.script("assert(u1 == u3)");
|
||||
lua.script("assert(not (u2 == u3))");
|
||||
lua.safe_script("assert(not (u1 == u2))");
|
||||
lua.safe_script("assert(u1 == u3)");
|
||||
lua.safe_script("assert(not (u2 == u3))");
|
||||
}());
|
||||
// Object should compare equal to themselves
|
||||
// (and not invoke operator==; pointer test should be sufficient)
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.script("assert(v1 == v1)");
|
||||
lua.script("assert(v2 == v2)");
|
||||
lua.script("assert(v3 == v3)");
|
||||
lua.safe_script("assert(v1 == v1)");
|
||||
lua.safe_script("assert(v2 == v2)");
|
||||
lua.safe_script("assert(v3 == v3)");
|
||||
}());
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.script("assert(not (v1 == v2))");
|
||||
lua.script("assert(v1 == v3)");
|
||||
lua.script("assert(not (v2 == v3))");
|
||||
lua.safe_script("assert(not (v1 == v2))");
|
||||
lua.safe_script("assert(v1 == v3)");
|
||||
lua.safe_script("assert(not (v2 == v3))");
|
||||
}());
|
||||
}
|
||||
SECTION("simple") {
|
||||
|
@ -95,38 +132,38 @@ TEST_CASE("operators/default", "test that generic equality operators and all sor
|
|||
|
||||
// Can only compare identity here
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.script("assert(t1 == t1)");
|
||||
lua.script("assert(t2 == t2)");
|
||||
lua.script("assert(t3 == t3)");
|
||||
lua.safe_script("assert(t1 == t1)");
|
||||
lua.safe_script("assert(t2 == t2)");
|
||||
lua.safe_script("assert(t3 == t3)");
|
||||
}());
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.script("assert(t1 == t2)");
|
||||
lua.script("assert(not (t1 == t3))");
|
||||
lua.script("assert(not (t2 == t3))");
|
||||
lua.safe_script("assert(t1 == t2)");
|
||||
lua.safe_script("assert(not (t1 == t3))");
|
||||
lua.safe_script("assert(not (t2 == t3))");
|
||||
}());
|
||||
// Object should compare equal to themselves
|
||||
// (and not invoke operator==; pointer test should be sufficient)
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.script("assert(u1 == u1)");
|
||||
lua.script("assert(u2 == u2)");
|
||||
lua.script("assert(u3 == u3)");
|
||||
lua.safe_script("assert(u1 == u1)");
|
||||
lua.safe_script("assert(u2 == u2)");
|
||||
lua.safe_script("assert(u3 == u3)");
|
||||
}());
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.script("assert(not (u1 == u2))");
|
||||
lua.script("assert(u1 == u3)");
|
||||
lua.script("assert(not (u2 == u3))");
|
||||
lua.safe_script("assert(not (u1 == u2))");
|
||||
lua.safe_script("assert(u1 == u3)");
|
||||
lua.safe_script("assert(not (u2 == u3))");
|
||||
}());
|
||||
// Object should compare equal to themselves
|
||||
// (and not invoke operator==; pointer test should be sufficient)
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.script("assert(v1 == v1)");
|
||||
lua.script("assert(v2 == v2)");
|
||||
lua.script("assert(v3 == v3)");
|
||||
lua.safe_script("assert(v1 == v1)");
|
||||
lua.safe_script("assert(v2 == v2)");
|
||||
lua.safe_script("assert(v3 == v3)");
|
||||
}());
|
||||
REQUIRE_NOTHROW([&] {
|
||||
lua.script("assert(not (v1 == v2))");
|
||||
lua.script("assert(v1 == v3)");
|
||||
lua.script("assert(not (v2 == v3))");
|
||||
lua.safe_script("assert(not (v1 == v2))");
|
||||
lua.safe_script("assert(v1 == v3)");
|
||||
lua.safe_script("assert(not (v2 == v3))");
|
||||
}());
|
||||
}
|
||||
}
|
||||
|
@ -134,13 +171,21 @@ TEST_CASE("operators/default", "test that generic equality operators and all sor
|
|||
TEST_CASE("operators/call", "test call operator generation") {
|
||||
struct callable {
|
||||
int operator ()(int a, std::string b) {
|
||||
return a + b.length();
|
||||
return a + static_cast<int>(b.length());
|
||||
}
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
SECTION("plain") {
|
||||
{
|
||||
lua.set("obj", callable());
|
||||
lua.safe_script("v = obj(2, 'bark woof')");
|
||||
int v = lua["v"];
|
||||
REQUIRE(v == 11);
|
||||
}
|
||||
}
|
||||
SECTION("regular") {
|
||||
lua.new_usertype<callable>("callable");
|
||||
{
|
||||
|
@ -168,13 +213,53 @@ const void* stringable::last_print_ptr = nullptr;
|
|||
|
||||
std::ostream& operator<< (std::ostream& ostr, const stringable& o) {
|
||||
stringable::last_print_ptr = static_cast<const void*>(&o);
|
||||
return ostr << " { stringable! }";
|
||||
return ostr << "{ stringable, std::ostream! }";
|
||||
}
|
||||
|
||||
struct adl_stringable {
|
||||
static const void* last_print_ptr;
|
||||
};
|
||||
const void* adl_stringable::last_print_ptr = nullptr;
|
||||
|
||||
std::string to_string(const adl_stringable& o) {
|
||||
adl_stringable::last_print_ptr = static_cast<const void*>(&o);
|
||||
return "{ adl_stringable, to_string! }";
|
||||
}
|
||||
|
||||
namespace inside {
|
||||
struct adl_stringable2 {
|
||||
static const void* last_print_ptr;
|
||||
};
|
||||
const void* adl_stringable2::last_print_ptr = nullptr;
|
||||
|
||||
std::string to_string(const adl_stringable2& o) {
|
||||
adl_stringable2::last_print_ptr = static_cast<const void*>(&o);
|
||||
return "{ inside::adl_stringable2, inside::to_string! }";
|
||||
}
|
||||
}
|
||||
|
||||
struct member_stringable {
|
||||
static const void* last_print_ptr;
|
||||
|
||||
std::string to_string() const {
|
||||
member_stringable::last_print_ptr = static_cast<const void*>(this);
|
||||
return "{ member_stringable, to_string! }";
|
||||
}
|
||||
};
|
||||
const void* member_stringable::last_print_ptr = nullptr;
|
||||
|
||||
TEST_CASE("operators/stringable", "test std::ostream stringability") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
SECTION("plain") {
|
||||
{
|
||||
lua["obj"] = stringable();
|
||||
lua.safe_script("print(obj)");
|
||||
stringable& obj = lua["obj"];
|
||||
REQUIRE(stringable::last_print_ptr == &obj);
|
||||
}
|
||||
}
|
||||
SECTION("regular") {
|
||||
lua.new_usertype<stringable>("stringable");
|
||||
{
|
||||
|
@ -195,6 +280,102 @@ TEST_CASE("operators/stringable", "test std::ostream stringability") {
|
|||
}
|
||||
}
|
||||
|
||||
TEST_CASE("operators/adl_stringable", "test adl to_string stringability") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
SECTION("plain") {
|
||||
{
|
||||
lua["obj"] = adl_stringable();
|
||||
lua.safe_script("print(obj)");
|
||||
adl_stringable& obj = lua["obj"];
|
||||
REQUIRE(adl_stringable::last_print_ptr == &obj);
|
||||
}
|
||||
}
|
||||
SECTION("regular") {
|
||||
lua.new_usertype<adl_stringable>("stringable");
|
||||
{
|
||||
lua["obj"] = adl_stringable();
|
||||
lua.safe_script("print(obj)");
|
||||
adl_stringable& obj = lua["obj"];
|
||||
REQUIRE(adl_stringable::last_print_ptr == &obj);
|
||||
}
|
||||
}
|
||||
SECTION("simple") {
|
||||
lua.new_simple_usertype<adl_stringable>("stringable");
|
||||
{
|
||||
lua.safe_script("obj = stringable.new()");
|
||||
lua.safe_script("print(obj)");
|
||||
adl_stringable& obj = lua["obj"];
|
||||
REQUIRE(adl_stringable::last_print_ptr == &obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("operators/inside::adl_stringable2", "test adl to_string stringability from inside a namespace") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
SECTION("plain") {
|
||||
{
|
||||
lua["obj"] = inside::adl_stringable2();
|
||||
lua.safe_script("print(obj)");
|
||||
inside::adl_stringable2& obj = lua["obj"];
|
||||
REQUIRE(inside::adl_stringable2::last_print_ptr == &obj);
|
||||
}
|
||||
}
|
||||
SECTION("regular") {
|
||||
lua.new_usertype<inside::adl_stringable2>("stringable");
|
||||
{
|
||||
lua.safe_script("obj = stringable.new()");
|
||||
lua.safe_script("print(obj)");
|
||||
inside::adl_stringable2& obj = lua["obj"];
|
||||
REQUIRE(inside::adl_stringable2::last_print_ptr == &obj);
|
||||
}
|
||||
}
|
||||
SECTION("simple") {
|
||||
lua.new_simple_usertype<inside::adl_stringable2>("stringable");
|
||||
{
|
||||
lua.safe_script("obj = stringable.new()");
|
||||
lua.safe_script("print(obj)");
|
||||
inside::adl_stringable2& obj = lua["obj"];
|
||||
REQUIRE(inside::adl_stringable2::last_print_ptr == &obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("operators/member_stringable", "test member to_string stringability") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
SECTION("plain") {
|
||||
{
|
||||
lua["obj"] = member_stringable();
|
||||
lua.safe_script("print(obj)");
|
||||
member_stringable& obj = lua["obj"];
|
||||
REQUIRE(member_stringable::last_print_ptr == &obj);
|
||||
}
|
||||
}
|
||||
SECTION("regular") {
|
||||
lua.new_usertype<member_stringable>("stringable");
|
||||
{
|
||||
lua.safe_script("obj = stringable.new()");
|
||||
lua.safe_script("print(obj)");
|
||||
member_stringable& obj = lua["obj"];
|
||||
REQUIRE(member_stringable::last_print_ptr == &obj);
|
||||
}
|
||||
}
|
||||
SECTION("simple") {
|
||||
lua.new_simple_usertype<member_stringable>("stringable");
|
||||
{
|
||||
lua.safe_script("obj = stringable.new()");
|
||||
lua.safe_script("print(obj)");
|
||||
member_stringable& obj = lua["obj"];
|
||||
REQUIRE(member_stringable::last_print_ptr == &obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("operators/container-like", "test that generic begin/end and iterator are automatically bound") {
|
||||
#if SOL_LUA_VERSION > 501
|
||||
struct container {
|
||||
|
@ -219,6 +400,14 @@ TEST_CASE("operators/container-like", "test that generic begin/end and iterator
|
|||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
SECTION("plain") {
|
||||
{
|
||||
lua["obj"] = container();
|
||||
lua.safe_script("i = 0 for k, v in pairs(obj) do i = i + 1 assert(k == v) end");
|
||||
std::size_t i = lua["i"];
|
||||
REQUIRE(i == 10);
|
||||
}
|
||||
}
|
||||
SECTION("regular") {
|
||||
lua.new_usertype<container>("container");
|
||||
{
|
||||
|
@ -252,6 +441,14 @@ TEST_CASE("operators/length", "test that size is automatically bound to the leng
|
|||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
SECTION("plain") {
|
||||
{
|
||||
lua["obj"] = sizable();
|
||||
lua.safe_script("s = #obj");
|
||||
std::size_t s = lua["s"];
|
||||
REQUIRE(s == 6);
|
||||
}
|
||||
}
|
||||
SECTION("regular") {
|
||||
lua.new_usertype<sizable>("sizable");
|
||||
{
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
TEST_CASE("issues/stack overflow", "make sure various operations repeated don't trigger stack overflow") {
|
||||
sol::state lua;
|
||||
lua.script("t = {};t[0]=20");
|
||||
lua.script("lua_function=function(i)return i;end");
|
||||
lua.safe_script("t = {};t[0]=20");
|
||||
lua.safe_script("lua_function=function(i)return i;end");
|
||||
|
||||
sol::function f = lua["lua_function"];
|
||||
std::string teststring = "testtext";
|
||||
|
|
72
test_plain_types.cpp
Normal file
72
test_plain_types.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
#define SOL_CHECK_ARGUMENTS 1
|
||||
|
||||
#include <sol.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("plain/alignment", "test that aligned classes in certain compilers don't trigger compiler errors") {
|
||||
#ifdef _MSC_VER
|
||||
__declspec(align(16)) class aligned_class {
|
||||
int var;
|
||||
};
|
||||
|
||||
class A {
|
||||
aligned_class a;
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base, sol::lib::math);
|
||||
|
||||
lua.new_usertype<A>("A");
|
||||
A a;
|
||||
lua["a"] = &a;
|
||||
A& la = lua["a"];
|
||||
REQUIRE(&a == &la);
|
||||
#else
|
||||
REQUIRE(true);
|
||||
#endif // VC++ stuff
|
||||
}
|
||||
|
||||
TEST_CASE("plain/indestructible", "test that we error for types that are innately indestructible") {
|
||||
struct indestructible {
|
||||
public:
|
||||
int v = 20;
|
||||
|
||||
struct insider {
|
||||
void operator()(indestructible* i) const {
|
||||
i->~indestructible();
|
||||
}
|
||||
};
|
||||
private:
|
||||
~indestructible() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
SECTION("doomed") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
std::unique_ptr<indestructible, indestructible::insider> i = sol::detail::make_unique_deleter<indestructible, indestructible::insider>();
|
||||
lua["i"] = *i;
|
||||
lua.safe_script("i = nil");
|
||||
auto result = lua.safe_script("collectgarbage()", sol::script_pass_on_error);
|
||||
REQUIRE_FALSE(result.valid());
|
||||
}
|
||||
SECTION("saved") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
std::unique_ptr<indestructible, indestructible::insider> i = sol::detail::make_unique_deleter<indestructible, indestructible::insider>();
|
||||
lua["i"] = *i;
|
||||
lua.new_usertype<indestructible>("indestructible",
|
||||
sol::default_constructor,
|
||||
sol::meta_function::garbage_collect, sol::destructor([](indestructible& i) {
|
||||
indestructible::insider del;
|
||||
del(&i);
|
||||
})
|
||||
);
|
||||
lua.safe_script("i = nil");
|
||||
auto result = lua.safe_script("collectgarbage()", sol::script_pass_on_error);
|
||||
REQUIRE(result.valid());
|
||||
}
|
||||
}
|
|
@ -49,20 +49,20 @@ TEST_CASE("simple_usertype/usertypes", "Ensure that simple usertypes properly wo
|
|||
"z", sol::overload(&bark::get, &bark::set)
|
||||
);
|
||||
|
||||
lua.script("b = bark.new()");
|
||||
lua.safe_script("b = bark.new()");
|
||||
bark& b = lua["b"];
|
||||
|
||||
lua.script("b:fun()");
|
||||
lua.safe_script("b:fun()");
|
||||
int var = b.var;
|
||||
REQUIRE(var == 51);
|
||||
|
||||
lua.script("b:var(20)");
|
||||
lua.script("v = b:var()");
|
||||
lua.safe_script("b:var(20)");
|
||||
lua.safe_script("v = b:var()");
|
||||
int v = lua["v"];
|
||||
REQUIRE(v == 20);
|
||||
REQUIRE(b.var == 20);
|
||||
|
||||
lua.script("m = b:the_marker()");
|
||||
lua.safe_script("m = b:the_marker()");
|
||||
marker& m = lua["m"];
|
||||
REQUIRE_FALSE(b.mark.value);
|
||||
REQUIRE_FALSE(m.value);
|
||||
|
@ -73,16 +73,16 @@ TEST_CASE("simple_usertype/usertypes", "Ensure that simple usertypes properly wo
|
|||
sol::table barktable = lua["bark"];
|
||||
barktable["special"] = &bark::special;
|
||||
|
||||
lua.script("s = b:special()");
|
||||
lua.safe_script("s = b:special()");
|
||||
std::string s = lua["s"];
|
||||
REQUIRE(s == "woof");
|
||||
|
||||
lua.script("b:y(24)");
|
||||
lua.script("x = b:x()");
|
||||
lua.safe_script("b:y(24)");
|
||||
lua.safe_script("x = b:x()");
|
||||
int x = lua["x"];
|
||||
REQUIRE(x == 24);
|
||||
|
||||
lua.script("z = b:z(b:z() + 5)");
|
||||
lua.safe_script("z = b:z(b:z() + 5)");
|
||||
int z = lua["z"];
|
||||
REQUIRE(z == 29);
|
||||
}
|
||||
|
@ -132,23 +132,23 @@ TEST_CASE("simple_usertype/usertype constructors", "Ensure that calls with speci
|
|||
"z", sol::overload(&bark::get, &bark::set)
|
||||
);
|
||||
|
||||
lua.script("bx = bark.new(760)");
|
||||
lua.safe_script("bx = bark.new(760)");
|
||||
bark& bx = lua["bx"];
|
||||
REQUIRE(bx.var == 760);
|
||||
|
||||
lua.script("b = bark.new()");
|
||||
lua.safe_script("b = bark.new()");
|
||||
bark& b = lua["b"];
|
||||
|
||||
lua.script("b:fun()");
|
||||
lua.safe_script("b:fun()");
|
||||
int var = b.var;
|
||||
REQUIRE(var == 51);
|
||||
|
||||
lua.script("b:var(20)");
|
||||
lua.script("v = b:var()");
|
||||
lua.safe_script("b:var(20)");
|
||||
lua.safe_script("v = b:var()");
|
||||
int v = lua["v"];
|
||||
REQUIRE(v == 20);
|
||||
|
||||
lua.script("m = b:the_marker()");
|
||||
lua.safe_script("m = b:the_marker()");
|
||||
marker& m = lua["m"];
|
||||
REQUIRE_FALSE(b.mark.value);
|
||||
REQUIRE_FALSE(m.value);
|
||||
|
@ -159,58 +159,20 @@ TEST_CASE("simple_usertype/usertype constructors", "Ensure that calls with speci
|
|||
sol::table barktable = lua["bark"];
|
||||
barktable["special"] = &bark::special;
|
||||
|
||||
lua.script("s = b:special()");
|
||||
lua.safe_script("s = b:special()");
|
||||
std::string s = lua["s"];
|
||||
REQUIRE(s == "woof");
|
||||
|
||||
lua.script("b:y(24)");
|
||||
lua.script("x = b:x()");
|
||||
lua.safe_script("b:y(24)");
|
||||
lua.safe_script("x = b:x()");
|
||||
int x = lua["x"];
|
||||
REQUIRE(x == 24);
|
||||
|
||||
lua.script("z = b:z(b:z() + 5)");
|
||||
lua.safe_script("z = b:z(b:z() + 5)");
|
||||
int z = lua["z"];
|
||||
REQUIRE(z == 29);
|
||||
}
|
||||
|
||||
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 {
|
||||
test() {
|
||||
++created;
|
||||
}
|
||||
|
||||
~test() {
|
||||
++destroyed;
|
||||
}
|
||||
};
|
||||
{
|
||||
std::list<std::shared_ptr<test>> tests;
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
|
||||
lua.new_simple_usertype<test>("test",
|
||||
"create", [&]() -> std::shared_ptr<test> {
|
||||
tests.push_back(std::make_shared<test>());
|
||||
return tests.back();
|
||||
}
|
||||
);
|
||||
REQUIRE(created == 0);
|
||||
REQUIRE(destroyed == 0);
|
||||
lua.script("x = test.create()");
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE_FALSE(tests.empty());
|
||||
std::shared_ptr<test>& x = lua["x"];
|
||||
std::size_t xuse = x.use_count();
|
||||
std::size_t tuse = tests.back().use_count();
|
||||
REQUIRE(xuse == tuse);
|
||||
}
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("simple_usertype/vars", "simple usertype vars can bind various values (no ref)") {
|
||||
int muh_variable = 10;
|
||||
int through_variable = 25;
|
||||
|
@ -228,7 +190,7 @@ TEST_CASE("simple_usertype/vars", "simple usertype vars can bind various values
|
|||
|
||||
through_variable = 20;
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
print(test.straight)
|
||||
s = test.straight
|
||||
print(test.global)
|
||||
|
@ -297,29 +259,29 @@ TEST_CASE("simple_usertype/variable-control", "test to see if usertypes respond
|
|||
|
||||
B b;
|
||||
lua.set("b", &b);
|
||||
lua.script("b:a()");
|
||||
lua.safe_script("b:a()");
|
||||
|
||||
sB sb;
|
||||
lua.set("sb", &sb);
|
||||
lua.script("sb:a()");
|
||||
lua.safe_script("sb:a()");
|
||||
|
||||
sV sv;
|
||||
lua.set("sv", &sv);
|
||||
lua.script("print(sv.b)assert(sv.b == 20)");
|
||||
lua.safe_script("print(sv.b)assert(sv.b == 20)");
|
||||
|
||||
sW sw;
|
||||
lua.set("sw", &sw);
|
||||
lua.script("print(sw.a)assert(sw.a == 10)");
|
||||
lua.script("print(sw.b)assert(sw.b == 20)");
|
||||
lua.script("print(sw.pb)assert(sw.pb == 22)");
|
||||
lua.script("sw.a = 11");
|
||||
lua.script("sw.b = 21");
|
||||
lua.script("print(sw.a)assert(sw.a == 11)");
|
||||
lua.script("print(sw.b)assert(sw.b == 21)");
|
||||
lua.script("print(sw.pb)assert(sw.pb == 23)");
|
||||
lua.script("sw.pb = 25");
|
||||
lua.script("print(sw.b)assert(sw.b == 25)");
|
||||
lua.script("print(sw.pb)assert(sw.pb == 27)");
|
||||
lua.safe_script("print(sw.a)assert(sw.a == 10)");
|
||||
lua.safe_script("print(sw.b)assert(sw.b == 20)");
|
||||
lua.safe_script("print(sw.pb)assert(sw.pb == 22)");
|
||||
lua.safe_script("sw.a = 11");
|
||||
lua.safe_script("sw.b = 21");
|
||||
lua.safe_script("print(sw.a)assert(sw.a == 11)");
|
||||
lua.safe_script("print(sw.b)assert(sw.b == 21)");
|
||||
lua.safe_script("print(sw.pb)assert(sw.pb == 23)");
|
||||
lua.safe_script("sw.pb = 25");
|
||||
lua.safe_script("print(sw.b)assert(sw.b == 25)");
|
||||
lua.safe_script("print(sw.pb)assert(sw.pb == 27)");
|
||||
}
|
||||
|
||||
TEST_CASE("simple_usertype/factory constructor overloads", "simple usertypes should invoke the proper factories") {
|
||||
|
@ -340,21 +302,30 @@ TEST_CASE("simple_usertype/factory constructor overloads", "simple usertypes sho
|
|||
sol::constructors<sol::types<>, sol::types<const B&>> c;
|
||||
lua.new_simple_usertype<B>("B",
|
||||
sol::call_constructor, c,
|
||||
"new", sol::factories([]() { return B(); }),
|
||||
"new2", sol::initializers([](B& mem) { new(&mem)B(); }, [](B& mem, int v) { new(&mem)B(); mem.bvar = v; }),
|
||||
"new", sol::factories([]() {
|
||||
return B();
|
||||
}),
|
||||
"new2", sol::initializers(
|
||||
[](B& mem) {
|
||||
new(&mem)B();
|
||||
},
|
||||
[](B& mem, int v) {
|
||||
new(&mem)B(); mem.bvar = v;
|
||||
}
|
||||
),
|
||||
"f", sol::as_function(&B::bvar),
|
||||
"g", sol::overload([](B&) { return 2; }, [](B&, int v) { return v; })
|
||||
);
|
||||
|
||||
lua.script("b = B()");
|
||||
lua.script("b2 = B.new()");
|
||||
lua.script("b3 = B.new2()");
|
||||
lua.script("b4 = B.new2(11)");
|
||||
lua.safe_script("b = B()");
|
||||
lua.safe_script("b2 = B.new()");
|
||||
lua.safe_script("b3 = B.new2()");
|
||||
lua.safe_script("b4 = B.new2(11)");
|
||||
|
||||
lua.script("x = b:f()");
|
||||
lua.script("x2 = b2:f()");
|
||||
lua.script("x3 = b3:f()");
|
||||
lua.script("x4 = b4:f()");
|
||||
lua.safe_script("x = b:f()");
|
||||
lua.safe_script("x2 = b2:f()");
|
||||
lua.safe_script("x3 = b3:f()");
|
||||
lua.safe_script("x4 = b4:f()");
|
||||
int x = lua["x"];
|
||||
int x2 = lua["x2"];
|
||||
int x3 = lua["x3"];
|
||||
|
@ -364,10 +335,10 @@ TEST_CASE("simple_usertype/factory constructor overloads", "simple usertypes sho
|
|||
REQUIRE(x3 == 24);
|
||||
REQUIRE(x4 == 11);
|
||||
|
||||
lua.script("y = b:g()");
|
||||
lua.script("y2 = b2:g(3)");
|
||||
lua.script("y3 = b3:g()");
|
||||
lua.script("y4 = b4:g(3)");
|
||||
lua.safe_script("y = b:g()");
|
||||
lua.safe_script("y2 = b2:g(3)");
|
||||
lua.safe_script("y3 = b3:g()");
|
||||
lua.safe_script("y4 = b4:g(3)");
|
||||
int y = lua["y"];
|
||||
int y2 = lua["y2"];
|
||||
int y3 = lua["y3"];
|
||||
|
@ -391,53 +362,22 @@ TEST_CASE("simple_usertype/runtime append", "allow extra functions to be appende
|
|||
lua.set("b", std::make_unique<B>());
|
||||
lua["A"]["method"] = []() { return 200; };
|
||||
lua["B"]["method2"] = [](B&) { return 100; };
|
||||
lua.script("x = b.method()");
|
||||
lua.script("y = b:method()");
|
||||
lua.safe_script("x = b.method()");
|
||||
lua.safe_script("y = b:method()");
|
||||
|
||||
int x = lua["x"];
|
||||
int y = lua["y"];
|
||||
REQUIRE(x == 200);
|
||||
REQUIRE(y == 200);
|
||||
|
||||
lua.script("z = b.method2(b)");
|
||||
lua.script("w = b:method2()");
|
||||
lua.safe_script("z = b.method2(b)");
|
||||
lua.safe_script("w = b:method2()");
|
||||
int z = lua["z"];
|
||||
int w = lua["w"];
|
||||
REQUIRE(z == 100);
|
||||
REQUIRE(w == 100);
|
||||
}
|
||||
|
||||
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 {
|
||||
public:
|
||||
CrashClass() {
|
||||
}
|
||||
|
||||
~CrashClass() {
|
||||
a = 10; // This will cause a crash.
|
||||
}
|
||||
|
||||
private:
|
||||
int a;
|
||||
};
|
||||
|
||||
lua.new_simple_usertype<CrashClass>("CrashClass",
|
||||
sol::call_constructor, sol::constructors<sol::types<>>()
|
||||
);
|
||||
|
||||
lua.script(R"(
|
||||
function testCrash()
|
||||
local x = CrashClass()
|
||||
end
|
||||
)");
|
||||
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
lua["testCrash"]();
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
|
@ -456,9 +396,9 @@ TEST_CASE("simple_usertype/table append", "Ensure that appending to the meta tab
|
|||
lua.set("pa", &a);
|
||||
lua.set("ua", std::make_unique<A>());
|
||||
REQUIRE_NOTHROW([&]{
|
||||
lua.script("assert(a:func() == 5000)");
|
||||
lua.script("assert(pa:func() == 5000)");
|
||||
lua.script("assert(ua:func() == 5000)");
|
||||
lua.safe_script("assert(a:func() == 5000)");
|
||||
lua.safe_script("assert(pa:func() == 5000)");
|
||||
lua.safe_script("assert(ua:func() == 5000)");
|
||||
}());
|
||||
}
|
||||
|
||||
|
@ -481,7 +421,7 @@ TEST_CASE("simple_usertype/class call propogation", "make sure methods and varia
|
|||
"var", &B::var
|
||||
);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
b = B.new()
|
||||
print(b.var)
|
||||
b:thing()
|
||||
|
@ -526,10 +466,10 @@ TEST_CASE("simple_usertype/call constructor", "ensure that all kinds of call-bas
|
|||
}
|
||||
);
|
||||
|
||||
lua.script("a = f_test()");
|
||||
lua.script("b = i_test()");
|
||||
lua.script("c = r_test()");
|
||||
lua.script("d = f_test.new()");
|
||||
lua.safe_script("a = f_test()");
|
||||
lua.safe_script("b = i_test()");
|
||||
lua.safe_script("c = r_test()");
|
||||
lua.safe_script("d = f_test.new()");
|
||||
f_test& a = lua["a"];
|
||||
f_test& d = lua["d"];
|
||||
i_test& b = lua["b"];
|
||||
|
@ -555,13 +495,13 @@ TEST_CASE("simple_usertype/call constructor", "ensure that all kinds of call-bas
|
|||
);
|
||||
|
||||
lua.new_simple_usertype<thing>("thing");
|
||||
lua.script("things = {thing.new(), thing.new()}");
|
||||
lua.safe_script("things = {thing.new(), thing.new()}");
|
||||
|
||||
SECTION("new") {
|
||||
REQUIRE_NOTHROW(lua.script("a = v_test.new(things)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("a = v_test.new(things)"));
|
||||
}
|
||||
SECTION("call_constructor") {
|
||||
REQUIRE_NOTHROW(lua.script("b = v_test(things)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("b = v_test(things)"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,7 +538,7 @@ TEST_CASE("simple_usertype/missing key", "make sure a missing key returns nil")
|
|||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.new_simple_usertype<thing>("thing");
|
||||
REQUIRE_NOTHROW(lua.script("print(thing.missingKey)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("print(thing.missingKey)"));
|
||||
}
|
||||
|
||||
TEST_CASE("simple_usertype/runtime extensibility", "Check if usertypes are runtime extensible") {
|
||||
|
@ -616,7 +556,7 @@ TEST_CASE("simple_usertype/runtime extensibility", "Check if usertypes are runti
|
|||
"func", &thing::func
|
||||
);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
t = thing.new()
|
||||
)");
|
||||
|
||||
|
@ -638,19 +578,19 @@ end
|
|||
REQUIRE_FALSE(result.valid());
|
||||
}
|
||||
|
||||
lua.script("val = t:func(2)");
|
||||
lua.safe_script("val = t:func(2)");
|
||||
val = lua["val"];
|
||||
REQUIRE(val == 2);
|
||||
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
function thing:runtime_func(a)
|
||||
return a + 1
|
||||
end
|
||||
)");
|
||||
}());
|
||||
|
||||
lua.script("val = t:runtime_func(2)");
|
||||
lua.safe_script("val = t:runtime_func(2)");
|
||||
val = lua["val"];
|
||||
REQUIRE(val == 3);
|
||||
}
|
||||
|
@ -663,7 +603,7 @@ end
|
|||
"v", &thing::v
|
||||
);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
t = thing.new()
|
||||
)");
|
||||
|
||||
|
@ -685,19 +625,19 @@ end
|
|||
REQUIRE_FALSE(result.valid());
|
||||
}());
|
||||
|
||||
lua.script("val = t:func(2)");
|
||||
lua.safe_script("val = t:func(2)");
|
||||
val = lua["val"];
|
||||
REQUIRE(val == 2);
|
||||
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
function thing:runtime_func(a)
|
||||
return a + 1
|
||||
end
|
||||
)");
|
||||
}());
|
||||
|
||||
lua.script("val = t:runtime_func(2)");
|
||||
lua.safe_script("val = t:runtime_func(2)");
|
||||
val = lua["val"];
|
||||
REQUIRE(val == 3);
|
||||
}
|
||||
|
@ -715,13 +655,13 @@ TEST_CASE("simple_usertype/runtime replacement", "ensure that functions can be p
|
|||
|
||||
lua.new_simple_usertype<heart_t>("a");
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("obj = a.new()");
|
||||
lua.script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.script("v1 = obj:heartbeat()");
|
||||
lua.script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.script("v2 = obj:heartbeat()");
|
||||
lua.script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.script("v3 = obj:heartbeat()");
|
||||
lua.safe_script("obj = a.new()");
|
||||
lua.safe_script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.safe_script("v1 = obj:heartbeat()");
|
||||
lua.safe_script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.safe_script("v2 = obj:heartbeat()");
|
||||
lua.safe_script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.safe_script("v3 = obj:heartbeat()");
|
||||
}());
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
|
@ -739,13 +679,13 @@ TEST_CASE("simple_usertype/runtime replacement", "ensure that functions can be p
|
|||
);
|
||||
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("obj = a.new()");
|
||||
lua.script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.script("v1 = obj:heartbeat()");
|
||||
lua.script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.script("v2 = obj:heartbeat()");
|
||||
lua.script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.script("v3 = obj:heartbeat()");
|
||||
lua.safe_script("obj = a.new()");
|
||||
lua.safe_script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.safe_script("v1 = obj:heartbeat()");
|
||||
lua.safe_script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.safe_script("v2 = obj:heartbeat()");
|
||||
lua.safe_script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.safe_script("v3 = obj:heartbeat()");
|
||||
}());
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
|
@ -764,13 +704,13 @@ TEST_CASE("simple_usertype/runtime replacement", "ensure that functions can be p
|
|||
);
|
||||
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("obj = a.new()");
|
||||
lua.script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.script("v1 = obj:heartbeat()");
|
||||
lua.script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.script("v2 = obj:heartbeat()");
|
||||
lua.script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.script("v3 = obj:heartbeat()");
|
||||
lua.safe_script("obj = a.new()");
|
||||
lua.safe_script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.safe_script("v1 = obj:heartbeat()");
|
||||
lua.safe_script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.safe_script("v2 = obj:heartbeat()");
|
||||
lua.safe_script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.safe_script("v3 = obj:heartbeat()");
|
||||
}());
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
|
@ -801,11 +741,11 @@ TEST_CASE("simple_usertype/meta key retrievals", "allow for special meta keys (_
|
|||
lua["var"] = s;
|
||||
|
||||
|
||||
lua.script("var = sample.new()");
|
||||
lua.script("var.key = 2");
|
||||
lua.script("var.__newindex = 4");
|
||||
lua.script("var.__index = 3");
|
||||
lua.script("var.__call = 1");
|
||||
lua.safe_script("var = sample.new()");
|
||||
lua.safe_script("var.key = 2");
|
||||
lua.safe_script("var.__newindex = 4");
|
||||
lua.safe_script("var.__index = 3");
|
||||
lua.safe_script("var.__call = 1");
|
||||
REQUIRE(values[0] == 2);
|
||||
REQUIRE(values[1] == 4);
|
||||
REQUIRE(values[2] == 3);
|
||||
|
@ -831,11 +771,11 @@ TEST_CASE("simple_usertype/meta key retrievals", "allow for special meta keys (_
|
|||
sol::state lua;
|
||||
lua.new_simple_usertype<sample>("sample", sol::meta_function::new_index, &sample::foo);
|
||||
|
||||
lua.script("var = sample.new()");
|
||||
lua.script("var.key = 2");
|
||||
lua.script("var.__newindex = 4");
|
||||
lua.script("var.__index = 3");
|
||||
lua.script("var.__call = 1");
|
||||
lua.safe_script("var = sample.new()");
|
||||
lua.safe_script("var.key = 2");
|
||||
lua.safe_script("var.__newindex = 4");
|
||||
lua.safe_script("var.__index = 3");
|
||||
lua.safe_script("var.__call = 1");
|
||||
REQUIRE(values[0] == 2);
|
||||
REQUIRE(values[1] == 4);
|
||||
REQUIRE(values[2] == 3);
|
||||
|
@ -871,10 +811,10 @@ TEST_CASE("simple_usertype/static properties", "allow for static functions to ge
|
|||
"g", sol::property(&test_t::s_func, &test_t::g_func)
|
||||
);
|
||||
|
||||
lua.script("v1 = test.f()");
|
||||
lua.script("v2 = test.g");
|
||||
lua.script("test.g = 60");
|
||||
lua.script("v2a = test.g");
|
||||
lua.safe_script("v1 = test.f()");
|
||||
lua.safe_script("v2 = test.g");
|
||||
lua.safe_script("test.g = 60");
|
||||
lua.safe_script("v2a = test.g");
|
||||
int v1 = lua["v1"];
|
||||
REQUIRE(v1 == 24);
|
||||
double v2 = lua["v2"];
|
||||
|
@ -914,7 +854,7 @@ TEST_CASE("simple_usertype/indexing", "make sure simple usertypes can be indexed
|
|||
sol::meta_function::new_index, &indexing_test::setter
|
||||
);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
local t = test.new()
|
||||
v = t.a
|
||||
print(v)
|
||||
|
@ -934,7 +874,7 @@ TEST_CASE("simple_usertype/indexing", "make sure simple usertypes can be indexed
|
|||
|
||||
lua["test"]["hi"] = [](indexing_test& _self) -> int { return _self.hi(); };
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
local t = test.new()
|
||||
v = t.a;
|
||||
print(v)
|
||||
|
|
|
@ -164,12 +164,12 @@ TEST_CASE("state/multi require", "make sure that requires transfers across hand-
|
|||
TEST_CASE("state/require-safety", "make sure unrelated modules aren't harmed in using requires") {
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
std::string t1 = lua.script(R"(require 'io'
|
||||
std::string t1 = lua.safe_script(R"(require 'io'
|
||||
return 'test1')");
|
||||
sol::object ot2 = lua.require_script("test2", R"(require 'io'
|
||||
return 'test2')");
|
||||
std::string t2 = ot2.as<std::string>();
|
||||
std::string t3 = lua.script(R"(require 'io'
|
||||
std::string t3 = lua.safe_script(R"(require 'io'
|
||||
return 'test3')");
|
||||
REQUIRE(t1 == "test1");
|
||||
REQUIRE(t2 == "test2");
|
||||
|
@ -179,7 +179,7 @@ return 'test3')");
|
|||
TEST_CASE("state/leak check", "make sure there are no humongous memory leaks in iteration") {
|
||||
#if 0
|
||||
sol::state lua;
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
record = {}
|
||||
for i=1,256 do
|
||||
record[i] = i
|
||||
|
@ -244,7 +244,7 @@ return example;
|
|||
|
||||
auto bar = [&script](sol::this_state l) {
|
||||
sol::state_view lua = l;
|
||||
sol::table data = lua.script(script);
|
||||
sol::table data = lua.safe_script(script);
|
||||
|
||||
std::string str = data["str"];
|
||||
int num = data["num"];
|
||||
|
@ -256,7 +256,7 @@ return example;
|
|||
|
||||
auto foo = [&script](int, sol::this_state l) {
|
||||
sol::state_view lua = l;
|
||||
sol::table data = lua.script(script);
|
||||
sol::table data = lua.safe_script(script);
|
||||
|
||||
std::string str = data["str"];
|
||||
int num = data["num"];
|
||||
|
@ -299,7 +299,7 @@ return example;
|
|||
lua.set_function("bar", bar);
|
||||
lua.set_function("bar2", bar2);
|
||||
|
||||
lua.script("bar() bar2() foo(1) foo2(1)");
|
||||
lua.safe_script("bar() bar2() foo(1) foo2(1)");
|
||||
}
|
||||
|
||||
TEST_CASE("state/copy and move", "ensure state can be properly copied and moved") {
|
||||
|
@ -318,9 +318,9 @@ TEST_CASE("state/requires-reload", "ensure that reloading semantics do not cause
|
|||
sol::state lua;
|
||||
sol::stack_guard sg(lua);
|
||||
lua.open_libraries();
|
||||
lua.script("require 'io'\nreturn 'test1'");
|
||||
lua.safe_script("require 'io'\nreturn 'test1'");
|
||||
lua.require_script("test2", "require 'io'\nreturn 'test2'");
|
||||
lua.script("require 'io'\nreturn 'test3'");
|
||||
lua.safe_script("require 'io'\nreturn 'test3'");
|
||||
}
|
||||
|
||||
TEST_CASE("state/script, do, and load", "test success and failure cases for loading and running scripts") {
|
||||
|
@ -348,7 +348,7 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
|
|||
SECTION("script") {
|
||||
sol::state lua;
|
||||
sol::stack_guard sg(lua);
|
||||
int ar = lua.script(good);
|
||||
int ar = lua.safe_script(good);
|
||||
int a = lua["a"];
|
||||
REQUIRE(a == 21);
|
||||
REQUIRE(ar == 21);
|
||||
|
@ -366,13 +366,13 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
|
|||
SECTION("script-handler") {
|
||||
sol::state lua;
|
||||
sol::stack_guard sg(lua);
|
||||
auto errbs = lua.script(bad_syntax, sol::script_pass_on_error);
|
||||
auto errbs = lua.safe_script(bad_syntax, sol::script_pass_on_error);
|
||||
REQUIRE(!errbs.valid());
|
||||
|
||||
auto errbr = lua.script(bad_runtime, sol::script_pass_on_error);
|
||||
auto errbr = lua.safe_script(bad_runtime, sol::script_pass_on_error);
|
||||
REQUIRE(!errbr.valid());
|
||||
|
||||
auto result = lua.script(good, sol::script_pass_on_error);
|
||||
auto result = lua.safe_script(good, sol::script_pass_on_error);
|
||||
int a = lua["a"];
|
||||
int ar = result;
|
||||
REQUIRE(result.valid());
|
||||
|
@ -423,7 +423,7 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
|
|||
SECTION("script_file") {
|
||||
sol::state lua;
|
||||
sol::stack_guard sg(lua);
|
||||
int ar = lua.script_file(file_good);
|
||||
int ar = lua.safe_script_file(file_good);
|
||||
int a = lua["a"];
|
||||
REQUIRE(a == 21);
|
||||
REQUIRE(ar == 21);
|
||||
|
@ -441,13 +441,13 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
|
|||
SECTION("script_file-handler") {
|
||||
sol::state lua;
|
||||
sol::stack_guard sg(lua);
|
||||
auto errbs = lua.script_file(file_bad_syntax, sol::script_pass_on_error);
|
||||
auto errbs = lua.safe_script_file(file_bad_syntax, sol::script_pass_on_error);
|
||||
REQUIRE(!errbs.valid());
|
||||
|
||||
auto errbr = lua.script_file(file_bad_runtime, sol::script_pass_on_error);
|
||||
auto errbr = lua.safe_script_file(file_bad_runtime, sol::script_pass_on_error);
|
||||
REQUIRE(!errbr.valid());
|
||||
|
||||
auto result = lua.script_file(file_good, sol::script_pass_on_error);
|
||||
auto result = lua.safe_script_file(file_good, sol::script_pass_on_error);
|
||||
int a = lua["a"];
|
||||
int ar = result;
|
||||
REQUIRE(result.valid());
|
||||
|
|
|
@ -97,7 +97,7 @@ TEST_CASE("tables/nested cleanup", "make sure tables leave the stack balanced")
|
|||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
|
||||
lua.script("A={}");
|
||||
lua.safe_script("A={}");
|
||||
auto f = [] { return 5; };
|
||||
for (int i = 0; i < 30; i++) {
|
||||
std::string name = std::string("init") + std::to_string(i);
|
||||
|
@ -143,7 +143,7 @@ TEST_CASE("tables/for_each", "Testing the use of for_each to get values from a l
|
|||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.script("arr = {\n"
|
||||
lua.safe_script("arr = {\n"
|
||||
"[0] = \"Hi\",\n"
|
||||
"[1] = 123.45,\n"
|
||||
"[2] = \"String value\",\n"
|
||||
|
@ -200,7 +200,7 @@ TEST_CASE("tables/for_each empty", "empty tables should not crash") {
|
|||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.script("arr = {}");
|
||||
lua.safe_script("arr = {}");
|
||||
sol::table tbl = lua["arr"];
|
||||
REQUIRE(tbl.empty());
|
||||
std::size_t tablesize = 0;
|
||||
|
@ -257,7 +257,7 @@ TEST_CASE("tables/iterators", "Testing the use of iteratrs to get values from a
|
|||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.script("arr = {\n"
|
||||
lua.safe_script("arr = {\n"
|
||||
"[0] = \"Hi\",\n"
|
||||
"[1] = 123.45,\n"
|
||||
"[2] = \"String value\",\n"
|
||||
|
@ -316,7 +316,7 @@ TEST_CASE("tables/variables", "Check if tables and variables work as intended")
|
|||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base, sol::lib::os);
|
||||
lua.get<sol::table>("os").set("name", "windows");
|
||||
REQUIRE_NOTHROW(lua.script("assert(os.name == \"windows\")"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(os.name == \"windows\")"));
|
||||
}
|
||||
|
||||
TEST_CASE("tables/create", "Check if creating a table is kosher") {
|
||||
|
@ -368,7 +368,7 @@ TEST_CASE("tables/function variables", "Check if tables and function calls work
|
|||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base, sol::lib::os);
|
||||
auto run_script = [](sol::state& lua) -> void {
|
||||
lua.script("assert(os.fun() == \"test\")");
|
||||
lua.safe_script("assert(os.fun() == \"test\")");
|
||||
};
|
||||
|
||||
lua.get<sol::table>("os").set_function("fun",
|
||||
|
@ -419,7 +419,7 @@ TEST_CASE("tables/operator[]", "Check if operator[] retrieval and setting works
|
|||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.script("foo = 20\nbar = \"hello world\"");
|
||||
lua.safe_script("foo = 20\nbar = \"hello world\"");
|
||||
// basic retrieval
|
||||
std::string bar = lua["bar"];
|
||||
int foo = lua["foo"];
|
||||
|
@ -439,7 +439,7 @@ TEST_CASE("tables/operator[]", "Check if operator[] retrieval and setting works
|
|||
|
||||
// function setting
|
||||
lua["test"] = plop_xyz;
|
||||
REQUIRE_NOTHROW(lua.script("assert(test(10, 11, \"hello\") == 11)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(test(10, 11, \"hello\") == 11)"));
|
||||
|
||||
// function retrieval
|
||||
sol::function test = lua["test"];
|
||||
|
@ -450,7 +450,7 @@ TEST_CASE("tables/operator[]", "Check if operator[] retrieval and setting works
|
|||
return x * 2;
|
||||
};
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("assert(lamb(220) == 440)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(lamb(220) == 440)"));
|
||||
|
||||
// function retrieval of a lambda
|
||||
sol::function lamb = lua["lamb"];
|
||||
|
@ -552,7 +552,7 @@ TEST_CASE("tables/boolean keys", "make sure boolean keys don't get caught up in
|
|||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
tbl = {}
|
||||
tbl[true] = 10
|
||||
tbl[1] = 20
|
||||
|
|
|
@ -271,7 +271,7 @@ TEST_CASE("usertype/usertype", "Show that we can create classes from usertype an
|
|||
sol::usertype<fuser> lc{ "add", &fuser::add, "add2", &fuser::add2 };
|
||||
lua.set_usertype(lc);
|
||||
|
||||
lua.script("a = fuser:new()\n"
|
||||
lua.safe_script("a = fuser:new()\n"
|
||||
"b = a:add(1)\n"
|
||||
"c = a:add2(1)\n");
|
||||
|
||||
|
@ -299,7 +299,7 @@ TEST_CASE("usertype/usertype-constructors", "Show that we can create classes fro
|
|||
sol::usertype<crapola::fuser> lc(con, "add", &crapola::fuser::add, "add2", &crapola::fuser::add2);
|
||||
lua.set_usertype(lc);
|
||||
|
||||
lua.script(
|
||||
lua.safe_script(
|
||||
"a = fuser.new(2)\n"
|
||||
"u = a:add(1)\n"
|
||||
"v = a:add2(1)\n"
|
||||
|
@ -339,7 +339,7 @@ TEST_CASE("usertype/usertype-utility", "Show internal management of classes regi
|
|||
|
||||
lua.new_usertype<fuser>("fuser", "add", &fuser::add, "add2", &fuser::add2);
|
||||
|
||||
lua.script("a = fuser.new()\n"
|
||||
lua.safe_script("a = fuser.new()\n"
|
||||
"b = a:add(1)\n"
|
||||
"c = a:add2(1)\n");
|
||||
|
||||
|
@ -367,8 +367,8 @@ TEST_CASE("usertype/usertype-utility-derived", "usertype classes must play nice
|
|||
|
||||
lua.set_usertype(baseusertype);
|
||||
|
||||
lua.script("base = Base.new(5)");
|
||||
REQUIRE_NOTHROW(lua.script("print(base:get_num())"));
|
||||
lua.safe_script("base = Base.new(5)");
|
||||
REQUIRE_NOTHROW(lua.safe_script("print(base:get_num())"));
|
||||
|
||||
sol::constructors<sol::types<int>> derivedctor;
|
||||
sol::usertype<Derived> derivedusertype(derivedctor,
|
||||
|
@ -378,10 +378,10 @@ TEST_CASE("usertype/usertype-utility-derived", "usertype classes must play nice
|
|||
|
||||
lua.set_usertype(derivedusertype);
|
||||
|
||||
lua.script("derived = Derived.new(7)");
|
||||
lua.script("dgn = derived:get_num()\n"
|
||||
lua.safe_script("derived = Derived.new(7)");
|
||||
lua.safe_script("dgn = derived:get_num()\n"
|
||||
"print(dgn)");
|
||||
lua.script("dgn10 = derived:get_num_10()\n"
|
||||
lua.safe_script("dgn10 = derived:get_num_10()\n"
|
||||
"print(dgn10)");
|
||||
|
||||
REQUIRE((lua.get<int>("dgn10") == 70));
|
||||
|
@ -394,7 +394,7 @@ TEST_CASE("usertype/self-referential usertype", "usertype classes must play nice
|
|||
|
||||
lua.new_usertype<self_test>("test", "g", &self_test::g, "f", &self_test::f);
|
||||
|
||||
lua.script(
|
||||
lua.safe_script(
|
||||
"local a = test.new()\n"
|
||||
"a:g(\"woof\")\n"
|
||||
"a:f(a)\n"
|
||||
|
@ -429,16 +429,16 @@ TEST_CASE("usertype/issue-number-twenty-five", "Using pointers and references fr
|
|||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
lua.new_usertype<test>("test", "set", &test::set, "get", &test::get, "pointer_get", &test::pget, "fun", &test::fun, "create_get", &test::create_get);
|
||||
REQUIRE_NOTHROW(lua.script("x = test.new()"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(x:set():get() == 10)"));
|
||||
REQUIRE_NOTHROW(lua.script("y = x:pointer_get()"));
|
||||
REQUIRE_NOTHROW(lua.script("y:set():get()"));
|
||||
REQUIRE_NOTHROW(lua.script("y:fun(10)"));
|
||||
REQUIRE_NOTHROW(lua.script("x:fun(10)"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(y:fun(10) == x:fun(10), '...')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(y:fun(10) == 100, '...')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(y:set():get() == y:set():get(), '...')"));
|
||||
REQUIRE_NOTHROW(lua.script("assert(y:set():get() == 10, '...')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("x = test.new()"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(x:set():get() == 10)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("y = x:pointer_get()"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("y:set():get()"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("y:fun(10)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("x:fun(10)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(y:fun(10) == x:fun(10), '...')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(y:fun(10) == 100, '...')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(y:set():get() == y:set():get(), '...')"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(y:set():get() == 10, '...')"));
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/issue-number-thirty-five", "using value types created from lua-called C++ code, fixing user-defined types with constructors") {
|
||||
|
@ -449,9 +449,9 @@ TEST_CASE("usertype/issue-number-thirty-five", "using value types created from l
|
|||
sol::usertype<Vec> udata(ctor, "normalized", &Vec::normalized, "length", &Vec::length);
|
||||
lua.set_usertype(udata);
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("v = Vec.new(1, 2, 3)\n"
|
||||
REQUIRE_NOTHROW(lua.safe_script("v = Vec.new(1, 2, 3)\n"
|
||||
"print(v:length())"));
|
||||
REQUIRE_NOTHROW(lua.script("v = Vec.new(1, 2, 3)\n"
|
||||
REQUIRE_NOTHROW(lua.safe_script("v = Vec.new(1, 2, 3)\n"
|
||||
"print(v:normalized():length())"));
|
||||
}
|
||||
|
||||
|
@ -469,11 +469,11 @@ TEST_CASE("usertype/lua-stored-usertype", "ensure usertype values can be stored
|
|||
// usertype dies, but still usable in lua!
|
||||
}
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("collectgarbage()\n"
|
||||
REQUIRE_NOTHROW(lua.safe_script("collectgarbage()\n"
|
||||
"v = Vec.new(1, 2, 3)\n"
|
||||
"print(v:length())"));
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("v = Vec.new(1, 2, 3)\n"
|
||||
REQUIRE_NOTHROW(lua.safe_script("v = Vec.new(1, 2, 3)\n"
|
||||
"print(v:normalized():length())"));
|
||||
}
|
||||
|
||||
|
@ -489,20 +489,20 @@ TEST_CASE("usertype/member-variables", "allow table-like accessors to behave as
|
|||
"length", &Vec::length);
|
||||
lua.set_usertype(udata);
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("v = Vec.new(1, 2, 3)\n"
|
||||
REQUIRE_NOTHROW(lua.safe_script("v = Vec.new(1, 2, 3)\n"
|
||||
"v2 = Vec.new(0, 1, 0)\n"
|
||||
"print(v:length())\n"
|
||||
));
|
||||
REQUIRE_NOTHROW(lua.script("v.x = 2\n"
|
||||
REQUIRE_NOTHROW(lua.safe_script("v.x = 2\n"
|
||||
"v2.y = 2\n"
|
||||
"print(v.x, v.y, v.z)\n"
|
||||
"print(v2.x, v2.y, v2.z)\n"
|
||||
));
|
||||
REQUIRE_NOTHROW(lua.script("assert(v.x == 2)\n"
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(v.x == 2)\n"
|
||||
"assert(v2.x == 0)\n"
|
||||
"assert(v2.y == 2)\n"
|
||||
));
|
||||
REQUIRE_NOTHROW(lua.script("v.x = 3\n"
|
||||
REQUIRE_NOTHROW(lua.safe_script("v.x = 3\n"
|
||||
"local x = v.x\n"
|
||||
"assert(x == 3)\n"
|
||||
));
|
||||
|
@ -518,8 +518,8 @@ TEST_CASE("usertype/member-variables", "allow table-like accessors to behave as
|
|||
);
|
||||
|
||||
breaks& b = lua["b"];
|
||||
REQUIRE_NOTHROW(lua.script("b.f = function () print('BARK!') end"));
|
||||
REQUIRE_NOTHROW(lua.script("b.f()"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("b.f = function () print('BARK!') end"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("b.f()"));
|
||||
REQUIRE_NOTHROW(b.f());
|
||||
}
|
||||
|
||||
|
@ -535,8 +535,8 @@ TEST_CASE("usertype/nonmember-functions", "let users set non-member functions th
|
|||
}
|
||||
).get<sol::table>("giver").set_function("stuff", giver::stuff);
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("giver.stuff()"));
|
||||
REQUIRE_NOTHROW(lua.script("t = giver.new()\n"
|
||||
REQUIRE_NOTHROW(lua.safe_script("giver.stuff()"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("t = giver.new()\n"
|
||||
"print(tostring(t))\n"
|
||||
"t:gief()\n"
|
||||
"t:gief_stuff(20)\n"));
|
||||
|
@ -575,7 +575,7 @@ TEST_CASE("regressions/one", "issue number 48") {
|
|||
sol::state lua;
|
||||
lua.new_usertype<vars>("vars",
|
||||
"boop", &vars::boop);
|
||||
REQUIRE_NOTHROW(lua.script("beep = vars.new()\n"
|
||||
REQUIRE_NOTHROW(lua.safe_script("beep = vars.new()\n"
|
||||
"beep.boop = 1"));
|
||||
// test for segfault
|
||||
auto my_var = lua.get<vars>("beep");
|
||||
|
@ -612,37 +612,6 @@ TEST_CASE("usertype/get-set-references", "properly get and set with std::ref sem
|
|||
REQUIRE(rvar.boop == ref_var.boop);
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/destructor-tests", "Show that proper copies / destruction happens") {
|
||||
static int created = 0;
|
||||
static int destroyed = 0;
|
||||
static void* last_call = nullptr;
|
||||
struct x {
|
||||
x() { ++created; }
|
||||
x(const x&) { ++created; }
|
||||
x(x&&) { ++created; }
|
||||
x& operator=(const x&) { return *this; }
|
||||
x& operator=(x&&) { return *this; }
|
||||
~x() { ++destroyed; }
|
||||
};
|
||||
{
|
||||
sol::state lua;
|
||||
lua.new_usertype<x>("x");
|
||||
x x1;
|
||||
x x2;
|
||||
lua.set("x1copy", x1, "x2copy", x2, "x1ref", std::ref(x1));
|
||||
x& x1copyref = lua["x1copy"];
|
||||
x& x2copyref = lua["x2copy"];
|
||||
x& x1ref = lua["x1ref"];
|
||||
REQUIRE(created == 4);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE(std::addressof(x1) == std::addressof(x1ref));
|
||||
REQUIRE(std::addressof(x1copyref) != std::addressof(x1));
|
||||
REQUIRE(std::addressof(x2copyref) != std::addressof(x2));
|
||||
}
|
||||
REQUIRE(created == 4);
|
||||
REQUIRE(destroyed == 4);
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/private-constructible", "Check to make sure special snowflake types from Enterprise thingamahjongs work properly.") {
|
||||
int numsaved = factory_test::num_saved;
|
||||
int numkilled = factory_test::num_killed;
|
||||
|
@ -658,9 +627,9 @@ TEST_CASE("usertype/private-constructible", "Check to make sure special snowflak
|
|||
|
||||
std::unique_ptr<factory_test, factory_test::deleter> f = factory_test::make();
|
||||
lua.set("true_a", factory_test::true_a, "f", f.get());
|
||||
REQUIRE_NOTHROW(lua.script("assert(f.a == true_a)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(f.a == true_a)"));
|
||||
|
||||
REQUIRE_NOTHROW(lua.script(
|
||||
REQUIRE_NOTHROW(lua.safe_script(
|
||||
"local fresh_f = factory_test:new()\n"
|
||||
"assert(fresh_f.a == true_a)\n"));
|
||||
}
|
||||
|
@ -682,7 +651,7 @@ TEST_CASE("usertype/const-pointer", "Make sure const pointers can be taken") {
|
|||
);
|
||||
lua.set("a", A_x());
|
||||
lua.set("b", B_foo());
|
||||
lua.script("x = b:foo(a)");
|
||||
lua.safe_script("x = b:foo(a)");
|
||||
int x = lua["x"];
|
||||
REQUIRE(x == 201);
|
||||
}
|
||||
|
@ -713,7 +682,7 @@ TEST_CASE("usertype/overloading", "Check if overloading works properly for usert
|
|||
|
||||
const std::string bark_58 = "bark 58";
|
||||
|
||||
REQUIRE_NOTHROW(lua.script(
|
||||
REQUIRE_NOTHROW(lua.safe_script(
|
||||
"r = woof:new()\n"
|
||||
"a = r:func(1)\n"
|
||||
"b = r:func(1, 2)\n"
|
||||
|
@ -782,7 +751,7 @@ TEST_CASE("usertype/reference-and-constness", "Make sure constness compiles prop
|
|||
lua.set("n", nested());
|
||||
lua.set("o", outer());
|
||||
lua.set("f", sol::c_call<decltype(&nested::f), &nested::f>);
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
x = w.b
|
||||
x.var = 20
|
||||
val = w.b.var == x.var
|
||||
|
@ -839,8 +808,8 @@ TEST_CASE("usertype/readonly-and-static-functions", "Check if static functions c
|
|||
sol::meta_function::call_function, &bark::operator()
|
||||
);
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("assert(bark.oh_boy('woo') == 3)"));
|
||||
REQUIRE_NOTHROW(lua.script("bark.oh_boy()"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(bark.oh_boy('woo') == 3)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("bark.oh_boy()"));
|
||||
|
||||
bark b;
|
||||
lua.set("b", &b);
|
||||
|
@ -865,7 +834,7 @@ TEST_CASE("usertype/readonly-and-static-functions", "Check if static functions c
|
|||
REQUIRE(z);
|
||||
REQUIRE(w == 5);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
lx = b(1)
|
||||
ly = getmetatable(b).__call(b, 1)
|
||||
lz = b.something()
|
||||
|
@ -926,11 +895,11 @@ TEST_CASE("usertype/properties", "Check if member properties/variables work") {
|
|||
bark b;
|
||||
lua.set("b", &b);
|
||||
|
||||
lua.script("b.a = 59");
|
||||
lua.script("var2_0 = b.a");
|
||||
lua.script("var2_1 = b.b");
|
||||
lua.script("b.d = 1568");
|
||||
lua.script("var2_2 = b.c");
|
||||
lua.safe_script("b.a = 59");
|
||||
lua.safe_script("var2_0 = b.a");
|
||||
lua.safe_script("var2_1 = b.b");
|
||||
lua.safe_script("b.d = 1568");
|
||||
lua.safe_script("var2_2 = b.c");
|
||||
|
||||
int var2_0 = lua["var2_0"];
|
||||
int var2_1 = lua["var2_1"];
|
||||
|
@ -987,7 +956,7 @@ TEST_CASE("usertype/call_constructor", "make sure lua types can be constructed w
|
|||
, sol::call_constructor, sol::constructors<sol::types<>, sol::types<int>>()
|
||||
);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
t = thing(256)
|
||||
)");
|
||||
|
||||
|
@ -1004,13 +973,13 @@ TEST_CASE("usertype/call_constructor-factories", "make sure tables can be passed
|
|||
sol::call_constructor, sol::factories(&matrix_xf::from_lua_table)
|
||||
);
|
||||
|
||||
lua.script("m = mat{ {1.1, 2.2} }");
|
||||
lua.safe_script("m = mat{ {1.1, 2.2} }");
|
||||
|
||||
lua.new_usertype<matrix_xi>("mati",
|
||||
sol::call_constructor, sol::factories(&matrix_xi::from_lua_table)
|
||||
);
|
||||
|
||||
lua.script("mi = mati{ {1, 2} }");
|
||||
lua.safe_script("mi = mati{ {1, 2} }");
|
||||
|
||||
matrix_xf& m = lua["m"];
|
||||
REQUIRE(m.a == 1.1f);
|
||||
|
@ -1044,7 +1013,7 @@ TEST_CASE("usertype/call_constructor_2", "prevent metatable regression") {
|
|||
sol::call_constructor, sol::constructors<sol::types<>, sol::types<const class02&>, sol::types<const class01&>>()
|
||||
);
|
||||
|
||||
REQUIRE_NOTHROW(lua.script(R"(
|
||||
REQUIRE_NOTHROW(lua.safe_script(R"(
|
||||
x = class01()
|
||||
y = class02(x)
|
||||
)"));
|
||||
|
@ -1138,7 +1107,7 @@ TEST_CASE("usertype/coverage", "try all the things") {
|
|||
|
||||
INFO("usertype created");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
e = ext_getset()
|
||||
w = e:x(e:x(), e:x(e:x()))
|
||||
print(w)
|
||||
|
@ -1149,7 +1118,7 @@ print(w)
|
|||
|
||||
INFO("REQUIRE(w) successful");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
e:set(500)
|
||||
e.sset(24)
|
||||
x = e:get()
|
||||
|
@ -1163,7 +1132,7 @@ y = e.sget(20)
|
|||
|
||||
INFO("REQUIRE(x, y) successful");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
e.bark = 5001
|
||||
a = e:get()
|
||||
print(e.bark)
|
||||
|
@ -1182,7 +1151,7 @@ print(b)
|
|||
|
||||
INFO("REQUIRE(a, b) successful");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
c = e.readonlybark
|
||||
d = e.meow
|
||||
print(e.readonlybark)
|
||||
|
@ -1198,7 +1167,7 @@ print(d)
|
|||
|
||||
INFO("REQUIRE(c, d) successful");
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
e.writeonlypropbark = 500
|
||||
z = e.readonlypropbark
|
||||
print(e.readonlybark)
|
||||
|
@ -1239,7 +1208,7 @@ TEST_CASE("usertype/copyability", "make sure user can write to a class variable
|
|||
lua.new_usertype<NoCopy>("NoCopy", "val", sol::property(&NoCopy::get, &NoCopy::set));
|
||||
|
||||
REQUIRE_NOTHROW(
|
||||
lua.script(R"__(
|
||||
lua.safe_script(R"__(
|
||||
nocopy = NoCopy.new()
|
||||
nocopy.val = 5
|
||||
)__")
|
||||
|
@ -1260,7 +1229,7 @@ TEST_CASE("usertype/protect", "users should be allowed to manually protect a fun
|
|||
);
|
||||
|
||||
REQUIRE_NOTHROW(
|
||||
lua.script(R"__(
|
||||
lua.safe_script(R"__(
|
||||
pm = protect_me.new()
|
||||
value = pcall(pm.gen,pm)
|
||||
)__")
|
||||
|
@ -1269,59 +1238,6 @@ value = pcall(pm.gen,pm)
|
|||
REQUIRE_FALSE(value);
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/shared-ptr-regression", "usertype metatables should not screw over unique usertype metatables") {
|
||||
static int created = 0;
|
||||
static int destroyed = 0;
|
||||
struct test {
|
||||
test() {
|
||||
++created;
|
||||
}
|
||||
|
||||
~test() {
|
||||
++destroyed;
|
||||
}
|
||||
};
|
||||
{
|
||||
std::list<std::shared_ptr<test>> tests;
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
|
||||
lua.new_usertype<test>("test",
|
||||
"create", [&]() -> std::shared_ptr<test> {
|
||||
tests.push_back(std::make_shared<test>());
|
||||
return tests.back();
|
||||
}
|
||||
);
|
||||
REQUIRE(created == 0);
|
||||
REQUIRE(destroyed == 0);
|
||||
lua.script("x = test.create()");
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE_FALSE(tests.empty());
|
||||
std::shared_ptr<test>& x = lua["x"];
|
||||
std::size_t xuse = x.use_count();
|
||||
std::size_t tuse = tests.back().use_count();
|
||||
REQUIRE(xuse == tuse);
|
||||
}
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/double-deleter-guards", "usertype metatables internally must not rely on C++ state") {
|
||||
struct c_a { int x; };
|
||||
struct c_b { int y; };
|
||||
auto routine = []() {
|
||||
sol::state lua;
|
||||
lua.new_usertype<c_a>("c_a", "x", &c_a::x);
|
||||
lua.new_usertype<c_b>("c_b", "y", &c_b::y);
|
||||
lua = sol::state();
|
||||
lua.new_usertype<c_a>("c_a", "x", &c_a::x);
|
||||
lua.new_usertype<c_b>("c_b", "y", &c_b::y);
|
||||
lua = sol::state();
|
||||
};
|
||||
REQUIRE_NOTHROW(routine());
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/vars", "usertype vars can bind various class items") {
|
||||
static int muh_variable = 25;
|
||||
static int through_variable = 10;
|
||||
|
@ -1349,7 +1265,7 @@ TEST_CASE("usertype/vars", "usertype vars can bind various class items") {
|
|||
REQUIRE(pretg2 == 10);
|
||||
REQUIRE(pretrg2 == 10);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
print(test.straight)
|
||||
test.straight = 50
|
||||
print(test.straight)
|
||||
|
@ -1357,7 +1273,7 @@ print(test.straight)
|
|||
int s = lua["test"]["straight"];
|
||||
REQUIRE(s == 50);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
t = test.new()
|
||||
print(t.global)
|
||||
t.global = 50
|
||||
|
@ -1368,7 +1284,7 @@ print(t.global)
|
|||
REQUIRE(muh_variable == 25);
|
||||
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
print(t.ref_global)
|
||||
t.ref_global = 50
|
||||
print(t.ref_global)
|
||||
|
@ -1378,7 +1294,7 @@ print(t.ref_global)
|
|||
REQUIRE(muh_variable == 50);
|
||||
|
||||
REQUIRE(through_variable == 10);
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
print(test.global2)
|
||||
test.global2 = 35
|
||||
print(test.global2)
|
||||
|
@ -1387,7 +1303,7 @@ print(test.global2)
|
|||
REQUIRE(through_variable == 10);
|
||||
REQUIRE(tv == 35);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
print(test.ref_global2)
|
||||
test.ref_global2 = 35
|
||||
print(test.ref_global2)
|
||||
|
@ -1421,10 +1337,10 @@ TEST_CASE("usertype/static-properties", "allow for static functions to get and s
|
|||
"g", sol::property(&test_t::s_func, &test_t::g_func)
|
||||
);
|
||||
|
||||
lua.script("v1 = test.f()");
|
||||
lua.script("v2 = test.g");
|
||||
lua.script("test.g = 60");
|
||||
lua.script("v2a = test.g");
|
||||
lua.safe_script("v1 = test.f()");
|
||||
lua.safe_script("v2 = test.g");
|
||||
lua.safe_script("test.g = 60");
|
||||
lua.safe_script("v2a = test.g");
|
||||
int v1 = lua["v1"];
|
||||
REQUIRE(v1 == 24);
|
||||
double v2 = lua["v2"];
|
||||
|
@ -1455,7 +1371,7 @@ TEST_CASE("usertype/var-and-property", "make sure const vars are readonly and pr
|
|||
"global", sol::var(std::ref(arf))
|
||||
);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
t = test.new()
|
||||
print(t.prop)
|
||||
t.prop = 50
|
||||
|
@ -1465,7 +1381,7 @@ print(t.prop)
|
|||
test& t = lua["t"];
|
||||
REQUIRE(t.value == 50);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
t = test.new()
|
||||
print(t.global)
|
||||
)");
|
||||
|
@ -1473,7 +1389,7 @@ print(t.global)
|
|||
auto result = lua.safe_script("t.global = 20", sol::script_pass_on_error);
|
||||
REQUIRE_FALSE(result.valid());
|
||||
}
|
||||
lua.script("print(t.global)");
|
||||
lua.safe_script("print(t.global)");
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/unique_usertype-check", "make sure unique usertypes don't get pushed as references with function calls and the like") {
|
||||
|
@ -1492,7 +1408,7 @@ TEST_CASE("usertype/unique_usertype-check", "make sure unique usertypes don't ge
|
|||
"get_name", &Entity::GetName
|
||||
);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
function my_func(entity)
|
||||
print("INSIDE LUA")
|
||||
print(entity:get_name())
|
||||
|
@ -1514,7 +1430,7 @@ TEST_CASE("usertype/abstract-base-class", "Ensure that abstract base classes and
|
|||
lua.new_usertype<abstract_A>("A", "a", &abstract_A::a);
|
||||
lua.new_usertype<abstract_B>("B", sol::base_classes, sol::bases<abstract_A>());
|
||||
REQUIRE_NOTHROW([&]() {
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
local b = B.new()
|
||||
b:a()
|
||||
)");
|
||||
|
@ -1533,45 +1449,14 @@ TEST_CASE("usertype/as_function", "Ensure that variables can be turned into func
|
|||
|
||||
B b;
|
||||
lua.set("b", &b);
|
||||
lua.script("x = b:f()");
|
||||
lua.script("y = b.b");
|
||||
lua.safe_script("x = b:f()");
|
||||
lua.safe_script("y = b.b");
|
||||
int x = lua["x"];
|
||||
int y = lua["y"];
|
||||
REQUIRE(x == 24);
|
||||
REQUIRE(y == 24);
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/destruction-test", "make sure usertypes are properly destructed and don't double-delete memory or segfault") {
|
||||
sol::state lua;
|
||||
|
||||
class CrashClass {
|
||||
public:
|
||||
CrashClass() {
|
||||
}
|
||||
|
||||
~CrashClass() {
|
||||
a = 10; // This will cause a crash.
|
||||
}
|
||||
|
||||
private:
|
||||
int a;
|
||||
};
|
||||
|
||||
lua.new_usertype<CrashClass>("CrashClass",
|
||||
sol::call_constructor, sol::constructors<sol::types<>>()
|
||||
);
|
||||
|
||||
lua.script(R"(
|
||||
function testCrash()
|
||||
local x = CrashClass()
|
||||
end
|
||||
)");
|
||||
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
lua["testCrash"]();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/call-initializers", "Ensure call constructors with initializers work well") {
|
||||
struct A {
|
||||
double f = 25.5;
|
||||
|
@ -1588,7 +1473,7 @@ TEST_CASE("usertype/call-initializers", "Ensure call constructors with initializ
|
|||
sol::call_constructor, sol::initializers(&A::init)
|
||||
);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
a = A(24.3)
|
||||
)");
|
||||
A& a = lua["a"];
|
||||
|
@ -1602,7 +1487,7 @@ TEST_CASE("usertype/missing-key", "make sure a missing key returns nil") {
|
|||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.new_usertype<thing>("thing");
|
||||
REQUIRE_NOTHROW(lua.script("v = thing.missingKey\nprint(v)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("v = thing.missingKey\nprint(v)"));
|
||||
sol::object o = lua["v"];
|
||||
bool isnil = o.is<sol::lua_nil_t>();
|
||||
REQUIRE(isnil);
|
||||
|
@ -1623,7 +1508,7 @@ TEST_CASE("usertype/runtime-extensibility", "Check if usertypes are runtime exte
|
|||
"func", &thing::func
|
||||
);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
t = thing.new()
|
||||
)");
|
||||
|
||||
|
@ -1645,19 +1530,19 @@ end
|
|||
REQUIRE_FALSE(result.valid());
|
||||
};
|
||||
|
||||
lua.script("val = t:func(2)");
|
||||
lua.safe_script("val = t:func(2)");
|
||||
val = lua["val"];
|
||||
REQUIRE(val == 2);
|
||||
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
function thing:runtime_func(a)
|
||||
return a + 1
|
||||
end
|
||||
)");
|
||||
}());
|
||||
|
||||
lua.script("val = t:runtime_func(2)");
|
||||
lua.safe_script("val = t:runtime_func(2)");
|
||||
val = lua["val"];
|
||||
REQUIRE(val == 3);
|
||||
}
|
||||
|
@ -1670,7 +1555,7 @@ end
|
|||
"v", &thing::v
|
||||
);
|
||||
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
t = thing.new()
|
||||
)");
|
||||
|
||||
|
@ -1692,19 +1577,19 @@ end
|
|||
REQUIRE_FALSE(result.valid());
|
||||
};
|
||||
|
||||
lua.script("val = t:func(2)");
|
||||
lua.safe_script("val = t:func(2)");
|
||||
val = lua["val"];
|
||||
REQUIRE(val == 2);
|
||||
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
function thing:runtime_func(a)
|
||||
return a + 1
|
||||
end
|
||||
)");
|
||||
}());
|
||||
|
||||
lua.script("val = t:runtime_func(2)");
|
||||
lua.safe_script("val = t:runtime_func(2)");
|
||||
val = lua["val"];
|
||||
REQUIRE(val == 3);
|
||||
}
|
||||
|
@ -1722,13 +1607,13 @@ TEST_CASE("usertype/runtime-replacement", "ensure that functions can be properly
|
|||
|
||||
lua.new_usertype<heart_t>("a");
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("obj = a.new()");
|
||||
lua.script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.script("v1 = obj:heartbeat()");
|
||||
lua.script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.script("v2 = obj:heartbeat()");
|
||||
lua.script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.script("v3 = obj:heartbeat()");
|
||||
lua.safe_script("obj = a.new()");
|
||||
lua.safe_script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.safe_script("v1 = obj:heartbeat()");
|
||||
lua.safe_script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.safe_script("v2 = obj:heartbeat()");
|
||||
lua.safe_script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.safe_script("v3 = obj:heartbeat()");
|
||||
}());
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
|
@ -1746,13 +1631,13 @@ TEST_CASE("usertype/runtime-replacement", "ensure that functions can be properly
|
|||
);
|
||||
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("obj = a.new()");
|
||||
lua.script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.script("v1 = obj:heartbeat()");
|
||||
lua.script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.script("v2 = obj:heartbeat()");
|
||||
lua.script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.script("v3 = obj:heartbeat()");
|
||||
lua.safe_script("obj = a.new()");
|
||||
lua.safe_script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.safe_script("v1 = obj:heartbeat()");
|
||||
lua.safe_script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.safe_script("v2 = obj:heartbeat()");
|
||||
lua.safe_script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.safe_script("v3 = obj:heartbeat()");
|
||||
}());
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
|
@ -1771,13 +1656,13 @@ TEST_CASE("usertype/runtime-replacement", "ensure that functions can be properly
|
|||
);
|
||||
|
||||
REQUIRE_NOTHROW([&lua]() {
|
||||
lua.script("obj = a.new()");
|
||||
lua.script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.script("v1 = obj:heartbeat()");
|
||||
lua.script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.script("v2 = obj:heartbeat()");
|
||||
lua.script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.script("v3 = obj:heartbeat()");
|
||||
lua.safe_script("obj = a.new()");
|
||||
lua.safe_script("function a:heartbeat () print('arf') return 1 end");
|
||||
lua.safe_script("v1 = obj:heartbeat()");
|
||||
lua.safe_script("function a:heartbeat () print('bark') return 2 end");
|
||||
lua.safe_script("v2 = obj:heartbeat()");
|
||||
lua.safe_script("a.heartbeat = function(self) print('woof') return 3 end");
|
||||
lua.safe_script("v3 = obj:heartbeat()");
|
||||
}());
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
|
@ -1808,11 +1693,11 @@ TEST_CASE("usertype/meta-key-retrievals", "allow for special meta keys (__index,
|
|||
lua["var"] = s;
|
||||
|
||||
|
||||
lua.script("var = sample.new()");
|
||||
lua.script("var.key = 2");
|
||||
lua.script("var.__newindex = 4");
|
||||
lua.script("var.__index = 3");
|
||||
lua.script("var.__call = 1");
|
||||
lua.safe_script("var = sample.new()");
|
||||
lua.safe_script("var.key = 2");
|
||||
lua.safe_script("var.__newindex = 4");
|
||||
lua.safe_script("var.__index = 3");
|
||||
lua.safe_script("var.__call = 1");
|
||||
REQUIRE(values[0] == 2);
|
||||
REQUIRE(values[1] == 4);
|
||||
REQUIRE(values[2] == 3);
|
||||
|
@ -1838,11 +1723,11 @@ TEST_CASE("usertype/meta-key-retrievals", "allow for special meta keys (__index,
|
|||
sol::state lua;
|
||||
lua.new_usertype<sample>("sample", sol::meta_function::new_index, &sample::foo);
|
||||
|
||||
lua.script("var = sample.new()");
|
||||
lua.script("var.key = 2");
|
||||
lua.script("var.__newindex = 4");
|
||||
lua.script("var.__index = 3");
|
||||
lua.script("var.__call = 1");
|
||||
lua.safe_script("var = sample.new()");
|
||||
lua.safe_script("var.key = 2");
|
||||
lua.safe_script("var.__newindex = 4");
|
||||
lua.safe_script("var.__index = 3");
|
||||
lua.safe_script("var.__call = 1");
|
||||
REQUIRE(values[0] == 2);
|
||||
REQUIRE(values[1] == 4);
|
||||
REQUIRE(values[2] == 3);
|
||||
|
@ -1871,9 +1756,9 @@ TEST_CASE("usertype/noexcept-methods", "make sure noexcept functinos and methods
|
|||
"nm", &T::noexcept_method
|
||||
);
|
||||
|
||||
lua.script("t = T.new()");
|
||||
lua.script("v1 = t.nf()");
|
||||
lua.script("v2 = t:nm()");
|
||||
lua.safe_script("t = T.new()");
|
||||
lua.safe_script("v1 = t.nf()");
|
||||
lua.safe_script("v2 = t:nm()");
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
REQUIRE(v1 == 0x61);
|
||||
|
|
|
@ -52,8 +52,8 @@ TEST_CASE("utility/variant", "test that variant can be round-tripped") {
|
|||
});
|
||||
lua["v"] = std::variant<float, int, std::string>(2);
|
||||
REQUIRE_NOTHROW([&]() {
|
||||
lua.script("assert(f(v))");
|
||||
lua.script("assert(g(v))");
|
||||
lua.safe_script("assert(f(v))");
|
||||
lua.safe_script("assert(g(v))");
|
||||
}());
|
||||
}
|
||||
SECTION("throws") {
|
||||
|
@ -93,7 +93,7 @@ TEST_CASE("utility/string_view", "test that string_view can be taken as an argum
|
|||
lua["v"] = "bark!";
|
||||
|
||||
REQUIRE_NOTHROW([&]() {
|
||||
lua.script("assert(f(v))");
|
||||
lua.safe_script("assert(f(v))");
|
||||
}());
|
||||
#else
|
||||
REQUIRE(true);
|
||||
|
@ -148,9 +148,9 @@ TEST_CASE("utility/this_state", "Ensure this_state argument can be gotten anywhe
|
|||
int a = fx(25, 25);
|
||||
INFO("finished setting fx");
|
||||
INFO("calling a script");
|
||||
lua.script("a = with_state_2(25, 25)");
|
||||
lua.safe_script("a = with_state_2(25, 25)");
|
||||
INFO("calling c script");
|
||||
lua.script("c = b:with_state(25, 25)");
|
||||
lua.safe_script("c = b:with_state(25, 25)");
|
||||
INFO("getting a");
|
||||
int la = lua["a"];
|
||||
INFO("getting b");
|
||||
|
|
|
@ -25,9 +25,9 @@ TEST_CASE("variadics/variadic_args", "Check to see we can receive multiple argum
|
|||
return{ r, r > 200 };
|
||||
});
|
||||
|
||||
lua.script("x = v(25, 25)");
|
||||
lua.script("x2 = v(25, 25, 100, 50, 250, 150)");
|
||||
lua.script("x3 = v(1, 2, 3, 4, 5, 6)");
|
||||
lua.safe_script("x = v(25, 25)");
|
||||
lua.safe_script("x2 = v(25, 25, 100, 50, 250, 150)");
|
||||
lua.safe_script("x3 = v(1, 2, 3, 4, 5, 6)");
|
||||
|
||||
structure& lx = lua["x"];
|
||||
structure& lx2 = lua["x2"];
|
||||
|
@ -46,8 +46,8 @@ TEST_CASE("variadics/required with variadic_args", "Check if a certain number of
|
|||
[](sol::this_state, sol::variadic_args, int, int) {
|
||||
}
|
||||
);
|
||||
REQUIRE_NOTHROW(lua.script("v(20, 25, 30)"));
|
||||
REQUIRE_NOTHROW(lua.script("v(20, 25)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("v(20, 25, 30)"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("v(20, 25)"));
|
||||
auto result = lua.safe_script("v(20)", sol::script_pass_on_error);
|
||||
REQUIRE_FALSE(result.valid());
|
||||
}
|
||||
|
@ -72,8 +72,8 @@ TEST_CASE("variadics/variadic_args get type", "Make sure we can inspect types pr
|
|||
REQUIRE(working);
|
||||
});
|
||||
|
||||
lua.script("f(1, 'bark', true)");
|
||||
lua.script("f(2, 'wuf', false)");
|
||||
lua.safe_script("f(1, 'bark', true)");
|
||||
lua.safe_script("f(2, 'wuf', false)");
|
||||
}
|
||||
|
||||
TEST_CASE("variadics/variadic_results", "returning a variable amount of arguments from C++") {
|
||||
|
@ -90,7 +90,7 @@ TEST_CASE("variadics/variadic_results", "returning a variable amount of argument
|
|||
});
|
||||
|
||||
REQUIRE_NOTHROW([&]() {
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
v1, v2, v3 = f()
|
||||
v4, v5 = g()
|
||||
)");
|
||||
|
@ -116,7 +116,7 @@ TEST_CASE("variadics/variadic_results", "returning a variable amount of argument
|
|||
});
|
||||
|
||||
REQUIRE_NOTHROW([&]() {
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
v1, v2, v3 = f(1, 'bark', true)
|
||||
v4, v5 = f(25, 82)
|
||||
)");
|
||||
|
@ -156,7 +156,7 @@ TEST_CASE("variadics/variadic_results", "returning a variable amount of argument
|
|||
});
|
||||
|
||||
REQUIRE_NOTHROW([&]() {
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
v1, v2, v3 = f(true)
|
||||
v4, v5, v6, v7 = f(false)
|
||||
)");
|
||||
|
@ -208,10 +208,10 @@ TEST_CASE("variadics/fallback_constructor", "ensure constructor matching behaves
|
|||
);
|
||||
|
||||
REQUIRE_NOTHROW([&]() {
|
||||
lua.script("v0 = vec2();");
|
||||
lua.script("v1 = vec2(1);");
|
||||
lua.script("v2 = vec2(1, 2);");
|
||||
lua.script("v3 = vec2(v2)");
|
||||
lua.safe_script("v0 = vec2();");
|
||||
lua.safe_script("v1 = vec2(1);");
|
||||
lua.safe_script("v2 = vec2(1, 2);");
|
||||
lua.safe_script("v3 = vec2(v2)");
|
||||
}());
|
||||
|
||||
vec2& v0 = lua["v0"];
|
||||
|
|
40
tests.cpp
40
tests.cpp
|
@ -77,40 +77,40 @@ TEST_CASE("simple/set", "Check if the set works properly.") {
|
|||
test_stack_guard g(lua.lua_state(), begintop, endtop);
|
||||
lua.set("a", 9);
|
||||
} REQUIRE(begintop == endtop);
|
||||
REQUIRE_NOTHROW(lua.script("if a ~= 9 then error('wrong value') end"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("if a ~= 9 then error('wrong value') end"));
|
||||
{
|
||||
test_stack_guard g(lua.lua_state(), begintop, endtop);
|
||||
lua.set("d", "hello");
|
||||
} REQUIRE(begintop == endtop);
|
||||
REQUIRE_NOTHROW(lua.script("if d ~= 'hello' then error('expected \\'hello\\', got '.. tostring(d)) end"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("if d ~= 'hello' then error('expected \\'hello\\', got '.. tostring(d)) end"));
|
||||
|
||||
{
|
||||
test_stack_guard g(lua.lua_state(), begintop, endtop);
|
||||
lua.set("e", std::string("hello"), "f", true);
|
||||
} REQUIRE(begintop == endtop);
|
||||
REQUIRE_NOTHROW(lua.script("if d ~= 'hello' then error('expected \\'hello\\', got '.. tostring(d)) end"));
|
||||
REQUIRE_NOTHROW(lua.script("if f ~= true then error('wrong value') end"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("if d ~= 'hello' then error('expected \\'hello\\', got '.. tostring(d)) end"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("if f ~= true then error('wrong value') end"));
|
||||
}
|
||||
|
||||
TEST_CASE("simple/get", "Tests if the get function works properly.") {
|
||||
sol::state lua;
|
||||
int begintop = 0, endtop = 0;
|
||||
|
||||
lua.script("a = 9");
|
||||
lua.safe_script("a = 9");
|
||||
{
|
||||
test_stack_guard g(lua.lua_state(), begintop, endtop);
|
||||
auto a = lua.get<int>("a");
|
||||
REQUIRE(a == 9.0);
|
||||
} REQUIRE(begintop == endtop);
|
||||
|
||||
lua.script("b = nil");
|
||||
lua.safe_script("b = nil");
|
||||
{
|
||||
test_stack_guard g(lua.lua_state(), begintop, endtop);
|
||||
REQUIRE_NOTHROW(lua.get<sol::nil_t>("b"));
|
||||
} REQUIRE(begintop == endtop);
|
||||
|
||||
lua.script("d = 'hello'");
|
||||
lua.script("e = true");
|
||||
lua.safe_script("d = 'hello'");
|
||||
lua.safe_script("e = true");
|
||||
{
|
||||
test_stack_guard g(lua.lua_state(), begintop, endtop);
|
||||
std::string d;
|
||||
|
@ -124,7 +124,7 @@ TEST_CASE("simple/get", "Tests if the get function works properly.") {
|
|||
TEST_CASE("simple/set and get global integer", "Tests if the get function works properly with global integers") {
|
||||
sol::state lua;
|
||||
lua[1] = 25.4;
|
||||
lua.script("b = 1");
|
||||
lua.safe_script("b = 1");
|
||||
double a = lua.get<double>(1);
|
||||
double b = lua.get<double>("b");
|
||||
REQUIRE(a == 25.4);
|
||||
|
@ -169,7 +169,7 @@ TEST_CASE("simple/addition", "check if addition works and can be gotten through
|
|||
sol::state lua;
|
||||
|
||||
lua.set("b", 0.2);
|
||||
lua.script("c = 9 + b");
|
||||
lua.safe_script("c = 9 + b");
|
||||
auto c = lua.get<double>("c");
|
||||
|
||||
REQUIRE(c == 9.2);
|
||||
|
@ -179,7 +179,7 @@ TEST_CASE("simple/if", "check if if statements work through lua") {
|
|||
sol::state lua;
|
||||
|
||||
std::string program = "if true then f = 0.1 else f = 'test' end";
|
||||
lua.script(program);
|
||||
lua.safe_script(program);
|
||||
auto f = lua.get<double>("f");
|
||||
|
||||
REQUIRE(f == 0.1);
|
||||
|
@ -223,7 +223,7 @@ TEST_CASE("interop/null-to-nil-and-back", "nil should be the given type when a p
|
|||
lua.set_function("rofl", [](int* x) {
|
||||
INFO(x);
|
||||
});
|
||||
REQUIRE_NOTHROW(lua.script("x = lol()\n"
|
||||
REQUIRE_NOTHROW(lua.safe_script("x = lol()\n"
|
||||
"rofl(x)\n"
|
||||
"assert(x == nil)"));
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ TEST_CASE("object/conversions", "make sure all basic reference types can be made
|
|||
|
||||
struct d {};
|
||||
|
||||
lua.script("function f () print('bark') end");
|
||||
lua.safe_script("function f () print('bark') end");
|
||||
lua["d"] = d{};
|
||||
lua["l"] = static_cast<void*>(nullptr);
|
||||
|
||||
|
@ -317,7 +317,7 @@ TEST_CASE("feature/indexing overrides", "make sure index functions can be overri
|
|||
, "props", sol::property(&DynamicObject::get_dynamic_props)
|
||||
);
|
||||
|
||||
lua.script(R"__(
|
||||
lua.safe_script(R"__(
|
||||
obj = DynamicObject:new()
|
||||
obj.props.name = 'test name'
|
||||
print('name = ' .. obj.props.name)
|
||||
|
@ -356,7 +356,7 @@ TEST_CASE("features/indexing numbers", "make sure indexing functions can be over
|
|||
lua.new_usertype<vector>("vector", sol::constructors<sol::types<>>(),
|
||||
sol::meta_function::index, &vector::my_index,
|
||||
sol::meta_function::new_index, &vector::my_new_index);
|
||||
lua.script("v = vector.new()\n"
|
||||
lua.safe_script("v = vector.new()\n"
|
||||
"print(v[1])\n"
|
||||
"v[2] = 3\n"
|
||||
"print(v[2])\n"
|
||||
|
@ -403,7 +403,7 @@ TEST_CASE("features/multiple inheritance", "Ensure that multiple inheritance wor
|
|||
"a2", &complex::a2,
|
||||
sol::base_classes, sol::bases<base1, base2>()
|
||||
);
|
||||
lua.script("c = complex.new()\n"
|
||||
lua.safe_script("c = complex.new()\n"
|
||||
"s = simple.new()\n"
|
||||
"b1 = base1.new()\n"
|
||||
"b2 = base1.new()\n"
|
||||
|
@ -455,7 +455,7 @@ TEST_CASE("optional/left out args", "Make sure arguments can be left out of opti
|
|||
// sol::optional needs an argument no matter what?
|
||||
lua.set_function("func_opt_ret_bool", func_opt_ret_bool);
|
||||
REQUIRE_NOTHROW([&]{
|
||||
lua.script(R"(
|
||||
lua.safe_script(R"(
|
||||
func_opt_ret_bool(42)
|
||||
func_opt_ret_bool()
|
||||
print('ok')
|
||||
|
@ -496,7 +496,7 @@ TEST_CASE("proxy/proper-pushing", "allow proxies to reference other proxies and
|
|||
T t;
|
||||
lua["t1"] = &t;
|
||||
lua["t2"] = lua["t1"];
|
||||
lua.script("b = t1 == t2");
|
||||
lua.safe_script("b = t1 == t2");
|
||||
bool b = lua["b"];
|
||||
REQUIRE(b);
|
||||
}
|
||||
|
@ -563,7 +563,7 @@ TEST_CASE("object/is", "test whether or not the is abstraction works properly fo
|
|||
lua.open_libraries(sol::lib::base);
|
||||
lua.set_function("is_thing", [](sol::stack_object obj) { return obj.is<thing>(); } );
|
||||
lua["a"] = thing{};
|
||||
REQUIRE_NOTHROW(lua.script("assert(is_thing(a))"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(is_thing(a))"));
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
|
@ -572,6 +572,6 @@ TEST_CASE("object/is", "test whether or not the is abstraction works properly fo
|
|||
lua.open_libraries(sol::lib::base);
|
||||
lua.set_function("is_thing", [](sol::object obj) { return obj.is<thing>(); });
|
||||
lua["a"] = thing{};
|
||||
REQUIRE_NOTHROW(lua.script("assert(is_thing(a))"));
|
||||
REQUIRE_NOTHROW(lua.safe_script("assert(is_thing(a))"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user