From dc2493e7525bb7633f697ef10f72b72b46222249 Mon Sep 17 00:00:00 2001 From: Andy Belle-Isle Date: Fri, 30 Aug 2019 00:45:36 -0400 Subject: Forget what I said, I just need to change git attributes to mark for vendor --- lib/sol2/tests/CMakeLists.txt | 26 + lib/sol2/tests/compile_tests/CMakeLists.txt | 101 ++ lib/sol2/tests/compile_tests/source/as_args.cpp | 26 + lib/sol2/tests/compile_tests/source/as_returns.cpp | 26 + .../tests/compile_tests/source/base_traits.cpp | 26 + .../tests/compile_tests/source/bind_traits.cpp | 26 + lib/sol2/tests/compile_tests/source/bytecode.cpp | 26 + lib/sol2/tests/compile_tests/source/call.cpp | 26 + .../tests/compile_tests/source/compatibility.cpp | 26 + .../source/compatibility/compat-5.3.cpp | 26 + .../compile_tests/source/compatibility/version.cpp | 26 + lib/sol2/tests/compile_tests/source/config.cpp | 26 + .../tests/compile_tests/source/config_setup.cpp | 26 + lib/sol2/tests/compile_tests/source/coroutine.cpp | 26 + lib/sol2/tests/compile_tests/source/debug.cpp | 26 + lib/sol2/tests/compile_tests/source/demangle.cpp | 26 + lib/sol2/tests/compile_tests/source/deprecate.cpp | 26 + lib/sol2/tests/compile_tests/source/ebco.cpp | 26 + .../tests/compile_tests/source/environment.cpp | 26 + lib/sol2/tests/compile_tests/source/error.cpp | 1 + .../tests/compile_tests/source/error_handler.cpp | 26 + .../tests/compile_tests/source/feature_test.cpp | 26 + lib/sol2/tests/compile_tests/source/forward.cpp | 26 + .../tests/compile_tests/source/forward_detail.cpp | 26 + lib/sol2/tests/compile_tests/source/function.cpp | 26 + .../tests/compile_tests/source/function_result.cpp | 26 + .../tests/compile_tests/source/function_types.cpp | 26 + .../compile_tests/source/function_types_core.cpp | 26 + .../source/function_types_overloaded.cpp | 26 + .../source/function_types_stateful.cpp | 26 + .../source/function_types_stateless.cpp | 26 + .../source/function_types_templated.cpp | 26 + lib/sol2/tests/compile_tests/source/in_place.cpp | 26 + .../tests/compile_tests/source/inheritance.cpp | 26 + .../tests/compile_tests/source/load_result.cpp | 26 + lib/sol2/tests/compile_tests/source/lua_table.cpp | 26 + lib/sol2/tests/compile_tests/source/lua_value.cpp | 26 + lib/sol2/tests/compile_tests/source/main.cpp | 30 + .../tests/compile_tests/source/make_reference.cpp | 26 + lib/sol2/tests/compile_tests/source/map.cpp | 26 + lib/sol2/tests/compile_tests/source/metatable.cpp | 26 + lib/sol2/tests/compile_tests/source/object.cpp | 26 + .../tests/compile_tests/source/object_base.cpp | 26 + lib/sol2/tests/compile_tests/source/optional.cpp | 26 + .../source/optional_implementation.cpp | 26 + lib/sol2/tests/compile_tests/source/overload.cpp | 26 + .../tests/compile_tests/source/pointer_like.cpp | 26 + lib/sol2/tests/compile_tests/source/policies.cpp | 26 + lib/sol2/tests/compile_tests/source/property.cpp | 26 + lib/sol2/tests/compile_tests/source/protect.cpp | 26 + .../compile_tests/source/protected_function.cpp | 26 + .../source/protected_function_result.cpp | 26 + .../compile_tests/source/protected_handler.cpp | 26 + lib/sol2/tests/compile_tests/source/proxy.cpp | 26 + lib/sol2/tests/compile_tests/source/proxy_base.cpp | 26 + lib/sol2/tests/compile_tests/source/raii.cpp | 26 + lib/sol2/tests/compile_tests/source/reference.cpp | 26 + lib/sol2/tests/compile_tests/source/resolve.cpp | 26 + lib/sol2/tests/compile_tests/source/sol.cpp | 26 + .../tests/compile_tests/source/sol_defines.hpp | 34 + lib/sol2/tests/compile_tests/source/stack.cpp | 26 + .../tests/compile_tests/source/stack_check.cpp | 27 + .../tests/compile_tests/source/stack_check_get.cpp | 27 + .../source/stack_check_get_qualified.cpp | 27 + .../source/stack_check_get_unqualified.cpp | 27 + .../compile_tests/source/stack_check_qualified.cpp | 27 + .../source/stack_check_unqualified.cpp | 27 + lib/sol2/tests/compile_tests/source/stack_core.cpp | 27 + .../tests/compile_tests/source/stack_field.cpp | 26 + lib/sol2/tests/compile_tests/source/stack_get.cpp | 27 + .../compile_tests/source/stack_get_qualified.cpp | 27 + .../compile_tests/source/stack_get_unqualified.cpp | 27 + .../tests/compile_tests/source/stack_guard.cpp | 26 + .../tests/compile_tests/source/stack_iterator.cpp | 26 + lib/sol2/tests/compile_tests/source/stack_pop.cpp | 27 + .../tests/compile_tests/source/stack_probe.cpp | 26 + .../tests/compile_tests/source/stack_proxy.cpp | 26 + .../compile_tests/source/stack_proxy_base.cpp | 26 + lib/sol2/tests/compile_tests/source/stack_push.cpp | 26 + .../tests/compile_tests/source/stack_reference.cpp | 26 + lib/sol2/tests/compile_tests/source/state.cpp | 1 + .../tests/compile_tests/source/state_handling.cpp | 26 + lib/sol2/tests/compile_tests/source/state_view.cpp | 1 + .../tests/compile_tests/source/string_view.cpp | 26 + lib/sol2/tests/compile_tests/source/table.cpp | 26 + lib/sol2/tests/compile_tests/source/table_core.cpp | 26 + .../tests/compile_tests/source/table_iterator.cpp | 26 + lib/sol2/tests/compile_tests/source/thread.cpp | 26 + lib/sol2/tests/compile_tests/source/tie.cpp | 26 + lib/sol2/tests/compile_tests/source/traits.cpp | 26 + lib/sol2/tests/compile_tests/source/trampoline.cpp | 26 + lib/sol2/tests/compile_tests/source/tuple.cpp | 26 + lib/sol2/tests/compile_tests/source/types.cpp | 26 + lib/sol2/tests/compile_tests/source/unicode.cpp | 26 + .../source/unique_usertype_traits.cpp | 26 + .../tests/compile_tests/source/unsafe_function.cpp | 26 + .../source/unsafe_function_result.cpp | 26 + lib/sol2/tests/compile_tests/source/userdata.cpp | 26 + lib/sol2/tests/compile_tests/source/usertype.cpp | 26 + .../compile_tests/source/usertype_container.cpp | 26 + .../source/usertype_container_launch.cpp | 26 + .../tests/compile_tests/source/usertype_core.cpp | 26 + .../tests/compile_tests/source/usertype_proxy.cpp | 26 + .../compile_tests/source/usertype_storage.cpp | 26 + .../tests/compile_tests/source/usertype_traits.cpp | 26 + .../tests/compile_tests/source/variadic_args.cpp | 26 + .../compile_tests/source/variadic_results.cpp | 26 + lib/sol2/tests/compile_tests/source/wrapper.cpp | 26 + lib/sol2/tests/runtime_tests/CMakeLists.txt | 108 ++ .../tests/runtime_tests/source/abort_clean.cpp | 11 + lib/sol2/tests/runtime_tests/source/basic.cpp | 725 ++++++++++ .../tests/runtime_tests/source/common_classes.hpp | 192 +++ .../runtime_tests/source/container_semantics.cpp | 439 ++++++ .../source/container_semantics.custom.cpp | 36 + .../source/container_semantics.ordered.cpp | 377 +++++ .../source/container_semantics.unordered.cpp | 269 ++++ .../tests/runtime_tests/source/container_shims.cpp | 311 ++++ .../tests/runtime_tests/source/container_table.cpp | 307 ++++ lib/sol2/tests/runtime_tests/source/containers.cpp | 538 +++++++ .../runtime_tests/source/containers.roundtrip.cpp | 172 +++ .../runtime_tests/source/containers.table.cpp | 268 ++++ lib/sol2/tests/runtime_tests/source/coroutines.cpp | 636 +++++++++ .../tests/runtime_tests/source/customizations.cpp | 283 ++++ .../source/customizations_private.cpp | 178 +++ lib/sol2/tests/runtime_tests/source/dump.cpp | 121 ++ .../tests/runtime_tests/source/environments.cpp | 276 ++++ lib/sol2/tests/runtime_tests/source/functions.cpp | 1495 ++++++++++++++++++++ .../tests/runtime_tests/source/functions.std.cpp | 236 +++ lib/sol2/tests/runtime_tests/source/gc.cpp | 623 ++++++++ .../tests/runtime_tests/source/large_integer.cpp | 156 ++ lib/sol2/tests/runtime_tests/source/lua_value.cpp | 401 ++++++ lib/sol2/tests/runtime_tests/source/main.cpp | 7 + lib/sol2/tests/runtime_tests/source/operators.cpp | 463 ++++++ lib/sol2/tests/runtime_tests/source/overflow.cpp | 68 + .../tests/runtime_tests/source/plain_types.cpp | 198 +++ lib/sol2/tests/runtime_tests/source/policies.cpp | 265 ++++ lib/sol2/tests/runtime_tests/source/proxies.cpp | 99 ++ lib/sol2/tests/runtime_tests/source/sol_test.hpp | 75 + lib/sol2/tests/runtime_tests/source/state.cpp | 706 +++++++++ lib/sol2/tests/runtime_tests/source/storage.cpp | 85 ++ lib/sol2/tests/runtime_tests/source/strings.cpp | 198 +++ .../tests/runtime_tests/source/tables.checks.cpp | 51 + .../tests/runtime_tests/source/tables.clear.cpp | 74 + lib/sol2/tests/runtime_tests/source/tables.cpp | 250 ++++ .../tests/runtime_tests/source/tables.enums.cpp | 90 ++ .../tests/runtime_tests/source/tables.indexing.cpp | 151 ++ .../runtime_tests/source/tables.insertion.cpp | 195 +++ .../runtime_tests/source/tables.traversal.cpp | 202 +++ .../tests/runtime_tests/source/usertypes.basic.cpp | 291 ++++ .../source/usertypes.constructors.cpp | 206 +++ lib/sol2/tests/runtime_tests/source/usertypes.cpp | 234 +++ .../runtime_tests/source/usertypes.inheritance.cpp | 115 ++ .../source/usertypes.inheritance.multi.cpp | 333 +++++ .../source/usertypes.member_variables.cpp | 128 ++ .../runtime_tests/source/usertypes.overload.cpp | 91 ++ .../runtime_tests/source/usertypes.properties.cpp | 610 ++++++++ .../runtime_tests/source/usertypes.runtime.cpp | 567 ++++++++ .../runtime_tests/source/usertypes.unique.cpp | 173 +++ .../runtime_tests/source/usertypes.unregister.cpp | 147 ++ lib/sol2/tests/runtime_tests/source/utility.cpp | 346 +++++ lib/sol2/tests/runtime_tests/source/variadics.cpp | 261 ++++ 161 files changed, 17668 insertions(+) create mode 100644 lib/sol2/tests/CMakeLists.txt create mode 100644 lib/sol2/tests/compile_tests/CMakeLists.txt create mode 100644 lib/sol2/tests/compile_tests/source/as_args.cpp create mode 100644 lib/sol2/tests/compile_tests/source/as_returns.cpp create mode 100644 lib/sol2/tests/compile_tests/source/base_traits.cpp create mode 100644 lib/sol2/tests/compile_tests/source/bind_traits.cpp create mode 100644 lib/sol2/tests/compile_tests/source/bytecode.cpp create mode 100644 lib/sol2/tests/compile_tests/source/call.cpp create mode 100644 lib/sol2/tests/compile_tests/source/compatibility.cpp create mode 100644 lib/sol2/tests/compile_tests/source/compatibility/compat-5.3.cpp create mode 100644 lib/sol2/tests/compile_tests/source/compatibility/version.cpp create mode 100644 lib/sol2/tests/compile_tests/source/config.cpp create mode 100644 lib/sol2/tests/compile_tests/source/config_setup.cpp create mode 100644 lib/sol2/tests/compile_tests/source/coroutine.cpp create mode 100644 lib/sol2/tests/compile_tests/source/debug.cpp create mode 100644 lib/sol2/tests/compile_tests/source/demangle.cpp create mode 100644 lib/sol2/tests/compile_tests/source/deprecate.cpp create mode 100644 lib/sol2/tests/compile_tests/source/ebco.cpp create mode 100644 lib/sol2/tests/compile_tests/source/environment.cpp create mode 100644 lib/sol2/tests/compile_tests/source/error.cpp create mode 100644 lib/sol2/tests/compile_tests/source/error_handler.cpp create mode 100644 lib/sol2/tests/compile_tests/source/feature_test.cpp create mode 100644 lib/sol2/tests/compile_tests/source/forward.cpp create mode 100644 lib/sol2/tests/compile_tests/source/forward_detail.cpp create mode 100644 lib/sol2/tests/compile_tests/source/function.cpp create mode 100644 lib/sol2/tests/compile_tests/source/function_result.cpp create mode 100644 lib/sol2/tests/compile_tests/source/function_types.cpp create mode 100644 lib/sol2/tests/compile_tests/source/function_types_core.cpp create mode 100644 lib/sol2/tests/compile_tests/source/function_types_overloaded.cpp create mode 100644 lib/sol2/tests/compile_tests/source/function_types_stateful.cpp create mode 100644 lib/sol2/tests/compile_tests/source/function_types_stateless.cpp create mode 100644 lib/sol2/tests/compile_tests/source/function_types_templated.cpp create mode 100644 lib/sol2/tests/compile_tests/source/in_place.cpp create mode 100644 lib/sol2/tests/compile_tests/source/inheritance.cpp create mode 100644 lib/sol2/tests/compile_tests/source/load_result.cpp create mode 100644 lib/sol2/tests/compile_tests/source/lua_table.cpp create mode 100644 lib/sol2/tests/compile_tests/source/lua_value.cpp create mode 100644 lib/sol2/tests/compile_tests/source/main.cpp create mode 100644 lib/sol2/tests/compile_tests/source/make_reference.cpp create mode 100644 lib/sol2/tests/compile_tests/source/map.cpp create mode 100644 lib/sol2/tests/compile_tests/source/metatable.cpp create mode 100644 lib/sol2/tests/compile_tests/source/object.cpp create mode 100644 lib/sol2/tests/compile_tests/source/object_base.cpp create mode 100644 lib/sol2/tests/compile_tests/source/optional.cpp create mode 100644 lib/sol2/tests/compile_tests/source/optional_implementation.cpp create mode 100644 lib/sol2/tests/compile_tests/source/overload.cpp create mode 100644 lib/sol2/tests/compile_tests/source/pointer_like.cpp create mode 100644 lib/sol2/tests/compile_tests/source/policies.cpp create mode 100644 lib/sol2/tests/compile_tests/source/property.cpp create mode 100644 lib/sol2/tests/compile_tests/source/protect.cpp create mode 100644 lib/sol2/tests/compile_tests/source/protected_function.cpp create mode 100644 lib/sol2/tests/compile_tests/source/protected_function_result.cpp create mode 100644 lib/sol2/tests/compile_tests/source/protected_handler.cpp create mode 100644 lib/sol2/tests/compile_tests/source/proxy.cpp create mode 100644 lib/sol2/tests/compile_tests/source/proxy_base.cpp create mode 100644 lib/sol2/tests/compile_tests/source/raii.cpp create mode 100644 lib/sol2/tests/compile_tests/source/reference.cpp create mode 100644 lib/sol2/tests/compile_tests/source/resolve.cpp create mode 100644 lib/sol2/tests/compile_tests/source/sol.cpp create mode 100644 lib/sol2/tests/compile_tests/source/sol_defines.hpp create mode 100644 lib/sol2/tests/compile_tests/source/stack.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_check.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_check_get.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_check_get_qualified.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_check_get_unqualified.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_check_qualified.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_check_unqualified.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_core.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_field.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_get.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_get_qualified.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_get_unqualified.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_guard.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_iterator.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_pop.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_probe.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_proxy.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_proxy_base.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_push.cpp create mode 100644 lib/sol2/tests/compile_tests/source/stack_reference.cpp create mode 100644 lib/sol2/tests/compile_tests/source/state.cpp create mode 100644 lib/sol2/tests/compile_tests/source/state_handling.cpp create mode 100644 lib/sol2/tests/compile_tests/source/state_view.cpp create mode 100644 lib/sol2/tests/compile_tests/source/string_view.cpp create mode 100644 lib/sol2/tests/compile_tests/source/table.cpp create mode 100644 lib/sol2/tests/compile_tests/source/table_core.cpp create mode 100644 lib/sol2/tests/compile_tests/source/table_iterator.cpp create mode 100644 lib/sol2/tests/compile_tests/source/thread.cpp create mode 100644 lib/sol2/tests/compile_tests/source/tie.cpp create mode 100644 lib/sol2/tests/compile_tests/source/traits.cpp create mode 100644 lib/sol2/tests/compile_tests/source/trampoline.cpp create mode 100644 lib/sol2/tests/compile_tests/source/tuple.cpp create mode 100644 lib/sol2/tests/compile_tests/source/types.cpp create mode 100644 lib/sol2/tests/compile_tests/source/unicode.cpp create mode 100644 lib/sol2/tests/compile_tests/source/unique_usertype_traits.cpp create mode 100644 lib/sol2/tests/compile_tests/source/unsafe_function.cpp create mode 100644 lib/sol2/tests/compile_tests/source/unsafe_function_result.cpp create mode 100644 lib/sol2/tests/compile_tests/source/userdata.cpp create mode 100644 lib/sol2/tests/compile_tests/source/usertype.cpp create mode 100644 lib/sol2/tests/compile_tests/source/usertype_container.cpp create mode 100644 lib/sol2/tests/compile_tests/source/usertype_container_launch.cpp create mode 100644 lib/sol2/tests/compile_tests/source/usertype_core.cpp create mode 100644 lib/sol2/tests/compile_tests/source/usertype_proxy.cpp create mode 100644 lib/sol2/tests/compile_tests/source/usertype_storage.cpp create mode 100644 lib/sol2/tests/compile_tests/source/usertype_traits.cpp create mode 100644 lib/sol2/tests/compile_tests/source/variadic_args.cpp create mode 100644 lib/sol2/tests/compile_tests/source/variadic_results.cpp create mode 100644 lib/sol2/tests/compile_tests/source/wrapper.cpp create mode 100644 lib/sol2/tests/runtime_tests/CMakeLists.txt create mode 100644 lib/sol2/tests/runtime_tests/source/abort_clean.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/basic.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/common_classes.hpp create mode 100644 lib/sol2/tests/runtime_tests/source/container_semantics.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/container_semantics.custom.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/container_semantics.ordered.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/container_semantics.unordered.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/container_shims.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/container_table.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/containers.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/containers.roundtrip.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/containers.table.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/coroutines.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/customizations.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/customizations_private.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/dump.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/environments.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/functions.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/functions.std.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/gc.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/large_integer.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/lua_value.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/main.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/operators.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/overflow.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/plain_types.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/policies.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/proxies.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/sol_test.hpp create mode 100644 lib/sol2/tests/runtime_tests/source/state.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/storage.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/strings.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/tables.checks.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/tables.clear.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/tables.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/tables.enums.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/tables.indexing.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/tables.insertion.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/tables.traversal.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/usertypes.basic.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/usertypes.constructors.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/usertypes.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/usertypes.inheritance.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/usertypes.inheritance.multi.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/usertypes.member_variables.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/usertypes.overload.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/usertypes.properties.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/usertypes.runtime.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/usertypes.unique.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/usertypes.unregister.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/utility.cpp create mode 100644 lib/sol2/tests/runtime_tests/source/variadics.cpp (limited to 'lib/sol2/tests') diff --git a/lib/sol2/tests/CMakeLists.txt b/lib/sol2/tests/CMakeLists.txt new file mode 100644 index 0000000..2e7ee37 --- /dev/null +++ b/lib/sol2/tests/CMakeLists.txt @@ -0,0 +1,26 @@ +# # # # sol3 +# The MIT License (MIT) +# +# Copyright (c) 2013-2019 Rapptz, ThePhD, and contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# # # # sol3 tests + +add_subdirectory(runtime_tests) +add_subdirectory(compile_tests) diff --git a/lib/sol2/tests/compile_tests/CMakeLists.txt b/lib/sol2/tests/compile_tests/CMakeLists.txt new file mode 100644 index 0000000..a973cd9 --- /dev/null +++ b/lib/sol2/tests/compile_tests/CMakeLists.txt @@ -0,0 +1,101 @@ +# # # # sol3 +# The MIT License (MIT) +# +# Copyright (c) 2013-2019 Rapptz, ThePhD, and contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# # # # sol3 tests - compilation tests + +file(GLOB_RECURSE SOL2_COMPILE_TEST_SOURCES source/*.cpp) +source_group(compile_test_sources FILES "${SOL2_COMPILE_TEST_SOURCES}") + +function(CREATE_TEST test_target_name test_name target_sol) + if (test_name MATCHES ".single") + add_executable(${test_target_name} "source/main.cpp" "source/forward.cpp" "source/sol.cpp") + else() + add_executable(${test_target_name} "${SOL2_COMPILE_TEST_SOURCES}") + endif() + set_target_properties(${test_target_name} + PROPERTIES + OUTPUT_NAME ${test_name} + EXPORT_NAME sol2::${test_name}) + target_link_libraries(${test_target_name} + PUBLIC Threads::Threads ${LUA_LIBRARIES} ${CATCH_LIBRARIES} ${target_sol}) + + if (MSVC) + target_compile_options(${test_target_name} + PRIVATE /std:c++latest /EHsc "$<$:/MDd>" + "$<$:/MD>" + "$<$:/MD>" + "$<$:/MD>") + target_compile_definitions(${test_target_name} + PRIVATE UNICODE _UNICODE + _CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE) + else() + target_compile_options(${test_target_name} + PRIVATE -std=c++1z + -Wno-unknown-warning -Wno-unknown-warning-option + -Wall -Wextra -Wpedantic -pedantic -pedantic-errors + -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) + endif() + endif() + + if (MSVC) + if (NOT CMAKE_COMPILER_ID MATCHES "Clang") + target_compile_options(${test_target_name} + PRIVATE /bigobj /W4) + endif() + else() + if (IS_X86) + if(MINGW) + set_target_properties(${test_target_name} + PROPERTIES + LINK_FLAGS -static-libstdc++) + endif() + endif() + endif() + if (SOL2_CI) + target_compile_definitions(${test_target_name} + PRIVATE SOL2_CI) + endif() + if (CMAKE_DL_LIBS) + target_link_libraries(${test_target_name} PUBLIC + ${CMAKE_DL_LIBS}) + endif() + + add_test(NAME ${test_name} COMMAND ${test_target_name}) + install(TARGETS ${test_target_name} RUNTIME DESTINATION bin) +endfunction(CREATE_TEST) + +if (SOL2_TESTS) + CREATE_TEST(compile_tests "compile_tests" sol2::sol2) +endif() +if (SOL2_TESTS_SINGLE) + CREATE_TEST(compile_tests_single "compile_tests.single" sol2::sol2_single) +endif() +if (SOL2_TESTS_SINGLE_GENERATED) + CREATE_TEST(compile_tests_generated_single "compile_tests.single.generated" sol2::sol2_single_generated) +endif() diff --git a/lib/sol2/tests/compile_tests/source/as_args.cpp b/lib/sol2/tests/compile_tests/source/as_args.cpp new file mode 100644 index 0000000..824db00 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/as_args.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/as_returns.cpp b/lib/sol2/tests/compile_tests/source/as_returns.cpp new file mode 100644 index 0000000..5c38554 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/as_returns.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/base_traits.cpp b/lib/sol2/tests/compile_tests/source/base_traits.cpp new file mode 100644 index 0000000..593da74 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/base_traits.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/bind_traits.cpp b/lib/sol2/tests/compile_tests/source/bind_traits.cpp new file mode 100644 index 0000000..3f8d362 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/bind_traits.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/bytecode.cpp b/lib/sol2/tests/compile_tests/source/bytecode.cpp new file mode 100644 index 0000000..cb0405f --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/bytecode.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/call.cpp b/lib/sol2/tests/compile_tests/source/call.cpp new file mode 100644 index 0000000..a7c7998 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/call.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/compatibility.cpp b/lib/sol2/tests/compile_tests/source/compatibility.cpp new file mode 100644 index 0000000..02ccb56 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/compatibility.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/compatibility/compat-5.3.cpp b/lib/sol2/tests/compile_tests/source/compatibility/compat-5.3.cpp new file mode 100644 index 0000000..a5a0358 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/compatibility/compat-5.3.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "../sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/compatibility/version.cpp b/lib/sol2/tests/compile_tests/source/compatibility/version.cpp new file mode 100644 index 0000000..1250fa3 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/compatibility/version.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "../sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/config.cpp b/lib/sol2/tests/compile_tests/source/config.cpp new file mode 100644 index 0000000..a5d3414 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/config.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/config_setup.cpp b/lib/sol2/tests/compile_tests/source/config_setup.cpp new file mode 100644 index 0000000..86e8311 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/config_setup.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/coroutine.cpp b/lib/sol2/tests/compile_tests/source/coroutine.cpp new file mode 100644 index 0000000..d498174 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/coroutine.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/debug.cpp b/lib/sol2/tests/compile_tests/source/debug.cpp new file mode 100644 index 0000000..64a8491 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/debug.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/demangle.cpp b/lib/sol2/tests/compile_tests/source/demangle.cpp new file mode 100644 index 0000000..5478260 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/demangle.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/deprecate.cpp b/lib/sol2/tests/compile_tests/source/deprecate.cpp new file mode 100644 index 0000000..5af312f --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/deprecate.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/ebco.cpp b/lib/sol2/tests/compile_tests/source/ebco.cpp new file mode 100644 index 0000000..7f4ca14 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/ebco.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/environment.cpp b/lib/sol2/tests/compile_tests/source/environment.cpp new file mode 100644 index 0000000..ee0d003 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/environment.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/error.cpp b/lib/sol2/tests/compile_tests/source/error.cpp new file mode 100644 index 0000000..bc2dc87 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/error.cpp @@ -0,0 +1 @@ +#include diff --git a/lib/sol2/tests/compile_tests/source/error_handler.cpp b/lib/sol2/tests/compile_tests/source/error_handler.cpp new file mode 100644 index 0000000..c0cb972 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/error_handler.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/feature_test.cpp b/lib/sol2/tests/compile_tests/source/feature_test.cpp new file mode 100644 index 0000000..d9567ee --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/feature_test.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/forward.cpp b/lib/sol2/tests/compile_tests/source/forward.cpp new file mode 100644 index 0000000..7e443e0 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/forward.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/forward_detail.cpp b/lib/sol2/tests/compile_tests/source/forward_detail.cpp new file mode 100644 index 0000000..93610da --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/forward_detail.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/function.cpp b/lib/sol2/tests/compile_tests/source/function.cpp new file mode 100644 index 0000000..4bb9364 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/function.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/function_result.cpp b/lib/sol2/tests/compile_tests/source/function_result.cpp new file mode 100644 index 0000000..4e0cbbf --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/function_result.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/function_types.cpp b/lib/sol2/tests/compile_tests/source/function_types.cpp new file mode 100644 index 0000000..f004b7e --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/function_types.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/function_types_core.cpp b/lib/sol2/tests/compile_tests/source/function_types_core.cpp new file mode 100644 index 0000000..627d1e4 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/function_types_core.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/function_types_overloaded.cpp b/lib/sol2/tests/compile_tests/source/function_types_overloaded.cpp new file mode 100644 index 0000000..9437407 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/function_types_overloaded.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/function_types_stateful.cpp b/lib/sol2/tests/compile_tests/source/function_types_stateful.cpp new file mode 100644 index 0000000..414116b --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/function_types_stateful.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/function_types_stateless.cpp b/lib/sol2/tests/compile_tests/source/function_types_stateless.cpp new file mode 100644 index 0000000..8e96d6e --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/function_types_stateless.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/function_types_templated.cpp b/lib/sol2/tests/compile_tests/source/function_types_templated.cpp new file mode 100644 index 0000000..55c3a4b --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/function_types_templated.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/in_place.cpp b/lib/sol2/tests/compile_tests/source/in_place.cpp new file mode 100644 index 0000000..f714ff2 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/in_place.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/inheritance.cpp b/lib/sol2/tests/compile_tests/source/inheritance.cpp new file mode 100644 index 0000000..e348f7f --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/inheritance.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/load_result.cpp b/lib/sol2/tests/compile_tests/source/load_result.cpp new file mode 100644 index 0000000..665205d --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/load_result.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/lua_table.cpp b/lib/sol2/tests/compile_tests/source/lua_table.cpp new file mode 100644 index 0000000..16e8600 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/lua_table.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/lua_value.cpp b/lib/sol2/tests/compile_tests/source/lua_value.cpp new file mode 100644 index 0000000..801d763 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/lua_value.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/main.cpp b/lib/sol2/tests/compile_tests/source/main.cpp new file mode 100644 index 0000000..22dfbbb --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/main.cpp @@ -0,0 +1,30 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include + +int main () { + return 0; +} \ No newline at end of file diff --git a/lib/sol2/tests/compile_tests/source/make_reference.cpp b/lib/sol2/tests/compile_tests/source/make_reference.cpp new file mode 100644 index 0000000..74719ea --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/make_reference.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/map.cpp b/lib/sol2/tests/compile_tests/source/map.cpp new file mode 100644 index 0000000..a1d86b1 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/map.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/metatable.cpp b/lib/sol2/tests/compile_tests/source/metatable.cpp new file mode 100644 index 0000000..406f8f7 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/metatable.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/object.cpp b/lib/sol2/tests/compile_tests/source/object.cpp new file mode 100644 index 0000000..e37baec --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/object.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/object_base.cpp b/lib/sol2/tests/compile_tests/source/object_base.cpp new file mode 100644 index 0000000..e937206 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/object_base.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/optional.cpp b/lib/sol2/tests/compile_tests/source/optional.cpp new file mode 100644 index 0000000..58722e1 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/optional.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/optional_implementation.cpp b/lib/sol2/tests/compile_tests/source/optional_implementation.cpp new file mode 100644 index 0000000..a6b2e9e --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/optional_implementation.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/overload.cpp b/lib/sol2/tests/compile_tests/source/overload.cpp new file mode 100644 index 0000000..e830563 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/overload.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/pointer_like.cpp b/lib/sol2/tests/compile_tests/source/pointer_like.cpp new file mode 100644 index 0000000..9ae5eda --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/pointer_like.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/policies.cpp b/lib/sol2/tests/compile_tests/source/policies.cpp new file mode 100644 index 0000000..6d15e2f --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/policies.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/property.cpp b/lib/sol2/tests/compile_tests/source/property.cpp new file mode 100644 index 0000000..3196623 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/property.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/protect.cpp b/lib/sol2/tests/compile_tests/source/protect.cpp new file mode 100644 index 0000000..2eb1332 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/protect.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/protected_function.cpp b/lib/sol2/tests/compile_tests/source/protected_function.cpp new file mode 100644 index 0000000..6f5b161 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/protected_function.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/protected_function_result.cpp b/lib/sol2/tests/compile_tests/source/protected_function_result.cpp new file mode 100644 index 0000000..7e029cb --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/protected_function_result.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/protected_handler.cpp b/lib/sol2/tests/compile_tests/source/protected_handler.cpp new file mode 100644 index 0000000..2f10cbf --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/protected_handler.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/proxy.cpp b/lib/sol2/tests/compile_tests/source/proxy.cpp new file mode 100644 index 0000000..5751acc --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/proxy.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/proxy_base.cpp b/lib/sol2/tests/compile_tests/source/proxy_base.cpp new file mode 100644 index 0000000..ef4abab --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/proxy_base.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/raii.cpp b/lib/sol2/tests/compile_tests/source/raii.cpp new file mode 100644 index 0000000..4be116b --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/raii.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/reference.cpp b/lib/sol2/tests/compile_tests/source/reference.cpp new file mode 100644 index 0000000..23baaa6 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/reference.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/resolve.cpp b/lib/sol2/tests/compile_tests/source/resolve.cpp new file mode 100644 index 0000000..255e1ee --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/resolve.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/sol.cpp b/lib/sol2/tests/compile_tests/source/sol.cpp new file mode 100644 index 0000000..8da9cb7 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/sol.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/sol_defines.hpp b/lib/sol2/tests/compile_tests/source/sol_defines.hpp new file mode 100644 index 0000000..2de38b9 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/sol_defines.hpp @@ -0,0 +1,34 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef SOL_TESTS_SOL_DEFINES_HPP +#define SOL_TESTS_SOL_DEFINES_HPP + +#if !defined(SOL_ALL_SAFETIES_ON) +#define SOL_ALL_SAFETIES_ON 1 +#endif // SOL_ALL_SAFETIES_ON +#if !defined(SOL_ENABLE_INTEROP) +#define SOL_ENABLE_INTEROP 1 +#endif // SOL_ENABLE_INTEROP + +#endif // SOL_TESTS_SOL_DEFINES_HPP diff --git a/lib/sol2/tests/compile_tests/source/stack.cpp b/lib/sol2/tests/compile_tests/source/stack.cpp new file mode 100644 index 0000000..d9643a3 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_check.cpp b/lib/sol2/tests/compile_tests/source/stack_check.cpp new file mode 100644 index 0000000..e4368f0 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_check.cpp @@ -0,0 +1,27 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +//#include +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_check_get.cpp b/lib/sol2/tests/compile_tests/source/stack_check_get.cpp new file mode 100644 index 0000000..d1f4485 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_check_get.cpp @@ -0,0 +1,27 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +//#include +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_check_get_qualified.cpp b/lib/sol2/tests/compile_tests/source/stack_check_get_qualified.cpp new file mode 100644 index 0000000..5da994a --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_check_get_qualified.cpp @@ -0,0 +1,27 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +//#include +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_check_get_unqualified.cpp b/lib/sol2/tests/compile_tests/source/stack_check_get_unqualified.cpp new file mode 100644 index 0000000..8e4f8d6 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_check_get_unqualified.cpp @@ -0,0 +1,27 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +//#include +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_check_qualified.cpp b/lib/sol2/tests/compile_tests/source/stack_check_qualified.cpp new file mode 100644 index 0000000..fc355d6 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_check_qualified.cpp @@ -0,0 +1,27 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +//#include +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_check_unqualified.cpp b/lib/sol2/tests/compile_tests/source/stack_check_unqualified.cpp new file mode 100644 index 0000000..45d5a06 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_check_unqualified.cpp @@ -0,0 +1,27 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +//#include +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_core.cpp b/lib/sol2/tests/compile_tests/source/stack_core.cpp new file mode 100644 index 0000000..7f5f321 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_core.cpp @@ -0,0 +1,27 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +//#include +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_field.cpp b/lib/sol2/tests/compile_tests/source/stack_field.cpp new file mode 100644 index 0000000..0e54608 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_field.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_get.cpp b/lib/sol2/tests/compile_tests/source/stack_get.cpp new file mode 100644 index 0000000..f70ad26 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_get.cpp @@ -0,0 +1,27 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +//#include +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_get_qualified.cpp b/lib/sol2/tests/compile_tests/source/stack_get_qualified.cpp new file mode 100644 index 0000000..bcb2f62 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_get_qualified.cpp @@ -0,0 +1,27 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +//#include +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_get_unqualified.cpp b/lib/sol2/tests/compile_tests/source/stack_get_unqualified.cpp new file mode 100644 index 0000000..7a706f1 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_get_unqualified.cpp @@ -0,0 +1,27 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +//#include +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_guard.cpp b/lib/sol2/tests/compile_tests/source/stack_guard.cpp new file mode 100644 index 0000000..b965ca6 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_guard.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_iterator.cpp b/lib/sol2/tests/compile_tests/source/stack_iterator.cpp new file mode 100644 index 0000000..b49c5ae --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_iterator.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_pop.cpp b/lib/sol2/tests/compile_tests/source/stack_pop.cpp new file mode 100644 index 0000000..3d66163 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_pop.cpp @@ -0,0 +1,27 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +//#include +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_probe.cpp b/lib/sol2/tests/compile_tests/source/stack_probe.cpp new file mode 100644 index 0000000..98ccd61 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_probe.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_proxy.cpp b/lib/sol2/tests/compile_tests/source/stack_proxy.cpp new file mode 100644 index 0000000..f2f5665 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_proxy.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_proxy_base.cpp b/lib/sol2/tests/compile_tests/source/stack_proxy_base.cpp new file mode 100644 index 0000000..776e4a8 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_proxy_base.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_push.cpp b/lib/sol2/tests/compile_tests/source/stack_push.cpp new file mode 100644 index 0000000..03dbfc4 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_push.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/stack_reference.cpp b/lib/sol2/tests/compile_tests/source/stack_reference.cpp new file mode 100644 index 0000000..f32f193 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/stack_reference.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/state.cpp b/lib/sol2/tests/compile_tests/source/state.cpp new file mode 100644 index 0000000..227dfc2 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/state.cpp @@ -0,0 +1 @@ +#include diff --git a/lib/sol2/tests/compile_tests/source/state_handling.cpp b/lib/sol2/tests/compile_tests/source/state_handling.cpp new file mode 100644 index 0000000..3969df3 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/state_handling.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/state_view.cpp b/lib/sol2/tests/compile_tests/source/state_view.cpp new file mode 100644 index 0000000..6f7730d --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/state_view.cpp @@ -0,0 +1 @@ +#include diff --git a/lib/sol2/tests/compile_tests/source/string_view.cpp b/lib/sol2/tests/compile_tests/source/string_view.cpp new file mode 100644 index 0000000..9a3d7ed --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/string_view.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/table.cpp b/lib/sol2/tests/compile_tests/source/table.cpp new file mode 100644 index 0000000..f14ed38 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/table.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/table_core.cpp b/lib/sol2/tests/compile_tests/source/table_core.cpp new file mode 100644 index 0000000..53de30e --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/table_core.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/table_iterator.cpp b/lib/sol2/tests/compile_tests/source/table_iterator.cpp new file mode 100644 index 0000000..b650660 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/table_iterator.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/thread.cpp b/lib/sol2/tests/compile_tests/source/thread.cpp new file mode 100644 index 0000000..1bb75ac --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/thread.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/tie.cpp b/lib/sol2/tests/compile_tests/source/tie.cpp new file mode 100644 index 0000000..ccb31ad --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/tie.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/traits.cpp b/lib/sol2/tests/compile_tests/source/traits.cpp new file mode 100644 index 0000000..5cb2384 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/traits.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/trampoline.cpp b/lib/sol2/tests/compile_tests/source/trampoline.cpp new file mode 100644 index 0000000..fa37c1b --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/trampoline.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/tuple.cpp b/lib/sol2/tests/compile_tests/source/tuple.cpp new file mode 100644 index 0000000..91c64c7 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/tuple.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/types.cpp b/lib/sol2/tests/compile_tests/source/types.cpp new file mode 100644 index 0000000..81848e6 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/types.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/unicode.cpp b/lib/sol2/tests/compile_tests/source/unicode.cpp new file mode 100644 index 0000000..ea71bec --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/unicode.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/unique_usertype_traits.cpp b/lib/sol2/tests/compile_tests/source/unique_usertype_traits.cpp new file mode 100644 index 0000000..8c6cf6d --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/unique_usertype_traits.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/unsafe_function.cpp b/lib/sol2/tests/compile_tests/source/unsafe_function.cpp new file mode 100644 index 0000000..02acddc --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/unsafe_function.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/unsafe_function_result.cpp b/lib/sol2/tests/compile_tests/source/unsafe_function_result.cpp new file mode 100644 index 0000000..d71ce96 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/unsafe_function_result.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/userdata.cpp b/lib/sol2/tests/compile_tests/source/userdata.cpp new file mode 100644 index 0000000..59ba57c --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/userdata.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/usertype.cpp b/lib/sol2/tests/compile_tests/source/usertype.cpp new file mode 100644 index 0000000..62c721d --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/usertype.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/usertype_container.cpp b/lib/sol2/tests/compile_tests/source/usertype_container.cpp new file mode 100644 index 0000000..5f5e213 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/usertype_container.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/usertype_container_launch.cpp b/lib/sol2/tests/compile_tests/source/usertype_container_launch.cpp new file mode 100644 index 0000000..d4670be --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/usertype_container_launch.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/usertype_core.cpp b/lib/sol2/tests/compile_tests/source/usertype_core.cpp new file mode 100644 index 0000000..ca86944 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/usertype_core.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/usertype_proxy.cpp b/lib/sol2/tests/compile_tests/source/usertype_proxy.cpp new file mode 100644 index 0000000..45a882b --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/usertype_proxy.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/usertype_storage.cpp b/lib/sol2/tests/compile_tests/source/usertype_storage.cpp new file mode 100644 index 0000000..b401f1c --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/usertype_storage.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/usertype_traits.cpp b/lib/sol2/tests/compile_tests/source/usertype_traits.cpp new file mode 100644 index 0000000..2048dd9 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/usertype_traits.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/variadic_args.cpp b/lib/sol2/tests/compile_tests/source/variadic_args.cpp new file mode 100644 index 0000000..2499bfe --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/variadic_args.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/variadic_results.cpp b/lib/sol2/tests/compile_tests/source/variadic_results.cpp new file mode 100644 index 0000000..8030be5 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/variadic_results.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/compile_tests/source/wrapper.cpp b/lib/sol2/tests/compile_tests/source/wrapper.cpp new file mode 100644 index 0000000..9365fb2 --- /dev/null +++ b/lib/sol2/tests/compile_tests/source/wrapper.cpp @@ -0,0 +1,26 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_defines.hpp" + +#include diff --git a/lib/sol2/tests/runtime_tests/CMakeLists.txt b/lib/sol2/tests/runtime_tests/CMakeLists.txt new file mode 100644 index 0000000..a997993 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/CMakeLists.txt @@ -0,0 +1,108 @@ +# # # # sol3 +# The MIT License (MIT) +# +# Copyright (c) 2013-2019 Rapptz, ThePhD, and contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# # # # sol3 tests - runtime tests + +if (CMAKE_GENERATOR MATCHES "Visual Studio 14 2015") + find_package(Catch 1.12.1 REQUIRED) +else() + find_package(Catch 2.1.2 REQUIRED) +endif() + +file(GLOB SOL2_RUNTIME_TEST_SOURCES source/*.cpp) +source_group(test_sources FILES ${SOL2_RUNTIME_TEST_SOURCES}) + +function(CREATE_TEST test_target_name test_name target_sol) + add_executable(${test_target_name} ${SOL2_RUNTIME_TEST_SOURCES}) + set_target_properties(${test_target_name} + PROPERTIES + OUTPUT_NAME ${test_name} + EXPORT_NAME sol2::${test_name}) + target_link_libraries(${test_target_name} + PUBLIC Threads::Threads ${LUA_LIBRARIES} ${CATCH_LIBRARIES} ${target_sol}) + + if (MSVC) + if (NOT CMAKE_COMPILER_ID MATCHES "Clang") + target_compile_options(${test_target_name} + PRIVATE /bigobj /W4) + endif() + else() + target_compile_options(${test_target_name} + PRIVATE -std=c++1z -pthread + -Wno-unknown-warning -Wno-unknown-warning-option + -Wall -Wpedantic -Werror -pedantic -pedantic-errors + -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) + endif() + + if (IS_X86) + if(MINGW) + set_target_properties(${test_target_name} + PROPERTIES + LINK_FLAGS -static-libstdc++) + endif() + endif() + endif() + if (MSVC) + target_compile_options(${test_target_name} + PRIVATE /EHsc /std:c++latest "$<$:/MDd>" + "$<$:/MD>" + "$<$:/MD>" + "$<$:/MD>") + target_compile_definitions(${test_target_name} + PRIVATE UNICODE _UNICODE + _CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE) + else() + target_compile_options(${test_target_name} + PRIVATE -std=c++1z -Wno-unknown-warning -Wno-unknown-warning-option + -Wall -Wextra -Wpedantic -pedantic -pedantic-errors) + endif() + + if (SOL2_CI) + target_compile_definitions(${test_target_name} + PRIVATE SOL2_CI) + endif() + + if (CMAKE_DL_LIBS) + target_link_libraries(${test_target_name} + PRIVATE ${CMAKE_DL_LIBS}) + endif() + + add_test(NAME ${test_name} COMMAND ${test_target_name}) + install(TARGETS ${test_target_name} RUNTIME DESTINATION bin) +endfunction(CREATE_TEST) + +if (SOL2_TESTS) + CREATE_TEST(runtime_tests "runtime_tests" sol2::sol2) +endif() +if (SOL2_TESTS_SINGLE) + CREATE_TEST(runtime_tests_single "runtime_tests.single" sol2::sol2_single) +endif() +if (SOL2_TESTS_SINGLE_GENERATED) + CREATE_TEST(runtime_tests_generated_single "runtime_tests.single.generated" sol2::sol2_single_generated) +endif() diff --git a/lib/sol2/tests/runtime_tests/source/abort_clean.cpp b/lib/sol2/tests/runtime_tests/source/abort_clean.cpp new file mode 100644 index 0000000..821333b --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/abort_clean.cpp @@ -0,0 +1,11 @@ +#include + +struct pre_main { + pre_main() { +#ifdef SOL2_CI +#ifdef _MSC_VER + _set_abort_behavior(0, _WRITE_ABORT_MSG); +#endif +#endif + } +} pm; diff --git a/lib/sol2/tests/runtime_tests/source/basic.cpp b/lib/sol2/tests/runtime_tests/source/basic.cpp new file mode 100644 index 0000000..2a8b710 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/basic.cpp @@ -0,0 +1,725 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include +#include +#include +#include + +bool func_opt_ret_bool(sol::optional i) { + if (i) { + INFO(i.value()); + } + else { + INFO("optional isn't set"); + } + return true; +} + +struct base1 { + int a1 = 250; +}; + +struct base2 { + int a2 = 500; +}; + +struct simple : base1 { +}; + +struct complex : base1, base2 { +}; + +SOL_BASE_CLASSES(complex, base1, base2); +SOL_BASE_CLASSES(simple, base1); +SOL_DERIVED_CLASSES(base1, simple, complex); +SOL_DERIVED_CLASSES(base2, complex); + +TEST_CASE("table/traversal", "ensure that we can chain requests and tunnel down into a value if we desire") { + + sol::state lua; + int begintop = 0, endtop = 0; + + sol::function scriptload = lua.load("t1 = {t2 = {t3 = 24}};"); + scriptload(); + { + test_stack_guard g(lua.lua_state(), begintop, endtop); + int traversex24 = lua.traverse_get("t1", "t2", "t3"); + REQUIRE(traversex24 == 24); + } + REQUIRE(begintop == endtop); + + { + test_stack_guard g(lua.lua_state(), begintop, endtop); + int x24 = lua["t1"]["t2"]["t3"]; + REQUIRE(x24 == 24); + } + REQUIRE(begintop == endtop); + + { + test_stack_guard g(lua.lua_state(), begintop, endtop); + lua["t1"]["t2"]["t3"] = 64; + } + REQUIRE(begintop == endtop); + + { + int traversex64 = lua.traverse_get("t1", "t2", "t3"); + REQUIRE(traversex64 == 64); + } + REQUIRE(begintop == endtop); + + { + test_stack_guard g(lua.lua_state(), begintop, endtop); + int x64 = lua["t1"]["t2"]["t3"]; + REQUIRE(x64 == 64); + } + REQUIRE(begintop == endtop); + + { + test_stack_guard g(lua.lua_state(), begintop, endtop); + lua.traverse_set("t1", "t2", "t3", 13); + } + REQUIRE(begintop == endtop); + + { + test_stack_guard g(lua.lua_state(), begintop, endtop); + int traversex13 = lua.traverse_get("t1", "t2", "t3"); + REQUIRE(traversex13 == 13); + } + REQUIRE(begintop == endtop); + + { + test_stack_guard g(lua.lua_state(), begintop, endtop); + int x13 = lua["t1"]["t2"]["t3"]; + REQUIRE(x13 == 13); + } + REQUIRE(begintop == endtop); +} + +TEST_CASE("simple/set", "Check if the set works properly.") { + sol::state lua; + int begintop = 0, endtop = 0; + { + test_stack_guard g(lua.lua_state(), begintop, endtop); + lua.set("a", 9); + } + REQUIRE(begintop == endtop); + { + auto result = lua.safe_script("if a ~= 9 then error('wrong value') end", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + test_stack_guard g(lua.lua_state(), begintop, endtop); + lua.set("d", "hello"); + } + REQUIRE(begintop == endtop); + { + auto result = lua.safe_script("if d ~= 'hello' then error('expected \\'hello\\', got '.. tostring(d)) end", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + + { + test_stack_guard g(lua.lua_state(), begintop, endtop); + lua.set("e", std::string("hello"), "f", true); + } + REQUIRE(begintop == endtop); + { + auto result = lua.safe_script("if d ~= 'hello' then error('expected \\'hello\\', got '.. tostring(d)) end", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("if f ~= true then error('wrong value') end", sol::script_pass_on_error); + REQUIRE(result.valid()); + } +} + +TEST_CASE("simple/get", "Tests if the get function works properly.") { + sol::state lua; + int begintop = 0, endtop = 0; + + lua.safe_script("a = 9"); + { + test_stack_guard g(lua.lua_state(), begintop, endtop); + auto a = lua.get("a"); + REQUIRE(a == 9.0); + } + REQUIRE(begintop == endtop); + + lua.safe_script("b = nil"); + { + test_stack_guard g(lua.lua_state(), begintop, endtop); + REQUIRE_NOTHROW(lua.get("b")); + } + REQUIRE(begintop == endtop); + + lua.safe_script("d = 'hello'"); + lua.safe_script("e = true"); + { + test_stack_guard g(lua.lua_state(), begintop, endtop); + std::string d; + bool e; + std::tie(d, e) = lua.get("d", "e"); + REQUIRE(d == "hello"); + REQUIRE(e == true); + } + REQUIRE(begintop == endtop); +} + +TEST_CASE("simple/set and get global integer", "Tests if the get function works properly with global integers") { + sol::state lua; + lua[1] = 25.4; + lua.safe_script("b = 1"); + double a = lua.get(1); + double b = lua.get("b"); + REQUIRE(a == 25.4); + REQUIRE(b == 1); +} + +TEST_CASE("simple/get_or", "check if table.get_or works correctly") { + sol::state lua; + + auto bob_table = lua.create_table("bob"); + bob_table.set("is_set", 42); + + int is_set = bob_table.get_or("is_set", 3); + int is_not_set = bob_table.get_or("is_not_set", 22); + + REQUIRE(is_set == 42); + REQUIRE(is_not_set == 22); + + lua["joe"] = 55.6; + double bark = lua.get_or("joe", 60); + REQUIRE(bark == 55.6); +} + +TEST_CASE("simple/proxy get_or", "check if proxy.get_or works correctly") { + sol::state lua; + + auto bob_table = lua.create_table("bob"); + bob_table.set("is_set", 42); + + int is_set = bob_table["is_set"].get_or(3); + int is_not_set = bob_table["is_not_set"].get_or(22); + + REQUIRE(is_set == 42); + REQUIRE(is_not_set == 22); + + lua["joe"] = 55.6; + double bark = lua["joe"].get_or(60); + REQUIRE(bark == 55.6); +} + +TEST_CASE("simple/addition", "check if addition works and can be gotten through lua.get and lua.set") { + sol::state lua; + + lua.set("b", 0.2); + lua.safe_script("c = 9 + b"); + auto c = lua.get("c"); + + REQUIRE(c == 9.2); +} + +TEST_CASE("simple/if", "check if if statements work through lua") { + sol::state lua; + + std::string program = "if true then f = 0.1 else f = 'test' end"; + lua.safe_script(program); + auto f = lua.get("f"); + + REQUIRE(f == 0.1); + REQUIRE((f == lua["f"])); +} + +TEST_CASE("negative/basic errors", "Check if error handling works correctly") { + sol::state lua; + + auto result = lua.safe_script("nil[5]", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); +} + +TEST_CASE("libraries", "Check if we can open libraries") { + sol::state lua; + REQUIRE_NOTHROW(lua.open_libraries(sol::lib::base, sol::lib::os)); +} + +TEST_CASE("libraries2", "Check if we can open ALL the libraries") { + sol::state lua; + REQUIRE_NOTHROW(lua.open_libraries(sol::lib::base, + sol::lib::bit32, + sol::lib::coroutine, + sol::lib::debug, + sol::lib::ffi, + sol::lib::jit, + sol::lib::math, + sol::lib::os, + sol::lib::package, + sol::lib::string, + sol::lib::table)); +} + +TEST_CASE("interop/null-to-nil-and-back", "nil should be the given type when a pointer from C++ is returned as nullptr, and nil should result in nullptr in connected C++ code") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.set_function("lol", []() -> int* { + return nullptr; + }); + lua.set_function("rofl", [](int* x) { + INFO(x); + }); + REQUIRE_NOTHROW(lua.safe_script( + "x = lol()\n" + "rofl(x)\n" + "assert(x == nil)")); +} + +TEST_CASE("object/conversions", "make sure all basic reference types can be made into objects") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + struct d {}; + + lua.safe_script("function f () print('bark') end"); + lua["d"] = d {}; + lua["l"] = static_cast(nullptr); + + sol::table t = lua.create_table(); + sol::table t2(lua, sol::create); + sol::thread th = sol::thread::create(lua); + sol::function f = lua["f"]; + sol::protected_function pf = lua["f"]; + sol::userdata ud = lua["d"]; + sol::lightuserdata lud = lua["l"]; + sol::environment env(lua, sol::create); + + sol::object ot(t); + sol::object ot2(t2); + sol::object oteq = ot; + sol::object oth(th); + sol::object of(f); + sol::object opf(pf); + sol::object od(ud); + sol::object ol(lud); + sol::object oenv(env); + + auto oni = sol::make_object(lua, 50); + auto ond = sol::make_object(lua, 50.0); + + std::string somestring = "look at this text isn't it nice"; + auto osl = sol::make_object(lua, "Bark bark bark"); + auto os = sol::make_object(lua, somestring); + + auto omn = sol::make_object(lua, sol::lua_nil); + + REQUIRE(ot.get_type() == sol::type::table); + REQUIRE(ot2.get_type() == sol::type::table); + REQUIRE(oteq.get_type() == sol::type::table); + REQUIRE(oth.get_type() == sol::type::thread); + REQUIRE(of.get_type() == sol::type::function); + REQUIRE(opf.get_type() == sol::type::function); + REQUIRE(od.get_type() == sol::type::userdata); + REQUIRE(ol.get_type() == sol::type::lightuserdata); + REQUIRE(oni.get_type() == sol::type::number); + REQUIRE(ond.get_type() == sol::type::number); + REQUIRE(osl.get_type() == sol::type::string); + REQUIRE(os.get_type() == sol::type::string); + REQUIRE(omn.get_type() == sol::type::lua_nil); + REQUIRE(oenv.get_type() == sol::type::table); +} + +TEST_CASE("object/main_* conversions", "make sure all basic reference types can be made into objects") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + struct d {}; + + lua.safe_script("function f () print('bark') end"); + lua["d"] = d {}; + lua["l"] = static_cast(nullptr); + + sol::main_table t = lua.create_table(); + sol::main_table t2(lua, sol::create); + sol::thread th = sol::thread::create(lua); + sol::main_function f = lua["f"]; + sol::main_protected_function pf = lua["f"]; + sol::main_userdata ud = lua["d"]; + sol::main_lightuserdata lud = lua["l"]; + sol::main_environment env(lua, sol::create); + + sol::main_object ot(t); + sol::main_object ot2(t2); + sol::main_object oteq = ot; + sol::main_object oth(th); + sol::main_object of(f); + sol::main_object opf(pf); + sol::main_object od(ud); + sol::main_object ol(lud); + sol::main_object oenv(env); + + auto oni = sol::make_object(lua, 50); + auto ond = sol::make_object(lua, 50.0); + + std::string somestring = "look at this text isn't it nice"; + auto osl = sol::make_object(lua, "Bark bark bark"); + auto os = sol::make_object(lua, somestring); + + auto omn = sol::make_object(lua, sol::lua_nil); + + REQUIRE(ot.get_type() == sol::type::table); + REQUIRE(ot2.get_type() == sol::type::table); + REQUIRE(oteq.get_type() == sol::type::table); + REQUIRE(oth.get_type() == sol::type::thread); + REQUIRE(of.get_type() == sol::type::function); + REQUIRE(opf.get_type() == sol::type::function); + REQUIRE(od.get_type() == sol::type::userdata); + REQUIRE(ol.get_type() == sol::type::lightuserdata); + REQUIRE(oni.get_type() == sol::type::number); + REQUIRE(ond.get_type() == sol::type::number); + REQUIRE(osl.get_type() == sol::type::string); + REQUIRE(os.get_type() == sol::type::string); + REQUIRE(omn.get_type() == sol::type::lua_nil); + REQUIRE(oenv.get_type() == sol::type::table); +} + +TEST_CASE("feature/indexing overrides", "make sure index functions can be overridden on types") { + struct PropertySet { + sol::object get_property_lua(const char* name, sol::this_state s) { + auto& var = props[name]; + return sol::make_object(s, var); + } + + void set_property_lua(const char* name, sol::stack_object object) { + props[name] = object.as(); + } + + std::unordered_map props; + }; + + struct DynamicObject { + PropertySet& get_dynamic_props() { + return dynamic_props; + } + + PropertySet dynamic_props; + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + + sol::usertype utps = lua.new_usertype("PropertySet"); + utps[sol::meta_function::new_index] = &PropertySet::set_property_lua; + utps[sol::meta_function::index] = &PropertySet::get_property_lua; + sol::usertype utdo = lua.new_usertype("DynamicObject"); + utdo["props"] = sol::property(&DynamicObject::get_dynamic_props); + + auto result = lua.safe_script(R"__( +obj = DynamicObject:new() +obj.props.name = 'test name' +print('name = ' .. obj.props.name) +)__", sol::script_pass_on_error); + REQUIRE(result.valid()); + + std::string name = lua["obj"]["props"]["name"]; + REQUIRE(name == "test name"); +} + +TEST_CASE("features/indexing numbers", "make sure indexing functions can be override on usertypes") { + class vector { + public: + double data[3]; + + vector() + : data { 0, 0, 0 } { + } + + double& operator[](int i) { + return data[i]; + } + + static double my_index(vector& v, int i) { + return v[i]; + } + + static void my_new_index(vector& v, int i, double x) { + v[i] = x; + } + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + lua.new_usertype("vector", sol::constructors>(), + sol::meta_function::index, &vector::my_index, + sol::meta_function::new_index, &vector::my_new_index); + lua.safe_script( + "v = vector.new()\n" + "print(v[1])\n" + "v[2] = 3\n" + "print(v[2])\n"); + + vector& v = lua["v"]; + REQUIRE(v[0] == 0.0); + REQUIRE(v[1] == 0.0); + REQUIRE(v[2] == 3.0); +} + +TEST_CASE("features/multiple inheritance", "Ensure that multiple inheritance works as advertised") { + sol::state lua; + lua.open_libraries(sol::lib::base); + lua.new_usertype("base1", + "a1", &base1::a1); + lua.new_usertype("base2", + "a2", &base2::a2); + lua.new_usertype("simple", + "a1", &simple::a1, + sol::base_classes, sol::bases()); + lua.new_usertype("complex", + "a1", &complex::a1, + "a2", &complex::a2, + sol::base_classes, sol::bases()); + lua.safe_script( + "c = complex.new()\n" + "s = simple.new()\n" + "b1 = base1.new()\n" + "b2 = base1.new()\n"); + + base1* sb1 = lua["s"]; + REQUIRE(sb1 != nullptr); + REQUIRE(sb1->a1 == 250); + + base1* cb1 = lua["c"]; + base2* cb2 = lua["c"]; + + REQUIRE(cb1 != nullptr); + REQUIRE(cb2 != nullptr); + REQUIRE(cb1->a1 == 250); + REQUIRE(cb2->a2 == 500); +} + +TEST_CASE("regressions/std::ref", "Ensure that std::reference_wrapper<> isn't considered as a function by using unwrap_unqualified_t trait") { + struct base1 { + int a1 = 250; + }; + + sol::state lua; + base1 v; + lua["vp"] = &v; + lua["vr"] = std::ref(v); + + base1* vp = lua["vp"]; + base1& vr = lua["vr"]; + REQUIRE(vp != nullptr); + REQUIRE(vp == &v); + + REQUIRE(vp->a1 == 250); + REQUIRE(vr.a1 == 250); + + v.a1 = 568; + + REQUIRE(vp->a1 == 568); + REQUIRE(vr.a1 == 568); +} + +TEST_CASE("optional/left out args", "Make sure arguments can be left out of optional without tanking miserably") { + + sol::state lua; + lua.open_libraries(sol::lib::base); + + // sol::optional needs an argument no matter what? + lua.set_function("func_opt_ret_bool", func_opt_ret_bool); + REQUIRE_NOTHROW([&] { + lua.safe_script(R"( + func_opt_ret_bool(42) + func_opt_ret_bool() + print('ok') + )"); + }()); +} + +TEST_CASE("optional/engaged versus unengaged", "solidify semantics for an engaged and unengaged optional") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.set_function("f", [](sol::optional optional_arg) { + if (optional_arg) { + return true; + } + return false; + }); + + auto valid0 = lua.safe_script("assert(not f())", sol::script_pass_on_error); + REQUIRE(valid0.valid()); + auto valid1 = lua.safe_script("assert(not f(nil))", sol::script_pass_on_error); + REQUIRE(valid1.valid()); + auto valid2 = lua.safe_script("assert(f(1))", sol::script_pass_on_error); + REQUIRE(valid2.valid()); + auto valid3 = lua.safe_script("assert(f('hi'))", sol::script_pass_on_error); + REQUIRE(valid3.valid()); +} + +TEST_CASE("pusher/constness", "Make sure more types can handle being const and junk") { + struct Foo { + Foo(const sol::function& f) + : _f(f) { + } + const sol::function& _f; + + const sol::function& f() const { + return _f; + } + }; + + sol::state lua; + + lua.new_usertype("Foo", + sol::call_constructor, sol::no_constructor, + "f", &Foo::f); + + lua["func"] = []() { return 20; }; + sol::function f = lua["func"]; + lua["foo"] = Foo(f); + Foo& foo = lua["foo"]; + int x = foo.f()(); + REQUIRE(x == 20); +} + +TEST_CASE("compilation/const regression", "make sure constness in tables is respected all the way down") { + struct State { + public: + State() { + this->state_.globals()["state"] = this; + } + + sol::state state_; + }; + + State state; + State* s = state.state_.globals()["state"]; + REQUIRE(s == &state); +} + +TEST_CASE("numbers/integers", "make sure integers are detectable on most platforms") { + sol::state lua; + + lua["a"] = 50; // int + lua["b"] = 50.5; // double + + sol::object a = lua["a"]; + sol::object b = lua["b"]; + + bool a_is_int = a.is(); + bool a_is_double = a.is(); + + bool b_is_int = b.is(); + bool b_is_double = b.is(); + + REQUIRE(a_is_int); + REQUIRE(a_is_double); + + // TODO: will this fail on certain lower Lua versions? + REQUIRE_FALSE(b_is_int); + REQUIRE(b_is_double); +} + +TEST_CASE("object/is", "test whether or not the is abstraction works properly for a user-defined type") { + struct thing {}; + + SECTION("stack_object") { + sol::state lua; + lua.open_libraries(sol::lib::base); + lua.set_function("is_thing", [](sol::stack_object obj) { return obj.is(); }); + lua["a"] = thing {}; + { + auto result = lua.safe_script("assert(is_thing(a))", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + } + + SECTION("object") { + sol::state lua; + lua.open_libraries(sol::lib::base); + lua.set_function("is_thing", [](sol::object obj) { return obj.is(); }); + lua["a"] = thing {}; + { + auto result = lua.safe_script("assert(is_thing(a))", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + } +} + +TEST_CASE("object/base_of_things", "make sure that object is the base of things and can be sliced / returned safely") { + SECTION("reference") { + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::coroutine); + + lua["ud"] = base1{}; + + lua["f1"] = [](sol::object o) -> sol::object { return o; }; + lua["f2"] = [](sol::table o) -> sol::object { return o; }; + lua["f3"] = [](sol::thread o) -> sol::object { return o; }; + lua["f4"] = [](sol::unsafe_function o) -> sol::object { return o; }; + lua["f5"] = [](sol::protected_function o) -> sol::object { return o; }; + lua["f6"] = [](sol::userdata o) -> sol::object { return o; }; + auto result1 = lua.safe_script("f1(2)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("f2({})", sol::script_pass_on_error); + REQUIRE(result2.valid()); + auto result3 = lua.safe_script("f3(coroutine.create( function () end ) )", sol::script_pass_on_error); + REQUIRE(result3.valid()); + auto result4 = lua.safe_script("f4( function () end )", sol::script_pass_on_error); + REQUIRE(result4.valid()); + auto result5 = lua.safe_script("f5( function () end )", sol::script_pass_on_error); + REQUIRE(result5.valid()); + auto result6 = lua.safe_script("f6(ud)", sol::script_pass_on_error); + REQUIRE(result6.valid()); + } + SECTION("stack_reference") { + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::coroutine); + + lua["ud"] = base1{}; + + lua["f1"] = [](sol::stack_object o) -> sol::stack_object { return o; }; + lua["f2"] = [](sol::stack_table o) -> sol::stack_object { return std::move(o); }; + lua["f3"] = [](sol::stack_thread o) -> sol::stack_object { return std::move(o); }; + lua["f4"] = [](sol::stack_unsafe_function o) -> sol::stack_object { return std::move(o); }; + lua["f5"] = [](sol::stack_protected_function o) -> sol::stack_object { return std::move(o); }; + lua["f6"] = [](sol::stack_userdata o) -> sol::stack_object { return std::move(o); }; + auto result1 = lua.safe_script("f1(2)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("f2({})", sol::script_pass_on_error); + REQUIRE(result2.valid()); + auto result3 = lua.safe_script("f3(coroutine.create( function () end ) )", sol::script_pass_on_error); + REQUIRE(result3.valid()); + auto result4 = lua.safe_script("f4( function () end )", sol::script_pass_on_error); + REQUIRE(result4.valid()); + auto result5 = lua.safe_script("f5( function () end )", sol::script_pass_on_error); + REQUIRE(result5.valid()); + auto result6 = lua.safe_script("f6(ud)", sol::script_pass_on_error); + REQUIRE(result6.valid()); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/common_classes.hpp b/lib/sol2/tests/runtime_tests/source/common_classes.hpp new file mode 100644 index 0000000..1d02450 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/common_classes.hpp @@ -0,0 +1,192 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef SOL_TESTS_COMMON_CLASSES_HPP +#define SOL_TESTS_COMMON_CLASSES_HPP + +#include + +struct woof { + int var; + + int func(int x) { + return var + x; + } + + double func2(int x, int y) { + return var + x + y + 0.5; + } + + std::string func2s(int x, std::string y) { + return y + " " + std::to_string(x); + } +}; + +struct thing { + int v = 100; + + thing() { + } + thing(int x) : v(x) { + } +}; + +struct non_copyable { + non_copyable() = default; + non_copyable(non_copyable&& other) noexcept = default; + non_copyable& operator=(non_copyable&& other) noexcept = default; + non_copyable(const non_copyable& other) noexcept = delete; + non_copyable& operator=(const non_copyable& other) noexcept = delete; +}; + +struct vars { + vars() { + } + + int boop = 0; + + ~vars() { + } +}; + +struct fuser { + int x; + fuser() : x(0) { + } + + fuser(int x) : x(x) { + } + + int add(int y) { + return x + y; + } + + int add2(int y) { + return x + y + 2; + } +}; + +namespace crapola { + struct fuser { + int x; + fuser() : x(0) { + } + fuser(int x) : x(x) { + } + fuser(int x, int x2) : x(x * x2) { + } + + int add(int y) { + return x + y; + } + int add2(int y) { + return x + y + 2; + } + }; +} // namespace crapola + +class Base { +public: + Base(int a_num) : m_num(a_num) { + } + + int get_num() { + return m_num; + } + +protected: + int m_num; +}; + +class Derived : public Base { +public: + Derived(int a_num) : Base(a_num) { + } + + int get_num_10() { + return 10 * m_num; + } +}; + +class abstract_A { +public: + virtual void a() = 0; + virtual ~abstract_A() { + } +}; + +class abstract_B : public abstract_A { +public: + virtual void a() override { + std::cout << "overridden a() in B : public A - BARK" << std::endl; + } +}; + +struct Vec { + float x, y, z; + Vec(float x, float y, float z) : x{ x }, y{ y }, z{ z } { + } + float length() { + return sqrtf(x * x + y * y + z * z); + } + Vec normalized() { + float invS = 1 / length(); + return { x * invS, y * invS, z * invS }; + } +}; + +struct giver { + int a = 0; + + giver() { + } + + void gief() { + a = 1; + } + + static int stuff() { + std::cout << "stuff" << std::endl; + return 97; + } + + static void gief_stuff(giver& t, int a) { + t.a = a; + } + + ~giver() { + } +}; + +struct lua_object { + +#define MAX_INFO_STRING 64 + + char info[MAX_INFO_STRING]; + const char stuck_info[MAX_INFO_STRING]; + + lua_object() : info("blah"), stuck_info("solid") { + } +}; + +#endif // SOL_TESTS_COMMON_CLASSES_HPP \ No newline at end of file diff --git a/lib/sol2/tests/runtime_tests/source/container_semantics.cpp b/lib/sol2/tests/runtime_tests/source/container_semantics.cpp new file mode 100644 index 0000000..b06a396 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/container_semantics.cpp @@ -0,0 +1,439 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include // std::iota + +template +void sequence_container_check(sol::state& lua, T& items) { + { + auto r1 = lua.safe_script(R"( +for i=1,#c do + v = c[i] + assert(v == (i + 10)) +end + )", + sol::script_pass_on_error); + REQUIRE(r1.valid()); + } + { + auto r1 = lua.safe_script("i1 = c:find(11)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("i2 = c:find(14)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("io1 = c:index_of(12)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("io2 = c:index_of(13)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("v1 = c:get(1)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("v2 = c:get(3)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("c:set(2, 20)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("c:set(6, 16)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r5 = lua.safe_script("s1 = #c", sol::script_pass_on_error); + REQUIRE(r5.valid()); + auto r1 = lua.safe_script("c:erase(i1)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r3 = lua.safe_script("s2 = #c", sol::script_pass_on_error); + REQUIRE(r3.valid()); + auto r2 = lua.safe_script("c:erase(i2)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + auto r4 = lua.safe_script("s3 = #c", sol::script_pass_on_error); + REQUIRE(r4.valid()); + } + { + auto r = lua.safe_script("c:add(17)", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + auto r = lua.safe_script("c[#c + 1] = 18", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + auto r = lua.safe_script("v3 = c[#c]", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + auto backit = items.begin(); + std::size_t len = 0; + { + auto e = items.end(); + auto last = backit; + for (; backit != e; ++backit, ++len) { + if (backit == e) { + break; + } + last = backit; + } + backit = last; + } + const int& first = *items.begin(); + const int& last = *backit; + std::size_t i1 = lua["i1"]; + std::size_t i2 = lua["i2"]; + std::size_t io1 = lua["io1"]; + std::size_t io2 = lua["io2"]; + std::size_t s1 = lua["s1"]; + std::size_t s2 = lua["s2"]; + std::size_t s3 = lua["s3"]; + int v1 = lua["v1"]; + int v2 = lua["v2"]; + int v3 = lua["v3"]; + int values[6] = { + 20, 13, 14, 16, 17, 18 + }; + { + std::size_t idx = 0; + for (const auto& i : items) { + const auto& v = values[idx]; + REQUIRE((i == v)); + ++idx; + } + } + REQUIRE((s1 == 6)); + REQUIRE((s2 == 5)); + REQUIRE((s3 == 4)); + REQUIRE((len == 6)); + REQUIRE((first == 20)); + REQUIRE((last == 18)); + REQUIRE((i1 == 1)); + REQUIRE((i2 == 4)); + REQUIRE((io1 == 2)); + REQUIRE((io2 == 3)); + REQUIRE((v1 == 11)); + REQUIRE((v2 == 13)); + REQUIRE((v3 == 18)); +} + +template +void fixed_container_check(sol::state& lua, T& items) { + { + auto r1 = lua.safe_script(R"( +for i=1,#c do + v = c[i] + assert(v == (i + 10)) +end + )", sol::script_pass_on_error); + REQUIRE(r1.valid()); + } + { + auto r1 = lua.safe_script("i1 = c:find(11)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("i2 = c:find(14)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("io1 = c:index_of(11)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("io2 = c:index_of(14)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("v1 = c:get(2)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("v2 = c:get(5)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("c:set(2, 20)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("c:set(6, 16)", sol::script_pass_on_error); + REQUIRE_FALSE(r2.valid()); + } + { + auto r5 = lua.safe_script("s1 = #c", sol::script_pass_on_error); + REQUIRE(r5.valid()); + auto r1 = lua.safe_script("c:erase(i1)", sol::script_pass_on_error); + REQUIRE_FALSE(r1.valid()); + auto r3 = lua.safe_script("s2 = #c", sol::script_pass_on_error); + REQUIRE(r3.valid()); + auto r2 = lua.safe_script("c:erase(i2)", sol::script_pass_on_error); + REQUIRE_FALSE(r2.valid()); + auto r4 = lua.safe_script("s3 = #c", sol::script_pass_on_error); + REQUIRE(r4.valid()); + } + { + auto r = lua.safe_script("c:add(17)", sol::script_pass_on_error); + REQUIRE_FALSE(r.valid()); + } + { + auto r = lua.safe_script("c[5] = 18", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + auto r = lua.safe_script("v3 = c[4]", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + auto backit = std::begin(items); + std::size_t len = 0; + { + auto e = std::end(items); + auto last = backit; + for (; backit != e; ++backit, ++len) { + if (backit == e) { + break; + } + last = backit; + } + backit = last; + } + const int& first = *std::begin(items); + const int& last = *backit; + int i1 = lua["i1"]; + int i2 = lua["i2"]; + std::size_t s1 = lua["s1"]; + std::size_t s2 = lua["s2"]; + std::size_t s3 = lua["s3"]; + int v1 = lua["v1"]; + int v2 = lua["v2"]; + int v3 = lua["v3"]; + int values[] = { + 11, 20, 13, 14, 18 + }; + { + std::size_t idx = 0; + for (const auto& i : items) { + const auto& v = values[idx]; + REQUIRE((i == v)); + ++idx; + } + } + REQUIRE((first == 11)); + REQUIRE((last == 18)); + REQUIRE((s1 == 5)); + REQUIRE((s2 == 5)); + REQUIRE((s3 == 5)); + REQUIRE((len == 5)); + REQUIRE((i1 == 1)); + REQUIRE((i2 == 4)); + REQUIRE((v1 == 12)); + REQUIRE((v2 == 15)); + REQUIRE((v3 == 14)); +} + +TEST_CASE("containers/sequence containers", "check all of the functinos for every single container") { + SECTION("vector") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + std::vector items{ 11, 12, 13, 14, 15 }; + lua["c"] = &items; + sequence_container_check(lua, items); + } + SECTION("list") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + std::list items{ 11, 12, 13, 14, 15 }; + lua["c"] = &items; + sequence_container_check(lua, items); + } + SECTION("forward_list") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + std::forward_list items{ 11, 12, 13, 14, 15 }; + lua["c"] = &items; + sequence_container_check(lua, items); + } + SECTION("deque") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + std::deque items{ 11, 12, 13, 14, 15 }; + lua["c"] = &items; + sequence_container_check(lua, items); + } +} + +TEST_CASE("containers/fixed containers", "check immutable container types") { + SECTION("array") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + std::array items{ { 11, 12, 13, 14, 15 } }; + lua["c"] = &items; + fixed_container_check(lua, items); + } + SECTION("array ref") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + std::array items{ { 11, 12, 13, 14, 15 } }; + lua["c"] = std::ref(items); + fixed_container_check(lua, items); + } + SECTION("c array") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + int items[5] = { 11, 12, 13, 14, 15 }; + lua["c"] = &items; + fixed_container_check(lua, items); + } + SECTION("c array ref") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + int items[5] = { 11, 12, 13, 14, 15 }; + lua["c"] = std::ref(items); + fixed_container_check(lua, items); + } +} + +TEST_CASE("containers/auxiliary functions test", "make sure the manipulation functions are present and usable and working across various container types") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(); + + auto result1 = lua.safe_script(R"( +function g (x) + x:add(20) +end + +function h (x) + x:add(20, 40) +end + +function i (x) + x:clear() +end + +function sf (x,v) + return x:find(v) +end + +)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + // Have the function we + // just defined in Lua + sol::function g = lua["g"]; + sol::function h = lua["h"]; + sol::function i = lua["i"]; + sol::function sf = lua["sf"]; + + // Set a global variable called + // "arr" to be a vector of 5 lements + lua["c_arr"] = std::array{ { 2, 4, 6, 8, 10 } }; + lua["arr"] = std::vector{ 2, 4, 6, 8, 10 }; + lua["map"] = std::map{ { 1, 2 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, { 5, 10 } }; + lua["set"] = std::set{ 2, 4, 6, 8, 10 }; + std::array& c_arr = lua["c_arr"]; + std::vector& arr = lua["arr"]; + std::map& map = lua["map"]; + std::set& set = lua["set"]; + REQUIRE(c_arr.size() == 5); + REQUIRE(arr.size() == 5); + REQUIRE(map.size() == 5); + REQUIRE(set.size() == 5); + + g(lua["set"]); + g(lua["arr"]); + h(lua["map"]); + REQUIRE(arr.size() == 6); + REQUIRE(map.size() == 6); + REQUIRE(set.size() == 6); + + { + int r = sf(set, 8); + REQUIRE(r == 8); + sol::object rn = sf(set, 9); + REQUIRE(rn == sol::lua_nil); + } + + { + int r = sf(map, 3); + REQUIRE(r == 6); + sol::object rn = sf(map, 9); + REQUIRE(rn == sol::lua_nil); + } + + i(lua["arr"]); + i(lua["map"]); + i(lua["set"]); + REQUIRE(arr.empty()); + REQUIRE(map.empty()); + REQUIRE(set.empty()); + + auto result2 = lua.safe_script(R"( +c_arr[1] = 7 +c_arr[2] = 7 +c_arr[3] = 7 +)", sol::script_pass_on_error); + REQUIRE(result2.valid()); +} + +TEST_CASE("containers/indices test", "test indices on fixed array types") { +#if 0 + SECTION("zero index test") { + sol::state lua; + sol::stack_guard luasg(lua); + + lua["c_arr"] = std::array{ { 2, 4, 6, 8, 10 } }; + auto result = lua.safe_script(R"( +c_arr[0] = 7 +)", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } + + SECTION("negative index test") { + sol::state lua; + sol::stack_guard luasg(lua); + + lua["c_arr"] = std::array{ { 2, 4, 6, 8, 10 } }; + auto result = lua.safe_script(R"( +c_arr[-1] = 7 +)", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } +#endif // Something is wrong with g++'s lower versions: it always fails this test... +} diff --git a/lib/sol2/tests/runtime_tests/source/container_semantics.custom.cpp b/lib/sol2/tests/runtime_tests/source/container_semantics.custom.cpp new file mode 100644 index 0000000..79dfb9d --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/container_semantics.custom.cpp @@ -0,0 +1,36 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include // std::iota diff --git a/lib/sol2/tests/runtime_tests/source/container_semantics.ordered.cpp b/lib/sol2/tests/runtime_tests/source/container_semantics.ordered.cpp new file mode 100644 index 0000000..8287518 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/container_semantics.ordered.cpp @@ -0,0 +1,377 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include + +template +void ordered_container_check(sol::state& lua, T& items) { + { + auto r1 = lua.safe_script(R"( +for i=1,#c do + v = c[(i + 10)] + assert(v == (i + 10)) +end + )", + sol::script_pass_on_error); + REQUIRE(r1.valid()); + } + { + auto r1 = lua.safe_script("i1 = c:find(11)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("i2 = c:find(14)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("io1 = c:index_of(12)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("io2 = c:index_of(13)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("v1 = c:get(11)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("v2 = c:get(13)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("c:set(20)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("c:set(16)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r5 = lua.safe_script("s1 = #c", sol::script_pass_on_error); + REQUIRE(r5.valid()); + auto r1 = lua.safe_script("c:erase(i1)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r3 = lua.safe_script("s2 = #c", sol::script_pass_on_error); + REQUIRE(r3.valid()); + auto r2 = lua.safe_script("c:erase(i2)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + auto r4 = lua.safe_script("s3 = #c", sol::script_pass_on_error); + REQUIRE(r4.valid()); + } + { + auto r = lua.safe_script("c:add(17)", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + auto r = lua.safe_script("c[18] = true", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + auto r = lua.safe_script("v3 = c[20]", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + auto backit = items.begin(); + std::size_t len = 0; + { + auto e = items.end(); + auto last = backit; + for (; backit != e; ++backit, ++len) { + if (backit == e) { + break; + } + last = backit; + } + backit = last; + } + const int& first = *items.begin(); + const int& last = *backit; + int i1 = lua["i1"]; + int i2 = lua["i2"]; + int io1 = lua["io1"]; + int io2 = lua["io2"]; + std::size_t s1 = lua["s1"]; + std::size_t s2 = lua["s2"]; + std::size_t s3 = lua["s3"]; + int v1 = lua["v1"]; + int v2 = lua["v2"]; + int v3 = lua["v3"]; + int values[] = { 12, 13, 15, 16, 17, 18, 20 }; + { + std::size_t idx = 0; + for (const auto& i : items) { + const auto& v = values[idx]; + REQUIRE((i == v)); + ++idx; + } + } + REQUIRE((s1 == 7)); + REQUIRE((s2 == 6)); + REQUIRE((s3 == 5)); + REQUIRE((len == 7)); + REQUIRE((first == 12)); + REQUIRE((last == 20)); + REQUIRE((i1 == 11)); + REQUIRE((i2 == 14)); + REQUIRE((io1 == 2)); + REQUIRE((io2 == 3)); + REQUIRE((v1 == 11)); + REQUIRE((v2 == 13)); + REQUIRE((v3 == 20)); +} + +template +void associative_ordered_container_check(sol::state& lua, T& items) { + { + auto r1 = lua.safe_script(R"( +for i=1,#c do + v = c[(i + 10)] + assert(v == (i + 20)) +end + )", + sol::script_pass_on_error); + REQUIRE(r1.valid()); + } + { + auto r1 = lua.safe_script("i1 = c:find(11)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("i2 = c:find(14)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("io1 = c:index_of(12)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("io2 = c:index_of(13)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("v1 = c:get(11)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("v2 = c:get(13)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("c:set(20, 30)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("c:set(16, 26)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + auto r3 = lua.safe_script("c:set(12, 31)", sol::script_pass_on_error); + REQUIRE(r3.valid()); + } + { + auto r5 = lua.safe_script("s1 = #c", sol::script_pass_on_error); + REQUIRE(r5.valid()); + auto r1 = lua.safe_script("c:erase(11)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r3 = lua.safe_script("s2 = #c", sol::script_pass_on_error); + REQUIRE(r3.valid()); + auto r2 = lua.safe_script("c:erase(14)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + auto r4 = lua.safe_script("s3 = #c", sol::script_pass_on_error); + REQUIRE(r4.valid()); + } + { + auto r = lua.safe_script("c:add(17, 27)", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + auto r = lua.safe_script("c[18] = 28", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + auto r = lua.safe_script("v3 = c[20]", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + auto backit = items.begin(); + std::size_t len = 0; + { + auto e = items.end(); + auto last = backit; + for (; backit != e; ++backit, ++len) { + if (backit == e) { + break; + } + last = backit; + } + backit = last; + } + const std::pair& first = *items.begin(); + const std::pair& last = *backit; + int i1 = lua["i1"]; + int i2 = lua["i2"]; + int io1 = lua["io1"]; + int io2 = lua["io2"]; + std::size_t s1 = lua["s1"]; + std::size_t s2 = lua["s2"]; + std::size_t s3 = lua["s3"]; + int v1 = lua["v1"]; + int v2 = lua["v2"]; + int v3 = lua["v3"]; + std::pair values[] + = { { (short)12, 31 }, { (short)13, 23 }, { (short)15, 25 }, { (short)16, 26 }, { (short)17, 27 }, { (short)18, 28 }, { (short)20, 30 } }; + { + std::size_t idx = 0; + for (const auto& i : items) { + const auto& v = values[idx]; + REQUIRE((i == v)); + ++idx; + } + } + REQUIRE((s1 == 7)); + REQUIRE((s2 == 6)); + REQUIRE((s3 == 5)); + REQUIRE((len == 7)); + REQUIRE((first.first == 12)); + REQUIRE((last.first == 20)); + REQUIRE((first.second == 31)); + REQUIRE((last.second == 30)); + REQUIRE((i1 == 21)); + REQUIRE((i2 == 24)); + REQUIRE((io1 == 2)); + REQUIRE((io2 == 3)); + REQUIRE((v1 == 21)); + REQUIRE((v2 == 23)); + REQUIRE((v3 == 30)); +} + +template +void associative_ordered_container_key_value_check(sol::state& lua, T& data, T& reflect) { + typedef typename T::key_type K; + typedef typename T::mapped_type V; + lua["collect"] = [&reflect](K k, V v) { reflect.insert({ k, v }); }; + +#if SOL_LUA_VERSION > 502 + lua["val"] = data; + auto r = lua.safe_script(R"( +for k, v in pairs(val) do + collect(k, v) +end +print() +)", + sol::script_pass_on_error); + REQUIRE(r.valid()); +#else + reflect = data; +#endif + REQUIRE((data == reflect)); +} + +template +void ordered_lookup_container_check(sol::state& lua, T&) { + auto result0 = lua.safe_script("assert(c['a'] == 'a')", sol::script_default_on_error); + REQUIRE(result0.valid()); + auto result1 = lua.safe_script("assert(c['b'] == 'b')", sol::script_default_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("assert(c['c'] == 'c')", sol::script_default_on_error); + REQUIRE(result2.valid()); +} + +TEST_CASE("containers/ordered lookup containers", "check ordered container types") { + SECTION("set") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::set items{ 11, 12, 13, 14, 15 }; + lua["c"] = &items; + ordered_container_check(lua, items); + } + SECTION("set string") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::set items({ "a", "b", "c" }); + lua["c"] = &items; + ordered_lookup_container_check(lua, items); + } + SECTION("multiset") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::multiset items{ 11, 12, 13, 14, 15 }; + lua["c"] = &items; + ordered_container_check(lua, items); + } + SECTION("multiset string") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::multiset items({ "a", "b", "c" }); + lua["c"] = &items; + ordered_lookup_container_check(lua, items); + } +} + +TEST_CASE("containers/associative ordered containers", "check associative (map) containers that are ordered fulfill basic functionality requirements") { + SECTION("map") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::map items{ { (short)11, 21 }, { (short)12, 22 }, { (short)13, 23 }, { (short)14, 24 }, { (short)15, 25 } }; + lua["c"] = &items; + associative_ordered_container_check(lua, items); + } + SECTION("map string") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::map items{ { "a", "a" }, { "b", "b" }, { "c", "c" } }; + lua["c"] = &items; + ordered_lookup_container_check(lua, items); + } + SECTION("multimap") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::multimap items{ { (short)11, 21 }, { (short)12, 22 }, { (short)13, 23 }, { (short)14, 24 }, { (short)15, 25 } }; + lua["c"] = &items; + associative_ordered_container_check(lua, items); + } + SECTION("multimap string") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::multimap items{ { "a", "a" }, { "b", "b" }, { "c", "c" } }; + lua["c"] = &items; + ordered_lookup_container_check(lua, items); + } +} + +TEST_CASE("containers/associative ordered pairs", "check to make sure pairs works properly for key-value types") { + struct bar {}; + std::unique_ptr ua(new bar()), ub(new bar()), uc(new bar()); + bar* a = ua.get(); + bar* b = ub.get(); + bar* c = uc.get(); + + SECTION("map") { + sol::state lua; + lua.open_libraries(sol::lib::base); + std::map data({ { "a", a }, { "b", b }, { "c", c } }); + std::map reflect; + associative_ordered_container_key_value_check(lua, data, reflect); + } + SECTION("multimap") { + sol::state lua; + lua.open_libraries(sol::lib::base); + std::multimap data({ { "a", a }, { "b", b }, { "c", c } }); + std::multimap reflect; + associative_ordered_container_key_value_check(lua, data, reflect); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/container_semantics.unordered.cpp b/lib/sol2/tests/runtime_tests/source/container_semantics.unordered.cpp new file mode 100644 index 0000000..de80cb8 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/container_semantics.unordered.cpp @@ -0,0 +1,269 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include + + +template +void unordered_container_check(sol::state& lua, T& items) { + { + auto r1 = lua.safe_script("i1 = c:find(11)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("i2 = c:find(14)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("io1 = c:index_of(12)", sol::script_pass_on_error); + REQUIRE_FALSE(r1.valid()); + auto r2 = lua.safe_script("io2 = c:index_of(13)", sol::script_pass_on_error); + REQUIRE_FALSE(r2.valid()); + } + { + auto r1 = lua.safe_script("v1 = c:get(11)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("v2 = c:get(13)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("c:set(20)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("c:set(16)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r5 = lua.safe_script("s1 = #c", sol::script_pass_on_error); + REQUIRE(r5.valid()); + auto r1 = lua.safe_script("c:erase(i1)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r3 = lua.safe_script("s2 = #c", sol::script_pass_on_error); + REQUIRE(r3.valid()); + auto r2 = lua.safe_script("c:erase(i2)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + auto r4 = lua.safe_script("s3 = #c", sol::script_pass_on_error); + REQUIRE(r4.valid()); + } + { + auto r = lua.safe_script("c:add(17)", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + auto r = lua.safe_script("c[18] = true", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + auto r = lua.safe_script("v3 = c[20]", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + std::size_t len = items.size(); + int i1 = lua["i1"]; + int i2 = lua["i2"]; + std::size_t s1 = lua["s1"]; + std::size_t s2 = lua["s2"]; + std::size_t s3 = lua["s3"]; + int v1 = lua["v1"]; + int v2 = lua["v2"]; + int v3 = lua["v3"]; + int values[] = { 12, 13, 15, 16, 17, 18, 20 }; + { + for (const auto& v : values) { + auto it = items.find(v); + REQUIRE((it != items.cend())); + REQUIRE((*it == v)); + } + } + REQUIRE((s1 == 7)); + REQUIRE((s2 == 6)); + REQUIRE((s3 == 5)); + REQUIRE((len == 7)); + REQUIRE((i1 == 11)); + REQUIRE((i2 == 14)); + REQUIRE((v1 == 11)); + REQUIRE((v2 == 13)); + REQUIRE((v3 == 20)); +} + +template +void associative_unordered_container_check(sol::state& lua, T& items) { + { + auto r1 = lua.safe_script("i1 = c:find(11)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("i2 = c:find(14)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("io1 = c:index_of(12)", sol::script_pass_on_error); + REQUIRE_FALSE(r1.valid()); + auto r2 = lua.safe_script("io2 = c:index_of(13)", sol::script_pass_on_error); + REQUIRE_FALSE(r2.valid()); + } + { + auto r1 = lua.safe_script("v1 = c:get(11)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("v2 = c:get(13)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + } + { + auto r1 = lua.safe_script("c:set(20, 30)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r2 = lua.safe_script("c:set(16, 26)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + auto r3 = lua.safe_script("c:set(12, 31)", sol::script_pass_on_error); + REQUIRE(r3.valid()); + } + { + auto r5 = lua.safe_script("s1 = #c", sol::script_pass_on_error); + REQUIRE(r5.valid()); + auto r1 = lua.safe_script("c:erase(11)", sol::script_pass_on_error); + REQUIRE(r1.valid()); + auto r3 = lua.safe_script("s2 = #c", sol::script_pass_on_error); + REQUIRE(r3.valid()); + auto r2 = lua.safe_script("c:erase(14)", sol::script_pass_on_error); + REQUIRE(r2.valid()); + auto r4 = lua.safe_script("s3 = #c", sol::script_pass_on_error); + REQUIRE(r4.valid()); + } + { + auto r = lua.safe_script("c:add(17, 27)", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + auto r = lua.safe_script("c[18] = 28", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + auto r = lua.safe_script("v3 = c[20]", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + std::size_t len = items.size(); + int i1 = lua["i1"]; + int i2 = lua["i2"]; + std::size_t s1 = lua["s1"]; + std::size_t s2 = lua["s2"]; + std::size_t s3 = lua["s3"]; + int v1 = lua["v1"]; + int v2 = lua["v2"]; + int v3 = lua["v3"]; + std::pair values[] + = { { (short)12, 31 }, { (short)13, 23 }, { (short)15, 25 }, { (short)16, 26 }, { (short)17, 27 }, { (short)18, 28 }, { (short)20, 30 } }; + { + for (const auto& v : values) { + auto it = items.find(v.first); + REQUIRE((it != items.cend())); + REQUIRE((it->second == v.second)); + } + } + REQUIRE((s1 == 7)); + REQUIRE((s2 == 6)); + REQUIRE((s3 == 5)); + REQUIRE((len == 7)); + REQUIRE((i1 == 21)); + REQUIRE((i2 == 24)); + REQUIRE((v1 == 21)); + REQUIRE((v2 == 23)); + REQUIRE((v3 == 30)); +} + +template +void unordered_lookup_container_check(sol::state& lua, T&) { + auto result0 = lua.safe_script("assert(c['a'] == 'a')", sol::script_default_on_error); + REQUIRE(result0.valid()); + auto result1 = lua.safe_script("assert(c['b'] == 'b')", sol::script_default_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("assert(c['c'] == 'c')", sol::script_default_on_error); + REQUIRE(result2.valid()); +} + +TEST_CASE("containers/unordered lookup containers", "check ordered container types") { + SECTION("unordered_set") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::unordered_set items{ 11, 12, 13, 14, 15 }; + lua["c"] = &items; + unordered_container_check(lua, items); + } + SECTION("unordered_set string") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::unordered_set items({ "a", "b", "c" }); + lua["c"] = &items; + unordered_lookup_container_check(lua, items); + } + SECTION("unordered_multiset") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::unordered_multiset items{ 11, 12, 13, 14, 15 }; + lua["c"] = &items; + unordered_container_check(lua, items); + } + SECTION("unordered_multiset string") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::unordered_multiset items({ "a", "b", "c" }); + lua["c"] = &items; + unordered_lookup_container_check(lua, items); + } +} + +TEST_CASE("containers/associative unordered containers", "check associative (map) containers that are ordered that they fulfill basic requirements") { + SECTION("unordered_map") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::unordered_map items{ { (short)11, 21 }, { (short)12, 22 }, { (short)13, 23 }, { (short)14, 24 }, { (short)15, 25 } }; + lua["c"] = &items; + associative_unordered_container_check(lua, items); + } + SECTION("unordered_map string") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::unordered_map items{ { "a", "a" }, { "b", "b" }, { "c", "c" } }; + lua["c"] = &items; + unordered_lookup_container_check(lua, items); + } + SECTION("unordered_multimap") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::unordered_multimap items{ { (short)11, 21 }, { (short)12, 22 }, { (short)13, 23 }, { (short)14, 24 }, { (short)15, 25 } }; + lua["c"] = &items; + associative_unordered_container_check(lua, items); + } + SECTION("unordered_multimap string") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::unordered_multimap items{ { "a", "a" }, { "b", "b" }, { "c", "c" } }; + lua["c"] = &items; + unordered_lookup_container_check(lua, items); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/container_shims.cpp b/lib/sol2/tests/runtime_tests/source/container_shims.cpp new file mode 100644 index 0000000..6e2d93d --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/container_shims.cpp @@ -0,0 +1,311 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class int_shim { +public: + int_shim() = default; + + int_shim(int x) : x_(x) { + } + + int val() const { + return x_; + } + +private: + int x_ = -1; +}; + +class input_it { +public: + typedef std::input_iterator_tag iterator_category; + typedef int_shim value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef std::ptrdiff_t difference_type; + + input_it() = default; + + input_it(int n, int m) : n_(n), m_(m), value_(n_) { + assert(n_ >= 0); + assert(m_ >= 0); + assert(n_ <= m_); + + if (!n_ && !m_) { + n_ = -1; + m_ = -1; + value_ = -1; + } + } + + const int_shim& operator*() const { + return value_; + } + + const int_shim* operator->() const { + return &value_; + } + + input_it& operator++() { + assert(n_ >= 0); + assert(m_ >= 0); + if (n_ == m_ - 1) { + n_ = m_ = -1; + } + else { + ++n_; + } + value_ = n_; + return *this; + } + + bool operator==(const input_it& i) const { + return n_ == i.n_ && m_ == i.m_; + } + + bool operator!=(const input_it& i) const { + return !(*this == i); + } + +private: + int n_ = -1; + int m_ = -1; + int_shim value_; +}; + +class not_really_a_container { +public: + using value_type = int_shim; + using iterator = input_it; + using const_iterator = input_it; + + const_iterator begin() const { + return iterator(0, 100); + } + + const_iterator end() const { + return iterator(); + } + + value_type gcc_warning_block() { + return int_shim(); + } + + std::size_t size() const { + return 100; + } +}; + +struct my_vec : public std::vector { + typedef std::vector base_t; + using base_t::base_t; +}; + +namespace sol { + template <> + struct is_container : std::true_type {}; + + template <> + struct usertype_container { + static auto begin(lua_State*, my_vec& self) { + return self.begin(); + } + static auto end(lua_State*, my_vec& self) { + return self.end(); + } + static std::ptrdiff_t index_adjustment(lua_State*, my_vec&) { + return 0; + } + }; + +} // namespace sol + +struct order_suit { + std::vector> objs; + std::vector> objs2; + + order_suit(int pairs) { + objs.reserve(pairs); + objs2.reserve(pairs * 2); + for (int i = 0; i < pairs; ++i) { + objs.push_back({ i, i * 10 }); + objs2.push_back({ (i + pairs) * 2, (i * 2) * 50 }); + objs2.push_back({ ((i + pairs) * 2) + 1, (i * 2 + 1) * 50 }); + } + } +}; + +TEST_CASE("containers/input iterators", "test shitty input iterators that are all kinds of B L E H") { + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::package); + lua.new_usertype("int_shim", "new", sol::no_constructor, "val", &int_shim::val); + + not_really_a_container c; + lua["c"] = &c; +#if SOL_LUA_VERSION > 502 + auto result0 = lua.safe_script(R"lua( +for k, v in pairs(c) do + assert((k - 1) == v:val()) +end +)lua", + sol::script_pass_on_error); + REQUIRE(result0.valid()); + +#endif + auto result1 = lua.safe_script(R"lua( +for k=1,#c do + v = c[k] + assert((k - 1) == v:val()) +end +)lua", + sol::script_pass_on_error); + REQUIRE(result1.valid()); +} + +TEST_CASE("containers/custom indexing", "allow containers to set a custom indexing offset") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua["c"] = my_vec{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + + auto result1 = lua.safe_script("for i=0,9 do assert(i == c[i]) end", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("assert(c[10] == nil)", sol::script_pass_on_error); + REQUIRE(result2.valid()); + auto result3 = lua.safe_script("assert(c[-1] == nil)", sol::script_pass_on_error); + REQUIRE(result3.valid()); +} + +TEST_CASE("containers/containers of pointers", "containers of pointers shouldn't have their value_type's overly stripped") { + sol::state lua; + + class MyContainer { + public: + typedef int** iterator; + typedef int* value_type; + + std::vector m_vec; + + inline iterator begin() { + return m_vec.data(); + } + inline iterator end() { + return m_vec.data() + m_vec.size(); + } + inline void push_back(value_type v) { + m_vec.push_back(v); + } + }; + int a = 500; + int b = 600; + + MyContainer ctr; + ctr.push_back(&a); + ctr.push_back(&b); + lua["c"] = ctr; + { + auto result1 = lua.safe_script("ap = c[1]", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("bp = c[2]", sol::script_pass_on_error); + REQUIRE(result2.valid()); + int* ap = lua["ap"]; + int* bp = lua["bp"]; + REQUIRE(ap == &a); + REQUIRE(bp == &b); + REQUIRE(*ap == 500); + REQUIRE(*bp == 600); + } + + std::unordered_map ptrs; + ptrs[5] = &a; + ptrs[6] = &b; + lua["c2"] = ptrs; + { + auto result1 = lua.safe_script("ap = c2[5]", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("bp = c2[6]", sol::script_pass_on_error); + REQUIRE(result2.valid()); + int* ap = lua["ap"]; + int* bp = lua["bp"]; + REQUIRE(ap == &a); + REQUIRE(bp == &b); + REQUIRE(*ap == 500); + REQUIRE(*bp == 600); + } +} + +TEST_CASE("containers/pair container in usertypes", "make sure containers that use pairs in usertypes do not trigger compiler errors") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + auto orderSuit = lua.new_usertype("order_suit", sol::constructors()); +#define SET_PROP(__PROP__) orderSuit.set(#__PROP__, &order_suit::__PROP__) + SET_PROP(objs); + SET_PROP(objs2); +#undef SET_PROP + + auto result1 = lua.safe_script("osobj = order_suit.new(5)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("pvec = osobj.objs", sol::script_pass_on_error); + REQUIRE(result2.valid()); + auto result3 = lua.safe_script("pvec2 = osobj.objs2", sol::script_pass_on_error); + REQUIRE(result3.valid()); + using vec_t = std::remove_reference_t().objs)>; + using vec2_t = std::remove_reference_t().objs2)>; + vec_t& pvec = lua["pvec"]; + vec2_t& pvec2 = lua["pvec2"]; + REQUIRE(pvec.size() == 5); + REQUIRE(pvec2.size() == 10); + + REQUIRE(pvec[0].first == 0); + REQUIRE(pvec[0].second == 0); + REQUIRE(pvec[1].first == 1); + REQUIRE(pvec[1].second == 10); + REQUIRE(pvec[2].first == 2); + REQUIRE(pvec[2].second == 20); + + REQUIRE(pvec2[0].first == 10); + REQUIRE(pvec2[0].second == 0); + REQUIRE(pvec2[1].first == 11); + REQUIRE(pvec2[1].second == 50); + REQUIRE(pvec2[2].first == 12); + REQUIRE(pvec2[2].second == 100); + REQUIRE(pvec2[3].first == 13); + REQUIRE(pvec2[3].second == 150); +} diff --git a/lib/sol2/tests/runtime_tests/source/container_table.cpp b/lib/sol2/tests/runtime_tests/source/container_table.cpp new file mode 100644 index 0000000..9cda226 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/container_table.cpp @@ -0,0 +1,307 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" +#include "common_classes.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +TEST_CASE("containers/vector table roundtrip", "make sure vectors can be round-tripped") { + sol::state lua; + std::vector v{ 1, 2, 3 }; + lua.set_function("f", [&]() { + return sol::as_table(v); + }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::as_table_t> x = lua["x"]; + bool areequal = x.value() == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/deque table roundtrip", "make sure deques can be round-tripped") { + sol::state lua; + std::deque v{ 1, 2, 3 }; + lua.set_function("f", [&]() { + return sol::as_table(v); + }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::as_table_t> x = lua["x"]; + bool areequal = x.value() == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/array table roundtrip", "make sure arrays can be round-tripped") { + sol::state lua; + std::array v{ { 1, 2, 3 } }; + lua.set_function("f", [&]() { + return sol::as_table(v); + }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::as_table_t> x = lua["x"]; + bool areequal = x.value() == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/list table roundtrip", "make sure lists can be round-tripped") { + sol::state lua; + std::list v{ 1, 2, 3 }; + lua.set_function("f", [&]() { + return sol::as_table(v); + }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::as_table_t> x = lua["x"]; + bool areequal = x.value() == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/forward_list table roundtrip", "make sure forward_lists can be round-tripped") { + sol::state lua; + std::forward_list v{ 1, 2, 3 }; + lua.set_function("f", [&]() { + return sol::as_table(v); + }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::as_table_t> x = lua["x"]; + bool areequal = x.value() == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/map table roundtrip", "make sure maps can be round-tripped") { + sol::state lua; + std::map v{ { "a", 1 }, { "b", 2 }, { "c", 3 } }; + lua.set_function("f", [&]() { + return sol::as_table(v); + }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::as_table_t> x = lua["x"]; + bool areequal = x.value() == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/unordered_map table roundtrip", "make sure unordered_maps can be round-tripped") { + sol::state lua; + std::unordered_map v{ { "a", 1 }, { "b", 2 }, { "c", 3 } }; + lua.set_function("f", [&]() { + return sol::as_table(v); + }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::as_table_t> x = lua["x"]; + bool areequal = x.value() == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/unordered_set table roundtrip", "make sure unordered_sets can be round-tripped") { + sol::state lua; + std::unordered_set v{ 1, 2, 3 }; + lua.set_function("f", [&]() { + return sol::as_table(v); + }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::as_table_t> x = lua["x"]; + bool areequal = x.value() == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/set table roundtrip", "make sure sets can be round-tripped") { + sol::state lua; + std::set v{ 1, 2, 3 }; + lua.set_function("f", [&]() { + return sol::as_table(v); + }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::as_table_t> x = lua["x"]; + bool areequal = x.value() == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/table conversions (lvalue)", "test table conversions with as_table and nested, when not directly serializing a temporary / new value") { + sol::state lua; + + auto f = []() { + std::vector response_words; + response_words.push_back("a"); + response_words.push_back("b"); + response_words.push_back("c"); + return sol::as_table(response_words); + }; + auto g = []() { + std::vector response_words; + response_words.push_back("a"); + response_words.push_back("b"); + response_words.push_back("c"); + return sol::as_nested(response_words); + }; + + lua["f"] = std::ref(f); + lua["g"] = std::ref(g); + + sol::safe_function sff = lua["f"]; + sol::safe_function sfg = lua["g"]; + sol::table tf = sff(); + sol::table tg = sfg(); + + std::string af = tf[1]; + std::string bf = tf[2]; + std::string cf = tf[3]; + std::string ag = tf[1]; + std::string bg = tf[2]; + std::string cg = tf[3]; + REQUIRE(tf.size() == 3); + REQUIRE(af == "a"); + REQUIRE(bf == "b"); + REQUIRE(cf == "c"); + REQUIRE(tg.size() == 3); + REQUIRE(ag == "a"); + REQUIRE(bg == "b"); + REQUIRE(cg == "c"); +} + +TEST_CASE("containers/table conversions (std::ref)", "test table conversions with as_table and nested, when not directly serializing a temporary / new value") { + sol::state lua; + + std::vector response_words; + response_words.push_back("a"); + response_words.push_back("b"); + response_words.push_back("c"); + auto f = [&response_words]() { return sol::as_table(std::ref(response_words)); }; + auto g = [&response_words]() { return sol::as_nested(std::ref(response_words)); }; + + lua["f"] = std::ref(f); + lua["g"] = std::ref(g); + + sol::safe_function sff = lua["f"]; + sol::safe_function sfg = lua["g"]; + sol::table tf = sff(); + sol::table tg = sfg(); + + std::string af = tf[1]; + std::string bf = tf[2]; + std::string cf = tf[3]; + std::string ag = tf[1]; + std::string bg = tf[2]; + std::string cg = tf[3]; + REQUIRE(tf.size() == 3); + REQUIRE(af == "a"); + REQUIRE(bf == "b"); + REQUIRE(cf == "c"); + REQUIRE(tg.size() == 3); + REQUIRE(ag == "a"); + REQUIRE(bg == "b"); + REQUIRE(cg == "c"); +} + +TEST_CASE("containers/table conversion", "test table conversions with as_table and nested") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.set_function("bark", []() { return sol::as_nested(std::vector{ "bark", "woof" }); }); + + lua.set_function("woof", []() { return sol::as_nested(std::vector{ "bark", "woof" }); }); + + auto result1 = lua.safe_script("v1 = bark()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("v2 = woof()", sol::script_pass_on_error); + REQUIRE(result2.valid()); + + sol::as_table_t> as_table_strings = lua["v1"]; + sol::nested> nested_strings = lua["v2"]; + + std::vector expected_values{ "bark", "woof" }; + REQUIRE(as_table_strings.value() == expected_values); + REQUIRE(nested_strings.value() == expected_values); +} + +TEST_CASE("containers/from table argument conversions", "test table conversions without as_table and nested for function args") { + const std::vector expected_values{ "bark", "woof" }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.set_function("f", [&](std::vector t) { return t == expected_values; }); + + auto result0 = lua.safe_script("t = { \"bark\", \"woof\" }"); + REQUIRE(result0.valid()); + + auto result1 = lua.safe_script("assert(f(t))", sol::script_pass_on_error); + REQUIRE(result1.valid()); + + sol::function f = lua["f"]; + sol::table t = lua["t"]; + bool passed = f(t); + REQUIRE(passed); +} + +TEST_CASE("containers/deeply nested", "make sure nested works for deeply-nested C++ containers and works as advertised") { + typedef std::map info_t; + typedef std::vector info_vector; + + class ModList { + public: + info_vector list; + + ModList() { + list.push_back(info_t{ { "a", "b" } }); + } + + sol::nested getList() { + return sol::nested(list); + } + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("ModList", "getList", &ModList::getList); + + sol::string_view code = R"( +mods = ModList.new() +local modlist = mods:getList() +print(modlist[1]) +assert(type(modlist) == "table") +assert(type(modlist[1]) == "table") +)"; + + auto result1 = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE(result1.valid()); +} diff --git a/lib/sol2/tests/runtime_tests/source/containers.cpp b/lib/sol2/tests/runtime_tests/source/containers.cpp new file mode 100644 index 0000000..e03ed3f --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/containers.cpp @@ -0,0 +1,538 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" +#include "common_classes.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +TEST_CASE("containers/returns", "make sure that even references to vectors are being serialized as tables") { + sol::state lua; + std::vector v{ 1, 2, 3 }; + auto f = [&]() -> std::vector& { + REQUIRE(v.size() == 3); + return v; + }; + lua.set_function("f", f); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::object x = lua["x"]; + sol::type xt = x.get_type(); + REQUIRE(xt == sol::type::userdata); + sol::table t = x; + bool matching; + matching = t[1] == 1; + REQUIRE(matching); + matching = t[2] == 2; + REQUIRE(matching); + matching = t[3] == 3; + REQUIRE(matching); +} + +TEST_CASE("containers/custom usertype", "make sure container usertype metatables can be overridden") { + typedef std::unordered_map bark; + + sol::state lua; + lua.open_libraries(); + lua.new_usertype("bark", + "something", + [](const bark& b) { INFO("It works: " << b.at(24)); }, + "size", + &bark::size, + "at", + sol::resolve(&bark::at), + "clear", + &bark::clear); + bark obj{ { 24, 50 } }; + lua.set("a", &obj); + { + auto result0 = lua.safe_script("assert(a:at(24) == 50)", sol::script_pass_on_error); + REQUIRE(result0.valid()); + auto result1 = lua.safe_script("a:something()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + } + lua.set("a", obj); + { + auto result = lua.safe_script("assert(a:at(24) == 50)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("a:something()", sol::script_pass_on_error); + REQUIRE(result.valid()); + } +} + +TEST_CASE("containers/const serialization kvp", "make sure const keys / values are respected") { + typedef std::map bark; + + sol::state lua; + lua.open_libraries(); + { + 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()); + auto result1 = lua.safe_script("a[24] = 51", sol::script_pass_on_error); + REQUIRE_FALSE(result1.valid()); + auto result2 = lua.safe_script("assert(a[24] == 50)", sol::script_pass_on_error); + REQUIRE(result2.valid()); + } +} + +TEST_CASE("containers/basic serialization", "make sure containers are turned into proper userdata and have basic hooks established") { + typedef std::vector 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 }); + { + 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 }; + lua.set("b", w); + { + auto result = lua.safe_script("for k = 1, #b do assert(k == b[k]) end", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + lua.set("b", &w); + { + auto result = lua.safe_script("for k = 1, #b do assert(k == b[k]) end", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + lua.set("b", std::ref(w)); + { + auto result = lua.safe_script("for k = 1, #b do assert(k == b[k]) end", sol::script_pass_on_error); + REQUIRE(result.valid()); + } +} + +#if 0 // LUL const int holders +TEST_CASE("containers/const serialization", "make sure containers are turned into proper userdata and the basic hooks respect const-ness") { + typedef std::vector 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 }); + { + auto result = lua.safe_script("for k, v in pairs(b) do assert(k == v) end", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("b[1] = 20", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } +} +#endif + +TEST_CASE("containers/const correctness", "usertype metatable names should reasonably ignore const attributes") { + struct Vec { + int x, y, z; + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + lua.new_usertype("Vec", "x", &Vec::x, "y", &Vec::y, "z", &Vec::z); + + Vec vec; + vec.x = 1; + vec.y = 2; + vec.z = -3; + + std::vector foo; + foo.push_back(vec); + + std::vector bar; + bar.push_back(&vec); + + auto result0 = lua.safe_script(R"( +func = function(vecs) + for i = 1, #vecs do + vec = vecs[i] + print(i, ":", vec.x, vec.y, vec.z) + end +end +)", + sol::script_pass_on_error); + REQUIRE(result0.valid()); + + sol::protected_function f(lua["func"]); + auto pfr1 = f(foo); + REQUIRE(pfr1.valid()); + auto pfr2 = f(bar); + REQUIRE(pfr2.valid()); +} + +TEST_CASE( + "containers/usertype transparency", "Make sure containers pass their arguments through transparently and push the results as references, not new values") { + class A { + public: + int a; + A(int b = 2) : a(b){}; + + void func() { + } + }; + + struct B { + + B() { + for (std::size_t i = 0; i < 20; ++i) { + a_list.emplace_back(static_cast(i)); + } + } + + std::vector a_list; + }; + + sol::state lua; + lua.new_usertype("B", "a_list", &B::a_list); + + auto result = lua.safe_script(R"( +b = B.new() +a_ref = b.a_list[2] +)", + sol::script_pass_on_error); + REQUIRE(result.valid()); + + B& b = lua["b"]; + A& a_ref = lua["a_ref"]; + REQUIRE(&b.a_list[1] == &a_ref); + REQUIRE(b.a_list[1].a == a_ref.a); +} + +struct options { + static int livingcount; + static options* last; + options() { + ++livingcount; + last = this; + INFO("constructor: " << this); + } + + std::string output_help() { + last = this; + INFO("func: " << this); + return ""; + } + + void begin() { + } + void end() { + } + + ~options() { + last = this; + --livingcount; + } +}; + +options* options::last = nullptr; +int options::livingcount = 0; + +struct machine { + options opt; +}; + +namespace sol { + template <> + struct is_container : std::false_type {}; +} // namespace sol + +TEST_CASE("containers/is container", "make sure the is_container trait behaves properly") { + sol::state lua; + lua.open_libraries(); + + lua.new_usertype("options_type", "output_help", &options::output_help); + + lua.new_usertype( + "machine_type", "new", sol::no_constructor, "opt", [](machine& m) { return &m.opt; }, "copy_opt", [](machine& m) { return m.opt; }); + + { + machine m; + lua["machine"] = &m; + + auto result0 = lua.safe_script(R"( + machine:opt():output_help() + )", + sol::script_pass_on_error); + REQUIRE(result0.valid()); + + REQUIRE(options::last == &m.opt); + REQUIRE(options::livingcount == 1); + } + REQUIRE(options::livingcount == 0); +} + +TEST_CASE("containers/readonly", "make sure readonly members are stored appropriately") { + sol::state lua; + lua.open_libraries(); + + struct bar { + int x = 24; + }; + + struct foo { + std::list seq; + }; + + lua.new_usertype("foo", + "seq", + &foo::seq, // this one works + "readonly_seq", + sol::readonly(&foo::seq) // this one does not work + ); + lua["value"] = std::list{ {}, {}, {} }; + + auto result0 = lua.safe_script(R"( +a = foo.new() +x = a.seq +a.seq = value +y = a.readonly_seq +)", + sol::script_pass_on_error); + REQUIRE(result0.valid()); + std::list& seqrefx = lua["x"]; + std::list& seqrefy = lua["y"]; + REQUIRE(&seqrefx == &seqrefy); + REQUIRE(seqrefx.size() == 3); + auto result = lua.safe_script("a.readonly_seq = value", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); +} + +TEST_CASE("containers/to_args", "Test that the to_args abstractions works") { + sol::state lua; + lua.open_libraries(); + + auto result1 = lua.safe_script("function f (a, b, c, d) print(a, b, c, d) return a, b, c, d end", sol::script_pass_on_error); + REQUIRE(result1.valid()); + + sol::function f = lua["f"]; + int a, b, c, d; + + std::vector 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 v4{ 7, 6, 8, 5 }; + sol::tie(a, b, c, d) = f(sol::as_args(v4)); + REQUIRE(a == 5); + REQUIRE(b == 6); + REQUIRE(c == 7); + REQUIRE(d == 8); + + int v3[] = { 10, 11, 12 }; + sol::tie(a, b, c, d) = f(9, sol::as_args(v3)); + REQUIRE(a == 9); + REQUIRE(b == 10); + REQUIRE(c == 11); + REQUIRE(d == 12); +} + +TEST_CASE("containers/append idiom", "ensure the append-idiom works as intended") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + auto result1 = lua.safe_script( + R"( +function f_fill(vec) + print("#vec in lua: " .. #vec) + for k = 1, #vec do + vec[k] = k + end + print("#vec in lua: " .. #vec) +end +function f_append(vec) + print("#vec in lua: " .. #vec) + vec[#vec] = -10456407 + vec[#vec + 1] = -54 + print("#vec in lua: " .. #vec) +end +)", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + + std::vector fill_cmp{ 1, 2, 3 }; + std::vector append_cmp{ -1, -1, -10456407, -54 }; + + std::vector vec1{ -1, -1, -1 }; + std::vector vec2{ -1, -1, -1 }; + + REQUIRE(vec1.size() == 3); + lua["f_fill"](vec1); + REQUIRE(vec1.size() == 3); + REQUIRE(vec1 == fill_cmp); + + REQUIRE(vec2.size() == 3); + lua["f_append"](vec2); + REQUIRE(vec2.size() == 4); + REQUIRE(vec2 == append_cmp); +} + +TEST_CASE("containers/non_copyable", "make sure non-copyable types in containers behave properly when stored as a member variable in a bound usertype") { + struct test { + std::vector b; + + test() : b() { + } + test(test&&) = default; + test& operator=(test&&) = default; + test(const test&) = delete; + test& operator=(const test&) = delete; + }; + + SECTION("normal") { + sol::state lua; + lua.new_usertype("test", "b", sol::readonly(&test::b)); + + lua["v"] = std::vector{}; + + auto pfr = lua.safe_script("t = test.new() t.b = v", sol::script_pass_on_error); + REQUIRE_FALSE(pfr.valid()); + } +} + +TEST_CASE("containers/pairs", "test how well pairs work with the underlying system") { + using pair_arr_t = std::pair[5]; + using arr_t = int[5]; + + sol::state lua; + + lua.open_libraries(sol::lib::base); + + std::vector> a{ { "one", 1 }, { "two", 2 }, { "three", 3 }, { "four", 4 }, { "five", 5 } }; + std::array, 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); + lua["b"] = &b; + lua["c"] = std::ref(c); + lua["d"] = &d; + + auto result1 = lua.safe_script("av1, av2 = a:get(1)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("bv1, bv2 = b:get(1)", sol::script_pass_on_error); + REQUIRE(result2.valid()); + auto result3 = lua.safe_script("cv1, cv2 = c:get(1)", sol::script_pass_on_error); + REQUIRE(result3.valid()); + auto result4 = lua.safe_script("dv1, dv2 = d:get(1)", sol::script_pass_on_error); + REQUIRE(result4.valid()); + + std::vector>& la = lua["a"]; + std::array, 5>& lb = lua["b"]; + pair_arr_t* plc = lua["c"]; + pair_arr_t& lc = *plc; + arr_t* pld = lua["d"]; + arr_t& ld = *pld; + + std::pair& va = la[0]; + std::pair& vb = lb[0]; + std::pair& vc = lc[0]; + int& vd = ld[0]; + + std::string av1 = lua["av1"]; + int av2 = lua["av2"]; + std::string bv1 = lua["bv1"]; + int bv2 = lua["bv2"]; + std::string cv1 = lua["cv1"]; + int cv2 = lua["cv2"]; + int dv1 = lua["dv1"]; + sol::lua_nil_t dv2 = lua["dv2"]; + + REQUIRE(va.first == "one"); + REQUIRE(va.second == 1); + REQUIRE(vb.first == "one"); + REQUIRE(vb.second == 1); + REQUIRE(vc.first == "one"); + REQUIRE(vc.second == 1); + REQUIRE(vd == 1); + + REQUIRE(av1 == "one"); + REQUIRE(av2 == 1); + REQUIRE(bv1 == "one"); + REQUIRE(bv2 == 1); + REQUIRE(cv1 == "one"); + REQUIRE(cv2 == 1); + REQUIRE(dv1 == 1); + REQUIRE(dv2 == sol::lua_nil); +} + +TEST_CASE("containers/pointer types", "check that containers with unique usertypes and pointers or something") { + struct base_t { + virtual int get() const = 0; + virtual ~base_t() { + } + }; + + struct derived_1_t : base_t { + virtual int get() const override { + return 250; + } + }; + + struct derived_2_t : base_t { + virtual int get() const override { + return 500; + } + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + derived_1_t d1; + derived_2_t d2; + + std::vector> v1; + v1.push_back(std::make_unique()); + v1.push_back(std::make_unique()); + + std::vector v2; + v2.push_back(&d1); + v2.push_back(&d2); + lua["c1"] = std::move(v1); + lua["c2"] = &v2; + + auto result1 = lua.safe_script("b1 = c1[1]", sol::script_pass_on_error); + REQUIRE(result1.valid()); + base_t* b1 = lua["b1"]; + int val1 = b1->get(); + REQUIRE(val1 == 250); + + auto result2 = lua.safe_script("b2 = c2[2]", sol::script_pass_on_error); + REQUIRE(result2.valid()); + base_t* b2 = lua["b2"]; + int val2 = b2->get(); + REQUIRE(val2 == 500); +} diff --git a/lib/sol2/tests/runtime_tests/source/containers.roundtrip.cpp b/lib/sol2/tests/runtime_tests/source/containers.roundtrip.cpp new file mode 100644 index 0000000..ea2bb32 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/containers.roundtrip.cpp @@ -0,0 +1,172 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" +#include "common_classes.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +TEST_CASE("containers/vector roundtrip", "make sure vectors can be round-tripped") { + sol::state lua; + std::vector v{ 1, 2, 3 }; + lua.set_function("f", [&]() -> std::vector& { return v; }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + std::vector x = lua["x"]; + bool areequal = x == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/deque roundtrip", "make sure deques can be round-tripped") { + sol::state lua; + std::deque v{ 1, 2, 3 }; + lua.set_function("f", [&]() -> std::deque& { return v; }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + std::deque x = lua["x"]; + bool areequal = x == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/array roundtrip", "make sure arrays can be round-tripped") { + sol::state lua; + std::array v{ { 1, 2, 3 } }; + lua.set_function("f", [&]() -> std::array& { return v; }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + std::array x = lua["x"]; + bool areequal = x == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/list roundtrip", "make sure lists can be round-tripped") { + sol::state lua; + std::list v{ 1, 2, 3 }; + lua.set_function("f", [&]() -> std::list& { return v; }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + std::list x = lua["x"]; + bool areequal = x == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/forward_list roundtrip", "make sure forward_lists can be round-tripped") { + sol::state lua; + std::forward_list v{ 1, 2, 3 }; + lua.set_function("f", [&]() -> std::forward_list& { return v; }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + std::forward_list x = lua["x"]; + bool areequal = x == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/map roundtrip", "make sure maps can be round-tripped") { + sol::state lua; + std::map v{ { "a", 1 }, { "b", 2 }, { "c", 3 } }; + lua.set_function("f", [&]() -> std::map& { return v; }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + std::map x = lua["x"]; + bool areequal = x == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/unordered_map roundtrip", "make sure unordered_maps can be round-tripped") { + sol::state lua; + std::unordered_map v{ { "a", 1 }, { "b", 2 }, { "c", 3 } }; + lua.set_function("f", [&]() -> std::unordered_map& { return v; }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + std::unordered_map x = lua["x"]; + bool areequal = x == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/unordered_set roundtrip", "make sure unordered_sets can be round-tripped") { + sol::state lua; + std::unordered_set v{ 1, 2, 3 }; + lua.set_function("f", [&]() -> std::unordered_set& { return v; }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + std::unordered_set x = lua["x"]; + bool areequal = x == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/set roundtrip", "make sure sets can be round-tripped") { + sol::state lua; + std::set v{ 1, 2, 3 }; + lua.set_function("f", [&]() -> std::set& { return v; }); + auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + std::set x = lua["x"]; + bool areequal = x == v; + REQUIRE(areequal); +} + +TEST_CASE("containers/ipairs test", "ensure that abstractions roundtrip properly") { + struct thing { + int x = 20; + }; + thing t{}; + sol::state lua; + lua.open_libraries(); + + lua.set_function("f", [&t]() { return std::vector(5, &t); }); + + auto result1 = lua.safe_script(R"( +c = f() +)", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + + auto result2 = lua.safe_script(R"( +check = {} +local i = 1 +while c[i] do + check[i] = c[i] + i = i + 1 +end +)", + sol::script_pass_on_error); + REQUIRE(result2.valid()); + + sol::table c = lua["check"]; + for (std::size_t i = 1; i < 6; ++i) { + thing& ct = c[i]; + REQUIRE(&t == &ct); + REQUIRE(ct.x == 20); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/containers.table.cpp b/lib/sol2/tests/runtime_tests/source/containers.table.cpp new file mode 100644 index 0000000..0389b85 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/containers.table.cpp @@ -0,0 +1,268 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" +#include "common_classes.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +auto test_table_return_one() { + return sol::as_table(std::vector{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); +} + +auto test_table_return_two() { + return sol::as_table(std::vector>{ { "one", 1 }, { "two", 2 }, { "three", 3 } }); +} + +auto test_table_return_three() { + return sol::as_table(std::map{ { "name", "Rapptz" }, { "friend", "ThePhD" }, { "project", "sol" } }); +} + +auto test_table_return_four() { + return sol::as_table(std::array, 4>{ { { "one", 1 }, { "two", 2 }, { "three", 3 }, { "four", 4 } } }); +} + +template +void check_ordered_values(S& src, T& target) { + std::size_t idx = 0; + auto b = std::begin(target); + auto e = std::end(target); + for (; b != e; ++b, ++idx) { + const auto& v = src[idx]; + REQUIRE((*b == v)); + } +} + +template +void table_check_unordered_values(S& src, T& target) { + std::size_t idx = 0; + auto b = std::begin(target); + auto e = std::end(target); + for (; b != e; ++b, ++idx) { + auto sb = std::begin(src); + auto se = std::end(src); + auto it = std::find(sb, se, *b); + REQUIRE((it != se)); + } +} + +TEST_CASE("containers/arbitrary creation", "userdata and tables should be usable from standard containers") { + sol::state lua; + lua.open_libraries(sol::lib::base); + lua.set_function("test_one", test_table_return_one); + lua.set_function("test_two", test_table_return_two); + lua.set_function("test_three", test_table_return_three); + lua.set_function("test_four", test_table_return_four); + + { + auto result = lua.safe_script("a = test_one()", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("b = test_two()", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("c = test_three()", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("d = test_four()", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + + { + auto result = lua.safe_script("assert(#a == 10, 'error')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(a[3] == 3, 'error')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(b.one == 1, 'error')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(b.three == 3, 'error')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(c.name == 'Rapptz', 'error')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(c.project == 'sol', 'error')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(d.one == 1, 'error')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(d.three == 3, 'error')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(d.four == 4, 'error')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + + sol::table a = lua.get("a"); + sol::table b = lua.get("b"); + sol::table c = lua.get("c"); + sol::table d = lua["d"]; + + REQUIRE(a.size() == 10ULL); + REQUIRE(a.get(3) == 3); + REQUIRE(b.get("one") == 1); + REQUIRE(b.get("three") == 3); + REQUIRE(c.get("name") == "Rapptz"); + REQUIRE(c.get("project") == "sol"); + REQUIRE(d.get("one") == 1); + REQUIRE(d.get("three") == 3); + REQUIRE(d.get("four") == 4); +} + +TEST_CASE("containers/table serialization", "ensure types can be serialized as tables still") { + typedef std::vector woof; + sol::state lua; + lua.open_libraries(); + lua.set("b", sol::as_table(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, v in ipairs(b) do assert(k == v) 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 }; + lua.set("b", sol::as_table(w)); + { + auto result = lua.safe_script("for k, v in ipairs(b) do assert(k == v) end", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + lua.set("b", sol::as_table(&w)); + { + auto result = lua.safe_script("for k, v in ipairs(b) do assert(k == v) end", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + lua.set("b", sol::as_table(std::ref(w))); + { + auto result = lua.safe_script("for k, v in ipairs(b) do assert(k == v) end", sol::script_pass_on_error); + REQUIRE(result.valid()); + } +} + +TEST_CASE("containers/initializer-list", "test initializer lists get pushed as tables directly rather than userdata") { + SECTION("array-like") { + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::table); + + lua["c"] = { 1, 2, 3, 4, 5 }; + auto result1 = lua.safe_script(R"lua( +for k, v in pairs(c) do + assert(k == v) +end +)lua", + sol::script_pass_on_error); + sol::as_table_t> t1vector = lua["c"]; + sol::as_table_t> t1deque = lua["c"]; + sol::as_table_t> t1list = lua["c"]; + sol::as_table_t> t1flist = lua["c"]; + sol::as_table_t> t1set = lua["c"]; + const int src[5] = { 1, 2, 3, 4, 5 }; + check_ordered_values(src, t1vector.value()); + check_ordered_values(src, t1deque.value()); + check_ordered_values(src, t1list.value()); + check_ordered_values(src, t1flist.value()); + check_ordered_values(src, t1set.value()); + } + SECTION("map-like") { + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::table); + std::pair src[5]{ { "a", 21 }, { "b", 22 }, { "c", 23 }, { "d", 24 }, { "e", 25 } }; + + lua["c"] = std::initializer_list>{ { "a", 21 }, { "b", 22 }, { "c", 23 }, { "d", 24 }, { "e", 25 } }; + + sol::as_table_t> t1umap = lua["c"]; + sol::as_table_t> t1ummap = lua["c"]; + table_check_unordered_values(src, t1umap.value()); + table_check_unordered_values(src, t1ummap.value()); + } +} + +TEST_CASE("containers/as_table with pointers", "test to make sure pointers are respected in as_table work") { + using EHandle = std::uint32_t; + + struct Entity { + public: + Entity(EHandle) {} + Entity(const Entity&) = default; + Entity(Entity&&) = default; + Entity& operator=(const Entity&) = default; + Entity& operator=(Entity&&) = default; + }; + + auto test_func_vec = []() -> std::vector { + return { reinterpret_cast(0x01), reinterpret_cast(0x02), reinterpret_cast(0x03) }; + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + lua.new_usertype("Entity"); + + lua["f"] = [&test_func_vec]() { return sol::as_table(test_func_vec()); }; + + lua["g"] = [&test_func_vec]() { return sol::as_nested(test_func_vec()); }; + + sol::optional maybe_err0 = lua.safe_script("t = f()"); + sol::optional maybe_err1 = lua.safe_script("u = g()"); + REQUIRE_FALSE(maybe_err0.has_value()); + REQUIRE_FALSE(maybe_err1.has_value()); + + sol::table t = lua["t"]; + Entity* e1 = t[1]; + Entity* e2 = t[2]; + Entity* e3 = t[3]; + REQUIRE(e1 == reinterpret_cast(0x01)); + REQUIRE(e2 == reinterpret_cast(0x02)); + REQUIRE(e3 == reinterpret_cast(0x03)); + + sol::table u = lua["u"]; + Entity* f1 = u[1]; + Entity* f2 = u[2]; + Entity* f3 = u[3]; + REQUIRE(f1 == reinterpret_cast(0x01)); + REQUIRE(f2 == reinterpret_cast(0x02)); + REQUIRE(f3 == reinterpret_cast(0x03)); +} diff --git a/lib/sol2/tests/runtime_tests/source/coroutines.cpp b/lib/sol2/tests/runtime_tests/source/coroutines.cpp new file mode 100644 index 0000000..db07494 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/coroutines.cpp @@ -0,0 +1,636 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +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() + while counter ~= 30 + do + coroutine.yield(counter); + counter = counter + 1; + end + return counter +end +)"; + + sol::state lua; + sol::stack_guard luasg(lua); + + lua.open_libraries(sol::lib::base, sol::lib::coroutine); + auto result1 = lua.safe_script(script); + REQUIRE(result1.valid()); + sol::coroutine cr = lua["loop"]; + + int counter; + for (counter = 20; counter < 31 && cr; ++counter) { + int value = cr(); + REQUIRE(counter == value); + } + counter -= 1; + REQUIRE(counter == 30); +} + +TEST_CASE("coroutines/new thread coroutines", "ensure calling a coroutine works when the work is put on a different thread") { + const auto& code = R"(counter = 20 +function loop() + while counter ~= 30 + do + coroutine.yield(counter); + counter = counter + 1; + end + return counter +end +)"; + + sol::state lua; + sol::stack_guard luasg(lua); + + lua.open_libraries(sol::lib::base, sol::lib::coroutine); + auto result = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE(result.valid()); + sol::thread runner = sol::thread::create(lua.lua_state()); + sol::state_view runnerstate = runner.state(); + sol::coroutine cr = runnerstate["loop"]; + + int counter; + for (counter = 20; counter < 31 && cr; ++counter) { + int value = cr(); + REQUIRE(counter == value); + } + counter -= 1; + REQUIRE(counter == 30); +} + +TEST_CASE("coroutines/transfer", "test that things created inside of a coroutine can have their state transferred using lua_xmove constructors") { + for (std::size_t tries = 0; tries < 200; ++tries) { + sol::state lua; + sol::stack_guard luasg(lua); + + lua.open_libraries(); + { + sol::function f2; + lua["f"] = [&lua, &f2](sol::object t) { + f2 = sol::function(lua, t); + }; + { + auto code = R"( +i = 0 +function INIT() + co = coroutine.create( + function() + local g = function() i = i + 1 end + f(g) + g = nil + collectgarbage() + end + ) + coroutine.resume(co) + co = nil + collectgarbage() +end +)"; + auto result = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE(result.valid()); + } + sol::function f3; + sol::function f1; + + { + auto code = "INIT()"; + auto result = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE(result.valid()); + } + f2(); + auto updatecode = "return function() collectgarbage() end"; + auto pfr = lua.safe_script(updatecode); + REQUIRE(pfr.valid()); + + sol::function update = pfr; + update(); + f3 = f2; + f3(); + update(); + f1 = f2; + f1(); + update(); + int i = lua["i"]; + REQUIRE(i == 3); + } + } +} + +TEST_CASE("coroutines/explicit transfer", "check that the xmove constructors shift things around appropriately") { + const std::string code = R"( +-- main thread - L1 +-- co - L2 +-- co2 - L3 + +x = coro_test.new("x") +local co = coroutine.wrap( + function() + local t = coro_test.new("t") + local co2 = coroutine.wrap( + function() + local t2 = { "SOME_TABLE" } + t:copy_store(t2) -- t2 = [L3], t.obj = [L2] + end + ) + + co2() + co2 = nil + + collectgarbage() -- t2 ref in t remains valid! + + x:store(t:get()) -- t.obj = [L2], x.obj = [L1] + end +) + +co() +collectgarbage() +collectgarbage() +co = nil +)"; + + sol::state lua; + lua.open_libraries(sol::lib::coroutine, sol::lib::base); + + lua.new_usertype("coro_test", + sol::constructors(), + "store", &coro_test::store, + "copy_store", &coro_test::copy_store, + "get", &coro_test::get); + + auto r = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE(r.valid()); + + coro_test& ct = lua["x"]; + + lua_State* Lmain1 = lua.lua_state(); + lua_State* Lmain2 = sol::main_thread(lua); + lua_State* Lmain3 = ct.get().lua_state(); + REQUIRE(Lmain1 == Lmain2); + REQUIRE(Lmain1 == Lmain3); + + sol::table t = ct.get(); + REQUIRE(t.size() == 1); + std::string s = t[1]; + REQUIRE(s == "SOME_TABLE"); +} + +TEST_CASE("coroutines/implicit transfer", "check that copy and move assignment constructors implicitly shift things around") { + const std::string code = R"( +-- main thread - L1 +-- co - L2 +-- co2 - L3 + +x = coro_test.new("x") +local co = coroutine.wrap( + function() + local t = coro_test.new("t") + local co2 = coroutine.wrap( + function() + local t2 = { "SOME_TABLE" } + t:copy_store(t2) -- t2 = [L3], t.obj = [L2] + end + ) + + co2() + co2 = nil + + collectgarbage() -- t2 ref in t remains valid! + + x:store(t:get()) -- t.obj = [L2], x.obj = [L1] + end +) + +co() +collectgarbage() +collectgarbage() +co = nil +)"; + + struct coro_test_implicit { + std::string identifier; + sol::reference obj; + + coro_test_implicit(sol::this_state L, std::string id) + : identifier(id), obj(L, sol::lua_nil) { + } + + void store(sol::table ref) { + // must be explicit + obj = std::move(ref); + } + + void copy_store(sol::table ref) { + // must be explicit + obj = ref; + } + + sol::reference get() { + return obj; + } + + ~coro_test_implicit() { + } + }; + + sol::state lua; + lua.open_libraries(sol::lib::coroutine, sol::lib::base); + + lua.new_usertype("coro_test", + sol::constructors(), + "store", &coro_test_implicit::store, + "copy_store", &coro_test_implicit::copy_store, + "get", &coro_test_implicit::get); + + auto r = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE(r.valid()); + + coro_test_implicit& ct = lua["x"]; + + lua_State* Lmain1 = lua.lua_state(); + lua_State* Lmain2 = sol::main_thread(lua); + lua_State* Lmain3 = ct.get().lua_state(); + REQUIRE(Lmain1 == Lmain2); + REQUIRE(Lmain1 == Lmain3); + + sol::table t = ct.get(); + REQUIRE(t.size() == 1); + std::string s = t[1]; + REQUIRE(s == "SOME_TABLE"); +} + +TEST_CASE("coroutines/main transfer", "check that copy and move assignment constructors using main-forced types work") { + const std::string code = R"( +-- main thread - L1 +-- co - L2 +-- co2 - L3 + +x = coro_test.new("x") +local co = coroutine.wrap( + function() + local t = coro_test.new("t") + local co2 = coroutine.wrap( + function() + local t2 = { "SOME_TABLE" } + t:copy_store(t2) -- t2 = [L3], t.obj = [L2] + end + ) + + co2() + co2 = nil + + collectgarbage() -- t2 ref in t remains valid! + + x:store(t:get()) -- t.obj = [L2], x.obj = [L1] + end +) + +co() +co = nil +collectgarbage() +)"; + + sol::state lua; + lua.open_libraries(sol::lib::coroutine, sol::lib::base); + + lua.new_usertype("coro_test", + sol::constructors(), + "store", &coro_test_implicit::store, + "copy_store", &coro_test_implicit::copy_store, + "get", &coro_test_implicit::get); + + auto r = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE(r.valid()); + + coro_test_implicit& ct = lua["x"]; + + lua_State* Lmain1 = lua.lua_state(); + lua_State* Lmain2 = sol::main_thread(lua); + lua_State* Lmain3 = ct.get().lua_state(); + REQUIRE(Lmain1 == Lmain2); + REQUIRE(Lmain1 == Lmain3); + + sol::table t = ct.get(); + REQUIRE(t.size() == 1); + std::string s = t[1]; + REQUIRE(s == "SOME_TABLE"); +} + +TEST_CASE("coroutines/coroutine.create protection", "ensure that a thread picked up from coroutine.create does not throw off the lua stack entirely when called from C++") { + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::coroutine); + + auto code = R"( +function loop() + local i = 0 + while true do + print("pre-yield in loop") + coroutine.yield(i) + print("post-yield in loop") + i = i+1 + end +end +loop_th = coroutine.create(loop) +)"; + + auto r = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE(r.valid()); + sol::thread runner_thread = lua["loop_th"]; + + auto test_resume = [&runner_thread]() { + sol::state_view th_state = runner_thread.state(); + sol::coroutine cr = th_state["loop"]; + int r = cr(); + return r; + }; + + lua.set_function("test_resume", std::ref(test_resume)); + + int v0 = test_resume(); + int v1 = test_resume(); + int v2, v3; + { + auto r2 = lua.safe_script("return test_resume()", sol::script_pass_on_error); + REQUIRE(r2.valid()); + auto r3 = lua.safe_script("return test_resume()", sol::script_pass_on_error); + REQUIRE(r3.valid()); + v2 = r2; + v3 = r3; + } + REQUIRE(v0 == 0); + REQUIRE(v1 == 1); + REQUIRE(v2 == 2); + REQUIRE(v3 == 3); +} + +TEST_CASE("coroutines/stack-check", "check that resumed functions consume the entire execution stack") { + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::table, sol::lib::coroutine); + { + auto code = R"( +unpack = unpack or table.unpack + +function loop() + local i = 0 + while true do + print("pre-yield in loop") + coroutine.yield(i) + print("post-yield in loop") + i = i+1 + end +end +loop_th = coroutine.create(loop) +loop_res = function(...) + returns = { coroutine.resume(loop_th, ...) } + return unpack(returns, 2) +end +)"; + auto result = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE(result.valid()); + } + + // Resume from lua via thread and coroutine + sol::thread runner_thread = lua["loop_th"]; + sol::state_view runner_thread_state = runner_thread.state(); + auto test_resume = [&runner_thread_state]() { + sol::coroutine cr = runner_thread_state["loop"]; + sol::stack::push(runner_thread_state, 50); + sol::stack::push(runner_thread_state, 25); + int r = cr(); + return r; + }; + lua.set_function("test_resume", std::ref(test_resume)); + + // Resume via getting a sol::function from the state + sol::function test_resume_lua = lua["loop_res"]; + + // Resume via passing a sol::function object + auto test_resume_func = [](sol::function f) { + int r = f(); + return r; + }; + lua.set_function("test_resume_func", std::ref(test_resume_func)); + + int v0 = test_resume(); + int s0 = runner_thread_state.stack_top(); + int v1 = test_resume(); + int s1 = runner_thread_state.stack_top(); + int v2; + { + auto result = lua.safe_script("return test_resume()", sol::script_pass_on_error); + REQUIRE(result.valid()); + v2 = result; + } + int s2 = runner_thread_state.stack_top(); + int v3; + { + auto result = lua.safe_script("return test_resume()", sol::script_pass_on_error); + REQUIRE(result.valid()); + v3 = result; + } + int s3 = runner_thread_state.stack_top(); + int v4 = test_resume_lua(); + int s4 = runner_thread_state.stack_top(); + int v5; + { + auto result = lua.safe_script("return test_resume_func(loop_res)", sol::script_pass_on_error); + REQUIRE(result.valid()); + v5 = result; + } + int s5 = runner_thread_state.stack_top(); + REQUIRE(v0 == 0); + REQUIRE(v1 == 1); + REQUIRE(v2 == 2); + REQUIRE(v3 == 3); + REQUIRE(v4 == 4); + REQUIRE(v5 == 5); + + REQUIRE(s0 == 0); + REQUIRE(s1 == 0); + REQUIRE(s2 == 0); + REQUIRE(s3 == 0); + REQUIRE(s4 == 0); + REQUIRE(s5 == 0); +} + +TEST_CASE("coroutines/yielding", "test that a sol3 bound function can yield when marked yieldable") { + SECTION("regular functions") { + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::coroutine); + + int i = 0; + auto func = [&i]() { + ++i; + return i; + }; + + coro_h hobj{}; + + lua["f"] = sol::yielding(func); + lua["g"] = sol::yielding([]() { return 300; }); + lua["h"] = sol::yielding(&coro_h::func); + lua["hobj"] = &hobj; + + sol::string_view code = R"( + co1 = coroutine.create(function () return f() end) + success1, value1 = coroutine.resume(co1) + co2 = coroutine.create(function () return g() end) + success2, value2 = coroutine.resume(co2) + co3 = coroutine.create(function() + h(hobj) + end) + success3, value3 = coroutine.resume(co3) + )"; + + auto result = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE(result.valid()); + + bool success1 = lua["success1"]; + int value1 = lua["value1"]; + REQUIRE(success1); + REQUIRE(value1 == 1); + + bool success2 = lua["success2"]; + int value2 = lua["value2"]; + REQUIRE(success2); + REQUIRE(value2 == 300); + + bool success3 = lua["success3"]; + int value3 = lua["value3"]; + REQUIRE(success3); + REQUIRE(value3 == 501); + + REQUIRE(hobj.x == 501); + } + SECTION("usertypes") { + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::coroutine); + + coro_h hobj; + + lua["hobj"] = &hobj; + + lua.new_usertype("coro_h", + "h", sol::yielding(&coro_h::func) + ); + + sol::string_view code = R"( + co4 = coroutine.create(function() + hobj:h() + hobj.h(hobj) + coro_h.h(hobj) + end) + success4, value4 = coroutine.resume(co4) + success5, value5 = coroutine.resume(co4) + success6, value6 = coroutine.resume(co4) + )"; + + auto result = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE(result.valid()); + + bool success4 = lua["success4"]; + int value4 = lua["value4"]; + REQUIRE(success4); + REQUIRE(value4 == 501); + + bool success5 = lua["success5"]; + int value5 = lua["value5"]; + REQUIRE(success5); + REQUIRE(value5 == 502); + + bool success6 = lua["success6"]; + int value6 = lua["value6"]; + REQUIRE(success6); + REQUIRE(value6 == 503); + + REQUIRE(hobj.x == 503); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/customizations.cpp b/lib/sol2/tests/runtime_tests/source/customizations.cpp new file mode 100644 index 0000000..a45d8bb --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/customizations.cpp @@ -0,0 +1,283 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include + +struct custom { + int bweh; + + static int get_calls; + static int check_calls; + static int check_get_calls; + static int push_calls; + static int exact_push_calls; +}; + +int custom::get_calls = 0; +int custom::check_calls = 0; +int custom::check_get_calls = 0; +int custom::push_calls = 0; +int custom::exact_push_calls = 0; + +custom sol_lua_get(sol::types, lua_State* L, int index, sol::stack::record& tracking) { + ++custom::get_calls; + return { sol::stack::get(L, index, tracking) }; +} + +template +bool sol_lua_check(sol::types, lua_State* L, int index, Handler&& handler, sol::stack::record& tracking) { + ++custom::check_calls; + return sol::stack::check(L, index, std::forward(handler), tracking); +} + +template +sol::optional sol_lua_check_get(sol::types type_tag, lua_State* L, int index, Handler&& handler, sol::stack::record& tracking) { + ++custom::check_get_calls; + if (sol_lua_check(type_tag, L, index, std::forward(handler), tracking)) { + return sol_lua_get(type_tag, L, index, tracking); + } + return sol::nullopt; +} + +int sol_lua_push(lua_State* L, const custom& c) { + ++custom::push_calls; + return sol::stack::push(L, c.bweh); +} + +int sol_lua_push(sol::types, lua_State* L, const custom& c) { + ++custom::exact_push_calls; + return sol::stack::push(L, c.bweh); +} + +struct multi_custom { + int bweh; + bool bwuh; + std::string blah; + + static int get_calls; + static int check_calls; + static int check_get_calls; + static int push_calls; + static int exact_push_calls; +}; + +int multi_custom::get_calls = 0; +int multi_custom::check_calls = 0; +int multi_custom::check_get_calls = 0; +int multi_custom::push_calls = 0; +int multi_custom::exact_push_calls = 0; + +multi_custom sol_lua_get(sol::types, lua_State* L, int index, sol::stack::record& tracking) { + ++multi_custom::get_calls; + return { + sol::stack::get(L, index + 0, tracking), sol::stack::get(L, index + 1, tracking), sol::stack::get(L, index + 2, tracking) + }; +} + +template +bool sol_lua_check(sol::types, lua_State* L, int index, Handler&& handler, sol::stack::record& tracking) { + ++multi_custom::check_calls; + bool success = sol::stack::check(L, index + 0, std::forward(handler), tracking) + && sol::stack::check(L, index + 1, std::forward(handler), tracking) + && sol::stack::check(L, index + 2, std::forward(handler), tracking); + return success; +} + +int sol_lua_push(lua_State* L, const multi_custom& c) { + ++multi_custom::push_calls; + int p = sol::stack::push(L, c.bweh); + p += sol::stack::push(L, c.bwuh); + p += sol::stack::push(L, c.blah); + return p; +} + +struct super_custom { + int bweh; + + static int get_calls; + static int check_calls; + static int check_get_calls; + static int push_calls; + static int exact_push_calls; + static int pointer_push_calls; +}; + +int super_custom::get_calls = 0; +int super_custom::check_calls = 0; +int super_custom::check_get_calls = 0; +int super_custom::push_calls = 0; +int super_custom::pointer_push_calls = 0; +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(memory); + std::allocator alloc{}; + std::allocator_traits>::destroy(alloc, data); + return 0; +} + +super_custom* sol_lua_get(sol::types, lua_State* L, int index, sol::stack::record& tracking) { + ++super_custom::get_calls; + tracking.use(1); + void* vp = lua_touserdata(L, index); + super_custom** pscp = static_cast(vp); + return *pscp; +} + +super_custom& sol_lua_get(sol::types, lua_State* L, int index, sol::stack::record& tracking) { + return *sol_lua_get(sol::types(), L, index, tracking); +} + +template +bool sol_lua_check(sol::types, lua_State* L, int index, Handler&& handler, sol::stack::record& tracking) { + ++super_custom::check_calls; + tracking.use(1); + if (luaL_testudata(L, index, "super_custom!") == nullptr) { + if (luaL_testudata(L, index, "super_custom!p") == nullptr) { + handler(L, index, sol::type::userdata, sol::type_of(L, index), "not a super_custom ?!"); + return false; + } + } + return true; +} + +template +bool sol_lua_check(sol::types, lua_State* L, int index, Handler&& handler, sol::stack::record& tracking) { + return sol_lua_check(sol::types(), L, index, std::forward(handler), tracking); +} + +int sol_lua_push(lua_State* L, const super_custom& c) { + ++super_custom::push_calls; + // ensure there's enough space for 1 more thing on the stack + lua_checkstack(L, 1); + // tell Lua we've left something on + // the stack: return what comes from pushing an integer + void* ud = lua_newuserdata(L, sizeof(super_custom*) + sizeof(super_custom)); + super_custom* tud = static_cast(static_cast(static_cast(ud) + sizeof(super_custom*))); + *static_cast(ud) = tud; + new(tud)super_custom(c); + if (luaL_newmetatable(L, "super_custom!") == 1) { + luaL_Reg l[2]{}; + l[0] = { sol::to_string(sol::meta_function::garbage_collect).c_str(), &destroy_super_custom }; + luaL_setfuncs(L, l, 0); + } + lua_setmetatable(L, -2); + return 1; +} + +int sol_lua_push(lua_State* L, super_custom* c) { + ++super_custom::pointer_push_calls; + // ensure there's enough space for 1 more thing on the stack + lua_checkstack(L, 1); + // tell Lua we've left something on + // the stack: return what comes from pushing an integer + void* ud = lua_newuserdata(L, sizeof(super_custom*)); + *static_cast(ud) = c; + luaL_newmetatable(L, "super_custom!p"); + lua_setmetatable(L, -2); + return 1; +} + +int sol_lua_push(sol::types>, lua_State* L, std::reference_wrapper c) { + ++super_custom::exact_push_calls; + return sol::stack::push(L, std::addressof(c.get())); +} + +TEST_CASE("customization/adl", "using the ADL customization points in various situations") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + SECTION("value-based") { + custom::get_calls = 0; + custom::check_calls = 0; + custom::check_get_calls = 0; + custom::push_calls = 0; + custom::exact_push_calls = 0; + + lua["meow"] = custom{ 25 }; + custom meow = lua["meow"]; + + REQUIRE(meow.bweh == 25); + REQUIRE(custom::get_calls > 0); + REQUIRE(custom::check_calls > 0); + REQUIRE(custom::check_get_calls > 0); + REQUIRE(custom::exact_push_calls > 0); + REQUIRE(custom::push_calls == 0); + } + SECTION("multi") { + multi_custom::get_calls = 0; + multi_custom::check_calls = 0; + multi_custom::check_get_calls = 0; + multi_custom::push_calls = 0; + multi_custom::exact_push_calls = 0; + + 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" }); + REQUIRE(pass_through.bweh == 22); + REQUIRE_FALSE(pass_through.bwuh); + REQUIRE(pass_through.blah == "miao"); + + REQUIRE(multi_custom::get_calls > 0); + REQUIRE(multi_custom::check_calls > 0); + REQUIRE(multi_custom::push_calls > 0); + REQUIRE(multi_custom::check_get_calls == 0); + REQUIRE(multi_custom::exact_push_calls == 0); + } + SECTION("reference-based") { + super_custom::get_calls = 0; + super_custom::check_calls = 0; + super_custom::check_get_calls = 0; + super_custom::push_calls = 0; + super_custom::pointer_push_calls = 0; + super_custom::exact_push_calls = 0; + + super_custom meow_original{ 50 }; + lua["meow"] = std::ref(meow_original); + super_custom& meow = lua["meow"]; + super_custom* p_meow = lua["meow"]; + std::reference_wrapper ref_meow = lua["meow"]; + super_custom meow_copy = lua["meow"]; + + REQUIRE(meow.bweh == 50); + REQUIRE(&meow == &meow_original); + REQUIRE(p_meow == &meow_original); + REQUIRE(&ref_meow.get() == &meow_original); + REQUIRE(meow_copy.bweh == 50); + REQUIRE(super_custom::get_calls > 0); + REQUIRE(super_custom::check_calls > 0); + REQUIRE(super_custom::check_get_calls == 0); + REQUIRE(super_custom::push_calls == 0); + REQUIRE(super_custom::pointer_push_calls > 0); + REQUIRE(super_custom::exact_push_calls > 0); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/customizations_private.cpp b/lib/sol2/tests/runtime_tests/source/customizations_private.cpp new file mode 100644 index 0000000..4a0f5fb --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/customizations_private.cpp @@ -0,0 +1,178 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include + +struct two_things { + int a; + bool b; +}; + +struct number_shim { + double num = 0; +}; + + +// HEY: +// Don't do this. +// The code below is for sol3 to specialize things, +// not for YOU to specialize things. +// If you customize things in this fashion, +// I will break your code sometime in the future when fixing things. +// Do. Not. Use the designated ADL customization points, or file +// a bug. +namespace sol { + + template <> + struct lua_size : std::integral_constant {}; + + template <> + struct lua_type_of : std::integral_constant {}; + + template <> + struct lua_type_of : std::integral_constant {}; + + namespace stack { + + template <> + struct unqualified_checker { + template + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + bool success = stack::check(L, index, handler) && stack::check(L, index + 1, handler); + tracking.use(2); + return success; + } + }; + + template <> + struct unqualified_getter { + static two_things get(lua_State* L, int index, record& tracking) { + int a = stack::get(L, index); + bool b = stack::get(L, index + 1); + tracking.use(2); + return two_things{ a, b }; + } + }; + + template <> + struct unqualified_pusher { + static int push(lua_State* L, const two_things& things) { + int amount = stack::push(L, things.a); + amount += stack::push(L, things.b); + return amount; + } + }; + + template <> + struct unqualified_checker { + template + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + if (!check_usertype(L, index) && !stack::check(L, index)) { + handler(L, index, type_of(L, index), type::userdata, "expected a number_shim or a number"); + return false; + } + tracking.use(1); + return true; + } + }; + + template <> + struct unqualified_getter { + static number_shim get(lua_State* L, int index, record& tracking) { + if (check_usertype(L, index)) { + number_shim& ns = get_usertype(L, index, tracking); + return ns; + } + number_shim ns{}; + ns.num = stack::get(L, index, tracking); + return ns; + } + }; + + } // namespace stack +} // namespace sol + +TEST_CASE("customization/split struct", "using the old customization points to handle different kinds of classes") { + sol::state lua; + + // Create a pass-through style of function + auto result1 = lua.safe_script("function f ( a, b, c ) return a + c, b end", sol::script_pass_on_error); + REQUIRE(result1.valid()); + lua.set_function("g", [](int a, bool b, int c, double d) { return std::make_tuple(a + c, b, d + 2.5); }); + + // get the function out of Lua + sol::function f = lua["f"]; + sol::function g = lua["g"]; + + two_things thingsf = f(two_things{ 24, true }, 1); + REQUIRE(thingsf.a == 25); + REQUIRE(thingsf.b); + + two_things thingsg; + double d; + sol::tie(thingsg, d) = g(two_things{ 25, false }, 2, 34.0); + REQUIRE(thingsg.a == 27); + REQUIRE_FALSE(thingsg.b); + REQUIRE(d == 36.5); +} + +TEST_CASE("customization/usertype", "using the old customization points to handle different kinds of classes") { + sol::state lua; + + // Create a pass-through style of function + auto result1 = lua.safe_script("function f ( a ) return a end"); + REQUIRE(result1.valid()); + lua.set_function("g", [](double a) { + number_shim ns; + ns.num = a; + return ns; + }); + + auto result2 = lua.safe_script("vf = f(25) vg = g(35)", sol::script_pass_on_error); + REQUIRE(result2.valid()); + + number_shim thingsf = lua["vf"]; + number_shim thingsg = lua["vg"]; + + REQUIRE(thingsf.num == 25); + REQUIRE(thingsg.num == 35); +} + +TEST_CASE("customization/overloading", "using multi-size customized types in an overload") { + bool TwoThingsWorks = false, OverloadWorks = false; + sol::state lua; + lua["test_two_things"] = [&](two_things) { TwoThingsWorks = true; }; + lua["test_overload"] = sol::overload([&](two_things) { OverloadWorks = true; }, [] {}); + + lua.script( + "test_two_things(0, true)\n" + "test_overload(0, true)"); + + REQUIRE(TwoThingsWorks); + REQUIRE(OverloadWorks); +} diff --git a/lib/sol2/tests/runtime_tests/source/dump.cpp b/lib/sol2/tests/runtime_tests/source/dump.cpp new file mode 100644 index 0000000..72b1e66 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/dump.cpp @@ -0,0 +1,121 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include +#include + +int dump_always_fail_number = -32; + +int dump_always_fail(lua_State*, const void*, size_t, void*) { + return dump_always_fail_number; +} + +TEST_CASE("dump/dump transfer", "test that a function can be transferred from one place to another") { + SECTION("safe") { + sol::state lua; + sol::state lua2; + lua2.open_libraries(sol::lib::base); + + sol::load_result lr = lua.load("a = function (v) print(v) return v end"); + REQUIRE(lr.valid()); + sol::protected_function target = lr; + sol::bytecode target_bc = target.dump(); + + auto result2 = lua2.safe_script(target_bc.as_string_view(), sol::script_pass_on_error); + REQUIRE(result2.valid()); + sol::protected_function pf = lua2["a"]; + int v = pf(25557); + REQUIRE(v == 25557); + } + SECTION("unsafe") { + sol::state lua; + sol::state lua2; + lua2.open_libraries(sol::lib::base); + + sol::load_result lr = lua.load("a = function (v) print(v) return v end"); + REQUIRE(lr.valid()); + sol::unsafe_function target = lr; + sol::bytecode target_bc = target.dump(); + + auto result2 = lua2.safe_script(target_bc.as_string_view(), sol::script_pass_on_error); + REQUIRE(result2.valid()); + sol::unsafe_function pf = lua2["a"]; + int v = pf(25557); + REQUIRE(v == 25557); + } +} + +TEST_CASE("dump/failure", "test that failure is properly propagated") { + SECTION("safe") { + 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; + int err = target.dump(&dump_always_fail, nullptr, false, sol::dump_pass_on_error); + REQUIRE(err == dump_always_fail_number); + } + SECTION("unsafe") { + sol::state lua; + sol::load_result lr = lua.load("a = function (v) print(v) return v end"); + REQUIRE(lr.valid()); + sol::unsafe_function target = lr; + int err = target.dump(&dump_always_fail, nullptr, false, sol::dump_pass_on_error); + REQUIRE(err == dump_always_fail_number); + } +} + +TEST_CASE("dump/different containers", "test that dump inserter works for various kinds of containers") { + SECTION("safe") { + 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::bytecode bytecode_dump = target.dump(); + std::list list_dump = target.dump>(); + std::vector vector_dump = target.dump>(); + std::deque deque_dump = target.dump>(); + REQUIRE(std::equal(bytecode_dump.cbegin(), bytecode_dump.cend(), vector_dump.cbegin(), vector_dump.cend())); + REQUIRE(std::equal(bytecode_dump.cbegin(), bytecode_dump.cend(), list_dump.cbegin(), list_dump.cend())); + REQUIRE(std::equal(bytecode_dump.cbegin(), bytecode_dump.cend(), deque_dump.cbegin(), deque_dump.cend())); + } + SECTION("unsafe") { + sol::state lua; + + sol::load_result lr = lua.load("a = function (v) print(v) return v end"); + REQUIRE(lr.valid()); + sol::unsafe_function target = lr; + sol::bytecode bytecode_dump = target.dump(); + std::list list_dump = target.dump>(); + std::vector vector_dump = target.dump>(); + std::deque deque_dump = target.dump>(); + REQUIRE(std::equal(bytecode_dump.cbegin(), bytecode_dump.cend(), vector_dump.cbegin(), vector_dump.cend())); + REQUIRE(std::equal(bytecode_dump.cbegin(), bytecode_dump.cend(), list_dump.cbegin(), list_dump.cend())); + REQUIRE(std::equal(bytecode_dump.cbegin(), bytecode_dump.cend(), deque_dump.cbegin(), deque_dump.cend())); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/environments.cpp b/lib/sol2/tests/runtime_tests/source/environments.cpp new file mode 100644 index 0000000..8ee9b78 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/environments.cpp @@ -0,0 +1,276 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include + +TEST_CASE("environments/get", "Envronments can be taken out of things like Lua functions properly") { + sol::state lua; + sol::stack_guard luasg(lua); + + lua.open_libraries(sol::lib::base); + + auto result1 = lua.safe_script("f = function() return test end", sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::function f = lua["f"]; + + sol::environment env_f(lua, sol::create); + env_f["test"] = 31; + sol::set_environment(env_f, f); + + int result = f(); + REQUIRE(result == 31); + + auto result2 = lua.safe_script("g = function() test = 5 end", sol::script_pass_on_error); + REQUIRE(result2.valid()); + sol::function g = lua["g"]; + sol::environment env_g(lua, sol::create); + env_g.set_on(g); + + g(); + + int test = env_g["test"]; + REQUIRE(test == 5); + + sol::object global_test = lua["test"]; + REQUIRE(!global_test.valid()); + + auto result3 = lua.safe_script("h = function() end", sol::script_pass_on_error); + REQUIRE(result3.valid()); + + lua.set_function("check_f_env", + [&lua, &env_f](sol::object target) { + sol::stack_guard luasg(lua); + sol::environment target_env(sol::env_key, target); + int test_env_f = env_f["test"]; + int test_target_env = target_env["test"]; + REQUIRE(test_env_f == test_target_env); + REQUIRE(test_env_f == 31); + REQUIRE(env_f == target_env); + }); + lua.set_function("check_g_env", + [&lua, &env_g](sol::function target) { + sol::stack_guard luasg(lua); + sol::environment target_env = sol::get_environment(target); + int test_env_g = env_g["test"]; + int test_target_env = target_env["test"]; + REQUIRE(test_env_g == test_target_env); + REQUIRE(test_env_g == 5); + REQUIRE(env_g == target_env); + }); + lua.set_function("check_h_env", + [&lua](sol::function target) { + sol::stack_guard luasg(lua); + sol::environment target_env = sol::get_environment(target); + }); + + auto checkf = lua.safe_script("check_f_env(f)"); + REQUIRE(checkf.valid()); + auto checkg = lua.safe_script("check_g_env(g)"); + REQUIRE(checkg.valid()); + auto checkh = lua.safe_script("check_h_env(h)"); + REQUIRE(checkh.valid()); +} + +TEST_CASE("environments/shadowing", "Environments can properly shadow and fallback on variables") { + + sol::state lua; + sol::stack_guard luasg(lua); + + lua["b"] = 2142; + + SECTION("no fallback") { + sol::environment plain_env(lua, sol::create); + auto result1 = lua.safe_script("a = 24", plain_env, sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::optional maybe_env_a = plain_env["a"]; + sol::optional maybe_global_a = lua["a"]; + sol::optional maybe_env_b = plain_env["b"]; + sol::optional maybe_global_b = lua["b"]; + + REQUIRE(maybe_env_a != sol::nullopt); + REQUIRE(maybe_env_a.value() == 24); + REQUIRE(maybe_env_b == sol::nullopt); + + REQUIRE(maybe_global_a == sol::nullopt); + REQUIRE(maybe_global_b != sol::nullopt); + REQUIRE(maybe_global_b.value() == 2142); + } + SECTION("fallback") { + sol::environment env_with_fallback(lua, sol::create, lua.globals()); + auto result1 = lua.safe_script("a = 56", env_with_fallback, sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::optional maybe_env_a = env_with_fallback["a"]; + sol::optional maybe_global_a = lua["a"]; + sol::optional maybe_env_b = env_with_fallback["b"]; + sol::optional maybe_global_b = lua["b"]; + + REQUIRE(maybe_env_a != sol::nullopt); + REQUIRE(maybe_env_a.value() == 56); + REQUIRE(maybe_env_b != sol::nullopt); + REQUIRE(maybe_env_b.value() == 2142); + + REQUIRE(maybe_global_a == sol::nullopt); + REQUIRE(maybe_global_b != sol::nullopt); + REQUIRE(maybe_global_b.value() == 2142); + } + SECTION("from name") { + sol::environment env_with_fallback(lua, sol::create, lua.globals()); + lua["env"] = env_with_fallback; + sol::environment env = lua["env"]; + auto result1 = lua.safe_script("a = 56", env, sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::optional maybe_env_a = env["a"]; + sol::optional maybe_global_a = lua["a"]; + sol::optional maybe_env_b = env["b"]; + sol::optional maybe_global_b = lua["b"]; + + REQUIRE(maybe_env_a != sol::nullopt); + REQUIRE(maybe_env_a.value() == 56); + REQUIRE(maybe_env_b != sol::nullopt); + REQUIRE(maybe_env_b.value() == 2142); + + REQUIRE(maybe_global_a == sol::nullopt); + REQUIRE(maybe_global_b != sol::nullopt); + REQUIRE(maybe_global_b.value() == 2142); + } + SECTION("name with newtable") { + lua["blank_env"] = sol::new_table(0, 1); + sol::environment plain_env = lua["blank_env"]; + auto result1 = lua.safe_script("a = 24", plain_env, sol::script_pass_on_error); + REQUIRE(result1.valid()); + + sol::optional maybe_env_a = plain_env["a"]; + sol::optional maybe_global_a = lua["a"]; + sol::optional maybe_env_b = plain_env["b"]; + sol::optional maybe_global_b = lua["b"]; + + REQUIRE(maybe_env_a != sol::nullopt); + REQUIRE(maybe_env_a.value() == 24); + REQUIRE(maybe_env_b == sol::nullopt); + + REQUIRE(maybe_global_a == sol::nullopt); + REQUIRE(maybe_global_b != sol::nullopt); + REQUIRE(maybe_global_b.value() == 2142); + } +} + +TEST_CASE("environments/functions", "see if environments on functions are working properly") { + + SECTION("basic") { + sol::state lua; + sol::stack_guard luasg(lua); + + auto result1 = lua.safe_script("a = function() return 5 end", sol::script_pass_on_error); + REQUIRE(result1.valid()); + + sol::function a = lua["a"]; + + int result0 = a(); + REQUIRE(result0 == 5); + + sol::environment env(lua, sol::create); + sol::set_environment(env, a); + + int value = a(); + REQUIRE(value == 5); + } + SECTION("return environment value") { + sol::state lua; + sol::stack_guard luasg(lua); + + auto result1 = lua.safe_script("a = function() return test end", sol::script_pass_on_error); + REQUIRE(result1.valid()); + + sol::function a = lua["a"]; + sol::environment env(lua, sol::create); + env["test"] = 5; + env.set_on(a); + + // the function returns the value from the environment table + int result = a(); + REQUIRE(result == 5); + } + + SECTION("set environment value") { + sol::state lua; + sol::stack_guard luasg(lua); + + auto result1 = lua.safe_script("a = function() test = 5 end", sol::script_pass_on_error); + REQUIRE(result1.valid()); + + sol::function a = lua["a"]; + sol::environment env(lua, sol::create); + sol::set_environment(env, a); + + a(); + + // the value can be retrieved from the env table + int result = env["test"]; + REQUIRE(result == 5); + + // the global environment is not polluted + auto gtest = lua["test"]; + REQUIRE(!gtest.valid()); + } +} + +TEST_CASE("environments/this_environment", "test various situations of pulling out an environment") { + static std::string code = "return (f(10))"; + + sol::state lua; + sol::stack_guard luasg(lua); + + lua["f"] = [](sol::this_environment te, int x, sol::this_state ts) { + if (te) { + sol::environment& env = te; + return x + static_cast(env["x"]); + } + sol::state_view lua = ts; + return x + static_cast(lua["x"]); + }; + + sol::environment e(lua, sol::create, lua.globals()); + lua["x"] = 5; + e["x"] = 20; + SECTION("from Lua script") { + auto result1 = lua.safe_script(code, e, sol::script_pass_on_error); + REQUIRE(result1.valid()); + int value = result1; + REQUIRE(value == 30); + } + SECTION("from C++") { + sol::function f = lua["f"]; + e.set_on(f); + int value = f(10); + REQUIRE(value == 30); + } + SECTION("from C++, with no env") { + sol::function f = lua["f"]; + int value = f(10); + REQUIRE(value == 15); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/functions.cpp b/lib/sol2/tests/runtime_tests/source/functions.cpp new file mode 100644 index 0000000..c68bbd8 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/functions.cpp @@ -0,0 +1,1495 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +#include "sol_test.hpp" + +#include + +#include + +template +T va_func(sol::variadic_args va, T first) { + T s = 0; + for (auto arg : va) { + T v = arg; + s += v; + } + std::cout << first << std::endl; + std::cout << s << std::endl; + + return s; +} + +struct A { + int a = 0xA; + int bark() { + return 1; + } +}; + +std::tuple bark(int num_value, A* a) { + return std::tuple(num_value * 2, a->bark()); +} + +int overloaded(int x) { + INFO(x); + return 3; +} + +int overloaded(int x, int y) { + INFO(x << " " << y); + return 7; +} + +int overloaded(int x, int y, int z) { + INFO(x << " " << y << " " << z); + return 11; +} + +int non_overloaded(int x, int y, int z) { + INFO(x << " " << y << " " << z); + return 13; +} + +namespace sep { + int plop_xyz(int x, int y, std::string z) { + INFO(x << " " << y << " " << z); + return 11; + } +} // namespace sep + +int func_1(int) { + return 1; +} + +std::string func_1s(std::string a) { + return "string: " + a; +} + +int func_2(int, int) { + return 2; +} + +void func_3(int, int, int) { +} + +int f1(int) { + return 32; +} +int f2(int, int) { + return 1; +} +struct fer { + double f3(int, int) { + return 2.5; + } +}; + +static int raw_noexcept_function(lua_State* L) noexcept { + return sol::stack::push(L, 0x63); +} + +TEST_CASE("functions/tuple returns", "Make sure tuple returns are ordered properly") { + sol::state lua; + auto result1 = lua.safe_script("function f() return '3', 4 end", sol::script_pass_on_error); + REQUIRE(result1.valid()); + + std::tuple result = lua["f"](); + auto s = std::get<0>(result); + auto v = std::get<1>(result); + REQUIRE(s == "3"); + REQUIRE(v == 4); +} + +TEST_CASE("functions/overload resolution", "Check if overloaded function resolution templates compile/work") { + sol::state lua; + sol::stack_guard luasg(lua); + + lua.open_libraries(sol::lib::base); + + lua.set_function("non_overloaded", non_overloaded); + { + auto result = lua.safe_script("x = non_overloaded(1, 2, 3)\nprint(x)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + + /* + // Cannot reasonably support: clang++ refuses to try enough + // deductions to make this work + lua.set_function("overloaded", overloaded); + { auto result = lua.safe_script("print(overloaded(1))", sol::script_pass_on_error); REQUIRE(result.valid()); } + + lua.set_function("overloaded", overloaded); + { auto result = lua.safe_script("print(overloaded(1, 2))", sol::script_pass_on_error); REQUIRE(result.valid()); } + + lua.set_function("overloaded", overloaded); + { auto result = lua.safe_script("print(overloaded(1, 2, 3))", sol::script_pass_on_error); REQUIRE(result.valid()); } + */ + lua.set_function("overloaded", sol::resolve(overloaded)); + { + auto result = lua.safe_script("print(overloaded(1))", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + + lua.set_function("overloaded", sol::resolve(overloaded)); + { + auto result = lua.safe_script("print(overloaded(1, 2))", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + + lua.set_function("overloaded", sol::resolve(overloaded)); + { + auto result = lua.safe_script("print(overloaded(1, 2, 3))", sol::script_pass_on_error); + REQUIRE(result.valid()); + } +} + +TEST_CASE("functions/return order and multi get", "Check if return order is in the same reading order specified in Lua") { + const static std::tuple triple = std::make_tuple(10, 11, 12); + const static std::tuple paired = std::make_tuple(10, 10.f); + sol::state lua; + sol::stack_guard luasg(lua); + + lua.set_function("f", [] { return std::make_tuple(10, 11, 12); }); + lua.set_function("h", []() { return std::make_tuple(10, 10.0f); }); + auto result1 = lua.safe_script("function g() return 10, 11, 12 end\nx,y,z = g()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + + auto tcpp = lua.get("f").call(); + auto tlua = lua.get("g").call(); + auto tcpp2 = lua.get("h").call(); + auto tluaget = lua.get("x", "y", "z"); + REQUIRE(tcpp == triple); + REQUIRE(tlua == triple); + REQUIRE(tluaget == triple); + REQUIRE(tcpp2 == paired); +} + +TEST_CASE("functions/deducing return order and multi get", "Check if return order is in the same reading order specified in Lua, with regular deducing calls") { + const static std::tuple triple = std::make_tuple(10, 11, 12); + sol::state lua; + lua.set_function("f_string", []() { return "this is a string!"; }); + sol::function f_string = lua["f_string"]; + + // Make sure there are no overload collisions / compiler errors for automatic string conversions + std::string f_string_result = f_string(); + REQUIRE(f_string_result == "this is a string!"); + f_string_result = f_string(); + REQUIRE(f_string_result == "this is a string!"); + + lua.set_function("f", [] { return std::make_tuple(10, 11, 12); }); + auto result1 = lua.safe_script("function g() return 10, 11, 12 end\nx,y,z = g()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + + std::tuple tcpp = lua.get("f")(); + std::tuple tlua = lua.get("g")(); + std::tuple tluaget = lua.get("x", "y", "z"); + INFO("cpp: " << std::get<0>(tcpp) << ',' << std::get<1>(tcpp) << ',' << std::get<2>(tcpp)); + INFO("lua: " << std::get<0>(tlua) << ',' << std::get<1>(tlua) << ',' << std::get<2>(tlua)); + INFO("lua xyz: " << lua.get("x") << ',' << lua.get("y") << ',' << lua.get("z")); + REQUIRE(tcpp == triple); + REQUIRE(tlua == triple); + REQUIRE(tluaget == triple); +} + +TEST_CASE("functions/optional values", "check if optionals can be passed in to be nil or otherwise") { + struct thing { + int v; + }; + sol::state lua; + auto result1 = lua.safe_script(R"( function f (a) + return a +end )", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + + sol::function lua_bark = lua["f"]; + + sol::optional testv = lua_bark(sol::optional(29)); + sol::optional testn = lua_bark(sol::nullopt); + REQUIRE((bool)testv); + REQUIRE_FALSE((bool)testn); + REQUIRE(testv.value() == 29); + sol::optional v = lua_bark(sol::optional(thing{ 29 })); + REQUIRE_NOTHROW([&] { + sol::lua_nil_t n = lua_bark(sol::nullopt); + return n; + }()); + REQUIRE(v->v == 29); +} + +TEST_CASE("functions/pair and tuple and proxy tests", "Check if sol::reference and sol::proxy can be passed to functions as arguments") { + sol::state lua; + sol::stack_guard luasg(lua); + + lua.new_usertype("A", "bark", &A::bark); + auto result1 = lua.safe_script(R"( function f (num_value, a) + return num_value * 2, a:bark() +end +function h (num_value, a, b) + return num_value * 2, a:bark(), b * 3 +end +nested = { variables = { no = { problem = 10 } } } )", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + + lua.set_function("g", bark); + + sol::function cpp_bark = lua["g"]; + sol::function lua_bark = lua["f"]; + sol::function lua_bark2 = lua["h"]; + + sol::reference lua_variable_x = lua["nested"]["variables"]["no"]["problem"]; + A cpp_variable_y; + + static const std::tuple abdesired(20, 1); + static const std::pair cddesired = { 20, 1 }; + static const std::tuple abcdesired(20, 1, 3); + + std::tuple ab = cpp_bark(lua_variable_x, cpp_variable_y); + std::pair cd = lua_bark(lua["nested"]["variables"]["no"]["problem"], cpp_variable_y); + + REQUIRE(ab == abdesired); + REQUIRE(cd == cddesired); + + ab = cpp_bark(std::make_pair(lua_variable_x, cpp_variable_y)); + cd = static_cast>(lua_bark(std::make_pair(lua["nested"]["variables"]["no"]["problem"], cpp_variable_y))); + + REQUIRE(ab == abdesired); + REQUIRE(cd == cddesired); + + std::tuple abc = lua_bark2(std::make_tuple(10, cpp_variable_y), sol::optional(1)); + REQUIRE(abc == abcdesired); +} + +TEST_CASE("functions/function_result and protected_function_result", + "Function result should be the beefy return type for sol::function that allows for error checking and error handlers") { + static const char unhandlederrormessage[] = "true error message"; + static const char handlederrormessage[] = "doodle"; + static const std::string handlederrormessage_s = handlederrormessage; + + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base, sol::lib::debug); + + // Some function; just using a lambda to be cheap + auto doomfx = []() { throw std::runtime_error(unhandlederrormessage); }; + lua.set_function("doom", doomfx); + + auto cpphandlerfx = [](std::string x) { + INFO("c++ handler called with: " << x); + return handlederrormessage; + }; + lua.set_function("cpphandler", cpphandlerfx); + + auto result1 = lua.safe_script(std::string("function luahandler ( message )") + " print('lua handler called with: ' .. message)" + " return '" + + handlederrormessage + "'" + "end", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + + auto nontrampolinefx = [](lua_State* L) -> int { return luaL_error(L, "x"); }; + lua_CFunction c_nontrampolinefx = nontrampolinefx; + lua.set("nontrampoline", c_nontrampolinefx); + + lua.set_function("bark", []() -> int { return 100; }); + + sol::function luahandler = lua["luahandler"]; + sol::function cpphandler = lua["cpphandler"]; + sol::protected_function doom(lua["doom"], luahandler); + sol::protected_function nontrampoline(lua["nontrampoline"], cpphandler); + sol::protected_function justfine = lua["bark"]; + sol::protected_function justfinewithhandler = lua["bark"]; + + justfinewithhandler.error_handler = luahandler; + bool present = true; + { + sol::protected_function_result result = doom(); + REQUIRE_FALSE(result.valid()); + sol::optional operr = result; + sol::optional opvalue = result; + present = (bool)operr; + REQUIRE(present); + present = (bool)opvalue; + REQUIRE_FALSE(present); + sol::error err = result; + REQUIRE(err.what() == handlederrormessage_s); + } + { + sol::protected_function_result result = nontrampoline(); + REQUIRE_FALSE(result.valid()); + sol::optional operr = result; + sol::optional opvalue = result; + present = (bool)operr; + REQUIRE(present); + present = (bool)opvalue; + REQUIRE_FALSE(present); + sol::error err = result; + REQUIRE(err.what() == handlederrormessage_s); + } + { + sol::protected_function_result result = justfine(); + REQUIRE(result.valid()); + sol::optional operr = result; + sol::optional opvalue = result; + present = (bool)operr; + REQUIRE_FALSE(present); + present = (bool)opvalue; + REQUIRE(present); + int value = result; + REQUIRE(value == 100); + } + { + sol::protected_function_result result = justfinewithhandler(); + REQUIRE(result.valid()); + sol::optional operr = result; + sol::optional opvalue = result; + present = (bool)operr; + REQUIRE_FALSE(present); + present = (bool)opvalue; + REQUIRE(present); + int value = result; + REQUIRE(value == 100); + } +} + +#if !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; + lua.open_libraries(sol::lib::base, sol::lib::debug); + static const char unhandlederrormessage[] = "true error message"; + static const char handlederrormessage[] = "doodle"; + static const std::string handlederrormessage_s = handlederrormessage; + + auto luadoomfx = [&lua]() { + // Does not bypass error function, will call it + // however, this bypasses `catch` state + // in trampoline entirely... + luaL_error(lua.lua_state(), unhandlederrormessage); + }; + lua.set_function("luadoom", luadoomfx); + + auto cpphandlerfx = [](std::string x) { + INFO("c++ handler called with: " << x); + return handlederrormessage; + }; + lua.set_function("cpphandler", cpphandlerfx); + + sol::function cpphandler = lua["cpphandler"]; + sol::protected_function luadoom(lua["luadoom"]); + luadoom.error_handler = cpphandler; + + bool present = true; + { + sol::protected_function_result result = luadoom(); + REQUIRE_FALSE(result.valid()); + sol::optional operr = result; + sol::optional opvalue = result; + present = (bool)operr; + REQUIRE(present); + present = (bool)opvalue; + REQUIRE_FALSE(present); + sol::error err = result; + REQUIRE(err.what() == handlederrormessage_s); + } +} + +TEST_CASE("functions/unsafe protected_function_result handlers", + "This test will thrash the stack and allocations on weaker compilers (e.g., non 64-bit ones). Run with caution.") { + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::debug); + static const char handlederrormessage[] = "doodle"; + static const std::string handlederrormessage_s = handlederrormessage; + + auto cpphandlerfx = [](std::string x) { + INFO("c++ handler called with: " << x); + return handlederrormessage; + }; + lua.set_function("cpphandler", cpphandlerfx); + auto nontrampolinefx = [](lua_State*) -> int { + // this code shoots an exception + // through the C API, without the trampoline + // present. + // it is probably guaranteed to kill our code. + throw "x"; + }; + lua_CFunction c_nontrampolinefx = nontrampolinefx; + lua.set("nontrampoline", c_nontrampolinefx); + + sol::function cpphandler = lua["cpphandler"]; + sol::protected_function nontrampoline = lua["nontrampoline"]; + nontrampoline.error_handler = cpphandler; + + { + sol::protected_function_result result = nontrampoline(); + REQUIRE_FALSE(result.valid()); + sol::optional operr = result; + sol::optional opvalue = result; + bool present = (bool)operr; + REQUIRE(present); + present = (bool)opvalue; + REQUIRE_FALSE(present); + sol::error err = result; +#ifdef SOL_LUAJIT +#if !((!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !(SOL_EXCEPTIONS_SAFE_PROPAGATION))) + REQUIRE(err.what() == std::string("C++ exception")); +#else + REQUIRE(err.what() == handlederrormessage_s); +#endif +#else + REQUIRE(err.what() == handlederrormessage_s); +#endif + } +} +#endif // These tests will thrash the stack and allocations on weaker compilers + +TEST_CASE("functions/all kinds", "Register all kinds of functions, make sure they all compile and work") { + sol::state lua; + sol::stack_guard luasg(lua); + + struct test_1 { + int a = 0xA; + virtual int bark() { + return a; + } + + int bark_mem() { + return a; + } + + static std::tuple x_bark(int num_value, test_1* a) { + return std::tuple(num_value * 2, a->a); + } + + virtual ~test_1() { + } + }; + + struct test_2 { + int a = 0xC; + int bark() { + return 20; + } + }; + + struct inner { + const int z = 5653; + }; + + struct nested { + inner i; + }; + + auto a = []() { return 500; }; + auto b = [&]() { return 501; }; + auto c = [&]() { return 502; }; + auto d = []() { return 503; }; + + lua.new_usertype("test_1", "bark", sol::c_call); + lua.new_usertype("test_2", "bark", sol::c_call); + test_2 t2; + + lua.set_function("a", a); + lua.set_function("b", b); + lua.set_function("c", std::ref(c)); + lua.set_function("d", std::ref(d)); + lua.set_function("f", &test_1::bark); + lua.set_function("g", test_1::x_bark); + lua.set_function("h", sol::c_call); + lua.set_function("i", &test_2::bark, test_2()); + lua.set_function("j", &test_2::a, test_2()); + lua.set_function("k", &test_2::a); + lua.set_function("l", sol::c_call); + lua.set_function("m", &test_2::a, &t2); + lua.set_function("n", sol::c_call); + + auto result1 = lua.safe_script(R"( +o1 = test_1.new() +o2 = test_2.new() +)", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + + auto result2 = lua.safe_script(R"( +ob = o1:bark() + +A = a() +B = b() +C = c() +D = d() +F = f(o1) +G0, G1 = g(2, o1) +H = h(o1) +I = i(o1) +I = i(o1) +)", + sol::script_pass_on_error); + REQUIRE(result2.valid()); + + auto result3 = lua.safe_script(R"( +J0 = j() +j(24) +J1 = j() + )", + sol::script_pass_on_error); + REQUIRE(result3.valid()); + + auto result4 = lua.safe_script(R"( +K0 = k(o2) +k(o2, 1024) +K1 = k(o2) + )", + sol::script_pass_on_error); + REQUIRE(result4.valid()); + + auto result5 = lua.safe_script(R"( +L0 = l(o1) +l(o1, 678) +L1 = l(o1) + )", + sol::script_pass_on_error); + REQUIRE(result5.valid()); + + auto result6 = lua.safe_script(R"( +M0 = m() +m(256) +M1 = m() + )", + sol::script_pass_on_error); + REQUIRE(result6.valid()); + + auto result7 = lua.safe_script(R"( +N = n(1, 2, 3) + )", + sol::script_pass_on_error); + REQUIRE(result7.valid()); + + int ob, A, B, C, D, F, G0, G1, H, I, J0, J1, K0, K1, L0, L1, M0, M1, N; + std::tie(ob, A, B, C, D, F, G0, G1, H, I, J0, J1, K0, K1, L0, L1, M0, M1, N) + = lua.get( + "ob", "A", "B", "C", "D", "F", "G0", "G1", "H", "I", "J0", "J1", "K0", "K1", "L0", "L1", "M0", "M1", "N"); + + REQUIRE(ob == 0xA); + + REQUIRE(A == 500); + REQUIRE(B == 501); + REQUIRE(C == 502); + REQUIRE(D == 503); + + REQUIRE(F == 0xA); + REQUIRE(G0 == 4); + REQUIRE(G1 == 0xA); + REQUIRE(H == 0xA); + REQUIRE(I == 20); + + REQUIRE(J0 == 0xC); + REQUIRE(J1 == 24); + + REQUIRE(K0 == 0xC); + REQUIRE(K1 == 1024); + + REQUIRE(L0 == 0xA); + REQUIRE(L1 == 678); + + REQUIRE(M0 == 0xC); + REQUIRE(M1 == 256); + + REQUIRE(N == 13); + + sol::tie(ob, A, B, C, D, F, G0, G1, H, I, J0, J1, K0, K1, L0, L1, M0, M1, N) + = lua.get( + "ob", "A", "B", "C", "D", "F", "G0", "G1", "H", "I", "J0", "J1", "K0", "K1", "L0", "L1", "M0", "M1", "N"); + + REQUIRE(ob == 0xA); + + REQUIRE(A == 500); + REQUIRE(B == 501); + REQUIRE(C == 502); + REQUIRE(D == 503); + + REQUIRE(F == 0xA); + REQUIRE(G0 == 4); + REQUIRE(G1 == 0xA); + REQUIRE(H == 0xA); + REQUIRE(I == 20); + + REQUIRE(J0 == 0xC); + REQUIRE(J1 == 24); + + REQUIRE(K0 == 0xC); + REQUIRE(K1 == 1024); + + REQUIRE(L0 == 0xA); + REQUIRE(L1 == 678); + + REQUIRE(M0 == 0xC); + REQUIRE(M1 == 256); + + REQUIRE(N == 13); + + // Work that compiler, WORK IT! + test_2 test_2_instance; + lua.set("o", &test_1::bark); + lua.set("p", test_1::x_bark); + lua.set("q", sol::c_call); + lua.set("r", &test_2::a); + lua.set("s", sol::readonly(&test_2::a)); + lua.set_function("t", sol::readonly(&test_2::a), test_2()); + lua.set_function("t2", sol::readonly(&test_2::a), &test_2_instance); + lua.set_function("t3", sol::readonly(&test_2::a), std::ref(test_2_instance)); + lua.set_function("t4", sol::readonly(&test_2::a), std::cref(test_2_instance)); + lua.set_function("u", &nested::i, nested()); + lua.set("v", &nested::i); + lua.set("nested", nested()); + lua.set("inner", inner()); + { + auto result = lua.safe_script("s(o2, 2)", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } + { + auto tresult = lua.safe_script("t(2)", sol::script_pass_on_error); + REQUIRE_FALSE(tresult.valid()); + auto tresult2 = lua.safe_script("t2(2)", sol::script_pass_on_error); + REQUIRE_FALSE(tresult2.valid()); + auto tresult3 = lua.safe_script("t3(2)", sol::script_pass_on_error); + REQUIRE_FALSE(tresult3.valid()); + auto tresult4 = lua.safe_script("t4(2)", sol::script_pass_on_error); + REQUIRE_FALSE(tresult4.valid()); + } + { + auto result = lua.safe_script("u(inner)", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } + { + auto result = lua.safe_script("v(nested, inner)", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } +} + +TEST_CASE("simple/call with parameters", "Lua function is called with a few parameters from C++") { + sol::state lua; + + { + auto result = lua.safe_script("function my_add(i, j, k) return i + j + k end", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + auto f = lua.get("my_add"); + { + auto result = lua.safe_script("function my_nothing(i, j, k) end", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + auto fvoid = lua.get("my_nothing"); + REQUIRE_NOTHROW([&]() { fvoid(1, 2, 3); }()); + REQUIRE_NOTHROW([&]() { + int a = f.call(1, 2, 3); + REQUIRE(a == 6); + }()); + sol::protected_function pf = f; + REQUIRE_NOTHROW([&]() { + sol::protected_function_result pfr = pf(1, 2, "arf"); + REQUIRE_FALSE(pfr.valid()); + }()); +} + +TEST_CASE("simple/call c++ function", "C++ function is called from lua") { + sol::state lua; + + lua.set_function("plop_xyz", sep::plop_xyz); + auto result1 = lua.safe_script("x = plop_xyz(2, 6, 'hello')", sol::script_pass_on_error); + REQUIRE(result1.valid()); + + REQUIRE(lua.get("x") == 11); +} + +TEST_CASE("simple/call lambda", "A C++ lambda is exposed to lua and called") { + sol::state lua; + + int a = 0; + + lua.set_function("foo", [&a] { a = 1; }); + + auto result1 = lua.safe_script("foo()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + + REQUIRE(a == 1); +} + +TEST_CASE("advanced/get and call", "Checks for lambdas returning values after a get operation") { + const static std::string lol = "lol", str = "str"; + const static std::tuple heh_tuple = std::make_tuple(1, 6.28f, 3.14, std::string("heh")); + sol::state lua; + + REQUIRE_NOTHROW(lua.set_function("a", [] { return 42; })); + REQUIRE(lua.get("a").call() == 42); + + REQUIRE_NOTHROW(lua.set_function("b", [] { return 42u; })); + REQUIRE(lua.get("b").call() == 42u); + + REQUIRE_NOTHROW(lua.set_function("c", [] { return 3.14; })); + REQUIRE(lua.get("c").call() == 3.14); + + REQUIRE_NOTHROW(lua.set_function("d", [] { return 6.28f; })); + REQUIRE(lua.get("d").call() == 6.28f); + + REQUIRE_NOTHROW(lua.set_function("e", [] { return "lol"; })); + REQUIRE(lua.get("e").call() == lol); + + REQUIRE_NOTHROW(lua.set_function("f", [] { return true; })); + REQUIRE(lua.get("f").call()); + + REQUIRE_NOTHROW(lua.set_function("g", [] { return std::string("str"); })); + REQUIRE(lua.get("g").call() == str); + + REQUIRE_NOTHROW(lua.set_function("h", [] {})); + REQUIRE_NOTHROW(lua.get("h").call()); + + REQUIRE_NOTHROW(lua.set_function("i", [] { return sol::lua_nil; })); + REQUIRE(lua.get("i").call() == sol::lua_nil); + REQUIRE_NOTHROW(lua.set_function("j", [] { return std::make_tuple(1, 6.28f, 3.14, std::string("heh")); })); + REQUIRE((lua.get("j").call() == heh_tuple)); +} + +TEST_CASE("advanced/operator[] call", "Checks for lambdas returning values using operator[]") { + const static std::string lol = "lol", str = "str"; + const static std::tuple heh_tuple = std::make_tuple(1, 6.28f, 3.14, std::string("heh")); + sol::state lua; + + REQUIRE_NOTHROW(lua.set_function("a", [] { return 42; })); + REQUIRE(lua["a"].call() == 42); + + REQUIRE_NOTHROW(lua.set_function("b", [] { return 42u; })); + REQUIRE(lua["b"].call() == 42u); + + REQUIRE_NOTHROW(lua.set_function("c", [] { return 3.14; })); + REQUIRE(lua["c"].call() == 3.14); + + REQUIRE_NOTHROW(lua.set_function("d", [] { return 6.28f; })); + REQUIRE(lua["d"].call() == 6.28f); + + REQUIRE_NOTHROW(lua.set_function("e", [] { return "lol"; })); + REQUIRE(lua["e"].call() == lol); + + REQUIRE_NOTHROW(lua.set_function("f", [] { return true; })); + REQUIRE(lua["f"].call()); + + REQUIRE_NOTHROW(lua.set_function("g", [] { return std::string("str"); })); + REQUIRE(lua["g"].call() == str); + + REQUIRE_NOTHROW(lua.set_function("h", [] {})); + REQUIRE_NOTHROW(lua["h"].call()); + + REQUIRE_NOTHROW(lua.set_function("i", [] { return sol::lua_nil; })); + REQUIRE(lua["i"].call() == sol::lua_nil); + REQUIRE_NOTHROW(lua.set_function("j", [] { return std::make_tuple(1, 6.28f, 3.14, std::string("heh")); })); + REQUIRE((lua["j"].call() == heh_tuple)); +} + +TEST_CASE("advanced/call lambdas", "A C++ lambda is exposed to lua and called") { + sol::state lua; + + int x = 0; + lua.set_function("set_x", [&](int new_x) { + x = new_x; + return 0; + }); + + auto result1 = lua.safe_script("set_x(9)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + REQUIRE(x == 9); +} + +TEST_CASE("advanced/call referenced obj", "A C++ object is passed by pointer/reference_wrapper to lua and invoked") { + sol::state lua; + + int x = 0; + auto objx = [&](int new_x) { + x = new_x; + return 0; + }; + lua.set_function("set_x", std::ref(objx)); + + int y = 0; + auto objy = [&](int new_y) { + y = new_y; + return std::tuple(0, 0); + }; + lua.set_function("set_y", &decltype(objy)::operator(), std::ref(objy)); + + auto result1 = lua.safe_script("set_x(9)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("set_y(9)", sol::script_pass_on_error); + REQUIRE(result2.valid()); + + REQUIRE(x == 9); + REQUIRE(y == 9); +} + +TEST_CASE("functions/tie", "make sure advanced syntax with 'tie' works") { + sol::state lua; + + auto result1 = lua.safe_script(R"(function f () + return 1, 2, 3 +end)", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::function f = lua["f"]; + + int a, b, c; + sol::tie(a, b, c) = f(); + REQUIRE(a == 1); + REQUIRE(b == 2); + REQUIRE(c == 3); +} + +TEST_CASE("functions/overloading", "Check if overloading works properly for regular set function syntax") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.set_function("func_1", func_1); + lua.set_function("func", sol::overload(func_2, func_3, func_1, func_1s)); + + const std::string string_bark = "string: bark"; + + { + auto result = lua.safe_script( + "a = func(1)\n" + "b = func('bark')\n" + "c = func(1,2)\n" + "func(1,2,3)\n", + sol::script_pass_on_error); + REQUIRE(result.valid()); + } + + REQUIRE((lua["a"] == 1)); + REQUIRE((lua["b"] == string_bark)); + REQUIRE((lua["c"] == 2)); + + { + auto result = lua.safe_script("func(1,2,'meow')", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } +} + +TEST_CASE("overloading/c_call", "Make sure that overloading works with c_call functionality") { + sol::state lua; + lua.set("f", sol::c_call, sol::wrap, sol::wrap>); + lua.set("g", sol::c_call>); + lua.set("h", sol::c_call); + lua.set("obj", fer()); + + lua.safe_script("r1 = f(1)"); + lua.safe_script("r2 = f(1, 2)"); + lua.safe_script("r3 = f(obj, 1, 2)"); + lua.safe_script("r4 = g(1)"); + lua.safe_script("r5 = h(1, 2)"); + + int r1 = lua["r1"]; + int r2 = lua["r2"]; + double r3 = lua["r3"]; + int r4 = lua["r4"]; + int r5 = lua["r5"]; + + REQUIRE(r1 == 32); + REQUIRE(r2 == 1); + REQUIRE(r3 == 2.5); + REQUIRE(r4 == 32); + REQUIRE(r5 == 1); +} + +TEST_CASE("functions/stack atomic", "make sure functions don't impede on the stack") { + // setup sol/lua + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::string); + + lua.safe_script("function ErrorHandler(msg) print('Lua created error msg : ' .. msg) return msg end"); + lua.safe_script("function stringtest(a) if a == nil then error('fuck') end print('Lua recieved content : ' .. a) return a end"); + + // test normal function + { + sol::stack_guard normalsg(lua); + std::string str = lua["stringtest"]("normal test"); + INFO("Back in C++, direct call result is : " << str); + } + + // test protected_function + sol::protected_function Stringtest(lua["stringtest"]); + Stringtest.error_handler = lua["ErrorHandler"]; + sol::stack_guard luasg(lua); + { + sol::protected_function_result stringresult = Stringtest("protected test"); + REQUIRE(stringresult.valid()); + std::string s = stringresult; + INFO("Back in C++, protected result is : " << s); + } + REQUIRE(luasg.check_stack()); + + // test optional + { + sol::stack_guard opsg(lua); + sol::optional opt_result = Stringtest("optional test"); + REQUIRE(opsg.check_stack()); + if (opt_result) { + std::string s = opt_result.value(); + INFO("Back in C++, opt_result is : " << s); + } + else { + INFO("opt_result failed"); + } + } + REQUIRE(luasg.check_stack()); + + { + sol::protected_function_result errresult = Stringtest(sol::lua_nil); + REQUIRE_FALSE(errresult.valid()); + sol::error err = errresult; + std::string msg = err.what(); + INFO("error :" << msg); + } + REQUIRE(luasg.check_stack()); +} + +TEST_CASE("functions/stack multi-return", "Make sure the stack is protected after multi-returns") { + sol::state lua; + lua.safe_script("function f () return 1, 2, 3, 4, 5 end"); + + { + sol::stack_guard luasg(lua); + sol::stack::push(lua, double(256.78)); + { + int a, b, c, d, e; + sol::stack_guard sg2(lua); + sol::function f = lua["f"]; + sol::tie(a, b, c, d, e) = f(); + REQUIRE(a == 1); + REQUIRE(b == 2); + REQUIRE(c == 3); + REQUIRE(d == 4); + REQUIRE(e == 5); + } + double f = sol::stack::pop(lua); + REQUIRE(f == 256.78); + } +} + +TEST_CASE("functions/protected stack multi-return", "Make sure the stack is protected after multi-returns") { + sol::state lua; + lua.safe_script("function f () return 1, 2, 3, 4, 5 end"); + + { + sol::stack_guard luasg(lua); + sol::stack::push(lua, double(256.78)); + { + int a, b, c, d, e; + sol::stack_guard sg2(lua); + sol::protected_function pf = lua["f"]; + sol::tie(a, b, c, d, e) = pf(); + REQUIRE(a == 1); + REQUIRE(b == 2); + REQUIRE(c == 3); + REQUIRE(d == 4); + REQUIRE(e == 5); + } + double f = sol::stack::pop(lua); + REQUIRE(f == 256.78); + } +} + +TEST_CASE("functions/function_result as arguments", "ensure that function_result can be pushed as its results and not a userdata") { + sol::state lua; + lua.open_libraries(); + + lua.safe_script("function f () return 1, 2, 3, 4, 5 end"); + lua.safe_script("function g (a, b, c, d, e) assert(a == 1) assert(b == 2) assert(c == 3) assert(d == 4) assert(e == 5) end"); + + { + sol::stack_guard luasg(lua); + sol::stack::push(lua, double(256.78)); + { + int a, b, c, d, e; + sol::stack_guard sg2(lua); + sol::function pf = lua["f"]; + sol::tie(a, b, c, d, e) = pf(); + REQUIRE(a == 1); + REQUIRE(b == 2); + REQUIRE(c == 3); + REQUIRE(d == 4); + REQUIRE(e == 5); + REQUIRE_NOTHROW([&]() { lua["g"](pf()); }()); + } + double f = sol::stack::pop(lua); + REQUIRE(f == 256.78); + } +} + +TEST_CASE("functions/protected_function_result as arguments", "ensure that protected_function_result can be pushed as its results and not a userdata") { + sol::state lua; + lua.open_libraries(); + + lua.safe_script("function f () return 1, 2, 3, 4, 5 end"); + lua.safe_script("function g (a, b, c, d, e) assert(a == 1) assert(b == 2) assert(c == 3) assert(d == 4) assert(e == 5) end"); + + { + sol::stack_guard luasg(lua); + sol::stack::push(lua, double(256.78)); + { + int a, b, c, d, e; + sol::stack_guard sg2(lua); + sol::protected_function pf = lua["f"]; + sol::tie(a, b, c, d, e) = pf(); + REQUIRE(a == 1); + REQUIRE(b == 2); + REQUIRE(c == 3); + REQUIRE(d == 4); + REQUIRE(e == 5); + REQUIRE_NOTHROW([&]() { lua["g"](pf()); }()); + } + double f = sol::stack::pop(lua); + REQUIRE(f == 256.78); + } +} + +TEST_CASE("functions/overloaded variadic", "make sure variadics work to some degree with overloading") { + sol::state lua; + lua.open_libraries(); + + sol::table ssl = lua.create_named_table("ssl"); + ssl.set_function("test", sol::overload(&va_func, &va_func)); + + lua.safe_script("a = ssl.test(1, 2, 3)"); + lua.safe_script("b = ssl.test(1, 2)"); + lua.safe_script("c = ssl.test(2.2)"); + + int a = lua["a"]; + int b = lua["b"]; + double c = lua["c"]; + REQUIRE(a == 6); + REQUIRE(b == 3); + REQUIRE(c == 2.2); +} + +TEST_CASE("functions/sectioning variadic", "make sure variadics can bite off chunks of data") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.set_function("f", [](sol::variadic_args va) { + int r = 0; + sol::variadic_args shifted_va(va.lua_state(), 3); + for (auto v : shifted_va) { + int value = v; + r += value; + } + return r; + }); + + lua.safe_script("x = f(1, 2, 3, 4)"); + lua.safe_script("x2 = f(8, 200, 3, 4)"); + lua.safe_script("x3 = f(1, 2, 3, 4, 5, 6)"); + + lua.safe_script("print(x) assert(x == 7)"); + lua.safe_script("print(x2) assert(x2 == 7)"); + lua.safe_script("print(x3) assert(x3 == 18)"); +} + +TEST_CASE("functions/pointer nullptr + nil", "ensure specific semantics for handling pointer-nils passed through sol") { + struct nil_test { + + static void f(nil_test* p) { + REQUIRE(p == nullptr); + } + static void g(std::unique_ptr& p) { + REQUIRE(p == nullptr); + } + static void h(std::shared_ptr& p) { + REQUIRE(p == nullptr); + } + }; + + std::shared_ptr sptr; + std::unique_ptr uptr; + std::unique_ptr ruptr; + nil_test* rptr = ruptr.get(); + nil_test* vptr = nullptr; + + SECTION("ptr") { + sol::state lua; + lua["v1"] = sptr; + lua["v2"] = std::unique_ptr(); + lua["v3"] = rptr; + lua["v4"] = vptr; + + REQUIRE_NOTHROW([&]() { + nil_test* v1 = lua["v1"]; + nil_test* v2 = lua["v2"]; + nil_test* v3 = lua["v3"]; + nil_test* v4 = lua["v4"]; + REQUIRE(v1 == sptr.get()); + REQUIRE(v1 == nullptr); + REQUIRE(v2 == uptr.get()); + REQUIRE(v2 == nullptr); + REQUIRE(v3 == rptr); + REQUIRE(v3 == nullptr); + REQUIRE(v4 == vptr); + REQUIRE(v4 == nullptr); + }()); + } + SECTION("ptr") { + sol::state lua; + lua.open_libraries(); + + lua["v1"] = sptr; + lua["v2"] = std::unique_ptr(); + lua["v3"] = rptr; + lua["v4"] = vptr; + lua["f"] = &nil_test::f; + lua["g"] = &nil_test::g; + lua["h"] = &nil_test::h; + + REQUIRE_NOTHROW([&]() { + lua.safe_script("f(v1)"); + lua.safe_script("f(v2)"); + lua.safe_script("f(v3)"); + lua.safe_script("f(v4)"); + + lua.safe_script("assert(v1 == nil)"); + lua.safe_script("assert(v2 == nil)"); + lua.safe_script("assert(v3 == nil)"); + lua.safe_script("assert(v4 == nil)"); + }()); + } + SECTION("throw unique argument") { + sol::state lua; + lua["v2"] = std::unique_ptr(); + lua["g"] = &nil_test::g; + + auto result = lua.safe_script("g(v2)", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } + SECTION("throw shared argument") { + sol::state lua; + lua["v1"] = sptr; + lua["h"] = &nil_test::h; + + auto result = lua.safe_script("h(v1)", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } + SECTION("throw ref") { + { + sol::state lua; + lua["v1"] = sptr; + sol::object o = lua["v1"]; + bool isp = o.is(); + REQUIRE_FALSE(isp); + } + { + sol::state lua; + lua["v2"] = std::unique_ptr(); + sol::object o = lua["v2"]; + bool isp = o.is(); + REQUIRE_FALSE(isp); + } + { + sol::state lua; + lua["v3"] = rptr; + sol::object o = lua["v3"]; + bool isp = o.is(); + REQUIRE_FALSE(isp); + } + { + sol::state lua; + lua["v4"] = vptr; + sol::object o = lua["v4"]; + bool isp = o.is(); + REQUIRE_FALSE(isp); + } + } + SECTION("throw unique") { + { + sol::state lua; + lua["v1"] = sptr; + sol::object o = lua["v1"]; + bool isp = o.is>(); + REQUIRE_FALSE(isp); + } + { + sol::state lua; + lua["v2"] = std::unique_ptr(); + sol::object o = lua["v2"]; + bool isp = o.is>(); + REQUIRE_FALSE(isp); + } + { + sol::state lua; + lua["v3"] = rptr; + sol::object o = lua["v3"]; + bool isp = o.is>(); + REQUIRE_FALSE(isp); + }; + { + sol::state lua; + lua["v4"] = vptr; + sol::object o = lua["v4"]; + bool isp = o.is>(); + REQUIRE_FALSE(isp); + }; + } + SECTION("throw shared") { + { + sol::state lua; + lua["v1"] = sptr; + sol::object o = lua["v1"]; + bool isp = o.is>(); + REQUIRE_FALSE(isp); + } + { + sol::state lua; + lua["v2"] = std::unique_ptr(); + sol::object o = lua["v2"]; + bool isp = o.is>(); + REQUIRE_FALSE(isp); + } + { + sol::state lua; + lua["v3"] = rptr; + sol::object o = lua["v3"]; + bool isp = o.is>(); + REQUIRE_FALSE(isp); + } + { + sol::state lua; + lua["v4"] = vptr; + sol::object o = lua["v4"]; + bool isp = o.is>(); + REQUIRE_FALSE(isp); + } + } +} + +TEST_CASE("functions/unique_usertype overloading", "make sure overloading can work with ptr vs. specifically asking for a unique_usertype") { + struct test { + int special_value = 17; + test() : special_value(17) { + } + test(int special_value) : special_value(special_value) { + } + }; + auto print_up_test = [](std::unique_ptr& x) { REQUIRE(x->special_value == 21); }; + auto print_up_2_test = [](int, std::unique_ptr& x) { REQUIRE(x->special_value == 21); }; + auto print_sp_test = [](std::shared_ptr& x) { REQUIRE(x->special_value == 44); }; + auto print_ptr_test = [](test* x) { REQUIRE(x->special_value == 17); }; + auto print_ref_test = [](test& x) { + bool is_any = x.special_value == 17 || x.special_value == 21 || x.special_value == 44; + REQUIRE(is_any); + }; + using f_t = void(test&); + f_t* fptr = print_ref_test; + + std::unique_ptr ut = std::make_unique(17); + SECTION("working") { + sol::state lua; + + lua.set_function("f", print_up_test); + lua.set_function("g", sol::overload(std::move(print_sp_test), print_up_test, std::ref(print_ptr_test))); + lua.set_function("h", std::ref(fptr)); + lua.set_function("i", std::move(print_up_2_test)); + + lua["v1"] = std::make_unique(21); + lua["v2"] = std::make_shared(44); + lua["v3"] = test(17); + lua["v4"] = ut.get(); + + { + auto result = lua.safe_script("f(v1)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("g(v1)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("g(v2)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("g(v3)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("g(v4)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("h(v1)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("h(v2)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("h(v3)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("h(v4)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("i(20, v1)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + }; + // LuaJIT segfaults hard on some Linux machines + // and it breaks all the tests... + SECTION("throws-value") { + sol::state lua; + + lua.set_function("f", print_up_test); + lua["v3"] = test(17); + + auto result = lua.safe_script("f(v3)", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + }; + SECTION("throws-shared_ptr") { + sol::state lua; + + lua.set_function("f", print_up_test); + lua["v2"] = std::make_shared(44); + + auto result = lua.safe_script("f(v2)", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + }; + SECTION("throws-ptr") { + sol::state lua; + + lua.set_function("f", print_up_test); + lua["v4"] = ut.get(); + + auto result = lua.safe_script("f(v4)", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + }; +} + +TEST_CASE("functions/lua style default arguments", "allow default arguments using sol::reference and sol::object") { + auto def_f1 = [](sol::object defaulted) -> int { + bool inactive = defaulted == sol::lua_nil; // inactive by default + if (inactive) { + return 20; + } + return 10; + }; + auto def_f2 = [](sol::reference defaulted) -> int { + bool inactive = defaulted == sol::lua_nil; // inactive by default + if (inactive) { + return 20; + } + return 10; + }; + auto def_f3 = [](sol::stack_reference defaulted) -> int { + bool inactive = defaulted == sol::lua_nil; // inactive by default + if (inactive) { + return 20; + } + return 10; + }; + + sol::state lua; + lua.set_function("f1", def_f1); + lua.set_function("f2", def_f2); + lua.set_function("f3", def_f3); + + auto result = lua.safe_script(R"( + v1d, v1nd = f1(), f1(1) + v2d, v2nd = f2(), f2(1) + v3d, v3nd = f3(), f3(1) + )", + sol::script_pass_on_error); + REQUIRE(result.valid()); + int v1d = lua["v1d"]; + int v1nd = lua["v1nd"]; + int v2d = lua["v2d"]; + int v2nd = lua["v2nd"]; + int v3d = lua["v3d"]; + int v3nd = lua["v3nd"]; + REQUIRE(20 == v1d); + REQUIRE(20 == v2d); + REQUIRE(20 == v3d); + REQUIRE(10 == v1nd); + REQUIRE(10 == v2nd); + REQUIRE(10 == v3nd); +} + +#if !defined(_MSC_VER) || !(defined(_WIN32) && !defined(_WIN64)) + +TEST_CASE("functions/noexcept", "allow noexcept functions to be serialized properly into Lua using sol3") { + struct T { + static int noexcept_function() noexcept { + return 0x61; + } + + int noexcept_method() noexcept { + return 0x62; + } + } t; + + lua_CFunction ccall = sol::c_call; + + sol::state lua; + + lua.set_function("f", &T::noexcept_function); + lua.set_function("g", &T::noexcept_method); + lua.set_function("h", &T::noexcept_method, T()); + lua.set_function("i", &T::noexcept_method, std::ref(t)); + lua.set_function("j", &T::noexcept_method, &t); + lua.set_function("k", &T::noexcept_method, t); + lua.set_function("l", &raw_noexcept_function); + lua.set_function("m", ccall); + + lua["t"] = T(); + lua.safe_script("v1 = f()"); + lua.safe_script("v2 = g(t)"); + lua.safe_script("v3 = h()"); + lua.safe_script("v4 = i()"); + lua.safe_script("v5 = j()"); + lua.safe_script("v6 = k()"); + lua.safe_script("v7 = l()"); + lua.safe_script("v8 = m()"); + int v1 = lua["v1"]; + int v2 = lua["v2"]; + int v3 = lua["v3"]; + int v4 = lua["v4"]; + int v5 = lua["v5"]; + int v6 = lua["v6"]; + int v7 = lua["v7"]; + int v8 = lua["v8"]; + REQUIRE(v1 == 0x61); + REQUIRE(v2 == 0x62); + REQUIRE(v3 == 0x62); + REQUIRE(v4 == 0x62); + REQUIRE(v5 == 0x62); + REQUIRE(v6 == 0x62); + REQUIRE(v7 == 0x63); + REQUIRE(v8 == 0x63); +} + +#endif // Strange VC++ stuff diff --git a/lib/sol2/tests/runtime_tests/source/functions.std.cpp b/lib/sol2/tests/runtime_tests/source/functions.std.cpp new file mode 100644 index 0000000..e728c7e --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/functions.std.cpp @@ -0,0 +1,236 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include + +void test_free_func(std::function f) { + f(); +} + +void test_free_func2(std::function f, int arg1) { + int val = f(arg1); + REQUIRE(val == arg1); +} + +std::function makefn() { + auto fx = []() -> int { return 0x1456789; }; + return fx; +} + +void takefn(std::function purr) { + if (purr() != 0x1456789) + throw 0; +} + +TEST_CASE("functions/empty std functions", "std::function is allowed to be empty, so it should be serialized to nil") { + sol::state lua; + lua.open_libraries(sol::lib::base); + std::function foo = nullptr; + sol::function bar; + + lua["Foo"] = foo; + lua["Bar"] = bar; + + sol::optional result = lua.safe_script(R"SCR( + if Bar ~= nil + then + Bar() + end + + if Foo ~= nil or type(Foo) == 'function' + then + Foo() + end + )SCR", + sol::script_pass_on_error); + REQUIRE_FALSE(result.has_value()); + + sol::optional result0 = lua.safe_script(R"SCR(Foo())SCR", sol::script_pass_on_error); + REQUIRE(result0.has_value()); + sol::optional result1 = lua.safe_script(R"SCR(Bar())SCR", sol::script_pass_on_error); + REQUIRE(result1.has_value()); +} + +TEST_CASE("functions/sol::function to std::function", "check if conversion to std::function works properly and calls with correct arguments") { + sol::state lua; + sol::stack_guard luasg(lua); + + lua.open_libraries(sol::lib::base); + + lua.set_function("testFunc", test_free_func); + lua.set_function("testFunc2", test_free_func2); + auto result1 = lua.safe_script("testFunc(function() print(\"hello std::function\") end)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + { + auto result = lua.safe_script( + "function m(a)\n" + " print(\"hello std::function with arg \", a)\n" + " return a\n" + "end\n" + "\n" + "testFunc2(m, 1)", + sol::script_pass_on_error); + REQUIRE(result.valid()); + } +} + +TEST_CASE("functions/returning functions from C++", "check to see if returning a functor and getting a functor from lua is possible") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.set_function("makefn", makefn); + lua.set_function("takefn", takefn); + { + auto result = lua.safe_script( + "afx = makefn()\n" + "print(afx())\n" + "takefn(afx)\n", + sol::script_pass_on_error); + REQUIRE(result.valid()); + } +} + +TEST_CASE("functions/set_function already wrapped", "setting a function returned from Lua code that is already wrapped into a sol::function or similar") { + SECTION("test different types") { + sol::state lua; + lua.open_libraries(sol::lib::base); + sol::function fn = lua.safe_script("return function() return 5 end"); + sol::protected_function pfn = fn; + std::function sfn = fn; + + lua.set_function("test", fn); + lua.set_function("test2", pfn); + lua.set_function("test3", sfn); + + { + auto result = lua.safe_script("assert(type(test) == 'function')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(test() ~= nil)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(test() == 5)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + + { + auto result = lua.safe_script("assert(type(test2) == 'function')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(test2() ~= nil)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(test2() == 5)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + + { + auto result = lua.safe_script("assert(type(test3) == 'function')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(test3() ~= nil)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(test3() == 5)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + } + + SECTION("getting the value from C++") { + sol::state lua; + lua.open_libraries(sol::lib::base); + sol::function fn = lua.safe_script("return function() return 5 end"); + + int result = fn(); + REQUIRE(result == 5); + } + + SECTION("setting the function directly") { + sol::state lua; + lua.open_libraries(sol::lib::base); + sol::function fn = lua.safe_script("return function() return 5 end"); + + lua.set_function("test", fn); + + { + auto result = lua.safe_script("assert(type(test) == 'function')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(test() ~= nil)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(test() == 5)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + } + + SECTION("does the function actually get executed?") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + sol::function fn2 = lua.safe_script("return function() print('this was executed') end"); + lua.set_function("test", fn2); + + { + auto result = lua.safe_script("assert(type(test) == 'function')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("test()", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + } + + SECTION("setting the function indirectly, with the return value cast explicitly") { + sol::state lua; + lua.open_libraries(sol::lib::base); + sol::function fn = lua.safe_script("return function() return 5 end"); + + lua.set_function("test", [&fn]() { return fn.call(); }); + + { + auto result = lua.safe_script("assert(type(test) == 'function')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(test() ~= nil)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(test() == 5)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + } +} diff --git a/lib/sol2/tests/runtime_tests/source/gc.cpp b/lib/sol2/tests/runtime_tests/source/gc.cpp new file mode 100644 index 0000000..f5cda70 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/gc.cpp @@ -0,0 +1,623 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include +#include +#include +#include +#include + +TEST_CASE("gc/destructors", "test if destructors are fired properly through gc of unbound usertypes") { + struct test; + static std::vector tests_destroyed; + struct test { + int v = 10; + ~test() { + tests_destroyed.push_back(this); + } + }; + test t; + test* pt = nullptr; + { + sol::state lua; + + lua["t"] = test{}; + pt = lua["t"]; + } + + REQUIRE(tests_destroyed.size() == 2); + REQUIRE(tests_destroyed.back() == pt); + + { + sol::state lua; + + lua["t"] = &t; + pt = lua["t"]; + } + + REQUIRE(tests_destroyed.size() == 2); + REQUIRE(&t == pt); + + { + sol::state lua; + + lua["t"] = std::ref(t); + pt = lua["t"]; + } + + REQUIRE(tests_destroyed.size() == 2); + REQUIRE(&t == pt); + + { + sol::state lua; + + lua["t"] = t; + pt = lua["t"]; + } + + REQUIRE(tests_destroyed.size() == 3); + REQUIRE(&t != pt); + REQUIRE(nullptr != pt); +} + +TEST_CASE("gc/virtual destructors", "ensure types with virtual destructions behave just fine") { + class B; + class A; + static std::vector bs; + static std::vector as; + + class A { + public: + virtual ~A() { + as.push_back(this); + std::cout << "~A" << std::endl; + } + }; + + class B : public A { + public: + virtual ~B() { + bs.push_back(this); + std::cout << "~B" << std::endl; + } + }; + + { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("A"); + lua.new_usertype("B", sol::base_classes, sol::bases()); + + B b1; + lua["b1"] = b1; // breaks here + } + + REQUIRE(as.size() == 2); + REQUIRE(bs.size() == 2); +} + +TEST_CASE("gc/function argument storage", "ensure functions take references on their types, not ownership, when specified") { + class gc_entity; + static std::vector entities; + + class gc_entity { + public: + ~gc_entity() { + entities.push_back(this); + } + }; + SECTION("plain") { + entities.clear(); + + sol::state lua; + lua.open_libraries(); + sol::function f = lua.safe_script(R"( +return function(e) +end +)"); + gc_entity* target = nullptr; + { + gc_entity e; + target = &e; + { + f(e); + lua.collect_garbage(); + } + { + f(&e); + lua.collect_garbage(); + } + { + f(std::ref(e)); + lua.collect_garbage(); + } + } + REQUIRE(entities.size() == 1); + REQUIRE(entities.back() == target); + } + SECTION("regular") { + entities.clear(); + + sol::state lua; + lua.open_libraries(); + lua.new_usertype("entity"); + sol::function f = lua.safe_script(R"( +return function(e) +end +)"); + gc_entity* target = nullptr; + { + gc_entity e; + target = &e; + { + f(e); // same with std::ref(e)! + lua.collect_garbage(); // destroys e for some reason + } + { + f(&e); // same with std::ref(e)! + lua.collect_garbage(); // destroys e for some reason + } + { + f(std::ref(e)); // same with std::ref(e)! + lua.collect_garbage(); // destroys e for some reason + } + } + REQUIRE(entities.size() == 1); + REQUIRE(entities.back() == target); + } +} + +TEST_CASE("gc/function storage", "show that proper copies / destruction happens for function storage (or not)") { + static int created = 0; + static int destroyed = 0; + static void* last_call = nullptr; + static void* static_call = reinterpret_cast(0x01); + typedef void (*fptr)(); + struct x { + x() { + ++created; + } + x(const x&) { + ++created; + } + x(x&&) { + ++created; + } + x& operator=(const x&) { + return *this; + } + x& operator=(x&&) { + return *this; + } + void func() { + last_call = static_cast(this); + }; + ~x() { + ++destroyed; + } + }; + struct y { + y() { + ++created; + } + y(const x&) { + ++created; + } + y(x&&) { + ++created; + } + y& operator=(const x&) { + return *this; + } + y& operator=(x&&) { + return *this; + } + static void func() { + last_call = static_call; + }; + void operator()() { + func(); + } + operator fptr() { + return func; + } + ~y() { + ++destroyed; + } + }; + + // stateful functors/member functions should always copy unless specified + { + created = 0; + destroyed = 0; + last_call = nullptr; + { + sol::state lua; + x x1; + lua.set_function("x1copy", &x::func, x1); + auto result1 = lua.safe_script("x1copy()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + REQUIRE(created == 2); + REQUIRE(destroyed == 0); + REQUIRE_FALSE(last_call == &x1); + + lua.set_function("x1ref", &x::func, std::ref(x1)); + auto result2 = lua.safe_script("x1ref()", sol::script_pass_on_error); + REQUIRE(result2.valid()); + REQUIRE(created == 2); + REQUIRE(destroyed == 0); + REQUIRE(last_call == &x1); + } + REQUIRE(created == 2); + REQUIRE(destroyed == 2); + } + + // things convertible to a static function should _never_ be forced to make copies + // therefore, pass through untouched + { + created = 0; + destroyed = 0; + last_call = nullptr; + { + sol::state lua; + y y1; + lua.set_function("y1copy", y1); + auto result1 = lua.safe_script("y1copy()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + REQUIRE(created == 1); + REQUIRE(destroyed == 0); + REQUIRE(last_call == static_call); + + last_call = nullptr; + lua.set_function("y1ref", std::ref(y1)); + auto result2 = lua.safe_script("y1ref()", sol::script_pass_on_error); + REQUIRE(result2.valid()); + REQUIRE(created == 1); + REQUIRE(destroyed == 0); + REQUIRE(last_call == static_call); + } + REQUIRE(created == 1); + REQUIRE(destroyed == 1); + } +} + +TEST_CASE("gc/same type closures", "make sure destructions are per-object, not per-type, by destroying one type multiple times") { + static std::set last_my_closures; + static bool checking_closures = false; + static bool check_failed = false; + + struct my_closure { + int& n; + + my_closure(int& n) + : n(n) { + } + ~my_closure() noexcept(false) { + if (!checking_closures) + return; + void* addr = static_cast(this); + auto f = last_my_closures.find(addr); + if (f != last_my_closures.cend()) { + check_failed = true; + } + last_my_closures.insert(f, addr); + } + + int operator()() { + ++n; + return n; + } + }; + + int n = 250; + my_closure a(n); + my_closure b(n); + { + sol::state lua; + + lua.set_function("f", a); + lua.set_function("g", b); + checking_closures = true; + } + REQUIRE_FALSE(check_failed); + REQUIRE(last_my_closures.size() == 2); +} + +TEST_CASE("gc/usertypes", "show that proper copies / destruction happens for usertypes") { + static int created = 0; + static int destroyed = 0; + struct x { + x() { + ++created; + } + x(const x&) { + ++created; + } + x(x&&) { + ++created; + } + x& operator=(const x&) { + return *this; + } + x& operator=(x&&) { + return *this; + } + ~x() { + ++destroyed; + } + }; + SECTION("plain") { + created = 0; + destroyed = 0; + { + sol::state lua; + x x1; + x x2; + lua.set("x1copy", x1, "x2copy", x2, "x1ref", std::ref(x1)); + x& x1copyref = lua["x1copy"]; + x& x2copyref = lua["x2copy"]; + x& x1ref = lua["x1ref"]; + REQUIRE(created == 4); + REQUIRE(destroyed == 0); + REQUIRE(std::addressof(x1) == std::addressof(x1ref)); + REQUIRE(std::addressof(x1copyref) != std::addressof(x1)); + REQUIRE(std::addressof(x2copyref) != std::addressof(x2)); + } + REQUIRE(created == 4); + REQUIRE(destroyed == 4); + } + SECTION("regular") { + created = 0; + destroyed = 0; + { + sol::state lua; + lua.new_usertype("x"); + x x1; + x x2; + lua.set("x1copy", x1, "x2copy", x2, "x1ref", std::ref(x1)); + x& x1copyref = lua["x1copy"]; + x& x2copyref = lua["x2copy"]; + x& x1ref = lua["x1ref"]; + REQUIRE(created == 4); + REQUIRE(destroyed == 0); + REQUIRE(std::addressof(x1) == std::addressof(x1ref)); + REQUIRE(std::addressof(x1copyref) != std::addressof(x1)); + REQUIRE(std::addressof(x2copyref) != std::addressof(x2)); + } + REQUIRE(created == 4); + REQUIRE(destroyed == 4); + } +} + +TEST_CASE("gc/double-deletion tests", "make sure usertypes are properly destructed and don't double-delete memory or segfault") { + class crash_class { + public: + crash_class() { + } + ~crash_class() { + a = 10; + } + + private: + int a; + }; + + sol::state lua; + + SECTION("regular") { + lua.new_usertype("CrashClass", + sol::call_constructor, sol::constructors>()); + + auto result1 = lua.safe_script(R"( + function testCrash() + local x = CrashClass() + end + )", sol::script_pass_on_error); + REQUIRE(result1.valid()); + + for (int i = 0; i < 1000; ++i) { + lua["testCrash"](); + } + } +} + +TEST_CASE("gc/shared_ptr regression", "metatables should not screw over unique usertype metatables") { + static int created = 0; + static int destroyed = 0; + struct test { + test() { + ++created; + } + + ~test() { + ++destroyed; + } + }; + + SECTION("regular") { + created = 0; + destroyed = 0; + { + std::list> tests; + sol::state lua; + lua.open_libraries(); + + lua.new_usertype("test", + "create", [&]() -> std::shared_ptr { + tests.push_back(std::make_shared()); + return tests.back(); + }); + REQUIRE(created == 0); + REQUIRE(destroyed == 0); + auto result1 = lua.safe_script("x = test.create()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + REQUIRE(created == 1); + REQUIRE(destroyed == 0); + REQUIRE_FALSE(tests.empty()); + std::shared_ptr& x = lua["x"]; + std::size_t xuse = x.use_count(); + std::size_t tuse = tests.back().use_count(); + REQUIRE(xuse == tuse); + } + REQUIRE(created == 1); + REQUIRE(destroyed == 1); + } +} + +TEST_CASE("gc/double deleter guards", "usertype metatables internally must not rely on C++ state") { + SECTION("regular") { + struct c_a { + int xv; + }; + struct c_b { + int yv; + }; + auto routine = []() { + sol::state lua; + lua.new_usertype("c_a", "x", &c_a::xv); + lua.new_usertype("c_b", "y", &c_b::yv); + lua = sol::state(); + lua.new_usertype("c_a", "x", &c_a::xv); + lua.new_usertype("c_b", "y", &c_b::yv); + lua = sol::state(); + }; + REQUIRE_NOTHROW(routine()); + } +} + +TEST_CASE("gc/alignment", "test that allocation is always on aligned boundaries, no matter the wrapper / type") { + struct test { + std::function callback = []() { std::cout << "Hello world!" << std::endl; }; + + void check_alignment() { + std::uintptr_t p = reinterpret_cast(this); + std::uintptr_t offset = p % std::alignment_of::value; + REQUIRE(offset == 0); + } + }; + + sol::state lua; + lua.new_usertype("test", + "callback", &test::callback); + + test obj{}; + lua["obj"] = &obj; + INFO("obj"); + { + auto r = lua.safe_script("obj.callback()", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + // Do not check for stack-created object + //test& lobj = lua["obj"]; + //lobj.check_alignment(); + } + + lua["obj0"] = std::ref(obj); + INFO("obj0"); + { + auto r = lua.safe_script("obj0.callback()", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + // Do not check for stack-created object + //test& lobj = lua["obj0"]; + //lobj.check_alignment(); + } + + lua["obj1"] = obj; + INFO("obj1"); + { + auto r = lua.safe_script("obj1.callback()", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + test& lobj = lua["obj1"]; + lobj.check_alignment(); + } + + lua["obj2"] = test{}; + INFO("obj2"); + { + auto r = lua.safe_script("obj2.callback()", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + test& lobj = lua["obj2"]; + lobj.check_alignment(); + } + + lua["obj3"] = std::make_unique(); + INFO("obj3"); + { + auto r = lua.safe_script("obj3.callback()", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + test& lobj = lua["obj3"]; + lobj.check_alignment(); + } + + lua["obj4"] = std::make_shared(); + INFO("obj4"); + { + auto r = lua.safe_script("obj4.callback()", sol::script_pass_on_error); + REQUIRE(r.valid()); + } + { + test& lobj = lua["obj4"]; + lobj.check_alignment(); + } +} + +TEST_CASE("gc/multi-argument destructors", "make sure transparent arguments come along for the ride") { + static int transparent_foos_destroyed = 0; + + struct transparent_foo { + ~transparent_foo() { + ++transparent_foos_destroyed; + } + }; + + lua_State* lua_state = nullptr; + lua_State* call_state = nullptr; + auto call_des = [&call_state](transparent_foo* f, sol::this_state s) { + call_state = s; + return f->~transparent_foo(); + }; + { + sol::state lua; + lua_state = lua; + lua.new_usertype("foo", sol::meta_function::garbage_collect, sol::destructor(std::move(call_des))); + + lua.script("foo.new()"); + } + REQUIRE(transparent_foos_destroyed == 1); + REQUIRE(call_state == lua_state); +} diff --git a/lib/sol2/tests/runtime_tests/source/large_integer.cpp b/lib/sol2/tests/runtime_tests/source/large_integer.cpp new file mode 100644 index 0000000..d5d08c7 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/large_integer.cpp @@ -0,0 +1,156 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include + +TEST_CASE("large_integer/bool", "pass bool integral value to and from lua") { + sol::state lua; + lua.open_libraries(); + lua.set_function("f", [&](bool num) { + REQUIRE(num == true); + return num; + }); + auto result1 = lua.safe_script("x = f(true)\n" + "assert(x == true)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::object x = lua["x"]; + REQUIRE(x.is()); + REQUIRE(x.as() == true); + REQUIRE_FALSE(x.is()); + { + auto result = lua.safe_script("f(1)", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } +} + +TEST_CASE("large_integers/unsigned32", "pass large unsigned 32bit values to and from lua") { + using T = std::uint32_t; + sol::state lua; + lua.open_libraries(); + lua.set_function("f", [&](T num) -> T { + REQUIRE(num == 0xFFFFFFFF); + return num; + }); + auto result1 = lua.safe_script("x = f(0xFFFFFFFF)\n" + "assert(x == 0xFFFFFFFF)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + sol::object x = lua["x"]; + REQUIRE(x.is()); + REQUIRE(x.as() == 0xFFFFFFFF); +} + +TEST_CASE("large_integer/unsigned53", "pass large unsigned 53bit value to and from lua") { + using T = std::uint64_t; + sol::state lua; + lua.open_libraries(); + lua.set_function("f", [&](T num) -> T { + REQUIRE(num == 0x1FFFFFFFFFFFFFull); + return num; + }); + auto result1 = lua.safe_script("x = f(0x1FFFFFFFFFFFFF)\n" + "assert(x == 0x1FFFFFFFFFFFFF)"); + REQUIRE(result1.valid()); + sol::object x = lua["x"]; + REQUIRE(x.is()); + REQUIRE(x.as() == 0x1FFFFFFFFFFFFFull); +} + +TEST_CASE("large_integer/unsigned64", "pass too large unsigned 64bit value to lua") { + using T = std::int64_t; + sol::state lua; + lua.set_function("f", [&](T num) -> T { + return num; + }); + REQUIRE_THROWS([&lua]() { + sol::protected_function pf = lua["f"]; + auto result = pf(0xFFFFFFFFFFFFFFFFull); + }()); +} + +TEST_CASE("large_integer/double", "pass negative and large positive values as signed and unsigned from and to lua") { + sol::state lua; + lua.open_libraries(); + lua.set_function("s32", [&](std::int32_t num) { + return num; + }); + lua.set_function("s64", [&](std::int64_t num) { + return num; + }); + lua.set_function("u32", [&](std::uint32_t num) { + return num; + }); + lua.set_function("u64", [&](std::uint64_t num) { + return num; + }); + { + //signed 32bit + auto result1 = lua.safe_script("x = s32(-1)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("assert(x == -1)", sol::script_pass_on_error); + REQUIRE(result2.valid()); + auto result3 = lua.safe_script("x = s32(0xFFFFFFFF)", sol::script_pass_on_error); + REQUIRE(result3.valid()); + auto result4 = lua.safe_script("assert(x == -1)", sol::script_pass_on_error); + REQUIRE(result4.valid()); + + sol::object x = lua["x"]; + REQUIRE(x.is()); + REQUIRE(x.as() == -1); + REQUIRE(x.is()); + REQUIRE(x.as() == 0xFFFFFFFF); + } + + //unsigned 32bit + { + auto result1 = lua.safe_script("x = u32(0xFFFFFFFF)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("assert(x == 0xFFFFFFFF)", sol::script_pass_on_error); + REQUIRE(result2.valid()); + auto result3 = lua.safe_script("x = u32(-1)", sol::script_pass_on_error); + REQUIRE(result3.valid()); + auto result4 = lua.safe_script("assert(x == 0xFFFFFFFF)", sol::script_pass_on_error); + REQUIRE(result4.valid()); + sol::object x = lua["x"]; + REQUIRE(x.is()); + REQUIRE(x.as() == -1); + REQUIRE(x.is()); + REQUIRE(x.as() == 0xFFFFFFFF); + } + //signed 64bit + { + auto result1 = lua.safe_script("x = s64(-1)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("assert(x == -1)", sol::script_pass_on_error); + REQUIRE(result2.valid()); + sol::object x = lua["x"]; + REQUIRE(x.is()); + REQUIRE(x.as() == -1); + REQUIRE(x.is()); + REQUIRE(x.as() == 0xFFFFFFFFFFFFFFFFull); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/lua_value.cpp b/lib/sol2/tests/runtime_tests/source/lua_value.cpp new file mode 100644 index 0000000..5e3126f --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/lua_value.cpp @@ -0,0 +1,401 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include +#include +#include +#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES +#include +#include +#endif // C++17 + +struct int_entry { + int value; + + int_entry() : value(0) { + } + + int_entry(int v) : value(v) { + } + + bool operator==(const int_entry& e) const { + return value == e.value; + } +}; + +std::mutex lua_value_construct_require_mutex; + +void lua_value_construct_race() { + sol::state lua; + try { + lua.open_libraries(); + lua["a"] = sol::lua_value(lua, 24); + int a = lua["a"]; + { + std::lock_guard lg(lua_value_construct_require_mutex); + REQUIRE(a == 24); + } + } + catch (const sol::error& e) { + std::lock_guard lg(lua_value_construct_require_mutex); + INFO(e.what()); + REQUIRE(false); + } + catch (...) { + std::lock_guard lg(lua_value_construct_require_mutex); + REQUIRE(false); + } +} + +TEST_CASE("lua_value/nested", "make nested values can be put in lua_value properly") { +#if defined(SOL_STD_VARIANT) && SOL_STD_VARIANT + using mixed_table_entry = std::variant; + using nested_entry = std::variant>; + + const std::vector> mixed_table_truth = { 1, int_entry(2), 3, int_entry(4), 5 }; + const std::vector mixed_nested_table_truth = { 1, int_entry(2), 3, int_entry(4), std::vector{ 5, 6, int_entry(7), "8" } }; + + sol::state lua; + + sol::lua_value lv_mixed_table(lua, sol::array_value{ 1, int_entry(2), 3, int_entry(4), 5 }); + sol::lua_value lv_mixed_nested_table(lua, sol::array_value{ 1, int_entry(2), 3, int_entry(4), sol::array_value{ 5, 6, int_entry(7), "8" } }); + + REQUIRE(lv_mixed_table.is()); + REQUIRE(lv_mixed_nested_table.is()); + + std::vector> mixed_table_value_lv = lv_mixed_table.as>>(); + std::vector mixed_nested_table_value_lv = lv_mixed_nested_table.as>(); + + REQUIRE(mixed_table_truth == mixed_table_value_lv); + REQUIRE(mixed_nested_table_truth == mixed_nested_table_value_lv); + + SECTION("type check (object)") { + sol::object obj_mixed_table(lv_mixed_table.value()); + sol::object obj_mixed_nested_table(lv_mixed_nested_table.value()); + + REQUIRE(obj_mixed_table.is()); + REQUIRE(obj_mixed_nested_table.is()); + + std::vector> mixed_table_value = obj_mixed_table.as>>(); + std::vector mixed_nested_table_value = obj_mixed_nested_table.as>(); + + REQUIRE(mixed_table_truth == mixed_table_value); + REQUIRE(mixed_nested_table_truth == mixed_nested_table_value); + } + SECTION("pushing/popping") { + lua["obj_mixed_table"] = lv_mixed_table; + lua["obj_mixed_nested_table"] = lv_mixed_nested_table; + + sol::lua_value obj_mixed_table = lua["obj_mixed_table"]; + sol::lua_value obj_mixed_nested_table = lua["obj_mixed_nested_table"]; + + REQUIRE(obj_mixed_table.is()); + REQUIRE(obj_mixed_nested_table.is()); + + std::vector> mixed_table_value = obj_mixed_table.as>>(); + std::vector mixed_nested_table_value = obj_mixed_nested_table.as>(); + + REQUIRE(mixed_table_truth == mixed_table_value); + REQUIRE(mixed_nested_table_truth == mixed_nested_table_value); + } + SECTION("pushing/popping (object)") { + lua["obj_mixed_table"] = lv_mixed_table; + lua["obj_mixed_nested_table"] = lv_mixed_nested_table; + + sol::object obj_mixed_table = lua["obj_mixed_table"]; + sol::object obj_mixed_nested_table = lua["obj_mixed_nested_table"]; + + REQUIRE(obj_mixed_table.is()); + REQUIRE(obj_mixed_nested_table.is()); + + std::vector> mixed_table_value = obj_mixed_table.as>>(); + std::vector mixed_nested_table_value = obj_mixed_nested_table.as>(); + + REQUIRE(mixed_table_truth == mixed_table_value); + REQUIRE(mixed_nested_table_truth == mixed_nested_table_value); + } +#else + REQUIRE(true); +#endif // C++17 +} + +TEST_CASE("lua_value/nested key value", "make nested values (key value) can be put in lua_value properly") { +#if defined(SOL_STD_VARIANT) && SOL_STD_VARIANT + using mixed_table_entry = std::variant; + using nested_entry = std::variant>; + + const std::vector> mixed_table_truth = { 1, int_entry(2), 3, int_entry(4), 5 }; + const std::vector mixed_nested_table_truth = { 1, int_entry(2), 3, int_entry(4), std::vector{ 5, 6, int_entry(7), "8" } }; + + sol::state lua; + + sol::lua_value lv_mixed_table(lua, sol::array_value{ 1, int_entry(2), 3, int_entry(4), 5 }); + sol::lua_value lv_mixed_nested_table(lua, sol::array_value{ 1, int_entry(2), 3, int_entry(4), sol::array_value{ 5, 6, int_entry(7), "8" } }); + + REQUIRE(lv_mixed_table.is()); + REQUIRE(lv_mixed_nested_table.is()); + + std::vector> mixed_table_value_lv = lv_mixed_table.as>>(); + std::vector mixed_nested_table_value_lv = lv_mixed_nested_table.as>(); + + REQUIRE(mixed_table_truth == mixed_table_value_lv); + REQUIRE(mixed_nested_table_truth == mixed_nested_table_value_lv); + + SECTION("type check (object)") { + sol::object obj_mixed_table(lv_mixed_table.value()); + sol::object obj_mixed_nested_table(lv_mixed_nested_table.value()); + + REQUIRE(obj_mixed_table.is()); + REQUIRE(obj_mixed_nested_table.is()); + + std::vector> mixed_table_value = obj_mixed_table.as>>(); + std::vector mixed_nested_table_value = obj_mixed_nested_table.as>(); + + REQUIRE(mixed_table_truth == mixed_table_value); + REQUIRE(mixed_nested_table_truth == mixed_nested_table_value); + } + SECTION("pushing/popping") { + lua["obj_mixed_table"] = lv_mixed_table; + lua["obj_mixed_nested_table"] = lv_mixed_nested_table; + + sol::lua_value obj_mixed_table = lua["obj_mixed_table"]; + sol::lua_value obj_mixed_nested_table = lua["obj_mixed_nested_table"]; + + REQUIRE(obj_mixed_table.is()); + REQUIRE(obj_mixed_nested_table.is()); + + std::vector> mixed_table_value = obj_mixed_table.as>>(); + std::vector mixed_nested_table_value = obj_mixed_nested_table.as>(); + + REQUIRE(mixed_table_truth == mixed_table_value); + REQUIRE(mixed_nested_table_truth == mixed_nested_table_value); + } + SECTION("pushing/popping (object)") { + lua["obj_mixed_table"] = lv_mixed_table; + lua["obj_mixed_nested_table"] = lv_mixed_nested_table; + + sol::object obj_mixed_table = lua["obj_mixed_table"]; + sol::object obj_mixed_nested_table = lua["obj_mixed_nested_table"]; + + REQUIRE(obj_mixed_table.is()); + REQUIRE(obj_mixed_nested_table.is()); + + std::vector> mixed_table_value = obj_mixed_table.as>>(); + std::vector mixed_nested_table_value = obj_mixed_nested_table.as>(); + + REQUIRE(mixed_table_truth == mixed_table_value); + REQUIRE(mixed_nested_table_truth == mixed_nested_table_value); + } +#else + REQUIRE(true); +#endif // C++17 +} + +TEST_CASE("lua_value/basic types", "make sure we can stick values and nested values in a lua_value and retrieve them") { + sol::state lua; + + const int_entry userdata_truth = int_entry(3); + const std::vector int_table_truth = { 1, 2, 3, 4, 5 }; + const std::map int_map_truth = { {1, 2}, {3, 4}, {5, 6} }; + + sol::lua_value lv_int(lua, 1); + sol::lua_value lv_double(lua, 2.0); + sol::lua_value lv_string(lua, "heyo"); + sol::lua_value lv_lstring(lua, L"hiyo"); + sol::lua_value lv_bool(lua, true); + sol::lua_value lv_nil(lua, sol::lua_nil); + sol::lua_value lv_userdata(lua, int_entry(3)); + sol::lua_value lv_int_table(lua, { 1, 2, 3, 4, 5 }); + sol::lua_value lv_int_map(lua, { {1, 2}, {3, 4}, {5, 6} }); + REQUIRE(lv_int.is()); + REQUIRE(lv_double.is()); + REQUIRE(lv_string.is()); + REQUIRE(lv_lstring.is()); + REQUIRE(lv_bool.is()); + REQUIRE(lv_nil.is()); + REQUIRE(lv_userdata.is()); + REQUIRE(lv_userdata.is()); + REQUIRE(lv_int_table.is()); + REQUIRE(lv_int_map.is()); + + REQUIRE(lv_int.as() == 1); + REQUIRE(lv_double.as() == 2.0); + REQUIRE(lv_string.as() == "heyo"); + REQUIRE(lv_lstring.as() == "hiyo"); + REQUIRE(lv_lstring.as() == L"hiyo"); + REQUIRE(lv_bool.as()); + REQUIRE(lv_nil.as() == sol::lua_nil); + REQUIRE(lv_userdata.as() == userdata_truth); + + std::vector int_table_value_lv = lv_int_table.as>(); + REQUIRE(int_table_truth == int_table_value_lv); + std::map int_map_value_lv = lv_int_map.as>(); + REQUIRE(int_map_truth == int_map_value_lv); + + SECTION("type check (object)") { + sol::object obj_int(lv_int.value()); + sol::object obj_double(lv_double.value()); + sol::object obj_string(lv_string.value()); + sol::object obj_lstring(lv_lstring.value()); + sol::object obj_bool(lv_bool.value()); + sol::object obj_nil(lv_nil.value()); + sol::object obj_userdata(lv_userdata.value()); + sol::object obj_int_table(lv_int_table.value()); + sol::object obj_int_map(lv_int_map.value()); + + REQUIRE(obj_int.is()); + REQUIRE(obj_double.is()); + REQUIRE(obj_string.is()); + REQUIRE(obj_lstring.is()); + REQUIRE(obj_bool.is()); + REQUIRE(obj_nil.is()); + REQUIRE(obj_userdata.is()); + REQUIRE(obj_userdata.is()); + REQUIRE(obj_int_table.is()); + REQUIRE(obj_int_map.is()); + + REQUIRE(obj_int.as() == 1); + REQUIRE(obj_double.as() == 2.0); + REQUIRE(obj_string.as() == "heyo"); + REQUIRE(obj_lstring.as() == "hiyo"); + REQUIRE(obj_lstring.as() == L"hiyo"); + REQUIRE(obj_bool.as()); + REQUIRE(obj_userdata.as() == userdata_truth); + REQUIRE(obj_nil.as() == sol::lua_nil); + + std::vector int_table_value = obj_int_table.as>(); + REQUIRE(int_table_truth == int_table_value); + std::map int_map_value = obj_int_map.as>(); + REQUIRE(int_map_truth == int_map_value); + } + SECTION("push/popping") { + lua["obj_int"] = lv_int; + lua["obj_double"] = lv_double; + lua["obj_string"] = lv_string; + lua["obj_lstring"] = lv_lstring; + lua["obj_bool"] = lv_bool; + lua["obj_nil"] = lv_nil; + lua["obj_userdata"] = lv_userdata; + lua["obj_int_table"] = lv_int_table; + lua["obj_int_map"] = lv_int_map; + + // these all actually invoke the constructor + // so do one .get<> explicitly to ensure it's + // working correctl for a few cases... + // but it's nice to make sure it's all there now + sol::lua_value obj_int = lua["obj_int"].get(); + sol::lua_value obj_double = lua["obj_double"].get(); + sol::lua_value obj_string = lua["obj_string"].get(); + sol::lua_value obj_lstring = lua["obj_lstring"].get(); + sol::lua_value obj_bool = lua["obj_bool"].get(); + sol::lua_value obj_nil = lua["obj_nil"]; + sol::lua_value obj_userdata = lua["obj_userdata"]; + sol::lua_value obj_int_table = lua["obj_int_table"]; + sol::lua_value obj_int_map = lua["obj_int_map"]; + + REQUIRE(obj_int.is()); + REQUIRE(obj_double.is()); + REQUIRE(obj_string.is()); + REQUIRE(obj_lstring.is()); + REQUIRE(obj_bool.is()); + REQUIRE(obj_nil.is()); + REQUIRE(obj_int_table.is()); + REQUIRE(obj_int_map.is()); + + REQUIRE(obj_int.as() == 1); + REQUIRE(obj_double.as() == 2.0); + REQUIRE(obj_string.as() == "heyo"); + REQUIRE(obj_lstring.as() == "hiyo"); + REQUIRE(obj_lstring.as() == L"hiyo"); + REQUIRE(obj_bool.as()); + REQUIRE(obj_nil.as() == sol::lua_nil); + + std::vector int_table_value = obj_int_table.as>(); + REQUIRE(int_table_truth == int_table_value); + std::map int_map_value = obj_int_map.as>(); + REQUIRE(int_map_truth == int_map_value); + } + SECTION("push/popping (object)") { + lua["obj_int"] = lv_int; + lua["obj_double"] = lv_double; + lua["obj_string"] = lv_string; + lua["obj_lstring"] = lv_lstring; + lua["obj_bool"] = lv_bool; + lua["obj_nil"] = lv_nil; + lua["obj_userdata"] = lv_userdata; + lua["obj_int_table"] = lv_int_table; + lua["obj_int_map"] = lv_int_map; + + sol::object obj_int = lua["obj_int"]; + sol::object obj_double = lua["obj_double"]; + sol::object obj_string = lua["obj_string"]; + sol::object obj_lstring = lua["obj_lstring"]; + sol::object obj_bool = lua["obj_bool"]; + sol::object obj_nil = lua["obj_nil"]; + sol::object obj_userdata = lua["obj_userdata"]; + sol::object obj_int_table = lua["obj_int_table"]; + sol::object obj_int_map = lua["obj_int_map"]; + + REQUIRE(obj_int.is()); + REQUIRE(obj_double.is()); + REQUIRE(obj_string.is()); + REQUIRE(obj_lstring.is()); + REQUIRE(obj_bool.is()); + REQUIRE(obj_nil.is()); + REQUIRE(obj_userdata.is()); + REQUIRE(obj_userdata.is()); + REQUIRE(obj_int_table.is()); + + REQUIRE(obj_int.as() == 1); + REQUIRE(obj_double.as() == 2.0); + REQUIRE(obj_string.as() == "heyo"); + REQUIRE(obj_lstring.as() == "hiyo"); + REQUIRE(obj_lstring.as() == L"hiyo"); + REQUIRE(obj_bool.as()); + REQUIRE(obj_nil.as() == sol::lua_nil); + REQUIRE(obj_userdata.as() == userdata_truth); + + std::vector int_table_value = obj_int_table.as>(); + REQUIRE(int_table_truth == int_table_value); + std::map int_map_value = obj_int_map.as>(); + REQUIRE(int_map_truth == int_map_value); + } +} + +TEST_CASE("lua_value/threading", "test that thread_local in lua_value constructors do not race or clobber") { + REQUIRE_NOTHROW([]() { + std::thread thrds[24]; + for (int i = 0; i < 24; i++) { + thrds[i] = std::thread(&lua_value_construct_race); + } + + for (int i = 0; i < 24; i++) { + thrds[i].join(); + } + }()); +} diff --git a/lib/sol2/tests/runtime_tests/source/main.cpp b/lib/sol2/tests/runtime_tests/source/main.cpp new file mode 100644 index 0000000..52d33f2 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/main.cpp @@ -0,0 +1,7 @@ +#define CATCH_CONFIG_RUNNER +#include + +int main(int argc, char* argv[]) { + int result = Catch::Session().run(argc, argv); + return result; +} diff --git a/lib/sol2/tests/runtime_tests/source/operators.cpp b/lib/sol2/tests/runtime_tests/source/operators.cpp new file mode 100644 index 0000000..e70e069 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/operators.cpp @@ -0,0 +1,463 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include +#include + +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) { + return a == r.a; + } + }; + struct V { + int a; + V(int x = 20) : a(x) { + } + bool operator==(const V& r) const { + return a == r.a; + } + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + + T t1; + T& t2 = t1; + T t3; + U u1; + U u2{ 30 }; + U u3; + V v1; + V v2{ 30 }; + V v3; + lua["t1"] = &t1; + lua["t2"] = &t2; + lua["t3"] = &t3; + lua["u1"] = &u1; + lua["u2"] = &u2; + lua["u3"] = &u3; + lua["v1"] = &v1; + lua["v2"] = &v2; + lua["v3"] = &v3; + + SECTION("plain") { + // Can only compare identity here + { + auto result1 = lua.safe_script( + "assert(t1 == t1)" + "assert(t2 == t2)" + "assert(t3 == t3)", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + } + { + auto result1 = lua.safe_script( + "assert(t1 == t2)" + "assert(not (t1 == t3))" + "assert(not (t2 == t3))", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + } + // Object should compare equal to themselves + // (and not invoke operator==; pointer test should be sufficient) + { + auto result1 = lua.safe_script( + "assert(u1 == u1)" + "assert(u2 == u2)" + "assert(u3 == u3)", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + } + { + auto result1 = lua.safe_script( + "assert(not (u1 == u2))" + "assert(u1 == u3)" + "assert(not (u2 == u3))", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + } + // Object should compare equal to themselves + // (and not invoke operator==; pointer test should be sufficient) + { + auto result1 = lua.safe_script( + "assert(v1 == v1)" + "assert(v2 == v2)" + "assert(v3 == v3)", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + } + { + auto result1 = lua.safe_script( + "assert(not (v1 == v2))" + "assert(v1 == v3)" + "assert(not (v2 == v3))", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + } + } + SECTION("regular") { + lua.new_usertype("T"); + lua.new_usertype("U"); + lua.new_usertype("V"); + + // Can only compare identity here + { + auto result1 = lua.safe_script( + "assert(t1 == t1)" + "assert(t2 == t2)" + "assert(t3 == t3)", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + } + { + auto result1 = lua.safe_script( + "assert(t1 == t2)" + "assert(not (t1 == t3))" + "assert(not (t2 == t3))", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + } + // Object should compare equal to themselves + // (and not invoke operator==; pointer test should be sufficient) + { + auto result1 = lua.safe_script( + "assert(u1 == u1)" + "assert(u2 == u2)" + "assert(u3 == u3)", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + } + { + auto result1 = lua.safe_script( + "assert(not (u1 == u2))" + "assert(u1 == u3)" + "assert(not (u2 == u3))", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + } + // Object should compare equal to themselves + // (and not invoke operator==; pointer test should be sufficient) + { + auto result1 = lua.safe_script( + "assert(v1 == v1)" + "assert(v2 == v2)" + "assert(v3 == v3)", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + } + { + auto result1 = lua.safe_script( + "assert(not (v1 == v2))" + "assert(v1 == v3)" + "assert(not (v2 == v3))", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + } + } +} + +TEST_CASE("operators/default with pointers", "test that default operations still work when working with reference (pointer) types") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("T"); + + + T test; + + lua["t1"] = &test; + lua["t2"] = &test; + lua["t3"] = std::unique_ptr(&test); + lua["t4"] = std::unique_ptr(&test); + + lua.script("ptr_test = t1 == t2"); + lua.script("unique_test = t3 == t4"); + + bool ptr_test = lua["ptr_test"]; + bool unique_test = lua["unique_test"]; + REQUIRE(ptr_test); + REQUIRE(unique_test); + +#if SOL_LUA_VERSION > 502 + lua.script("ptr_unique_test = t1 == t3"); + + bool ptr_unique_test = lua["ptr_unique_test"]; + REQUIRE(ptr_unique_test); +#endif +} + +TEST_CASE("operators/call", "test call operator generation") { + struct callable { + int operator()(int a, std::string b) { + return a + static_cast(b.length()); + } + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + + SECTION("plain") { + { + lua.set("obj", callable()); + auto result1 = lua.safe_script("v = obj(2, 'bark woof')", sol::script_pass_on_error); + REQUIRE(result1.valid()); + int v = lua["v"]; + REQUIRE(v == 11); + } + } + SECTION("regular") { + lua.new_usertype("callable"); + { + auto result1 = lua.safe_script( + "obj = callable.new()\n" + "v = obj(2, 'bark woof')", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + int v = lua["v"]; + REQUIRE(v == 11); + } + } +} + +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(&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(&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(&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(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); + + SECTION("plain") { + { + lua["obj"] = stringable(); + auto result1 = lua.safe_script("print(obj)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + stringable& obj = lua["obj"]; + REQUIRE(stringable::last_print_ptr == &obj); + } + } + SECTION("regular") { + lua.new_usertype("stringable"); + { + auto result1 = lua.safe_script(R"(obj = stringable.new() + print(obj) )", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + stringable& obj = lua["obj"]; + REQUIRE(stringable::last_print_ptr == &obj); + } + } +} + +TEST_CASE("operators/adl_stringable", "test adl to_string stringability") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + SECTION("plain") { + { + lua["obj"] = adl_stringable(); + lua.safe_script("print(obj)"); + adl_stringable& obj = lua["obj"]; + REQUIRE(adl_stringable::last_print_ptr == &obj); + } + } + SECTION("regular") { + lua.new_usertype("stringable"); + { + lua["obj"] = adl_stringable(); + lua.safe_script("print(obj)"); + adl_stringable& obj = lua["obj"]; + REQUIRE(adl_stringable::last_print_ptr == &obj); + } + } +} + +TEST_CASE("operators/inside::adl_stringable2", "test adl to_string stringability from inside a namespace") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + SECTION("plain") { + { + lua["obj"] = inside::adl_stringable2(); + lua.safe_script("print(obj)"); + inside::adl_stringable2& obj = lua["obj"]; + REQUIRE(inside::adl_stringable2::last_print_ptr == &obj); + } + } + SECTION("regular") { + lua.new_usertype("stringable"); + { + lua.safe_script("obj = stringable.new()"); + lua.safe_script("print(obj)"); + inside::adl_stringable2& obj = lua["obj"]; + REQUIRE(inside::adl_stringable2::last_print_ptr == &obj); + } + } +} + +TEST_CASE("operators/member_stringable", "test member to_string stringability") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + SECTION("plain") { + { + lua["obj"] = member_stringable(); + lua.safe_script("print(obj)"); + member_stringable& obj = lua["obj"]; + REQUIRE(member_stringable::last_print_ptr == &obj); + } + } + SECTION("regular") { + lua.new_usertype("stringable"); + { + lua.safe_script("obj = stringable.new()"); + lua.safe_script("print(obj)"); + member_stringable& obj = lua["obj"]; + REQUIRE(member_stringable::last_print_ptr == &obj); + } + } +} + +TEST_CASE("operators/container-like", "test that generic begin/end and iterator are automatically bound") { +#if SOL_LUA_VERSION > 501 + struct container { + typedef int* iterator; + typedef int value_type; + + value_type values[10]; + + container() { + std::iota(begin(), end(), 1); + } + + iterator begin() { + return &values[0]; + } + + iterator end() { + return &values[0] + 10; + } + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + + SECTION("plain") { + { + lua["obj"] = container(); + lua.safe_script("i = 0 for k, v in pairs(obj) do i = i + 1 assert(k == v) end"); + std::size_t i = lua["i"]; + REQUIRE(i == 10); + } + } + SECTION("regular") { + lua.new_usertype("container"); + { + lua.safe_script("obj = container.new()"); + lua.safe_script("i = 0 for k, v in pairs(obj) do i = i + 1 assert(k == v) end"); + std::size_t i = lua["i"]; + REQUIRE(i == 10); + } + } +#else + SUCCEED(""); +#endif +} + +TEST_CASE("operators/length", "test that size is automatically bound to the length operator") { + struct sizable { + std::size_t size() const { + return 6; + } + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + + SECTION("plain") { + { + lua["obj"] = sizable(); + lua.safe_script("s = #obj"); + std::size_t s = lua["s"]; + REQUIRE(s == 6); + } + } + SECTION("regular") { + lua.new_usertype("sizable"); + { + lua.safe_script("obj = sizable.new()"); + lua.safe_script("s = #obj"); + std::size_t s = lua["s"]; + REQUIRE(s == 6); + } + } +} diff --git a/lib/sol2/tests/runtime_tests/source/overflow.cpp b/lib/sol2/tests/runtime_tests/source/overflow.cpp new file mode 100644 index 0000000..4418a2f --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/overflow.cpp @@ -0,0 +1,68 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +TEST_CASE("issues/stack overflow", "make sure various operations repeated don't trigger stack overflow") { + sol::state lua; + lua.safe_script("t = {};t[0]=20"); + lua.safe_script("lua_function=function(i)return i;end"); + + sol::function f = lua["lua_function"]; + std::string teststring = "testtext"; + REQUIRE_NOTHROW([&] { + for (int i = 0; i < 1000000; ++i) { + std::string result = f(teststring); + if (result != teststring) + throw std::logic_error("RIP"); + } + }()); + sol::table t = lua["t"]; + int expected = 20; + REQUIRE_NOTHROW([&] { + for (int i = 0; i < 1000000; ++i) { + int result = t[0]; + t.size(); + if (result != expected) + throw std::logic_error("RIP"); + } + }()); +} + +TEST_CASE("issues/stack overflow 2", "make sure basic iterators clean up properly when they're not iterated through (e.g., with empty())") { + sol::state lua; + sol::table t = lua.create_table_with(1, "wut"); + int MAX = 50000; + auto fx = [&]() { + int a = 50; + for (int i = 0; i < MAX; ++i) { + if (t.empty()) { + a += 4; + } + a += 2; + } + }; + REQUIRE_NOTHROW(fx()); +} diff --git a/lib/sol2/tests/runtime_tests/source/plain_types.cpp b/lib/sol2/tests/runtime_tests/source/plain_types.cpp new file mode 100644 index 0000000..4fb4aa2 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/plain_types.cpp @@ -0,0 +1,198 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" +#include "common_classes.hpp" + +#include +#include + + +TEST_CASE("plain/alignment", "test that aligned classes in certain compilers don't trigger compiler errors") { +#ifdef _MSC_VER + __declspec(align(16)) struct aligned_class { __declspec(align(16)) int var; }; + + struct A { + aligned_class a; + }; + + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::math); + + lua.new_usertype("A"); + A a; + lua["a"] = &a; + A& la = lua["a"]; + REQUIRE(&a == &la); +#else + REQUIRE(true); +#endif // VC++ stuff +} + +TEST_CASE("plain/indestructible", "test that we error for types that are innately indestructible") { + struct indestructible { + public: + int v = 20; + + struct insider { + void operator()(indestructible* i) const { + i->~indestructible(); + } + }; + + private: + ~indestructible() { + } + }; + + SECTION("doomed") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::unique_ptr i + = sol::detail::make_unique_deleter(); + lua["i"] = *i; + lua.safe_script("i = nil"); + auto result = lua.safe_script("collectgarbage()", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } + SECTION("saved") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + std::unique_ptr i + = sol::detail::make_unique_deleter(); + lua["i"] = *i; + lua.new_usertype("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") { + static int constructed = 0; + static int destructed = 0; + static int copied = 0; + static int moved = 0; + + struct st { + int value = 10; + + st() : value(10) { + ++constructed; + } + + st(const st& o) : value(o.value) { + ++copied; + ++constructed; + } + + st(st&& o) : value(o.value) { + ++moved; + ++constructed; + } + + ~st() { + value = 0; + ++destructed; + } + }; + + struct deallocate_only { + void operator()(st* p) const { + std::allocator alloc; + alloc.deallocate(p, 1); + } + }; + + { + sol::state lua; + + lua["f"] = sol::constructors(); + lua["g"] = sol::initializers([](st* mem) { + std::allocator alloc; + std::allocator_traits>::construct(alloc, mem); + }); + lua["h"] = sol::factories([]() { return st(); }); + lua["d"] = sol::destructor([](st& m) { m.~st(); }); + + sol::protected_function_result result1 = lua.safe_script("v = f()", &sol::script_pass_on_error); + REQUIRE(result1.valid()); + st& v = lua["v"]; + REQUIRE(v.value == 10); + REQUIRE(constructed == 1); + REQUIRE(destructed == 0); + { + std::unique_ptr unsafe(new st()); + lua["unsafe"] = unsafe.get(); + sol::protected_function_result result2 = lua.safe_script("d(unsafe)", &sol::script_pass_on_error); + REQUIRE(result2.valid()); + REQUIRE(constructed == 2); + REQUIRE(destructed == 1); + } + REQUIRE(constructed == 2); + REQUIRE(destructed == 1); + + { + sol::protected_function_result result3 = lua.safe_script("vg = g()", &sol::script_pass_on_error); + REQUIRE(result3.valid()); + st& vg = lua["vg"]; + REQUIRE(vg.value == 10); + REQUIRE(constructed == 3); + REQUIRE(destructed == 1); + } + + { + sol::protected_function_result result4 = lua.safe_script("vh = h()", &sol::script_pass_on_error); + REQUIRE(result4.valid()); + st& vh = lua["vh"]; + REQUIRE(vh.value == 10); + } + } + int purely_constructed = constructed - moved - copied; + int purely_destructed = destructed - moved - copied; + REQUIRE(constructed == destructed); + REQUIRE(purely_constructed == purely_destructed); + REQUIRE(purely_constructed == 4); + REQUIRE(purely_destructed == 4); +} + +TEST_CASE("plain/arrays", "make sure c-style arrays don't ruin everything and compile fine as usertype variables") { + sol::state lua; + + lua.open_libraries(); + lua.new_usertype("lua_object", "info", &lua_object::info, "stuck_info", &lua_object::stuck_info); + + auto result0 = lua.safe_script("obj = lua_object.new()", sol::script_pass_on_error); + REQUIRE(result0.valid()); + auto result1 = lua.safe_script("print(obj.info)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("print(obj.stuck_info)", sol::script_pass_on_error); + REQUIRE(result2.valid()); +} diff --git a/lib/sol2/tests/runtime_tests/source/policies.cpp b/lib/sol2/tests/runtime_tests/source/policies.cpp new file mode 100644 index 0000000..fec240f --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/policies.cpp @@ -0,0 +1,265 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include + +TEST_CASE("policies/self", "ensure we return a direct reference to the lua userdata rather than creating a new one") { + struct vec2 { + float x = 20.f; + float y = 20.f; + + vec2& normalize() { + float len2 = x * x + y * y; + if (len2 != 0) { + float len = sqrtf(len2); + x /= len; + y /= len; + } + return *this; + } + + ~vec2() { + x = std::numeric_limits::lowest(); + y = std::numeric_limits::lowest(); + } + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("vec2", + "x", &vec2::x, + "y", &vec2::y, + "normalize", sol::policies(&vec2::normalize, sol::returns_self())); + + auto result1 = lua.safe_script(R"( +v1 = vec2.new() +print('v1:', v1.x, v1.y) +v2 = v1:normalize() +print('v1:', v1.x, v1.y) +print('v2:', v2.x, v2.y) +print(v1, v2) +assert(rawequal(v1, v2)) +v1 = nil +collectgarbage() +print(v2) -- v2 points to same, is not destroyed + )", sol::script_pass_on_error); + REQUIRE(result1.valid()); +} + +TEST_CASE("policies/self_dependency", "ensure we can keep a userdata instance alive by attaching it to the lifetime of another userdata") { + struct dep; + struct gc_test; + static std::vector deps_destroyed; + static std::vector gc_tests_destroyed; + + struct dep { + int value = 20; + ~dep() { + std::cout << "\t" + << "[C++] ~dep" << std::endl; + value = std::numeric_limits::max(); + deps_destroyed.push_back(this); + } + }; + + struct gc_test { + + dep d; + + ~gc_test() { + std::cout << "\t" + << "[C++] ~gc_test" << std::endl; + gc_tests_destroyed.push_back(this); + } + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("dep", + "value", &dep::value, + sol::meta_function::to_string, [](dep& d) { + return "{ " + std::to_string(d.value) + " }"; + }); + lua.new_usertype("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); + REQUIRE(result1.valid()); + REQUIRE(deps_destroyed.empty()); + REQUIRE(gc_tests_destroyed.empty()); + + gc_test* g = lua["g"]; + dep* d = lua["d"]; + + auto result2 = lua.safe_script(R"( +print("g = nil, collectgarbage") +g = nil +collectgarbage() +print("", d) +)", sol::script_pass_on_error); + REQUIRE(result2.valid()); + + REQUIRE(deps_destroyed.empty()); + REQUIRE(gc_tests_destroyed.empty()); + + auto result3 = lua.safe_script(R"( +print("d = nil, collectgarbage") +d = nil +collectgarbage() +)", sol::script_pass_on_error); + REQUIRE(result3.valid()); + + REQUIRE(deps_destroyed.size() == 1); + REQUIRE(gc_tests_destroyed.size() == 1); + REQUIRE(deps_destroyed[0] == d); + REQUIRE(gc_tests_destroyed[0] == g); +} + +TEST_CASE("policies/stack_dependencies", "ensure we can take dependencies even to arguments pushed on the stack") { + struct holder; + struct depends_on_reference; + struct composition_related; + static std::vector composition_relateds_destroyed; + static std::vector holders_destroyed; + static std::vector depends_on_references_destroyed; + + struct composition_related { + std::string text = "bark"; + + ~composition_related() { + std::cout << "[C++] ~composition_related" << std::endl; + text = ""; + composition_relateds_destroyed.push_back(this); + } + }; + + struct holder { + int value = 20; + ~holder() { + std::cout << "[C++] ~holder" << std::endl; + value = std::numeric_limits::max(); + holders_destroyed.push_back(this); + } + }; + + struct depends_on_reference { + + std::reference_wrapper href; + composition_related comp; + + depends_on_reference(holder& h) + : href(h) { + } + + ~depends_on_reference() { + std::cout << "[C++] ~depends_on_reference" << std::endl; + depends_on_references_destroyed.push_back(this); + } + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("holder", + "value", &holder::value); + lua.new_usertype("depends_on_reference", + "new", sol::policies(sol::constructors(), sol::stack_dependencies(-1, 1)), + "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); + REQUIRE(result1.valid()); + REQUIRE(composition_relateds_destroyed.empty()); + REQUIRE(holders_destroyed.empty()); + REQUIRE(depends_on_references_destroyed.empty()); + + holder* h = lua["h"]; + composition_related* c = lua["c"]; + depends_on_reference* dor = lua["dor"]; + + REQUIRE(h == &dor->href.get()); + REQUIRE(c == &dor->comp); + + auto result2 = lua.safe_script(R"( +h = nil +collectgarbage() +)"); + REQUIRE(result2.valid()); + REQUIRE(composition_relateds_destroyed.empty()); + REQUIRE(holders_destroyed.empty()); + REQUIRE(depends_on_references_destroyed.empty()); + + auto result3 = lua.safe_script(R"( +c = nil +collectgarbage() +)", sol::script_pass_on_error); + REQUIRE(result3.valid()); + + REQUIRE(composition_relateds_destroyed.empty()); + REQUIRE(holders_destroyed.empty()); + REQUIRE(depends_on_references_destroyed.empty()); + + auto result4 = lua.safe_script(R"( +dor = nil +collectgarbage() +)", sol::script_pass_on_error); + REQUIRE(result4.valid()); + + REQUIRE(composition_relateds_destroyed.size() == 1); + REQUIRE(holders_destroyed.size() == 1); + REQUIRE(depends_on_references_destroyed.size() == 1); + REQUIRE(composition_relateds_destroyed[0] == c); + REQUIRE(holders_destroyed[0] == h); + REQUIRE(depends_on_references_destroyed[0] == dor); +} + +int always_return_24(lua_State* L, int) { + return sol::stack::push(L, 24); +} + +TEST_CASE("policies/custom", "ensure we can return dependencies on multiple things in the stack") { + + sol::state lua; + lua.set_function("f", sol::policies([]() { return std::string("hi there"); }, always_return_24)); + + int value = lua["f"](); + REQUIRE(value == 24); +} diff --git a/lib/sol2/tests/runtime_tests/source/proxies.cpp b/lib/sol2/tests/runtime_tests/source/proxies.cpp new file mode 100644 index 0000000..7cfeb0e --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/proxies.cpp @@ -0,0 +1,99 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include + +TEST_CASE("proxy/function results", "make sure that function results return proper proxies and can be indexed nicely") { + sol::state lua; + SECTION("unsafe_function_result") { + auto ufr = lua.script("return 1, 2, 3, 4"); + int accum = 0; + for (const auto& r : ufr) { + int v = r; + accum += v; + } + REQUIRE(accum == 10); + } + SECTION("protected_function_result") { + auto pfr = lua.safe_script("return 1, 2, 3, 4"); + int accum = 0; + for (const auto& r : pfr) { + int v = r; + accum += v; + } + REQUIRE(accum == 10); + } +} + +TEST_CASE("proxy/optional conversion", "make sure optional conversions out of a table work properly") { + sol::state state{}; + sol::table table = state.create_table_with("func", 42); + sol::optional func = table["func"]; + REQUIRE(func == sol::nullopt); +} + +TEST_CASE("proxy/proper-pushing", "allow proxies to reference other proxies and be serialized as the proxy itself and not a function or something") { + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::io); + + class T {}; + lua.new_usertype("T"); + + T t; + lua["t1"] = &t; + lua["t2"] = lua["t1"]; + lua.safe_script("b = t1 == t2"); + bool b = lua["b"]; + REQUIRE(b); +} + +TEST_CASE("proxy/equality", "check to make sure equality tests work") { + sol::state lua; +#ifndef __clang__ + REQUIRE((lua["a"] == sol::lua_nil)); + REQUIRE((lua["a"] == nullptr)); + REQUIRE_FALSE((lua["a"] != sol::lua_nil)); + REQUIRE_FALSE((lua["a"] != nullptr)); + REQUIRE_FALSE((lua["a"] == 0)); + REQUIRE_FALSE((lua["a"] == 2)); + REQUIRE((lua["a"] != 0)); + REQUIRE((lua["a"] != 2)); +#endif // clang screws up by trying to access int128 types that it doesn't support, even when we don't ask for them + + lua["a"] = 2; + +#ifndef __clang__ + REQUIRE_FALSE((lua["a"] == sol::lua_nil)); + REQUIRE_FALSE((lua["a"] == nullptr)); + REQUIRE((lua["a"] != sol::lua_nil)); + REQUIRE((lua["a"] != nullptr)); + REQUIRE_FALSE((lua["a"] == 0)); + REQUIRE((lua["a"] == 2)); + REQUIRE((lua["a"] != 0)); + REQUIRE_FALSE((lua["a"] != 2)); +#endif // clang screws up by trying to access int128 types that it doesn't support, even when we don't ask for them +} diff --git a/lib/sol2/tests/runtime_tests/source/sol_test.hpp b/lib/sol2/tests/runtime_tests/source/sol_test.hpp new file mode 100644 index 0000000..ac753eb --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/sol_test.hpp @@ -0,0 +1,75 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#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 +#include + +#include +#include + +struct test_stack_guard { + lua_State* L; + int& begintop; + int& endtop; + test_stack_guard(lua_State* L, int& begintop, int& endtop) : L(L), begintop(begintop), endtop(endtop) { + begintop = lua_gettop(L); + } + + void check() { + if (begintop != endtop) { + std::abort(); + } + } + + ~test_stack_guard() { + endtop = lua_gettop(L); + } +}; + +struct no_delete { + template + void operator()(P) const noexcept { + + } +}; + +#endif // SOL_TESTS_SOL_TEST_HPP diff --git a/lib/sol2/tests/runtime_tests/source/state.cpp b/lib/sol2/tests/runtime_tests/source/state.cpp new file mode 100644 index 0000000..7136fad --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/state.cpp @@ -0,0 +1,706 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include +#include +#include +#include +#include + +template +void write_file_attempt(Name&& filename, Data&& data) { + bool success = false; + for (std::size_t i = 0; i < 20; ++i) { + try { + std::ofstream file(std::forward(filename), std::ios::out); + file.exceptions(std::ios_base::badbit | std::ios_base::failbit); + file << std::forward(data) << std::endl; + file.close(); + } + catch (const std::exception&) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + continue; + } + success = true; + break; + } + if (!success) { + throw std::runtime_error("cannot open file or write out"); + } +} + +struct write_file_attempt_object { + template + void operator()(Args&&... args) { + write_file_attempt(std::forward(args)...); + } +}; + +struct string_reader_load { + const std::string& str; + std::size_t reads; + + string_reader_load(const std::string& s) + : str(s), reads(0) { + } +}; + +const char* string_reader(lua_State* L, void* vpstr, size_t* sz) { + (void)L; + string_reader_load& srl = *static_cast(vpstr); + if (srl.reads++ > 0) { + *sz = 0; + return NULL; + } + *sz = static_cast(srl.str.size()); + return srl.str.c_str(); +} + +TEST_CASE("state/require_file", "opening files as 'requires'") { + static const char file_require_file[] = "./tmp_thingy.lua"; + static const char file_require_file_user[] = "./tmp_thingy_user.lua"; + static const char require_file_code[] = "return { modfunc = function () return 221 end }"; + static const char require_file_user_code[] = "return { modfunc = function () return foo.new(221) end }"; + static std::atomic finished(0); + static std::once_flag flag_file = {}, flag_file_user = {}; + std::call_once(flag_file, write_file_attempt_object(), file_require_file, require_file_code); + std::call_once(flag_file_user, write_file_attempt_object(), file_require_file_user, require_file_user_code); + + auto clean_files = []() { + if (finished.fetch_add(1) < 1) { + return; + } + std::remove(file_require_file); + std::remove(file_require_file_user); + }; + + SECTION("with usertypes") { + struct foo { + foo(int bar) + : bar(bar) { + } + + const int bar; + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("foo", + sol::constructors>{}, + "bar", &foo::bar); + + const sol::table thingy1 = lua.require_file("thingy", file_require_file_user); + + REQUIRE(thingy1.valid()); + + const foo foo_v = thingy1["modfunc"](); + + int val1 = foo_v.bar; + + REQUIRE(val1 == 221); + clean_files(); + } + + SECTION("simple") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + const sol::table thingy1 = lua.require_file("thingy", file_require_file); + const sol::table thingy2 = lua.require_file("thingy", file_require_file); + + REQUIRE(thingy1.valid()); + REQUIRE(thingy2.valid()); + + int val1 = thingy1["modfunc"](); + int val2 = thingy2["modfunc"](); + + REQUIRE(val1 == 221); + REQUIRE(val2 == 221); + // must have loaded the same table + REQUIRE((thingy1 == thingy2)); + clean_files(); + } +} + +TEST_CASE("state/require_script", "opening strings as 'requires' clauses") { + std::string code = "return { modfunc = function () return 221 end }"; + + sol::state lua; + sol::stack_guard luasg(lua); + sol::table thingy1 = lua.require_script("thingy", code); + sol::table thingy2 = lua.require_script("thingy", code); + + int val1 = thingy1["modfunc"](); + int val2 = thingy2["modfunc"](); + REQUIRE(val1 == 221); + REQUIRE(val2 == 221); + // must have loaded the same table + REQUIRE((thingy1 == thingy2)); +} + +TEST_CASE("state/require", "require using a function") { + struct open { + static int open_func(lua_State* L) { + sol::state_view lua = L; + return sol::stack::push(L, lua.create_table_with("modfunc", sol::as_function([]() { return 221; }))); + } + }; + + sol::state lua; + sol::stack_guard luasg(lua); + sol::table thingy1 = lua.require("thingy", open::open_func); + sol::table thingy2 = lua.require("thingy", open::open_func); + + int val1 = thingy1["modfunc"](); + int val2 = thingy2["modfunc"](); + REQUIRE(val1 == 221); + REQUIRE(val2 == 221); + // THIS IS ONLY REQUIRED IN LUA 5.3, FOR SOME REASON + // must have loaded the same table + // REQUIRE(thingy1 == thingy2); +} + +TEST_CASE("state/multi require", "make sure that requires transfers across hand-rolled script implementation and standard requiref") { + struct open { + static int open_func(lua_State* L) { + sol::state_view lua = L; + return sol::stack::push(L, lua.create_table_with("modfunc", sol::as_function([]() { return 221; }))); + } + }; + + std::string code = "return { modfunc = function () return 221 end }"; + sol::state lua; + sol::table thingy1 = lua.require("thingy", open::open_func); + sol::table thingy2 = lua.require("thingy", open::open_func); + sol::table thingy3 = lua.require_script("thingy", code); + + int val1 = thingy1["modfunc"](); + int val2 = thingy2["modfunc"](); + int val3 = thingy3["modfunc"](); + REQUIRE(val1 == 221); + REQUIRE(val2 == 221); + REQUIRE(val3 == 221); + // must have loaded the same table + // Lua is not obliged to give a shit. Thanks, Lua + //REQUIRE(thingy1 == thingy2); + // But we care, thankfully + //REQUIRE(thingy1 == thingy3); + REQUIRE((thingy2 == thingy3)); +} + +TEST_CASE("state/require-safety", "make sure unrelated modules aren't harmed in using requires") { + sol::state lua; + lua.open_libraries(); + std::string t1 = lua.safe_script(R"(require 'io' +return 'test1')"); + sol::object ot2 = lua.require_script("test2", R"(require 'io' +return 'test2')"); + std::string t2 = ot2.as(); + std::string t3 = lua.safe_script(R"(require 'io' +return 'test3')"); + REQUIRE(t1 == "test1"); + REQUIRE(t2 == "test2"); + REQUIRE(t3 == "test3"); +} + +TEST_CASE("state/leak check", "make sure there are no humongous memory leaks in iteration") { +#if 0 + sol::state lua; + lua.safe_script(R"( +record = {} +for i=1,256 do + record[i] = i +end +function run() + for i=1,25000 do + fun(record) + end +end +function run2() + for i=1,50000 do + fun(record) + end +end +)"); + + lua["fun"] = [](const sol::table &t) { + //removing the for loop fixes the memory leak + auto b = t.begin(); + auto e = t.end(); + for (; b != e; ++b) { + + } + }; + + size_t beforewarmup = lua.memory_used(); + lua["run"](); + + size_t beforerun = lua.memory_used(); + lua["run"](); + size_t afterrun = lua.memory_used(); + lua["run2"](); + size_t afterrun2 = lua.memory_used(); + + // Less memory used before the warmup + REQUIRE(beforewarmup <= beforerun); + // Iteration size and such does not bloat or affect memory + // (these are weak checks but they'll warn us nonetheless if something goes wrong) + REQUIRE(beforerun == afterrun); + REQUIRE(afterrun == afterrun2); +#else + REQUIRE(true); +#endif +} + +TEST_CASE("state/script returns", "make sure script returns are done properly") { + std::string script = + R"( +local example = +{ + str = "this is a string", + num = 1234, + + func = function(self) + print(self.str) + return "fstr" + end +} + +return example; +)"; + + auto bar = [&script](sol::this_state l) { + sol::state_view lua = l; + sol::table data = lua.safe_script(script); + + std::string str = data["str"]; + int num = data["num"]; + std::string fstr = data["func"](data); + REQUIRE(str == "this is a string"); + REQUIRE(fstr == "fstr"); + REQUIRE(num == 1234); + }; + + auto foo = [&script](int, sol::this_state l) { + sol::state_view lua = l; + sol::table data = lua.safe_script(script); + + std::string str = data["str"]; + int num = data["num"]; + std::string fstr = data["func"](data); + REQUIRE(str == "this is a string"); + REQUIRE(fstr == "fstr"); + REQUIRE(num == 1234); + }; + + auto bar2 = [&script](sol::this_state l) { + sol::state_view lua = l; + sol::table data = lua.do_string(script); + + std::string str = data["str"]; + int num = data["num"]; + std::string fstr = data["func"](data); + REQUIRE(str == "this is a string"); + REQUIRE(fstr == "fstr"); + REQUIRE(num == 1234); + }; + + auto foo2 = [&script](int, sol::this_state l) { + sol::state_view lua = l; + sol::table data = lua.do_string(script); + + std::string str = data["str"]; + int num = data["num"]; + std::string fstr = data["func"](data); + REQUIRE(str == "this is a string"); + REQUIRE(fstr == "fstr"); + REQUIRE(num == 1234); + }; + + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(); + + lua.set_function("foo", foo); + lua.set_function("foo2", foo2); + lua.set_function("bar", bar); + lua.set_function("bar2", bar2); + + lua.safe_script("bar() bar2() foo(1) foo2(1)"); +} + +TEST_CASE("state/copy and move", "ensure state can be properly copied and moved") { + sol::state lua; + lua["a"] = 1; + + sol::state lua2(std::move(lua)); + int a2 = lua2["a"]; + REQUIRE(a2 == 1); + lua = std::move(lua2); + int a = lua["a"]; + REQUIRE(a == 1); +} + +TEST_CASE("state/requires-reload", "ensure that reloading semantics do not cause a crash") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(); + lua.safe_script("require 'io'\nreturn 'test1'"); + lua.require_script("test2", "require 'io'\nreturn 'test2'"); + lua.safe_script("require 'io'\nreturn 'test3'"); +} + +TEST_CASE("state/script, do, and load", "test success and failure cases for loading and running scripts") { + const static std::string bad_syntax = "weird\n%$@symb\nols"; + static const char file_bad_syntax[] = "./temp.bad_syntax.lua"; + const static std::string bad_runtime = "bad.code = 20"; + static const char file_bad_runtime[] = "./temp.bad_runtime.lua"; + const static std::string good = "a = 21\nreturn a"; + static const char file_good[] = "./temp.good.lua"; + static std::once_flag flag_file_bs = {}, flag_file_br = {}, flag_file_g = {}; + static std::atomic finished(0); + std::call_once(flag_file_bs, write_file_attempt_object(), file_bad_syntax, bad_syntax); + std::call_once(flag_file_br, write_file_attempt_object(), file_bad_runtime, bad_runtime); + std::call_once(flag_file_g, write_file_attempt_object(), file_good, good); + + auto clean_files = []() { + if (finished.fetch_add(1) < 14) { + return; + } + std::remove(file_bad_syntax); + std::remove(file_bad_runtime); + std::remove(file_good); + }; + + SECTION("script") { + sol::state lua; + sol::stack_guard luasg(lua); + int ar = lua.safe_script(good); + int a = lua["a"]; + REQUIRE(a == 21); + REQUIRE(ar == 21); + clean_files(); + } + SECTION("unsafe_script") { + sol::state lua; + sol::stack_guard luasg(lua); + int ar = lua.unsafe_script(good); + int a = lua["a"]; + REQUIRE(a == 21); + REQUIRE(ar == 21); + clean_files(); + } + SECTION("script-handler") { + sol::state lua; + sol::stack_guard luasg(lua); + auto errbs = lua.safe_script(bad_syntax, sol::script_pass_on_error); + REQUIRE(!errbs.valid()); + + auto errbr = lua.safe_script(bad_runtime, sol::script_pass_on_error); + REQUIRE(!errbr.valid()); + + auto result = lua.safe_script(good, sol::script_pass_on_error); + int a = lua["a"]; + int ar = result; + REQUIRE(result.valid()); + REQUIRE(a == 21); + REQUIRE(ar == 21); + clean_files(); + } + SECTION("do_string") { + sol::state lua; + sol::stack_guard luasg(lua); + auto errbs = lua.do_string(bad_syntax); + REQUIRE(!errbs.valid()); + + auto errbr = lua.do_string(bad_runtime); + REQUIRE(!errbr.valid()); + + auto result = lua.do_string(good); + int a = lua["a"]; + int ar = result; + REQUIRE(result.valid()); + REQUIRE(a == 21); + REQUIRE(ar == 21); + clean_files(); + } + SECTION("load_string") { + sol::state lua; + sol::stack_guard luasg(lua); + auto errbsload = lua.load(bad_syntax); + REQUIRE(!errbsload.valid()); + + sol::load_result errbrload = lua.load(bad_runtime); + REQUIRE(errbrload.valid()); + sol::protected_function errbrpf = errbrload; + auto errbr = errbrpf(); + REQUIRE(!errbr.valid()); + + sol::load_result resultload = lua.load(good); + REQUIRE(resultload.valid()); + sol::protected_function resultpf = resultload; + auto result = resultpf(); + int a = lua["a"]; + int ar = result; + REQUIRE(result.valid()); + REQUIRE(a == 21); + REQUIRE(ar == 21); + clean_files(); + } + SECTION("load") { + sol::state lua; + sol::stack_guard luasg(lua); + string_reader_load bssrl(bad_syntax); + void* vpbssrl = static_cast(&bssrl); + auto errbsload = lua.load(&string_reader, vpbssrl, bad_syntax); + REQUIRE(!errbsload.valid()); + + string_reader_load brsrl(bad_runtime); + void* vpbrsrl = static_cast(&brsrl); + sol::load_result errbrload = lua.load(&string_reader, vpbrsrl, bad_runtime); + REQUIRE(errbrload.valid()); + sol::protected_function errbrpf = errbrload; + auto errbr = errbrpf(); + REQUIRE(!errbr.valid()); + + string_reader_load gsrl(good); + void* vpgsrl = static_cast(&gsrl); + sol::load_result resultload = lua.load(&string_reader, vpgsrl, good); + REQUIRE(resultload.valid()); + sol::protected_function resultpf = resultload; + auto result = resultpf(); + int a = lua["a"]; + int ar = result; + REQUIRE(result.valid()); + REQUIRE(a == 21); + REQUIRE(ar == 21); + clean_files(); + } + SECTION("load_string (text)") { + sol::state lua; + sol::stack_guard luasg(lua); + auto errbsload = lua.load(bad_syntax, bad_syntax, sol::load_mode::text); + REQUIRE(!errbsload.valid()); + + sol::load_result errbrload = lua.load(bad_runtime, bad_runtime, sol::load_mode::text); + REQUIRE(errbrload.valid()); + sol::protected_function errbrpf = errbrload; + 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; + auto result = resultpf(); + int a = lua["a"]; + int ar = result; + REQUIRE(result.valid()); + REQUIRE(a == 21); + REQUIRE(ar == 21); + clean_files(); + } + SECTION("load (text)") { + sol::state lua; + sol::stack_guard luasg(lua); + string_reader_load bssrl(bad_syntax); + void* vpbssrl = static_cast(&bssrl); + auto errbsload = lua.load(&string_reader, vpbssrl, bad_syntax, sol::load_mode::text); + REQUIRE(!errbsload.valid()); + + string_reader_load brsrl(bad_runtime); + void* vpbrsrl = static_cast(&brsrl); + sol::load_result errbrload = lua.load(&string_reader, vpbrsrl, bad_runtime, sol::load_mode::text); + REQUIRE(errbrload.valid()); + sol::protected_function errbrpf = errbrload; + auto errbr = errbrpf(); + REQUIRE(!errbr.valid()); + + string_reader_load gsrl(good); + void* vpgsrl = static_cast(&gsrl); + sol::load_result resultload = lua.load(&string_reader, vpgsrl, good, sol::load_mode::text); + REQUIRE(resultload.valid()); + sol::protected_function resultpf = resultload; + auto result = resultpf(); + int a = lua["a"]; + int ar = result; + REQUIRE(result.valid()); + REQUIRE(a == 21); + REQUIRE(ar == 21); + clean_files(); + } + SECTION("script_file") { + sol::state lua; + sol::stack_guard luasg(lua); + int ar = lua.safe_script_file(file_good); + int a = lua["a"]; + REQUIRE(a == 21); + REQUIRE(ar == 21); + clean_files(); + } + SECTION("unsafe_script_file") { + sol::state lua; + sol::stack_guard luasg(lua); + int ar = lua.unsafe_script_file(file_good); + int a = lua["a"]; + REQUIRE(a == 21); + REQUIRE(ar == 21); + clean_files(); + } + SECTION("script_file-handler") { + sol::state lua; + sol::stack_guard luasg(lua); + auto errbs = lua.safe_script_file(file_bad_syntax, sol::script_pass_on_error); + REQUIRE(!errbs.valid()); + + auto errbr = lua.safe_script_file(file_bad_runtime, sol::script_pass_on_error); + REQUIRE(!errbr.valid()); + + auto result = lua.safe_script_file(file_good, sol::script_pass_on_error); + int a = lua["a"]; + int ar = result; + REQUIRE(result.valid()); + REQUIRE(a == 21); + REQUIRE(ar == 21); + clean_files(); + } + SECTION("safe_script_file-handler") { + sol::state lua; + sol::stack_guard luasg(lua); + auto errbs = lua.safe_script_file(file_bad_syntax, sol::script_pass_on_error); + REQUIRE(!errbs.valid()); + + auto errbr = lua.safe_script_file(file_bad_runtime, sol::script_pass_on_error); + REQUIRE(!errbr.valid()); + + auto result = lua.safe_script_file(file_good, sol::script_pass_on_error); + int a = lua["a"]; + int ar = result; + REQUIRE(result.valid()); + REQUIRE(a == 21); + REQUIRE(ar == 21); + clean_files(); + } + SECTION("do_file") { + sol::state lua; + sol::stack_guard luasg(lua); + auto errbs = lua.do_file(file_bad_syntax); + REQUIRE(!errbs.valid()); + + auto errbr = lua.do_file(file_bad_runtime); + REQUIRE(!errbr.valid()); + + auto result = lua.do_file(file_good); + int a = lua["a"]; + int ar = result; + REQUIRE(result.valid()); + REQUIRE(a == 21); + REQUIRE(ar == 21); + clean_files(); + } + SECTION("load_file") { + sol::state lua; + sol::stack_guard luasg(lua); + auto errbsload = lua.load_file(file_bad_syntax); + REQUIRE(!errbsload.valid()); + + sol::load_result errbrload = lua.load_file(file_bad_runtime); + REQUIRE(errbrload.valid()); + sol::protected_function errbrpf = errbrload; + auto errbr = errbrpf(); + REQUIRE(!errbr.valid()); + + sol::load_result resultload = lua.load_file(file_good); + REQUIRE(resultload.valid()); + sol::protected_function resultpf = resultload; + auto result = resultpf(); + int a = lua["a"]; + int ar = result; + REQUIRE(result.valid()); + REQUIRE(a == 21); + REQUIRE(ar == 21); + clean_files(); + } + SECTION("load_file (text)") { + sol::state lua; + sol::stack_guard luasg(lua); + auto errbsload = lua.load_file(file_bad_syntax, sol::load_mode::text); + REQUIRE(!errbsload.valid()); + + sol::load_result errbrload = lua.load_file(file_bad_runtime, sol::load_mode::text); + REQUIRE(errbrload.valid()); + sol::protected_function errbrpf = errbrload; + 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; + auto result = resultpf(); + int a = lua["a"]; + int ar = result; + REQUIRE(result.valid()); + REQUIRE(a == 21); + REQUIRE(ar == 21); + clean_files(); + } +} + +TEST_CASE("state/script return converts", "make sure that script return values are convertable from one to another") { + sol::state lua; + + sol::protected_function_result r1 = lua.unsafe_script("return 2"); + sol::unsafe_function_result r2 = lua.safe_script("return 3"); + + int v1 = r1; + int v2 = r2; + REQUIRE(v1 == 2); + REQUIRE(v2 == 3); +} + +TEST_CASE("state/script function returns", "make sure that returned functions are converitble from a result to a function") { + SECTION("from result move constructor") { + sol::state lua; + + sol::protected_function pf = lua.safe_script("return function () return 2 end", sol::script_pass_on_error); + REQUIRE(pf.valid()); + + int v1 = pf(); + REQUIRE(v1 == 2); + } + SECTION("from result operator=") { + sol::state lua; + + 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; + int v1 = pf(); + REQUIRE(v1 == 1); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/storage.cpp b/lib/sol2/tests/runtime_tests/source/storage.cpp new file mode 100644 index 0000000..44d99d8 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/storage.cpp @@ -0,0 +1,85 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#define SOL_ALL_SAFETIES_ON 1 +#define SOL_ENABLE_INTEROP 1 + +#include + +#include + +TEST_CASE("storage/registry construction", "ensure entries from the registry can be retrieved") { + const auto& code = R"( +function f() + return 2 +end +)"; + + sol::state lua; + sol::stack_guard luasg(lua); + + { + auto r = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE(r.valid()); + } + sol::function f = lua["f"]; + sol::reference r = lua["f"]; + sol::function regf(lua, f); + sol::reference regr(lua, sol::ref_index(f.registry_index())); + bool isequal = f == r; + REQUIRE(isequal); + isequal = f == regf; + REQUIRE(isequal); + isequal = f == regr; + REQUIRE(isequal); +} + +TEST_CASE("storage/registry construction empty", "ensure entries from the registry can be retrieved") { + sol::state lua; + sol::function f = lua["f"]; + sol::reference r = lua["f"]; + sol::function regf(lua, f); + sol::reference regr(lua, sol::ref_index(f.registry_index())); + bool isequal = f == r; + REQUIRE(isequal); + isequal = f == regf; + REQUIRE(isequal); + isequal = f == regr; + REQUIRE(isequal); +} + +TEST_CASE("storage/main thread", "ensure round-tripping and pulling out thread data even on 5.1 with a backup works") { + sol::state lua; + { + sol::stack_guard g(lua); + lua_State* orig = lua; + lua_State* ts = sol::main_thread(lua, lua); + REQUIRE(ts == orig); + } + { + sol::stack_guard g(lua); + lua_State* orig = lua; + lua_State* ts = sol::main_thread(lua); + REQUIRE(ts == orig); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/strings.cpp b/lib/sol2/tests/runtime_tests/source/strings.cpp new file mode 100644 index 0000000..d5e7a31 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/strings.cpp @@ -0,0 +1,198 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include + +struct test {}; +template +struct test_t {}; + +namespace muh_namespace { + struct ns_test {}; + + namespace { + struct ns_anon_test {}; + } // namespace +} // namespace muh_namespace + +TEST_CASE("stack/strings", "test that strings can be roundtripped") { + sol::state lua; + sol::stack_guard luasg(lua); + + static const char utf8str[] = "\xF0\x9F\x8D\x8C\x20\xE6\x99\xA5\x20\x46\x6F\x6F\x20\xC2\xA9\x20\x62\x61\x72\x20\xF0\x9D\x8C\x86\x20\x62\x61\x7A\x20\xE2\x98\x83\x20\x71\x75\x78"; + static const char16_t utf16str[] = { 0xD83C, 0xDF4C, 0x20, 0x6665, 0x20, 0x46, 0x6F, 0x6F, 0x20, 0xA9, 0x20, 0x62, 0x61, 0x72, 0x20, 0xD834, 0xDF06, 0x20, 0x62, 0x61, 0x7A, 0x20, 0x2603, 0x20, 0x71, 0x75, 0x78, 0x00 }; + static const char32_t utf32str[] = { 0x1F34C, 0x0020, 0x6665, 0x0020, 0x0046, 0x006F, 0x006F, 0x0020, 0x00A9, 0x0020, 0x0062, 0x0061, 0x0072, 0x0020, 0x1D306, 0x0020, 0x0062, 0x0061, 0x007A, 0x0020, 0x2603, 0x0020, 0x0071, 0x0075, 0x0078, 0x00 }; +#ifdef _WIN32 + INFO("win32 widestr"); + static const wchar_t widestr[] = { 0xD83C, 0xDF4C, 0x20, 0x6665, 0x20, 0x46, 0x6F, 0x6F, 0x20, 0xA9, 0x20, 0x62, 0x61, 0x72, 0x20, 0xD834, 0xDF06, 0x20, 0x62, 0x61, 0x7A, 0x20, 0x2603, 0x20, 0x71, 0x75, 0x78, 0x00 }; +#else + INFO("non-windows widestr"); + static const wchar_t widestr[] = { 0x1F34C, 0x0020, 0x6665, 0x0020, 0x0046, 0x006F, 0x006F, 0x0020, 0x00A9, 0x0020, 0x0062, 0x0061, 0x0072, 0x0020, 0x1D306, 0x0020, 0x0062, 0x0061, 0x007A, 0x0020, 0x2603, 0x0020, 0x0071, 0x0075, 0x0078, 0x00 }; +#endif + static const std::string utf8str_s = utf8str; + static const std::u16string utf16str_s = utf16str; + static const std::u32string utf32str_s = utf32str; + static const std::wstring widestr_s = widestr; + + INFO("sizeof(wchar_t): " << sizeof(wchar_t)); + INFO("sizeof(char16_t): " << sizeof(char16_t)); + INFO("sizeof(char32_t): " << sizeof(char32_t)); + INFO("utf8str: " << utf8str); + INFO("utf8str_s: " << utf8str_s); + + lua["utf8"] = utf8str; + lua["utf16"] = utf16str; + lua["utf32"] = utf32str; + lua["wide"] = widestr; + + SECTION("to_utf8") { + std::string utf8_to_utf8 = lua["utf8"]; + std::string utf16_to_utf8 = lua["utf16"]; + std::string utf32_to_utf8 = lua["utf32"]; + std::string wide_to_utf8 = lua["wide"]; + + REQUIRE(utf8_to_utf8 == utf8str_s); + REQUIRE(utf16_to_utf8 == utf8str_s); + REQUIRE(utf32_to_utf8 == utf8str_s); + REQUIRE(wide_to_utf8 == utf8str_s); + } + SECTION("to_wide") { + std::wstring utf8_to_wide = lua["utf8"]; + std::wstring utf16_to_wide = lua["utf16"]; + std::wstring utf32_to_wide = lua["utf32"]; + std::wstring wide_to_wide = lua["wide"]; + + REQUIRE(utf8_to_wide == widestr_s); + REQUIRE(utf16_to_wide == widestr_s); + REQUIRE(utf32_to_wide == widestr_s); + REQUIRE(wide_to_wide == widestr_s); + } + SECTION("to_utf16") { + std::u16string utf8_to_utf16 = lua["utf8"]; + std::u16string utf16_to_utf16 = lua["utf16"]; + std::u16string utf32_to_utf16 = lua["utf32"]; + std::u16string wide_to_utf16 = lua["wide"]; + + REQUIRE(utf8_to_utf16 == utf16str_s); + REQUIRE(utf16_to_utf16 == utf16str_s); + REQUIRE(utf32_to_utf16 == utf16str_s); + REQUIRE(wide_to_utf16 == utf16str_s); + } + SECTION("to_utf32") { + std::u32string utf8_to_utf32 = lua["utf8"]; + std::u32string utf16_to_utf32 = lua["utf16"]; + std::u32string utf32_to_utf32 = lua["utf32"]; + std::u32string wide_to_utf32 = lua["wide"]; + + REQUIRE(utf8_to_utf32 == utf32str_s); + REQUIRE(utf16_to_utf32 == utf32str_s); + REQUIRE(utf32_to_utf32 == utf32str_s); + REQUIRE(wide_to_utf32 == utf32str_s); + } + SECTION("to_char32_t") { + char32_t utf8_to_char32 = lua["utf8"]; + char32_t utf16_to_char32 = lua["utf16"]; + char32_t utf32_to_char32 = lua["utf32"]; + char32_t wide_to_char32 = lua["wide"]; + + REQUIRE(utf8_to_char32 == utf32str[0]); + REQUIRE(utf16_to_char32 == utf32str[0]); + REQUIRE(utf32_to_char32 == utf32str[0]); + REQUIRE(wide_to_char32 == utf32str[0]); + } + SECTION("to_char16_t") { + char16_t utf8_to_char16 = lua["utf8"]; + char16_t utf16_to_char16 = lua["utf16"]; + char16_t utf32_to_char16 = lua["utf32"]; + char16_t wide_to_char16 = lua["wide"]; + + REQUIRE(utf8_to_char16 == utf16str[0]); + REQUIRE(utf16_to_char16 == utf16str[0]); + REQUIRE(utf32_to_char16 == utf16str[0]); + REQUIRE(wide_to_char16 == utf16str[0]); + } + SECTION("to_char") { + char utf8_to_char = lua["utf8"].get(); + char utf16_to_char = lua["utf16"].get(); + char utf32_to_char = lua["utf32"].get(); + char wide_to_char = lua["wide"].get(); + + REQUIRE(utf8_to_char == utf8str[0]); + REQUIRE(utf16_to_char == utf8str[0]); + REQUIRE(utf32_to_char == utf8str[0]); + REQUIRE(wide_to_char == utf8str[0]); + } +} + +TEST_CASE("detail/demangling", "test some basic demangling cases") { + std::string teststr = sol::detail::short_demangle(); + std::string nsteststr = sol::detail::short_demangle(); + std::string nsateststr = sol::detail::short_demangle(); + + REQUIRE(teststr == "test"); + REQUIRE(nsteststr == "ns_test"); + REQUIRE(nsateststr == "ns_anon_test"); +} + +TEST_CASE("object/string-pushers", "test some basic string pushers with in_place constructor") { + sol::state lua; + + sol::object ocs(lua, sol::in_place, "bark\0bark", 9); + sol::object os(lua, sol::in_place_type, std::string("bark\0bark", 9), 8); + sol::object osv(lua, sol::in_place_type, sol::string_view("woofwoof", 8), 8); + bool test1 = ocs.as() == std::string("bark\0bark", 9); + bool test2 = os.as() == std::string("bark\0bar", 8); + bool test3 = osv.as() == std::string("woofwoof", 8); + REQUIRE(ocs.get_type() == sol::type::string); + REQUIRE(ocs.is()); + REQUIRE(ocs.is()); + + REQUIRE(os.get_type() == sol::type::string); + REQUIRE(os.is()); + REQUIRE(os.is()); + + REQUIRE(osv.get_type() == sol::type::string); + REQUIRE(osv.is()); + REQUIRE(osv.is()); + + REQUIRE(test1); + REQUIRE(test2); + REQUIRE(test3); +} + +TEST_CASE("strings/non const c strings", "push non const qualified c strings as strings") { + sol::state lua; + + char cbark[] = "bark"; + char* bark = cbark; + lua["bark"] = bark; + sol::type t = lua["bark"].get_type(); + std::string lbark = lua["bark"]; + + REQUIRE((t == sol::type::string)); + REQUIRE((bark == std::string("bark"))); +} diff --git a/lib/sol2/tests/runtime_tests/source/tables.checks.cpp b/lib/sol2/tests/runtime_tests/source/tables.checks.cpp new file mode 100644 index 0000000..cc8a3b4 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/tables.checks.cpp @@ -0,0 +1,51 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +struct not_a_table_at_all {}; + +TEST_CASE("tables/lua_table", "check that lua_table accepts only lua-style tables, and not other types") { + sol::state lua; + lua["f"] = [](sol::lua_table lt) { + int x = lt["a"]; + REQUIRE(x == 3); + }; + lua["ud"] = not_a_table_at_all{}; + + auto result0 = lua.safe_script("t = { a = 3 }", sol::script_pass_on_error); + REQUIRE(result0.valid()); + auto result1 = lua.safe_script("f(t)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + + auto result2 = lua.safe_script("f(ud)", sol::script_pass_on_error); + REQUIRE_FALSE(result2.valid()); + auto result3 = lua.safe_script("f(24)", sol::script_pass_on_error); + REQUIRE_FALSE(result3.valid()); + auto result4 = lua.safe_script("f(nil)", sol::script_pass_on_error); + REQUIRE_FALSE(result4.valid()); + auto result5 = lua.safe_script("f('bark')", sol::script_pass_on_error); + REQUIRE_FALSE(result5.valid()); +} diff --git a/lib/sol2/tests/runtime_tests/source/tables.clear.cpp b/lib/sol2/tests/runtime_tests/source/tables.clear.cpp new file mode 100644 index 0000000..ae92f39 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/tables.clear.cpp @@ -0,0 +1,74 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +TEST_CASE("tables/clear", "clear method works and does not clobber stack") { + sol::state lua; + sol::stack_guard luasg(lua); + lua["t"] = sol::lua_value({ { "a", "b" }, { "c", "d" } }); + sol::table t = lua["t"]; + { + sol::stack_guard clearsg(lua); + t.clear(); + } + REQUIRE(!t["a"].valid()); + REQUIRE(!t["c"].valid()); +} + +TEST_CASE("tables/stack clear", "stack-based clear method works and does not clobber stack") { + sol::state lua; + SECTION("reference based") { + sol::stack_guard luasg(lua); + lua["t"] = sol::lua_value({ { "a", "b" }, { "c", "d" } }); + sol::table t = lua["t"]; + REQUIRE(t["a"] == std::string("b")); + REQUIRE(t["c"] == std::string("d")); + { + sol::stack_guard clearsg(lua); + sol::stack::clear(t); + } + REQUIRE(!t["a"].valid()); + REQUIRE(!t["c"].valid()); + } + SECTION("with index") { + sol::stack_guard luasg(lua); + lua["t"] = sol::lua_value({ { "a", "b" }, { "c", "d" } }); + sol::table t = lua["t"]; + REQUIRE(t["a"] == std::string("b")); + REQUIRE(t["c"] == std::string("d")); + { + sol::stack_guard ppclearsg(lua); + auto pp = sol::stack::push_pop(t); + int table_index = pp.index_of(t); + { + sol::stack_guard clearsg(lua); + sol::stack::clear(lua, table_index); + } + } + REQUIRE(!t["a"].valid()); + REQUIRE(!t["c"].valid()); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/tables.cpp b/lib/sol2/tests/runtime_tests/source/tables.cpp new file mode 100644 index 0000000..a6b45cc --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/tables.cpp @@ -0,0 +1,250 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include +#include +#include + +std::string free_function() { + INFO("free_function()"); + return "test"; +} + +struct object { + std::string operator()() { + INFO("member_test()"); + return "test"; + } +}; + +TEST_CASE("tables/cleanup", "make sure tables leave the stack balanced") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(); + + auto f = [] { return 5; }; + for (int i = 0; i < 30; i++) { + std::string name = std::string("init") + std::to_string(i); + int top = lua_gettop(lua); + lua[name] = f; + int aftertop = lua_gettop(lua); + REQUIRE(aftertop == top); + int val = lua[name](); + REQUIRE(val == 5); + } +} + +TEST_CASE("tables/nested cleanup", "make sure tables leave the stack balanced") { + sol::state lua; + lua.open_libraries(); + + lua.safe_script("A={}"); + auto f = [] { return 5; }; + for (int i = 0; i < 30; i++) { + std::string name = std::string("init") + std::to_string(i); + int top = lua_gettop(lua); + auto A = lua["A"]; + int beforetop = lua_gettop(lua); + REQUIRE(beforetop == top); + A[name] = f; + int aftertop = lua_gettop(lua); + REQUIRE(aftertop == top); + int val = A[name](); + REQUIRE(val == 5); + } +} + +TEST_CASE("tables/variables", "Check if tables and variables work as intended") { + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::os); + lua.get("os").set("name", "windows"); + { + auto result = lua.safe_script("assert(os.name == \"windows\")", sol::script_pass_on_error); + REQUIRE(result.valid()); + } +} + +TEST_CASE("tables/create", "Check if creating a table is kosher") { + sol::state lua; + lua["testtable"] = sol::table::create(lua.lua_state(), 0, 0, "Woof", "Bark", 1, 2, 3, 4); + sol::object testobj = lua["testtable"]; + REQUIRE(testobj.is()); + sol::table testtable = testobj.as(); + REQUIRE((testtable["Woof"] == std::string("Bark"))); + REQUIRE((testtable[1] == 2)); + REQUIRE((testtable[3] == 4)); +} + +TEST_CASE("tables/create local", "Check if creating a table is kosher") { + sol::state lua; + lua["testtable"] = lua.create_table(0, 0, "Woof", "Bark", 1, 2, 3, 4); + sol::object testobj = lua["testtable"]; + REQUIRE(testobj.is()); + sol::table testtable = testobj.as(); + REQUIRE((testtable["Woof"] == std::string("Bark"))); + REQUIRE((testtable[1] == 2)); + REQUIRE((testtable[3] == 4)); +} + +TEST_CASE("tables/create local named", "Check if creating a table is kosher") { + sol::state lua; + sol::table testtable = lua.create_table("testtable", 0, 0, "Woof", "Bark", 1, 2, 3, 4); + sol::object testobj = lua["testtable"]; + REQUIRE(testobj.is()); + REQUIRE((testobj == testtable)); + REQUIRE_FALSE((testobj != testtable)); + REQUIRE((testtable["Woof"] == std::string("Bark"))); + REQUIRE((testtable[1] == 2)); + REQUIRE((testtable[3] == 4)); +} + +TEST_CASE("tables/create-with-local", "Check if creating a table is kosher") { + sol::state lua; + lua["testtable"] = lua.create_table_with("Woof", "Bark", 1, 2, 3, 4); + sol::object testobj = lua["testtable"]; + REQUIRE(testobj.is()); + sol::table testtable = testobj.as(); + REQUIRE((testtable["Woof"] == std::string("Bark"))); + REQUIRE((testtable[1] == 2)); + REQUIRE((testtable[3] == 4)); +} + +TEST_CASE("tables/function variables", "Check if tables and function calls work as intended") { + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::os); + auto run_script = [](sol::state& lua) -> void { lua.safe_script("assert(os.fun() == \"test\")"); }; + + lua.get("os").set_function("fun", []() { + INFO("stateless lambda()"); + return "test"; + }); + REQUIRE_NOTHROW(run_script(lua)); + + lua.get("os").set_function("fun", &free_function); + REQUIRE_NOTHROW(run_script(lua)); + + // l-value, canNOT optimise + // prefer value semantics unless wrapped with std::reference_wrapper + { + auto lval = object(); + lua.get("os").set_function("fun", &object::operator(), lval); + } + REQUIRE_NOTHROW(run_script(lua)); + + auto reflval = object(); + lua.get("os").set_function("fun", &object::operator(), std::ref(reflval)); + REQUIRE_NOTHROW(run_script(lua)); + + // stateful lambda: non-convertible, cannot be optimised + int breakit = 50; + lua.get("os").set_function("fun", [&breakit]() { + INFO("stateful lambda() with breakit:" << breakit); + return "test"; + }); + REQUIRE_NOTHROW(run_script(lua)); + + // r-value, cannot optimise + lua.get("os").set_function("fun", &object::operator(), object()); + REQUIRE_NOTHROW(run_script(lua)); + + // r-value, cannot optimise + auto rval = object(); + lua.get("os").set_function("fun", &object::operator(), std::move(rval)); + REQUIRE_NOTHROW(run_script(lua)); +} + +TEST_CASE("tables/add", "Basic test to make sure the 'add' feature works") { + static const int sz = 120; + + sol::state lua; + sol::table t = lua.create_table(sz, 0); + + std::vector bigvec(sz); + std::iota(bigvec.begin(), bigvec.end(), 1); + + for (std::size_t i = 0; i < bigvec.size(); ++i) { + t.add(bigvec[i]); + } + for (std::size_t i = 0; i < bigvec.size(); ++i) { + int val = t[i + 1]; + REQUIRE(val == bigvec[i]); + } +} + +TEST_CASE("tables/raw set and raw get", "ensure raw setting and getting works through metatables") { + sol::state lua; + sol::table t = lua.create_table(); + t[sol::metatable_key] = lua.create_table_with(sol::meta_function::new_index, + [](lua_State* L) { return luaL_error(L, "nay"); }, + sol::meta_function::index, + [](lua_State* L) { return luaL_error(L, "nay"); }); + t.raw_set("a", 2.5); + double la = t.raw_get("a"); + REQUIRE(la == 2.5); +} + +TEST_CASE("tables/boolean keys", "make sure boolean keys don't get caught up in `is_integral` specializations") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.safe_script(R"( +tbl = {} +tbl[true] = 10 +tbl[1] = 20 + +print(tbl[true]) +print(tbl[1]) +)"); + sol::table tbl = lua["tbl"]; + int v1 = tbl[true]; + int v2 = tbl[1]; + REQUIRE(v1 == 10); + REQUIRE(v2 == 20); + + tbl[true] = 30; + tbl[1] = 40; + v1 = tbl[true]; + v2 = tbl[1]; + REQUIRE(v1 == 30); + REQUIRE(v2 == 40); +} + +TEST_CASE("tables/optional move", "ensure pushing a sol::optional rvalue correctly moves the contained object into tables") { + sol::state sol_state; + struct move_only { + int secret_code; + move_only(int sc) : secret_code(sc) {} + + move_only(const move_only&) = delete; + move_only(move_only&&) = default; + move_only& operator=(const move_only&) = delete; + move_only& operator=(move_only&&) = default; + }; + sol_state["requires_move"] = sol::optional(move_only(0x4D)); + REQUIRE(sol_state["requires_move"].get().secret_code == 0x4D); +} diff --git a/lib/sol2/tests/runtime_tests/source/tables.enums.cpp b/lib/sol2/tests/runtime_tests/source/tables.enums.cpp new file mode 100644 index 0000000..0e08140 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/tables.enums.cpp @@ -0,0 +1,90 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +enum weak_direction { up, down, left, right }; +enum class strong_direction { up, down, left, right }; + +TEST_CASE("tables/as enums", "Making sure enums can be put in and gotten out as values") { + + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua["strong_direction"] + = lua.create_table_with("up", weak_direction::up, "down", weak_direction::down, "left", weak_direction::left, "right", weak_direction::right); + + sol::object obj = lua["strong_direction"]["up"]; + bool isdir = obj.is(); + REQUIRE(isdir); + auto dir = obj.as(); + REQUIRE(dir == weak_direction::up); +} + +TEST_CASE("tables/as enum classes", "Making sure enums can be put in and gotten out as values") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua["strong_direction"] + = lua.create_table_with("up", strong_direction::up, "down", strong_direction::down, "left", strong_direction::left, "right", strong_direction::right); + + sol::object obj = lua["strong_direction"]["up"]; + bool isdir = obj.is(); + REQUIRE(isdir); + auto dir = obj.as(); + REQUIRE(dir == strong_direction::up); +} + +TEST_CASE("tables/new_enum", "Making sure enums can be put in and gotten out as values") { + enum class strong_direction { up, down, left, right }; + + SECTION("variadics") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_enum("strong_direction", "up", strong_direction::up, "down", strong_direction::down, "left", strong_direction::left, "right", strong_direction::right); + + strong_direction d = lua["strong_direction"]["left"]; + REQUIRE(d == strong_direction::left); + auto result = lua.safe_script("strong_direction.left = 50", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + d = lua["strong_direction"]["left"]; + REQUIRE(d == strong_direction::left); + } + SECTION("initializer_list") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_enum( + "strong_direction", { { "up", strong_direction::up }, { "down", strong_direction::down }, { "left", strong_direction::left }, { "right", strong_direction::right } }); + + strong_direction d = lua["strong_direction"]["left"]; + REQUIRE(d == strong_direction::left); + auto result = lua.safe_script("strong_direction.left = 50", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + d = lua["strong_direction"]["left"]; + REQUIRE(d == strong_direction::left); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/tables.indexing.cpp b/lib/sol2/tests/runtime_tests/source/tables.indexing.cpp new file mode 100644 index 0000000..ca97500 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/tables.indexing.cpp @@ -0,0 +1,151 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +int plop_xyz(int x, int y, std::string z) { + INFO(x << " " << y << " " << z); + return 11; +} + +TEST_CASE("tables/operator[]", "Check if operator[] retrieval and setting works properly") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.safe_script("foo = 20\nbar = \"hello world\""); + // basic retrieval + std::string bar = lua["bar"]; + int foo = lua["foo"]; + REQUIRE(bar == "hello world"); + REQUIRE(foo == 20); + // test operator= for stringification + // errors due to ambiguous operators + bar = lua["bar"]; + + // basic setting + lua["bar"] = 20.4; + lua["foo"] = "goodbye"; + + // doesn't modify the actual values obviously. + REQUIRE(bar == "hello world"); + REQUIRE(foo == 20); + + // function setting + lua["test"] = plop_xyz; + { + auto result = lua.safe_script("assert(test(10, 11, \"hello\") == 11)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + + // function retrieval + sol::function test = lua["test"]; + REQUIRE(test.call(10, 11, "hello") == 11); + + // setting a lambda + lua["lamb"] = [](int x) { return x * 2; }; + + { + auto result = lua.safe_script("assert(lamb(220) == 440)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + + // function retrieval of a lambda + sol::function lamb = lua["lamb"]; + REQUIRE(lamb.call(220) == 440); + + // test const table retrieval + auto assert1 = [](const sol::table& t) { + std::string a = t["foo"]; + double b = t["bar"]; + REQUIRE(a == "goodbye"); + REQUIRE(b == 20.4); + }; + + REQUIRE_NOTHROW(assert1(lua.globals())); +} + +TEST_CASE("tables/operator[] valid", "Test if proxies on tables can lazily evaluate validity") { + sol::state lua; + bool isFullScreen = false; + auto fullscreennopers = lua["fullscreen"]["nopers"]; + auto fullscreen = lua["fullscreen"]; + REQUIRE_FALSE(fullscreennopers.valid()); + REQUIRE_FALSE(fullscreen.valid()); + + lua["fullscreen"] = true; + + REQUIRE_FALSE(fullscreennopers.valid()); + REQUIRE(fullscreen.valid()); + isFullScreen = lua["fullscreen"]; + REQUIRE(isFullScreen); + + lua["fullscreen"] = false; + REQUIRE_FALSE(fullscreennopers.valid()); + REQUIRE(fullscreen.valid()); + isFullScreen = lua["fullscreen"]; + REQUIRE_FALSE(isFullScreen); +} + +TEST_CASE("tables/operator[] optional", "Test if proxies on tables can lazily evaluate validity") { + sol::state lua; + + sol::optional test1 = lua["no_exist_yet"]; + bool present = (bool)test1; + REQUIRE_FALSE(present); + + lua["no_exist_yet"] = 262; + sol::optional test2 = lua["no_exist_yet"]; + present = (bool)test2; + REQUIRE(present); + REQUIRE(test2.value() == 262); + + sol::optional nope = lua["nope"]["kek"]["hah"]; + auto nope2 = lua.get>(std::make_tuple("nope", "kek", "hah")); + present = (bool)nope; + REQUIRE_FALSE(present); + present = (bool)nope2; + REQUIRE_FALSE(present); + lua.create_named_table("nope", "kek", lua.create_table_with("hah", 1)); + sol::optional non_nope = lua["nope"]["kek"]["hah"].get>(); + sol::optional non_nope2 = lua.get>(std::make_tuple("nope", "kek", "hah")); + present = (bool)non_nope; + REQUIRE(present); + present = (bool)non_nope2; + REQUIRE(present); + REQUIRE(non_nope.value() == 1); + REQUIRE(non_nope2.value() == 1); + + INFO("Keys: nope, kek, hah"); + lua.set(std::make_tuple("nope", "kek", "hah"), 35); + sol::optional non_nope3 = lua["nope"]["kek"]["hah"].get>(); + sol::optional non_nope4 = lua.get>(std::make_tuple("nope", "kek", "hah")); + present = (bool)non_nope3; + REQUIRE(present); + present = (bool)non_nope4; + REQUIRE(present); + REQUIRE(non_nope3.value() == 35); + REQUIRE(non_nope4.value() == 35); +} + diff --git a/lib/sol2/tests/runtime_tests/source/tables.insertion.cpp b/lib/sol2/tests/runtime_tests/source/tables.insertion.cpp new file mode 100644 index 0000000..b16b9dd --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/tables.insertion.cpp @@ -0,0 +1,195 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include + +TEST_CASE("tables/proxy override_value", "allow override_value by way of key") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base, sol::lib::io); + + sol::optional not_there = lua["a"]["b"]["c"]; + REQUIRE_FALSE(static_cast(not_there)); + lua["a"].force()["b"].force()["c"] = 357; + sol::optional totally_there = lua["a"]["b"]["c"]; + REQUIRE(static_cast(totally_there)); + REQUIRE(*totally_there == 357); +} + +TEST_CASE("tables/insertion override", "allow override all non-table values plus final value") { + SECTION("traverse") { + sol::state lua; + sol::stack_guard luasg(lua); + + sol::optional not_there = lua["a"]["b"]["c"]; + REQUIRE_FALSE(static_cast(not_there)); + lua.traverse_set(sol::override_value, "a", "b", "c", 357); + sol::optional totally_there = lua["a"]["b"]["c"]; + REQUIRE(static_cast(totally_there)); + REQUIRE(*totally_there == 357); + + lua.traverse_set(sol::override_value, "a", "b", 500); + sol::optional b_totally_there = lua["a"]["b"]; + sol::optional totally_not_there = lua["a"]["b"]["c"]; + REQUIRE(static_cast(b_totally_there)); + REQUIRE(*b_totally_there == 500); + REQUIRE_FALSE(static_cast(totally_not_there)); + } + SECTION("proxy") { + sol::state lua; + sol::stack_guard luasg(lua); + + sol::optional not_there = lua["a"]["b"]["c"]; + REQUIRE_FALSE(static_cast(not_there)); + lua[sol::override_value]["a"]["b"]["c"] = 357; + sol::optional totally_there = lua["a"]["b"]["c"]; + REQUIRE(static_cast(totally_there)); + REQUIRE(*totally_there == 357); + + lua[sol::override_value]["a"]["b"] = 500; + sol::optional b_totally_there = lua["a"]["b"]; + sol::optional totally_not_there = lua["a"]["b"]["c"]; + REQUIRE(static_cast(b_totally_there)); + REQUIRE(*b_totally_there == 500); + REQUIRE_FALSE(static_cast(totally_not_there)); + } + SECTION("complex proxy") { + sol::state lua; + sol::stack_guard luasg(lua); + + sol::optional not_there = lua["a"]["b"]["c"]; + REQUIRE_FALSE(static_cast(not_there)); + int definitely_there = (lua[sol::override_value]["a"]["b"]["c"] = 357); + sol::optional totally_there = lua["a"]["b"]["c"]; + REQUIRE(static_cast(totally_there)); + REQUIRE(*totally_there == definitely_there); + REQUIRE(*totally_there == 357); + REQUIRE(definitely_there == 357); + } +} + +TEST_CASE("tables/insertion update_if_empty", "allow updating a value only if it's missing") { + SECTION("traverse") { + sol::state lua; + sol::stack_guard luasg(lua); + + sol::optional not_there = lua["a"]["b"]["c"]; + REQUIRE_FALSE(static_cast(not_there)); + lua.traverse_set(sol::update_if_empty, "a", "b", "c", 357); + sol::optional totally_there = lua["a"]["b"]["c"]; + REQUIRE(static_cast(totally_there)); + REQUIRE(*totally_there == 357); + } + SECTION("proxy") { + sol::state lua; + sol::stack_guard luasg(lua); + + sol::optional not_there = lua["a"]["b"]["c"]; + REQUIRE_FALSE(static_cast(not_there)); + lua[sol::update_if_empty]["a"]["b"]["c"] = 357; + sol::optional totally_there = lua["a"]["b"]["c"]; + REQUIRE(static_cast(totally_there)); + REQUIRE(*totally_there == 357); + + lua[sol::update_if_empty]["a"]["b"]["c"] = 500; + sol::optional totally_there_still = lua["a"]["b"]["c"]; + REQUIRE(static_cast(totally_there_still)); + REQUIRE(*totally_there_still == 357); + } + SECTION("proxy invoker") { + sol::state lua; + sol::stack_guard luasg(lua); + + sol::optional not_there = lua["a"]["b"]["c"]; + REQUIRE_FALSE(static_cast(not_there)); + lua[sol::update_if_empty]["a"]["b"]["c"] = sol::push_invoke([]() { return 357; }); + sol::optional totally_there = lua["a"]["b"]["c"]; + REQUIRE(static_cast(totally_there)); + REQUIRE(*totally_there == 357); + + lua[sol::update_if_empty]["a"]["b"]["c"] = sol::push_invoke([]() { return 1000; }); + sol::optional totally_there_still = lua["a"]["b"]["c"]; + REQUIRE(static_cast(totally_there_still)); + REQUIRE(*totally_there_still == 357); + } +} + +TEST_CASE("tables/get create_if_nil", "create tables all the way down") { + SECTION("traverse non-optional") { + sol::state lua; + sol::stack_guard luasg_outer(lua); + + { + sol::stack_guard luasg_inner_1(lua); + sol::optional not_there = lua["a"]["b"]["c"]; + REQUIRE_FALSE(static_cast(not_there)); + } + { + sol::stack_guard luasg_inner_2(lua); + sol::table totally_created = lua.traverse_get(sol::create_if_nil, "a", "b", "c"); + REQUIRE(totally_created.size() == 0); + } + } + SECTION("traverse") { + sol::state lua; + sol::stack_guard luasg(lua); + + sol::optional not_there = lua["a"]["b"]["c"]; + REQUIRE_FALSE(static_cast(not_there)); + sol::optional totally_created = lua.traverse_get>(sol::create_if_nil, "a", "b", "c"); + sol::optional totally_there = lua["a"]["b"]["c"]; + REQUIRE(static_cast(totally_created)); + REQUIRE(static_cast(totally_there)); + } + SECTION("proxy non-optional") { + sol::state lua; + sol::stack_guard luasg_outer(lua); + + { + sol::stack_guard luasg_inner_1(lua); + sol::optional not_there = lua["a"]["b"]["c"]; + REQUIRE_FALSE(static_cast(not_there)); + } + { + sol::stack_guard luasg_inner_2(lua); + sol::table totally_created = lua[sol::create_if_nil]["a"]["b"]["c"]; + REQUIRE(totally_created.size() == 0); + } + } + + SECTION("proxy") { + sol::state lua; + sol::stack_guard luasg(lua); + + sol::optional not_there = lua["a"]["b"]["c"]; + REQUIRE_FALSE(static_cast(not_there)); + sol::optional totally_created = lua[sol::create_if_nil]["a"]["b"]["c"]; + sol::optional totally_there = lua["a"]["b"]["c"]; + REQUIRE(static_cast(totally_created)); + REQUIRE(static_cast(totally_there)); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/tables.traversal.cpp b/lib/sol2/tests/runtime_tests/source/tables.traversal.cpp new file mode 100644 index 0000000..94b2085 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/tables.traversal.cpp @@ -0,0 +1,202 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +TEST_CASE("tables/for_each", "Testing the use of for_each to get values from a lua table") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.safe_script( + "arr = {\n" + "[0] = \"Hi\",\n" + "[1] = 123.45,\n" + "[2] = \"String value\",\n" + // Does nothing + //"[3] = nil,\n" + //"[nil] = 3,\n" + "[\"WOOF\"] = 123,\n" + "}"); + sol::table tbl = lua["arr"]; + std::size_t tablesize = 4; + std::size_t iterations = 0; + auto fx = [&iterations](sol::object key, sol::object value) { + ++iterations; + sol::type keytype = key.get_type(); + switch (keytype) { + case sol::type::number: + switch (key.as()) { + case 0: + REQUIRE((value.as() == "Hi")); + break; + case 1: + REQUIRE((value.as() == 123.45)); + break; + case 2: + REQUIRE((value.as() == "String value")); + break; + case 3: + REQUIRE((value.is())); + break; + } + break; + case sol::type::string: + if (key.as() == "WOOF") { + REQUIRE((value.as() == 123)); + } + break; + case sol::type::lua_nil: + REQUIRE((value.as() == 3)); + break; + default: + break; + } + }; + auto fxpair = [&fx](std::pair kvp) { fx(kvp.first, kvp.second); }; + tbl.for_each(fx); + REQUIRE(iterations == tablesize); + + iterations = 0; + tbl.for_each(fxpair); + REQUIRE(iterations == tablesize); +} + +TEST_CASE("tables/for_each empty", "empty tables should not crash") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.safe_script("arr = {}"); + sol::table tbl = lua["arr"]; + REQUIRE(tbl.empty()); + std::size_t tablesize = 0; + std::size_t iterations = 0; + auto fx = [&iterations](sol::object key, sol::object value) { + ++iterations; + sol::type keytype = key.get_type(); + switch (keytype) { + case sol::type::number: + switch (key.as()) { + case 0: + REQUIRE((value.as() == "Hi")); + break; + case 1: + REQUIRE((value.as() == 123.45)); + break; + case 2: + REQUIRE((value.as() == "String value")); + break; + case 3: + REQUIRE((value.is())); + break; + } + break; + case sol::type::string: + if (key.as() == "WOOF") { + REQUIRE((value.as() == 123)); + } + break; + case sol::type::lua_nil: + REQUIRE((value.as() == 3)); + break; + default: + break; + } + }; + auto fxpair = [&fx](std::pair kvp) { fx(kvp.first, kvp.second); }; + tbl.for_each(fx); + REQUIRE(iterations == tablesize); + + iterations = 0; + tbl.for_each(fxpair); + REQUIRE(iterations == tablesize); + + iterations = 0; + for (const auto& kvp : tbl) { + fxpair(kvp); + ++iterations; + } + REQUIRE(iterations == tablesize); +} + +TEST_CASE("tables/iterators", "Testing the use of iteratrs to get values from a lua table") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.safe_script( + "arr = {\n" + "[0] = \"Hi\",\n" + "[1] = 123.45,\n" + "[2] = \"String value\",\n" + // Does nothing + //"[3] = nil,\n" + //"[nil] = 3,\n" + "[\"WOOF\"] = 123,\n" + "}"); + sol::table tbl = lua["arr"]; + std::size_t tablesize = 4; + std::size_t iterations = 0; + + int begintop = 0; + int endtop = 0; + { + test_stack_guard s(lua.lua_state(), begintop, endtop); + for (auto& kvp : tbl) { + [&iterations](sol::object key, sol::object value) { + ++iterations; + sol::type keytype = key.get_type(); + switch (keytype) { + case sol::type::number: + switch (key.as()) { + case 0: + REQUIRE((value.as() == "Hi")); + break; + case 1: + REQUIRE((value.as() == 123.45)); + break; + case 2: + REQUIRE((value.as() == "String value")); + break; + case 3: + REQUIRE((value.is())); + break; + } + break; + case sol::type::string: + if (key.as() == "WOOF") { + REQUIRE((value.as() == 123)); + } + break; + case sol::type::lua_nil: + REQUIRE((value.as() == 3)); + break; + default: + break; + } + }(kvp.first, kvp.second); + } + } + REQUIRE(begintop == endtop); + REQUIRE(iterations == tablesize); +} diff --git a/lib/sol2/tests/runtime_tests/source/usertypes.basic.cpp b/lib/sol2/tests/runtime_tests/source/usertypes.basic.cpp new file mode 100644 index 0000000..4bbca99 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/usertypes.basic.cpp @@ -0,0 +1,291 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include "common_classes.hpp" + +#include + + +TEST_CASE("usertype/usertype", "Show that we can create classes from usertype and use them") { + sol::state lua; + sol::stack_guard luasg(lua); + + sol::usertype lc = lua.new_usertype("fuser", "add", &fuser::add, "add2", &fuser::add2); + + lua.safe_script( + "a = fuser:new()\n" + "b = a:add(1)\n" + "c = a:add2(1)\n"); + + sol::object a = lua.get("a"); + sol::object b = lua.get("b"); + sol::object c = lua.get("c"); + REQUIRE((a.is())); + auto atype = a.get_type(); + auto btype = b.get_type(); + auto ctype = c.get_type(); + REQUIRE((atype == sol::type::userdata)); + REQUIRE((btype == sol::type::number)); + REQUIRE((ctype == sol::type::number)); + int bresult = b.as(); + int cresult = c.as(); + REQUIRE(bresult == 1); + REQUIRE(cresult == 3); +} + +TEST_CASE("usertype/usertype fundamentals", "Verify new_usertype registers basic member functions and a constructor") { + sol::state lua; + sol::stack_guard luasg(lua); + + lua.new_usertype("fuser", "add", &fuser::add, "add2", &fuser::add2); + + lua.safe_script( + "a = fuser.new()\n" + "b = a:add(1)\n" + "c = a:add2(1)\n"); + + sol::object a = lua.get("a"); + sol::object b = lua.get("b"); + sol::object c = lua.get("c"); + REQUIRE((a.is())); + auto atype = a.get_type(); + auto btype = b.get_type(); + auto ctype = c.get_type(); + REQUIRE((atype == sol::type::userdata)); + REQUIRE((btype == sol::type::number)); + REQUIRE((ctype == sol::type::number)); + int bresult = b.as(); + int cresult = c.as(); + REQUIRE(bresult == 1); + REQUIRE(cresult == 3); +} + +TEST_CASE("usertype/safety", "crash with an exception -- not a segfault -- on bad userdata calls") { + class Test { + public: + void sayHello() { + std::cout << "Hey\n"; + } + }; + + sol::state lua; + lua.new_usertype("Test", "sayHello", &Test::sayHello); + static const std::string code = R"( + local t = Test.new() + t:sayHello() --Works fine + t.sayHello() --Uh oh. + )"; + auto result = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); +} + +TEST_CASE("regressions/one", "issue number 48") { + sol::state lua; + lua.new_usertype("vars", "boop", &vars::boop); + auto code + = "beep = vars.new()\n" + "beep.boop = 1"; + auto result1 = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE(result1.valid()); + // test for segfault + auto my_var = lua.get("beep"); + auto& my_var_ref = lua.get("beep"); + auto* my_var_ptr = lua.get("beep"); + REQUIRE(my_var.boop == 1); + REQUIRE(my_var_ref.boop == 1); + REQUIRE(my_var_ptr->boop == 1); + REQUIRE(std::addressof(my_var_ref) == my_var_ptr); + std::cout << "----- end of 3" << std::endl; +} + +TEST_CASE("usertype/issue-number-twenty-five", "Using pointers and references from C++ classes in Lua") { + struct test { + int x = 0; + test& set() { + x = 10; + return *this; + } + + int get() { + return x; + } + + test* pget() { + return this; + } + + test create_get() { + return *this; + } + + int fun(int xa) { + return xa * 10; + } + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + lua.new_usertype("test", "set", &test::set, "get", &test::get, "pointer_get", &test::pget, "fun", &test::fun, "create_get", &test::create_get); + { + auto result = lua.safe_script("x = test.new()", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(x:set():get() == 10)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("y = x:pointer_get()", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("y:set():get()", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("y:fun(10)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("x:fun(10)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(y:fun(10) == x:fun(10), '...')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(y:fun(10) == 100, '...')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(y:set():get() == y:set():get(), '...')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(y:set():get() == 10, '...')", sol::script_pass_on_error); + REQUIRE(result.valid()); + } +} + +TEST_CASE("usertype/issue-number-thirty-five", "using value types created from lua-called C++ code, fixing user-defined types with constructors") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + sol::constructors> ctor; + lua.new_usertype("Vec", ctor, "normalized", &Vec::normalized, "length", &Vec::length); + + { + auto result = lua.safe_script( + "v = Vec.new(1, 2, 3)\n" + "print(v:length())"); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script( + "v = Vec.new(1, 2, 3)\n" + "print(v:normalized():length())"); + REQUIRE(result.valid()); + } +} + +TEST_CASE("usertype/lua-stored-usertype", "ensure usertype values can be stored without keeping usertype object alive") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + { + sol::constructors> ctor; + sol::usertype udata = lua.new_usertype("Vec", ctor, "normalized", &Vec::normalized, "length", &Vec::length); + // usertype dies, but still usable in lua! + } + + { + auto result = lua.safe_script( + "collectgarbage()\n" + "v = Vec.new(1, 2, 3)\n" + "print(v:length())"); + REQUIRE(result.valid()); + } + + { + auto result = lua.safe_script( + "v = Vec.new(1, 2, 3)\n" + "print(v:normalized():length())"); + REQUIRE(result.valid()); + } +} + +TEST_CASE("usertype/get-set-references", "properly get and set with std::ref semantics. Note that to get, we must not use Unqualified on the type...") { + std::cout << "----- in 4" << std::endl; + sol::state lua; + + lua.new_usertype("vars", "boop", &vars::boop); + vars var{}; + vars rvar{}; + std::cout << "setting beep" << std::endl; + lua.set("beep", var); + std::cout << "setting rbeep" << std::endl; + lua.set("rbeep", std::ref(rvar)); + std::cout << "getting my_var" << std::endl; + auto& my_var = lua.get("beep"); + std::cout << "setting rbeep" << std::endl; + auto& ref_var = lua.get>("rbeep"); + vars& proxy_my_var = lua["beep"]; + std::reference_wrapper proxy_ref_var = lua["rbeep"]; + var.boop = 2; + rvar.boop = 5; + + // Was return as a value: var must be diferent from "beep" + REQUIRE_FALSE(std::addressof(var) == std::addressof(my_var)); + REQUIRE_FALSE(std::addressof(proxy_my_var) == std::addressof(var)); + REQUIRE((my_var.boop == 0)); + REQUIRE(var.boop != my_var.boop); + + REQUIRE(std::addressof(ref_var) == std::addressof(rvar)); + REQUIRE(std::addressof(proxy_ref_var.get()) == std::addressof(rvar)); + REQUIRE(rvar.boop == 5); + REQUIRE(rvar.boop == ref_var.boop); + std::cout << "----- end of 4" << std::endl; +} + +TEST_CASE("usertype/const-pointer", "Make sure const pointers can be taken") { + struct A_x { + int x = 201; + }; + struct B_foo { + int foo(const A_x* a) { + return a->x; + }; + }; + + sol::state lua; + lua.new_usertype("B", "foo", &B_foo::foo); + lua.set("a", A_x()); + lua.set("b", B_foo()); + lua.safe_script("x = b:foo(a)"); + int x = lua["x"]; + REQUIRE(x == 201); + std::cout << "----- end of 6" << std::endl; +} diff --git a/lib/sol2/tests/runtime_tests/source/usertypes.constructors.cpp b/lib/sol2/tests/runtime_tests/source/usertypes.constructors.cpp new file mode 100644 index 0000000..b85f165 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/usertypes.constructors.cpp @@ -0,0 +1,206 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include "common_classes.hpp" + +#include + + +struct matrix_xf { + float a, b; + + static matrix_xf from_lua_table(sol::table t) { + matrix_xf m; + m.a = t[1][1]; + m.b = t[1][2]; + return m; + } +}; + +struct matrix_xi { + int a, b; + + static matrix_xi from_lua_table(sol::table t) { + matrix_xi m; + m.a = t[1][1]; + m.b = t[1][2]; + return m; + } +}; + +TEST_CASE("usertype/call_constructor", "make sure lua types can be constructed with function call constructors") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("thing", "v", &thing::v, sol::call_constructor, sol::constructors, sol::types>()); + + lua.safe_script(R"( +t = thing(256) +)"); + + thing& y = lua["t"]; + INFO(y.v); + REQUIRE(y.v == 256); +} + +TEST_CASE("usertype/call_constructor factories", "make sure tables can be passed to factory-based call constructors") { + sol::state lua; + lua.open_libraries(); + + lua.new_usertype("mat", sol::call_constructor, sol::factories(&matrix_xf::from_lua_table)); + + lua.safe_script("m = mat{ {1.1, 2.2} }"); + + lua.new_usertype("mati", sol::call_constructor, sol::factories(&matrix_xi::from_lua_table)); + + lua.safe_script("mi = mati{ {1, 2} }"); + + matrix_xf& m = lua["m"]; + REQUIRE(m.a == 1.1f); + REQUIRE(m.b == 2.2f); + matrix_xi& mi = lua["mi"]; + REQUIRE(mi.a == 1); + REQUIRE(mi.b == 2); +} + +TEST_CASE("usertype/call_constructor metatable check", "prevent metatable regression") { + class class01 { + public: + int x = 57; + class01() { + } + }; + + class class02 { + public: + int x = 50; + class02() { + } + class02(const class01& other) : x(other.x) { + } + }; + + sol::state lua; + + lua.new_usertype("class01", sol::call_constructor, sol::constructors, sol::types>()); + + lua.new_usertype("class02", sol::call_constructor, sol::constructors, sol::types, sol::types>()); + + REQUIRE_NOTHROW(lua.safe_script(R"( +x = class01() +y = class02(x) +)")); + class02& y = lua["y"]; + REQUIRE(y.x == 57); +} + +TEST_CASE("usertype/blank_constructor", "make sure lua types cannot be constructed with arguments if a blank / empty constructor is provided") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("thing", "v", &thing::v, sol::call_constructor, sol::constructors<>()); + + auto result = lua.safe_script("t = thing(256)", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); +} + +TEST_CASE("usertype/no_constructor", "make sure lua types cannot be constructed if a blank / empty constructor is provided") { + SECTION("order1") { + sol::state lua; + lua.open_libraries(sol::lib::base); + lua.new_usertype("thing", "v", &thing::v, sol::call_constructor, sol::no_constructor); + auto result = lua.safe_script("t = thing()", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } + + SECTION("order2") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("thing", sol::call_constructor, sol::no_constructor, "v", &thing::v); + auto result = lua.safe_script("t = thing.new()", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } + + SECTION("new no_constructor") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("thing", sol::meta_function::construct, sol::no_constructor); + auto result = lua.safe_script("t = thing.new()", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } + + SECTION("call no_constructor") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("thing", sol::call_constructor, sol::no_constructor); + auto result = lua.safe_script("t = thing()", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } +} + +TEST_CASE("usertype/constructor list", "Show that we can create classes from usertype and use them with multiple constructors") { + + sol::state lua; + + sol::constructors, sol::types, sol::types> con; + sol::usertype lc = lua.new_usertype("fuser", con, "add", &crapola::fuser::add, "add2", &crapola::fuser::add2); + + lua.safe_script( + "a = fuser.new(2)\n" + "u = a:add(1)\n" + "v = a:add2(1)\n" + "b = fuser:new()\n" + "w = b:add(1)\n" + "x = b:add2(1)\n" + "c = fuser.new(2, 3)\n" + "y = c:add(1)\n" + "z = c:add2(1)\n"); + sol::object a = lua.get("a"); + auto atype = a.get_type(); + REQUIRE((atype == sol::type::userdata)); + sol::object u = lua.get("u"); + sol::object v = lua.get("v"); + REQUIRE((u.as() == 3)); + REQUIRE((v.as() == 5)); + + sol::object b = lua.get("b"); + auto btype = b.get_type(); + REQUIRE((btype == sol::type::userdata)); + sol::object w = lua.get("w"); + sol::object x = lua.get("x"); + REQUIRE((w.as() == 1)); + REQUIRE((x.as() == 3)); + + sol::object c = lua.get("c"); + auto ctype = c.get_type(); + REQUIRE((ctype == sol::type::userdata)); + sol::object y = lua.get("y"); + sol::object z = lua.get("z"); + REQUIRE((y.as() == 7)); + REQUIRE((z.as() == 9)); +} diff --git a/lib/sol2/tests/runtime_tests/source/usertypes.cpp b/lib/sol2/tests/runtime_tests/source/usertypes.cpp new file mode 100644 index 0000000..4edeee4 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/usertypes.cpp @@ -0,0 +1,234 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include "common_classes.hpp" + +#include + +#include +#include +#include + +struct self_test { + int bark; + + self_test() + : bark(100) { + } + + void g(const std::string& str) { + std::cout << str << '\n'; + bark += 1; + } + + void f(const self_test& t) { + std::cout << "got test" << '\n'; + if (t.bark != bark) + throw sol::error("bark values are not the same for self_test f function"); + if (&t != this) + throw sol::error("call does not reference self for self_test f function"); + } +}; + +TEST_CASE("usertype/self-referential usertype", "usertype classes must play nice when C++ object types are requested for C++ code") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + lua.new_usertype("test", "g", &self_test::g, "f", &self_test::f); + + auto result = lua.safe_script( + "local a = test.new()\n" + "a:g(\"woof\")\n" + "a:f(a)\n", + sol::script_pass_on_error); + REQUIRE(result.valid()); +} + +TEST_CASE("usertype/nonmember-functions", "let users set non-member functions that take unqualified T as first parameter to usertype") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + lua.new_usertype("giver", + "gief_stuff", giver::gief_stuff, + "gief", &giver::gief, + "__tostring", [](const giver& t) { + return std::to_string(t.a) + ": giving value"; + }); + lua.get("giver").set_function("stuff", giver::stuff); + + { + auto result = lua.safe_script("assert(giver.stuff() == 97)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script( + "t = giver.new()\n" + "print(tostring(t))\n" + "t:gief()\n" + "t:gief_stuff(20)\n", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + giver& g = lua.get("t"); + REQUIRE(g.a == 20); + std::cout << "----- end of 1" << std::endl; +} + +TEST_CASE("usertype/abstract-base-class", "Ensure that abstract base classes and such can be registered") { + sol::state lua; + sol::stack_guard luasg(lua); + + lua.new_usertype("A", "a", &abstract_A::a); + lua.new_usertype("B", sol::base_classes, sol::bases()); + REQUIRE_NOTHROW([&]() { + lua.safe_script(R"( +local b = B.new() +b:a() + )"); + }); +} + +TEST_CASE("usertype/as_function", "Ensure that variables can be turned into functions by as_function") { + class B { + public: + int bvar = 24; + }; + + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(); + + lua.new_usertype("B", "b", &B::bvar, "f", sol::as_function(&B::bvar)); + + B b; + lua.set("b", &b); + lua.safe_script("x = b:f()"); + lua.safe_script("y = b.b"); + int x = lua["x"]; + int y = lua["y"]; + REQUIRE(x == 24); + REQUIRE(y == 24); +} + +TEST_CASE("usertype/call-initializers", "Ensure call constructors with initializers work well") { + struct A { + double f = 25.5; + + static void init(A& x, double f) { + x.f = f; + } + }; + + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(); + + lua.new_usertype("A", + sol::call_constructor, sol::initializers(&A::init)); + + lua.safe_script(R"( +a = A(24.3) +)"); + A& a = lua["a"]; + REQUIRE(a.f == 24.3); +} + +TEST_CASE("usertype/missing-key", "make sure a missing key returns nil") { + struct thing {}; + + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + lua.new_usertype("thing"); + { + auto result = lua.safe_script("v = thing.missingKey\nprint(v)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + sol::object o = lua["v"]; + bool isnil = o.is(); + REQUIRE(isnil); +} + +TEST_CASE("usertype/basic type information", "check that we can query some basic type information") { + struct my_thing {}; + + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + lua.new_usertype("my_thing"); + + lua.safe_script("obj = my_thing.new()"); + + lua.safe_script("assert(my_thing.__type.is(obj))"); + lua.safe_script("assert(not my_thing.__type.is(1))"); + lua.safe_script("assert(not my_thing.__type.is(\"not a thing\"))"); + lua.safe_script("print(my_thing.__type.name)"); + + lua.safe_script("assert(obj.__type.is(obj))"); + lua.safe_script("assert(not obj.__type.is(1))"); + lua.safe_script("assert(not obj.__type.is(\"not a thing\"))"); + lua.safe_script("print(obj.__type.name)"); + + lua.safe_script("assert(getmetatable(my_thing).__type.is(obj))"); + lua.safe_script("assert(not getmetatable(my_thing).__type.is(1))"); + lua.safe_script("assert(not getmetatable(my_thing).__type.is(\"not a thing\"))"); + lua.safe_script("print(getmetatable(my_thing).__type.name)"); + + lua.safe_script("assert(getmetatable(obj).__type.is(obj))"); + lua.safe_script("assert(not getmetatable(obj).__type.is(1))"); + lua.safe_script("assert(not getmetatable(obj).__type.is(\"not a thing\"))"); + lua.safe_script("print(getmetatable(obj).__type.name)"); +} + +#if !defined(_MSC_VER) || !(defined(_WIN32) && !defined(_WIN64)) + +TEST_CASE("usertype/noexcept-methods", "make sure noexcept functions and methods can be bound to usertypes without issues") { + struct T { + static int noexcept_function() noexcept { + return 0x61; + } + + int noexcept_method() noexcept { + return 0x62; + } + }; + + sol::state lua; + sol::stack_guard luasg(lua); + lua.new_usertype("T", "nf", &T::noexcept_function, "nm", &T::noexcept_method); + + lua.safe_script("t = T.new()"); + lua.safe_script("v1 = t.nf()"); + lua.safe_script("v2 = t:nm()"); + int v1 = lua["v1"]; + int v2 = lua["v2"]; + REQUIRE(v1 == 0x61); + REQUIRE(v2 == 0x62); +} + +#endif // VC++ or my path/compiler settings doing strange bullshit (but it happens on Appveyor too???) diff --git a/lib/sol2/tests/runtime_tests/source/usertypes.inheritance.cpp b/lib/sol2/tests/runtime_tests/source/usertypes.inheritance.cpp new file mode 100644 index 0000000..62d5cf0 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/usertypes.inheritance.cpp @@ -0,0 +1,115 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include "common_classes.hpp" + +#include + +#include + +struct inh_test_A { + int a = 5; +}; + +struct inh_test_B { + int b() { + return 10; + } +}; + +struct inh_test_C : inh_test_B, inh_test_A { + double c = 2.4; +}; + +struct inh_test_D : inh_test_C { + bool d() const { + return true; + } +}; + +SOL_BASE_CLASSES(inh_test_D, inh_test_C); +SOL_BASE_CLASSES(inh_test_C, inh_test_B, inh_test_A); +SOL_DERIVED_CLASSES(inh_test_C, inh_test_D); +SOL_DERIVED_CLASSES(inh_test_B, inh_test_C); +SOL_DERIVED_CLASSES(inh_test_A, inh_test_B); + +TEST_CASE("inheritance/basic", "test that metatables are properly inherited") { + sol::state lua; + int begintop = 0, endtop = 0; + lua.new_usertype("A", "a", &inh_test_A::a); + lua.new_usertype("B", "b", &inh_test_B::b); + lua.new_usertype("C", "c", &inh_test_C::c, sol::base_classes, sol::bases()); + lua.new_usertype("D", "d", &inh_test_D::d, sol::base_classes, sol::bases()); + + test_stack_guard tsg(lua, begintop, endtop); + + auto result1 = lua.safe_script("obj = D.new()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("d = obj:d()", sol::script_pass_on_error); + REQUIRE(result2.valid()); + bool d = lua["d"]; + auto result3 = lua.safe_script("c = obj.c", sol::script_pass_on_error); + REQUIRE(result3.valid()); + double c = lua["c"]; + auto result4 = lua.safe_script("b = obj:b()", sol::script_pass_on_error); + REQUIRE(result4.valid()); + int b = lua["b"]; + auto result5 = lua.safe_script("a = obj.a", sol::script_pass_on_error); + REQUIRE(result5.valid()); + int a = lua["a"]; + + REQUIRE(d); + REQUIRE(c == 2.4); + REQUIRE(b == 10); + REQUIRE(a == 5); +} + +TEST_CASE("inheritance/usertype derived non-hiding", "usertype classes must play nice when a derived class does not overload a publically visible base function") { + sol::state lua; + lua.open_libraries(sol::lib::base); + sol::constructors> basector; + sol::usertype baseusertype = lua.new_usertype("Base", basector, "get_num", &Base::get_num); + + lua.safe_script("base = Base.new(5)"); + { + auto result = lua.safe_script("print(base:get_num())", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + + sol::constructors> derivedctor; + sol::usertype derivedusertype + = lua.new_usertype("Derived", derivedctor, "get_num_10", &Derived::get_num_10, "get_num", &Derived::get_num); + + lua.safe_script("derived = Derived.new(7)"); + lua.safe_script( + "dgn = derived:get_num()\n" + "print(dgn)"); + lua.safe_script( + "dgn10 = derived:get_num_10()\n" + "print(dgn10)"); + + REQUIRE((lua.get("dgn10") == 70)); + REQUIRE((lua.get("dgn") == 7)); +} diff --git a/lib/sol2/tests/runtime_tests/source/usertypes.inheritance.multi.cpp b/lib/sol2/tests/runtime_tests/source/usertypes.inheritance.multi.cpp new file mode 100644 index 0000000..0e39838 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/usertypes.inheritance.multi.cpp @@ -0,0 +1,333 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include "common_classes.hpp" + +#include + +#include + +class TestClass00 { +public: + TestClass00() { + } + + int Thing() const { + return 123; + } +}; + +class TestClass01 : public TestClass00 { +public: + TestClass01() : a(1) { + } + TestClass01(const TestClass00& other) : a(other.Thing()) { + } + + int a; +}; + +class TestClass02 : public TestClass01 { +public: + TestClass02() : b(2) { + } + TestClass02(const TestClass01& other) : b(other.a) { + } + TestClass02(const TestClass00& other) : b(other.Thing()) { + } + + int b; +}; + +class TestClass03 : public TestClass02 { +public: + TestClass03() : c(2) { + } + TestClass03(const TestClass02& other) : c(other.b) { + } + TestClass03(const TestClass01& other) : c(other.a) { + } + TestClass03(const TestClass00& other) : c(other.Thing()) { + } + + int c; +}; + +struct inh_test_A { + int a = 5; +}; + +struct inh_test_B { + int b() { + return 10; + } +}; + +struct inh_test_C : inh_test_B, inh_test_A { + double c = 2.4; +}; + +struct inh_test_D : inh_test_C { + bool d() const { + return true; + } +}; + +SOL_BASE_CLASSES(TestClass03, TestClass02); +SOL_BASE_CLASSES(TestClass02, TestClass01); +SOL_BASE_CLASSES(TestClass01, TestClass00); +SOL_DERIVED_CLASSES(TestClass02, TestClass03); +SOL_DERIVED_CLASSES(TestClass01, TestClass02); +SOL_DERIVED_CLASSES(TestClass00, TestClass01); + +TEST_CASE("inheritance/multi base", "test that multiple bases all work and overloading for constructors works with them") { + + sol::state lua; + + sol::usertype s_TestUsertype00 + = lua.new_usertype("TestClass00", sol::call_constructor, sol::constructors(), "Thing", &TestClass00::Thing); + + sol::usertype s_TestUsertype01 = lua.new_usertype("TestClass01", + sol::call_constructor, + sol::constructors, sol::types>(), + sol::base_classes, + sol::bases(), + "a", + &TestClass01::a); + + sol::usertype s_TestUsertype02 = lua.new_usertype("TestClass02", + sol::call_constructor, + sol::constructors, sol::types, sol::types>(), + sol::base_classes, + sol::bases(), + "b", + &TestClass02::b); + + sol::usertype s_TestUsertype03 = lua.new_usertype("TestClass03", + sol::call_constructor, + sol::constructors, sol::types, sol::types, sol::types>(), + sol::base_classes, + sol::bases(), + "c", + &TestClass03::c); + + auto result1 = lua.safe_script(R"( +tc0 = TestClass00() +tc2 = TestClass02(tc0) +tc1 = TestClass01() +tc3 = TestClass03(tc1) +)", + sol::script_pass_on_error); + REQUIRE(result1.valid()); + + TestClass00& tc0 = lua["tc0"]; + TestClass01& tc1 = lua["tc1"]; + TestClass02& tc2 = lua["tc2"]; + TestClass03& tc3 = lua["tc3"]; + REQUIRE(tc0.Thing() == 123); + REQUIRE(tc1.a == 1); + REQUIRE(tc2.a == 1); + REQUIRE(tc2.b == 123); + REQUIRE(tc3.a == 1); + REQUIRE(tc3.b == 2); + REQUIRE(tc3.c == 1); +} + +TEST_CASE("inheritance/runtime multi base", "test that multiple bases all work and overloading for constructors works with them when just using sol::bases") { + struct runtime_A { + int a = 5; + }; + + struct runtime_B { + int b2 = 46; + + int b() { + return 10; + } + }; + + struct runtime_C : runtime_B, runtime_A { + double c = 2.4; + }; + + struct runtime_D : runtime_C { + bool d() const { + return true; + } + }; + + sol::state lua; + lua.new_usertype("A", "a", &runtime_A::a); + lua.new_usertype("B", "b", &runtime_B::b); + lua.new_usertype("C", "c", &runtime_C::c, sol::base_classes, sol::bases()); + lua.new_usertype("D", "d", &runtime_D::d, sol::base_classes, sol::bases()); + + auto result1 = lua.safe_script("obj = D.new()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("d = obj:d()", sol::script_pass_on_error); + REQUIRE(result2.valid()); + bool d = lua["d"]; + auto result3 = lua.safe_script("c = obj.c", sol::script_pass_on_error); + REQUIRE(result3.valid()); + double c = lua["c"]; + auto result4 = lua.safe_script("b = obj:b()", sol::script_pass_on_error); + REQUIRE(result4.valid()); + int b = lua["b"]; + auto result5 = lua.safe_script("a = obj.a", sol::script_pass_on_error); + REQUIRE(result5.valid()); + int a = lua["a"]; + + REQUIRE(d); + REQUIRE(c == 2.4); + REQUIRE(b == 10); + REQUIRE(a == 5); + + runtime_D& d_obj = lua["obj"]; + REQUIRE(d_obj.d()); + REQUIRE(d_obj.c == 2.4); + REQUIRE(d_obj.b() == 10); + REQUIRE(d_obj.b2 == 46); + REQUIRE(d_obj.a == 5); + runtime_C& c_obj = lua["obj"]; + REQUIRE(c_obj.c == 2.4); + REQUIRE(c_obj.b() == 10); + REQUIRE(c_obj.b2 == 46); + REQUIRE(c_obj.a == 5); + runtime_B& b_obj = lua["obj"]; + REQUIRE(b_obj.b() == 10); + REQUIRE(b_obj.b2 == 46); + runtime_A& a_obj = lua["obj"]; + REQUIRE(a_obj.a == 5); +} + +TEST_CASE("inheritance/bad_base-class", "check to make sure bad/unregistered base classes do not blow up usertypes") { + struct a { + a(sol::this_state ts, sol::this_environment) { + lua_State* L = ts; + ud = sol::userdata(L, -2); + } + + + sol::object get_property_lua(const char* name, sol::this_state) { + return props[name]; + } + + void set_property_lua(const char* name, sol::stack_object object) { + props[name] = object.as(); + } + + std::unordered_map props; + sol::userdata ud; + }; + + struct nofun { + nofun() { + } + }; + + struct b : public a, public nofun { + b(sol::this_state ts, sol::this_environment te, int) : a(ts, te) { + sol::state_view lua = ts; + lua.script("function break_crap(b_obj) b_obj.test3 = {} end"); + + sol::protected_function pf = lua["break_crap"]; + sol::optional result = pf(this); + REQUIRE_FALSE(result.has_value()); + } + + b(sol::this_state ts, sol::this_environment te, int, int) : a(ts, te) { + } + ~b() { + } + }; + + struct c : public b { + c(sol::this_state ts, sol::this_environment te, int ab) : b(ts, te, ab) { + } + + c(sol::this_state ts, sol::this_environment te, int ab, int bc) : b(ts, te, ab, bc) { + } + ~c() { + } + }; + + sol::state lua; + + lua.open_libraries(sol::lib::base, sol::lib::os, sol::lib::string, sol::lib::math, sol::lib::table, sol::lib::package, sol::lib::debug); + + lua.new_usertype("a", sol::meta_function::new_index, &a::set_property_lua, sol::meta_function::index, &a::get_property_lua); + + lua.new_usertype("b", + sol::constructors(), + sol::meta_function::new_index, + &b::set_property_lua, + sol::meta_function::index, + &b::get_property_lua, + sol::base_classes, + sol::bases()); + + + lua.new_usertype("c", + sol::constructors(), + sol::meta_function::new_index, + &c::set_property_lua, + sol::meta_function::index, + &c::get_property_lua, + sol::base_classes, + sol::bases()); + + + lua.script(R"( + function init_entity(e) + init_entity_properties(e) + return true + end + + function init_entity_properties(e) + e._internal_entity_properties_ = {} + + function e : GetName() + return self._internal_entity_properties_['name'] + end + + function e : SetName(s) + self._internal_entity_properties_['name'] = s + end + --return e + end + + )"); + + sol::optional result = lua.safe_script("b_tmp = b.new(1)", sol::script_pass_on_error); + REQUIRE_FALSE(result.has_value()); + + a* b_base = lua["b_tmp"]; // get the base... + sol::protected_function pf = lua["init_entity"]; + sol::optional result1 = pf(b_base); + REQUIRE_FALSE(result1.has_value()); + + sol::optional result2 = lua.script("c_tmp = c.new(1)", sol::script_pass_on_error); + REQUIRE_FALSE(result2.has_value()); +} diff --git a/lib/sol2/tests/runtime_tests/source/usertypes.member_variables.cpp b/lib/sol2/tests/runtime_tests/source/usertypes.member_variables.cpp new file mode 100644 index 0000000..bd21208 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/usertypes.member_variables.cpp @@ -0,0 +1,128 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include "common_classes.hpp" + +#include + + +TEST_CASE("usertype/member-variables", "allow table-like accessors to behave as member variables for usertype") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + sol::constructors> ctor; + sol::usertype udata + = lua.new_usertype("Vec", ctor, "x", &Vec::x, "y", &Vec::y, "z", &Vec::z, "normalized", &Vec::normalized, "length", &Vec::length); + + REQUIRE_NOTHROW( + lua.safe_script("v = Vec.new(1, 2, 3)\n" + "v2 = Vec.new(0, 1, 0)\n" + "print(v:length())\n")); + REQUIRE_NOTHROW( + lua.safe_script("v.x = 2\n" + "v2.y = 2\n" + "print(v.x, v.y, v.z)\n" + "print(v2.x, v2.y, v2.z)\n")); + REQUIRE_NOTHROW( + lua.safe_script("assert(v.x == 2)\n" + "assert(v2.x == 0)\n" + "assert(v2.y == 2)\n")); + REQUIRE_NOTHROW( + lua.safe_script("v.x = 3\n" + "local x = v.x\n" + "assert(x == 3)\n")); + + struct breaks { + sol::function f; + }; + + lua.set("b", breaks()); + lua.new_usertype("breaks", "f", &breaks::f); + + breaks& b = lua["b"]; + { + auto result = lua.safe_script("b.f = function () print('BARK!') end", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("b.f()", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + REQUIRE_NOTHROW(b.f()); +} + +TEST_CASE("usertype/reference-and-constness", "Make sure constness compiles properly and errors out at runtime") { + struct bark { + int var = 50; + }; + struct woof { + bark b; + }; + + struct nested { + const int f = 25; + }; + + struct outer { + nested n; + }; + + sol::state lua; + sol::stack_guard luasg(lua); + + lua.new_usertype("woof", "b", &woof::b); + lua.new_usertype("bark", "var", &bark::var); + lua.new_usertype("outer", "n", &outer::n); + lua.set("w", woof()); + lua.set("n", nested()); + lua.set("o", outer()); + lua.set("f", sol::c_call); + lua.safe_script(R"( + x = w.b + x.var = 20 + val = w.b.var == x.var + v = f(n); + )"); + + woof& w = lua["w"]; + bark& x = lua["x"]; + nested& n = lua["n"]; + int v = lua["v"]; + bool val = lua["val"]; + // enforce reference semantics + REQUIRE(std::addressof(w.b) == std::addressof(x)); + REQUIRE(n.f == 25); + REQUIRE(v == 25); + REQUIRE(val); + + { + auto result = lua.safe_script("f(n, 50)", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } + { + auto result = lua.safe_script("o.n = 25", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/usertypes.overload.cpp b/lib/sol2/tests/runtime_tests/source/usertypes.overload.cpp new file mode 100644 index 0000000..04791e0 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/usertypes.overload.cpp @@ -0,0 +1,91 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include "common_classes.hpp" + +#include + +struct overloading_test { + int print(int i) { + INFO("Integer print: " << i); + return 500 + i; + } + int print() { + INFO("No param print."); + return 500; + } +}; + +TEST_CASE("usertype/overloading", "Check if overloading works properly for usertypes") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + lua.new_usertype("woof", "var", &woof::var, "func", sol::overload(&woof::func, &woof::func2, &woof::func2s)); + + const std::string bark_58 = "bark 58"; + + REQUIRE_NOTHROW( + lua.safe_script("r = woof:new()\n" + "a = r:func(1)\n" + "b = r:func(1, 2)\n" + "c = r:func(58, 'bark')\n")); + REQUIRE((lua["a"] == 1)); + REQUIRE((lua["b"] == 3.5)); + REQUIRE((lua["c"] == bark_58)); + auto result = lua.safe_script("r:func(1,2,'meow')", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + std::cout << "----- end of 7" << std::endl; +} + +TEST_CASE("usertype/overloading_values", "ensure overloads handle properly") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.new_usertype("overloading_test", + sol::constructors<>(), + "print", + sol::overload( + static_cast(&overloading_test::print), static_cast(&overloading_test::print)), + "print2", + sol::overload( + static_cast(&overloading_test::print), static_cast(&overloading_test::print))); + lua.set("test", overloading_test()); + + sol::function f0_0 = lua.load("return test:print()"); + sol::function f0_1 = lua.load("return test:print2()"); + sol::function f1_0 = lua.load("return test:print(24)"); + sol::function f1_1 = lua.load("return test:print2(24)"); + int res = f0_0(); + int res2 = f0_1(); + int res3 = f1_0(); + int res4 = f1_1(); + + REQUIRE(res == 500); + REQUIRE(res2 == 500); + + REQUIRE(res3 == 524); + REQUIRE(res4 == 524); + std::cout << "----- end of 8" << std::endl; +} diff --git a/lib/sol2/tests/runtime_tests/source/usertypes.properties.cpp b/lib/sol2/tests/runtime_tests/source/usertypes.properties.cpp new file mode 100644 index 0000000..3b5df16 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/usertypes.properties.cpp @@ -0,0 +1,610 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// we have a test for weirdly aligned wrappers +// do not make lots of noise about it +#ifdef _MSC_VER +#pragma warning(disable : 4324) +#endif + +#include "sol_test.hpp" + +#include "common_classes.hpp" + +#include + +bool something_func_true() { + return true; +} + +struct ext_getset { + + int bark = 24; + const int meow = 56; + + ext_getset() = default; + ext_getset(int v) : bark(v) { + } + ext_getset(ext_getset&&) = default; + ext_getset(const ext_getset&) = delete; + ext_getset& operator=(ext_getset&&) = delete; + ext_getset& operator=(const ext_getset&) = delete; + ~ext_getset() { + } + + std::string x() { + return "bark bark bark"; + } + + int x2(std::string x) { + return static_cast(x.length()); + } + + void set(sol::variadic_args, sol::this_state, int x) { + bark = x; + } + + int get(sol::this_state, sol::variadic_args) { + return bark; + } + + static void s_set(int) { + } + + static int s_get(int x) { + return x + 20; + } +}; + +template +void des(T& e) { + e.~T(); +} + +template +struct alignas(16) weird_aligned_wrapper { + template , std::nullptr_t> = nullptr> + weird_aligned_wrapper(F&& f) : lambda(std::forward(f)) { + } + void operator()(SelfType& self, sol::object param) const { + lambda(self, param.as()); + } + std::function lambda; +}; + +TEST_CASE("usertype/properties", "Check if member properties/variables work") { + struct bark { + int var = 50; + int var2 = 25; + + int get_var2() const { + return var2; + } + + int get_var3() { + return var2; + } + + void set_var2(int x) { + var2 = x; + } + }; + + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + lua.new_usertype("bark", + "var", + &bark::var, + "var2", + sol::readonly(&bark::var2), + "a", + sol::property(&bark::get_var2, &bark::set_var2), + "b", + sol::property(&bark::get_var2), + "c", + sol::property(&bark::get_var3), + "d", + sol::property(&bark::set_var2)); + + bark b; + lua.set("b", &b); + + lua.safe_script("b.a = 59"); + lua.safe_script("var2_0 = b.a"); + lua.safe_script("var2_1 = b.b"); + lua.safe_script("b.d = 1568"); + lua.safe_script("var2_2 = b.c"); + + int var2_0 = lua["var2_0"]; + int var2_1 = lua["var2_1"]; + int var2_2 = lua["var2_2"]; + REQUIRE(var2_0 == 59); + REQUIRE(var2_1 == 59); + REQUIRE(var2_2 == 1568); + + { + auto result = lua.safe_script("b.var2 = 24", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } + { + auto result = lua.safe_script("r = b.d", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } + { + auto result = lua.safe_script("r = b.d", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } + { + auto result = lua.safe_script("b.b = 25", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } + { + auto result = lua.safe_script("b.c = 11", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } +} + +TEST_CASE("usertype/copyability", "make sure user can write to a class variable even if the class itself isn't copy-safe") { + struct NoCopy { + int get() const { + return _you_can_copy_me; + } + void set(int val) { + _you_can_copy_me = val; + } + + int _you_can_copy_me; + non_copyable _haha_you_cant_copy_me; + }; + + sol::state lua; + sol::stack_guard luasg(lua); + + lua.new_usertype("NoCopy", "val", sol::property(&NoCopy::get, &NoCopy::set)); + + REQUIRE_NOTHROW(lua.safe_script(R"__( +nocopy = NoCopy.new() +nocopy.val = 5 + )__")); +} + +TEST_CASE("usertype/protect", "users should be allowed to manually protect a function") { + struct protect_me { + int gen(int x) { + return x; + } + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + lua.new_usertype("protect_me", "gen", sol::protect(&protect_me::gen)); + + REQUIRE_NOTHROW(lua.safe_script(R"__( +pm = protect_me.new() +value = pcall(pm.gen,pm) +)__")); + bool value = lua["value"]; + REQUIRE_FALSE(value); +} + +TEST_CASE("usertype/static-properties", "allow for static functions to get and set things as a property") { + static int b = 50; + struct test_t { + static double s_func() { + return b + 0.5; + } + + static void g_func(int v) { + b = v; + } + + std::size_t func() { + return 24; + } + }; + test_t manager; + + sol::state lua; + sol::stack_guard luasg(lua); + + lua.new_usertype( + "test", "f", std::function(std::bind(std::mem_fn(&test_t::func), &manager)), "g", sol::property(&test_t::s_func, &test_t::g_func)); + + lua.safe_script("v1 = test.f()"); + lua.safe_script("v2 = test.g"); + lua.safe_script("test.g = 60"); + lua.safe_script("v2a = test.g"); + int v1 = lua["v1"]; + REQUIRE(v1 == 24); + double v2 = lua["v2"]; + REQUIRE(v2 == 50.5); + double v2a = lua["v2a"]; + REQUIRE(v2a == 60.5); +} + +TEST_CASE("usertype/var with string literals", "String literals are the bane of my existence and one day C++ will make them not be fucking arrays") { + struct blah {}; + + sol::state lua; + sol::usertype x = lua.new_usertype("blah"); + x["__className"] = sol::var("Entity"); + + std::string cxx_name = x["__className"]; + std::string lua_name = lua.script("return blah.__className"); + REQUIRE(cxx_name == lua_name); + REQUIRE(cxx_name == "Entity"); + REQUIRE(lua_name == "Entity"); +} + +TEST_CASE("usertype/var-and-property", "make sure const vars are readonly and properties can handle lambdas") { + const static int arf = 20; + + struct test { + int value = 10; + }; + + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(); + + lua.new_usertype( + "test", "prop", sol::property([](test& t) { return t.value; }, [](test& t, int x) { t.value = x; }), "global", sol::var(std::ref(arf))); + + lua.safe_script(R"( +t = test.new() +print(t.prop) +t.prop = 50 +print(t.prop) + )"); + + test& t = lua["t"]; + REQUIRE(t.value == 50); + + lua.safe_script(R"( +t = test.new() +print(t.global) + )"); + { + auto result = lua.safe_script("t.global = 20", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } + lua.safe_script("print(t.global)"); +} + +TEST_CASE("usertype/coverage", "try all the things") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("ext_getset", + sol::call_constructor, + sol::constructors, sol::types>(), + sol::meta_function::garbage_collect, + sol::destructor(des), + "x", + sol::overload(&ext_getset::x, &ext_getset::x2, [](ext_getset& m, std::string x, int y) { return m.meow + 50 + y + x.length(); }), + "bark", + &ext_getset::bark, + "meow", + &ext_getset::meow, + "readonlybark", + sol::readonly(&ext_getset::bark), + "set", + &ext_getset::set, + "get", + &ext_getset::get, + "sset", + &ext_getset::s_set, + "sget", + &ext_getset::s_get, + "propbark", + sol::property(&ext_getset::set, &ext_getset::get), + "readonlypropbark", + sol::property(&ext_getset::get), + "writeonlypropbark", + sol::property(&ext_getset::set)); + + INFO("usertype created"); + + lua.safe_script(R"( +e = ext_getset() +w = e:x(e:x(), e:x(e:x())) +print(w) +)"); + + int w = lua["w"]; + REQUIRE(w == (56 + 50 + 14 + 14)); + + INFO("REQUIRE(w) successful"); + + lua.safe_script(R"( +e:set(500) +e.sset(24) +x = e:get() +y = e.sget(20) +)"); + + int x = lua["x"]; + int y = lua["y"]; + REQUIRE(x == 500); + REQUIRE(y == 40); + + INFO("REQUIRE(x, y) successful"); + + lua.safe_script(R"( +e.bark = 5001 +a = e:get() +print(e.bark) +print(a) + +e.propbark = 9700 +b = e:get() +print(e.propbark) +print(b) +)"); + int a = lua["a"]; + int b = lua["b"]; + + REQUIRE(a == 5001); + REQUIRE(b == 9700); + + INFO("REQUIRE(a, b) successful"); + + lua.safe_script(R"( +c = e.readonlybark +d = e.meow +print(e.readonlybark) +print(c) +print(e.meow) +print(d) +)"); + + int c = lua["c"]; + int d = lua["d"]; + REQUIRE(c == 9700); + REQUIRE(d == 56); + + INFO("REQUIRE(c, d) successful"); + + lua.safe_script(R"( +e.writeonlypropbark = 500 +z = e.readonlypropbark +print(e.readonlybark) +print(e.bark) +)"); + + int z = lua["z"]; + REQUIRE(z == 500); + + INFO("REQUIRE(z) successful"); + { + auto result = lua.safe_script("e.readonlybark = 24", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + INFO("REQUIRE_FALSE 1 successful"); + } + { + auto result = lua.safe_script("e.readonlypropbark = 500", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + INFO("REQUIRE_FALSE 2 successful"); + } + { + auto result = lua.safe_script("y = e.writeonlypropbark", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + INFO("REQUIRE_FALSE 3 successful"); + } +} + +TEST_CASE("usertype/alignment", "ensure that alignment does not trigger weird aliasing issues") { + struct aligned_base {}; + struct aligned_derived : aligned_base {}; + + sol::state lua; + sol::stack_guard luasg(lua); + + auto f = [](aligned_base&, float d) { REQUIRE(d == 5.0f); }; + lua.new_usertype("Base", "x", sol::writeonly_property(weird_aligned_wrapper(std::ref(f)))); + lua.new_usertype("Derived", sol::base_classes, sol::bases()); + + aligned_derived d; + lua["d"] = d; + + auto result = lua.safe_script("d.x = 5"); + REQUIRE(result.valid()); +} + +TEST_CASE("usertype/readonly-and-static-functions", "Check if static functions can be called on userdata and from their originating (meta)tables") { + struct bark { + int var = 50; + + void func() { + } + + static void oh_boy() { + } + + static int oh_boy(std::string name) { + return static_cast(name.length()); + } + + int operator()(int x) { + return x; + } + }; + + sol::state lua; + lua.open_libraries(sol::lib::base); + lua.new_usertype("bark", + "var", + &bark::var, + "var2", + sol::readonly(&bark::var), + "something", + something_func_true, + "something2", + [](int x, int y) { return x + y; }, + "func", + &bark::func, + "oh_boy", + sol::overload(sol::resolve(&bark::oh_boy), sol::resolve(&bark::oh_boy)), + sol::meta_function::call_function, + &bark::operator()); + + { + auto result = lua.safe_script("assert(bark.oh_boy('woo') == 3)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("bark.oh_boy()", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + + bark b; + lua.set("b", &b); + + sol::table b_table = lua["b"]; + sol::function member_func = b_table["func"]; + sol::function s = b_table["something"]; + sol::function s2 = b_table["something2"]; + + sol::table b_metatable = b_table[sol::metatable_key]; + bool isvalidmt = b_metatable.valid(); + REQUIRE(isvalidmt); + sol::function b_call = b_metatable["__call"]; + sol::function b_as_function = lua["b"]; + + int x = b_as_function(1); + int y = b_call(b, 1); + bool z = s(); + int w = s2(2, 3); + REQUIRE(x == 1); + REQUIRE(y == 1); + REQUIRE(z); + REQUIRE(w == 5); + + lua.safe_script(R"( +lx = b(1) +ly = getmetatable(b).__call(b, 1) +lz = b.something() +lz2 = bark.something() +lw = b.something2(2, 3) +lw2 = bark.something2(2, 3) + )"); + + int lx = lua["lx"]; + int ly = lua["ly"]; + bool lz = lua["lz"]; + int lw = lua["lw"]; + bool lz2 = lua["lz2"]; + int lw2 = lua["lw2"]; + REQUIRE(lx == 1); + REQUIRE(ly == 1); + REQUIRE(lz); + REQUIRE(lz2); + REQUIRE(lw == 5); + REQUIRE(lw2 == 5); + REQUIRE(lx == ly); + REQUIRE(lz == lz2); + REQUIRE(lw == lw2); + + auto result = lua.safe_script("b.var2 = 2", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); +} + +TEST_CASE("usertype/vars", "usertype vars can bind various class items") { + static int muh_variable = 25; + static int through_variable = 10; + + sol::state lua; + lua.open_libraries(); + struct test {}; + lua.new_usertype("test", + "straight", + sol::var(2), + "global", + sol::var(muh_variable), + "ref_global", + sol::var(std::ref(muh_variable)), + "global2", + sol::var(through_variable), + "ref_global2", + sol::var(std::ref(through_variable))); + + int prets = lua["test"]["straight"]; + int pretg = lua["test"]["global"]; + int pretrg = lua["test"]["ref_global"]; + int pretg2 = lua["test"]["global2"]; + int pretrg2 = lua["test"]["ref_global2"]; + + REQUIRE(prets == 2); + REQUIRE(pretg == 25); + REQUIRE(pretrg == 25); + REQUIRE(pretg2 == 10); + REQUIRE(pretrg2 == 10); + + lua.safe_script(R"( +print(test.straight) +test.straight = 50 +print(test.straight) +)"); + int s = lua["test"]["straight"]; + REQUIRE(s == 50); + + lua.safe_script(R"( +t = test.new() +print(t.global) +t.global = 50 +print(t.global) +)"); + int mv = lua["test"]["global"]; + REQUIRE(mv == 50); + REQUIRE(muh_variable == 25); + + lua.safe_script(R"( +print(t.ref_global) +t.ref_global = 50 +print(t.ref_global) +)"); + int rmv = lua["test"]["ref_global"]; + REQUIRE(rmv == 50); + REQUIRE(muh_variable == 50); + + REQUIRE(through_variable == 10); + lua.safe_script(R"( +print(test.global2) +test.global2 = 35 +print(test.global2) +)"); + int tv = lua["test"]["global2"]; + REQUIRE(through_variable == 10); + REQUIRE(tv == 35); + + lua.safe_script(R"( +print(test.ref_global2) +test.ref_global2 = 35 +print(test.ref_global2) +)"); + int rtv = lua["test"]["ref_global2"]; + REQUIRE(rtv == 35); + REQUIRE(through_variable == 35); +} diff --git a/lib/sol2/tests/runtime_tests/source/usertypes.runtime.cpp b/lib/sol2/tests/runtime_tests/source/usertypes.runtime.cpp new file mode 100644 index 0000000..3e0d6b3 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/usertypes.runtime.cpp @@ -0,0 +1,567 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include "common_classes.hpp" + +#include + +#include +#include +#include +#include +#include + +struct static_special_property_object { + static int named_set_calls; + static int named_get_calls; + + struct obj_hash { + std::size_t operator()(const sol::object& obj) const noexcept { + return std::hash()(obj.pointer()); + } + }; + + std::unordered_map props; + + sol::object get_property_lua(sol::stack_object key) const { + if (auto it = props.find(key); it != props.cend()) { + return it->second; + } + return sol::lua_nil; + } + + void set_property_lua(sol::stack_object key, sol::stack_object value) { + props.insert_or_assign(key, sol::object(value)); + } + + static void named_get_property_lua(sol::this_state L) { + ++named_get_calls; + luaL_error(L, "absolutely not"); + } + + static void named_set_property_lua(sol::this_state L) { + ++named_set_calls; + luaL_error(L, "absolutely not"); + } +}; + +int static_special_property_object::named_get_calls = 0; +int static_special_property_object::named_set_calls = 0; + +struct special_property_object { + struct obj_hash { + std::size_t operator()(const sol::object& obj) const noexcept { + return std::hash()(obj.pointer()); + } + }; + + std::unordered_map props; + + sol::object get_property_lua(sol::stack_object key) const { + if (auto it = props.find(key); it != props.cend()) { + return it->second; + } + return sol::lua_nil; + } + + void set_property_lua(sol::stack_object key, sol::stack_object value) { + props.insert_or_assign(key, sol::object(value)); + } +}; + +struct new_index_test_object { + bool new_indexed = false; + bool borf_new_indexed = false; + + float GetLevel(int x) const { + return static_cast(x); + } + + static void nidx(new_index_test_object& self, std::string_view key, sol::stack_object value) { + if (key == "borf" && value.is() && value.as() == 2) { + self.borf_new_indexed = true; + return; + } + self.new_indexed = true; + } + + static sol::object idx(sol::stack_object self, std::string_view key) { + if (key == "bark") { + return sol::object(self.lua_state(), sol::in_place, &new_index_test_object::GetLevel); + } + return sol::lua_nil; + } +}; + +TEST_CASE("usertype/runtime-extensibility", "Check if usertypes are runtime extensible") { + struct thing { + int v = 20; + int func(int a) { + return a; + } + }; + int val = 0; + + class base_a { + public: + int x; + }; + + class derived_b : public base_a {}; + + SECTION("just functions") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("thing", "func", &thing::func); + + lua.safe_script(R"( +t = thing.new() + )"); + + { + auto result = lua.safe_script(R"( +t.runtime_func = function (a) + return a + 50 +end + )", + sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + }; + + { + auto result = lua.safe_script(R"( +function t:runtime_func(a) + return a + 52 +end + )", + sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + }; + + lua.safe_script("val = t:func(2)"); + val = lua["val"]; + REQUIRE(val == 2); + + REQUIRE_NOTHROW([&lua]() { + lua.safe_script(R"( +function thing:runtime_func(a) + return a + 1 +end + )"); + }()); + + lua.safe_script("val = t:runtime_func(2)"); + val = lua["val"]; + REQUIRE(val == 3); + } + SECTION("with variable") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("thing", "func", &thing::func, "v", &thing::v); + + lua.safe_script(R"( +t = thing.new() + )"); + + { + auto result = lua.safe_script(R"( +t.runtime_func = function (a) + return a + 50 +end + )", + sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + }; + + { + auto result = lua.safe_script(R"( +function t:runtime_func(a) + return a + 52 +end + )", + sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + }; + + lua.safe_script("val = t:func(2)"); + val = lua["val"]; + REQUIRE(val == 2); + + REQUIRE_NOTHROW([&lua]() { + lua.safe_script(R"( +function thing:runtime_func(a) + return a + 1 +end + )"); + }()); + + lua.safe_script("val = t:runtime_func(2)"); + val = lua["val"]; + REQUIRE(val == 3); + } + SECTION("with bases") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("A", "x", &base_a::x // no crash without this + ); + + lua.new_usertype("B", sol::base_classes, sol::bases()); + + auto pfr0 = lua.safe_script("function A:c() print('A') return 1 end", sol::script_pass_on_error); + REQUIRE(pfr0.valid()); + auto pfr1 = lua.safe_script("function B:c() print('B') return 2 end", sol::script_pass_on_error); + REQUIRE(pfr1.valid()); + auto pfr2 = lua.safe_script("obja = A.new() objb = B.new()", sol::script_default_on_error); + REQUIRE(pfr2.valid()); + auto pfr3 = lua.safe_script("assert(obja:c() == 1)", sol::script_default_on_error); + REQUIRE(pfr3.valid()); + auto pfr4 = lua.safe_script("assert(objb:c() == 2)", sol::script_default_on_error); + REQUIRE(pfr4.valid()); + } +} + +TEST_CASE("usertype/runtime-replacement", "ensure that functions can be properly replaced at runtime for non-indexed things") { + struct heart_base_t {}; + struct heart_t : heart_base_t { + int x = 0; + void func() { + } + }; + + SECTION("plain") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("a"); + { + auto result1 = lua.safe_script("obj = a.new()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("function a:heartbeat () print('arf') return 1 end", sol::script_pass_on_error); + REQUIRE(result2.valid()); + auto result3 = lua.safe_script("v1 = obj:heartbeat()", sol::script_pass_on_error); + REQUIRE(result3.valid()); + auto result4 = lua.safe_script("function a:heartbeat () print('bark') return 2 end", sol::script_pass_on_error); + REQUIRE(result4.valid()); + auto result5 = lua.safe_script("v2 = obj:heartbeat()", sol::script_pass_on_error); + REQUIRE(result5.valid()); + auto result6 = lua.safe_script("a.heartbeat = function(self) print('woof') return 3 end", sol::script_pass_on_error); + REQUIRE(result6.valid()); + auto result7 = lua.safe_script("v3 = obj:heartbeat()", sol::script_pass_on_error); + REQUIRE(result7.valid()); + } + int v1 = lua["v1"]; + int v2 = lua["v2"]; + int v3 = lua["v3"]; + REQUIRE(v1 == 1); + REQUIRE(v2 == 2); + REQUIRE(v3 == 3); + } + SECTION("variables") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("a", "x", &heart_t::x, sol::base_classes, sol::bases()); + + { + auto result1 = lua.safe_script("obj = a.new()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("function a:heartbeat () print('arf') return 1 end", sol::script_pass_on_error); + REQUIRE(result2.valid()); + auto result3 = lua.safe_script("v1 = obj:heartbeat()", sol::script_pass_on_error); + REQUIRE(result3.valid()); + auto result4 = lua.safe_script("function a:heartbeat () print('bark') return 2 end", sol::script_pass_on_error); + REQUIRE(result4.valid()); + auto result5 = lua.safe_script("v2 = obj:heartbeat()", sol::script_pass_on_error); + REQUIRE(result5.valid()); + auto result6 = lua.safe_script("a.heartbeat = function(self) print('woof') return 3 end", sol::script_pass_on_error); + REQUIRE(result6.valid()); + auto result7 = lua.safe_script("v3 = obj:heartbeat()", sol::script_pass_on_error); + REQUIRE(result7.valid()); + } + int v1 = lua["v1"]; + int v2 = lua["v2"]; + int v3 = lua["v3"]; + REQUIRE(v1 == 1); + REQUIRE(v2 == 2); + REQUIRE(v3 == 3); + } + SECTION("methods") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("a", "func", &heart_t::func, sol::base_classes, sol::bases()); + + { + auto result1 = lua.safe_script("obj = a.new()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("function a:heartbeat () print('arf') return 1 end", sol::script_pass_on_error); + REQUIRE(result2.valid()); + auto result3 = lua.safe_script("v1 = obj:heartbeat()", sol::script_pass_on_error); + REQUIRE(result3.valid()); + auto result4 = lua.safe_script("function a:heartbeat () print('bark') return 2 end", sol::script_pass_on_error); + REQUIRE(result4.valid()); + auto result5 = lua.safe_script("v2 = obj:heartbeat()", sol::script_pass_on_error); + REQUIRE(result5.valid()); + auto result6 = lua.safe_script("a.heartbeat = function(self) print('woof') return 3 end", sol::script_pass_on_error); + REQUIRE(result6.valid()); + auto result7 = lua.safe_script("v3 = obj:heartbeat()", sol::script_pass_on_error); + REQUIRE(result7.valid()); + } + int v1 = lua["v1"]; + int v2 = lua["v2"]; + int v3 = lua["v3"]; + REQUIRE(v1 == 1); + REQUIRE(v2 == 2); + REQUIRE(v3 == 3); + } +} + +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 {}; + sol::state lua; + lua.open_libraries(sol::lib::base); + lua.new_usertype("object", sol::meta_function::new_index, [](newindex_object&, sol::object, sol::object) { return; }); + + lua["object"]["test"] = [](newindex_object&) { + std::cout << "test" << std::endl; + return 446; + }; + + auto result1 = lua.safe_script("o = object.new()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("assert(o:test() == 446)", sol::script_pass_on_error); + REQUIRE(result2.valid()); +} + +TEST_CASE("usertype/meta-key-retrievals", "allow for special meta keys (__index, __newindex) to trigger methods even if overwritten directly") { + SECTION("dynamically") { + static int writes = 0; + static std::string keys[4] = {}; + static int values[4] = {}; + struct d_sample { + void foo(std::string k, int v) { + keys[writes] = k; + values[writes] = v; + ++writes; + } + }; + + sol::state lua; + lua.new_usertype("sample"); + sol::table s = lua["sample"]["new"](); + 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"); + REQUIRE(values[0] == 2); + REQUIRE(values[1] == 4); + REQUIRE(values[2] == 3); + REQUIRE(values[3] == 1); + REQUIRE(keys[0] == "key"); + REQUIRE(keys[1] == "__newindex"); + REQUIRE(keys[2] == "__index"); + REQUIRE(keys[3] == "__call"); + } + + SECTION("statically") { + static int writes = 0; + static std::string keys[4] = {}; + static int values[4] = {}; + struct sample { + void foo(std::string k, int v) { + keys[writes] = k; + values[writes] = v; + ++writes; + } + }; + + sol::state lua; + lua.new_usertype("sample", sol::meta_function::new_index, &sample::foo); + + 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"); + REQUIRE(values[0] == 2); + REQUIRE(values[1] == 4); + REQUIRE(values[2] == 3); + REQUIRE(values[3] == 1); + REQUIRE(keys[0] == "key"); + REQUIRE(keys[1] == "__newindex"); + REQUIRE(keys[2] == "__index"); + REQUIRE(keys[3] == "__call"); + } +} + +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); + + lua.new_usertype("new_index_test_object", + sol::meta_function::index, + &new_index_test_object::idx, + sol::meta_function::new_index, + &new_index_test_object::nidx, + "Level", + &new_index_test_object::GetLevel); + + const auto& code = R"(a = new_index_test_object.new() + print(a:Level(1)) + print(a:Level(2)) + print(a:Level(3)))"; + + auto result0 = lua.safe_script(code, sol::script_pass_on_error); + REQUIRE(result0.valid()); + auto result1 = lua.safe_script("print(a:bark(1))", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("assert(a.Level2 == nil)", sol::script_pass_on_error); + REQUIRE(result2.valid()); + auto result3 = lua.safe_script("a:Level3()", sol::script_pass_on_error); + REQUIRE_FALSE(result3.valid()); + + new_index_test_object& a = lua["a"]; + REQUIRE_FALSE(a.borf_new_indexed); + REQUIRE_FALSE(a.new_indexed); + + auto resultnormal = lua.safe_script("a.normal = 'foo'", sol::script_pass_on_error); + REQUIRE(resultnormal.valid()); + REQUIRE_FALSE(a.borf_new_indexed); + REQUIRE(a.new_indexed); + + auto resultborf = lua.safe_script("a.borf = 2", sol::script_pass_on_error); + REQUIRE(resultborf.valid()); + REQUIRE(a.borf_new_indexed); + REQUIRE(a.new_indexed); +} + +TEST_CASE("usertype/object and class extensible", "make sure that a class which override new_index and friends can still work properly") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("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(L, 1); + sol::usertype mt = self[sol::metatable_key]; + mt["additional_function"] = []() { return 24; }; + }; + + lua["add_object_func"] = [](sol::this_state L, special_property_object&) { + sol::stack_userdata self = sol::stack::get(L, 1); + self["specific_function"] = []() { return 23; }; + }; + + sol::optional result0 = lua.safe_script(R"( + s = special_property_object.new() + s2 = special_property_object.new() + add_class_func(s) + add_object_func(s) + value = s:additional_function() + assert(value == 24) + value2 = s:specific_function() + assert(value2 == 23) + )", + sol::script_pass_on_error); + REQUIRE_FALSE(result0.has_value()); + int value = lua["value"]; + REQUIRE(value == 24); + int value2 = lua["value2"]; + REQUIRE(value2 == 23); + + sol::optional result1 = lua.safe_script(R"( + value3 = s2:specific_function() + assert(value3 == 23) + )", + sol::script_pass_on_error); + REQUIRE(result1.has_value()); +} + +TEST_CASE("usertypes/static new index and static index", "ensure static index and static new index provide the proper interface") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype("static_special_property_object", + sol::meta_function::index, + &static_special_property_object::get_property_lua, + sol::meta_function::new_index, + &static_special_property_object::set_property_lua, + sol::meta_function::static_index, + &static_special_property_object::named_get_property_lua, + sol::meta_function::static_new_index, + &static_special_property_object::named_set_property_lua); + + lua["add_object_func"] = [](sol::this_state L, static_special_property_object&) { + sol::stack_userdata self = sol::stack::get(L, 1); + self["specific_function"] = []() { return 23; }; + }; + + sol::optional result0 = lua.safe_script(R"( + s = static_special_property_object.new() + s2 = static_special_property_object.new() + add_object_func(s) + value2 = s:specific_function() + assert(value2 == 23) + )", + sol::script_pass_on_error); + REQUIRE_FALSE(result0.has_value()); + int value2 = lua["value2"]; + REQUIRE(value2 == 23); + + sol::optional result1 = lua.safe_script(R"( + function static_special_property_object:additional_function () + return 24 + end + value = s:additional_function() + assert(value == 24) + )", + sol::script_pass_on_error); + REQUIRE(result1.has_value()); + bool is_value_valid = lua["value"].valid(); + REQUIRE_FALSE(is_value_valid); + + sol::optional result2 = lua.safe_script(R"( + value3 = s2:specific_function() + assert(value3 == 23) + )", + sol::script_pass_on_error); + REQUIRE(result2.has_value()); + + sol::optional result3 = lua.safe_script(R"( + assert(static_special_property_object.non_existent == nil) + )", + sol::script_pass_on_error); + REQUIRE(result3.has_value()); + + REQUIRE(static_special_property_object::named_get_calls == 1); + REQUIRE(static_special_property_object::named_set_calls == 1); +} diff --git a/lib/sol2/tests/runtime_tests/source/usertypes.unique.cpp b/lib/sol2/tests/runtime_tests/source/usertypes.unique.cpp new file mode 100644 index 0000000..e3028ea --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/usertypes.unique.cpp @@ -0,0 +1,173 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include "common_classes.hpp" + +#include + + +struct factory_test { +private: + factory_test() { + a = true_a; + } + ~factory_test() { + a = 0; + } + +public: + static int num_saved; + static int num_killed; + + struct deleter { + void operator()(factory_test* f) { + f->~factory_test(); + } + }; + + static const int true_a; + int a; + + static std::unique_ptr make() { + return std::unique_ptr(new factory_test(), deleter()); + } + + static void save(factory_test& f) { + new (&f) factory_test(); + ++num_saved; + } + + static void kill(factory_test& f) { + f.~factory_test(); + ++num_killed; + } +}; + +int factory_test::num_saved = 0; +int factory_test::num_killed = 0; +const int factory_test::true_a = 156; + + +TEST_CASE("usertype/unique-shared-ptr", "manage the conversion and use of unique and shared pointers ('unique usertypes')") { + const int64_t unique_value = 0x7125679355635963; + auto uniqueint = std::make_unique(unique_value); + auto sharedint = std::make_shared(unique_value); + long preusecount = sharedint.use_count(); + { + sol::state lua; + lua.open_libraries(sol::lib::base); + lua.set("uniqueint", std::move(uniqueint)); + lua.set("sharedint", sharedint); + std::unique_ptr& uniqueintref = lua["uniqueint"]; + std::shared_ptr& sharedintref = lua["sharedint"]; + int64_t* rawuniqueintref = lua["uniqueint"]; + int64_t* rawsharedintref = lua["sharedint"]; + int siusecount = sharedintref.use_count(); + REQUIRE((uniqueintref.get() == rawuniqueintref && sharedintref.get() == rawsharedintref)); + REQUIRE((uniqueintref != nullptr && sharedintref != nullptr && rawuniqueintref != nullptr && rawsharedintref != nullptr)); + REQUIRE((unique_value == *uniqueintref.get() && unique_value == *sharedintref.get())); + REQUIRE((unique_value == *rawuniqueintref && unique_value == *rawsharedintref)); + REQUIRE(siusecount == sharedint.use_count()); + std::shared_ptr moreref = sharedint; + REQUIRE(unique_value == *moreref.get()); + REQUIRE(moreref.use_count() == sharedint.use_count()); + REQUIRE(moreref.use_count() == sharedintref.use_count()); + } + REQUIRE(preusecount == sharedint.use_count()); + std::cout << "----- end of 2" << std::endl; +} + +TEST_CASE("usertype/private-constructible", "Check to make sure special snowflake types from Enterprise thingamahjongs work properly.") { + int numsaved = factory_test::num_saved; + int numkilled = factory_test::num_killed; + { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.new_usertype( + "factory_test", "new", sol::initializers(factory_test::save), "__gc", sol::destructor(factory_test::kill), "a", &factory_test::a); + + std::unique_ptr f = factory_test::make(); + lua.set("true_a", factory_test::true_a, "f", f.get()); + { + auto result = lua.safe_script("assert(f.a == true_a)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + + auto code1 + = "local fresh_f = factory_test:new()\n" + "assert(fresh_f.a == true_a)\n"; + auto result1 = lua.safe_script(code1, sol::script_pass_on_error); + REQUIRE(result1.valid()); + } + int expectednumsaved = numsaved + 1; + int expectednumkilled = numkilled + 1; + REQUIRE(expectednumsaved == factory_test::num_saved); + REQUIRE(expectednumkilled == factory_test::num_killed); + std::cout << "----- end of 5" << std::endl; +} + +TEST_CASE("usertype/unique_usertype-check", "make sure unique usertypes don't get pushed as references with function calls and the like") { + class Entity { + public: + std::string GetName() { + return "Charmander"; + } + }; + + sol::state lua; + lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string, sol::lib::io); + + lua.new_usertype("Entity", "new", sol::no_constructor, "get_name", &Entity::GetName); + + lua.safe_script(R"( + function my_func(entity) + print("INSIDE LUA") + print(entity:get_name()) + end +)"); + + sol::function my_func = lua["my_func"]; + REQUIRE_NOTHROW([&] { + auto ent = std::make_shared(); + my_func(ent); + Entity ent2; + my_func(ent2); + my_func(std::make_shared()); + }()); +} + +TEST_CASE("usertype/unique void pointers", "can compile shared_ptr types and not trip the compiler or sol3's internals") { + sol::state lua; + lua.set_function("f", [](std::shared_ptr d) { + int* pi = static_cast(d.get()); + REQUIRE(*pi == 567); + }); + + std::shared_ptr s = std::make_shared(567); + lua["s"] = std::move(s); + auto result = lua.safe_script("f(s)", sol::script_pass_on_error); + REQUIRE(result.valid()); +} diff --git a/lib/sol2/tests/runtime_tests/source/usertypes.unregister.cpp b/lib/sol2/tests/runtime_tests/source/usertypes.unregister.cpp new file mode 100644 index 0000000..3302b8e --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/usertypes.unregister.cpp @@ -0,0 +1,147 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +struct unregister_me { + double b = 5.5; + std::string f_val = "registered"; + + unregister_me() { + } + + std::string f() { + return f_val; + } +}; + +TEST_CASE("usertypes/unregister", "make sure that a class can still be bound but that it becomes completely unregistered") { + const sol::string_view line1 = "assert(u:f() == 'registered')"; + const sol::string_view line2 = "assert(urm.a() == 20)"; + const sol::string_view line3 = "assert(u.a() == 20) assert(u:a() == 20)"; + const sol::string_view line4 = "assert(u.b == 5.5)"; + + sol::state lua; + lua.open_libraries(); + auto register_urm = [&lua, &line1, &line2, &line3, &line4]() { + lua.new_usertype("urm", "f", &unregister_me::f, "a", []() { return 20; }, "b", &unregister_me::b); + { + sol::object urm_obj = lua["urm"]; + REQUIRE(urm_obj.get_type() == sol::type::table); + REQUIRE(urm_obj.is()); + REQUIRE(urm_obj.is()); + REQUIRE(urm_obj.is>()); + } + + lua["urm_unregister"] = [](sol::this_state ts) { + sol::state_view current_lua = ts; + sol::usertype urm = current_lua["urm"]; + urm.unregister(); + }; + + auto sresult0 = lua.safe_script("u = urm.new()", sol::script_pass_on_error); + REQUIRE(sresult0.valid()); + auto sresult1 = lua.safe_script(line1, sol::script_pass_on_error); + REQUIRE(sresult1.valid()); + auto sresult2 = lua.safe_script(line2, sol::script_pass_on_error); + REQUIRE(sresult2.valid()); + auto sresult3 = lua.safe_script(line3, sol::script_pass_on_error); + REQUIRE(sresult3.valid()); + auto sresult4 = lua.safe_script(line4, sol::script_pass_on_error); + REQUIRE(sresult4.valid()); + + unregister_me& u_orig = lua["u"]; + REQUIRE(u_orig.b == 5.5); + REQUIRE(u_orig.f() == "registered"); + }; + SECTION("unregister C++") { + register_urm(); + + { + sol::usertype urm = lua["urm"]; + urm.unregister(); + } + + auto result0 = lua.safe_script("u_fail = urm.new()", sol::script_pass_on_error); + REQUIRE_FALSE(result0.valid()); + auto result1 = lua.safe_script(line1, sol::script_pass_on_error); + REQUIRE_FALSE(result1.valid()); + auto result2 = lua.safe_script(line2, sol::script_pass_on_error); + REQUIRE_FALSE(result2.valid()); + auto result3 = lua.safe_script(line3, sol::script_pass_on_error); + REQUIRE_FALSE(result3.valid()); + auto result4 = lua.safe_script(line4, sol::script_pass_on_error); + REQUIRE_FALSE(result4.valid()); + + unregister_me& u = lua["u"]; + REQUIRE(u.b == 5.5); + REQUIRE(u.f() == "registered"); + } + SECTION("re-register") { + register_urm(); + + sol::protected_function urm_unregister_func = lua["urm_unregister"]; + auto unregister_result = urm_unregister_func(); + REQUIRE(unregister_result.valid()); + + auto result0 = lua.safe_script("u_fail2 = urm.new()", sol::script_pass_on_error); + REQUIRE_FALSE(result0.valid()); + auto result1 = lua.safe_script(line1, sol::script_pass_on_error); + REQUIRE_FALSE(result1.valid()); + auto result2 = lua.safe_script(line2, sol::script_pass_on_error); + REQUIRE_FALSE(result2.valid()); + auto result3 = lua.safe_script(line3, sol::script_pass_on_error); + REQUIRE_FALSE(result3.valid()); + auto result4 = lua.safe_script(line4, sol::script_pass_on_error); + REQUIRE_FALSE(result4.valid()); + + unregister_me& u = lua["u"]; + REQUIRE(u.b == 5.5); + REQUIRE(u.f() == "registered"); + + register_urm(); + } + SECTION("unregister lua") { + register_urm(); + + auto unregister_result = lua.safe_script("urm_unregister()", sol::script_pass_on_error); + REQUIRE(unregister_result.valid()); + + auto result0 = lua.safe_script("u_fail2 = urm.new()", sol::script_pass_on_error); + REQUIRE_FALSE(result0.valid()); + auto result1 = lua.safe_script(line1, sol::script_pass_on_error); + REQUIRE_FALSE(result1.valid()); + auto result2 = lua.safe_script(line2, sol::script_pass_on_error); + REQUIRE_FALSE(result2.valid()); + auto result3 = lua.safe_script(line3, sol::script_pass_on_error); + REQUIRE_FALSE(result3.valid()); + auto result4 = lua.safe_script(line4, sol::script_pass_on_error); + REQUIRE_FALSE(result4.valid()); + + unregister_me& u = lua["u"]; + REQUIRE(u.b == 5.5); + REQUIRE(u.f() == "registered"); + } +} diff --git a/lib/sol2/tests/runtime_tests/source/utility.cpp b/lib/sol2/tests/runtime_tests/source/utility.cpp new file mode 100644 index 0000000..0abb899 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/utility.cpp @@ -0,0 +1,346 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" +#include "common_classes.hpp" + +#include + +#include +#include + +#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES +#include +#include +#endif // C++17 + +struct optional_ref_t { + int x = 0; +}; + +std::mutex basic_init_require_mutex; + +void basic_initialization_and_lib_open() { + sol::state lua; + try { + lua.open_libraries(); + lua["a"] = 24; + int a = lua["a"]; + { + std::lock_guard lg(basic_init_require_mutex); + REQUIRE(a == 24); + } + } + catch (const sol::error& e) { + std::lock_guard lg(basic_init_require_mutex); + INFO(e.what()); + REQUIRE(false); + } + catch (...) { + std::lock_guard lg(basic_init_require_mutex); + REQUIRE(false); + } +} + +TEST_CASE("utility/variant", "test that variant can be round-tripped") { +#ifdef SOL_CXX17_FEATURES + SECTION("okay") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.set_function("f", [](int v) { + return v == 2; + }); + lua.set_function("g", [](std::variant vv) { + int v = std::get(vv); + return v == 2; + }); + lua["v"] = std::variant(2); + { + auto result = lua.safe_script("assert(f(v))", sol::script_pass_on_error); + REQUIRE(result.valid()); + }; + { + auto result = lua.safe_script("assert(g(v))", sol::script_pass_on_error); + REQUIRE(result.valid()); + }; + } + SECTION("throws") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.set_function("f", [](int v) { + return v == 2; + }); + lua.set_function("g", [](std::variant vv) { + int v = std::get(vv); + return v == 2; + }); + lua["v"] = std::variant(std::string("bark")); + { + auto result = lua.safe_script("assert(f(v))", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + }; + { + auto result = lua.safe_script("assert(g(v))", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + }; + } +#else + REQUIRE(true); +#endif // C++17 +} + +TEST_CASE("utility/optional-conversion", "test that regular optional will properly catch certain types") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + lua.new_usertype("vars"); + + lua["test"] = [](sol::optional x) { return static_cast(x); }; + + const auto result = lua.safe_script(R"( + assert(test(vars:new())) + assert(not test(3)) + assert(not test(nil)) + )", + sol::script_pass_on_error); + REQUIRE(result.valid()); +} + +TEST_CASE("utility/optional-value-or", "test that regular optional will properly handle value_or") { + sol::optional str; + auto x = str.value_or("!"); + + sol::optional un; + auto y = un.value_or(64); + + optional_ref_t def_custom; + sol::optional custom; + auto z = custom.value_or(def_custom); + const auto& z_ref = custom.value_or(def_custom); + + REQUIRE(x == "!"); + + REQUIRE(y == 64); + + REQUIRE(&def_custom == &z_ref); + REQUIRE(&z != &def_custom); +} + +TEST_CASE("utility/std optional", "test that shit optional can be round-tripped") { +#ifdef SOL_CXX17_FEATURES + SECTION("okay") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + lua.set_function("f", [](int v) { + return v == 2; + }); + lua.set_function("g", [](std::optional vv) { + return vv && *vv == 2; + }); + lua["v"] = std::optional(2); + { + auto result = lua.safe_script("assert(f(v))", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(g(v))", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + } + SECTION("throws") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + lua.set_function("f", [](int v) { + return v == 2; + }); + lua.set_function("g", [](std::optional vv) { + return vv && *vv == 2; + }); + lua["v"] = std::optional(std::nullopt); + { + auto result = lua.safe_script("assert(f(v))", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + }; + { + auto result = lua.safe_script("assert(g(v))", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + }; + } + SECTION("in classes") { + sol::state lua; + sol::stack_guard luasg(lua); + + lua.open_libraries(sol::lib::base); + + struct opt_c { + std::optional member; + }; + + auto uto = lua.new_usertype("opt_c", + "value", &opt_c::member); + + opt_c obj; + lua["obj"] = std::ref(obj); + + lua.safe_script("print(obj.value) obj.value = 20 print(obj.value)"); + REQUIRE(obj.member == 20); + lua.safe_script("print(obj.value) obj.value = nil print(obj.value)"); + REQUIRE(obj.member == std::nullopt); + } +#else + REQUIRE(true); +#endif // C++17 +} + +TEST_CASE("utility/string_view", "test that string_view can be taken as an argument") { +#ifdef SOL_CXX17_FEATURES + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + lua.set_function("f", [](std::string_view v) { + return v == "bark!"; + }); + lua["v"] = "bark!"; + + REQUIRE_NOTHROW([&]() { + lua.safe_script("assert(f(v))"); + }()); +#else + REQUIRE(true); +#endif // C++17 +} + +TEST_CASE("utility/thread", "fire up lots of threads at the same time to make sure the initialization changes do not cause horrible crashing data races") { + REQUIRE_NOTHROW([]() { + std::thread thrds[16]; + for (int i = 0; i < 16; i++) { + thrds[i] = std::thread(&basic_initialization_and_lib_open); + } + + for (int i = 0; i < 16; i++) { + thrds[i].join(); + } + }()); +} + +TEST_CASE("utility/pointer", "check we can get pointer value from references") { + sol::state lua; + sol::stack_guard luasg(lua); + + lua.set_function("f", [](bool aorb, sol::reference a, sol::stack_reference b) { + if (aorb) { + return a.pointer(); + } + return b.pointer(); + }); + auto result0 = lua.safe_script("v0 = 'hi'", sol::script_pass_on_error); + REQUIRE(result0.valid()); + auto result1 = lua.safe_script("v1 = f(true, v0)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("v2 = f(false, nil, v0)", sol::script_pass_on_error); + REQUIRE(result2.valid()); + const void* ap = lua["v1"]; + const void* bp = lua["v2"]; + REQUIRE(ap == bp); +} + +TEST_CASE("utility/this_state", "Ensure this_state argument can be gotten anywhere in the function.") { + struct bark { + int with_state(sol::this_state l, int a, int b) { + lua_State* L = l; + int c = lua_gettop(L); + return a + b + (c - c); + } + + static int with_state_2(int a, sol::this_state l, int b) { + INFO("inside with_state_2"); + lua_State* L = l; + INFO("L is" << (void*)L); + int c = lua_gettop(L); + return a * b + (c - c); + } + }; + + sol::state lua; + sol::stack_guard luasg(lua); + + INFO("created lua state"); + lua.open_libraries(sol::lib::base); + lua.new_usertype("bark", + "with_state", &bark::with_state); + + INFO("setting b and with_state_2"); + bark b; + lua.set("b", &b); + lua.set("with_state_2", bark::with_state_2); + INFO("finished setting"); + INFO("getting fx"); + sol::function fx = lua["with_state_2"]; + INFO("calling fx"); + int a = fx(25, 25); + INFO("finished setting fx"); + INFO("calling a script"); + lua.safe_script("a = with_state_2(25, 25)"); + INFO("calling c script"); + lua.safe_script("c = b:with_state(25, 25)"); + INFO("getting a"); + int la = lua["a"]; + INFO("getting b"); + int lc = lua["c"]; + + REQUIRE(lc == 50); + REQUIRE(a == 625); + REQUIRE(la == 625); +} + +TEST_CASE("safety/check_stack", "check to make sure that if we overflow the stack in safety mode, we get the appropriate error thrown") { + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + lua["okay"] = []() { + // clang-format off + return std::make_tuple(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, 31, 32, 33, 34, 35, 36, 37); + // clang-format on + }; + lua["bad"] = [](lua_State* L) { + constexpr int max_stack_guess = 1000000 * 2 * 4; + int p = 0; + for (std::size_t i = 0; i < max_stack_guess; ++i) { + p += sol::stack::push(L, i); + } + return p; + }; + auto result1 = lua.safe_script("okay()", sol::script_pass_on_error); + REQUIRE(result1.valid()); + auto result2 = lua.safe_script("bad()", sol::script_pass_on_error); + REQUIRE_FALSE(result2.valid()); +} diff --git a/lib/sol2/tests/runtime_tests/source/variadics.cpp b/lib/sol2/tests/runtime_tests/source/variadics.cpp new file mode 100644 index 0000000..5518e89 --- /dev/null +++ b/lib/sol2/tests/runtime_tests/source/variadics.cpp @@ -0,0 +1,261 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "sol_test.hpp" + +#include + +#include +#include +#include +#include + +TEST_CASE("variadics/variadic_args", "Check to see we can receive multiple arguments through a variadic") { + struct structure { + int x; + bool b; + }; + + sol::state lua; + sol::stack_guard luasg(lua); + lua.open_libraries(sol::lib::base); + + lua.set_function("v", [](sol::this_state, sol::variadic_args va) -> structure { + int r = 0; + for (auto v : va) { + int value = v; + r += value; + } + return { r, r > 200 }; + }); + + lua.safe_script("x = v(25, 25)"); + lua.safe_script("x2 = v(25, 25, 100, 50, 250, 150)"); + lua.safe_script("x3 = v(1, 2, 3, 4, 5, 6)"); + + structure& lx = lua["x"]; + structure& lx2 = lua["x2"]; + structure& lx3 = lua["x3"]; + REQUIRE(lx.x == 50); + REQUIRE(lx2.x == 600); + REQUIRE(lx3.x == 21); + REQUIRE_FALSE(lx.b); + REQUIRE(lx2.b); + REQUIRE_FALSE(lx3.b); +} + +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) { + }); + { + auto result = lua.safe_script("v(20, 25, 30)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("v(20, 25)", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("v(20)", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + } +} + +TEST_CASE("variadics/variadic_args get type", "Make sure we can inspect types proper from variadic_args") { + sol::state lua; + 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 + }; + bool working = true; + auto b = va.begin(); + for (std::size_t i = 0; i < va.size(); ++i, ++b) { + sol::type t1 = va.get_type(i); + sol::type t2 = b->get_type(); + working &= types[i] == t1; + working &= types[i] == t2; + } + REQUIRE(working); + }); + + lua.safe_script("f(1, 'bark', true)"); + lua.safe_script("f(2, 'wuf', false)"); +} + +TEST_CASE("variadics/variadic_results", "returning a variable amount of arguments from C++") { + SECTION("as_returns - containers") { + sol::state lua; + sol::stack_guard luasg(lua); + + lua.set_function("f", []() { + std::set results{ "arf", "bark", "woof" }; + return sol::as_returns(std::move(results)); + }); + lua.set_function("g", []() { + static const std::deque results{ 25, 82 }; + return sol::as_returns(std::ref(results)); + }); + + REQUIRE_NOTHROW([&]() { + lua.safe_script(R"( + v1, v2, v3 = f() + v4, v5 = g() +)"); + }()); + + std::string v1 = lua["v1"]; + std::string v2 = lua["v2"]; + std::string v3 = lua["v3"]; + int v4 = lua["v4"]; + int v5 = lua["v5"]; + + REQUIRE(v1 == "arf"); + REQUIRE(v2 == "bark"); + REQUIRE(v3 == "woof"); + REQUIRE(v4 == 25); + REQUIRE(v5 == 82); + } + SECTION("variadic_results - variadic_args") { + sol::state lua; + sol::stack_guard luasg(lua); + + 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); + REQUIRE(result1.valid()); + + int v1 = lua["v1"]; + std::string v2 = lua["v2"]; + bool v3 = lua["v3"]; + int v4 = lua["v4"]; + int v5 = lua["v5"]; + + REQUIRE(v1 == 1); + REQUIRE(v2 == "bark"); + REQUIRE(v3); + REQUIRE(v4 == 25); + REQUIRE(v5 == 82); + } + SECTION("variadic_results") { + sol::state lua; + sol::stack_guard luasg(lua); + + lua.set_function("f", [](sol::this_state ts, bool maybe) { + if (maybe) { + sol::variadic_results vr; + vr.push_back({ ts, sol::in_place, 1 }); + vr.push_back({ ts, sol::in_place, 2 }); + vr.insert(vr.cend(), { ts, sol::in_place, 3 }); + return vr; + } + else { + sol::variadic_results vr; + vr.push_back({ ts, sol::in_place, "bark" }); + vr.push_back({ ts, sol::in_place, "woof" }); + vr.insert(vr.cend(), { ts, sol::in_place, "arf" }); + vr.push_back({ ts, sol::in_place, "borf" }); + return vr; + } + }); + + auto result1 = lua.safe_script(R"( + v1, v2, v3 = f(true) + v4, v5, v6, v7 = f(false) + )", sol::script_pass_on_error); + REQUIRE(result1.valid()); + + int v1 = lua["v1"]; + int v2 = lua["v2"]; + int v3 = lua["v3"]; + std::string v4 = lua["v4"]; + std::string v5 = lua["v5"]; + std::string v6 = lua["v6"]; + std::string v7 = lua["v7"]; + + REQUIRE(v1 == 1); + REQUIRE(v2 == 2); + REQUIRE(v3 == 3); + REQUIRE(v4 == "bark"); + REQUIRE(v5 == "woof"); + REQUIRE(v6 == "arf"); + REQUIRE(v7 == "borf"); + } +} + +TEST_CASE("variadics/fallback_constructor", "ensure constructor matching behaves properly in the presence of variadic fallbacks") { + struct vec2x { + float x = 0, y = 0; + }; + + sol::state lua; + + lua.new_usertype("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(); + res.y = va[0].get(); + } + else if (va.size() == 2) { + res.x = va[0].get(); + res.y = va[1].get(); + } + 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); + auto result3 = lua.safe_script("v2 = vec2x(1, 2);", sol::script_pass_on_error); + auto result4 = lua.safe_script("v3 = vec2x(v2)", sol::script_pass_on_error); + REQUIRE(result1.valid()); + REQUIRE(result2.valid()); + REQUIRE(result3.valid()); + REQUIRE(result4.valid()); + + vec2x& v0 = lua["v0"]; + vec2x& v1 = lua["v1"]; + vec2x& v2 = lua["v2"]; + vec2x& v3 = lua["v3"]; + + REQUIRE(v0.x == 0); + REQUIRE(v0.y == 0); + REQUIRE(v1.x == 1); + REQUIRE(v1.y == 1); + REQUIRE(v2.x == 1); + REQUIRE(v2.y == 2); + REQUIRE(v3.x == v2.x); + REQUIRE(v3.y == v2.y); +} -- cgit v1.2.3