mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Let's do iiiit.
This commit is contained in:
parent
08b5204dee
commit
de359acb3e
|
@ -74,18 +74,18 @@ Explanations for a few categories are below (rest are self-explanatory).
|
||||||
|
|
||||||
* optional: Support for getting an element, or potentially not (and not forcing the default construction of what amounts to a bogus/dead object). Usually comes with ``std(::experimental)::optional``. It's a fairly new class, so a hand-rolled class internal to the library with similar semantics is also acceptable
|
* optional: Support for getting an element, or potentially not (and not forcing the default construction of what amounts to a bogus/dead object). Usually comes with ``std(::experimental)::optional``. It's a fairly new class, so a hand-rolled class internal to the library with similar semantics is also acceptable
|
||||||
* tables: Some sort of abstraction for dealing with tables. Ideal support is ``mytable["some_key"] = value``, and everything that the syntax implies.
|
* tables: Some sort of abstraction for dealing with tables. Ideal support is ``mytable["some_key"] = value``, and everything that the syntax implies.
|
||||||
* table chaining: In conjunction with tables, having the ability to do nest deeply into tables ``mytable["key1"]["key2"]["key3"]``. Note that this becomes a tripping point for some libraries: crashing if ``"key1"`` doesn't exist while trying to access ``"key2"`` (Sol avoids this specifically when you use ``sol::optional``), and sometimes it's also a heavy performance bottleneck as expressions are not lazy-evaluated by a library.
|
* table chaining: In conjunction with tables, having the ability to query deeply into tables ``mytable["key1"]["key2"]["key3"]``. Note that this becomes a tripping point for some libraries: crashing if ``"key1"`` doesn't exist while trying to access ``"key2"`` (Sol avoids this specifically when you use ``sol::optional``), and sometimes it's also a heavy performance bottleneck as expressions are not lazy-evaluated by a library.
|
||||||
* arbitrary keys: Letting C++ code use userdata, other tables, integers, etc. as keys for into a table without dropping to the plain API.
|
* arbitrary keys: Letting C++ code use userdata, other tables, integers, etc. as keys for into a table.
|
||||||
* user-defined types (udts): C++ types given form and function in lua code.
|
* user-defined types (udts): C++ types given form and function in Lua code.
|
||||||
* udts - member functions: C++ member functions on a type, usually callable with ``my_object:foo(1)`` or similar in Lua.
|
* udts - member functions: C++ member functions on a type, usually callable with ``my_object:foo(1)`` or similar in Lua.
|
||||||
* udts - variables: C++ member variables, manipulated by ``my_object.var = 24`` and friends
|
* udts - variables: C++ member variables, manipulated by ``my_object.var = 24`` and friends
|
||||||
* function binding: Support for binding all types of functions. Lambdas, member functions, free functions, in different contexts, etc...
|
* function binding: Support for binding all types of functions. Lambdas, member functions, free functions, in different contexts, etc...
|
||||||
* protected function: Use of ``lua_pcall`` to call a function, which offers error-handling and trampolining
|
* protected function: Use of ``lua_pcall`` to call a function, which offers error-handling and trampolining (as well as the ability to opt-in / opt-out of this behavior)
|
||||||
* multi-return: returning multiple values from and to lua
|
* multi-return: returning multiple values from and to Lua (generally through ``std::tuple<...>`` or in some other way)
|
||||||
* variadic/variant argument: being able to accept "anything" from lua, and even return "anything" to lua
|
* variadic/variant argument: being able to accept "anything" from Lua, and even return "anything" to Lua (``object`` abstraction, variadic arguments, etc...)
|
||||||
* inheritance: allowing some degree of subtyping or inheritance on classes / userdata from lua
|
* inheritance: allowing some degree of subtyping or inheritance on classes / userdata from Lua - this generally means that you can retrieve a base pointer from Lua even if you hand the library a derived pointer
|
||||||
* overloading: the ability to call overloaded functions, matched based on arity or type (``foo( 1 )`` from lua calls a different function then ``foo( "bark" )``).
|
* overloading: the ability to call overloaded functions, matched based on arity or type (``foo( 1 )`` from lua calls a different function then ``foo( "bark" )``).
|
||||||
* lua thread: basic wrapping of the lua thread API; ties in with coroutine.
|
* Lua thread: basic wrapping of the lua thread API; ties in with coroutine.
|
||||||
* coroutines: allowing a function to be called multiple times, resuming the execution of a Lua coroutine each time
|
* coroutines: allowing a function to be called multiple times, resuming the execution of a Lua coroutine each time
|
||||||
|
|
||||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||||
|
@ -112,7 +112,7 @@ Explanations for a few categories are below (rest are self-explanatory).
|
||||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||||
| function binding | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ |
|
| function binding | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ |
|
||||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||||
| protected function | ~ | ✗ | ~ | ~ | ~ | ✔ | ~ | ✔ | ~ | ~ | ~ | ~ | ~ |
|
| protected call | ~ | ✗ | ~ | ~ | ~ | ✔ | ~ | ✔ | ~ | ~ | ~ | ~ | ~ |
|
||||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||||
| multi-return | ~ | ✗ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ~ | ✔ | ~ | ✗ |
|
| multi-return | ~ | ✗ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ~ | ✔ | ~ | ✗ |
|
||||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||||
|
@ -122,7 +122,7 @@ Explanations for a few categories are below (rest are self-explanatory).
|
||||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||||
| overloading | ~ | ✗ | ✗ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ | ✔ | ✔ | ✗ | ✗ |
|
| overloading | ~ | ✗ | ✗ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ | ✔ | ✔ | ✗ | ✗ |
|
||||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||||
| lua thread | ~ | ✗ | ~ | ✗ | ✗ | ✔ | ✔ | ✗ | ✔ | ✗ | ✗ | ✔ | ✗ |
|
| Lua thread | ~ | ✗ | ~ | ✗ | ✗ | ✔ | ✔ | ✗ | ✔ | ✗ | ✗ | ✔ | ✗ |
|
||||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||||
| coroutines | ~ | ✗ | ~ | ✔ | ✔ | ✔ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ | ✗ |
|
| coroutines | ~ | ✗ | ~ | ✔ | ✔ | ✔ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ | ✗ |
|
||||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||||
|
|
|
@ -367,7 +367,7 @@ namespace sol {
|
||||||
int operator()(types<Fx>, index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start, F& f) {
|
int operator()(types<Fx>, index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start, F& f) {
|
||||||
const auto& metakey = usertype_traits<T>::metatable;
|
const auto& metakey = usertype_traits<T>::metatable;
|
||||||
T** pointerpointer = reinterpret_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
|
T** pointerpointer = reinterpret_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
|
||||||
stack_reference userdataref(L, -1);
|
reference userdataref(L, -1);
|
||||||
T*& referencepointer = *pointerpointer;
|
T*& referencepointer = *pointerpointer;
|
||||||
T* obj = reinterpret_cast<T*>(pointerpointer + 1);
|
T* obj = reinterpret_cast<T*>(pointerpointer + 1);
|
||||||
referencepointer = obj;
|
referencepointer = obj;
|
||||||
|
|
|
@ -23,9 +23,7 @@
|
||||||
#define SOL_INHERITANCE_HPP
|
#define SOL_INHERITANCE_HPP
|
||||||
|
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
#if defined(SOL_NO_RTTI) && defined(SOL_NO_EXCEPTIONS)
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#endif // No Runtime Type Information and No Exceptions
|
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
|
@ -46,7 +44,6 @@ namespace sol {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool has_derived<T>::value = false;
|
bool has_derived<T>::value = false;
|
||||||
|
|
||||||
#if defined(SOL_NO_RTTI) && defined(SOL_NO_EXCEPTIONS)
|
|
||||||
inline std::size_t unique_id() {
|
inline std::size_t unique_id() {
|
||||||
static std::atomic<std::size_t> x(0);
|
static std::atomic<std::size_t> x(0);
|
||||||
return ++x;
|
return ++x;
|
||||||
|
@ -59,7 +56,6 @@ namespace sol {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const std::size_t id_for<T>::value = unique_id();
|
const std::size_t id_for<T>::value = unique_id();
|
||||||
#endif // No Runtime Type Information / No Exceptions
|
|
||||||
|
|
||||||
inline decltype(auto) base_class_check_key() {
|
inline decltype(auto) base_class_check_key() {
|
||||||
static const auto& key = u8"♡o。.(✿ฺ。 ✿ฺ)";
|
static const auto& key = u8"♡o。.(✿ฺ。 ✿ฺ)";
|
||||||
|
@ -71,112 +67,39 @@ namespace sol {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SOL_NO_EXCEPTIONS
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void throw_as(void* p) {
|
|
||||||
throw static_cast<T*>(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
using throw_cast = decltype(&throw_as<void>);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T* catch_cast(void* p, throw_cast f) {
|
|
||||||
try {
|
|
||||||
f(static_cast<void*>(p));
|
|
||||||
}
|
|
||||||
catch (T* ptr) {
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
return static_cast<T*>(p);
|
|
||||||
}
|
|
||||||
return static_cast<T*>(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool catch_check(throw_cast f) {
|
|
||||||
try {
|
|
||||||
f(nullptr);
|
|
||||||
}
|
|
||||||
catch (T*) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif !defined(SOL_NO_RTTI)
|
|
||||||
template <typename T, typename... Bases>
|
template <typename T, typename... Bases>
|
||||||
struct inheritance {
|
struct inheritance {
|
||||||
static bool type_check(types<>, const std::type_info&) {
|
static bool type_check_bases(types<>, std::size_t) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Base, typename... Args>
|
template <typename Base, typename... Args>
|
||||||
static bool type_check(types<Base, Args...>, const std::type_info& ti) {
|
static bool type_check_bases(types<Base, Args...>, std::size_t ti) {
|
||||||
return ti != typeid(Base) || type_check(types<Bases...>(), ti);
|
return ti != id_for<Base>::value || type_check_bases(types<Args...>(), ti);
|
||||||
}
|
|
||||||
|
|
||||||
static bool type_check(const std::type_info& ti) {
|
|
||||||
return ti != typeid(T) || type_check(types<Bases...>(), ti);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* type_cast(types<>, T*, const std::type_info& ti) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Base, typename... Args>
|
|
||||||
static void* type_cast(types<Base, Args...>, T* data, const std::type_info& ti) {
|
|
||||||
// Make sure to convert to T first, and then dynamic cast to the proper type
|
|
||||||
return ti != typeid(Base) ? type_cast(types<Bases...>(), data, ti) : static_cast<void*>(dynamic_cast<Base*>(static_cast<T*>(data)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* type_cast(void* voiddata, const std::type_info& ti) {
|
|
||||||
T* data = static_cast<T*>(voiddata);
|
|
||||||
return static_cast<void*>(ti != typeid(T) ? type_cast(types<Bases...>(), data, ti) : data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
using inheritance_check_function = decltype(&inheritance<void>::type_check);
|
|
||||||
using inheritance_cast_function = decltype(&inheritance<void>::type_cast);
|
|
||||||
#else
|
|
||||||
template <typename T, typename... Bases>
|
|
||||||
struct inheritance {
|
|
||||||
static bool type_check(types<>, std::size_t) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Base, typename... Args>
|
|
||||||
static bool type_check(types<Base, Args...>, std::size_t ti) {
|
|
||||||
return ti != id_for<Base>::value || type_check(types<Bases...>(), ti);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool type_check(std::size_t ti) {
|
static bool type_check(std::size_t ti) {
|
||||||
return ti != id_for<T>::value || type_check(types<Bases...>(), ti);
|
return ti != id_for<T>::value || type_check_bases(types<Bases...>(), ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* type_cast(types<>, T*, std::size_t) {
|
static void* type_cast_bases(types<>, T*, std::size_t) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Base, typename... Args>
|
template <typename Base, typename... Args>
|
||||||
static void* type_cast(types<Base, Args...>, T* data, std::size_t ti) {
|
static void* type_cast_bases(types<Base, Args...>, T* data, std::size_t ti) {
|
||||||
// Make sure to convert to T first, and then dynamic cast to the proper type
|
// Make sure to convert to T first, and then dynamic cast to the proper type
|
||||||
return ti != id_for<Base>::value ? type_cast(types<Bases...>(), data, ti) : static_cast<void*>(static_cast<Base*>(data));
|
return ti != id_for<Base>::value ? type_cast_bases(types<Args...>(), data, ti) : static_cast<void*>(static_cast<Base*>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* type_cast(void* voiddata, std::size_t ti) {
|
static void* type_cast(void* voiddata, std::size_t ti) {
|
||||||
T* data = static_cast<T*>(voiddata);
|
T* data = static_cast<T*>(voiddata);
|
||||||
return static_cast<void*>(ti != id_for<T>::value ? type_cast(types<Bases...>(), data, ti) : data);
|
return static_cast<void*>(ti != id_for<T>::value ? type_cast_bases(types<Bases...>(), data, ti) : data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using inheritance_check_function = decltype(&inheritance<void>::type_check);
|
using inheritance_check_function = decltype(&inheritance<void>::type_check);
|
||||||
using inheritance_cast_function = decltype(&inheritance<void>::type_cast);
|
using inheritance_cast_function = decltype(&inheritance<void>::type_cast);
|
||||||
#endif // No Exceptions and/or No Runtime Type Information
|
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
} // sol
|
} // sol
|
||||||
|
|
|
@ -93,7 +93,9 @@ namespace sol {
|
||||||
object make_reference(lua_State* L, Args&&... args) {
|
object make_reference(lua_State* L, Args&&... args) {
|
||||||
int backpedal = stack::push<T>(L, std::forward<Args>(args)...);
|
int backpedal = stack::push<T>(L, std::forward<Args>(args)...);
|
||||||
object r = stack::get<sol::object>(L, -backpedal);
|
object r = stack::get<sol::object>(L, -backpedal);
|
||||||
lua_pop(L, backpedal);
|
if (should_pop) {
|
||||||
|
lua_pop(L, backpedal);
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,17 @@
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
namespace stack {
|
namespace stack {
|
||||||
|
template <bool top_level>
|
||||||
|
struct push_popper_n {
|
||||||
|
lua_State* L;
|
||||||
|
int t;
|
||||||
|
push_popper_n(lua_State* L, int x) : L(L), t(x) { }
|
||||||
|
~push_popper_n() { lua_pop(L, t); }
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct push_popper_n<true> {
|
||||||
|
push_popper_n(lua_State*, int) { }
|
||||||
|
};
|
||||||
template <bool top_level, typename T>
|
template <bool top_level, typename T>
|
||||||
struct push_popper {
|
struct push_popper {
|
||||||
T t;
|
T t;
|
||||||
|
@ -42,6 +53,10 @@ namespace sol {
|
||||||
push_popper<top_level, T> push_pop(T&& x) {
|
push_popper<top_level, T> push_pop(T&& x) {
|
||||||
return push_popper<top_level, T>(std::forward<T>(x));
|
return push_popper<top_level, T>(std::forward<T>(x));
|
||||||
}
|
}
|
||||||
|
template <bool top_level = false>
|
||||||
|
push_popper_n<top_level> pop_n(lua_State* L, int x) {
|
||||||
|
return push_popper_n<top_level>(L, x);
|
||||||
|
}
|
||||||
} // stack
|
} // stack
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
@ -135,9 +150,8 @@ namespace sol {
|
||||||
}
|
}
|
||||||
|
|
||||||
type get_type() const noexcept {
|
type get_type() const noexcept {
|
||||||
push();
|
auto pp = stack::push_pop(*this);
|
||||||
int result = lua_type(L, -1);
|
int result = lua_type(L, -1);
|
||||||
lua_pop(L, 1);
|
|
||||||
return static_cast<type>(result);
|
return static_cast<type>(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,12 +148,14 @@ namespace sol {
|
||||||
template<bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
|
template<bool check_args = stack_detail::default_check_arguments, 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) {
|
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)...);
|
call<check_args>(tr, ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
||||||
|
lua_settop(L, 0);
|
||||||
return 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, 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) {
|
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)...);
|
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);
|
||||||
return push_reference(L, std::forward<decltype(r)>(r));
|
return push_reference(L, std::forward<decltype(r)>(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,11 +169,10 @@ namespace sol {
|
||||||
|
|
||||||
inline call_syntax get_call_syntax(lua_State* L, const std::string& key, int index = -2) {
|
inline call_syntax get_call_syntax(lua_State* L, const std::string& key, int index = -2) {
|
||||||
luaL_getmetatable(L, key.c_str());
|
luaL_getmetatable(L, key.c_str());
|
||||||
|
auto pn = pop_n(L, 1);
|
||||||
if (lua_compare(L, -1, index, LUA_OPEQ) == 1) {
|
if (lua_compare(L, -1, index, LUA_OPEQ) == 1) {
|
||||||
lua_pop(L, 1);
|
|
||||||
return call_syntax::colon;
|
return call_syntax::colon;
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
|
||||||
return call_syntax::dot;
|
return call_syntax::dot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,8 +191,8 @@ namespace sol {
|
||||||
inline void luajit_exception_handler(lua_State* L, int(*handler)(lua_State*, lua_CFunction) = detail::c_trampoline) {
|
inline void luajit_exception_handler(lua_State* L, int(*handler)(lua_State*, lua_CFunction) = detail::c_trampoline) {
|
||||||
#ifdef SOL_LUAJIT
|
#ifdef SOL_LUAJIT
|
||||||
lua_pushlightuserdata(L, (void*)handler);
|
lua_pushlightuserdata(L, (void*)handler);
|
||||||
|
auto pn = pop_n(L, 1);
|
||||||
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON);
|
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON);
|
||||||
lua_pop(L, 1);
|
|
||||||
#else
|
#else
|
||||||
(void)L;
|
(void)L;
|
||||||
(void)handler;
|
(void)handler;
|
||||||
|
|
|
@ -209,14 +209,14 @@ namespace sol {
|
||||||
static const auto& callkey = name_of(meta_function::call);
|
static const auto& callkey = name_of(meta_function::call);
|
||||||
lua_getmetatable(L, index);
|
lua_getmetatable(L, index);
|
||||||
if (lua_isnoneornil(L, -1)) {
|
if (lua_isnoneornil(L, -1)) {
|
||||||
handler(L, index, t, type::function);
|
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
handler(L, index, t, type::function);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
lua_getfield(L, -1, &callkey[0]);
|
lua_getfield(L, -1, &callkey[0]);
|
||||||
if (lua_isnoneornil(L, -1)) {
|
if (lua_isnoneornil(L, -1)) {
|
||||||
handler(L, index, t, type::function);
|
|
||||||
lua_pop(L, 2);
|
lua_pop(L, 2);
|
||||||
|
handler(L, index, t, type::function);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// has call, is definitely a function
|
// has call, is definitely a function
|
||||||
|
@ -274,30 +274,15 @@ namespace sol {
|
||||||
if (stack_detail::check_metatable<detail::unique_usertype<U>>(L))
|
if (stack_detail::check_metatable<detail::unique_usertype<U>>(L))
|
||||||
return true;
|
return true;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
#ifndef SOL_NO_EXCEPTIONS
|
{
|
||||||
lua_getfield(L, -1, &detail::base_class_check_key()[0]);
|
auto pn = stack::pop_n(L, 2);
|
||||||
if (type_of(L, -1) != type::nil) {
|
lua_getfield(L, -1, &detail::base_class_check_key()[0]);
|
||||||
void* basecastdata = lua_touserdata(L, -1);
|
if (type_of(L, -1) != type::nil) {
|
||||||
detail::throw_cast basecast = (detail::throw_cast)basecastdata;
|
void* basecastdata = lua_touserdata(L, -1);
|
||||||
success = detail::catch_check<T>(basecast);
|
detail::inheritance_check_function ic = (detail::inheritance_check_function)basecastdata;
|
||||||
|
success = ic(detail::id_for<T>::value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#elif !defined(SOL_NO_RTTI)
|
|
||||||
lua_getfield(L, -1, &detail::base_class_check_key()[0]);
|
|
||||||
if (type_of(L, -1) != type::nil) {
|
|
||||||
void* basecastdata = lua_touserdata(L, -1);
|
|
||||||
detail::inheritance_check_function ic = (detail::inheritance_check_function)basecastdata;
|
|
||||||
success = ic(typeid(T));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Topkek
|
|
||||||
lua_getfield(L, -1, &detail::base_class_check_key()[0]);
|
|
||||||
if (type_of(L, -1) != type::nil) {
|
|
||||||
void* basecastdata = lua_touserdata(L, -1);
|
|
||||||
detail::inheritance_check_function ic = (detail::inheritance_check_function)basecastdata;
|
|
||||||
success = ic(detail::id_for<T>::value);
|
|
||||||
}
|
|
||||||
#endif // No Runtime Type Information || Exceptions
|
|
||||||
lua_pop(L, 2);
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
handler(L, index, type::userdata, indextype);
|
handler(L, index, type::userdata, indextype);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -289,24 +289,6 @@ namespace sol {
|
||||||
}
|
}
|
||||||
|
|
||||||
static T* get_no_nil_from(lua_State* L, void* udata, int index = -1) {
|
static T* get_no_nil_from(lua_State* L, void* udata, int index = -1) {
|
||||||
#ifndef SOL_NO_EXCEPTIONS
|
|
||||||
if (detail::has_derived<T>::value && luaL_getmetafield(L, index, &detail::base_class_check_key()[0]) != 0) {
|
|
||||||
void* basecastdata = lua_touserdata(L, -1);
|
|
||||||
detail::throw_cast basecast = (detail::throw_cast)basecastdata;
|
|
||||||
// use the casting function to properly adjust the pointer for the desired T
|
|
||||||
udata = detail::catch_cast<T>(udata, basecast);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
#elif !defined(SOL_NO_RTTI)
|
|
||||||
if (detail::has_derived<T>::value && luaL_getmetafield(L, index, &detail::base_class_cast_key()[0]) != 0) {
|
|
||||||
void* basecastdata = lua_touserdata(L, -1);
|
|
||||||
detail::inheritance_cast_function ic = (detail::inheritance_cast_function)basecastdata;
|
|
||||||
// use the casting function to properly adjust the pointer for the desired T
|
|
||||||
udata = ic(udata, typeid(T));
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Lol, you motherfucker
|
|
||||||
if (detail::has_derived<T>::value && luaL_getmetafield(L, index, &detail::base_class_cast_key()[0]) != 0) {
|
if (detail::has_derived<T>::value && luaL_getmetafield(L, index, &detail::base_class_cast_key()[0]) != 0) {
|
||||||
void* basecastdata = lua_touserdata(L, -1);
|
void* basecastdata = lua_touserdata(L, -1);
|
||||||
detail::inheritance_cast_function ic = (detail::inheritance_cast_function)basecastdata;
|
detail::inheritance_cast_function ic = (detail::inheritance_cast_function)basecastdata;
|
||||||
|
@ -314,7 +296,6 @@ namespace sol {
|
||||||
udata = ic(udata, detail::id_for<T>::value);
|
udata = ic(udata, detail::id_for<T>::value);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
#endif // No Runtime Type Information || Exceptions
|
|
||||||
T* obj = static_cast<T*>(udata);
|
T* obj = static_cast<T*>(udata);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,8 +54,8 @@ namespace sol {
|
||||||
sol::object key(base_t::lua_state(), -2);
|
sol::object key(base_t::lua_state(), -2);
|
||||||
sol::object value(base_t::lua_state(), -1);
|
sol::object value(base_t::lua_state(), -1);
|
||||||
std::pair<sol::object&, sol::object&> keyvalue(key, value);
|
std::pair<sol::object&, sol::object&> keyvalue(key, value);
|
||||||
|
auto pn = stack::pop_n(base_t::lua_state(), 1);
|
||||||
fx(keyvalue);
|
fx(keyvalue);
|
||||||
lua_pop(base_t::lua_state(), 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,8 +66,8 @@ namespace sol {
|
||||||
while (lua_next(base_t::lua_state(), -2)) {
|
while (lua_next(base_t::lua_state(), -2)) {
|
||||||
sol::object key(base_t::lua_state(), -2);
|
sol::object key(base_t::lua_state(), -2);
|
||||||
sol::object value(base_t::lua_state(), -1);
|
sol::object value(base_t::lua_state(), -1);
|
||||||
|
auto pn = stack::pop_n(base_t::lua_state(), 1);
|
||||||
fx(key, value);
|
fx(key, value);
|
||||||
lua_pop(base_t::lua_state(), 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,8 +231,8 @@ namespace sol {
|
||||||
template <typename... Keys>
|
template <typename... Keys>
|
||||||
basic_table_core& traverse_set(Keys&&... keys) {
|
basic_table_core& traverse_set(Keys&&... keys) {
|
||||||
auto pp = stack::push_pop<is_global<Keys...>::value>(*this);
|
auto pp = stack::push_pop<is_global<Keys...>::value>(*this);
|
||||||
|
auto pn = stack::pop_n(base_t::lua_state(), static_cast<int>(sizeof...(Keys)-2));
|
||||||
traverse_set_deep<top_level>(std::forward<Keys>(keys)...);
|
traverse_set_deep<top_level>(std::forward<Keys>(keys)...);
|
||||||
lua_pop(base_t::lua_state(), static_cast<int>(sizeof...(Keys)-2));
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -188,20 +188,11 @@ namespace sol {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(void)detail::swallow{ 0, ((detail::has_derived<Bases>::value = true), 0)... };
|
(void)detail::swallow{ 0, ((detail::has_derived<Bases>::value = true), 0)... };
|
||||||
#ifndef SOL_NO_EXCEPTIONS
|
|
||||||
static_assert(sizeof(void*) <= sizeof(detail::throw_cast), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
|
|
||||||
baseclasscheck = baseclasscast = (void*)&detail::throw_as<T>;
|
|
||||||
#elif !defined(SOL_NO_RTTI)
|
|
||||||
static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
|
static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
|
||||||
static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
|
static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
|
||||||
baseclasscheck = (void*)&detail::inheritance<T, Args...>::type_check;
|
baseclasscheck = (void*)&detail::inheritance<T, Bases...>::type_check;
|
||||||
baseclasscast = (void*)&detail::inheritance<T, Args...>::type_cast;
|
baseclasscast = (void*)&detail::inheritance<T, Bases...>::type_cast;
|
||||||
#else
|
|
||||||
static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
|
|
||||||
static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
|
|
||||||
baseclasscheck = (void*)&detail::inheritance<T, Args...>::type_check;
|
|
||||||
baseclasscast = (void*)&detail::inheritance<T, Args...>::type_cast;
|
|
||||||
#endif // No Runtime Type Information vs. Throw-Style Inheritance
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t Idx, typename N, typename F, typename = std::enable_if_t<!meta::any_same<meta::unqualified_t<N>, base_classes_tag, call_construction>::value>>
|
template <std::size_t Idx, typename N, typename F, typename = std::enable_if_t<!meta::any_same<meta::unqualified_t<N>, base_classes_tag, call_construction>::value>>
|
||||||
|
|
|
@ -627,6 +627,23 @@ TEST_CASE("usertype/private-constructible", "Check to make sure special snowflak
|
||||||
REQUIRE(expectednumkilled == factory_test::num_killed);
|
REQUIRE(expectednumkilled == factory_test::num_killed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("usertype/const-pointer", "Make sure const pointers can be taken") {
|
||||||
|
struct A { int x = 201; };
|
||||||
|
struct B {
|
||||||
|
int foo(const A* a) { return a->x; };
|
||||||
|
};
|
||||||
|
|
||||||
|
sol::state lua;
|
||||||
|
lua.new_usertype<B>("B",
|
||||||
|
"foo", &B::foo
|
||||||
|
);
|
||||||
|
lua.set("a", A());
|
||||||
|
lua.set("b", B());
|
||||||
|
lua.script("x = b:foo(a)");
|
||||||
|
int x = lua["x"];
|
||||||
|
REQUIRE(x == 201);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("usertype/overloading", "Check if overloading works properly for usertypes") {
|
TEST_CASE("usertype/overloading", "Check if overloading works properly for usertypes") {
|
||||||
struct woof {
|
struct woof {
|
||||||
int var;
|
int var;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user