Break all the behaviors. _All_ of them.

This commit is contained in:
ThePhD 2019-11-29 13:08:41 -05:00
parent 21c030933f
commit 83a656ae61
No known key found for this signature in database
GPG Key ID: 1509DB1C0F702BFA
15 changed files with 242 additions and 157 deletions

View File

@ -95,6 +95,9 @@ else()
set(IS_X64 TRUE)
endif()
if (PROJECT_SOURCE_DIR MATCHES ${CMAKE_SOURCE_DIR})
set(SOL2_IS_TOP_LEVEL TRUE)
endif()
# # # sol2 Source Groups
# # Sources everyone is going to need
@ -190,7 +193,7 @@ else()
endif()
# # # Tests, Examples and other CI suites that come with sol2
if (DO_TESTS OR DO_EXAMPLES)
if (SOL2_IS_TOP_LEVEL)
# # # General project output locations
if (IS_X86 OR CMAKE_SIZEOF_VOID_P EQUAL 4)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/x86/lib")
@ -217,6 +220,8 @@ if (DO_TESTS OR DO_EXAMPLES)
else()
string(REGEX REPLACE "/W[0-4]" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
string(REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
string(REGEX REPLACE "/MT" "/MD" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
string(REGEX REPLACE "/MT" "/MD" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
endif()
find_package(Threads REQUIRED)

View File

@ -28,7 +28,7 @@ include(Common/Core)
if (Catch_FIND_VERSION)
set(catch_version ${Catch_FIND_VERSION})
else()
set(catch_version 2.1.2)
set(catch_version 2.11.0)
endif()
set(catch_lib catch_lib_${catch_version})

View File

@ -185,7 +185,27 @@ if (MSVC)
"C:/Program Files/Microsoft Visual Studio/2017/Professional/VC"
"C:/Program Files/Microsoft Visual Studio/2017/Enterprise/VC/Auxiliary/Build"
"C:/Program Files/Microsoft Visual Studio/2017/Enterprise/VC/Auxiliary"
"C:/Program Files/Microsoft Visual Studio/2017/Enterprise/VC")
"C:/Program Files/Microsoft Visual Studio/2017/Enterprise/VC"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Auxiliary"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Auxiliary/Build"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Auxiliary"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC"
"C:/Program Files/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build"
"C:/Program Files/Microsoft Visual Studio/2019/Community/VC/Auxiliary"
"C:/Program Files/Microsoft Visual Studio/2019/Community/VC"
"C:/Program Files/Microsoft Visual Studio/2019/Professional/VC/Auxiliary/Build"
"C:/Program Files/Microsoft Visual Studio/2019/Professional/VC/Auxiliary"
"C:/Program Files/Microsoft Visual Studio/2019/Professional/VC"
"C:/Program Files/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build"
"C:/Program Files/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary"
"C:/Program Files/Microsoft Visual Studio/2019/Enterprise/VC")
if (VCVARS_ALL_BAT MATCHES "VCVARS_ALL_BAT-NOTFOUND")
MESSAGE(FATAL_ERROR "Cannot find 'vcvarsall.bat' file or similar needed to build LuaJIT ${LUA_VERSION} on Windows")
endif()
@ -195,6 +215,9 @@ if (MSVC)
set(LUA_JIT_MAKE_COMMAND "${VCVARS_ALL_BAT}" x64)
endif()
set(LUA_JIT_MAKE_COMMAND ${LUA_JIT_MAKE_COMMAND} && cd src && msvcbuild.bat)
if (CMAKE_BUILD_TYPE MATCHES "Debug")
set(LUA_JIT_MAKE_COMMAND ${LUA_JIT_MAKE_COMMAND} debug)
endif()
if (NOT BUILD_LUA_AS_DLL)
set(LUA_JIT_MAKE_COMMAND ${LUA_JIT_MAKE_COMMAND} static)
endif()

View File

@ -78,10 +78,7 @@ function (MAKE_EXAMPLE example_source_file example_suffix target_sol)
if (MSVC)
target_compile_options(${example_name}
PRIVATE /std:c++latest /EHsc "$<$<CONFIG:Debug>:/MDd>"
"$<$<CONFIG:Release>:/MD>"
"$<$<CONFIG:RelWithDebInfo>:/MD>"
"$<$<CONFIG:MinSizeRel>:/MD>")
PRIVATE /std:c++latest /EHsc)
target_compile_definitions(${example_name}
PRIVATE UNICODE _UNICODE
_CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE )

View File

@ -15,10 +15,7 @@ int main() {
lua_State* L = ts;
// references the object that called this function
// in constructors:
sol::stack_object selfobj(L, -1);
// the -1 (NEGATIVE one) above
// means "off the top fo the stack"
// (-1 is the top, -2 is one below, etc...)
sol::stack_object selfobj(L, 1);
// definitely the same
thing& self = selfobj.as<thing>();
@ -42,10 +39,7 @@ int main() {
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<thing>("thing",
sol::constructors<thing(sol::this_state)>(),
"func", &thing::func
);
lua.new_usertype<thing>("thing", sol::constructors<thing(sol::this_state)>(), "func", &thing::func);
lua.script(R"(
obj = thing.new()

View File

@ -217,15 +217,17 @@ namespace sol {
start,
std::forward<Args>(args)...);
}
if (!traits::runtime_variadics_t::value && traits::free_arity != fxarity) {
return overload_match_arity(types<>(),
std::index_sequence<>(),
std::index_sequence<traits::free_arity, M...>(),
std::forward<Match>(matchfx),
L,
fxarity,
start,
std::forward<Args>(args)...);
if constexpr (!traits::runtime_variadics_t::value) {
if (traits::free_arity != fxarity) {
return overload_match_arity(types<>(),
std::index_sequence<>(),
std::index_sequence<traits::free_arity, M...>(),
std::forward<Match>(matchfx),
L,
fxarity,
start,
std::forward<Args>(args)...);
}
}
return matchfx(types<Fx>(), meta::index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
}
@ -315,6 +317,8 @@ namespace sol {
stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
umf();
// put userdata at the first index
lua_insert(L, 1);
construct_match<T, TypeLists...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, 1 + static_cast<int>(syntax));
userdataref.push();
@ -639,7 +643,9 @@ namespace sol {
stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
umf();
construct_match<T, Args...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, boost + 1 + static_cast<int>(syntax));
// put userdata at the first index
lua_insert(L, 1);
construct_match<T, Args...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, boost + 1 + 1 + static_cast<int>(syntax));
userdataref.push();
return 1;
@ -660,7 +666,9 @@ namespace sol {
umf();
auto& func = std::get<I>(f.functions);
stack::call_into_lua<checked, clean_stack>(r, a, L, boost + start, func, detail::implicit_wrapper<T>(obj));
// put userdata at the first index
lua_insert(L, 1);
stack::call_into_lua<checked, clean_stack>(r, a, L, boost + 1 + start, func, detail::implicit_wrapper<T>(obj));
userdataref.push();
return 1;

View File

@ -52,6 +52,14 @@ namespace sol {
return result_code;
}
inline int dump_panic_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
(void)L;
(void)writer_function;
(void)userdata;
(void)strip;
return luaL_error(L, "a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code);
}
inline int dump_throw_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
#if defined(SOL_NO_EXCEPTIONS) && SOL_NO_EXCEPTIONS != 0
return dump_panic_on_error(L, result_code, writer_function, userdata, strip);
@ -64,14 +72,6 @@ namespace sol {
#endif // no exceptions stuff
}
inline int dump_panic_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
(void)L;
(void)writer_function;
(void)userdata;
(void)strip;
return luaL_error(L, "a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code);
}
} // namespace sol
#endif // SOL_DUMP_HANDLER_HPP

View File

@ -46,10 +46,9 @@ namespace sol {
std::size_t len;
template <typename... Args>
stack_dependencies(int stack_target, Args&&... args)
: target(stack_target), stack_indices(), len(sizeof...(Args)) {
stack_dependencies(int stack_target, Args&&... args) : target(stack_target), stack_indices(), len(sizeof...(Args)) {
std::size_t i = 0;
(void)detail::swallow{int(), (stack_indices[i++] = static_cast<int>(std::forward<Args>(args)), int())...};
(void)detail::swallow{ int(), (stack_indices[i++] = static_cast<int>(std::forward<Args>(args)), int())... };
}
int& operator[](std::size_t i) {
@ -73,8 +72,7 @@ namespace sol {
std::tuple<Policies...> policies;
template <typename Fx, typename... Args, meta::enable<meta::neg<std::is_same<meta::unqualified_t<Fx>, policy_wrapper>>> = meta::enabler>
policy_wrapper(Fx&& fx, Args&&... args)
: value(std::forward<Fx>(fx)), policies(std::forward<Args>(args)...) {
policy_wrapper(Fx&& fx, Args&&... args) : value(std::forward<Fx>(fx)), policies(std::forward<Args>(args)...) {
}
policy_wrapper(const policy_wrapper&) = default;
@ -94,7 +92,7 @@ namespace sol {
template <typename T>
inline constexpr bool is_policy_v = is_policy<T>::value;
}
} // namespace detail
} // namespace sol
#endif // SOL_FILTERS_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 2019-11-24 05:21:55.164513 UTC
// This header was generated with sol v3.0.3 (revision fd9e282)
// Generated 2019-11-29 18:08:19.653548 UTC
// This header was generated with sol v3.0.3 (revision 21c0309)
// https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP
@ -99,13 +99,13 @@
#endif // vc++ || clang++/g++
#if defined(SOL_CHECK_ARGUMENTS) && SOL_CHECK_ARGUMENTS
#if defined(SOL_CHECK_ARGUMENTS) && SOL_CHECK_ARGUMENTS != 0
#if defined(SOL_ALL_SAFETIES_ON)
#define SOL_ALL_SAFETIES_ON 1
#endif // turn all the safeties on
#endif // Compatibility define
#endif // Compatibility Define for Safety
#if defined(SOL_ALL_SAFETIES_ON) && SOL_ALL_SAFETIES_ON
#if defined(SOL_ALL_SAFETIES_ON) && SOL_ALL_SAFETIES_ON != 0
// Checks low-level getter function
// (and thusly, affects nearly entire framework)
@ -174,7 +174,7 @@
#endif // Turn on Safety for all if top-level macro is defined
#if defined(SOL_IN_DEBUG_DETECTED) && SOL_IN_DEBUG_DETECTED
#if defined(SOL_IN_DEBUG_DETECTED) && SOL_IN_DEBUG_DETECTED != 0
#if !defined(SOL_SAFE_REFERENCES)
// Ensure that references are forcefully type-checked upon construction

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 2019-11-24 05:21:54.660860 UTC
// This header was generated with sol v3.0.3 (revision fd9e282)
// Generated 2019-11-29 18:08:19.142496 UTC
// This header was generated with sol v3.0.3 (revision 21c0309)
// https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP
@ -125,13 +125,13 @@
#endif // vc++ || clang++/g++
#if defined(SOL_CHECK_ARGUMENTS) && SOL_CHECK_ARGUMENTS
#if defined(SOL_CHECK_ARGUMENTS) && SOL_CHECK_ARGUMENTS != 0
#if defined(SOL_ALL_SAFETIES_ON)
#define SOL_ALL_SAFETIES_ON 1
#endif // turn all the safeties on
#endif // Compatibility define
#endif // Compatibility Define for Safety
#if defined(SOL_ALL_SAFETIES_ON) && SOL_ALL_SAFETIES_ON
#if defined(SOL_ALL_SAFETIES_ON) && SOL_ALL_SAFETIES_ON != 0
// Checks low-level getter function
// (and thusly, affects nearly entire framework)
@ -200,7 +200,7 @@
#endif // Turn on Safety for all if top-level macro is defined
#if defined(SOL_IN_DEBUG_DETECTED) && SOL_IN_DEBUG_DETECTED
#if defined(SOL_IN_DEBUG_DETECTED) && SOL_IN_DEBUG_DETECTED != 0
#if !defined(SOL_SAFE_REFERENCES)
// Ensure that references are forcefully type-checked upon construction
@ -6114,10 +6114,9 @@ namespace sol {
std::size_t len;
template <typename... Args>
stack_dependencies(int stack_target, Args&&... args)
: target(stack_target), stack_indices(), len(sizeof...(Args)) {
stack_dependencies(int stack_target, Args&&... args) : target(stack_target), stack_indices(), len(sizeof...(Args)) {
std::size_t i = 0;
(void)detail::swallow{int(), (stack_indices[i++] = static_cast<int>(std::forward<Args>(args)), int())...};
(void)detail::swallow{ int(), (stack_indices[i++] = static_cast<int>(std::forward<Args>(args)), int())... };
}
int& operator[](std::size_t i) {
@ -6141,8 +6140,7 @@ namespace sol {
std::tuple<Policies...> policies;
template <typename Fx, typename... Args, meta::enable<meta::neg<std::is_same<meta::unqualified_t<Fx>, policy_wrapper>>> = meta::enabler>
policy_wrapper(Fx&& fx, Args&&... args)
: value(std::forward<Fx>(fx)), policies(std::forward<Args>(args)...) {
policy_wrapper(Fx&& fx, Args&&... args) : value(std::forward<Fx>(fx)), policies(std::forward<Args>(args)...) {
}
policy_wrapper(const policy_wrapper&) = default;
@ -6162,7 +6160,7 @@ namespace sol {
template <typename T>
inline constexpr bool is_policy_v = is_policy<T>::value;
}
} // namespace detail
} // namespace sol
// end of sol/policies.hpp
@ -16346,15 +16344,17 @@ namespace sol {
start,
std::forward<Args>(args)...);
}
if (!traits::runtime_variadics_t::value && traits::free_arity != fxarity) {
return overload_match_arity(types<>(),
std::index_sequence<>(),
std::index_sequence<traits::free_arity, M...>(),
std::forward<Match>(matchfx),
L,
fxarity,
start,
std::forward<Args>(args)...);
if constexpr (!traits::runtime_variadics_t::value) {
if (traits::free_arity != fxarity) {
return overload_match_arity(types<>(),
std::index_sequence<>(),
std::index_sequence<traits::free_arity, M...>(),
std::forward<Match>(matchfx),
L,
fxarity,
start,
std::forward<Args>(args)...);
}
}
return matchfx(types<Fx>(), meta::index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
}
@ -16444,6 +16444,8 @@ namespace sol {
stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
umf();
// put userdata at the first index
lua_insert(L, 1);
construct_match<T, TypeLists...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, 1 + static_cast<int>(syntax));
userdataref.push();
@ -16768,7 +16770,9 @@ namespace sol {
stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
umf();
construct_match<T, Args...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, boost + 1 + static_cast<int>(syntax));
// put userdata at the first index
lua_insert(L, 1);
construct_match<T, Args...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, boost + 1 + 1 + static_cast<int>(syntax));
userdataref.push();
return 1;
@ -16789,7 +16793,9 @@ namespace sol {
umf();
auto& func = std::get<I>(f.functions);
stack::call_into_lua<checked, clean_stack>(r, a, L, boost + start, func, detail::implicit_wrapper<T>(obj));
// put userdata at the first index
lua_insert(L, 1);
stack::call_into_lua<checked, clean_stack>(r, a, L, boost + 1 + start, func, detail::implicit_wrapper<T>(obj));
userdataref.push();
return 1;
@ -18375,6 +18381,14 @@ namespace sol {
return result_code;
}
inline int dump_panic_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
(void)L;
(void)writer_function;
(void)userdata;
(void)strip;
return luaL_error(L, "a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code);
}
inline int dump_throw_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
#if defined(SOL_NO_EXCEPTIONS) && SOL_NO_EXCEPTIONS != 0
return dump_panic_on_error(L, result_code, writer_function, userdata, strip);
@ -18387,14 +18401,6 @@ namespace sol {
#endif // no exceptions stuff
}
inline int dump_panic_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
(void)L;
(void)writer_function;
(void)userdata;
(void)strip;
return luaL_error(L, "a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code);
}
} // namespace sol
// end of sol/dump_handler.hpp

View File

@ -25,7 +25,7 @@
if (CMAKE_GENERATOR MATCHES "Visual Studio 14 2015")
find_package(Catch 1.12.1 REQUIRED)
else()
find_package(Catch 2.1.2 REQUIRED)
find_package(Catch REQUIRED)
endif()
file(GLOB SOL2_RUNTIME_TEST_SOURCES source/*.cpp)
@ -70,10 +70,7 @@ function(CREATE_TEST test_target_name test_name target_sol)
endif()
if (MSVC)
target_compile_options(${test_target_name}
PRIVATE /EHsc /std:c++latest "$<$<CONFIG:Debug>:/MDd>"
"$<$<CONFIG:Release>:/MD>"
"$<$<CONFIG:RelWithDebInfo>:/MD>"
"$<$<CONFIG:MinSizeRel>:/MD>")
PRIVATE /EHsc /std:c++latest)
target_compile_definitions(${test_target_name}
PRIVATE UNICODE _UNICODE
_CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE)

View File

@ -69,33 +69,34 @@ TEST_CASE("plain/indestructible", "test that we error for types that are innatel
sol::state lua;
lua.open_libraries(sol::lib::base);
std::unique_ptr<indestructible, indestructible::insider> i
= sol::detail::make_unique_deleter<indestructible, indestructible::insider>();
std::unique_ptr<indestructible, indestructible::insider> i = sol::detail::make_unique_deleter<indestructible, indestructible::insider>();
lua["i"] = *i;
lua.safe_script("i = nil");
auto result = lua.safe_script("collectgarbage()", sol::script_pass_on_error);
auto result = lua.safe_script("collectgarbage() collectgarbage()", sol::script_pass_on_error);
#if SOL_LUA_VERSION > 503
REQUIRE(result.valid());
#else
REQUIRE_FALSE(result.valid());
#endif
}
SECTION("saved") {
sol::state lua;
lua.open_libraries(sol::lib::base);
std::unique_ptr<indestructible, indestructible::insider> i
= sol::detail::make_unique_deleter<indestructible, indestructible::insider>();
std::unique_ptr<indestructible, indestructible::insider> i = sol::detail::make_unique_deleter<indestructible, indestructible::insider>();
lua["i"] = *i;
lua.new_usertype<indestructible>("indestructible", sol::default_constructor,
sol::meta_function::garbage_collect, sol::destructor([](indestructible& i) {
indestructible::insider del;
del(&i);
}));
lua.new_usertype<indestructible>(
"indestructible", sol::default_constructor, sol::meta_function::garbage_collect, sol::destructor([](indestructible& i) {
indestructible::insider del;
del(&i);
}));
lua.safe_script("i = nil");
auto result = lua.safe_script("collectgarbage()", sol::script_pass_on_error);
REQUIRE(result.valid());
}
}
TEST_CASE("plain/constructors and destructors",
"Make sure that constructors, destructors, deallocators and others work properly with the desired type") {
TEST_CASE("plain/constructors and destructors", "Make sure that constructors, destructors, deallocators and others work properly with the desired type") {
static int constructed = 0;
static int destructed = 0;
static int copied = 0;

View File

@ -52,10 +52,7 @@ TEST_CASE("policies/self", "ensure we return a direct reference to the lua userd
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<vec2>("vec2",
"x", &vec2::x,
"y", &vec2::y,
"normalize", sol::policies(&vec2::normalize, sol::returns_self()));
lua.new_usertype<vec2>("vec2", "x", &vec2::x, "y", &vec2::y, "normalize", sol::policies(&vec2::normalize, sol::returns_self()));
auto result1 = lua.safe_script(R"(
v1 = vec2.new()
@ -68,7 +65,8 @@ assert(rawequal(v1, v2))
v1 = nil
collectgarbage()
print(v2) -- v2 points to same, is not destroyed
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(result1.valid());
}
@ -82,7 +80,7 @@ TEST_CASE("policies/self_dependency", "ensure we can keep a userdata instance al
int value = 20;
~dep() {
std::cout << "\t"
<< "[C++] ~dep" << std::endl;
<< "[C++] ~dep" << std::endl;
value = std::numeric_limits<int>::max();
deps_destroyed.push_back(this);
}
@ -94,7 +92,7 @@ TEST_CASE("policies/self_dependency", "ensure we can keep a userdata instance al
~gc_test() {
std::cout << "\t"
<< "[C++] ~gc_test" << std::endl;
<< "[C++] ~gc_test" << std::endl;
gc_tests_destroyed.push_back(this);
}
};
@ -102,23 +100,18 @@ TEST_CASE("policies/self_dependency", "ensure we can keep a userdata instance al
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<dep>("dep",
"value", &dep::value,
sol::meta_function::to_string, [](dep& d) {
return "{ " + std::to_string(d.value) + " }";
});
lua.new_usertype<gc_test>("gc_test",
"d", sol::policies(&gc_test::d, sol::self_dependency()),
sol::meta_function::to_string, [](gc_test& g) {
return "{ d: { " + std::to_string(g.d.value) + " } }";
});
lua.new_usertype<dep>("dep", "value", &dep::value, sol::meta_function::to_string, [](dep& d) { return "{ " + std::to_string(d.value) + " }"; });
lua.new_usertype<gc_test>("gc_test", "d", sol::policies(&gc_test::d, sol::self_dependency()), sol::meta_function::to_string, [](gc_test& g) {
return "{ d: { " + std::to_string(g.d.value) + " } }";
});
auto result1 = lua.safe_script(R"(
g = gc_test.new()
d = g.d
print("new gc_test, d = g.d")
print("", g)
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(result1.valid());
REQUIRE(deps_destroyed.empty());
REQUIRE(gc_tests_destroyed.empty());
@ -131,7 +124,8 @@ print("g = nil, collectgarbage")
g = nil
collectgarbage()
print("", d)
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(result2.valid());
REQUIRE(deps_destroyed.empty());
@ -141,7 +135,8 @@ print("", d)
print("d = nil, collectgarbage")
d = nil
collectgarbage()
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(result3.valid());
REQUIRE(deps_destroyed.size() == 1);
@ -182,8 +177,7 @@ TEST_CASE("policies/stack_dependencies", "ensure we can take dependencies even t
std::reference_wrapper<holder> href;
composition_related comp;
depends_on_reference(holder& h)
: href(h) {
depends_on_reference(holder& h) : href(h) {
}
~depends_on_reference() {
@ -195,17 +189,19 @@ TEST_CASE("policies/stack_dependencies", "ensure we can take dependencies even t
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<holder>("holder",
"value", &holder::value);
lua.new_usertype<holder>("holder", "value", &holder::value);
lua.new_usertype<depends_on_reference>("depends_on_reference",
"new", sol::policies(sol::constructors<depends_on_reference(holder&)>(), sol::stack_dependencies(-1, 1)),
"comp", &depends_on_reference::comp);
"new",
sol::policies(sol::constructors<depends_on_reference(holder&)>(), sol::stack_dependencies(-1, 2)),
"comp",
&depends_on_reference::comp);
auto result1 = lua.safe_script(R"(
h = holder.new()
dor = depends_on_reference.new(h)
c = dor.comp
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(result1.valid());
REQUIRE(composition_relateds_destroyed.empty());
REQUIRE(holders_destroyed.empty());
@ -230,7 +226,8 @@ collectgarbage()
auto result3 = lua.safe_script(R"(
c = nil
collectgarbage()
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(result3.valid());
REQUIRE(composition_relateds_destroyed.empty());
@ -240,7 +237,8 @@ collectgarbage()
auto result4 = lua.safe_script(R"(
dor = nil
collectgarbage()
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(result4.valid());
REQUIRE(composition_relateds_destroyed.size() == 1);

View File

@ -226,7 +226,7 @@ TEST_CASE("inheritance/bad_base-class", "check to make sure bad/unregistered bas
struct a {
a(sol::this_state ts, sol::this_environment) {
lua_State* L = ts;
ud = sol::userdata(L, -2);
ud = sol::userdata(L, 1);
}

View File

@ -30,6 +30,46 @@
#include <functional>
#include <string>
struct self_cons_0 {
self_cons_0(sol::variadic_args args, sol::this_state thisL) {
lua_State* L = thisL;
self_cons_0* pself = sol::stack::get<self_cons_0*>(L);
REQUIRE(pself == this);
REQUIRE(args.size() == 0);
}
};
struct self_cons_1 {
self_cons_1(sol::variadic_args args, sol::this_state thisL) {
lua_State* L = thisL;
self_cons_1* pself = sol::stack::get<self_cons_1*>(L, 1);
REQUIRE(pself == this);
REQUIRE(args.size() == 1);
}
};
struct self_cons_2 {
static void init_self_cons_2(self_cons_2& mem, sol::variadic_args args, sol::this_state thisL) {
lua_State* L = thisL;
self_cons_2* pself = sol::stack::get<self_cons_2*>(L, 1);
std::allocator<self_cons_2> alloc{};
std::allocator_traits<std::allocator<self_cons_2>>::construct(alloc, &mem);
REQUIRE(pself == &mem);
REQUIRE(args.size() == 2);
}
};
struct self_cons_3 {
static void init_self_cons_3(self_cons_3* mem, sol::variadic_args args, sol::this_state thisL) {
lua_State* L = thisL;
self_cons_3* pself = sol::stack::get<self_cons_3*>(L, 1);
std::allocator<self_cons_3> alloc{};
std::allocator_traits<std::allocator<self_cons_3>>::construct(alloc, mem);
REQUIRE(pself == mem);
REQUIRE(args.size() == 3);
}
};
TEST_CASE("variadics/variadic_args", "Check to see we can receive multiple arguments through a variadic") {
struct structure {
int x;
@ -66,9 +106,7 @@ TEST_CASE("variadics/variadic_args", "Check to see we can receive multiple argum
TEST_CASE("variadics/required with variadic_args", "Check if a certain number of arguments can still be required even when using variadic_args") {
sol::state lua;
lua.set_function("v",
[](sol::this_state, sol::variadic_args, int, int) {
});
lua.set_function("v", [](sol::this_state, sol::variadic_args, int, int) {});
{
auto result = lua.safe_script("v(20, 25, 30)", sol::script_pass_on_error);
REQUIRE(result.valid());
@ -88,11 +126,7 @@ TEST_CASE("variadics/variadic_args get type", "Make sure we can inspect types pr
sol::stack_guard luasg(lua);
lua.set_function("f", [](sol::variadic_args va) {
sol::type types[] = {
sol::type::number,
sol::type::string,
sol::type::boolean
};
sol::type types[] = { sol::type::number, sol::type::string, sol::type::boolean };
bool working = true;
auto b = va.begin();
for (std::size_t i = 0; i < va.size(); ++i, ++b) {
@ -145,14 +179,13 @@ TEST_CASE("variadics/variadic_results", "returning a variable amount of argument
sol::state lua;
sol::stack_guard luasg(lua);
lua.set_function("f", [](sol::variadic_args args) {
return sol::variadic_results(args.cbegin(), args.cend());
});
lua.set_function("f", [](sol::variadic_args args) { return sol::variadic_results(args.cbegin(), args.cend()); });
auto result1 = lua.safe_script(R"(
v1, v2, v3 = f(1, 'bark', true)
v4, v5 = f(25, 82)
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(result1.valid());
int v1 = lua["v1"];
@ -192,7 +225,8 @@ TEST_CASE("variadics/variadic_results", "returning a variable amount of argument
auto result1 = lua.safe_script(R"(
v1, v2, v3 = f(true)
v4, v5, v6, v7 = f(false)
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(result1.valid());
int v1 = lua["v1"];
@ -221,20 +255,24 @@ TEST_CASE("variadics/fallback_constructor", "ensure constructor matching behaves
sol::state lua;
lua.new_usertype<vec2x>("vec2x",
sol::call_constructor, sol::factories([]() { return vec2x{}; }, [](vec2x const& v) -> vec2x { return v; }, [](sol::variadic_args va) {
vec2x res{};
if (va.size() == 1) {
res.x = va[0].get<float>();
res.y = va[0].get<float>();
}
else if (va.size() == 2) {
res.x = va[0].get<float>();
res.y = va[1].get<float>();
}
else {
throw sol::error("invalid args");
}
return res; }));
sol::call_constructor,
sol::factories([]() { return vec2x{}; },
[](vec2x const& v) -> vec2x { return v; },
[](sol::variadic_args va) {
vec2x res{};
if (va.size() == 1) {
res.x = va[0].get<float>();
res.y = va[0].get<float>();
}
else if (va.size() == 2) {
res.x = va[0].get<float>();
res.y = va[1].get<float>();
}
else {
throw sol::error("invalid args");
}
return res;
}));
auto result1 = lua.safe_script("v0 = vec2x();", sol::script_pass_on_error);
auto result2 = lua.safe_script("v1 = vec2x(1);", sol::script_pass_on_error);
@ -259,3 +297,23 @@ TEST_CASE("variadics/fallback_constructor", "ensure constructor matching behaves
REQUIRE(v3.x == v2.x);
REQUIRE(v3.y == v2.y);
}
TEST_CASE("variadics/self_test", "test argument count and self object reference") {
sol::state lua;
lua.open_libraries();
lua.new_usertype<self_cons_0>("foo0", sol::constructors<self_cons_0(sol::variadic_args, sol::this_state)>());
lua.new_usertype<self_cons_1>("foo1", sol::constructors<self_cons_1(sol::variadic_args, sol::this_state)>());
lua.new_usertype<self_cons_2>("foo2", "new", sol::initializers(&self_cons_2::init_self_cons_2));
lua.new_usertype<self_cons_3>("foo3", "new", sol::initializers(&self_cons_3::init_self_cons_3));
sol::optional<sol::error> maybe_err = lua.safe_script(R"(
local obj0 = foo0.new()
local obj1 = foo1.new(0)
local obj2 = foo2.new(0, 1)
local obj3 = foo3.new(0, 1, 2)
)",
sol::script_pass_on_error);
REQUIRE_FALSE(maybe_err.has_value());
}