mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Update catch, move yielding check up one level to avoid problems with trampoline and exception handling, and add a new test/example from an issue. Closes #906. Closes #917.
This commit is contained in:
parent
1c89390356
commit
c77b5b432e
|
@ -28,7 +28,7 @@ include(Common/Core)
|
||||||
if (Catch_FIND_VERSION)
|
if (Catch_FIND_VERSION)
|
||||||
set(catch_version ${Catch_FIND_VERSION})
|
set(catch_version ${Catch_FIND_VERSION})
|
||||||
else()
|
else()
|
||||||
set(catch_version 2.11.0)
|
set(catch_version 2.11.1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(catch_lib catch_lib_${catch_version})
|
set(catch_lib catch_lib_${catch_version})
|
||||||
|
|
|
@ -26,7 +26,7 @@ cmake_minimum_required(VERSION 3.5.0)
|
||||||
|
|
||||||
find_package(Python3 COMPONENTS Interpreter)
|
find_package(Python3 COMPONENTS Interpreter)
|
||||||
|
|
||||||
if (NOT Python3_Interpreter_FOUND)
|
if (NOT Python3_FOUND AND NOT Python3_Interpreter_FOUND)
|
||||||
message(FATAL_ERROR "sol2 documentation cannot be generated as python 3 has not been found: install or set the python 3 interpreter for the docs to find it and be sure to pip install sphinx")
|
message(FATAL_ERROR "sol2 documentation cannot be generated as python 3 has not been found: install or set the python 3 interpreter for the docs to find it and be sure to pip install sphinx")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
46
examples/source/shared_ptr_inheritance.cpp
Normal file
46
examples/source/shared_ptr_inheritance.cpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#define SOL_ALL_SAFETIES_ON 1
|
||||||
|
#include <sol/sol.hpp>
|
||||||
|
|
||||||
|
#include "assert.hpp"
|
||||||
|
#include <memory>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
struct Shape {
|
||||||
|
virtual ~Shape() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Box : Shape {};
|
||||||
|
|
||||||
|
SOL_BASE_CLASSES(Box, Shape);
|
||||||
|
SOL_DERIVED_CLASSES(Shape, Box);
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
sol::state lua;
|
||||||
|
lua.open_libraries(sol::lib::base);
|
||||||
|
|
||||||
|
lua.new_usertype<Shape>("Shape", sol::no_constructor);
|
||||||
|
|
||||||
|
lua.new_usertype<Box>("Box", sol::factories([&]() {
|
||||||
|
auto b = std::make_shared<Box>();
|
||||||
|
std::cout << "create Box@" << std::hex << b.get() << '\n';
|
||||||
|
return b;
|
||||||
|
}));
|
||||||
|
|
||||||
|
lua.set_function("inspect_shape_table", [](const sol::table& args) {
|
||||||
|
std::shared_ptr<Shape> defbox = nullptr;
|
||||||
|
// check if there's a field with the name "shape"
|
||||||
|
auto s = args.get<sol::optional<std::shared_ptr<Shape>>>("shape");
|
||||||
|
std::cout << "has : " << std::boolalpha << s.has_value() << '\n';
|
||||||
|
|
||||||
|
// get the field named "shape" or use the default value
|
||||||
|
std::cout << "get_or: " << std::hex << args.get_or<std::shared_ptr<Shape>>("shape", defbox).get() << '\n';
|
||||||
|
|
||||||
|
// this works but I can't test for existence beforehand...
|
||||||
|
std::cout << "get : " << std::hex << args.get<std::shared_ptr<Shape>>("shape").get() << '\n';
|
||||||
|
});
|
||||||
|
|
||||||
|
sol::protected_function_result result = lua.safe_script("inspect_shape_table({shape=Box.new()})");
|
||||||
|
c_assert(result.valid());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -867,8 +867,7 @@ namespace sol {
|
||||||
if constexpr (meta::is_specialization_of_v<uFx, yielding_t>) {
|
if constexpr (meta::is_specialization_of_v<uFx, yielding_t>) {
|
||||||
using real_fx = meta::unqualified_t<decltype(std::forward<Fx>(fx).func)>;
|
using real_fx = meta::unqualified_t<decltype(std::forward<Fx>(fx).func)>;
|
||||||
lua_call_wrapper<T, real_fx, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
lua_call_wrapper<T, real_fx, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
||||||
int nr = lcw.call(L, std::forward<Fx>(fx).func, std::forward<Args>(args)...);
|
return lcw.call(L, std::forward<Fx>(fx).func, std::forward<Args>(args)...);
|
||||||
return lua_yield(L, nr);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lua_call_wrapper<T, uFx, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
lua_call_wrapper<T, uFx, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
||||||
|
@ -880,7 +879,14 @@ namespace sol {
|
||||||
bool clean_stack = true>
|
bool clean_stack = true>
|
||||||
inline int call_user(lua_State* L) {
|
inline int call_user(lua_State* L) {
|
||||||
auto& fx = stack::unqualified_get<user<F>>(L, upvalue_index(start));
|
auto& fx = stack::unqualified_get<user<F>>(L, upvalue_index(start));
|
||||||
return call_wrapped<T, is_index, is_variable, 0, checked, clean_stack>(L, fx);
|
using uFx = meta::unqualified_t<F>;
|
||||||
|
int nr = call_wrapped<T, is_index, is_variable, 0, checked, clean_stack>(L, fx);
|
||||||
|
if constexpr (meta::is_specialization_of_v<uFx, yielding_t>) {
|
||||||
|
return lua_yield(L, nr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename = void>
|
template <typename T, typename = void>
|
||||||
|
|
|
@ -59,8 +59,25 @@ namespace sol { namespace stack {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct qualified_getter<optional<T>> {
|
struct qualified_getter<optional<T>> {
|
||||||
static decltype(auto) get(lua_State* L, int index, record& tracking) {
|
static optional<T> get(lua_State* L, int index, record& tracking) {
|
||||||
return check_get<T>(L, index, no_panic, tracking);
|
if constexpr (is_lua_reference_v<T>) {
|
||||||
|
// actually check if it's none here, otherwise
|
||||||
|
// we'll have a none object inside an optional!
|
||||||
|
bool success = lua_isnoneornil(L, index) == 0 && stack::check<T>(L, index, no_panic);
|
||||||
|
if (!success) {
|
||||||
|
// expected type, actual type
|
||||||
|
tracking.use(static_cast<int>(success));
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
|
return stack_detail::unchecked_get<T>(L, index, tracking);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!check<T>(L, index, &no_panic)) {
|
||||||
|
tracking.use(static_cast<int>(!lua_isnone(L, index)));
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
|
return stack_detail::unchecked_get<T>(L, index, tracking);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -918,6 +918,20 @@ namespace sol {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
int push_userdata(lua_State* L, T&& t, Args&&... args) {
|
||||||
|
using U = meta::unqualified_t<T>;
|
||||||
|
using Tr = meta::conditional_t<std::is_pointer<U>::value, detail::as_pointer_tag<std::remove_pointer_t<U>>, detail::as_value_tag<U>>;
|
||||||
|
return stack::push<Tr>(L, std::forward<T>(t), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename Arg, typename... Args>
|
||||||
|
int push_userdata(lua_State* L, Arg&& arg, Args&&... args) {
|
||||||
|
using U = meta::unqualified_t<T>;
|
||||||
|
using Tr = meta::conditional_t<std::is_pointer<U>::value, detail::as_pointer_tag<std::remove_pointer_t<U>>, detail::as_value_tag<U>>;
|
||||||
|
return stack::push<Tr>(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
namespace stack_detail {
|
namespace stack_detail {
|
||||||
|
|
||||||
template <typename T, typename Arg, typename... Args>
|
template <typename T, typename Arg, typename... Args>
|
||||||
|
|
|
@ -97,7 +97,13 @@ namespace sol { namespace u_detail {
|
||||||
|
|
||||||
template <bool is_index = true, bool is_variable = false>
|
template <bool is_index = true, bool is_variable = false>
|
||||||
static inline int call(lua_State* L) {
|
static inline int call(lua_State* L) {
|
||||||
return detail::typed_static_trampoline<decltype(&call_<is_index, is_variable>), (&call_<is_index, is_variable>)>(L);
|
int r = detail::typed_static_trampoline<decltype(&call_<is_index, is_variable>), (&call_<is_index, is_variable>)>(L);
|
||||||
|
if constexpr (meta::is_specialization_of_v<uF, yielding_t>) {
|
||||||
|
return lua_yield(L, r);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool is_index = true, bool is_variable = false>
|
template <bool is_index = true, bool is_variable = false>
|
||||||
|
@ -132,7 +138,13 @@ namespace sol { namespace u_detail {
|
||||||
|
|
||||||
template <bool is_index = true, bool is_variable = false>
|
template <bool is_index = true, bool is_variable = false>
|
||||||
static inline int index_call(lua_State* L) {
|
static inline int index_call(lua_State* L) {
|
||||||
return detail::typed_static_trampoline<decltype(&index_call_<is_index, is_variable>), (&index_call_<is_index, is_variable>)>(L);
|
int r = detail::typed_static_trampoline<decltype(&index_call_<is_index, is_variable>), (&index_call_<is_index, is_variable>)>(L);
|
||||||
|
if constexpr (meta::is_specialization_of_v<uF, yielding_t>) {
|
||||||
|
return lua_yield(L, r);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// This file was generated with a script.
|
// This file was generated with a script.
|
||||||
// Generated 2020-01-08 11:39:55.025761 UTC
|
// Generated 2020-01-17 10:21:31.165776 UTC
|
||||||
// This header was generated with sol v3.2.0 (revision 43f215c)
|
// This header was generated with sol v3.2.0 (revision 1c89390)
|
||||||
// https://github.com/ThePhD/sol2
|
// https://github.com/ThePhD/sol2
|
||||||
|
|
||||||
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP
|
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// This file was generated with a script.
|
// This file was generated with a script.
|
||||||
// Generated 2020-01-08 11:39:54.499598 UTC
|
// Generated 2020-01-17 10:21:30.504542 UTC
|
||||||
// This header was generated with sol v3.2.0 (revision 43f215c)
|
// This header was generated with sol v3.2.0 (revision 1c89390)
|
||||||
// https://github.com/ThePhD/sol2
|
// https://github.com/ThePhD/sol2
|
||||||
|
|
||||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||||
|
@ -10361,6 +10361,20 @@ namespace sol {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
int push_userdata(lua_State* L, T&& t, Args&&... args) {
|
||||||
|
using U = meta::unqualified_t<T>;
|
||||||
|
using Tr = meta::conditional_t<std::is_pointer<U>::value, detail::as_pointer_tag<std::remove_pointer_t<U>>, detail::as_value_tag<U>>;
|
||||||
|
return stack::push<Tr>(L, std::forward<T>(t), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename Arg, typename... Args>
|
||||||
|
int push_userdata(lua_State* L, Arg&& arg, Args&&... args) {
|
||||||
|
using U = meta::unqualified_t<T>;
|
||||||
|
using Tr = meta::conditional_t<std::is_pointer<U>::value, detail::as_pointer_tag<std::remove_pointer_t<U>>, detail::as_value_tag<U>>;
|
||||||
|
return stack::push<Tr>(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
namespace stack_detail {
|
namespace stack_detail {
|
||||||
|
|
||||||
template <typename T, typename Arg, typename... Args>
|
template <typename T, typename Arg, typename... Args>
|
||||||
|
@ -13053,8 +13067,25 @@ namespace sol { namespace stack {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct qualified_getter<optional<T>> {
|
struct qualified_getter<optional<T>> {
|
||||||
static decltype(auto) get(lua_State* L, int index, record& tracking) {
|
static optional<T> get(lua_State* L, int index, record& tracking) {
|
||||||
return check_get<T>(L, index, no_panic, tracking);
|
if constexpr (is_lua_reference_v<T>) {
|
||||||
|
// actually check if it's none here, otherwise
|
||||||
|
// we'll have a none object inside an optional!
|
||||||
|
bool success = lua_isnoneornil(L, index) == 0 && stack::check<T>(L, index, no_panic);
|
||||||
|
if (!success) {
|
||||||
|
// expected type, actual type
|
||||||
|
tracking.use(static_cast<int>(success));
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
|
return stack_detail::unchecked_get<T>(L, index, tracking);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!check<T>(L, index, &no_panic)) {
|
||||||
|
tracking.use(static_cast<int>(!lua_isnone(L, index)));
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
|
return stack_detail::unchecked_get<T>(L, index, tracking);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16991,8 +17022,7 @@ namespace sol {
|
||||||
if constexpr (meta::is_specialization_of_v<uFx, yielding_t>) {
|
if constexpr (meta::is_specialization_of_v<uFx, yielding_t>) {
|
||||||
using real_fx = meta::unqualified_t<decltype(std::forward<Fx>(fx).func)>;
|
using real_fx = meta::unqualified_t<decltype(std::forward<Fx>(fx).func)>;
|
||||||
lua_call_wrapper<T, real_fx, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
lua_call_wrapper<T, real_fx, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
||||||
int nr = lcw.call(L, std::forward<Fx>(fx).func, std::forward<Args>(args)...);
|
return lcw.call(L, std::forward<Fx>(fx).func, std::forward<Args>(args)...);
|
||||||
return lua_yield(L, nr);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lua_call_wrapper<T, uFx, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
lua_call_wrapper<T, uFx, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
||||||
|
@ -17004,7 +17034,14 @@ namespace sol {
|
||||||
bool clean_stack = true>
|
bool clean_stack = true>
|
||||||
inline int call_user(lua_State* L) {
|
inline int call_user(lua_State* L) {
|
||||||
auto& fx = stack::unqualified_get<user<F>>(L, upvalue_index(start));
|
auto& fx = stack::unqualified_get<user<F>>(L, upvalue_index(start));
|
||||||
return call_wrapped<T, is_index, is_variable, 0, checked, clean_stack>(L, fx);
|
using uFx = meta::unqualified_t<F>;
|
||||||
|
int nr = call_wrapped<T, is_index, is_variable, 0, checked, clean_stack>(L, fx);
|
||||||
|
if constexpr (meta::is_specialization_of_v<uFx, yielding_t>) {
|
||||||
|
return lua_yield(L, nr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename = void>
|
template <typename T, typename = void>
|
||||||
|
@ -21251,7 +21288,13 @@ namespace sol { namespace u_detail {
|
||||||
|
|
||||||
template <bool is_index = true, bool is_variable = false>
|
template <bool is_index = true, bool is_variable = false>
|
||||||
static inline int call(lua_State* L) {
|
static inline int call(lua_State* L) {
|
||||||
return detail::typed_static_trampoline<decltype(&call_<is_index, is_variable>), (&call_<is_index, is_variable>)>(L);
|
int r = detail::typed_static_trampoline<decltype(&call_<is_index, is_variable>), (&call_<is_index, is_variable>)>(L);
|
||||||
|
if constexpr (meta::is_specialization_of_v<uF, yielding_t>) {
|
||||||
|
return lua_yield(L, r);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool is_index = true, bool is_variable = false>
|
template <bool is_index = true, bool is_variable = false>
|
||||||
|
@ -21286,7 +21329,13 @@ namespace sol { namespace u_detail {
|
||||||
|
|
||||||
template <bool is_index = true, bool is_variable = false>
|
template <bool is_index = true, bool is_variable = false>
|
||||||
static inline int index_call(lua_State* L) {
|
static inline int index_call(lua_State* L) {
|
||||||
return detail::typed_static_trampoline<decltype(&index_call_<is_index, is_variable>), (&index_call_<is_index, is_variable>)>(L);
|
int r = detail::typed_static_trampoline<decltype(&index_call_<is_index, is_variable>), (&index_call_<is_index, is_variable>)>(L);
|
||||||
|
if constexpr (meta::is_specialization_of_v<uF, yielding_t>) {
|
||||||
|
return lua_yield(L, r);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user