mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
add noexcept function type barriers and guards
noexcept-proof function call trampolines add noexcept tests to ensure its being checked TODO: check g++ 7.1 builds when using -std=c++17 ...
This commit is contained in:
parent
39fdb5e041
commit
11916a7c72
|
@ -20,8 +20,8 @@
|
|||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// This file was generated with a script.
|
||||
// Generated 2017-06-15 05:24:30.745677 UTC
|
||||
// This header was generated with sol v2.17.5 (revision 0fb5333)
|
||||
// Generated 2017-06-16 19:36:12.857631 UTC
|
||||
// This header was generated with sol v2.17.5 (revision 39fdb5e)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||
|
@ -47,9 +47,6 @@
|
|||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#if __GNUC__ > 6
|
||||
#pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
#elif defined _MSC_VER
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4324 ) // structure was padded due to alignment specifier
|
||||
|
@ -193,12 +190,13 @@ namespace sol {
|
|||
template <std::size_t I, typename T>
|
||||
using void_tuple_element_t = typename void_tuple_element<I, T>::type;
|
||||
|
||||
template <bool has_c_variadic, typename T, typename R, typename... Args>
|
||||
template <bool it_is_noexcept, bool has_c_variadic, typename T, typename R, typename... Args>
|
||||
struct basic_traits {
|
||||
private:
|
||||
typedef std::conditional_t<std::is_void<T>::value, int, T>& first_type;
|
||||
|
||||
public:
|
||||
static const bool is_noexcept = it_is_noexcept;
|
||||
static const bool is_member_function = std::is_void<T>::value;
|
||||
static const bool has_c_var_arg = has_c_variadic;
|
||||
static const std::size_t arity = sizeof...(Args);
|
||||
|
@ -218,123 +216,238 @@ namespace sol {
|
|||
};
|
||||
|
||||
template<typename Signature, bool b = has_deducible_signature<Signature>::value>
|
||||
struct fx_traits : basic_traits<false, void, void> {};
|
||||
struct fx_traits : basic_traits<false, false, void, void> {};
|
||||
|
||||
// Free Functions
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(Args...), false> : basic_traits<false, void, R, Args...> {
|
||||
struct fx_traits<R(Args...), false> : basic_traits<false, false, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(*)(Args...), false> : basic_traits<false, void, R, Args...> {
|
||||
struct fx_traits<R(*)(Args...), false> : basic_traits<false, false, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(Args..., ...), false> : basic_traits<true, void, R, Args...> {
|
||||
struct fx_traits<R(Args..., ...), false> : basic_traits<false, true, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(*)(Args..., ...), false> : basic_traits<true, void, R, Args...> {
|
||||
struct fx_traits<R(*)(Args..., ...), false> : basic_traits<false, true, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
// Member Functions
|
||||
/* C-Style Variadics */
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...), false> : basic_traits<false, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args...), false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...), false> : basic_traits<true, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args..., ...), false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
/* Const Volatile */
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const, false> : basic_traits<false, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args...) const, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const, false> : basic_traits<true, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args..., ...) const, false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const volatile, false> : basic_traits<false, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args...) const volatile, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const volatile;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const volatile, false> : basic_traits<true, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args..., ...) const volatile, false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const volatile;
|
||||
};
|
||||
|
||||
/* Member Function Qualifiers */
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) &, false> : basic_traits<false, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args...) &, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) &;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) &, false> : basic_traits<true, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args..., ...) &, false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) &;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const &, false> : basic_traits<false, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args...) const &, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const &;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const &, false> : basic_traits<true, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args..., ...) const &, false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const &;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const volatile &, false> : basic_traits<false, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args...) const volatile &, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const volatile &;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const volatile &, false> : basic_traits<true, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args..., ...) const volatile &, false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const volatile &;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) && , false> : basic_traits<false, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args...) && , false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) && ;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) && , false> : basic_traits<true, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args..., ...) && , false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) && ;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const &&, false> : basic_traits<false, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args...) const &&, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const &&;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const &&, false> : basic_traits<true, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args..., ...) const &&, false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const &&;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const volatile &&, false> : basic_traits<false, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args...) const volatile &&, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const volatile &&;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const volatile &&, false> : basic_traits<true, T, R, Args...> {
|
||||
struct fx_traits<R(T::*)(Args..., ...) const volatile &&, false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const volatile &&;
|
||||
};
|
||||
|
||||
#ifdef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(*)(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(*)(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
/* Const Volatile */
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const volatile noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const volatile;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const volatile noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const volatile;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) & noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) &;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) & noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) &;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const & noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const &;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const & noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const &;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const volatile & noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const volatile &;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const volatile & noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const volatile &;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) && noexcept , false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) && ;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) && noexcept , false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) && ;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const && noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const &&;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const && noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const &&;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const volatile && noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const volatile &&;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const volatile && noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const volatile &&;
|
||||
};
|
||||
|
||||
#endif // noexcept is part of a function's type
|
||||
|
||||
template<typename Signature>
|
||||
struct fx_traits<Signature, true> : fx_traits<typename fx_traits<decltype(&Signature::operator())>::function_type, false> {};
|
||||
|
||||
|
@ -348,6 +461,7 @@ namespace sol {
|
|||
typedef R Arg;
|
||||
typedef T object_type;
|
||||
using signature_type = R(T::*);
|
||||
static const bool is_noexcept = false;
|
||||
static const bool is_member_function = false;
|
||||
static const std::size_t arity = 1;
|
||||
static const std::size_t free_arity = 2;
|
||||
|
@ -362,6 +476,7 @@ namespace sol {
|
|||
template<std::size_t i>
|
||||
using arg_at = void_tuple_element_t<i, args_tuple>;
|
||||
};
|
||||
|
||||
} // meta_detail
|
||||
|
||||
template<typename Signature>
|
||||
|
@ -823,6 +938,12 @@ namespace sol {
|
|||
#include <lua.hpp>
|
||||
#endif // C++ Mangling for Lua
|
||||
|
||||
#if defined(__cpp_noexcept_function_type) && (__cpp_noexcept_function_type >= 201510L)
|
||||
#ifndef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
#define SOL_NOEXCEPT_FUNCTION_TYPE 1
|
||||
#endif // noexcept is part of a function's type
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_MSC_VER)
|
||||
#ifndef SOL_CODECVT_SUPPORT
|
||||
#define SOL_CODECVT_SUPPORT 1
|
||||
|
@ -3045,6 +3166,10 @@ namespace sol {
|
|||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
#ifdef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
typedef int(*lua_CFunction_noexcept) (lua_State *L) noexcept;
|
||||
#endif // noexcept function type for lua_CFunction
|
||||
|
||||
#ifdef SOL_NO_EXCEPTIONS
|
||||
template <lua_CFunction f>
|
||||
int static_trampoline(lua_State* L) {
|
||||
|
@ -3080,8 +3205,33 @@ namespace sol {
|
|||
return lua_error(L);
|
||||
}
|
||||
|
||||
#ifdef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
template <lua_CFunction_noexcept f>
|
||||
int static_trampoline(lua_State* L) {
|
||||
try {
|
||||
return f(L);
|
||||
}
|
||||
catch (const char *s) {
|
||||
lua_pushstring(L, s);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
lua_pushstring(L, e.what());
|
||||
}
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
catch (...) {
|
||||
std::exception_ptr eptr = std::current_exception();
|
||||
lua_pushstring(L, "caught (...) exception");
|
||||
}
|
||||
#endif
|
||||
return lua_error(L);
|
||||
}
|
||||
#endif // noexcept lua_CFunction type
|
||||
|
||||
template <typename Fx, typename... Args>
|
||||
int trampoline(lua_State* L, Fx&& f, Args&&... args) {
|
||||
if (meta::bind_traits<meta::unqualified_t<Fx>>::is_noexcept) {
|
||||
return f(L, std::forward<Args>(args)...);
|
||||
}
|
||||
try {
|
||||
return f(L, std::forward<Args>(args)...);
|
||||
}
|
||||
|
@ -8032,6 +8182,85 @@ namespace sol {
|
|||
|
||||
};
|
||||
|
||||
#ifdef SOL_NOEXCEPT_FUNCTION_TYPE //noexcept has become a part of a function's type
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args...) noexcept> : public member_function_wrapper<R(O:: *)(Args...) noexcept, R, O, Args...> {
|
||||
|
||||
};
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args...) const noexcept> : public member_function_wrapper<R(O:: *)(Args...) const noexcept, R, O, Args...> {
|
||||
|
||||
};
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args...) const volatile noexcept> : public member_function_wrapper<R(O:: *)(Args...) const volatile noexcept, R, O, Args...> {
|
||||
|
||||
};
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args...) & noexcept> : public member_function_wrapper<R(O:: *)(Args...) & noexcept, R, O, Args...> {
|
||||
|
||||
};
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args...) const & noexcept> : public member_function_wrapper<R(O:: *)(Args...) const & noexcept, R, O, Args...> {
|
||||
|
||||
};
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args...) const volatile & noexcept> : public member_function_wrapper<R(O:: *)(Args...) const volatile & noexcept, R, O, Args...> {
|
||||
|
||||
};
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args..., ...) & noexcept> : public member_function_wrapper<R(O:: *)(Args..., ...) & noexcept, R, O, Args...> {
|
||||
|
||||
};
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args..., ...) const & noexcept> : public member_function_wrapper<R(O:: *)(Args..., ...) const & noexcept, R, O, Args...> {
|
||||
|
||||
};
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args..., ...) const volatile & noexcept> : public member_function_wrapper<R(O:: *)(Args..., ...) const volatile & noexcept, R, O, Args...> {
|
||||
|
||||
};
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args...) && noexcept> : public member_function_wrapper<R(O:: *)(Args...) & noexcept, R, O, Args...> {
|
||||
|
||||
};
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args...) const && noexcept> : public member_function_wrapper<R(O:: *)(Args...) const & noexcept, R, O, Args...> {
|
||||
|
||||
};
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args...) const volatile && noexcept> : public member_function_wrapper<R(O:: *)(Args...) const volatile & noexcept, R, O, Args...> {
|
||||
|
||||
};
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args..., ...) && noexcept> : public member_function_wrapper<R(O:: *)(Args..., ...) & noexcept, R, O, Args...> {
|
||||
|
||||
};
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args..., ...) const && noexcept> : public member_function_wrapper<R(O:: *)(Args..., ...) const & noexcept, R, O, Args...> {
|
||||
|
||||
};
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args..., ...) const volatile && noexcept> : public member_function_wrapper<R(O:: *)(Args..., ...) const volatile & noexcept, R, O, Args...> {
|
||||
|
||||
};
|
||||
|
||||
#endif // noexcept is part of a function's type
|
||||
|
||||
} // sol
|
||||
|
||||
// end of sol/wrapper.hpp
|
||||
|
|
|
@ -103,30 +103,6 @@ namespace sol {
|
|||
typedef R(*function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(*)(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(*)(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
#endif//#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
|
||||
|
||||
// Member Functions
|
||||
/* C-Style Variadics */
|
||||
template<typename T, typename R, typename... Args>
|
||||
|
@ -139,20 +115,6 @@ namespace sol {
|
|||
typedef R(T::* function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
#endif//#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
|
||||
|
||||
/* Const Volatile */
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const, false> : basic_traits<false, false, T, R, Args...> {
|
||||
|
@ -174,31 +136,6 @@ namespace sol {
|
|||
typedef R(T::* function_pointer_type)(Args..., ...) const volatile;
|
||||
};
|
||||
|
||||
#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
|
||||
|
||||
/* Const Volatile */
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const volatile noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const volatile;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const volatile noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const volatile;
|
||||
};
|
||||
|
||||
#endif//#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
|
||||
|
||||
/* Member Function Qualifiers */
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) &, false> : basic_traits<false, false, T, R, Args...> {
|
||||
|
@ -260,7 +197,58 @@ namespace sol {
|
|||
typedef R(T::* function_pointer_type)(Args..., ...) const volatile &&;
|
||||
};
|
||||
|
||||
#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
|
||||
#ifdef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(*)(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct fx_traits<R(*)(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
|
||||
typedef R(*function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
/* Const Volatile */
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) const volatile noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args...) const volatile;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args..., ...) const volatile noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R(T::* function_pointer_type)(Args..., ...) const volatile;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
struct fx_traits<R(T::*)(Args...) & noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
|
@ -322,7 +310,7 @@ namespace sol {
|
|||
typedef R(T::* function_pointer_type)(Args..., ...) const volatile &&;
|
||||
};
|
||||
|
||||
#endif//#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
|
||||
#endif // noexcept is part of a function's type
|
||||
|
||||
template<typename Signature>
|
||||
struct fx_traits<Signature, true> : fx_traits<typename fx_traits<decltype(&Signature::operator())>::function_type, false> {};
|
||||
|
@ -337,6 +325,7 @@ namespace sol {
|
|||
typedef R Arg;
|
||||
typedef T object_type;
|
||||
using signature_type = R(T::*);
|
||||
static const bool is_noexcept = false;
|
||||
static const bool is_member_function = false;
|
||||
static const std::size_t arity = 1;
|
||||
static const std::size_t free_arity = 2;
|
||||
|
@ -351,6 +340,7 @@ namespace sol {
|
|||
template<std::size_t i>
|
||||
using arg_at = void_tuple_element_t<i, args_tuple>;
|
||||
};
|
||||
|
||||
} // meta_detail
|
||||
|
||||
template<typename Signature>
|
||||
|
|
|
@ -30,6 +30,12 @@
|
|||
#include <lua.hpp>
|
||||
#endif // C++ Mangling for Lua
|
||||
|
||||
#if defined(__cpp_noexcept_function_type) && (__cpp_noexcept_function_type >= 201510L)
|
||||
#ifndef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
#define SOL_NOEXCEPT_FUNCTION_TYPE 1
|
||||
#endif // noexcept is part of a function's type
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_MSC_VER)
|
||||
#ifndef SOL_CODECVT_SUPPORT
|
||||
#define SOL_CODECVT_SUPPORT 1
|
||||
|
|
|
@ -190,9 +190,15 @@ namespace sol {
|
|||
stack::push(L, f);
|
||||
}
|
||||
|
||||
#ifdef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
static void select_function(std::true_type, lua_State* L, detail::lua_CFunction_noexcept f) {
|
||||
stack::push(L, f);
|
||||
}
|
||||
#endif // noexcept function type
|
||||
|
||||
template <typename Fx, typename... Args, meta::disable<meta::any<std::is_base_of<reference, meta::unqualified_t<Fx>>, std::is_base_of<stack_reference, meta::unqualified_t<Fx>>>> = meta::enabler>
|
||||
static void select(lua_State* L, Fx&& fx, Args&&... args) {
|
||||
select_function(std::is_function<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
select_function(std::is_function<std::remove_pointer_t<meta::unqualified_t<Fx>>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Fx, meta::enable<meta::any<std::is_base_of<reference, meta::unqualified_t<Fx>>, std::is_base_of<stack_reference, meta::unqualified_t<Fx>>>> = meta::enabler>
|
||||
|
@ -254,7 +260,15 @@ namespace sol {
|
|||
};
|
||||
|
||||
template<typename Signature>
|
||||
struct pusher<Signature, std::enable_if_t<meta::all<std::is_function<Signature>, meta::neg<std::is_same<Signature, lua_CFunction>>, meta::neg<std::is_same<Signature, std::remove_pointer_t<lua_CFunction>>>>::value>> {
|
||||
struct pusher<Signature, std::enable_if_t<meta::all<
|
||||
std::is_function<Signature>,
|
||||
meta::neg<std::is_same<Signature, lua_CFunction>>,
|
||||
meta::neg<std::is_same<Signature, std::remove_pointer_t<lua_CFunction>>>
|
||||
#ifdef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
, meta::neg<std::is_same<Signature, detail::lua_CFunction_noexcept>>,
|
||||
meta::neg<std::is_same<Signature, std::remove_pointer_t<detail::lua_CFunction_noexcept>>>
|
||||
#endif // noexcept function types
|
||||
>::value>> {
|
||||
template <typename F>
|
||||
static int push(lua_State* L, F&& f) {
|
||||
return pusher<function_sig<>>{}.push(L, std::forward<F>(f));
|
||||
|
|
|
@ -28,11 +28,11 @@ namespace sol {
|
|||
namespace function_detail {
|
||||
template<typename Func>
|
||||
struct functor_function {
|
||||
typedef meta::unwrapped_t<meta::unqualified_t<Func>> Function;
|
||||
Function fx;
|
||||
typedef std::decay_t<meta::unwrap_unqualified_t<Func>> function_type;
|
||||
function_type fx;
|
||||
|
||||
template<typename... Args>
|
||||
functor_function(Function f, Args&&... args) : fx(std::move(f), std::forward<Args>(args)...) {}
|
||||
functor_function(function_type f, Args&&... args) : fx(std::move(f), std::forward<Args>(args)...) {}
|
||||
|
||||
int call(lua_State* L) {
|
||||
return call_detail::call_wrapped<void, true, false>(L, fx);
|
||||
|
|
|
@ -84,7 +84,7 @@ namespace sol {
|
|||
}
|
||||
|
||||
template <typename F, F fx>
|
||||
int call_wrapper_entry(lua_State* L) {
|
||||
int call_wrapper_entry(lua_State* L) noexcept(meta::bind_traits<F>::is_noexcept) {
|
||||
return call_wrapper_function<F, fx>(std::is_member_function_pointer<meta::unqualified_t<F>>(), L);
|
||||
}
|
||||
|
||||
|
@ -97,10 +97,21 @@ namespace sol {
|
|||
}
|
||||
};
|
||||
|
||||
} // function_detail
|
||||
template <typename F, F fx>
|
||||
inline int c_call_raw(std::true_type, lua_State* L) {
|
||||
#ifdef __clang__
|
||||
return detail::trampoline(L, fx);
|
||||
#else
|
||||
#ifdef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
return meta::bind_traits<F>::is_noexcept ? detail::static_trampoline_noexcept<fx>(L) : detail::static_trampoline<fx>(L);
|
||||
#else
|
||||
return detail::static_trampoline<fx>(L);
|
||||
#endif
|
||||
#endif // fuck you clang :c
|
||||
}
|
||||
|
||||
template <typename F, F fx>
|
||||
inline int c_call(lua_State* L) {
|
||||
inline int c_call_raw(std::false_type, lua_State* L) {
|
||||
#ifdef __clang__
|
||||
return detail::trampoline(L, function_detail::call_wrapper_entry<F, fx>);
|
||||
#else
|
||||
|
@ -108,6 +119,18 @@ namespace sol {
|
|||
#endif // fuck you clang :c
|
||||
}
|
||||
|
||||
} // function_detail
|
||||
|
||||
template <typename F, F fx>
|
||||
inline int c_call(lua_State* L) {
|
||||
typedef meta::unqualified_t<F> Fu;
|
||||
return function_detail::c_call_raw<F, fx>(std::integral_constant<bool, std::is_same<Fu, lua_CFunction>::value
|
||||
#ifdef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
|| std::is_same<Fu, detail::lua_CFunction_noexcept>::value
|
||||
#endif
|
||||
>(), L);
|
||||
}
|
||||
|
||||
template <typename F, F f>
|
||||
struct wrap {
|
||||
typedef F type;
|
||||
|
|
|
@ -310,6 +310,23 @@ namespace sol {
|
|||
return 1;
|
||||
}
|
||||
};
|
||||
#ifdef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
template<>
|
||||
struct pusher<std::remove_pointer_t<detail::lua_CFunction_noexcept>> {
|
||||
static int push(lua_State* L, detail::lua_CFunction_noexcept func, int n = 0) {
|
||||
lua_pushcclosure(L, func, n);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct pusher<detail::lua_CFunction_noexcept> {
|
||||
static int push(lua_State* L, detail::lua_CFunction_noexcept func, int n = 0) {
|
||||
lua_pushcclosure(L, func, n);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
#endif // noexcept function type
|
||||
|
||||
template<>
|
||||
struct pusher<c_closure> {
|
||||
|
|
|
@ -31,18 +31,22 @@
|
|||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
#ifdef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
typedef int(*lua_CFunction_noexcept) (lua_State *L) noexcept;
|
||||
#endif // noexcept function type for lua_CFunction
|
||||
|
||||
#ifdef SOL_NO_EXCEPTIONS
|
||||
template <lua_CFunction f>
|
||||
int static_trampoline(lua_State* L) {
|
||||
int static_trampoline(lua_State* L) noexcept {
|
||||
return f(L);
|
||||
}
|
||||
|
||||
template <typename Fx, typename... Args>
|
||||
int trampoline(lua_State* L, Fx&& f, Args&&... args) {
|
||||
int trampoline(lua_State* L, Fx&& f, Args&&... args) noexcept {
|
||||
return f(L, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
inline int c_trampoline(lua_State* L, lua_CFunction f) {
|
||||
inline int c_trampoline(lua_State* L, lua_CFunction f) noexcept {
|
||||
return trampoline(L, f);
|
||||
}
|
||||
#else
|
||||
|
@ -59,15 +63,33 @@ namespace sol {
|
|||
}
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
catch (...) {
|
||||
std::exception_ptr eptr = std::current_exception();
|
||||
lua_pushstring(L, "caught (...) exception");
|
||||
}
|
||||
#endif
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
#ifdef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
#if 0
|
||||
// impossible: g++/clang++ choke as they think this function is ambiguous:
|
||||
// to fix, wait for template <auto X> and then switch on no-exceptness of the function
|
||||
template <lua_CFunction_noexcept f>
|
||||
int static_trampoline(lua_State* L) noexcept {
|
||||
#else
|
||||
template <lua_CFunction_noexcept f>
|
||||
int static_trampoline_noexcept(lua_State* L) noexcept {
|
||||
#endif // impossible
|
||||
std::cout << "[STATIC_TRAMPOLINE] HEY A NOEXCEPTION FUNCTION IS GONNA BE CALLED" << std::endl;
|
||||
return f(L);
|
||||
}
|
||||
#endif // noexcept lua_CFunction type
|
||||
|
||||
template <typename Fx, typename... Args>
|
||||
int trampoline(lua_State* L, Fx&& f, Args&&... args) {
|
||||
if (meta::bind_traits<meta::unqualified_t<Fx>>::is_noexcept) {
|
||||
std::cout << "[TRAMPOLINE] HEY A NOEXCEPTION FUNCTION IS GONNA BE CALLED" << std::endl;
|
||||
return f(L, std::forward<Args>(args)...);
|
||||
}
|
||||
try {
|
||||
return f(L, std::forward<Args>(args)...);
|
||||
}
|
||||
|
|
|
@ -233,7 +233,7 @@ namespace sol {
|
|||
|
||||
};
|
||||
|
||||
#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
|
||||
#ifdef SOL_NOEXCEPT_FUNCTION_TYPE //noexcept has become a part of a function's type
|
||||
|
||||
template <typename R, typename O, typename... Args>
|
||||
struct wrapper<R(O:: *)(Args...) noexcept> : public member_function_wrapper<R(O:: *)(Args...) noexcept, R, O, Args...> {
|
||||
|
@ -310,7 +310,7 @@ namespace sol {
|
|||
|
||||
};
|
||||
|
||||
#endif//#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
|
||||
#endif // noexcept is part of a function's type
|
||||
|
||||
} // sol
|
||||
|
||||
|
|
|
@ -99,8 +99,9 @@ struct fer {
|
|||
}
|
||||
};
|
||||
|
||||
inline void noexcept_function() noexcept {}
|
||||
struct type_with_noexcept_method{ void noexcept_method() noexcept {} };
|
||||
static int raw_noexcept_function(lua_State* L) noexcept {
|
||||
return sol::stack::push(L, 0x63);
|
||||
}
|
||||
|
||||
TEST_CASE("functions/tuple-returns", "Make sure tuple returns are ordered properly") {
|
||||
sol::state lua;
|
||||
|
@ -1226,9 +1227,53 @@ TEST_CASE("functions/unique-overloading", "make sure overloading can work with p
|
|||
};
|
||||
}
|
||||
|
||||
TEST_CASE("functions/noexcept", "allow noexcept free - and member functions in Lua") {
|
||||
TEST_CASE("functions/noexcept", "allow noexcept functions to be serialized properly into Lua using sol2") {
|
||||
struct T {
|
||||
static int noexcept_function() noexcept {
|
||||
return 0x61;
|
||||
}
|
||||
|
||||
int noexcept_method() noexcept {
|
||||
return 0x62;
|
||||
}
|
||||
} t;
|
||||
|
||||
lua_CFunction ccall = sol::c_call<decltype(&raw_noexcept_function), &raw_noexcept_function>;
|
||||
|
||||
sol::state lua;
|
||||
|
||||
lua.set_function("noexcept_function", &noexcept_function);
|
||||
lua.set_function("noexcept_member_function", &type_with_noexcept_method::noexcept_method);
|
||||
lua.set_function("f", &T::noexcept_function);
|
||||
lua.set_function("g", &T::noexcept_method);
|
||||
lua.set_function("h", &T::noexcept_method, T());
|
||||
lua.set_function("i", &T::noexcept_method, std::ref(t));
|
||||
lua.set_function("j", &T::noexcept_method, &t);
|
||||
lua.set_function("k", &T::noexcept_method, t);
|
||||
lua.set_function("l", &raw_noexcept_function);
|
||||
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()");
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
int v3 = lua["v3"];
|
||||
int v4 = lua["v4"];
|
||||
int v5 = lua["v5"];
|
||||
int v6 = lua["v6"];
|
||||
int v7 = lua["v7"];
|
||||
int v8 = lua["v8"];
|
||||
REQUIRE(v1 == 0x61);
|
||||
REQUIRE(v2 == 0x62);
|
||||
REQUIRE(v3 == 0x62);
|
||||
REQUIRE(v4 == 0x62);
|
||||
REQUIRE(v5 == 0x62);
|
||||
REQUIRE(v6 == 0x62);
|
||||
REQUIRE(v7 == 0x63);
|
||||
REQUIRE(v8 == 0x63);
|
||||
}
|
||||
|
|
|
@ -265,9 +265,6 @@ struct matrix_xi {
|
|||
}
|
||||
};
|
||||
|
||||
inline void noexcept_function() noexcept {}
|
||||
struct type_with_noexcept_method{ void noexcept_method() noexcept {} };
|
||||
|
||||
TEST_CASE("usertype/usertype", "Show that we can create classes from usertype and use them") {
|
||||
sol::state lua;
|
||||
|
||||
|
@ -1814,6 +1811,27 @@ TEST_CASE("usertype/meta-key-retrievals", "allow for special meta keys (__index,
|
|||
}
|
||||
|
||||
TEST_CASE("usertype/noexcept-methods", "make sure noexcept functinos and methods can be bound to usertypes without issues") {
|
||||
sol::state lua;
|
||||
lua.new_usertype<type_with_noexcept_method>("tmp", "nf", &noexcept_function, "nm", &type_with_noexcept_method::noexcept_method);
|
||||
struct T {
|
||||
static int noexcept_function() noexcept {
|
||||
return 0x61;
|
||||
}
|
||||
|
||||
int noexcept_method() noexcept {
|
||||
return 0x62;
|
||||
}
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.new_usertype<T>("T",
|
||||
"nf", &T::noexcept_function,
|
||||
"nm", &T::noexcept_method
|
||||
);
|
||||
|
||||
lua.script("t = T.new()");
|
||||
lua.script("v1 = t.nf()");
|
||||
lua.script("v2 = t:nm()");
|
||||
int v1 = lua["v1"];
|
||||
int v2 = lua["v2"];
|
||||
REQUIRE(v1 == 0x61);
|
||||
REQUIRE(v2 == 0x62);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user