Fix various issues

- readonly(...) should no longer issue errors in bogus manners
- binding for member function pointers and normal pointers should behave better now
- coroutines should now properly transfer the state/identity of their error handlers
- Fix empty base class optimization type
- Improve bind traits metaprogramming
- Add new define to catch-all for exception propagation
- Improve natvis
- Move test defines to build system, as we should
- Add a new example for multiple thread/states in Coroutines
- Add proper direct to mangling in Clang for Windows
- Exceptions are still busted on some platforms (Clang being quite funky)
This commit is contained in:
ThePhD 2020-11-19 15:12:56 -05:00
parent b8aa189e32
commit 62804667ee
No known key found for this signature in database
GPG Key ID: 1509DB1C0F702BFA
31 changed files with 1076 additions and 841 deletions

View File

@ -35,10 +35,12 @@ include(Common/Core)
set(LUA_VANILLA_5.1_LATEST_VERSION 5.1.5)
set(LUA_VANILLA_5.2_LATEST_VERSION 5.2.4)
set(LUA_VANILLA_5.3_LATEST_VERSION 5.3.5)
set(LUA_VANILLA_5.4_LATEST_VERSION 5.4.0)
set(LUA_VANILLA_5.4_LATEST_VERSION 5.4.1)
# exact version, coming from CI: pull directly from Lua and use external project to build
# list of known md5 / sha1: must update when there are changes
set(LUA_VANILLA_MD5_5.4.1 1d575faef1c907292edd79e7a2784d30)
set(LUA_VANILLA_SHA1_5.4.1 88961e7d4fda58ca2c6163938fd48db8880e803d)
set(LUA_VANILLA_MD5_5.4.0 dbf155764e5d433fc55ae80ea7060b60)
set(LUA_VANILLA_SHA1_5.4.0 8cdbffa8a214a23d190d7c45f38c19518ae62e89)
set(LUA_VANILLA_MD5_5.3.5 4f4b4f323fd3514a68e0ab3da8ce3455)

View File

@ -0,0 +1,49 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
#include <string>
#include <iostream>
int main () {
std::cout << "=== coroutine - multple threads ===" << std::endl;
sol::state lua;
lua.open_libraries(sol::lib::base, sol::lib::package, sol::lib::coroutine);
lua["print"] = [](sol::object v){
std::cout << v.as<std::string>() << std::endl;
};
lua["cyield"] = sol::yielding([](){
std::cout << "YIELDING" << std::endl;
});
// notice the new threads!
sol::thread thread1 = sol::thread::create(lua);
sol::thread thread2 = sol::thread::create(lua);
// notice we load it FROM the new "execution stack"
// we need it to have thread1's stack perspective
sol::coroutine co1 = thread1.state().load(R"(
print("AA : Step 1")
cyield()
print("AA : Step 2")
)");
// call first coroutine here
co1();
// notice we load it FROM the new "execution stack"
// we need it to have thread2's stack and perspective
sol::coroutine co2 = thread2.state().load(R"(
print("BB : Step 1")
cyield()
print("BB : Step 2")
)");
// run the other coroutine
co2();
co1();
// tada! they run on
// independent stacks
return 0;
}

View File

