🛠 Address lifetime issues through Lua references in iterators.

📝 Fixes #1315, #1374, and #1400.
— 📝 Lifetime in iterators was referencing the wrong stack (the main thread) rather than the coroutine's stack at time of creation.
— 📝 Using main_reference/main_* objects was a suitable enough fix for most of these problems.
— 🛠 Prevent performance and usability issues from changing containers by storing the being/end iterator separately, rather than continually invoking `deferred_uc::end(…)` every time.
— 🛠 Improve sizes for stored iterators in select cases.
— 🛠 Allow for sentinel-style C++20-and-beyond ranges.
— 🔧 Improve single file generation CMake.
— 👷‍♀️ Fix up internal Lua build system issues.
This commit is contained in:
ShepherdSoasis 2023-07-17 14:45:56 -04:00 committed by The Phantom Derpstorm
parent 97806f2a7c
commit 64e3823bd2
46 changed files with 702 additions and 137 deletions

View File

@ -60,7 +60,7 @@ ExternalProject_Add(KAGUYA_BUILD_SOURCE
add_library(${kaguya_lib} INTERFACE)
add_dependencies(${kaguya_lib} KAGUYA_BUILD_SOURCE)
target_include_directories(${kaguya_lib} INTERFACE ${kaguya_include_dirs})
target_link_libraries(${kaguya_lib} INTERFACE ${LUA_LIBRARIES})
target_link_libraries(${kaguya_lib} INTERFACE Lua::Lua)
if (NOT MSVC)
target_compile_options(${kaguya_lib} INTERFACE
-Wno-noexcept-type -Wno-ignored-qualifiers -Wno-unused-parameter)

View File

@ -59,7 +59,7 @@ ExternalProject_Add(LUABRIDGE_BUILD_SOURCE
add_library(${luabridge_lib} INTERFACE)
add_dependencies(${luabridge_lib} LUABRIDGE_BUILD_SOURCE)
target_include_directories(${luabridge_lib} INTERFACE ${luabridge_include_dirs})
target_link_libraries(${luabridge_lib} INTERFACE ${LUA_LIBRARIES})
target_link_libraries(${luabridge_lib} INTERFACE Lua::Lua)
if (NOT MSVC)
target_compile_options(${luabridge_lib} INTERFACE
-Wno-noexcept-type -Wno-ignored-qualifiers -Wno-unused-parameter)

View File

@ -88,7 +88,7 @@ function(find_lua_build LUA_VERSION)
endif()
# # Export variables to the parent scope
set(LUA_LIBRARIES ${LUA_LIBRARIES} PARENT_SCOPE)
set(LUA_LIBRARIES Lua::Lua PARENT_SCOPE)
set(LUA_INTERPRETER ${LUA_INTERPRETER} PARENT_SCOPE)
set(LUA_INCLUDE_DIRS ${LUA_INCLUDE_DIRS} PARENT_SCOPE)
set(LUA_VERSION_STRING ${LUA_VERSION_STRING} PARENT_SCOPE)

View File

@ -103,20 +103,20 @@ if (LUA_VANILLA_VERSION MATCHES "^5\\.1")
lbaselib.c ldblib.c liolib.c lmathlib.c loslib.c ltablib.c
lstrlib.c loadlib.c linit.c)
set(LUA_VANILLA_LUA_SOURCES lua.c )
if (LUA_BUILD_LUA_COMPILER)
set(LUA_VANILLA_LUAC_SOURCES luac.c print.c )
endif()
if (LUA_BUILD_LUA_COMPILER)
set(LUA_VANILLA_LUAC_SOURCES luac.c print.c)
endif()
set(LUA_VANILLA_GENERATE_LUA_HPP true)
elseif (LUA_VANILLA_VERSION MATCHES "^5\\.2")
set(LUA_VANILLA_LIB_SOURCES lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c
set(LUA_VANILLA_LIB_SOURCES lapi.c lbitlib.c lcode.c lctype.c ldebug.c ldo.c ldump.c
lfunc.c lgc.c llex.c lmem.c lobject.c lopcodes.c lparser.c
lstate.c lstring.c ltable.c ltm.c lundump.c lvm.c lzio.c
lauxlib.c lbaselib.c lcorolib.c ldblib.c liolib.c
lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c)
set(LUA_VANILLA_LUA_SOURCES lua.c )
if (LUA_BUILD_LUA_COMPILER)
set(LUA_VANILLA_LUAC_SOURCES luac.c )
endif()
set(LUA_VANILLA_LUA_SOURCES lua.c)
if (LUA_BUILD_LUA_COMPILER)
set(LUA_VANILLA_LUAC_SOURCES luac.c)
endif()
set(LUA_VANILLA_GENERATE_LUA_HPP false)
elseif (LUA_VANILLA_VERSION MATCHES "^5\\.3")
set(LUA_VANILLA_LIB_SOURCES lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c
@ -125,9 +125,9 @@ elseif (LUA_VANILLA_VERSION MATCHES "^5\\.3")
lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c lmathlib.c
loslib.c lstrlib.c ltablib.c lutf8lib.c loadlib.c linit.c)
set(LUA_VANILLA_LUA_SOURCES lua.c )
if (LUA_BUILD_LUA_COMPILER)
set(LUA_VANILLA_LUAC_SOURCES luac.c )
endif()
if (LUA_BUILD_LUA_COMPILER)
set(LUA_VANILLA_LUAC_SOURCES luac.c)
endif()
set(LUA_VANILLA_GENERATE_LUA_HPP false)
elseif (LUA_VANILLA_VERSION MATCHES "^5\\.4")
if (LUA_VANILLA_VERSION MATCHES "work" OR LUA_VANILLA_VERSION MATCHES "alpha" OR LUA_VANILLA_VERSION MATCHES "beta")
@ -138,10 +138,10 @@ elseif (LUA_VANILLA_VERSION MATCHES "^5\\.4")
llex.c lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c loslib.c
lparser.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c ltm.c lundump.c
lutf8lib.c lvm.c lzio.c)
set(LUA_VANILLA_LUA_SOURCES lua.c )
if (LUA_BUILD_LUA_COMPILER)
set(LUA_VANILLA_LUAC_SOURCES luac.c )
endif()
set(LUA_VANILLA_LUA_SOURCES lua.c)
if (LUA_BUILD_LUA_COMPILER)
set(LUA_VANILLA_LUAC_SOURCES luac.c)
endif()
set(LUA_VANILLA_GENERATE_LUA_HPP false)
else()
MESSAGE(WARNING "Using Lua 5.4.4 file list for ${LUA_VERSION} version")
@ -150,10 +150,10 @@ else()
llex.c lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c loslib.c
lparser.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c ltm.c lundump.c
lutf8lib.c lvm.c lzio.c)
set(LUA_VANILLA_LUA_SOURCES lua.c )
if (LUA_BUILD_LUA_COMPILER)
set(LUA_VANILLA_LUAC_SOURCES luac.c )
endif()
set(LUA_VANILLA_LUA_SOURCES lua.c)
if (LUA_BUILD_LUA_COMPILER)
set(LUA_VANILLA_LUAC_SOURCES luac.c)
endif()
set(LUA_VANILLA_GENERATE_LUA_HPP false)
endif()
@ -217,6 +217,7 @@ set(luacompiler "luac-${LUA_VANILLA_VERSION}")
# make an actual, buildable target
# that other parts of the code can depend on
add_library(${liblua} ${LUA_BUILD_LIBRARY_TYPE} ${LUA_VANILLA_LIB_SOURCES})
add_library(Lua::Lua ALIAS ${liblua})
set_target_properties(${liblua}
PROPERTIES
LANGUAGE ${LUA_VANILLA_LANGUAGE}
@ -233,7 +234,9 @@ set_source_files_properties(${LUA_VANILLA_LIB_SOURCES}
target_include_directories(${liblua}
PUBLIC "${LUA_VANILLA_INCLUDE_DIRS}")
target_compile_definitions(${liblua}
PUBLIC LUA_COMPAT_ALL ${LUA_VANILLA_DLL_DEFINE})
PUBLIC
LUA_COMPAT_ALL
${LUA_VANILLA_DLL_DEFINE})
if (MSVC)
target_compile_options(${liblua}
PRIVATE /W1)

View File

@ -59,7 +59,7 @@ ExternalProject_Add(LUWRA_BUILD_SOURCE
add_library(${luwra_lib} INTERFACE)
add_dependencies(${luwra_lib} LUWRA_BUILD_SOURCE)
target_include_directories(${luwra_lib} INTERFACE ${luwra_include_dirs})
target_link_libraries(${luwra_lib} INTERFACE ${LUA_LIBRARIES})
target_link_libraries(${luwra_lib} INTERFACE Lua::Lua)
if (NOT MSVC)
target_compile_options(${luwra_lib} INTERFACE
-Wno-noexcept-type -Wno-ignored-qualifiers -Wno-unused-parameter)

View File

@ -65,7 +65,7 @@ set_target_properties(${toluapp_lib} PROPERTIES
POSITION_INDEPENDENT_CODE TRUE)
target_include_directories(${toluapp_lib}
PUBLIC ${toluapp_include_dirs})
target_link_libraries(${toluapp_lib} PRIVATE ${LUA_LIBRARIES} ${CMAKE_DL_LIBS})
target_link_libraries(${toluapp_lib} PRIVATE Lua::Lua ${CMAKE_DL_LIBS})
if (MSVC)
target_compile_options(${toluapp_lib}
PRIVATE /W1)

View File

@ -24,7 +24,7 @@
function(sol2_add_example_properties target-name)
target_link_libraries(${target-name}
PUBLIC Threads::Threads ${LUA_LIBRARIES} ${CMAKE_DL_LIBS})
PUBLIC Threads::Threads Lua::Lua ${CMAKE_DL_LIBS})
target_compile_definitions(${target-name}
PUBLIC SOL_PRINT_ERRORS=1)
target_compile_options(${target-name}

View File

@ -50,7 +50,7 @@ function (MAKE_CUSTOMIZATION_EXAMPLE example_suffix target_sol)
endif()
target_link_libraries(${customization_example_name}
PRIVATE Threads::Threads ${target_sol} ${LUA_LIBRARIES})
PRIVATE Threads::Threads ${target_sol} Lua::Lua)
target_include_directories(${customization_example_name}
PRIVATE include)
endfunction()

View File

@ -30,7 +30,7 @@ function (make_luabridge_interop_example target_library example_suffix)
add_executable(${example_name} source/LuaBridge.cpp)
target_link_libraries(${example_name}
PRIVATE ${LUA_LIBRARIES} ${LUABRIDGE_LIBRARIES}
PRIVATE Lua::Lua ${LUABRIDGE_LIBRARIES}
${target_library} ${CMAKE_DL_LIBS})
if (MSVC)

View File

@ -30,7 +30,7 @@ function (make_kaguya_interop_example target_library example_suffix)
add_executable(${example_name} source/kaguya.cpp)
target_link_libraries(${example_name}
PRIVATE ${LUA_LIBRARIES} ${KAGUYA_LIBRARIES}
PRIVATE Lua::Lua ${KAGUYA_LIBRARIES}
${target_library} ${CMAKE_DL_LIBS})
if (MSVC)

View File

@ -30,7 +30,7 @@ function (make_luwra_interop_example target_library example_suffix)
add_executable(${example_name} source/luwra.cpp)
target_link_libraries(${example_name}
PRIVATE ${LUA_LIBRARIES} ${LUWRA_LIBRARIES}
PRIVATE Lua::Lua ${LUWRA_LIBRARIES}
${target_library} ${CMAKE_DL_LIBS})
if (MSVC)

View File

@ -31,7 +31,7 @@ function(make_tolua_interop_example target_library example_suffix)
add_executable(${example_name} source/tolua.cpp)
target_link_libraries(${example_name}
PRIVATE
${LUA_LIBRARIES} ${TOLUAPP_LIBRARIES} ${target_library} ${CMAKE_DL_LIBS})
Lua::Lua ${TOLUAPP_LIBRARIES} ${target_library} ${CMAKE_DL_LIBS})
if (MSVC)
target_compile_options(${example_name}

View File

@ -46,7 +46,7 @@ function(make_require_from_dll_example target_lib example_lib_name_suffix)
PUBLIC MY_OBJECT_DLL
PRIVATE MY_OBJECT_BUILD)
target_link_libraries(${example_lib_name}
PUBLIC ${target_lib} ${LUA_LIBRARIES} ${CMAKE_DL_LIBS})
PUBLIC ${target_lib} Lua::Lua ${CMAKE_DL_LIBS})
target_include_directories(${example_lib_name}
PUBLIC "${LUA_INCLUDE_DIRS}")
@ -83,7 +83,7 @@ function(make_require_from_dll_example target_lib example_lib_name_suffix)
# add executable target that represents require_from_dll program
add_executable(${example_name} ${require_from_dll_sources})
target_link_libraries(${example_name}
PRIVATE my_object ${LUA_LIBRARIES} ${target_lib} ${CMAKE_DL_LIBS})
PRIVATE my_object Lua::Lua ${target_lib} ${CMAKE_DL_LIBS})
target_include_directories(${example_name}
PRIVATE ${LUA_INCLUDE_DIRS})

