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
|
||||
* 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.
|
||||
* arbitrary keys: Letting C++ code use userdata, other tables, integers, etc. as keys for into a table without dropping to the plain API.
|
||||
* user-defined types (udts): C++ types given form and function in lua code.
|
||||
* 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.
|
||||
* 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 - 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...
|
||||
* protected function: Use of ``lua_pcall`` to call a function, which offers error-handling and trampolining
|
||||
* multi-return: returning multiple values from and to lua
|
||||
* variadic/variant argument: being able to accept "anything" from lua, and even return "anything" to lua
|
||||
* inheritance: allowing some degree of subtyping or inheritance on classes / userdata from lua
|
||||
* 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 (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 (``object`` abstraction, variadic arguments, etc...)
|
||||
* 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" )``).
|
||||
* 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
|
||||
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||
|
@ -112,7 +112,7 @@ Explanations for a few categories are below (rest are self-explanatory).
|
|||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||
| function binding | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||
| protected function | ~ | ✗ | ~ | ~ | ~ | ✔ | ~ | ✔ | ~ | ~ | ~ | ~ | ~ |
|
||||
| protected call | ~ | ✗ | ~ | ~ | ~ | ✔ | ~ | ✔ | ~ | ~ | ~ | ~ | ~ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||
| multi-return | ~ | ✗ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ~ | ✔ | ~ | ✗ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||
|
@ -122,7 +122,7 @@ Explanations for a few categories are below (rest are self-explanatory).
|
|||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||
| overloading | ~ | ✗ | ✗ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ | ✔ | ✔ | ✗ | ✗ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||
| lua thread | ~ | ✗ | ~ | ✗ | ✗ | ✔ | ✔ | ✗ | ✔ | ✗ | ✗ | ✔ | ✗ |
|
||||
| Lua thread | ~ | ✗ | ~ | ✗ | ✗ | ✔ | ✔ | ✗ | ✔ | ✗ | ✗ | ✔ | ✗ |
|
||||
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
|
||||
| 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) {
|
||||
const auto& metakey = usertype_traits<T>::metatable;
|
||||
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* obj = reinterpret_cast<T*>(pointerpointer + 1);
|
||||
referencepointer = obj;
|
||||
|
|
|
@ -23,9 +23,7 @@
|
|||
#define SOL_INHERITANCE_HPP
|
||||
|
||||
#include "types.hpp"
|
||||
#if defined(SOL_NO_RTTI) && defined(SOL_NO_EXCEPTIONS)
|
||||
#include <atomic>
|
||||
#endif // No Runtime Type Information and No Exceptions
|
||||
|
||||
namespace sol {
|
||||
template <typename... Args>
|
||||
|
@ -46,7 +44,6 @@ namespace sol {
|
|||
template <typename T>
|
||||
bool has_derived<T>::value = false;
|
||||
|
||||
#if defined(SOL_NO_RTTI) && defined(SOL_NO_EXCEPTIONS)
|
||||
inline std::size_t unique_id() {
|
||||
static std::atomic<std::size_t> x(0);
|
||||
return ++x;
|
||||
|
@ -59,7 +56,6 @@ namespace sol {
|
|||
|
||||
template <typename T>
|
||||
const std::size_t id_for<T>::value = unique_id();
|
||||
#endif // No Runtime Type Information / No Exceptions
|
||||
|
||||
inline decltype(auto) base_class_check_key() {
|
||||
static const auto& key = u8"♡o。.(✿ฺ。 ✿ฺ)";
|
||||
|
@ -71,112 +67,39 @@ namespace sol {
|
|||
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>
|
||||
struct inheritance {
|
||||
static bool type_check(types<>, const std::type_info&) {
|
||||
static bool type_check_bases(types<>, std::size_t) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Base, typename... Args>
|
||||
static bool type_check(types<Base, Args...>, const std::type_info& ti) {
|
||||
return ti != typeid(Base) || type_check(types<Bases...>(), 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_bases(types<Base, Args...>, std::size_t ti) {
|
||||
return ti != id_for<Base>::value || type_check_bases(types<Args...>(), 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;
|
||||
}
|
||||
|
||||
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
|
||||
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) {
|
||||
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_cast_function = decltype(&inheritance<void>::type_cast);
|
||||
#endif // No Exceptions and/or No Runtime Type Information
|
||||
|
||||
} // detail
|
||||
} // sol
|
||||
|
|
|
@ -93,7 +93,9 @@ namespace sol {
|
|||
object make_reference(lua_State* L, Args&&... args) {
|
||||
int backpedal = stack::push<T>(L, std::forward<Args>(args)...);
|
||||
object r = stack::get<sol::object>(L, -backpedal);
|
||||
lua_pop(L, backpedal);
|
||||
if (should_pop) {
|
||||
lua_pop(L, backpedal);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,17 @@
|
|||
|
||||
namespace sol {
|
||||
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>
|
||||
struct push_popper {
|
||||
T t;
|
||||
|
@ -42,6 +53,10 @@ namespace sol {
|
|||
push_popper<top_level, T> push_pop(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
|
||||
|
||||
namespace detail {
|
||||
|
@ -135,9 +150,8 @@ namespace sol {
|
|||
}
|
||||
|
||||
type get_type() const noexcept {
|
||||
push();
|
||||
auto pp = stack::push_pop(*this);
|
||||
int result = lua_type(L, -1);
|
||||
lua_pop(L, 1);
|
||||
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>
|
||||
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);
|
||||
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>>
|
||||
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);
|
||||
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) {
|
||||
luaL_getmetatable(L, key.c_str());
|
||||
auto pn = pop_n(L, 1);
|
||||
if (lua_compare(L, -1, index, LUA_OPEQ) == 1) {
|
||||
lua_pop(L, 1);
|
||||
return call_syntax::colon;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
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) {
|
||||
#ifdef SOL_LUAJIT
|
||||
lua_pushlightuserdata(L, (void*)handler);
|
||||
auto pn = pop_n(L, 1);
|
||||
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON);
|
||||
lua_pop(L, 1);
|
||||
#else
|
||||
(void)L;
|
||||
(void)handler;
|
||||
|
|
|
@ -209,14 +209,14 @@ namespace sol {
|
|||
static const auto& callkey = name_of(meta_function::call);
|
||||
lua_getmetatable(L, index);
|
||||
if (lua_isnoneornil(L, -1)) {
|
||||
handler(L, index, t, type::function);
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, t, type::function);
|
||||
return false;
|
||||
}
|
||||
lua_getfield(L, -1, &callkey[0]);
|
||||
if (lua_isnoneornil(L, -1)) {
|
||||
handler(L, index, t, type::function);
|
||||
lua_pop(L, 2);
|
||||
handler(L, index, t, type::function);
|
||||
return false;
|
||||
}
|
||||
// has call, is definitely a function
|
||||
|
@ -274,30 +274,15 @@ namespace sol {
|
|||
if (stack_detail::check_metatable<detail::unique_usertype<U>>(L))
|
||||
return true;
|
||||
bool success = false;
|
||||
#ifndef SOL_NO_EXCEPTIONS
|
||||
lua_getfield(L, -1, &detail::base_class_check_key()[0]);
|
||||
if (type_of(L, -1) != type::nil) {
|
||||
void* basecastdata = lua_touserdata(L, -1);
|
||||
detail::throw_cast basecast = (detail::throw_cast)basecastdata;
|
||||
success = detail::catch_check<T>(basecast);
|
||||
{
|
||||
auto pn = stack::pop_n(L, 2);
|
||||
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);
|
||||
}
|
||||
}
|
||||
#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) {
|
||||
handler(L, index, type::userdata, indextype);
|
||||
return false;
|
||||
|
|
|
@ -289,24 +289,6 @@ namespace sol {
|
|||
}
|
||||
|
||||
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) {
|
||||
void* basecastdata = lua_touserdata(L, -1);
|
||||
detail::inheritance_cast_function ic = (detail::inheritance_cast_function)basecastdata;
|
||||
|
@ -314,7 +296,6 @@ namespace sol {
|
|||
udata = ic(udata, detail::id_for<T>::value);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
#endif // No Runtime Type Information || Exceptions
|
||||
T* obj = static_cast<T*>(udata);
|
||||
return obj;
|
||||
}
|
||||
|
|
|
@ -54,8 +54,8 @@ namespace sol {
|
|||
sol::object key(base_t::lua_state(), -2);
|
||||
sol::object value(base_t::lua_state(), -1);
|
||||
std::pair<sol::object&, sol::object&> keyvalue(key, value);
|
||||
auto pn = stack::pop_n(base_t::lua_state(), 1);
|
||||
fx(keyvalue);
|
||||
lua_pop(base_t::lua_state(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,8 @@ namespace sol {
|
|||
while (lua_next(base_t::lua_state(), -2)) {
|
||||
sol::object key(base_t::lua_state(), -2);
|
||||
sol::object value(base_t::lua_state(), -1);
|
||||
auto pn = stack::pop_n(base_t::lua_state(), 1);
|
||||
fx(key, value);
|
||||
lua_pop(base_t::lua_state(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,8 +231,8 @@ namespace sol {
|
|||
template <typename... Keys>
|
||||
basic_table_core& traverse_set(Keys&&... keys) {
|
||||
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)...);
|
||||
lua_pop(base_t::lua_state(), static_cast<int>(sizeof...(Keys)-2));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -188,20 +188,11 @@ namespace sol {
|
|||
return;
|
||||
}
|
||||
(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_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;
|
||||
#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
|
||||
baseclasscheck = (void*)&detail::inheritance<T, Bases...>::type_check;
|
||||
baseclasscast = (void*)&detail::inheritance<T, Bases...>::type_cast;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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") {
|
||||
struct woof {
|
||||
int var;
|
||||
|
|
Loading…
Reference in New Issue
Block a user