@ -30,26 +30,20 @@
namespace sol { namespace meta {
namespace meta_detail {
template <class F>
struct check_deducible_signature {
struct nat {};
template <class G>
static auto test(int) -> decltype(&G::operator(), void());
template <class>
static auto test(...) -> nat;
using type = std::is_void<decltype(test<F>(0))>;
};
template <typename F>
using detect_deducible_signature = decltype(&F::operator(), void());
} // namespace meta_detail
template <class F>
struct has_deducible_signature : meta_detail::check_deducible_signature<F>::type {};
template <typename F>
using call_operator_deducible = typename is_detected<meta_detail::detect_deducible_signature, F>::type;
template <typename F>
constexpr inline bool call_operator_deducible_v = call_operator_deducible<F>::value;
namespace meta_detail {
template <std::size_t I, typename T>
struct void_tuple_element : meta::tuple_element<I, T> {};
struct void_tuple_element : meta::tuple_element<I, T> { };
template <std::size_t I>
struct void_tuple_element<I, std::tuple<>> {
@ -84,234 +78,234 @@ namespace sol { namespace meta {
using arg_at = void_tuple_element_t<i, args_tuple>;
};
template <typename Signature, bool b = has_deducible_signature<Signature>::value>
struct fx_traits : basic_traits<false, false, void, void> {};
template <typename Signature, bool b = call_operator_deducible<Signature>::value>
struct fx_traits : public basic_traits<false, false, void, void> { };
// Free Functions
template <typename R, typename... Args>
struct fx_traits<R(Args...), false> : basic_traits<false, false, void, R, Args...> {
struct fx_traits<R(Args...), false> : public 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, false, void, R, Args...> {
struct fx_traits<R (*)(Args...), false> : public 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, true, void, R, Args...> {
struct fx_traits<R(Args..., ...), false> : public 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<false, true, void, R, Args...> {
struct fx_traits<R (*)(Args..., ...), false> : public 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, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...), false> : public 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<false, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...), false> : public 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, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...) const, false> : public 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<false, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...) const, false> : public 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, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...) const volatile, false> : public 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<false, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...) const volatile, false> : public 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, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...)&, false> : public 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<false, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...)&, false> : public 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, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...) const&, false> : public 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<false, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...) const&, false> : public 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, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...) const volatile&, false> : public 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<false, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...) const volatile&, false> : public 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, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...)&&, false> : public 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<false, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...)&&, false> : public 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, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...) const&&, false> : public 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<false, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...) const&&, false> : public 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, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...) const volatile&&, false> : public 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<false, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...) const volatile&&, false> : public basic_traits<false, true, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args..., ...) const volatile&&;
};
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
template <typename R, typename... Args>
struct fx_traits<R(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
struct fx_traits<R(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {
typedef R (*function_pointer_type)(Args...) noexcept;
};
template <typename R, typename... Args>
struct fx_traits<R (*)(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
struct fx_traits<R (*)(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {
typedef R (*function_pointer_type)(Args...) noexcept;
};
template <typename R, typename... Args>
struct fx_traits<R(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
struct fx_traits<R(Args..., ...) noexcept, false> : public basic_traits<true, true, void, R, Args...> {
typedef R (*function_pointer_type)(Args..., ...) noexcept;
};
template <typename R, typename... Args>
struct fx_traits<R (*)(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
struct fx_traits<R (*)(Args..., ...) noexcept, false> : public basic_traits<true, true, void, R, Args...> {
typedef R (*function_pointer_type)(Args..., ...) noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args...) noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...) noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args...) noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args..., ...) noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...) noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args..., ...) noexcept;
};
/* 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...> {
struct fx_traits<R (T::*)(Args...) const noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args...) const noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args..., ...) const noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...) const noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args..., ...) const noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args...) const volatile noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...) const volatile noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args...) const volatile noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args..., ...) const volatile noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...) const volatile noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args..., ...) const volatile noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args...) & noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...)& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args...) & noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args..., ...) & noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...)& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args..., ...) & noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args...) const& noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...) const& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args...) const& noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args..., ...) const& noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...) const& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args..., ...) const& noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args...) const volatile& noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...) const volatile& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args...) const volatile& noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args..., ...) const volatile& noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...) const volatile& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args..., ...) const volatile& noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args...) && noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...)&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args...) && noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args..., ...) && noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...)&& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args..., ...) && noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args...) const&& noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...) const&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args...) const&& noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args..., ...) const&& noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...) const&& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args..., ...) const&& noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args...) const volatile&& noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (T::*)(Args...) const volatile&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args...) const volatile&& noexcept;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (T::*)(Args..., ...) const volatile&& noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (T::*)(Args..., ...) const volatile&& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (T::*function_pointer_type)(Args..., ...) const volatile&& noexcept;
};
@ -319,194 +313,192 @@ namespace sol { namespace meta {
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) && SOL_IS_ON(SOL_PLATFORM_X86_I_)
template <typename R, typename... Args>
struct fx_traits<R __stdcall(Args...), false> : basic_traits<false, false, void, R, Args...> {
struct fx_traits<R __stdcall(Args...), false> : public basic_traits<false, false, void, R, Args...> {
typedef R(__stdcall* function_pointer_type)(Args...);
};
template <typename R, typename... Args>
struct fx_traits<R(__stdcall*)(Args...), false> : basic_traits<false, false, void, R, Args...> {
struct fx_traits<R(__stdcall*)(Args...), false> : public basic_traits<false, false, void, R, Args...> {
typedef R(__stdcall* function_pointer_type)(Args...);
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...), false> : basic_traits<false, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...), false> : public basic_traits<false, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...);
};
/* Const Volatile */
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...) const, false> : basic_traits<false, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...) const, false> : public basic_traits<false, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) const;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...) const volatile, false> : basic_traits<false, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...) const volatile, false> : public basic_traits<false, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile;
};
/* Member Function Qualifiers */
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...)&, false> : basic_traits<false, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...)&, false> : public basic_traits<false, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) &;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...) const&, false> : basic_traits<false, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...) const&, false> : public basic_traits<false, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) const&;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...) const volatile&, false> : basic_traits<false, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...) const volatile&, false> : public basic_traits<false, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...)&&, false> : basic_traits<false, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...)&&, false> : public basic_traits<false, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) &&;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...) const&&, false> : basic_traits<false, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...) const&&, false> : public basic_traits<false, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) const&&;
};
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...) const volatile&&, false> : basic_traits<false, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...) const volatile&&, false> : public basic_traits<false, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&&;
};
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
template <typename R, typename... Args>
struct fx_traits<R __stdcall(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
struct fx_traits<R __stdcall(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {
typedef R(__stdcall* function_pointer_type)(Args...) noexcept;
};
template <typename R, typename... Args>
struct fx_traits<R(__stdcall*)(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
struct fx_traits<R(__stdcall*)(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {
typedef R(__stdcall* function_pointer_type)(Args...) noexcept;
};
/* __stdcall cannot be applied to functions with varargs*/
/*template <typename R, typename... Args>
struct fx_traits<__stdcall R(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
struct fx_traits<__stdcall R(Args..., ...) noexcept, false> : public basic_traits<true, true, void, R, Args...> {
typedef R(__stdcall* function_pointer_type)(Args..., ...) noexcept;
};
template <typename R, typename... Args>
struct fx_traits<R (__stdcall *)(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
struct fx_traits<R (__stdcall *)(Args..., ...) noexcept, false> : public basic_traits<true, true, void, R, Args...> {
typedef R(__stdcall* function_pointer_type)(Args..., ...) noexcept;
};*/
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...) noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...) noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) noexcept;
};
/* __stdcall does not work with varargs */
/*template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args..., ...) noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args..., ...) noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) noexcept;
};*/
/* Const Volatile */
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...) const noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...) const noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) const noexcept;
};
/* __stdcall does not work with varargs */
/*template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args..., ...) const noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args..., ...) const noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const noexcept;
};*/
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...) const volatile noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...) const volatile noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile noexcept;
};
/* __stdcall does not work with varargs */
/*template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const volatile noexcept;
};*/
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...) & noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...)& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) & noexcept;
};
/* __stdcall does not work with varargs */
/*template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args..., ...) & noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args..., ...) & noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) & noexcept;
};*/
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...) const& noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...) const& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) const& noexcept;
};
/* __stdcall does not work with varargs */
/*template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args..., ...) const& noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args..., ...) const& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const& noexcept;
};*/
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...) const volatile& noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...) const volatile& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile& noexcept;
};
/* __stdcall does not work with varargs */
/*template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile& noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const volatile& noexcept;
};*/
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...) && noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...)&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) && noexcept;
};
/* __stdcall does not work with varargs */
/*template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args..., ...) && noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args..., ...) && noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) && noexcept;
};*/
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...) const&& noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...) const&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) const&& noexcept;
};
/* __stdcall does not work with varargs */
/*template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args..., ...) const&& noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args..., ...) const&& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const&& noexcept;
};*/
template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args...) const volatile&& noexcept, false> : basic_traits<true, false, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args...) const volatile&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&& noexcept;
};
/* __stdcall does not work with varargs */
/*template <typename T, typename R, typename... Args>
struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile&& noexcept, false> : basic_traits<true, true, T, R, Args...> {
struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile&& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const volatile&& noexcept;
};*/
#endif // noexcept is part of a function's type
#endif // __stdcall x86 VC++ bug
template <typename Signature>
struct fx_traits<Signature, true>
: public fx_traits<typename fx_traits<decltype(&Signature::operator())>::function_type, false> {};
struct fx_traits<Signature, true> : public fx_traits<typename fx_traits<decltype(&Signature::operator())>::function_type, false> { };
template <typename Signature, bool b = std::is_member_object_pointer<Signature>::value>
struct callable_traits
: public fx_traits<std::decay_t<Signature>> {};
struct callable_traits : public fx_traits<std::decay_t<Signature>> { };
template <typename R, typename T>
struct callable_traits<R(T::*), true> {
@ -532,7 +524,21 @@ namespace sol { namespace meta {
} // namespace meta_detail
template <typename Signature>
struct bind_traits : meta_detail::callable_traits<Signature> {};
using bind_traits = meta_detail::callable_traits<Signature>;
namespace meta_detail {
template <typename, bool>
struct is_probably_stateless_lambda : std::false_type { };
template <typename T>
struct is_probably_stateless_lambda<T, true> : std::is_convertible<T, typename bind_traits<T>::function_type*>::type { };
} // namespace meta_detail
template <typename T>
using is_probably_stateless_lambda = typename meta_detail::is_probably_stateless_lambda<T, std::is_empty_v<T> && call_operator_deducible_v<T>>::type;
template <typename T>
inline constexpr bool is_probably_stateless_lambda_v = is_probably_stateless_lambda<T>::value;
template <typename Signature>
using function_args_t = typename bind_traits<Signature>::args_list;

View File

@ -125,7 +125,23 @@
// shoving exceptions through Lua and errors should
// always be serialized
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_OFF
#endif // LuaJIT beta 02.01.00 have better exception handling on all platforms since beta3
#endif
// Some configurations work with exceptions,
// but cannot catch-all everything...
#if defined(SOL_EXCEPTIONS_CATCH_ALL)
#if (SOL_EXCEPTIONS_CATCH_ALL != 0)
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_ON
#else
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_OFF
#endif
#else
#if SOL_IS_ON(SOL_USE_LUAJIT_I_)
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
#else
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_ON
#endif
#endif
#if defined(SOL_LUAJIT_USE_EXCEPTION_TRAMPOLINE)
#if (SOL_LUAJIT_USE_EXCEPTION_TRAMPOLINE != 0)

View File

@ -105,29 +105,40 @@ namespace sol {
}
#endif // Safety
}
basic_coroutine(const basic_coroutine&) = default;
basic_coroutine(const basic_coroutine& other) = default;
basic_coroutine& operator=(const basic_coroutine&) = default;
basic_coroutine(basic_coroutine&&) = default;
basic_coroutine& operator=(basic_coroutine&&) = default;
basic_coroutine(const basic_function<base_t>& b)
basic_coroutine(basic_coroutine&& other) noexcept : base_t(std::move(other)), error_handler(this->lua_state(), std::move(other.error_handler)) {
}
basic_coroutine& operator=(basic_coroutine&& other) noexcept {
base_t::operator=(std::move(other));
// must change the state, since it could change on the coroutine type
error_handler.abandon();
error_handler = handler_t(this->lua_state(), std::move(other.error_handler));
return *this;
}
basic_coroutine(const basic_function<base_t>& b) noexcept
: basic_coroutine(b, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(b.lua_state())) {
}
basic_coroutine(basic_function<base_t>&& b)
basic_coroutine(basic_function<base_t>&& b) noexcept
: basic_coroutine(std::move(b), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(b.lua_state())) {
}
basic_coroutine(const basic_function<base_t>& b, handler_t eh) : base_t(b), error_handler(std::move(eh)) {
basic_coroutine(const basic_function<base_t>& b, handler_t eh) noexcept : base_t(b), error_handler(std::move(eh)) {
}
basic_coroutine(basic_function<base_t>&& b, handler_t eh) : base_t(std::move(b)), error_handler(std::move(eh)) {
basic_coroutine(basic_function<base_t>&& b, handler_t eh) noexcept : base_t(std::move(b)), error_handler(std::move(eh)) {
}
basic_coroutine(const stack_reference& r)
basic_coroutine(const stack_reference& r) noexcept
: basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
}
basic_coroutine(stack_reference&& r)
basic_coroutine(stack_reference&& r) noexcept
: basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
}
basic_coroutine(const stack_reference& r, handler_t eh) : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
basic_coroutine(const stack_reference& r, handler_t eh) noexcept : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
}
basic_coroutine(stack_reference&& r, handler_t eh) : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
basic_coroutine(stack_reference&& r, handler_t eh) noexcept : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
}
template <typename Super>
@ -144,7 +155,7 @@ namespace sol {
}
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_coroutine(lua_State* L, T&& r)
basic_coroutine(lua_State* L, T&& r) noexcept
: basic_coroutine(L, std::forward<T>(r), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>

View File

@ -47,7 +47,7 @@ namespace sol { namespace detail {
"`anonymous namespace'" } };
#if SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_)
#if SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_VCXX_CLANG_I_)
inline std::string ctti_get_type_name_from_sig(std::string name) {
// cardinal sins from MINGW
using namespace std;

View File

@ -38,8 +38,8 @@ namespace sol { namespace detail {
ebco(ebco&&) = default;
ebco& operator=(const ebco&) = default;
ebco& operator=(ebco&&) = default;
ebco(const T& v) : value_(v){};
ebco(T&& v) : value_(std::move(v)){};
ebco(const T& v) : value_(v) {};
ebco(T&& v) : value_(std::move(v)) {};
ebco& operator=(const T& v) {
value_ = v;
return *this;
@ -49,15 +49,16 @@ namespace sol { namespace detail {
return *this;
};
template <typename Arg, typename... Args,
typename = std::enable_if_t<!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T>>>
ebco(Arg&& arg, Args&&... args) : T(std::forward<Arg>(arg), std::forward<Args>(args)...){}
typename = std::enable_if_t<!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T>>>
ebco(Arg&& arg, Args&&... args) : value_(std::forward<Arg>(arg), std::forward<Args>(args)...) {
}
T& value() & {
return value_;
}
T const& value() const & {
T const& value() const& {
return value_;
}
@ -71,8 +72,8 @@ namespace sol { namespace detail {
ebco() = default;
ebco(const ebco&) = default;
ebco(ebco&&) = default;
ebco(const T& v) : T(v){};
ebco(T&& v) : T(std::move(v)){};
ebco(const T& v) : T(v) {};
ebco(T&& v) : T(std::move(v)) {};
template <typename Arg, typename... Args,
typename = std::enable_if_t<!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T>>>
@ -94,7 +95,7 @@ namespace sol { namespace detail {
return static_cast<T&>(*this);
}
T const& value() const & {
T const& value() const& {
return static_cast<T const&>(*this);
}
@ -110,7 +111,7 @@ namespace sol { namespace detail {
ebco() = default;
ebco(const ebco&) = default;
ebco(ebco&&) = default;
ebco(T& v) : ref(v){};
ebco(T& v) : ref(v) {};
ebco& operator=(const ebco&) = default;
ebco& operator=(ebco&&) = default;
@ -131,7 +132,7 @@ namespace sol { namespace detail {
ebco() = default;
ebco(const ebco&) = default;
ebco(ebco&&) = default;
ebco(T&& v) : ref(v){};
ebco(T&& v) : ref(v) {};
ebco& operator=(const ebco&) = default;
ebco& operator=(ebco&&) = default;
@ -144,7 +145,7 @@ namespace sol { namespace detail {
return ref;
}
const T& value() const & {
const T& value() const& {
return ref;
}

View File

@ -359,7 +359,7 @@ namespace sol {
};
template <typename Signature>
struct unqualified_pusher<Signature, std::enable_if_t<std::is_member_pointer<Signature>::value>> {
struct unqualified_pusher<Signature, std::enable_if_t<meta::is_member_object_or_function_v<Signature>>> {
template <typename... Args>
static int push(lua_State* L, Args&&... args) {
function_detail::select<false>(L, std::forward<Args>(args)...);

View File

@ -31,8 +31,8 @@
namespace sol {
namespace detail {
struct no_prop {};
}
struct no_prop { };
} // namespace detail
template <typename R, typename W>
struct property_wrapper : detail::ebco<R, 0>, detail::ebco<W, 1> {
@ -42,8 +42,7 @@ namespace sol {
public:
template <typename Rx, typename Wx>
property_wrapper(Rx&& r, Wx&& w)
: read_base_t(std::forward<Rx>(r)), write_base_t(std::forward<Wx>(w)) {
property_wrapper(Rx&& r, Wx&& w) : read_base_t(std::forward<Rx>(r)), write_base_t(std::forward<Wx>(w)) {
}
W& write() {
@ -135,13 +134,16 @@ namespace sol {
namespace meta {
template <typename T>
struct is_member_object : std::is_member_object_pointer<T> {};
template <typename T>
struct is_member_object<readonly_wrapper<T>> : std::true_type {};
using is_member_object = std::integral_constant<bool, std::is_member_object_pointer_v<T> || is_specialization_of_v<T, readonly_wrapper>>;
template <typename T>
inline constexpr bool is_member_object_v = is_member_object<T>::value;
template <typename T>
using is_member_object_or_function = std::integral_constant<bool, is_member_object_v<T> || std::is_member_pointer_v<T>>;
template <typename T>
inline constexpr bool is_member_object_or_function_v = is_member_object_or_function<T>::value;
} // namespace meta
} // namespace sol

View File

@ -40,7 +40,8 @@ namespace sol {
namespace detail {
template <bool b, typename handler_t>
inline void handle_protected_exception(lua_State* L, optional<const std::exception&> maybe_ex, const char* error, detail::protected_handler<b, handler_t>& h) {
inline void handle_protected_exception(
lua_State* L, optional<const std::exception&> maybe_ex, const char* error, detail::protected_handler<b, handler_t>& h) {
h.stackindex = 0;
if (b) {
h.target.push();
@ -51,7 +52,7 @@ namespace sol {
detail::call_exception_handler(L, maybe_ex, error);
}
}
}
} // namespace detail
template <typename ref_t, bool aligned = false, typename handler_t = reference>
class basic_protected_function : public basic_object<ref_t> {
@ -100,17 +101,14 @@ namespace sol {
int firstreturn = 1;
int returncount = 0;
call_status code = call_status::ok;
#if !defined(SOL_NO_EXCEPTIONS) || !SOL_NO_EXCEPTIONS
#if (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !SOL_NO_EXCEPTIONS_SAFE_PROPAGATION) || (defined(SOL_LUAJIT) && SOL_LUAJIT)
#if SOL_IS_ON(SOL_EXCEPTIONS_I_) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_)
try {
#endif // Safe Exception Propagation
#endif // No Exceptions
firstreturn = (std::max)(1, static_cast<int>(stacksize - n - static_cast<int>(h.valid() && !is_stack_handler::value)));
code = luacall(n, LUA_MULTRET, h);
poststacksize = lua_gettop(lua_state()) - static_cast<int>(h.valid() && !is_stack_handler::value);
returncount = poststacksize - (firstreturn - 1);
#ifndef SOL_NO_EXCEPTIONS
#if (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !SOL_NO_EXCEPTIONS_SAFE_PROPAGATION) || (defined(SOL_LUAJIT) && SOL_LUAJIT)
#if SOL_IS_ON(SOL_EXCEPTIONS_I_) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_)
}
// Handle C++ errors thrown from C++ functions bound inside of lua
catch (const char* error) {
@ -128,7 +126,7 @@ namespace sol {
firstreturn = lua_gettop(lua_state());
return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
}
#if (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !SOL_NO_EXCEPTIONS_SAFE_PROPAGATION)
#if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL_I_)
// LuaJIT cannot have the catchall when the safe propagation is on
// but LuaJIT will swallow all C++ errors
// if we don't at least catch std::exception ones
@ -137,10 +135,9 @@ namespace sol {
firstreturn = lua_gettop(lua_state());
return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
}
#endif // LuaJIT
#endif // Always catch edge case
#else
// do not handle exceptions: they can be propogated into C++ and keep all type information / rich information
#endif // Safe Exception Propagation
#endif // Exceptions vs. No Exceptions
return protected_function_result(lua_state(), firstreturn, returncount, returncount, code);
}
@ -151,13 +148,15 @@ namespace sol {
handler_t error_handler;
basic_protected_function() = default;
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_protected_function>>, meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>, meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_protected_function(T&& r) noexcept
: base_t(std::forward<T>(r)), error_handler(get_default_handler(r.lua_state())) {
template <typename T,
meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_protected_function>>,
meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_protected_function(T&& r) noexcept : base_t(std::forward<T>(r)), error_handler(get_default_handler(r.lua_state())) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler{};
constructor_handler handler {};
stack::check<basic_protected_function>(lua_state(), -1, handler);
}
#endif // Safety
@ -166,100 +165,79 @@ namespace sol {
basic_protected_function& operator=(const basic_protected_function&) = default;
basic_protected_function(basic_protected_function&&) = default;
basic_protected_function& operator=(basic_protected_function&&) = default;
basic_protected_function(const basic_function<base_t>& b)
: basic_protected_function(b, get_default_handler(b.lua_state())) {
basic_protected_function(const basic_function<base_t>& b) : basic_protected_function(b, get_default_handler(b.lua_state())) {
}
basic_protected_function(basic_function<base_t>&& b)
: basic_protected_function(std::move(b), get_default_handler(b.lua_state())) {
basic_protected_function(basic_function<base_t>&& b) : basic_protected_function(std::move(b), get_default_handler(b.lua_state())) {
}
basic_protected_function(const basic_function<base_t>& b, handler_t eh)
: base_t(b), error_handler(std::move(eh)) {
basic_protected_function(const basic_function<base_t>& b, handler_t eh) : base_t(b), error_handler(std::move(eh)) {
}
basic_protected_function(basic_function<base_t>&& b, handler_t eh)
: base_t(std::move(b)), error_handler(std::move(eh)) {
basic_protected_function(basic_function<base_t>&& b, handler_t eh) : base_t(std::move(b)), error_handler(std::move(eh)) {
}
basic_protected_function(const stack_reference& r)
: basic_protected_function(r.lua_state(), r.stack_index(), get_default_handler(r.lua_state())) {
basic_protected_function(const stack_reference& r) : basic_protected_function(r.lua_state(), r.stack_index(), get_default_handler(r.lua_state())) {
}
basic_protected_function(stack_reference&& r)
: basic_protected_function(r.lua_state(), r.stack_index(), get_default_handler(r.lua_state())) {
basic_protected_function(stack_reference&& r) : basic_protected_function(r.lua_state(), r.stack_index(), get_default_handler(r.lua_state())) {
}
basic_protected_function(const stack_reference& r, handler_t eh)
: basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {
basic_protected_function(const stack_reference& r, handler_t eh) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {
}
basic_protected_function(stack_reference&& r, handler_t eh)
: basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {
basic_protected_function(stack_reference&& r, handler_t eh) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {
}
template <typename Super>
basic_protected_function(const proxy_base<Super>& p)
: basic_protected_function(p, get_default_handler(p.lua_state())) {
basic_protected_function(const proxy_base<Super>& p) : basic_protected_function(p, get_default_handler(p.lua_state())) {
}
template <typename Super>
basic_protected_function(proxy_base<Super>&& p)
: basic_protected_function(std::move(p), get_default_handler(p.lua_state())) {
basic_protected_function(proxy_base<Super>&& p) : basic_protected_function(std::move(p), get_default_handler(p.lua_state())) {
}
template <typename Proxy, typename Handler, meta::enable<std::is_base_of<proxy_base_tag, meta::unqualified_t<Proxy>>, meta::neg<is_lua_index<meta::unqualified_t<Handler>>>> = meta::enabler>
basic_protected_function(Proxy&& p, Handler&& eh)
: basic_protected_function(detail::force_cast<base_t>(p), std::forward<Handler>(eh)) {
template <typename Proxy, typename Handler,
meta::enable<std::is_base_of<proxy_base_tag, meta::unqualified_t<Proxy>>, meta::neg<is_lua_index<meta::unqualified_t<Handler>>>> = meta::enabler>
basic_protected_function(Proxy&& p, Handler&& eh) : basic_protected_function(detail::force_cast<base_t>(p), std::forward<Handler>(eh)) {
}
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_protected_function(lua_State* L, T&& r)
: basic_protected_function(L, std::forward<T>(r), get_default_handler(L)) {
basic_protected_function(lua_State* L, T&& r) : basic_protected_function(L, std::forward<T>(r), get_default_handler(L)) {
}
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_protected_function(lua_State* L, T&& r, handler_t eh)
: base_t(L, std::forward<T>(r)), error_handler(std::move(eh)) {
basic_protected_function(lua_State* L, T&& r, handler_t eh) : base_t(L, std::forward<T>(r)), error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
auto pp = stack::push_pop(*this);
constructor_handler handler{};
constructor_handler handler {};
stack::check<basic_protected_function>(lua_state(), -1, handler);
#endif // Safety
}
basic_protected_function(lua_nil_t n)
: base_t(n), error_handler(n) {
basic_protected_function(lua_nil_t n) : base_t(n), error_handler(n) {
}
basic_protected_function(lua_State* L, int index = -1)
: basic_protected_function(L, index, get_default_handler(L)) {
basic_protected_function(lua_State* L, int index = -1) : basic_protected_function(L, index, get_default_handler(L)) {
}
basic_protected_function(lua_State* L, int index, handler_t eh)
: base_t(L, index), error_handler(std::move(eh)) {
basic_protected_function(lua_State* L, int index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
constructor_handler handler{};
constructor_handler handler {};
stack::check<basic_protected_function>(L, index, handler);
#endif // Safety
}
basic_protected_function(lua_State* L, absolute_index index)
: basic_protected_function(L, index, get_default_handler(L)) {
basic_protected_function(lua_State* L, absolute_index index) : basic_protected_function(L, index, get_default_handler(L)) {
}
basic_protected_function(lua_State* L, absolute_index index, handler_t eh)
: base_t(L, index), error_handler(std::move(eh)) {
basic_protected_function(lua_State* L, absolute_index index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
constructor_handler handler{};
constructor_handler handler {};
stack::check<basic_protected_function>(L, index, handler);
#endif // Safety
}
basic_protected_function(lua_State* L, raw_index index)
: basic_protected_function(L, index, get_default_handler(L)) {
basic_protected_function(lua_State* L, raw_index index) : basic_protected_function(L, index, get_default_handler(L)) {
}
basic_protected_function(lua_State* L, raw_index index, handler_t eh)
: base_t(L, index), error_handler(std::move(eh)) {
basic_protected_function(lua_State* L, raw_index index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
constructor_handler handler{};
constructor_handler handler {};
stack::check<basic_protected_function>(L, index, handler);
#endif // Safety
}
basic_protected_function(lua_State* L, ref_index index)
: basic_protected_function(L, index, get_default_handler(L)) {
basic_protected_function(lua_State* L, ref_index index) : basic_protected_function(L, index, get_default_handler(L)) {
}
basic_protected_function(lua_State* L, ref_index index, handler_t eh)
: base_t(L, index), error_handler(std::move(eh)) {
basic_protected_function(lua_State* L, ref_index index, handler_t eh) : base_t(L, index), error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
auto pp = stack::push_pop(*this);
constructor_handler handler{};
constructor_handler handler {};
stack::check<basic_protected_function>(lua_state(), -1, handler);
#endif // Safety
}

View File

@ -29,7 +29,7 @@
#include <sol/stack.hpp>
namespace sol {
struct proxy_base_tag {};
struct proxy_base_tag { };
namespace detail {
template <typename T>
@ -37,30 +37,35 @@ namespace sol {
std::tuple<meta::conditional_t<std::is_array_v<meta::unqualified_t<T>>, std::remove_reference_t<T>&, meta::unqualified_t<T>>>>;
}
#define SOL_PROXY_BASE_IMPL_MSVC_IS_TRASH_I_(Super) \
operator std::string() const { \
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this)); \
return super.template get<std::string>(); \
} \
\
template <typename T, meta::enable<meta::neg<meta::is_string_constructible<T>>, is_proxy_primitive<meta::unqualified_t<T>>> = meta::enabler> \
operator T() const { \
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this)); \
return super.template get<T>(); \
} \
\
template <typename T, meta::enable<meta::neg<meta::is_string_constructible<T>>, meta::neg<is_proxy_primitive<meta::unqualified_t<T>>>> = meta::enabler> \
operator T&() const { \
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this)); \
return super.template get<T&>(); \
} \
static_assert(true, "This is ridiculous and I hate MSVC.")
template <typename Super>
struct proxy_base : proxy_base_tag {
operator std::string() const {
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
return super.template get<std::string>();
}
template <typename T, meta::enable<meta::neg<meta::is_string_constructible<T>>, is_proxy_primitive<meta::unqualified_t<T>>> = meta::enabler>
operator T() const {
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
return super.template get<T>();
}
template <typename T, meta::enable<meta::neg<meta::is_string_constructible<T>>, meta::neg<is_proxy_primitive<meta::unqualified_t<T>>>> = meta::enabler>
operator T&() const {
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
return super.template get<T&>();
}
struct proxy_base : public proxy_base_tag {
lua_State* lua_state() const {
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
return super.lua_state();
}
SOL_PROXY_BASE_IMPL_MSVC_IS_TRASH_I_(Super);
};
} // namespace sol
#endif // SOL_PROXY_BASE_HPP

View File

@ -48,13 +48,12 @@ namespace sol {
template <typename F>
inline constexpr void resolve_f(std::false_type, F&&) {
static_assert(
meta::has_deducible_signature<F>::value, "Cannot use no-template-parameter call with an overloaded functor: specify the signature");
static_assert(meta::call_operator_deducible_v<F>, "Cannot use no-template-parameter call with an overloaded functor: specify the signature");
}
template <typename F, typename U = meta::unqualified_t<F>>
inline constexpr auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::has_deducible_signature<U>(), std::forward<F>(f))) {
return resolve_f(meta::has_deducible_signature<U> {}, std::forward<F>(f));
inline constexpr auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::call_operator_deducible<U>(), std::forward<F>(f))) {
return resolve_f(meta::call_operator_deducible<U> {}, std::forward<F>(f));
}
template <typename... Args, typename F, typename R = std::invoke_result_t<F&, Args...>>
@ -118,13 +117,12 @@ namespace sol {
template <typename F>
inline void resolve_f(std::false_type, F&&) {
static_assert(
meta::has_deducible_signature<F>::value, "Cannot use no-template-parameter call with an overloaded functor: specify the signature");
static_assert(meta::call_operator_deducible_v<F>, "Cannot use no-template-parameter call with an overloaded functor: specify the signature");
}
template <typename F, typename U = meta::unqualified_t<F>>
inline auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::has_deducible_signature<U>(), std::forward<F>(f))) {
return resolve_f(meta::has_deducible_signature<U> {}, std::forward<F>(f));
inline auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::call_operator_deducible<U>(), std::forward<F>(f))) {
return resolve_f(meta::call_operator_deducible<U> {}, std::forward<F>(f));
}
template <typename... Args, typename F, typename R = std::invoke_result_t<F&, Args...>>

View File

@ -57,7 +57,7 @@ namespace sol { namespace meta {
using unwrapped_t = typename unwrapped<T>::type;
template <typename T>
struct unwrap_unqualified : unwrapped<unqualified_t<T>> {};
struct unwrap_unqualified : unwrapped<unqualified_t<T>> { };
template <typename T>
using unwrap_unqualified_t = typename unwrap_unqualified<T>::type;
@ -79,16 +79,16 @@ namespace sol { namespace meta {
using remove_member_pointer_t = remove_member_pointer<T>;
template <typename T, typename...>
struct all_same : std::true_type {};
struct all_same : std::true_type { };
template <typename T, typename U, typename... Args>
struct all_same<T, U, Args...> : std::integral_constant<bool, std::is_same<T, U>::value && all_same<T, Args...>::value> {};
struct all_same<T, U, Args...> : std::integral_constant<bool, std::is_same<T, U>::value && all_same<T, Args...>::value> { };
template <typename T, typename...>
struct any_same : std::false_type {};
struct any_same : std::false_type { };
template <typename T, typename U, typename... Args>
struct any_same<T, U, Args...> : std::integral_constant<bool, std::is_same<T, U>::value || any_same<T, Args...>::value> {};
struct any_same<T, U, Args...> : std::integral_constant<bool, std::is_same<T, U>::value || any_same<T, Args...>::value> { };
template <typename T, typename... Args>
constexpr inline bool any_same_v = any_same<T, Args...>::value;
@ -106,16 +106,16 @@ namespace sol { namespace meta {
constexpr inline bool neg_v = neg<T>::value;
template <typename... Args>
struct all : boolean<true> {};
struct all : boolean<true> { };
template <typename T, typename... Args>
struct all<T, Args...> : std::conditional_t<T::value, all<Args...>, boolean<false>> {};
struct all<T, Args...> : std::conditional_t<T::value, all<Args...>, boolean<false>> { };
template <typename... Args>
struct any : boolean<false> {};
struct any : boolean<false> { };
template <typename T, typename... Args>
struct any<T, Args...> : std::conditional_t<T::value, boolean<true>, any<Args...>> {};
struct any<T, Args...> : std::conditional_t<T::value, boolean<true>, any<Args...>> { };
template <typename T, typename... Args>
constexpr inline bool all_v = all<T, Args...>::value;
@ -143,37 +143,37 @@ namespace sol { namespace meta {
using disable_any = std::enable_if_t<neg<any<Args...>>::value, enable_t>;
template <typename V, typename... Vs>
struct find_in_pack_v : boolean<false> {};
struct find_in_pack_v : boolean<false> { };
template <typename V, typename Vs1, typename... Vs>
struct find_in_pack_v<V, Vs1, Vs...> : any<boolean<(V::value == Vs1::value)>, find_in_pack_v<V, Vs...>> {};
struct find_in_pack_v<V, Vs1, Vs...> : any<boolean<(V::value == Vs1::value)>, find_in_pack_v<V, Vs...>> { };
namespace meta_detail {
template <std::size_t I, typename T, typename... Args>
struct index_in_pack : std::integral_constant<std::size_t, SIZE_MAX> {};
struct index_in_pack : std::integral_constant<std::size_t, SIZE_MAX> { };
template <std::size_t I, typename T, typename T1, typename... Args>
struct index_in_pack<I, T, T1, Args...>
: conditional_t<std::is_same<T, T1>::value, std::integral_constant<std::ptrdiff_t, I>, index_in_pack<I + 1, T, Args...>> {};
: conditional_t<std::is_same<T, T1>::value, std::integral_constant<std::ptrdiff_t, I>, index_in_pack<I + 1, T, Args...>> { };
} // namespace meta_detail
template <typename T, typename... Args>
struct index_in_pack : meta_detail::index_in_pack<0, T, Args...> {};
struct index_in_pack : meta_detail::index_in_pack<0, T, Args...> { };
template <typename T, typename List>
struct index_in : meta_detail::index_in_pack<0, T, List> {};
struct index_in : meta_detail::index_in_pack<0, T, List> { };
template <typename T, typename... Args>
struct index_in<T, types<Args...>> : meta_detail::index_in_pack<0, T, Args...> {};
struct index_in<T, types<Args...>> : meta_detail::index_in_pack<0, T, Args...> { };
template <std::size_t I, typename... Args>
struct at_in_pack {};
struct at_in_pack { };
template <std::size_t I, typename... Args>
using at_in_pack_t = typename at_in_pack<I, Args...>::type;
template <std::size_t I, typename Arg, typename... Args>
struct at_in_pack<I, Arg, Args...> : std::conditional<I == 0, Arg, at_in_pack_t<I - 1, Args...>> {};
struct at_in_pack<I, Arg, Args...> : std::conditional<I == 0, Arg, at_in_pack_t<I - 1, Args...>> { };
template <typename Arg, typename... Args>
struct at_in_pack<0, Arg, Args...> {
@ -191,17 +191,17 @@ namespace sol { namespace meta {
using on_always = std::true_type;
template <template <typename...> class When, std::size_t Limit, std::size_t I, template <typename...> class Pred, typename... Ts>
struct count_when_for_pack : std::integral_constant<std::size_t, 0> {};
struct count_when_for_pack : std::integral_constant<std::size_t, 0> { };
template <template <typename...> class When, std::size_t Limit, std::size_t I, template <typename...> class Pred, typename T, typename... Ts>
struct count_when_for_pack<When, Limit, I, Pred, T, Ts...> : conditional_t < sizeof...(Ts)
== 0
|| Limit<2, std::integral_constant<std::size_t, I + static_cast<std::size_t>(Limit != 0 && Pred<T>::value)>,
count_when_for_pack<When, Limit - static_cast<std::size_t>(When<T, std::integral_constant<std::size_t, I>>::value),
I + static_cast<std::size_t>(When<T, std::integral_constant<std::size_t, I>>::value&& Pred<T>::value), Pred, Ts...>> {};
I + static_cast<std::size_t>(When<T, std::integral_constant<std::size_t, I>>::value&& Pred<T>::value), Pred, Ts...>> { };
} // namespace meta_detail
template <template <typename...> class Pred, typename... Ts>
struct count_for_pack : meta_detail::count_when_for_pack<meta_detail::on_always, sizeof...(Ts), 0, Pred, Ts...> {};
struct count_for_pack : meta_detail::count_when_for_pack<meta_detail::on_always, sizeof...(Ts), 0, Pred, Ts...> { };
template <template <typename...> class Pred, typename... Ts>
inline constexpr std::size_t count_for_pack_v = count_for_pack<Pred, Ts...>::value;
@ -210,16 +210,16 @@ namespace sol { namespace meta {
struct count_for;
template <template <typename...> class Pred, typename... Args>
struct count_for<Pred, types<Args...>> : count_for_pack<Pred, Args...> {};
struct count_for<Pred, types<Args...>> : count_for_pack<Pred, Args...> { };
template <std::size_t Limit, template <typename...> class Pred, typename... Ts>
struct count_for_to_pack : meta_detail::count_when_for_pack<meta_detail::on_always, Limit, 0, Pred, Ts...> {};
struct count_for_to_pack : meta_detail::count_when_for_pack<meta_detail::on_always, Limit, 0, Pred, Ts...> { };
template <std::size_t Limit, template <typename...> class Pred, typename... Ts>
inline constexpr std::size_t count_for_to_pack_v = count_for_to_pack<Limit, Pred, Ts...>::value;
template <template <typename...> class When, std::size_t Limit, template <typename...> class Pred, typename... Ts>
struct count_when_for_to_pack : meta_detail::count_when_for_pack<When, Limit, 0, Pred, Ts...> {};
struct count_when_for_to_pack : meta_detail::count_when_for_pack<When, Limit, 0, Pred, Ts...> { };
template <template <typename...> class When, std::size_t Limit, template <typename...> class Pred, typename... Ts>
inline constexpr std::size_t count_when_for_to_pack_v = count_when_for_to_pack<When, Limit, Pred, Ts...>::value;
@ -256,7 +256,7 @@ namespace sol { namespace meta {
namespace meta_detail {
template <typename>
struct always_true : std::true_type {};
struct always_true : std::true_type { };
struct is_invokable_tester {
template <typename Fun, typename... Args>
static always_true<decltype(std::declval<Fun>()(std::declval<Args>()...))> test(int);
@ -268,17 +268,17 @@ namespace sol { namespace meta {
template <typename T>
struct is_invokable;
template <typename Fun, typename... Args>
struct is_invokable<Fun(Args...)> : decltype(meta_detail::is_invokable_tester::test<Fun, Args...>(0)) {};
struct is_invokable<Fun(Args...)> : decltype(meta_detail::is_invokable_tester::test<Fun, Args...>(0)) { };
namespace meta_detail {
template <typename T, typename = void>
struct is_callable : std::is_function<std::remove_pointer_t<T>> {};
struct is_callable : std::is_function<std::remove_pointer_t<T>> { };
template <typename T>
struct is_callable<T,
std::enable_if_t<std::is_final<unqualified_t<T>>::value && std::is_class<unqualified_t<T>>::value
&& std::is_same<decltype(void(&T::operator())), void>::value>> {};
&& std::is_same<decltype(void(&T::operator())), void>::value>> { };
template <typename T>
struct is_callable<T,
@ -287,7 +287,7 @@ namespace sol { namespace meta {
struct F {
void operator()() {};
};
struct Derived : T, F {};
struct Derived : T, F { };
template <typename U, U>
struct Check;
@ -463,62 +463,62 @@ namespace sol { namespace meta {
};
template <typename T, typename U, typename = void>
class supports_op_less_test : public std::false_type {};
class supports_op_less_test : public std::false_type { };
template <typename T, typename U>
class supports_op_less_test<T, U, void_t<decltype(std::declval<T&>() < std::declval<U&>())>>
: public std::integral_constant<bool,
!is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>> {};
!is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>> { };
template <typename T, typename U, typename = void>
class supports_op_equal_test : public std::false_type {};
class supports_op_equal_test : public std::false_type { };
template <typename T, typename U>
class supports_op_equal_test<T, U, void_t<decltype(std::declval<T&>() == std::declval<U&>())>>
: public std::integral_constant<bool,
!is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>> {};
!is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>> { };
template <typename T, typename U, typename = void>
class supports_op_less_equal_test : public std::false_type {};
class supports_op_less_equal_test : public std::false_type { };
template <typename T, typename U>
class supports_op_less_equal_test<T, U, void_t<decltype(std::declval<T&>() <= std::declval<U&>())>>
: public std::integral_constant<bool,
!is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>> {};
!is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>> { };
template <typename T, typename U, typename = void>
class supports_op_left_shift_test : public std::false_type {};
class supports_op_left_shift_test : public std::false_type { };
template <typename T, typename U>
class supports_op_left_shift_test<T, U, void_t<decltype(std::declval<T&>() << std::declval<U&>())>> : public std::true_type {};
class supports_op_left_shift_test<T, U, void_t<decltype(std::declval<T&>() << std::declval<U&>())>> : public std::true_type { };
template <typename T, typename = void>
class supports_adl_to_string_test : public std::false_type {};
class supports_adl_to_string_test : public std::false_type { };
template <typename T>
class supports_adl_to_string_test<T, void_t<decltype(to_string(std::declval<const T&>()))>> : public std::true_type {};
class supports_adl_to_string_test<T, void_t<decltype(to_string(std::declval<const T&>()))>> : public std::true_type { };
template <typename T, bool b>
struct is_matched_lookup_impl : std::false_type {};
struct is_matched_lookup_impl : std::false_type { };
template <typename T>
struct is_matched_lookup_impl<T, true> : std::is_same<typename T::key_type, typename T::value_type> {};
struct is_matched_lookup_impl<T, true> : std::is_same<typename T::key_type, typename T::value_type> { };
template <typename T>
using non_void_t = meta::conditional_t<std::is_void_v<T>, ::sol::detail::unchecked_t, T>;
} // namespace meta_detail
template <typename T, typename U = T>
class supports_op_less : public meta_detail::supports_op_less_test<T, U> {};
class supports_op_less : public meta_detail::supports_op_less_test<T, U> { };
template <typename T, typename U = T>
class supports_op_equal : public meta_detail::supports_op_equal_test<T, U> {};
class supports_op_equal : public meta_detail::supports_op_equal_test<T, U> { };
template <typename T, typename U = T>
class supports_op_less_equal : public meta_detail::supports_op_less_equal_test<T, U> {};
class supports_op_less_equal : public meta_detail::supports_op_less_equal_test<T, U> { };
template <typename T, typename U = T>
class supports_op_left_shift : public meta_detail::supports_op_left_shift_test<T, U> {};
class supports_op_left_shift : public meta_detail::supports_op_left_shift_test<T, U> { };
template <typename T>
class supports_adl_to_string : public meta_detail::supports_adl_to_string_test<T> {};
class supports_adl_to_string : public meta_detail::supports_adl_to_string_test<T> { };
template <typename T>
class supports_to_string_member : public meta::boolean<meta_detail::has_to_string_test<meta_detail::non_void_t<T>>::value> {};
class supports_to_string_member : public meta::boolean<meta_detail::has_to_string_test<meta_detail::non_void_t<T>>::value> { };
template <typename T>
using is_callable = boolean<meta_detail::is_callable<T>::value>;
@ -527,31 +527,31 @@ namespace sol { namespace meta {
constexpr inline bool is_callable_v = is_callable<T>::value;
template <typename T>
struct has_begin_end : decltype(meta_detail::has_begin_end_impl::test<T>(0)) {};
struct has_begin_end : decltype(meta_detail::has_begin_end_impl::test<T>(0)) { };
template <typename T>
constexpr inline bool has_begin_end_v = has_begin_end<T>::value;
template <typename T>
struct has_key_value_pair : decltype(meta_detail::has_key_value_pair_impl::test<T>(0)) {};
struct has_key_value_pair : decltype(meta_detail::has_key_value_pair_impl::test<T>(0)) { };
template <typename T>
struct has_key_type : decltype(meta_detail::has_key_type_impl::test<T>(0)) {};
struct has_key_type : decltype(meta_detail::has_key_type_impl::test<T>(0)) { };
template <typename T>
struct has_key_comp : decltype(meta_detail::has_key_comp_impl::test<T>(0)) {};
struct has_key_comp : decltype(meta_detail::has_key_comp_impl::test<T>(0)) { };
template <typename T>
struct has_load_factor : decltype(meta_detail::has_load_factor_impl::test<T>(0)) {};
struct has_load_factor : decltype(meta_detail::has_load_factor_impl::test<T>(0)) { };
template <typename T>
struct has_mapped_type : decltype(meta_detail::has_mapped_type_impl::test<T>(0)) {};
struct has_mapped_type : decltype(meta_detail::has_mapped_type_impl::test<T>(0)) { };
template <typename T>
struct has_iterator : decltype(meta_detail::has_iterator_impl::test<T>(0)) {};
struct has_iterator : decltype(meta_detail::has_iterator_impl::test<T>(0)) { };
template <typename T>
struct has_value_type : decltype(meta_detail::has_value_type_impl::test<T>(0)) {};
struct has_value_type : decltype(meta_detail::has_value_type_impl::test<T>(0)) { };
template <typename T>
using has_push_back = meta::boolean<meta_detail::has_push_back_test<T>::value>;
@ -599,19 +599,19 @@ namespace sol { namespace meta {
constexpr inline bool is_string_literal_array_v = is_string_literal_array<T>::value;
template <typename T, typename CharT>
struct is_string_of : std::false_type {};
struct is_string_of : std::false_type { };
template <typename CharT, typename CharTargetT, typename TraitsT, typename AllocT>
struct is_string_of<std::basic_string<CharT, TraitsT, AllocT>, CharTargetT> : std::is_same<CharT, CharTargetT> {};
struct is_string_of<std::basic_string<CharT, TraitsT, AllocT>, CharTargetT> : std::is_same<CharT, CharTargetT> { };
template <typename T, typename CharT>
constexpr inline bool is_string_of_v = is_string_of<T, CharT>::value;
template <typename T, typename CharT>
struct is_string_view_of : std::false_type {};
struct is_string_view_of : std::false_type { };
template <typename CharT, typename CharTargetT, typename TraitsT>
struct is_string_view_of<std::basic_string_view<CharT, TraitsT>, CharTargetT> : std::is_same<CharT, CharTargetT> {};
struct is_string_view_of<std::basic_string_view<CharT, TraitsT>, CharTargetT> : std::is_same<CharT, CharTargetT> { };
template <typename T, typename CharT>
constexpr inline bool is_string_view_of_v = is_string_view_of<T, CharT>::value;
@ -635,10 +635,10 @@ namespace sol { namespace meta {
using is_string_like_or_constructible = meta::boolean<is_string_like_v<T> || is_string_constructible_v<T>>;
template <typename T>
struct is_pair : std::false_type {};
struct is_pair : std::false_type { };
template <typename T1, typename T2>
struct is_pair<std::pair<T1, T2>> : std::true_type {};
struct is_pair<std::pair<T1, T2>> : std::true_type { };
template <typename T, typename Char>
using is_c_str_of = any<std::is_same<T, const Char*>, std::is_same<T, Char const* const>, std::is_same<T, Char*>, is_string_of<T, Char>,
@ -654,7 +654,7 @@ namespace sol { namespace meta {
constexpr inline bool is_c_str_v = is_c_str<T>::value;
template <typename T>
struct is_move_only : all<neg<std::is_reference<T>>, neg<std::is_copy_constructible<unqualified_t<T>>>, std::is_move_constructible<unqualified_t<T>>> {};
struct is_move_only : all<neg<std::is_reference<T>>, neg<std::is_copy_constructible<unqualified_t<T>>>, std::is_move_constructible<unqualified_t<T>>> { };
template <typename T>
using is_not_move_only = neg<is_move_only<T>>;

View File

@ -103,7 +103,6 @@ namespace sol {
inline int lua_cfunction_trampoline(lua_State* L, lua_CFunction f) {
#if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS_I_)
return f(L);
#else
try {
return f(L);
@ -117,7 +116,7 @@ namespace sol {
catch (const std::exception& e) {
call_exception_handler(L, optional<const std::exception&>(e), e.what());
}
#if SOL_IS_OFF(SOL_USE_LUAJIT_I_)
#if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL_I_)
// LuaJIT cannot have the catchall when the safe propagation is on
// but LuaJIT will swallow all C++ errors
// if we don't at least catch std::exception ones
@ -167,7 +166,7 @@ namespace sol {
catch (const std::exception& e) {
call_exception_handler(L, optional<const std::exception&>(e), e.what());
}
#if SOL_IS_OFF(SOL_USE_LUAJIT_I_)
#if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL_I_)
// LuaJIT cannot have the catchall when the safe propagation is on
// but LuaJIT will swallow all C++ errors
// if we don't at least catch std::exception ones

View File

@ -153,13 +153,13 @@ namespace sol {
}
}
if (fx(meta_function::to_string)) {
if constexpr (is_to_stringable<T>::value) {
if constexpr (is_to_stringable<T>::value && !meta::is_probably_stateless_lambda_v<T> && !std::is_member_pointer_v<T>) {
auto f = &detail::static_trampoline<&default_to_string<T>>;
ifx(meta_function::to_string, f);
}
}
if (fx(meta_function::call_function)) {
if constexpr (meta::has_deducible_signature<T>::value) {
if constexpr (meta::call_operator_deducible_v<T>) {
auto f = &c_call<decltype(&T::operator()), &T::operator()>;
ifx(meta_function::call_function, f);
}
@ -177,12 +177,12 @@ namespace sol {
t.push();
detail::lua_reg_table l{};
detail::lua_reg_table l {};
int index = 0;
detail::indexed_insert insert_fx(l, index);
detail::insert_default_registrations<T>(insert_fx, detail::property_always_true);
if constexpr (!std::is_pointer_v<X>) {
l[index] = luaL_Reg{ to_string(meta_function::garbage_collect).c_str(), detail::make_destructor<T>() };
l[index] = luaL_Reg { to_string(meta_function::garbage_collect).c_str(), detail::make_destructor<T>() };
}
luaL_setfuncs(L, l, 0);

View File

@ -47,25 +47,38 @@
#define SOL_DEFAULT_OFF -
#if defined(_MSC_VER)
#define SOL_COMPILER_CLANG_I_ SOL_OFF
#define SOL_COMPILER_GCC_I_ SOL_OFF
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_ON
#if defined(__clang__)
#define SOL_COMPILER_CLANG_I_ SOL_OFF
#define SOL_COMPILER_GCC_I_ SOL_OFF
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_ON
#define SOL_COMPILER_VCXX_CLANG_I_ SOL_ON
#else
#define SOL_COMPILER_VCXX_CLANG_I_ SOL_OFF
#define SOL_COMPILER_CLANG_I_ SOL_OFF
#define SOL_COMPILER_GCC_I_ SOL_OFF
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_ON
#define SOL_COMPILER_VCXX_CLANG_I_ SOL_OFF
#endif
#elif defined(__clang__)
#define SOL_COMPILER_CLANG_I_ SOL_ON
#define SOL_COMPILER_GCC_I_ SOL_OFF
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_OFF
#define SOL_COMPILER_VCXX_CLANG_I_ SOL_OFF
#elif defined(__GNUC__)
#define SOL_COMPILER_CLANG_I_ SOL_OFF
#define SOL_COMPILER_GCC_I_ SOL_ON
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_OFF
#define SOL_COMPILER_VCXX_CLANG_I_ SOL_OFF
#else
#define SOL_COMPILER_CLANG_I_ SOL_OFF
#define SOL_COMPILER_GCC_I_ SOL_OFF
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_OFF
#define SOL_COMPILER_VCXX_CLANG_I_ SOL_OFF
#endif
#if defined(__MINGW32__)

View File

@ -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 2020-11-02 10:53:05.003420 UTC
// This header was generated with sol v3.2.3 (revision 63e396b9)
// Generated 2020-11-19 20:04:06.393002 UTC
// This header was generated with sol v3.2.3 (revision b8aa189e)
// https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_CONFIG_HPP

View File

@ -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 2020-11-02 10:53:04.990407 UTC
// This header was generated with sol v3.2.3 (revision 63e396b9)
// Generated 2020-11-19 20:04:06.378005 UTC
// This header was generated with sol v3.2.3 (revision b8aa189e)
// https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP
@ -55,25 +55,38 @@
#define SOL_DEFAULT_OFF -
#if defined(_MSC_VER)
#define SOL_COMPILER_CLANG_I_ SOL_OFF
#define SOL_COMPILER_GCC_I_ SOL_OFF
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_ON
#if defined(__clang__)
#define SOL_COMPILER_CLANG_I_ SOL_OFF
#define SOL_COMPILER_GCC_I_ SOL_OFF
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_ON
#define SOL_COMPILER_VCXX_CLANG_I_ SOL_ON
#else
#define SOL_COMPILER_VCXX_CLANG_I_ SOL_OFF
#define SOL_COMPILER_CLANG_I_ SOL_OFF
#define SOL_COMPILER_GCC_I_ SOL_OFF
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_ON
#define SOL_COMPILER_VCXX_CLANG_I_ SOL_OFF
#endif
#elif defined(__clang__)
#define SOL_COMPILER_CLANG_I_ SOL_ON
#define SOL_COMPILER_GCC_I_ SOL_OFF
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_OFF
#define SOL_COMPILER_VCXX_CLANG_I_ SOL_OFF
#elif defined(__GNUC__)
#define SOL_COMPILER_CLANG_I_ SOL_OFF
#define SOL_COMPILER_GCC_I_ SOL_ON
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_OFF
#define SOL_COMPILER_VCXX_CLANG_I_ SOL_OFF
#else
#define SOL_COMPILER_CLANG_I_ SOL_OFF
#define SOL_COMPILER_GCC_I_ SOL_OFF
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_OFF
#define SOL_COMPILER_VCXX_CLANG_I_ SOL_OFF
#endif
#if defined(__MINGW32__)

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="sol::optional&lt;*&gt;">
<DisplayString Condition="init_ == false">empty</DisplayString>
<DisplayString>{*((value_type*)(&amp;storage_[0]))}</DisplayString>
<DisplayString Condition="m_has_value == false">empty</DisplayString>
<DisplayString Condition="m_has_value == true">{m_value}</DisplayString>
<Expand>
<Item Name="value" Condition="init_ == true">*((value_type*)(&amp;storage_[0]))</Item>
<Item Name="value" Condition="m_has_value == true">m_value</Item>
</Expand>
</Type>
<Type Name="sol::basic_reference&lt;*&gt;">
@ -21,4 +21,35 @@
<Item Name="state">luastate</Item>
</Expand>
</Type>
<Type Name="sol::basic_coroutine&lt;*&gt;">
<DisplayString>ref={this->ref} status={stats} error_handler={error_handler}</DisplayString>
<Expand>
<Item Name="status">stats</Item>
<Item Name="error_handler">error_handler</Item>
<Item Name="reference">*($T1*)this</Item>
</Expand>
</Type>
<Type Name="sol::basic_protected_function&lt;*&gt;">
<DisplayString>status={stats} error_handler={error_handler} index={index} state={luastate}</DisplayString>
<Expand>
<Item Name="error_handler">error_handler</Item>
<Item Name="reference">*($T1*)this</Item>
</Expand>
</Type>
<Type Name="sol::state_view">
<DisplayString>L={L} globals={global} registry={reg}</DisplayString>
<Expand>
<Item Name="globals">global</Item>
<Item Name="registry">reg</Item>
<Item Name="state">L</Item>
</Expand>
</Type>
<Type Name="sol::state">
<DisplayString>L={L} globals={global} registry={reg}</DisplayString>
<Expand>
<Item Name="globals">global</Item>
<Item Name="registry">reg</Item>
<Item Name="state">L</Item>
</Expand>
</Type>
</AutoVisualizer>

View File

@ -39,11 +39,15 @@ function(CREATE_TEST test_target_name test_name target_sol)
EXPORT_NAME sol2::${test_name})
target_link_libraries(${test_target_name}
PUBLIC Threads::Threads ${LUA_LIBRARIES} ${CATCH_LIBRARIES} ${target_sol})
target_compile_definitions(${test_target_name}
PUBLIC SOL_ALL_SAFETIES_ON=1 SOL_PRINT_ERRORS=1 SOL_ENABLE_INTEROP=1)
if (MSVC)
if (NOT CMAKE_COMPILER_ID MATCHES "Clang")
target_compile_options(${test_target_name}
PRIVATE /bigobj /W4)
PRIVATE /bigobj /W4 /w44800)
else()
target_compile_options(${test_target_name}
PRIVATE -ftemplate-backtrace-limit=0)
endif()
else()
target_compile_options(${test_target_name}
@ -53,11 +57,8 @@ function(CREATE_TEST test_target_name test_name target_sol)
-Wno-noexcept-type)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# For another day, when C++ is not so crap
# and we have time to audit the entire lib
# for all uses of `detail::swallow`...
#target_compile_options(${test_target_name}
# PRIVATE -Wcomma)
target_compile_options(${test_target_name}
PRIVATE -Wno-microsoft-cast)
endif()
if (IS_X86)

View File

@ -44,7 +44,7 @@ for i=1,#c do
assert(v == (i + 10))
end
)",
sol::script_pass_on_error);
sol::script_pass_on_error);
REQUIRE(r1.valid());
}
{
@ -120,9 +120,7 @@ end
int v1 = lua["v1"];
int v2 = lua["v2"];
int v3 = lua["v3"];
int values[6] = {
20, 13, 14, 16, 17, 18
};
int values[6] = { 20, 13, 14, 16, 17, 18 };
{
std::size_t idx = 0;
for (const auto& i : items) {
@ -154,7 +152,8 @@ for i=1,#c do
v = c[i]
assert(v == (i + 10))
end
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(r1.valid());
}
{
@ -228,9 +227,7 @@ end
int v1 = lua["v1"];
int v2 = lua["v2"];
int v3 = lua["v3"];
int values[] = {
11, 20, 13, 14, 18
};
int values[] = { 11, 20, 13, 14, 18 };
{
std::size_t idx = 0;
for (const auto& i : items) {
@ -258,7 +255,7 @@ TEST_CASE("containers/sequence containers", "check all of the functinos for ever
sol::stack_guard luasg(lua);
lua.open_libraries(sol::lib::base);
std::vector<int> items{ 11, 12, 13, 14, 15 };
std::vector<int> items { 11, 12, 13, 14, 15 };
lua["c"] = &items;
sequence_container_check(lua, items);
}
@ -267,7 +264,7 @@ TEST_CASE("containers/sequence containers", "check all of the functinos for ever
sol::stack_guard luasg(lua);
lua.open_libraries(sol::lib::base);
std::list<int> items{ 11, 12, 13, 14, 15 };
std::list<int> items { 11, 12, 13, 14, 15 };
lua["c"] = &items;
sequence_container_check(lua, items);
}
@ -276,7 +273,7 @@ TEST_CASE("containers/sequence containers", "check all of the functinos for ever
sol::stack_guard luasg(lua);
lua.open_libraries(sol::lib::base);
std::forward_list<int> items{ 11, 12, 13, 14, 15 };
std::forward_list<int> items { 11, 12, 13, 14, 15 };
lua["c"] = &items;
sequence_container_check(lua, items);
}
@ -285,7 +282,7 @@ TEST_CASE("containers/sequence containers", "check all of the functinos for ever
sol::stack_guard luasg(lua);
lua.open_libraries(sol::lib::base);
std::deque<int> items{ 11, 12, 13, 14, 15 };
std::deque<int> items { 11, 12, 13, 14, 15 };
lua["c"] = &items;
sequence_container_check(lua, items);
}
@ -297,7 +294,7 @@ TEST_CASE("containers/fixed containers", "check immutable container types") {
sol::stack_guard luasg(lua);
lua.open_libraries(sol::lib::base);
std::array<int, 5> items{ { 11, 12, 13, 14, 15 } };
std::array<int, 5> items { { 11, 12, 13, 14, 15 } };
lua["c"] = &items;
fixed_container_check(lua, items);
}
@ -306,7 +303,7 @@ TEST_CASE("containers/fixed containers", "check immutable container types") {
sol::stack_guard luasg(lua);
lua.open_libraries(sol::lib::base);
std::array<int, 5> items{ { 11, 12, 13, 14, 15 } };
std::array<int, 5> items { { 11, 12, 13, 14, 15 } };
lua["c"] = std::ref(items);
fixed_container_check(lua, items);
}
@ -352,7 +349,8 @@ function sf (x,v)
return x:find(v)
end
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(result1.valid());
// Have the function we
// just defined in Lua
@ -363,10 +361,10 @@ end
// Set a global variable called
// "arr" to be a vector of 5 lements
lua["c_arr"] = std::array<int, 5>{ { 2, 4, 6, 8, 10 } };
lua["arr"] = std::vector<int>{ 2, 4, 6, 8, 10 };
lua["map"] = std::map<int, int>{ { 1, 2 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, { 5, 10 } };
lua["set"] = std::set<int>{ 2, 4, 6, 8, 10 };
lua["c_arr"] = std::array<int, 5> { { 2, 4, 6, 8, 10 } };
lua["arr"] = std::vector<int> { 2, 4, 6, 8, 10 };
lua["map"] = std::map<int, int> { { 1, 2 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, { 5, 10 } };
lua["set"] = std::set<int> { 2, 4, 6, 8, 10 };
std::array<int, 5>& c_arr = lua["c_arr"];
std::vector<int>& arr = lua["arr"];
std::map<int, int>& map = lua["map"];
@ -396,7 +394,6 @@ end
sol::object rn = sf(map, 9);
REQUIRE(rn == sol::lua_nil);
}
i(lua["arr"]);
i(lua["map"]);
i(lua["set"]);
@ -408,7 +405,8 @@ end
c_arr[1] = 7
c_arr[2] = 7
c_arr[3] = 7
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(result2.valid());
}

View File

@ -53,7 +53,7 @@ inline namespace sol2_test_containers {
TEST_CASE("containers/returns", "make sure that even references to vectors are being serialized as tables") {
sol::state lua;
std::vector<int> v{ 1, 2, 3 };
std::vector<int> v { 1, 2, 3 };
returns_callable f(v);
lua.set_function("f", f);
auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error);
@ -76,7 +76,8 @@ TEST_CASE("containers/custom usertype", "make sure container usertype metatables
sol::state lua;
lua.open_libraries();
lua.new_usertype<bark>("bark",
lua.new_usertype<bark>(
"bark",
"something",
[](const bark& b) { INFO("It works: " << b.at(24)); },
"size",
@ -85,7 +86,7 @@ TEST_CASE("containers/custom usertype", "make sure container usertype metatables
sol::resolve<const int&>(&bark::at),
"clear",
&bark::clear);
bark obj{ { 24, 50 } };
bark obj { { 24, 50 } };
lua.set("a", &obj);
{
auto result0 = lua.safe_script("assert(a:at(24) == 50)", sol::script_pass_on_error);
@ -110,7 +111,7 @@ TEST_CASE("containers/const serialization kvp", "make sure const keys / values a
sol::state lua;
lua.open_libraries();
{
bark obj{ { 24, 50 } };
bark obj { { 24, 50 } };
lua.set("a", std::ref(obj));
auto result0 = lua.safe_script("assert(a[24] == 50)", sol::script_pass_on_error);
REQUIRE(result0.valid());
@ -125,12 +126,12 @@ TEST_CASE("containers/basic serialization", "make sure containers are turned int
typedef std::vector<int> woof;
sol::state lua;
lua.open_libraries();
lua.set("b", woof{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 });
lua.set("b", woof { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 });
{
auto result = lua.safe_script("for k = 1, #b do assert(k == b[k]) end", sol::script_pass_on_error);
REQUIRE(result.valid());
}
woof w{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };
woof w { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };
lua.set("b", w);
{
auto result = lua.safe_script("for k = 1, #b do assert(k == b[k]) end", sol::script_pass_on_error);
@ -208,7 +209,7 @@ TEST_CASE(
class A {
public:
int a;
A(int b = 2) : a(b){};
A(int b = 2) : a(b) {};
void func() {
}
@ -276,7 +277,7 @@ struct machine {
namespace sol {
template <>
struct is_container<options> : std::false_type {};
struct is_container<options> : std::false_type { };
} // namespace sol
TEST_CASE("containers/is container", "make sure the is_container trait behaves properly") {
@ -320,9 +321,8 @@ TEST_CASE("containers/readonly", "make sure readonly members are stored appropri
"seq",
&foo::seq, // this one works
"readonly_seq",
sol::readonly(&foo::seq) // this one does not work
);
lua["value"] = std::list<bar>{ {}, {}, {} };
sol::readonly(&foo::seq));
lua["value"] = std::list<bar> { {}, {}, {} };
auto result0 = lua.safe_script(R"(
a = foo.new()
@ -350,14 +350,14 @@ TEST_CASE("containers/to_args", "Test that the to_args abstractions works") {
sol::function f = lua["f"];
int a, b, c, d;
std::vector<int> v2{ 3, 4 };
std::vector<int> v2 { 3, 4 };
sol::tie(a, b, c, d) = f(1, 2, sol::as_args(v2));
REQUIRE(a == 1);
REQUIRE(b == 2);
REQUIRE(c == 3);
REQUIRE(d == 4);
std::set<int> v4{ 7, 6, 8, 5 };
std::set<int> v4 { 7, 6, 8, 5 };
sol::tie(a, b, c, d) = f(sol::as_args(v4));
REQUIRE(a == 5);
REQUIRE(b == 6);
@ -395,11 +395,11 @@ end
sol::script_pass_on_error);
REQUIRE(result1.valid());
std::vector<int> fill_cmp{ 1, 2, 3 };
std::vector<int> append_cmp{ -1, -1, -10456407, -54 };
std::vector<int> fill_cmp { 1, 2, 3 };
std::vector<int> append_cmp { -1, -1, -10456407, -54 };
std::vector<int> vec1{ -1, -1, -1 };
std::vector<int> vec2{ -1, -1, -1 };
std::vector<int> vec1 { -1, -1, -1 };
std::vector<int> vec2 { -1, -1, -1 };
REQUIRE(vec1.size() == 3);
lua["f_fill"](vec1);
@ -428,7 +428,7 @@ TEST_CASE("containers/non_copyable", "make sure non-copyable types in containers
sol::state lua;
lua.new_usertype<test>("test", "b", sol::readonly(&test::b));
lua["v"] = std::vector<non_copyable>{};
lua["v"] = std::vector<non_copyable> {};
auto pfr = lua.safe_script("t = test.new() t.b = v", sol::script_pass_on_error);
REQUIRE_FALSE(pfr.valid());
@ -443,9 +443,9 @@ TEST_CASE("containers/pairs", "test how well pairs work with the underlying syst
lua.open_libraries(sol::lib::base);
std::vector<std::pair<std::string, int>> a{ { "one", 1 }, { "two", 2 }, { "three", 3 }, { "four", 4 }, { "five", 5 } };
std::array<std::pair<std::string, int>, 5> b{ { { "one", 1 }, { "two", 2 }, { "three", 3 }, { "four", 4 }, { "five", 5 } } };
pair_arr_t c{ { "one", 1 }, { "two", 2 }, { "three", 3 }, { "four", 4 }, { "five", 5 } };
std::vector<std::pair<std::string, int>> a { { "one", 1 }, { "two", 2 }, { "three", 3 }, { "four", 4 }, { "five", 5 } };
std::array<std::pair<std::string, int>, 5> b { { { "one", 1 }, { "two", 2 }, { "three", 3 }, { "four", 4 }, { "five", 5 } } };
pair_arr_t c { { "one", 1 }, { "two", 2 }, { "three", 3 }, { "four", 4 }, { "five", 5 } };
arr_t d = { 1, 2, 3, 4, 5 };
lua["a"] = std::ref(a);

View File

@ -25,6 +25,8 @@
#include <catch.hpp>
#include <vector>
inline namespace sol2_test_coroutines {
struct coroutine_thread_runner_state {
sol::state_view* prunner_thread_state;
@ -56,70 +58,108 @@ inline namespace sol2_test_coroutines {
return r;
}
};
struct coroutine_storage {
coroutine_storage(sol::state& luaContext) {
mLuaState = &luaContext;
mThread = sol::thread::create(luaContext);
sol::state_view luaThreadState = mThread.state();
mThreadEnvironment = sol::environment(luaThreadState, sol::create, luaThreadState.globals());
sol::set_environment(mThreadEnvironment, mThread);
sol::optional<sol::table> actionTable = luaThreadState["aTable"];
if (actionTable) {
mThreadTick = actionTable.value()["Tick"];
}
}
coroutine_storage& operator=(coroutine_storage&& r) noexcept {
mThread = std::move(r.mThread);
mThreadEnvironment = std::move(r.mThreadEnvironment);
mThreadTick = std::move(r.mThreadTick);
return *this;
}
coroutine_storage(coroutine_storage&& r) noexcept
: mLuaState(std::move(r.mLuaState))
, mThread(std::move(r.mThread))
, mThreadEnvironment(std::move(r.mThreadEnvironment))
, mThreadTick(std::move(r.mThreadTick)) {
}
coroutine_storage& operator=(const coroutine_storage& r) = delete;
coroutine_storage(const coroutine_storage& r) = delete;
sol::state* mLuaState;
sol::thread mThread;
sol::environment mThreadEnvironment;
sol::coroutine mThreadTick;
};
struct coro_h {
int x = 500;
int func() {
x += 1;
return x;
}
};
struct coro_test {
std::string identifier;
sol::reference obj;
coro_test(sol::this_state L, std::string id) : identifier(id), obj(L, sol::lua_nil) {
}
void store(sol::table ref) {
// must be explicit
obj = sol::reference(obj.lua_state(), ref);
}
void copy_store(sol::table ref) {
// must be explicit
obj = sol::reference(obj.lua_state(), ref);
}
sol::reference get() {
return obj;
}
~coro_test() {
}
};
struct coro_test_implicit {
std::string identifier;
sol::main_reference obj;
coro_test_implicit(sol::this_state L, std::string id) : identifier(id), obj(L, sol::lua_nil) {
}
void store(sol::table ref) {
// main_reference does the state shift implicitly
obj = std::move(ref);
lua_State* Lmain = sol::main_thread(ref.lua_state());
REQUIRE(obj.lua_state() == Lmain);
}
void copy_store(sol::table ref) {
// main_reference does the state shift implicitly
obj = ref;
lua_State* Lmain = sol::main_thread(ref.lua_state());
REQUIRE(obj.lua_state() == Lmain);
}
sol::reference get() {
return obj;
}
~coro_test_implicit() {
}
};
} // namespace sol2_test_coroutines
struct coro_h {
int x = 500;
int func() {
x += 1;
return x;
}
};
struct coro_test {
std::string identifier;
sol::reference obj;
coro_test(sol::this_state L, std::string id) : identifier(id), obj(L, sol::lua_nil) {
}
void store(sol::table ref) {
// must be explicit
obj = sol::reference(obj.lua_state(), ref);
}
void copy_store(sol::table ref) {
// must be explicit
obj = sol::reference(obj.lua_state(), ref);
}
sol::reference get() {
return obj;
}
~coro_test() {
}
};
struct coro_test_implicit {
std::string identifier;
sol::main_reference obj;
coro_test_implicit(sol::this_state L, std::string id) : identifier(id), obj(L, sol::lua_nil) {
}
void store(sol::table ref) {
// main_reference does the state shift implicitly
obj = std::move(ref);
lua_State* Lmain = sol::main_thread(ref.lua_state());
REQUIRE(obj.lua_state() == Lmain);
}
void copy_store(sol::table ref) {
// main_reference does the state shift implicitly
obj = ref;
lua_State* Lmain = sol::main_thread(ref.lua_state());
REQUIRE(obj.lua_state() == Lmain);
}
sol::reference get() {
return obj;
}
~coro_test_implicit() {
}
};
TEST_CASE("coroutines/coroutine.yield", "ensure calling a coroutine works") {
const auto& script = R"(counter = 20
function loop()
@ -222,7 +262,7 @@ end
auto pfr = lua.safe_script(updatecode);
REQUIRE(pfr.valid());
sol::function update = pfr;
sol::function update = pfr.get<sol::function>();
update();
f3 = f2;
f3();
@ -581,7 +621,7 @@ TEST_CASE("coroutines/yielding", "test that a sol3 bound function can yield when
return i;
};
coro_h hobj{};
coro_h hobj {};
lua["f"] = sol::yielding(func);
lua["g"] = sol::yielding([]() { return 300; });
@ -661,3 +701,27 @@ TEST_CASE("coroutines/yielding", "test that a sol3 bound function can yield when
REQUIRE(hobj.x == 503);
}
}
TEST_CASE("coroutines/error_handler_state_transfer", "test that sol3 coroutines with their error handlers are properly sourced") {
sol::state lua;
lua.open_libraries(sol::lib::base, sol::lib::coroutine);
sol::optional<sol::error> maybe_result = lua.safe_script(R"(
aTable = {}
aTable["Tick"] = function()
coroutine.yield()
end
)");
REQUIRE_FALSE(maybe_result.has_value());
int begintop = 0, endtop = 0;
{
test_stack_guard g(lua.lua_state(), begintop, endtop);
std::vector<coroutine_storage> luaCoroutines;
luaCoroutines.emplace_back(lua);
luaCoroutines.emplace_back(lua);
luaCoroutines[0] = std::move(luaCoroutines.back());
luaCoroutines.pop_back();
}
}

View File

@ -139,7 +139,7 @@ int super_custom::exact_push_calls = 0;
int destroy_super_custom(lua_State* L) {
void* memory = lua_touserdata(L, 1);
super_custom* data = static_cast<super_custom*>(memory);
std::allocator<super_custom> alloc{};
std::allocator<super_custom> alloc {};
std::allocator_traits<std::allocator<super_custom>>::destroy(alloc, data);
return 0;
}
@ -183,9 +183,9 @@ int sol_lua_push(lua_State* L, const super_custom& c) {
void* ud = lua_newuserdata(L, sizeof(super_custom*) + sizeof(super_custom));
super_custom* tud = static_cast<super_custom*>(static_cast<void*>(static_cast<char*>(ud) + sizeof(super_custom*)));
*static_cast<super_custom**>(ud) = tud;
new(tud)super_custom(c);
new (tud) super_custom(c);
if (luaL_newmetatable(L, "super_custom!") == 1) {
luaL_Reg l[2]{};
luaL_Reg l[2] {};
l[0] = { sol::to_string(sol::meta_function::garbage_collect).c_str(), &destroy_super_custom };
luaL_setfuncs(L, l, 0);
}
@ -222,7 +222,7 @@ TEST_CASE("customization/adl", "using the ADL customization points in various si
custom::push_calls = 0;
custom::exact_push_calls = 0;
lua["meow"] = custom{ 25 };
lua["meow"] = custom { 25 };
custom meow = lua["meow"];
REQUIRE(meow.bweh == 25);
@ -241,8 +241,8 @@ TEST_CASE("customization/adl", "using the ADL customization points in various si
auto result = lua.safe_script("return function (a, b, c) return a, b, c end", sol::script_pass_on_error);
REQUIRE(result.valid());
sol::protected_function f = result;
multi_custom pass_through = f(multi_custom{ 22, false, "miao" });
sol::protected_function f = result.get<sol::protected_function>();
multi_custom pass_through = f(multi_custom { 22, false, "miao" });
REQUIRE(pass_through.bweh == 22);
REQUIRE_FALSE(pass_through.bwuh);
REQUIRE(pass_through.blah == "miao");
@ -261,7 +261,7 @@ TEST_CASE("customization/adl", "using the ADL customization points in various si
super_custom::pointer_push_calls = 0;
super_custom::exact_push_calls = 0;
super_custom meow_original{ 50 };
super_custom meow_original { 50 };
lua["meow"] = std::ref(meow_original);
super_custom& meow = lua["meow"];
super_custom* p_meow = lua["meow"];

View File

@ -43,7 +43,7 @@ TEST_CASE("dump/dump transfer", "test that a function can be transferred from on
sol::load_result lr = lua.load("a = function (v) print(v) return v end");
REQUIRE(lr.valid());
sol::protected_function target = lr;
sol::protected_function target = lr.get<sol::protected_function>();
sol::bytecode target_bc = target.dump();
auto result2 = lua2.safe_script(target_bc.as_string_view(), sol::script_pass_on_error);
@ -75,7 +75,7 @@ TEST_CASE("dump/failure", "test that failure is properly propagated") {
sol::state lua;
sol::load_result lr = lua.load("a = function (v) print(v) return v end");
REQUIRE(lr.valid());
sol::protected_function target = lr;
sol::protected_function target = lr.get<sol::protected_function>();
int err = target.dump(&dump_always_fail, nullptr, false, sol::dump_pass_on_error);
REQUIRE(err == dump_always_fail_number);
}
@ -95,7 +95,7 @@ TEST_CASE("dump/different containers", "test that dump inserter works for variou
sol::load_result lr = lua.load("a = function (v) print(v) return v end");
REQUIRE(lr.valid());
sol::protected_function target = lr;
sol::protected_function target = lr.get<sol::protected_function>();
sol::bytecode bytecode_dump = target.dump();
std::list<std::byte> list_dump = target.dump<std::list<std::byte>>();
std::vector<std::byte> vector_dump = target.dump<std::vector<std::byte>>();

View File

@ -372,7 +372,8 @@ TEST_CASE("functions/function_result and protected_function_result",
}
}
#if !defined(SOL2_CI) && !(SOL2_CI) && ((!defined(_M_IX86) || defined(_M_IA64)) || (defined(_WIN64)) || (defined(__LLP64__) || defined(__LP64__)))
#if SOL_IS_OFF(SOL_COMPILER_VCXX_CLANG_I_) \
&& (!defined(SOL2_CI) && !(SOL2_CI) && ((!defined(_M_IX86) || defined(_M_IA64)) || (defined(_WIN64)) || (defined(__LLP64__) || defined(__LP64__))))
TEST_CASE("functions/safe protected_function_result handlers",
"These tests will (hopefully) not destroy the stack since they are supposed to be mildly safe. Still, run with caution.") {
sol::state lua;
@ -426,7 +427,7 @@ TEST_CASE("functions/unsafe protected_function_result handlers",
return handlederrormessage;
};
lua.set_function("cpphandler", cpphandlerfx);
auto nontrampolinefx = [](lua_State*) -> int {
auto nontrampolinefx = [](lua_State*) noexcept(false) -> int {
// this code shoots an exception
// through the C API, without the trampoline
// present.

View File

@ -29,17 +29,27 @@
#include <numeric>
#include <iostream>
struct T { };
inline namespace sol2_test_operators {
struct T { };
TEST_CASE("operators/default", "test that generic equality operators and all sorts of equality tests can be used") {
struct U {
int a;
U(int x = 20) : a(x) {
}
bool operator==(const U& r) {
bool operator==(U& r) {
return a == r.a;
}
};
struct U_cpp_non_20 {
int a;
U_cpp_non_20(int x = 20) : a(x) {
}
bool operator==(const U_cpp_non_20& r) {
return a == r.a;
}
};
struct V {
int a;
V(int x = 20) : a(x) {
@ -49,6 +59,51 @@ TEST_CASE("operators/default", "test that generic equality operators and all sor
}
};
struct stringable {
static const void* last_print_ptr;
};
const void* stringable::last_print_ptr = nullptr;
std::ostream& operator<<(std::ostream& ostr, const stringable& o) {
stringable::last_print_ptr = static_cast<const void*>(&o);
return ostr << "{ stringable, std::ostream! }";
}
struct adl_stringable {
static const void* last_print_ptr;
};
const void* adl_stringable::last_print_ptr = nullptr;
std::string to_string(const adl_stringable& o) {
adl_stringable::last_print_ptr = static_cast<const void*>(&o);
return "{ adl_stringable, to_string! }";
}
namespace inside {
struct adl_stringable2 {
static const void* last_print_ptr;
};
const void* adl_stringable2::last_print_ptr = nullptr;
std::string to_string(const adl_stringable2& o) {
adl_stringable2::last_print_ptr = static_cast<const void*>(&o);
return "{ inside::adl_stringable2, inside::to_string! }";
}
} // namespace inside
struct member_stringable {
static const void* last_print_ptr;
std::string to_string() const {
member_stringable::last_print_ptr = static_cast<const void*>(this);
return "{ member_stringable, to_string! }";
}
};
const void* member_stringable::last_print_ptr = nullptr;
} // namespace sol2_test_operators
TEST_CASE("operators/default", "test that generic equality operators and all sorts of equality tests can be used") {
sol::state lua;
lua.open_libraries(sol::lib::base);
@ -61,12 +116,18 @@ TEST_CASE("operators/default", "test that generic equality operators and all sor
V v1;
V v2 { 30 };
V v3;
U_cpp_non_20 u20_1;
U_cpp_non_20 u20_2 { 30 };
U_cpp_non_20 u20_3;
lua["t1"] = &t1;
lua["t2"] = &t2;
lua["t3"] = &t3;
lua["u1"] = &u1;
lua["u2"] = &u2;
lua["u3"] = &u3;
lua["u20_1"] = &u20_1;
lua["u20_2"] = &u20_2;
lua["u20_3"] = &u20_3;
lua["v1"] = &v1;
lua["v2"] = &v2;
lua["v3"] = &v3;
@ -99,13 +160,25 @@ TEST_CASE("operators/default", "test that generic equality operators and all sor
sol::script_pass_on_error);
REQUIRE(result1.valid());
}
#if __cplusplus < 202000L
// C++20 changed object rewrite
// rules, so only test on versions below that
{
auto result1 = lua.safe_script(
"assert(u20_1 == u20_1)"
"assert(u20_2 == u20_2)"
"assert(u20_3 == u20_3)",
sol::script_pass_on_error);
REQUIRE(result1.valid());
}
#endif
{
sol::optional<sol::error> result1 = lua.safe_script(
"assert(not (u1 == u2))"
"assert(u1 == u3)"
"assert(not (u2 == u3))",
sol::script_pass_on_error);
REQUIRE(result1.valid());
REQUIRE_FALSE(result1.has_value());
}
// Object should compare equal to themselves
// (and not invoke operator==; pointer test should be sufficient)
@ -250,48 +323,6 @@ TEST_CASE("operators/call", "test call operator generation") {
}
}
struct stringable {
static const void* last_print_ptr;
};
const void* stringable::last_print_ptr = nullptr;
std::ostream& operator<<(std::ostream& ostr, const stringable& o) {
stringable::last_print_ptr = static_cast<const void*>(&o);
return ostr << "{ stringable, std::ostream! }";
}
struct adl_stringable {
static const void* last_print_ptr;
};
const void* adl_stringable::last_print_ptr = nullptr;
std::string to_string(const adl_stringable& o) {
adl_stringable::last_print_ptr = static_cast<const void*>(&o);
return "{ adl_stringable, to_string! }";
}
namespace inside {
struct adl_stringable2 {
static const void* last_print_ptr;
};
const void* adl_stringable2::last_print_ptr = nullptr;
std::string to_string(const adl_stringable2& o) {
adl_stringable2::last_print_ptr = static_cast<const void*>(&o);
return "{ inside::adl_stringable2, inside::to_string! }";
}
} // namespace inside
struct member_stringable {
static const void* last_print_ptr;
std::string to_string() const {
member_stringable::last_print_ptr = static_cast<const void*>(this);
return "{ member_stringable, to_string! }";
}
};
const void* member_stringable::last_print_ptr = nullptr;
TEST_CASE("operators/stringable", "test std::ostream stringability") {
sol::state lua;
lua.open_libraries(sol::lib::base);

View File

@ -24,22 +24,6 @@
#ifndef SOL_TESTS_SOL_TEST_HPP
#define SOL_TESTS_SOL_TEST_HPP
#if !defined(SOL_ALL_SAFETIES_ON)
#define SOL_ALL_SAFETIES_ON 1
#endif // SOL_ALL_SAFETIES_ON
#if !defined(SOL_PRINT_ERRORS)
#define SOL_PRINT_ERRORS 1
#endif // SOL_ALL_SAFETIES_ON
#if !defined(SOL_ENABLE_INTEROP)
#define SOL_ENABLE_INTEROP 1
#endif // SOL_ENABLE_INTEROP
// Can't activate until all script/safe_script calls are vetted...
/*#ifndef SOL_DEFAULT_PASS_ON_ERROR
#define SOL_DEFAULT_PASS_ON_ERROR 1
#endif // SOL_DEFAULT_PASS_ON_ERROR
*/
#include <iostream>
#include <cstdlib>
@ -68,7 +52,6 @@ struct test_stack_guard {
struct no_delete {
template <typename P>
void operator()(P) const noexcept {
}
};

View File

@ -65,8 +65,7 @@ struct string_reader_load {
const std::string& str;
std::size_t reads;
string_reader_load(const std::string& s)
: str(s), reads(0) {
string_reader_load(const std::string& s) : str(s), reads(0) {
}
};
@ -101,8 +100,7 @@ TEST_CASE("state/require_file", "opening files as 'requires'") {
SECTION("with usertypes") {
struct foo {
foo(int bar)
: bar(bar) {
foo(int bar) : bar(bar) {
}
const int bar;
@ -111,9 +109,7 @@ TEST_CASE("state/require_file", "opening files as 'requires'") {
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<foo>("foo",
sol::constructors<sol::types<int>>{},
"bar", &foo::bar);
lua.new_usertype<foo>("foo", sol::constructors<sol::types<int>> {}, "bar", &foo::bar);
const sol::table thingy1 = lua.require_file("thingy", file_require_file_user);
@ -208,9 +204,9 @@ TEST_CASE("state/multi require", "make sure that requires transfers across hand-
REQUIRE(val3 == 221);
// must have loaded the same table
// Lua is not obliged to give a shit. Thanks, Lua
//REQUIRE(thingy1 == thingy2);
// REQUIRE(thingy1 == thingy2);
// But we care, thankfully
//REQUIRE(thingy1 == thingy3);
// REQUIRE(thingy1 == thingy3);
REQUIRE((thingy2 == thingy3));
}
@ -280,7 +276,7 @@ end
TEST_CASE("state/script returns", "make sure script returns are done properly") {
std::string script =
R"(
R"(
local example =
{
str = "this is a string",
@ -458,13 +454,13 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
sol::load_result errbrload = lua.load(bad_runtime);
REQUIRE(errbrload.valid());
sol::protected_function errbrpf = errbrload;
sol::protected_function errbrpf = errbrload.get<sol::protected_function>();
auto errbr = errbrpf();
REQUIRE(!errbr.valid());
sol::load_result resultload = lua.load(good);
REQUIRE(resultload.valid());
sol::protected_function resultpf = resultload;
sol::protected_function resultpf = resultload.get<sol::protected_function>();
auto result = resultpf();
int a = lua["a"];
int ar = result;
@ -485,7 +481,7 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
void* vpbrsrl = static_cast<void*>(&brsrl);
sol::load_result errbrload = lua.load(&string_reader, vpbrsrl, bad_runtime);
REQUIRE(errbrload.valid());
sol::protected_function errbrpf = errbrload;
sol::protected_function errbrpf = errbrload.get<sol::protected_function>();
auto errbr = errbrpf();
REQUIRE(!errbr.valid());
@ -493,7 +489,7 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
void* vpgsrl = static_cast<void*>(&gsrl);
sol::load_result resultload = lua.load(&string_reader, vpgsrl, good);
REQUIRE(resultload.valid());
sol::protected_function resultpf = resultload;
sol::protected_function resultpf = resultload.get<sol::protected_function>();
auto result = resultpf();
int a = lua["a"];
int ar = result;
@ -510,13 +506,13 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
sol::load_result errbrload = lua.load(bad_runtime, bad_runtime, sol::load_mode::text);
REQUIRE(errbrload.valid());
sol::protected_function errbrpf = errbrload;
sol::protected_function errbrpf = errbrload.get<sol::protected_function>();
auto errbr = errbrpf();
REQUIRE(!errbr.valid());
sol::load_result resultload = lua.load(good, good, sol::load_mode::text);
REQUIRE(resultload.valid());
sol::protected_function resultpf = resultload;
sol::protected_function resultpf = resultload.get<sol::protected_function>();
auto result = resultpf();
int a = lua["a"];
int ar = result;
@ -537,7 +533,7 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
void* vpbrsrl = static_cast<void*>(&brsrl);
sol::load_result errbrload = lua.load(&string_reader, vpbrsrl, bad_runtime, sol::load_mode::text);
REQUIRE(errbrload.valid());
sol::protected_function errbrpf = errbrload;
sol::protected_function errbrpf = errbrload.get<sol::protected_function>();
auto errbr = errbrpf();
REQUIRE(!errbr.valid());
@ -545,7 +541,7 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
void* vpgsrl = static_cast<void*>(&gsrl);
sol::load_result resultload = lua.load(&string_reader, vpgsrl, good, sol::load_mode::text);
REQUIRE(resultload.valid());
sol::protected_function resultpf = resultload;
sol::protected_function resultpf = resultload.get<sol::protected_function>();
auto result = resultpf();
int a = lua["a"];
int ar = result;
@ -631,13 +627,13 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
sol::load_result errbrload = lua.load_file(file_bad_runtime);
REQUIRE(errbrload.valid());
sol::protected_function errbrpf = errbrload;
sol::protected_function errbrpf = errbrload.get<sol::protected_function>();
auto errbr = errbrpf();
REQUIRE(!errbr.valid());
sol::load_result resultload = lua.load_file(file_good);
REQUIRE(resultload.valid());
sol::protected_function resultpf = resultload;
sol::protected_function resultpf = resultload.get<sol::protected_function>();
auto result = resultpf();
int a = lua["a"];
int ar = result;
@ -654,13 +650,13 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
sol::load_result errbrload = lua.load_file(file_bad_runtime, sol::load_mode::text);
REQUIRE(errbrload.valid());
sol::protected_function errbrpf = errbrload;
sol::protected_function errbrpf = errbrload.get<sol::protected_function>();
auto errbr = errbrpf();
REQUIRE(!errbr.valid());
sol::load_result resultload = lua.load_file(file_good, sol::load_mode::text);
REQUIRE(resultload.valid());
sol::protected_function resultpf = resultload;
sol::protected_function resultpf = resultload.get<sol::protected_function>();
auto result = resultpf();
int a = lua["a"];
int ar = result;
@ -699,7 +695,7 @@ TEST_CASE("state/script function returns", "make sure that returned functions ar
sol::protected_function_result r1 = lua.safe_script("return function () return 1 end", sol::script_pass_on_error);
REQUIRE(r1.valid());
sol::protected_function pf = r1;
sol::protected_function pf = r1.get<sol::protected_function>();
int v1 = pf();
REQUIRE(v1 == 1);
}

View File

@ -129,7 +129,7 @@ TEST_CASE("usertype/runtime-extensibility", "Check if usertypes are runtime exte
int x;
};
class derived_b : public base_a {};
class derived_b : public base_a { };
SECTION("just functions") {
sol::state lua;
@ -246,7 +246,7 @@ end
}
TEST_CASE("usertype/runtime-replacement", "ensure that functions can be properly replaced at runtime for non-indexed things") {
struct heart_base_t {};
struct heart_base_t { };
struct heart_t : heart_base_t {
int x = 0;
void func() {
@ -342,7 +342,7 @@ TEST_CASE("usertype/runtime-replacement", "ensure that functions can be properly
}
TEST_CASE("usertype/runtime additions with newindex", "ensure that additions when new_index is overriden don't hit the specified new_index function") {
class newindex_object {};
class newindex_object { };
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<newindex_object>("object", sol::meta_function::new_index, [](newindex_object&, sol::object, sol::object) { return; });
@ -377,11 +377,16 @@ TEST_CASE("usertype/meta-key-retrievals", "allow for special meta keys (__index,
s[sol::metatable_key][sol::meta_function::new_index] = &d_sample::foo;
lua["var"] = s;
lua.safe_script("var = sample.new()");
lua.safe_script("var.key = 2");
lua.safe_script("var.__newindex = 4");
lua.safe_script("var.__index = 3");
lua.safe_script("var.__call = 1");
sol::optional<sol::error> maybe_error0 = lua.safe_script("var = sample.new()", sol::script_pass_on_error);
REQUIRE_FALSE(maybe_error0.has_value());
sol::optional<sol::error> maybe_error1 = lua.safe_script("var.key = 2", sol::script_pass_on_error);
REQUIRE_FALSE(maybe_error1.has_value());
sol::optional<sol::error> maybe_error2 = lua.safe_script("var.__newindex = 4", sol::script_pass_on_error);
REQUIRE_FALSE(maybe_error2.has_value());
sol::optional<sol::error> maybe_error3 = lua.safe_script("var.__index = 3", sol::script_pass_on_error);
REQUIRE_FALSE(maybe_error3.has_value());
sol::optional<sol::error> maybe_error4 = lua.safe_script("var.__call = 1", sol::script_pass_on_error);
REQUIRE_FALSE(maybe_error4.has_value());
REQUIRE(values[0] == 2);
REQUIRE(values[1] == 4);
REQUIRE(values[2] == 3);
@ -423,7 +428,8 @@ TEST_CASE("usertype/meta-key-retrievals", "allow for special meta keys (__index,
}
}
TEST_CASE("usertype/new_index and index", "a custom new_index and index only kicks in after the values pre-ordained on the index and new_index tables are assigned") {
TEST_CASE("usertype/new_index and index",
"a custom new_index and index only kicks in after the values pre-ordained on the index and new_index tables are assigned") {
sol::state lua;
lua.open_libraries(sol::lib::base);
@ -468,7 +474,11 @@ TEST_CASE("usertype/object and class extensible", "make sure that a class which
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<special_property_object>("special_property_object", sol::meta_function::new_index, &special_property_object::set_property_lua, sol::meta_function::index, &special_property_object::get_property_lua);
lua.new_usertype<special_property_object>("special_property_object",
sol::meta_function::new_index,
&special_property_object::set_property_lua,
sol::meta_function::index,
&special_property_object::get_property_lua);
lua["add_class_func"] = [](sol::this_state L, special_property_object&) {
sol::stack_userdata self = sol::stack::get<sol::stack_userdata>(L, 1);