47
include/sol/abort.hpp Normal file
View File

@ -0,0 +1,47 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 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_ABORT_HPP
#define SOL_ABORT_HPP
#include <sol/version.hpp>
#include <sol/base_traits.hpp>
#include <cstdlib>
// clang-format off
#if SOL_IS_ON(SOL_DEBUG_BUILD)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
#define SOL_DEBUG_ABORT() \
if (true) { ::std::abort(); } \
static_assert(true, "")
#else
#define SOL_DEBUG_ABORT() ::std::abort()
#endif
#else
#define SOL_DEBUG_ABORT() static_assert(true, "")
#endif
// clang-format on
#endif // SOL_ABORT_HPP

View File

@ -62,6 +62,39 @@ namespace sol {
template <template <class...> class Trait, class... Args>
constexpr inline bool is_detected_v = is_detected<Trait, Args...>::value;
template <typename _Default, typename _Void, template <typename...> typename _Op, typename... _Args>
class detector {
public:
using value_t = ::std::false_type;
using type = _Default;
};
template <typename _Default, template <typename...> typename _Op, typename... _Args>
class detector<_Default, void_t<_Op<_Args...>>, _Op, _Args...> {
public:
using value_t = ::std::true_type;
using type = _Op<_Args...>;
};
class nonesuch {
public:
~nonesuch() = delete;
nonesuch(nonesuch const&) = delete;
nonesuch& operator=(nonesuch const&) = delete;
};
template <template <typename...> typename _Op, typename... _Args>
using detected_t = typename detector<nonesuch, void, _Op, _Args...>::type;
template <typename _Default, template <typename...> typename _Op, typename... _Args>
using detected_or = detector<_Default, void, _Op, _Args...>;
template <typename _Default, template <typename...> typename _Op, typename... _Args>
using detected_or_t = typename detector<_Default, void, _Op, _Args...>::type;
template <typename _Default, template <typename...> typename _Op, typename... _Args>
constexpr inline bool detected_or_v = detector<_Default, void, _Op, _Args...>::value;
template <std::size_t I>
using index_value = std::integral_constant<std::size_t, I>;

View File

@ -34,18 +34,18 @@
#if SOL_IS_ON(SOL_USE_COMPATIBILITY_LAYER)
#if SOL_IS_ON(SOL_USE_CXX_LUA) || SOL_IS_ON(SOL_USE_CXX_LUAJIT)
#ifndef COMPAT53_LUA_CPP
#define COMPAT53_LUA_CPP 1
#endif // Build Lua Compat layer as C++
// clang-format off
#if SOL_IS_ON(SOL_USING_CXX_LUA) || SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#ifndef COMPAT53_LUA_CPP
#define COMPAT53_LUA_CPP 1
#endif // Build Lua Compat layer as C++
#endif
#ifndef COMPAT53_INCLUDE_SOURCE
#define COMPAT53_INCLUDE_SOURCE 1
#endif // Build Compat Layer Inline
#include <sol/compatibility/compat-5.3.h>
#include <sol/compatibility/compat-5.4.h>
#ifndef COMPAT53_INCLUDE_SOURCE
#define COMPAT53_INCLUDE_SOURCE 1
#endif // Build Compat Layer Inline
#include <sol/compatibility/compat-5.3.h>
#include <sol/compatibility/compat-5.4.h>
#endif
// clang-format on
#endif // SOL_COMPATIBILITY_HPP

View File

@ -28,7 +28,7 @@
// clang-format off
#if SOL_IS_ON(SOL_USE_CXX_LUA)
#if SOL_IS_ON(SOL_USING_CXX_LUA)
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
@ -54,7 +54,7 @@
#define SOL_USE_LUAJIT_I_ SOL_DEFAULT_OFF
#endif // luajit
#if SOL_IS_ON(SOL_USE_CXX_LUAJIT)
#if SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#include <luajit.h>
#elif SOL_IS_ON(SOL_USE_LUAJIT)
extern "C" {
@ -146,9 +146,9 @@
#else
#if SOL_IS_ON(SOL_USE_LUAJIT)
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
#elif SOL_IS_ON(SOL_USE_CXX_LUAJIT)
#elif SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
#elif SOL_IS_ON(SOL_USE_CXX_LUA)
#elif SOL_IS_ON(SOL_USING_CXX_LUA)
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
#else
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_ON
@ -192,7 +192,11 @@
#else
// Lua 5.2 only (deprecated in 5.3 (503)) (Can be turned on with Compat flags)
// Lua 5.2, or other versions of Lua with the compat flag, or Lua that is not 5.2 with the specific define (5.4.1 either removed it entirely or broke it)
#if (SOL_LUA_VERSION_I_ == 502) || (defined(LUA_COMPAT_BITLIB) && (LUA_COMPAT_BITLIB != 0)) || (SOL_LUA_VERSION_I_ < 504 && (defined(LUA_COMPAT_5_2) && (LUA_COMPAT_5_2 != 0)))
#if (SOL_LUA_VERSION_I_ == 502)
#define SOL_LUA_BIT32_LIB_I_ SOL_ON
#elif (defined(LUA_COMPAT_BITLIB) && (LUA_COMPAT_BITLIB != 0))
#define SOL_LUA_BIT32_LIB_I_ SOL_ON
#elif (SOL_LUA_VERSION_I_ < 504 && (defined(LUA_COMPAT_5_2) && (LUA_COMPAT_5_2 != 0)))
#define SOL_LUA_BIT32_LIB_I_ SOL_ON
#else
#define SOL_LUA_BIT32_LIB_I_ SOL_DEFAULT_OFF

View File

@ -30,7 +30,7 @@
#include <type_traits>
#include <string_view>
#if SOL_IS_ON(SOL_USE_CXX_LUA) || SOL_IS_ON(SOL_USE_CXX_LUAJIT)
#if SOL_IS_ON(SOL_USING_CXX_LUA) || SOL_IS_ON(SOL_USING_CXX_LUAJIT)
struct lua_State;
#else
extern "C" {
@ -253,7 +253,7 @@ namespace sol {
typedef ::sol::types<__VA_ARGS__> type; \
}; \
} \
void a_sol3_detail_function_decl_please_no_collide()
static_assert(true, "")
#define SOL_DERIVED_CLASSES(T, ...) \
namespace sol { \
template <> \
@ -261,6 +261,6 @@ namespace sol {
typedef ::sol::types<__VA_ARGS__> type; \
}; \
} \
void a_sol3_detail_function_decl_please_no_collide()
static_assert(true, "")
#endif // SOL_FORWARD_HPP

View File

@ -0,0 +1,44 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 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_FORWARD_AS_HPP
#define SOL_FORWARD_AS_HPP
#include <sol/version.hpp>
#include <utility>
#include <type_traits>
namespace sol {
template <typename T, typename U>
constexpr decltype(auto) forward_as(U&& value) noexcept {
if constexpr (::std::is_lvalue_reference_v<T>) {
return value;
}
else {
return ::std::move(value);
}
}
}
#endif // SOL_FORWARD_AS_HPP

View File

@ -32,6 +32,7 @@
#include <sol/overload.hpp>
#include <sol/error.hpp>
#include <sol/unicode.hpp>
#include <sol/abort.hpp>
#include <memory>
#include <functional>
@ -212,11 +213,9 @@ namespace sol { namespace stack {
}
actual r {};
if constexpr (!derive<element>::value) {
#if SOL_IS_ON(SOL_DEBUG_BUILD)
// In debug mode we would rather abort you for this grave failure rather
// than let you deref a null pointer and fuck everything over
std::abort();
#endif
SOL_DEBUG_ABORT();
return static_cast<actual>(std::move(r));
}
else {
@ -249,11 +248,7 @@ namespace sol { namespace stack {
// uh oh..
break;
}
#if SOL_IS_ON(SOL_DEBUG_BUILD)
// In debug mode we would rather abort you for this grave failure rather
// than let you deref a null pointer and fuck everything over
std::abort();
#endif
SOL_DEBUG_ABORT();
return static_cast<actual>(r);
}
}

View File

@ -530,8 +530,20 @@ namespace sol { namespace meta {
template <typename T>
using non_void_t = meta::conditional_t<std::is_void_v<T>, ::sol::detail::unchecked_t, T>;
template <typename T>
using detect_sentinel = typename T::sentinel;
} // namespace meta_detail
template <typename T, typename Fallback>
class sentinel_or {
public:
using type = detected_or_t<Fallback, meta_detail::detect_sentinel, T>;
};
template <typename T, typename Fallback>
using sentinel_or_t = typename sentinel_or<T, Fallback>::type;
template <typename T, typename U = T>
class supports_op_less : public meta_detail::supports_op_less_test<T, U> { };
@ -626,11 +638,12 @@ namespace sol { namespace meta {
constexpr inline bool is_string_literal_array_of_v = is_string_literal_array_of<T, CharT>::value;
template <typename T>
using is_string_literal_array = boolean<std::is_array_v<T> && any_same_v<std::remove_all_extents_t<T>, char,
using is_string_literal_array = boolean<std::is_array_v<T>
&& any_same_v<std::remove_all_extents_t<T>, char,
#if SOL_IS_ON(SOL_CHAR8_T)
char8_t,
char8_t,
#endif
char16_t, char32_t, wchar_t>>;
char16_t, char32_t, wchar_t>>;
template <typename T>
constexpr inline bool is_string_literal_array_v = is_string_literal_array<T>::value;
@ -661,9 +674,8 @@ namespace sol { namespace meta {
constexpr inline bool is_string_like_v = is_string_like<T>::value;
template <typename T, typename CharT = char>
using is_string_constructible = meta::boolean<
is_string_literal_array_of_v<T,
CharT> || std::is_same_v<T, const CharT*> || std::is_same_v<T, CharT> || is_string_of_v<T, CharT> || std::is_same_v<T, std::initializer_list<CharT>> || is_string_view_of_v<T, CharT> || std::is_null_pointer_v<T>>;
using is_string_constructible = meta::boolean<is_string_literal_array_of_v<T, CharT> || std::is_same_v<T, const CharT*> || std::is_same_v<T, CharT>
|| is_string_of_v<T, CharT> || std::is_same_v<T, std::initializer_list<CharT>> || is_string_view_of_v<T, CharT> || std::is_null_pointer_v<T>>;
template <typename T, typename CharT = char>
constexpr inline bool is_string_constructible_v = is_string_constructible<T, CharT>::value;
@ -733,7 +745,6 @@ namespace sol { namespace meta {
struct iterator_tag<T, conditional_t<false, typename std::iterator_traits<T>::iterator_category, void>> {
using type = typename std::iterator_traits<T>::iterator_category;
};
}} // namespace sol::meta
}} // namespace sol::meta
#endif // SOL_TRAITS_HPP

View File

@ -0,0 +1,37 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 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_UNREACHABLE_HPP
#define SOL_UNREACHABLE_HPP
#include <sol/version.hpp>
#if SOL_HAS_BUILTIN_I_(__builtin_unreachable)
#define SOL_UNREACHABLE() __builtin_unreachable();
#elif SOL_IS_ON(SOL_COMPILER_VCXX)
#define SOL_UNREACHABLE() __assume(false);
#else
#define SOL_UNREACHABLE() __builtin_unreachable();
#endif
#endif

View File

@ -400,6 +400,7 @@ namespace sol {
public:
typedef lua_nil_t iterator;
typedef iterator sentinel;
typedef lua_nil_t value_type;
static int at(lua_State* L_) {
@ -472,7 +473,7 @@ namespace sol {
return lua_nil;
}
static iterator end(lua_State* L_, T&) {
static sentinel end(lua_State* L_, T&) {
luaL_error(L_, "sol: cannot call 'end' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
return lua_nil;
}
@ -492,6 +493,7 @@ namespace sol {
using is_ordered = meta::is_ordered<T>;
using is_matched_lookup = meta::is_matched_lookup<T>;
using iterator = typename T::iterator;
using sentinel = meta::sentinel_or_t<T, iterator>;
using value_type = typename T::value_type;
typedef meta::conditional_t<is_matched_lookup::value, std::pair<value_type, value_type>,
meta::conditional_t<is_associative::value || is_lookup::value, value_type, std::pair<std::ptrdiff_t, value_type>>>
@ -511,16 +513,30 @@ namespace sol {
typedef meta::unqualified_t<decltype(get_key(is_associative(), std::declval<std::add_lvalue_reference_t<value_type>>()))> key_type;
typedef meta::all<std::is_integral<K>, meta::neg<meta::any<is_associative, is_lookup>>> is_linear_integral;
struct iter {
reference keep_alive;
T& source;
iterator it;
struct iter : detail::ebco<iterator, 0>, detail::ebco<sentinel, 1> {
using it_base = detail::ebco<iterator, 0>;
using sen_base = detail::ebco<sentinel, 1>;
main_reference keep_alive;
std::size_t index;
iter(lua_State* L_, int stack_index, T& source_, iterator it_) : keep_alive(sol::main_thread(L_, L_), stack_index), source(source_), it(std::move(it_)), index(0) {
iter(lua_State* L_, int stack_index_, iterator it_, sentinel sen_) noexcept
: it_base(std::move(it_)), sen_base(std::move(sen_)), keep_alive(L_, stack_index_), index(0) {
}
~iter() {
iterator& it() noexcept {
return it_base::value();
}
const iterator& it() const noexcept {
return it_base::value();
}
sentinel& sen() noexcept {
return sen_base::value();
}
const sentinel& sen() const noexcept {
return sen_base::value();
}
};
@ -1172,9 +1188,9 @@ namespace sol {
template <bool ip>
static int next_associative(std::true_type, lua_State* L_) {
iter& i = stack::unqualified_get<user<iter>>(L_, 1);
auto& source = i.source;
auto& it = i.it;
if (it == deferred_uc::end(L_, source)) {
auto& end = i.end;
if (it == end) {
return stack::push(L_, lua_nil);
}
int p;
@ -1193,10 +1209,10 @@ namespace sol {
template <bool>
static int next_associative(std::false_type, lua_State* L_) {
iter& i = stack::unqualified_get<user<iter>>(L_, 1);
auto& source = i.source;
auto& it = i.it;
auto& it = i.it();
auto& end = i.sen();
next_K k = stack::unqualified_get<next_K>(L_, 2);
if (it == deferred_uc::end(L_, source)) {
if (it == end) {
return stack::push(L_, lua_nil);
}
int p;
@ -1221,7 +1237,7 @@ namespace sol {
static int pairs_associative(std::true_type, lua_State* L_) {
auto& src = get_src(L_);
stack::push(L_, next_iter<ip>);
stack::push<user<iter>>(L_, L_, 1, src, deferred_uc::begin(L_, src));
stack::push<user<iter>>(L_, L_, 1, deferred_uc::begin(L_, src), deferred_uc::begin(L_, src));
stack::push(L_, lua_nil);
return 3;
}
@ -1230,7 +1246,7 @@ namespace sol {
static int pairs_associative(std::false_type, lua_State* L_) {
auto& src = get_src(L_);
stack::push(L_, next_iter<ip>);
stack::push<user<iter>>(L_, L_, 1, src, deferred_uc::begin(L_, src));
stack::push<user<iter>>(L_, L_, 1, deferred_uc::begin(L_, src), deferred_uc::end(L_, src));
stack::push(L_, 0);
return 3;
}
@ -1322,7 +1338,7 @@ namespace sol {
}
}
static iterator end(lua_State*, T& self) {
static sentinel end(lua_State*, T& self) {
if constexpr (meta::has_begin_end_v<T>) {
return self.end();
}
@ -1387,19 +1403,32 @@ namespace sol {
public:
typedef std::remove_extent_t<T> value_type;
typedef value_type* iterator;
typedef iterator sentinel;
private:
struct iter {
struct iter : detail::ebco<iterator, 0>, detail::ebco<sentinel, 1> {
using it_base = detail::ebco<iterator, 0>;
using sen_base = detail::ebco<sentinel, 1>;
reference keep_alive;
T& source;
iterator it;
iter(lua_State* L_, int stack_index, T& source, iterator it) noexcept
: keep_alive(sol::main_thread(L_, L_), stack_index), source(source), it(std::move(it)) {
iter(lua_State* L_, int stack_index_, iterator it_, sentinel sen_) noexcept
: it_base(std::move(it_)), sen_base(std::move(sen_)), keep_alive(sol::main_thread(L_, L_), stack_index_) {
}
~iter() {
iterator& it() noexcept {
return it_base::value();
}
const iterator& it() const noexcept {
return it_base::value();
}
sentinel& sen() noexcept {
return sen_base::value();
}
const sentinel& sen() const noexcept {
return sen_base::value();
}
};
@ -1440,10 +1469,10 @@ namespace sol {
static int next_iter(lua_State* L_) {
iter& i = stack::unqualified_get<user<iter>>(L_, 1);
auto& source = i.source;
auto& it = i.it;
auto& it = i.it();
auto& end = i.sen();
std::size_t k = stack::unqualified_get<std::size_t>(L_, 2);
if (it == deferred_uc::end(L_, source)) {
if (it == end) {
return 0;
}
int p;
@ -1525,7 +1554,7 @@ namespace sol {
static int pairs(lua_State* L_) {
auto& src = get_src(L_);
stack::push(L_, next_iter);
stack::push<user<iter>>(L_, L_, 1, src, deferred_uc::begin(L_, src));
stack::push<user<iter>>(L_, L_, 1, deferred_uc::begin(L_, src), deferred_uc::end(L_, src));
stack::push(L_, 0);
return 3;
}
@ -1546,7 +1575,7 @@ namespace sol {
return std::addressof(self[0]);
}
static iterator end(lua_State*, T& self) {
static sentinel end(lua_State*, T& self) {
return std::addressof(self[0]) + std::extent<T>::value;
}
};

View File

@ -89,6 +89,14 @@
#include <climits>
#endif
#if defined(SOL_HAS_BUILTIN)
#define SOL_HAS_BUILTIN_I_(...) SOL_HAS_BUILTIN(__VA_ARGS__)
#elif defined(__has_builtin)
#define SOL_HAS_BUILTIN_I_(...) __has_builtin(__VA_ARGS__)
#else
#define SOL_HAS_BUILTIN_I_(...) 0
#endif
#if defined(SOL_COMPILER_VCXX)
#if defined(SOL_COMPILER_VCXX != 0)
#define SOL_COMPILER_VCXX_I_ SOL_ON
@ -638,34 +646,35 @@
#if defined(SOL_USING_CXX_LUA)
#if (SOL_USING_CXX_LUA != 0)
#define SOL_USE_CXX_LUA_I_ SOL_ON
#define SOL_USING_CXX_LUA_I_ SOL_ON
#else
#define SOL_USE_CXX_LUA_I_ SOL_OFF
#define SOL_USING_CXX_LUA_I_ SOL_OFF
#endif
#elif defined(SOL_USE_CXX_LUA)
// alternative spelling
#if (SOL_USE_CXX_LUA != 0)
#define SOL_USE_CXX_LUA_I_ SOL_ON
#define SOL_USING_CXX_LUA_I_ SOL_ON
#else
#define SOL_USE_CXX_LUA_I_ SOL_OFF
#define SOL_USING_CXX_LUA_I_ SOL_OFF
#endif
#else
#define SOL_USE_CXX_LUA_I_ SOL_DEFAULT_OFF
#define SOL_USING_CXX_LUA_I_ SOL_DEFAULT_OFF
#endif
#if defined(SOL_USING_CXX_LUAJIT)
#if (SOL_USING_CXX_LUA != 0)
#define SOL_USE_CXX_LUAJIT_I_ SOL_ON
#if (SOL_USING_CXX_LUAJIT != 0)
#define SOL_USING_CXX_LUAJIT_I_ SOL_ON
#else
#define SOL_USE_CXX_LUAJIT_I_ SOL_OFF
#define SOL_USING_CXX_LUAJIT_I_ SOL_OFF
#endif
#elif defined(SOL_USE_CXX_LUAJIT)
#if (SOL_USE_CXX_LUA != 0)
#define SOL_USE_CXX_LUAJIT_I_ SOL_ON
#if (SOL_USE_CXX_LUAJIT != 0)
#define SOL_USING_CXX_LUAJIT_I_ SOL_ON
#else
#define SOL_USE_CXX_LUAJIT_I_ SOL_OFF
#define SOL_USING_CXX_LUAJIT_I_ SOL_OFF
#endif
#else
#define SOL_USE_CXX_LUAJIT_I_ SOL_DEFAULT_OFF
#define SOL_USING_CXX_LUAJIT_I_ SOL_DEFAULT_OFF
#endif
#if defined(SOL_NO_LUA_HPP)
@ -674,7 +683,7 @@
#else
#define SOL_USE_LUA_HPP_I_ SOL_ON
#endif
#elif defined(SOL_USING_CXX_LUA)
#elif SOL_IS_ON(SOL_USING_CXX_LUA)
#define SOL_USE_LUA_HPP_I_ SOL_OFF
#elif defined(__has_include)
#if __has_include(<lua.hpp>)

View File

@ -34,10 +34,10 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/include/sol"
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/single.py" --input "${CMAKE_CURRENT_SOURCE_DIR}/../include" --output "${CMAKE_CURRENT_BINARY_DIR}/include/sol/sol.hpp"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/single.py" "${sol2_generated_header_sources}"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/sol/sol.hpp" "${CMAKE_CURRENT_BINARY_DIR}/include/sol/forward.hpp")
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/sol/sol.hpp" "${CMAKE_CURRENT_BINARY_DIR}/include/sol/forward.hpp" "${CMAKE_CURRENT_BINARY_DIR}/include/sol/config.hpp")
add_custom_target(sol2_single_header_generator ALL
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/single.py"
"${CMAKE_CURRENT_BINARY_DIR}/include/sol/sol.hpp" "${CMAKE_CURRENT_BINARY_DIR}/include/sol/forward.hpp"
"${CMAKE_CURRENT_BINARY_DIR}/include/sol/sol.hpp" "${CMAKE_CURRENT_BINARY_DIR}/include/sol/forward.hpp" "${CMAKE_CURRENT_BINARY_DIR}/include/sol/config.hpp"
"${sol2_generated_header_sources}")
# # # sol3 generated single header library

View File

@ -107,10 +107,10 @@ intro = """// The MIT License (MIT)
"""
includes = set([])
standard_include = re.compile(r'#include <(.*?)>')
local_include = re.compile(r'#(\s*?)include "(.*?)"')
project_include = re.compile(r'#(\s*?)include <(sol/.*?)>')
project_config_include = re.compile(r'#(\s*?)include <sol/config.hpp>')
standard_include = re.compile(r'\s*#include <(.*?)>')
local_include = re.compile(r'\s*#(\s*?)include "(.*?)"')
project_include = re.compile(r'\s*#(\s*?)include <(sol/.*?)>')
project_config_include = re.compile(r'\s*#(\s*?)include <sol/config.hpp>')
pragma_once_cpp = re.compile(r'(\s*)#(\s*)pragma(\s+)once')
ifndef_cpp = re.compile(r'#ifndef SOL_.*?_HPP')
define_cpp = re.compile(r'#define SOL_.*?_HPP')
@ -223,9 +223,9 @@ def process_file(filename, out):
version = get_version()
revision = get_revision()
include_guard = 'SOL_SINGLE_INCLUDE_HPP'
forward_include_guard = 'SOL_SINGLE_INCLUDE_FORWARD_HPP'
config_include_guard = 'SOL_SINGLE_CONFIG_HPP'
include_guard = 'SOL_SINGLE_INCLUDE_SOL_HPP'
forward_include_guard = 'SOL_SINGLE_INCLUDE_SOL_FORWARD_HPP'
config_include_guard = 'SOL_SINGLE_SOL_CONFIG_HPP'
processed_files = [os.path.join(script_path, x) for x in ['sol/sol.hpp']]
forward_processed_files = [

View File

@ -24,15 +24,15 @@
# # Dependencies
FetchContent_Declare(
catch2
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG devel
)
FetchContent_MakeAvailable(catch2)
FetchContent_MakeAvailable(Catch2)
function(sol2_add_test_properties target-name)
target_link_libraries(${target-name}
PUBLIC Threads::Threads ${LUA_LIBRARIES} Catch2::Catch2 ${CMAKE_DL_LIBS})
PUBLIC Threads::Threads Lua::Lua Catch2::Catch2 ${CMAKE_DL_LIBS})
target_compile_definitions(${target-name}
PUBLIC SOL_PRINT_ERRORS=1)
target_compile_options(${target-name}
@ -84,6 +84,7 @@ endfunction()
add_subdirectory(inclusion)
add_subdirectory(container_exhaustive)
add_subdirectory(coroutines)
add_subdirectory(enum)
add_subdirectory(environment)
add_subdirectory(exceptions)

View File

@ -0,0 +1,40 @@
# # # # sol2
# The MIT License (MIT)
#
# Copyright (c) 2013-2022 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.
# # # # sol2 tests - special configurations - unsafe function pointers
file(GLOB sources
LIST_DIRECTORIES FALSE
CONFIGURE_DEPENDS
source/*.cpp)
sol2_create_basic_test(sol2.tests.coroutines sol2::sol2 ${sources})
sol2_create_basic_test(sol2.tests.coroutines.SOL_ALL_SAFETIES_ON sol2::sol2 ${sources})
target_compile_definitions(sol2.tests.coroutines PRIVATE
SOL_GET_FUNCTION_POINTER_UNSAFE=1)
target_compile_definitions(sol2.tests.coroutines.SOL_ALL_SAFETIES_ON PRIVATE
SOL_ALL_SAFETIES_ON=1 SOL_GET_FUNCTION_POINTER_UNSAFE=1)
if (SOL2_TESTS_SINGLE)
sol2_create_basic_test(sol2.single.tests.coroutines sol2::sol2::single ${sources})
target_compile_definitions(sol2.single.tests.coroutines PRIVATE
SOL_GET_FUNCTION_POINTER_UNSAFE=1)
endif()

View File

@ -0,0 +1,185 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 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 <catch2/catch_all.hpp>
#include <sol/sol.hpp>
#include <vector>
#include <memory>
#include <iterator>
inline namespace sol2_regression_test_coroutines_array_proxy_lifetime {
struct A {
public:
A(int value_) : value(value_) {
}
int value;
int getValue() {
return value;
}
std::vector<std::shared_ptr<A>> children;
};
struct ArrayProxy {
using value_type = std::weak_ptr<A>;
struct iterator {
using iterator_category = std::random_access_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = std::weak_ptr<A>;
using pointer = std::weak_ptr<A>*; // or also value_type*
using reference = std::weak_ptr<A>&; // or also value_type&
const ArrayProxy& a;
size_t index;
iterator(const ArrayProxy& a_, size_t index_) : a(a_), index(index_) {
}
value_type operator*() const {
size_t size = a.mpParent.children.size();
if (index >= 0 && index < size) {
return a.mpParent.children[index];
}
return std::weak_ptr<A>();
}
// Operators : arithmetic
inline iterator& operator++() {
++index;
return *this;
}
inline iterator& operator--() {
--index;
return *this;
}
inline iterator& operator+=(const size_t& rhs) {
index += rhs;
return *this;
}
inline iterator& operator-=(const size_t& rhs) {
index -= rhs;
return *this;
}
// Operators : comparison
inline bool operator==(const iterator& rhs) {
return index == rhs.index;
}
inline bool operator!=(const iterator& rhs) {
return index != rhs.index;
}
inline bool operator>(const iterator& rhs) {
return index > rhs.index;
}
inline bool operator<(const iterator& rhs) {
return index < rhs.index;
}
inline bool operator>=(const iterator& rhs) {
return index >= rhs.index;
}
inline bool operator<=(const iterator& rhs) {
return index <= rhs.index;
}
};
ArrayProxy(const A& parent) : mpParent(parent) {
}
~ArrayProxy() {
}
auto begin() const {
return iterator(*this, 0);
}
auto end() const {
return iterator(*this, mpParent.children.size());
}
size_t size() const {
return mpParent.children.size();
}
const A& mpParent;
};
static ArrayProxy getChildren(const A& a) {
return ArrayProxy(a);
}
} // namespace sol2_regression_test_coroutines_array_proxy_lifetime
namespace sol {
template <typename T>
struct unique_usertype_traits<std::weak_ptr<T>> {
static T* get(lua_State*, const std::weak_ptr<T>& ptr) noexcept {
return ptr.lock().get();
}
static bool is_null(lua_State*, const std::weak_ptr<T>& ptr) noexcept {
return ptr.expired();
}
};
template <>
struct is_container<ArrayProxy> : std::true_type { };
} // namespace sol
TEST_CASE("test for issue #1400 - array proxy tests", "[sol2][regression][issue-1400]") {
sol::state lua;
lua.open_libraries(
sol::lib::base, sol::lib::package, sol::lib::table, sol::lib::debug, sol::lib::string, sol::lib::math, sol::lib::bit32, sol::lib::coroutine);
const int outer = 10;
const int inner = 100;
A a(0);
for (int i = 0; i < outer; i++) {
auto child = std::make_shared<A>(i * outer);
for (int j = 0; j < inner; j++) {
auto child2 = std::make_shared<A>(i * outer + j);
child->children.push_back(child2);
}
a.children.push_back(child);
}
lua.new_usertype<A>("A", "value", sol::property(&A::getValue), "children", sol::property(&getChildren));
lua.globals()["A"] = &a;
const auto& code = R"(
print(A.value)
for i=1, 10 do
co = coroutine.create( function()
print("A")
for _, child in pairs(A.children) do
for _, child2 in pairs(child.children) do
print(child2.value)
end
end
end)
coroutine.resume(co)
end
)";
// call lua code directly
sol::optional<sol::error> result = lua.safe_script(code);
REQUIRE_FALSE(result.has_value());
}

View File

@ -0,0 +1,31 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 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 CATCH_CONFIG_RUNNER
#include <catch2/catch_all.hpp>
int main(int argc, char* argv[]) {
int result = Catch::Session().run(argc, argv);
return result;
}

View File

@ -0,0 +1,96 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 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 <catch2/catch_all.hpp>
#include <sol/sol.hpp>
inline namespace sol2_regression_test_coroutines_properties_lifetime {
struct A {
public:
A() {
}
sol::object index(sol::object key) {
if (mProperties.valid()) {
auto prop = mProperties[key];
return prop.get<sol::object>();
}
return sol::object();
}
void new_index(sol::object key, sol::object value, sol::this_main_state L) {
if (!mProperties.valid()) {
sol::state_view lua(L);
mProperties = lua.create_table();
}
if (mProperties.lua_state() != key.lua_state()) {
std::cout << "scream A" << std::endl;
}
if (mProperties.lua_state() != value.lua_state()) {
std::cout << "scream B" << std::endl;
}
if (mProperties.lua_state() != L.lua_state()) {
std::cout << "scream C" << std::endl;
}
mProperties[key] = value;
}
protected:
// ❗❗ Here ❗❗
sol::main_table mProperties;
};
} // namespace sol2_regression_test_coroutines_properties_lifetime
TEST_CASE("issue #1374 - coroutine lifetime tests (using main_* classes)", "[sol2][regression][issue-1374]") {
sol::state lua;
A a;
lua.open_libraries(
sol::lib::base, sol::lib::package, sol::lib::table, sol::lib::debug, sol::lib::string, sol::lib::math, sol::lib::bit32, sol::lib::coroutine);
lua.new_usertype<A>("A", sol::meta_function::index, &A::index, sol::meta_function::new_index, &A::new_index);
lua["A"] = &a;
const auto& code = R"(
for i=1, 300 do
co = coroutine.create( function()
A.foo = 7
A.bar = {}
for j=1, 170 do
A.bar[j] = j
end
end)
coroutine.resume(co)
print(A.foo)
for _, value in pairs(A.bar) do
print(value)
end
end)";
// call lua code directly
sol::optional<sol::error> result = lua.safe_script(code);
REQUIRE_FALSE(result.has_value());
}

View File

@ -34,7 +34,7 @@ inline namespace sol2_regression_test_1000 {
};
} // namespace sol2_regression_test_1000
TEST_CASE("Test for Issue #1000 - readonly warning", "[sol2][regression][Issue-1000]") {
TEST_CASE("issue #1000 - readonly warning", "[sol2][regression][issue1000]") {
sol::state lua;
lua.create_named_table("t");

View File

@ -25,7 +25,7 @@
#include <sol/sol.hpp>
TEST_CASE("Test for Issue #1008 - as_function binding must trigger correctly", "[sol2][regression][Issue-1008]") {
TEST_CASE("issue #1008 - as_function binding must trigger correctly", "[sol2][regression][issue1008]") {
sol::state lua;
lua.create_named_table("t");

View File

@ -25,7 +25,7 @@
#include <sol/sol.hpp>
TEST_CASE("Test for Issue #1067 - as_function binding not triggering properly", "[sol2][regression][Issue-1067]") {
TEST_CASE("issue #1067 - as_function binding not triggering properly", "[sol2][regression][issue1067]") {
sol::state lua;
lua.open_libraries(sol::lib::base);

View File

@ -25,7 +25,7 @@
#include <sol/sol.hpp>
TEST_CASE("Test for Issue #1072 - capture exception propagation", "[sol2][regression][Issue-1072]") {
TEST_CASE("issue #1072 - capture exception propagation", "[sol2][regression][issue1072]") {
auto lua = sol::state {};
// If you remove the capture, the problem goes away.
lua["foo"] = [&] { throw std::runtime_error(""); };

View File

@ -31,7 +31,7 @@ inline namespace sol2_regression_test_1087 {
};
} // namespace sol2_regression_test_1087
TEST_CASE("Test for Issue #1087 - readonly property error checking", "[sol2][regression][Issue-1087]") {
TEST_CASE("issue #1087 - readonly property error checking", "[sol2][regression][issue1087]") {
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<MyStruct>("MyStruct", "prop", sol::readonly_property(&MyStruct::prop));

View File

@ -28,7 +28,7 @@
#include <iostream>
#include <string>
TEST_CASE("Test for Issue #1095 - raw_get from global table should NOT fail at all", "[sol2][regression][Issue-1095]") {
TEST_CASE("issue #1095 - raw_get from global table should NOT fail at all", "[sol2][regression][issue1095]") {
const std::string magic_value = "test_value";
sol::state lua;

View File

@ -35,7 +35,7 @@ inline namespace sol2_regression_test_1096 {
}
} // namespace sol2_regression_test_1096
TEST_CASE("Test for Issue #1096 - checking different functions/lambdas/structures bind as intendedcorrectly", "[sol2][regression][Issue-1096]") {
TEST_CASE("issue #1096 - checking different functions/lambdas/structures bind as intendedcorrectly", "[sol2][regression][issue1096]") {
sol::state lua;
lua.open_libraries(sol::lib::base);

View File

@ -40,7 +40,7 @@ inline namespace sol2_regression_test_1144 {
}
} // namespace sol2_regression_test_1144
TEST_CASE("Test for Issue #1144 -", "[sol2][regression][Issue-1144]") {
TEST_CASE("issue #1144 -", "[sol2][regression][issue1144]") {
sol::state state;
bind_class(state);
sol::protected_function_result pr = state.do_string("local a = MyClass();");

View File

@ -36,7 +36,7 @@ inline namespace sol2_regression_test_1149 {
};
} // namespace sol2_regression_test_1149
TEST_CASE("Test for Issue #1149 - static method should not be morphed to const and error internally", "[sol2][regression][Issue-1149]") {
TEST_CASE("issue #1149 - static method should not be morphed to const and error internally", "[sol2][regression][issue1149]") {
sol::state lua = {};
auto T = lua.new_usertype<Test>("Test");
// Does compile ok.

View File

@ -37,7 +37,7 @@ inline namespace sol2_regression_test_1192 {
};
} // namespace sol2_regression_test_1192
TEST_CASE("Test for Issue #1192 - alignment test should not fail for strangely-aligned / over-aligned objects", "[sol2][regression][Issue-1192]") {
TEST_CASE("issue #1192 - alignment test should not fail for strangely-aligned / over-aligned objects", "[sol2][regression][issue1192]") {
sol::state lua;
static_assert(sizeof(Test) == 8);

View File

@ -25,7 +25,7 @@
#include <sol/sol.hpp>
TEST_CASE("Test for Issue #1211 - default-constructed protected_function_result should destruct fine", "[sol2][regression][Issue-1211]") {
TEST_CASE("issue #1211 - default-constructed protected_function_result should destruct fine", "[sol2][regression][issue1211]") {
{
// Should destruct properly, without issue.
[[maybe_unused]] sol::protected_function_result let_die;

View File

@ -27,7 +27,7 @@
#include <string>
TEST_CASE("Test for Issue #1266 - add method in Lua 5.4 exposes freelist in table, unfortunately", "[sol2][regression][Issue-1266]") {
TEST_CASE("issue #1266 - add method in Lua 5.4 exposes freelist in table, unfortunately", "[sol2][regression][issue1266]") {
sol::state lua;
lua.open_libraries(sol::lib::base);

View File

@ -49,7 +49,7 @@ inline namespace sol2_regression_test_1315 {
} // namespace sol2_regression_test_1315
TEST_CASE("Test for Issue #1315 - memory keep-alive with iteration functions, using a pointer", "[sol2][regression][Issue-1315][pointer]") {
TEST_CASE("issue #1315 - memory keep-alive with iteration functions, using a pointer", "[sol2][regression][issue1315][pointer]") {
sol::state lua;
lua.open_libraries(sol::lib::base, sol::lib::coroutine);

View File

@ -88,11 +88,11 @@ end
REQUIRE(r.valid());
}
{
auto r = lua.safe_script("c[Issue-c + 1] = 18", sol::script_pass_on_error);
auto r = lua.safe_script("c[issuec + 1] = 18", sol::script_pass_on_error);
REQUIRE(r.valid());
}
{
auto r = lua.safe_script("v3 = c[Issue-c]", sol::script_pass_on_error);
auto r = lua.safe_script("v3 = c[issuec]", sol::script_pass_on_error);
REQUIRE(r.valid());
}
auto backit = items.begin();

View File

@ -387,8 +387,8 @@ function f_fill(vec)
end
function f_append(vec)
print("#vec in lua: " .. #vec)
vec[Issue-vec] = -10456407
vec[Issue-vec + 1] = -54
vec[issuevec] = -10456407
vec[issuevec + 1] = -54
print("#vec in lua: " .. #vec)
end
)",