mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Update patrons
Reduce compile-times by removing lambda shenanigans and moving data that is already serialized into runtime systems to runtime Fix bugs with precedence ordering related to index and new_index Prepare to add 20000 more if constexpr to reduce compile-times even further.
This commit is contained in:
parent
0a21fbf3f0
commit
59174e76af
@ -1,18 +1,26 @@
|
|||||||
# Donators! ♥
|
# 🎉 Donators! ♥ 🎉
|
||||||
|
|
||||||
Thank you to all patrons, donators and contributors who help keep sol2 amazing.
|
Thank you to all patrons, donators and contributors who help keep sol2 amazing.
|
||||||
|
|
||||||
Robert Salvet
|
- Robert Salvet
|
||||||
Ορφέας Ζαφείρης - 2x Donations!
|
- Ορφέας Ζαφείρης - 2x Donations!
|
||||||
Michael Wallar
|
- Michael Wallar
|
||||||
Johannes Schultz
|
- Johannes Schultz
|
||||||
Dailidzionak Ilya
|
- Dailidzionak Ilya
|
||||||
|
- BECKMANN & EGLE Industrieelektronik GmbH [bue.de](https://www.bue.de/)
|
||||||
|
|
||||||
|
|
||||||
# Patrons
|
# 🎉 Patrons! ♥ 🎉
|
||||||
|
|
||||||
Beyond just a one-time donation, patrons make a continued commitment to help keep sol2 supported and bug-free. Thank you for your patronage! Here are the supporters that wanted to be featured as sol2 contributors.
|
Beyond just a one-time donation, patrons make a continued commitment to help keep sol2 supported and bug-free. Thank you for your patronage! Here are the supporters that wanted to be featured as sol2 contributors.
|
||||||
|
|
||||||
Michael Caisse
|
- Michael Caisse
|
||||||
Joshua Fisher
|
- Joshua Fisher
|
||||||
|
- Ορφέας Ζαφείρης
|
||||||
|
|
||||||
|
|
||||||
|
# Company Patrons / Supporters #
|
||||||
|
|
||||||
|
Companies who sign up for a long-term support contract or patronage are listed here! They really push forward what's possible with sol2 (and the newer v3)! Please reach out to phdofthehouse@gmail.com if you are interested in a custom solution or a long-term support contract that goes beyond the current release's needs!
|
||||||
|
|
||||||
|
- Intrepid Control Systems [intrepidcs.com](https://www.intrepidcs.com/)
|
||||||
|
@ -1,233 +0,0 @@
|
|||||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
||||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
|
||||||
|
|
||||||
#.rst:
|
|
||||||
# FindLua
|
|
||||||
# -------
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Locate Lua library. This module defines
|
|
||||||
#
|
|
||||||
# ::
|
|
||||||
#
|
|
||||||
# LUA_FOUND - if false, do not try to link to Lua
|
|
||||||
# LUA_LIBRARIES - both lua and lualib
|
|
||||||
# LUA_INCLUDE_DIR - where to find lua.h
|
|
||||||
# LUA_LIBRARY_DIR - Dir(s) where Lua libraries are found
|
|
||||||
# LUA_VERSION_STRING - the version of Lua found
|
|
||||||
# LUA_VERSION_MAJOR - the major version of Lua
|
|
||||||
# LUA_VERSION_MINOR - the minor version of Lua
|
|
||||||
# LUA_VERSION_PATCH - the patch version of Lua
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Note that the expected include convention is
|
|
||||||
#
|
|
||||||
# ::
|
|
||||||
#
|
|
||||||
# #include "lua.h"
|
|
||||||
#
|
|
||||||
# and not
|
|
||||||
#
|
|
||||||
# ::
|
|
||||||
#
|
|
||||||
# #include <lua/lua.h>
|
|
||||||
#
|
|
||||||
# This is because, the lua location is not standardized and may exist in
|
|
||||||
# locations other than lua/
|
|
||||||
|
|
||||||
unset(_lua_include_subdirs)
|
|
||||||
unset(_lua_append_versions)
|
|
||||||
unset(_lua_library_names)
|
|
||||||
|
|
||||||
|
|
||||||
include(${CMAKE_CURRENT_LIST_DIR}/FindLua/set_version_vars.cmake)
|
|
||||||
include(${CMAKE_CURRENT_LIST_DIR}/FindLua/version_check.cmake)
|
|
||||||
|
|
||||||
# # this is a function only to have all the variables inside go away automatically
|
|
||||||
# function(_lua_set_version_vars)
|
|
||||||
# set(LUA_VERSIONS5 5.3 5.2 5.1 5.0)
|
|
||||||
|
|
||||||
# if (Lua_FIND_VERSION_EXACT)
|
|
||||||
# if (Lua_FIND_VERSION_COUNT GREATER 1)
|
|
||||||
# set(_lua_append_versions ${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR})
|
|
||||||
# endif ()
|
|
||||||
# elseif (Lua_FIND_VERSION)
|
|
||||||
# # once there is a different major version supported this should become a loop
|
|
||||||
# if (NOT Lua_FIND_VERSION_MAJOR GREATER 5)
|
|
||||||
# if (Lua_FIND_VERSION_COUNT EQUAL 1)
|
|
||||||
# set(_lua_append_versions ${LUA_VERSIONS5})
|
|
||||||
# else ()
|
|
||||||
# foreach (subver IN LISTS LUA_VERSIONS5)
|
|
||||||
# if (NOT subver VERSION_LESS ${Lua_FIND_VERSION})
|
|
||||||
# list(APPEND _lua_append_versions ${subver})
|
|
||||||
# endif ()
|
|
||||||
# endforeach ()
|
|
||||||
# endif ()
|
|
||||||
# endif ()
|
|
||||||
# else ()
|
|
||||||
# # once there is a different major version supported this should become a loop
|
|
||||||
# set(_lua_append_versions ${LUA_VERSIONS5})
|
|
||||||
# endif ()
|
|
||||||
|
|
||||||
# list(APPEND _lua_include_subdirs "include/lua" "include")
|
|
||||||
|
|
||||||
# foreach (ver IN LISTS _lua_append_versions)
|
|
||||||
# string(REGEX MATCH "^([0-9]+)\\.([0-9]+)$" _ver "${ver}")
|
|
||||||
# list(APPEND _lua_include_subdirs
|
|
||||||
# include/lua${CMAKE_MATCH_1}${CMAKE_MATCH_2}
|
|
||||||
# include/lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
|
|
||||||
# include/lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
|
|
||||||
# )
|
|
||||||
# list(APPEND _lua_library_names
|
|
||||||
# lua${CMAKE_MATCH_1}${CMAKE_MATCH_2}
|
|
||||||
# lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
|
|
||||||
# lua.${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
|
|
||||||
# lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
|
|
||||||
# )
|
|
||||||
# endforeach ()
|
|
||||||
|
|
||||||
# set(_lua_include_subdirs "${_lua_include_subdirs}" PARENT_SCOPE)
|
|
||||||
# set(_lua_append_versions "${_lua_append_versions}" PARENT_SCOPE)
|
|
||||||
# endfunction(_lua_set_version_vars)
|
|
||||||
|
|
||||||
# function(_lua_check_header_version _hdr_file)
|
|
||||||
# # At least 5.[012] have different ways to express the version
|
|
||||||
# # so all of them need to be tested. Lua 5.2 defines LUA_VERSION
|
|
||||||
# # and LUA_RELEASE as joined by the C preprocessor, so avoid those.
|
|
||||||
# file(STRINGS "${_hdr_file}" lua_version_strings
|
|
||||||
# REGEX "^#define[ \t]+LUA_(RELEASE[ \t]+\"Lua [0-9]|VERSION([ \t]+\"Lua [0-9]|_[MR])).*")
|
|
||||||
|
|
||||||
# string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MAJOR ";${lua_version_strings};")
|
|
||||||
# if (LUA_VERSION_MAJOR MATCHES "^[0-9]+$")
|
|
||||||
# string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MINOR ";${lua_version_strings};")
|
|
||||||
# string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_PATCH ";${lua_version_strings};")
|
|
||||||
# set(LUA_VERSION_STRING "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}")
|
|
||||||
# else ()
|
|
||||||
# string(REGEX REPLACE ".*;#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
|
|
||||||
# if (NOT LUA_VERSION_STRING MATCHES "^[0-9.]+$")
|
|
||||||
# string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
|
|
||||||
# endif ()
|
|
||||||
# string(REGEX REPLACE "^([0-9]+)\\.[0-9.]*$" "\\1" LUA_VERSION_MAJOR "${LUA_VERSION_STRING}")
|
|
||||||
# string(REGEX REPLACE "^[0-9]+\\.([0-9]+)[0-9.]*$" "\\1" LUA_VERSION_MINOR "${LUA_VERSION_STRING}")
|
|
||||||
# string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]).*" "\\1" LUA_VERSION_PATCH "${LUA_VERSION_STRING}")
|
|
||||||
# endif ()
|
|
||||||
# foreach (ver IN LISTS _lua_append_versions)
|
|
||||||
# if (ver STREQUAL "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}")
|
|
||||||
# set(LUA_VERSION_MAJOR ${LUA_VERSION_MAJOR} PARENT_SCOPE)
|
|
||||||
# set(LUA_VERSION_MINOR ${LUA_VERSION_MINOR} PARENT_SCOPE)
|
|
||||||
# set(LUA_VERSION_PATCH ${LUA_VERSION_PATCH} PARENT_SCOPE)
|
|
||||||
# set(LUA_VERSION_STRING ${LUA_VERSION_STRING} PARENT_SCOPE)
|
|
||||||
# return()
|
|
||||||
# endif ()
|
|
||||||
# endforeach ()
|
|
||||||
# endfunction(_lua_check_header_version)
|
|
||||||
|
|
||||||
_lua_set_version_vars(lua "")
|
|
||||||
|
|
||||||
find_path(LUA_INCLUDE_DIR lua.h
|
|
||||||
HINTS
|
|
||||||
ENV LUA_DIR
|
|
||||||
PATH_SUFFIXES ${_lua_include_subdirs} include
|
|
||||||
PATHS
|
|
||||||
${LUA_DIR}
|
|
||||||
~/Library/Frameworks
|
|
||||||
/Library/Frameworks
|
|
||||||
/sw # Fink
|
|
||||||
/opt/local # DarwinPorts
|
|
||||||
/opt/csw # Blastwave
|
|
||||||
/opt
|
|
||||||
/usr
|
|
||||||
/usr/local # Homebrew
|
|
||||||
)
|
|
||||||
|
|
||||||
if (LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
|
|
||||||
_lua_check_header_version("${LUA_INCLUDE_DIR}/lua.h" "LUA")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
if (NOT LUA_VERSION_STRING)
|
|
||||||
foreach (subdir IN LISTS _lua_include_subdirs)
|
|
||||||
unset(LUA_INCLUDE_PREFIX CACHE)
|
|
||||||
find_path(LUA_INCLUDE_PREFIX ${subdir}/lua.h
|
|
||||||
HINTS
|
|
||||||
ENV LUA_DIR
|
|
||||||
PATHS
|
|
||||||
${LUA_DIR}
|
|
||||||
~/Library/Frameworks
|
|
||||||
/Library/Frameworks
|
|
||||||
/sw # Fink
|
|
||||||
/opt/local # DarwinPorts
|
|
||||||
/opt/csw # Blastwave
|
|
||||||
/opt
|
|
||||||
/usr
|
|
||||||
/usr/local
|
|
||||||
)
|
|
||||||
if (LUA_INCLUDE_PREFIX)
|
|
||||||
_lua_check_header_version("${LUA_INCLUDE_PREFIX}/${subdir}/lua.h")
|
|
||||||
if (LUA_VERSION_STRING)
|
|
||||||
set(LUA_INCLUDE_DIR "${LUA_INCLUDE_PREFIX}/${subdir}")
|
|
||||||
break()
|
|
||||||
endif ()
|
|
||||||
endif ()
|
|
||||||
endforeach ()
|
|
||||||
endif ()
|
|
||||||
unset(_lua_include_subdirs)
|
|
||||||
unset(_lua_append_versions)
|
|
||||||
|
|
||||||
find_library(LUA_LIBRARY
|
|
||||||
NAMES ${_lua_library_names} lua
|
|
||||||
HINTS
|
|
||||||
ENV LUA_DIR
|
|
||||||
PATH_SUFFIXES lib bin
|
|
||||||
PATHS
|
|
||||||
${LUA_DIR}
|
|
||||||
~/Library/Frameworks
|
|
||||||
/Library/Frameworks
|
|
||||||
/sw
|
|
||||||
/opt/local
|
|
||||||
/opt/csw
|
|
||||||
/opt
|
|
||||||
/usr
|
|
||||||
/usr/local
|
|
||||||
|
|
||||||
# From the include_dir
|
|
||||||
${LUA_INCLUDE_DIR}/../lib
|
|
||||||
)
|
|
||||||
unset(_lua_library_names)
|
|
||||||
|
|
||||||
if (LUA_LIBRARY)
|
|
||||||
# include the math library for Unix
|
|
||||||
if (UNIX AND NOT APPLE AND NOT BEOS)
|
|
||||||
find_library(LUA_MATH_LIBRARY m)
|
|
||||||
set(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}")
|
|
||||||
|
|
||||||
# include dl library for statically-linked Lua library
|
|
||||||
get_filename_component(LUA_LIB_EXT ${LUA_LIBRARY} EXT)
|
|
||||||
if (LUA_LIB_EXT STREQUAL CMAKE_STATIC_LIBRARY_SUFFIX)
|
|
||||||
list(APPEND LUA_LIBRARIES ${CMAKE_DL_LIBS})
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
# For Windows and Mac, don't need to explicitly include the math library
|
|
||||||
else ()
|
|
||||||
set(LUA_LIBRARIES "${LUA_LIBRARY}")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
set(LUA_LIBRARY_DIR )
|
|
||||||
foreach (lib ${LUA_LIBRARIES})
|
|
||||||
get_filename_component(lib_dir ${lib} DIRECTORY CACHE)
|
|
||||||
list(APPEND LUA_LIBRARY_DIR ${lib_dir})
|
|
||||||
endforeach ()
|
|
||||||
list(REMOVE_DUPLICATES LUA_LIBRARY_DIR)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if
|
|
||||||
# all listed variables are TRUE
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua
|
|
||||||
FOUND_VAR Lua_FOUND
|
|
||||||
REQUIRED_VARS LUA_LIBRARIES LUA_LIBRARY_DIR LUA_INCLUDE_DIR
|
|
||||||
VERSION_VAR LUA_VERSION_STRING)
|
|
||||||
|
|
||||||
mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY LUA_LIBRARY_DIR LUA_MATH_LIBRARY)
|
|
@ -236,11 +236,17 @@ prepend(LUA_VANILLA_LUA_SOURCES "${LUA_VANILLA_SOURCE_DIR}/" ${LUA_VANILLA_LUA_S
|
|||||||
prepend(LUA_VANILLA_LUAC_SOURCES "${LUA_VANILLA_SOURCE_DIR}/" ${LUA_VANILLA_LUAC_SOURCES})
|
prepend(LUA_VANILLA_LUAC_SOURCES "${LUA_VANILLA_SOURCE_DIR}/" ${LUA_VANILLA_LUAC_SOURCES})
|
||||||
|
|
||||||
# download, just for the sake of download + extract
|
# download, just for the sake of download + extract
|
||||||
# have to use 2 different commands just to have an empty command
|
# or pull from local folder
|
||||||
# that results in nothing being run
|
if (LUA_LOCAL_DIR)
|
||||||
# TODO: talk to smarter CMake people...?
|
file(COPY "${LUA_LOCAL_DIR}/src"
|
||||||
|
DESTINATION "${LUA_BUILD_TOPLEVEL}")
|
||||||
ExternalProject_Add(LUA_VANILLA
|
file(COPY "${LUA_LOCAL_DIR}/include"
|
||||||
|
DESTINATION "${LUA_BUILD_TOPLEVEL}")
|
||||||
|
add_custom_target(LUA_VANILLA
|
||||||
|
DEPENDS "${LUA_VANILLA_LIB_SOURCES}" "${LUA_VANILLA_LUA_SOURCES}" "${LUA_VANILLA_LUAC_SOURCES}")
|
||||||
|
set(LUA_VANILLA_INCLUDE_DIRS ${LUA_VANILLA_INCLUDE_DIRS} "${LUA_VANILLA_SOURCE_DIR}" "${LUA_BUILD_TOPLEVEL}/include")
|
||||||
|
else()
|
||||||
|
ExternalProject_Add(LUA_VANILLA
|
||||||
BUILD_IN_SOURCE TRUE
|
BUILD_IN_SOURCE TRUE
|
||||||
BUILD_ALWAYS FALSE
|
BUILD_ALWAYS FALSE
|
||||||
TLS_VERIFY TRUE
|
TLS_VERIFY TRUE
|
||||||
@ -259,8 +265,8 @@ ExternalProject_Add(LUA_VANILLA
|
|||||||
TEST_COMMAND ""
|
TEST_COMMAND ""
|
||||||
BUILD_BYPRODUCTS "${LUA_VANILLA_LIB_SOURCES}" "${LUA_VANILLA_LUA_SOURCES}" "${LUA_VANILLA_LUAC_SOURCES}")
|
BUILD_BYPRODUCTS "${LUA_VANILLA_LIB_SOURCES}" "${LUA_VANILLA_LUA_SOURCES}" "${LUA_VANILLA_LUAC_SOURCES}")
|
||||||
|
|
||||||
# make a quick lua.hpp for 5.1 targets that don't have it
|
# make a quick lua.hpp for 5.1 targets that don't have it
|
||||||
if (LUA_VANILLA_GENERATE_LUA_HPP)
|
if (LUA_VANILLA_GENERATE_LUA_HPP)
|
||||||
set(LUA_VANILLA_LUA_HPP_CONTENT "// lua.hpp
|
set(LUA_VANILLA_LUA_HPP_CONTENT "// lua.hpp
|
||||||
// Lua header files for C++
|
// Lua header files for C++
|
||||||
// <<extern \"C\">> not supplied automatically because Lua also compiles as C++
|
// <<extern \"C\">> not supplied automatically because Lua also compiles as C++
|
||||||
@ -284,8 +290,11 @@ extern \"C\" {
|
|||||||
BYPRODUCTS "${LUA_VANILLA_DESTINATION_LUA_HPP}"
|
BYPRODUCTS "${LUA_VANILLA_DESTINATION_LUA_HPP}"
|
||||||
COMMENT "Moving \"${LUA_VANILLA_SOURCE_LUA_HPP}\" to \"${LUA_VANILLA_DESTINATION_LUA_HPP}\"..."
|
COMMENT "Moving \"${LUA_VANILLA_SOURCE_LUA_HPP}\" to \"${LUA_VANILLA_DESTINATION_LUA_HPP}\"..."
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy "${LUA_VANILLA_SOURCE_LUA_HPP}" "${LUA_VANILLA_DESTINATION_LUA_HPP}")
|
COMMAND "${CMAKE_COMMAND}" -E copy "${LUA_VANILLA_SOURCE_LUA_HPP}" "${LUA_VANILLA_DESTINATION_LUA_HPP}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(LUA_VANILLA_INCLUDE_DIRS ${LUA_VANILLA_SOURCE_DIR})
|
||||||
|
endif()
|
||||||
|
message(STATUS "${LUA_VANILLA_INCLUDE_DIRS}")
|
||||||
# # Target names
|
# # Target names
|
||||||
set(liblua "liblua-${LUA_VANILLA_VERSION}")
|
set(liblua "liblua-${LUA_VANILLA_VERSION}")
|
||||||
set(luainterpreter "lua-${LUA_VANILLA_VERSION}")
|
set(luainterpreter "lua-${LUA_VANILLA_VERSION}")
|
||||||
@ -308,13 +317,12 @@ set_target_properties(${liblua}
|
|||||||
C_STANDARD 99
|
C_STANDARD 99
|
||||||
C_EXTENSIONS TRUE
|
C_EXTENSIONS TRUE
|
||||||
POSITION_INDEPENDENT_CODE TRUE
|
POSITION_INDEPENDENT_CODE TRUE
|
||||||
INCLUDE_DIRECTORIES ${LUA_VANILLA_SOURCE_DIR}
|
|
||||||
OUTPUT_NAME ${LUA_BUILD_LIBNAME}
|
OUTPUT_NAME ${LUA_BUILD_LIBNAME}
|
||||||
RUNTIME_OUTPUT_NAME ${LUA_BUILD_LIBNAME}
|
RUNTIME_OUTPUT_NAME ${LUA_BUILD_LIBNAME}
|
||||||
LIBRARY_OUTPUT_NAME ${LUA_BUILD_LIBNAME}
|
LIBRARY_OUTPUT_NAME ${LUA_BUILD_LIBNAME}
|
||||||
ARCHIVE_OUTPUT_NAME ${LUA_BUILD_LIBNAME})
|
ARCHIVE_OUTPUT_NAME ${LUA_BUILD_LIBNAME})
|
||||||
target_include_directories(${liblua}
|
target_include_directories(${liblua}
|
||||||
PUBLIC ${LUA_VANILLA_SOURCE_DIR})
|
PUBLIC "${LUA_VANILLA_INCLUDE_DIRS}")
|
||||||
target_compile_definitions(${liblua}
|
target_compile_definitions(${liblua}
|
||||||
PUBLIC LUA_COMPAT_ALL ${LUA_VANILLA_DLL_DEFINE})
|
PUBLIC LUA_COMPAT_ALL ${LUA_VANILLA_DLL_DEFINE})
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
@ -352,7 +360,7 @@ set_target_properties(${luainterpreter}
|
|||||||
C_EXTENSIONS TRUE
|
C_EXTENSIONS TRUE
|
||||||
OUTPUT_NAME lua-${LUA_VANILLA_VERSION})
|
OUTPUT_NAME lua-${LUA_VANILLA_VERSION})
|
||||||
target_include_directories(${luainterpreter}
|
target_include_directories(${luainterpreter}
|
||||||
PRIVATE ${LUA_VANILLA_SOURCE_DIR})
|
PRIVATE "${LUA_VANILLA_INCLUDE_DIRS}")
|
||||||
target_compile_definitions(${luainterpreter}
|
target_compile_definitions(${luainterpreter}
|
||||||
PUBLIC LUA_COMPAT_ALL ${LUA_VANILLA_DLL_DEFINE}
|
PUBLIC LUA_COMPAT_ALL ${LUA_VANILLA_DLL_DEFINE}
|
||||||
PRIVATE LUA_COMPAT_ALL ${LUA_VANILLA_DLL_DEFINE})
|
PRIVATE LUA_COMPAT_ALL ${LUA_VANILLA_DLL_DEFINE})
|
||||||
@ -394,7 +402,7 @@ set_target_properties(${luacompiler}
|
|||||||
C_EXTENSIONS TRUE
|
C_EXTENSIONS TRUE
|
||||||
OUTPUT_NAME luac-${LUA_VANILLA_VERSION})
|
OUTPUT_NAME luac-${LUA_VANILLA_VERSION})
|
||||||
target_include_directories(${luacompiler}
|
target_include_directories(${luacompiler}
|
||||||
PRIVATE ${LUA_VANILLA_SOURCE_DIR})
|
PRIVATE "${LUA_VANILLA_INCLUDE_DIRS}")
|
||||||
target_compile_options(${luacompiler}
|
target_compile_options(${luacompiler}
|
||||||
PRIVATE ${LUA_VANILLA_LUA_LUAC_COMPILER_OPTIONS})
|
PRIVATE ${LUA_VANILLA_LUA_LUAC_COMPILER_OPTIONS})
|
||||||
target_compile_definitions(${luacompiler}
|
target_compile_definitions(${luacompiler}
|
||||||
|
@ -167,7 +167,7 @@ namespace sol {
|
|||||||
typedef meta::tuple_types<typename traits::return_type> return_types;
|
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||||
typedef typename traits::free_args_list args_list;
|
typedef typename traits::free_args_list args_list;
|
||||||
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||||
if (!traits::runtime_variadics_t::value && meta::find_in_pack_v<meta::index_value<traits::free_arity>, meta::index_value<M>...>::value) {
|
if constexpr (!traits::runtime_variadics_t::value && meta::find_in_pack_v<meta::index_value<traits::free_arity>, meta::index_value<M>...>::value) {
|
||||||
return overload_match_arity(types<>(), std::index_sequence<>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
return overload_match_arity(types<>(), std::index_sequence<>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
if (!traits::runtime_variadics_t::value && traits::free_arity != fxarity) {
|
if (!traits::runtime_variadics_t::value && traits::free_arity != fxarity) {
|
||||||
|
@ -27,44 +27,61 @@
|
|||||||
#include "../feature_test.hpp"
|
#include "../feature_test.hpp"
|
||||||
|
|
||||||
#if defined(SOL_USING_CXX_LUA) && SOL_USING_CXX_LUA
|
#if defined(SOL_USING_CXX_LUA) && SOL_USING_CXX_LUA
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
#include <lualib.h>
|
#include <lualib.h>
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
#if defined(SOL_USING_CXX_LUAJIT) && SOL_USING_CXX_LUAJIT
|
#if defined(SOL_USING_CXX_LUAJIT) && SOL_USING_CXX_LUAJIT
|
||||||
#include <luajit.h>
|
#include <luajit.h>
|
||||||
#endif // C++ LuaJIT ... whatever that means
|
#endif // C++ LuaJIT ... whatever that means
|
||||||
#if (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !(SOL_EXCEPTIONS_SAFE_PROPAGATION)) && (!defined(SOL_EXCEPTIONS_ALWAYS_UNSAFE) || !(SOL_EXCEPTIONS_ALWAYS_UNSAFE))
|
#if (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !(SOL_EXCEPTIONS_SAFE_PROPAGATION)) && (!defined(SOL_EXCEPTIONS_ALWAYS_UNSAFE) || !(SOL_EXCEPTIONS_ALWAYS_UNSAFE))
|
||||||
#define SOL_EXCEPTIONS_SAFE_PROPAGATION 1
|
#define SOL_EXCEPTIONS_SAFE_PROPAGATION 1
|
||||||
#endif // Exceptions can be propagated safely using C++-compiled Lua
|
#endif // Exceptions can be propagated safely using C++-compiled Lua
|
||||||
#else
|
#else
|
||||||
#include <lua.hpp>
|
#if defined(__has_include)
|
||||||
#endif // C++ Mangling for Lua
|
#if __has_include(<lua.hpp>)
|
||||||
|
#include <lua.hpp>
|
||||||
|
#else
|
||||||
|
extern "C" {
|
||||||
|
#include <lua.h>
|
||||||
|
#include <lauxlib.h>
|
||||||
|
#include <lualib.h>
|
||||||
|
#if defined(SOL_LUAJIT) && SOL_LUAJIT
|
||||||
|
#include <luajit.h>
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif // lua.hpp exists or does not
|
||||||
|
#else
|
||||||
|
#include <lua.hpp>
|
||||||
|
#endif // check for lua.hpp safely for Lua 5.1 derps
|
||||||
|
#endif // C++ Mangling for Lua vs. Not
|
||||||
|
|
||||||
#ifdef LUAJIT_VERSION
|
#ifdef LUAJIT_VERSION
|
||||||
#ifndef SOL_LUAJIT
|
#ifndef SOL_LUAJIT
|
||||||
#define SOL_LUAJIT 1
|
#define SOL_LUAJIT 1
|
||||||
#ifndef SOL_LUAJIT_VERSION
|
#endif // sol luajit
|
||||||
#define SOL_LUAJIT_VERSION LUAJIT_VERSION_NUM
|
#if defined(SOL_LUAJIT) && SOL_LUAJIT
|
||||||
#endif // SOL_LUAJIT_VERSION definition, if not present
|
#ifndef SOL_LUAJIT_VERSION
|
||||||
#endif // sol luajit
|
#define SOL_LUAJIT_VERSION LUAJIT_VERSION_NUM
|
||||||
|
#endif // SOL_LUAJIT_VERSION definition, if not present
|
||||||
|
#endif
|
||||||
#endif // luajit
|
#endif // luajit
|
||||||
|
|
||||||
#if SOL_LUAJIT && SOL_LUAJIT_VERSION >= 20100
|
#if SOL_LUAJIT && SOL_LUAJIT_VERSION >= 20100
|
||||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) && (!defined(SOL_EXCEPTIONS_ALWAYS_UNSAFE) && !(SOL_EXCEPTIONS_ALWAYS_UNSAFE))
|
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) && (!defined(SOL_EXCEPTIONS_ALWAYS_UNSAFE) && !(SOL_EXCEPTIONS_ALWAYS_UNSAFE))
|
||||||
#define SOL_EXCEPTIONS_SAFE_PROPAGATION 1
|
#define SOL_EXCEPTIONS_SAFE_PROPAGATION 1
|
||||||
#endif // Do not catch (...) clauses
|
#endif // Do not catch (...) clauses
|
||||||
#endif // LuaJIT beta 02.01.00 have better exception handling on all platforms since beta3
|
#endif // LuaJIT beta 02.01.00 have better exception handling on all platforms since beta3
|
||||||
|
|
||||||
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 502
|
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 502
|
||||||
#define SOL_LUA_VERSION LUA_VERSION_NUM
|
#define SOL_LUA_VERSION LUA_VERSION_NUM
|
||||||
#elif defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
|
#elif defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
|
||||||
#define SOL_LUA_VERSION LUA_VERSION_NUM
|
#define SOL_LUA_VERSION LUA_VERSION_NUM
|
||||||
#elif !defined(LUA_VERSION_NUM) || !(LUA_VERSION_NUM)
|
#elif !defined(LUA_VERSION_NUM) || !(LUA_VERSION_NUM)
|
||||||
// Definitely 5.0
|
// Definitely 5.0
|
||||||
#define SOL_LUA_VERSION 500
|
#define SOL_LUA_VERSION 500
|
||||||
#else
|
#else
|
||||||
// ??? Not sure, assume 502?
|
// ??? Not sure, assume 503?
|
||||||
#define SOL_LUA_VERSION 502
|
#define SOL_LUA_VERSION 503
|
||||||
#endif // Lua Version 502, 501 || luajit, 500
|
#endif // Lua Version 503, 502, 501 || luajit, 500
|
||||||
|
|
||||||
#endif // SOL_VERSION_HPP
|
#endif // SOL_VERSION_HPP
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#ifndef SOL_DEMANGLE_HPP
|
#ifndef SOL_DEMANGLE_HPP
|
||||||
#define SOL_DEMANGLE_HPP
|
#define SOL_DEMANGLE_HPP
|
||||||
|
|
||||||
|
#include "string_view.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
@ -36,12 +37,22 @@ extern "C" {
|
|||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
inline constexpr std::array<string_view, 9> removals{ { "{anonymous}",
|
||||||
|
"(anonymous namespace)",
|
||||||
|
"public:",
|
||||||
|
"private:",
|
||||||
|
"protected:",
|
||||||
|
"struct ",
|
||||||
|
"class ",
|
||||||
|
"`anonymous-namespace'",
|
||||||
|
"`anonymous namespace'" } };
|
||||||
|
|
||||||
|
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
template <typename T, class seperator_mark = int>
|
template <typename T, class seperator_mark = int>
|
||||||
inline std::string ctti_get_type_name() {
|
inline std::string ctti_get_type_name() {
|
||||||
// cardinal sins from MINGW
|
// cardinal sins from MINGW
|
||||||
using namespace std;
|
using namespace std;
|
||||||
static const std::array<std::string, 2> removals = {{"{anonymous}", "(anonymous namespace)"}};
|
|
||||||
std::string name = __PRETTY_FUNCTION__;
|
std::string name = __PRETTY_FUNCTION__;
|
||||||
std::size_t start = name.find_first_of('[');
|
std::size_t start = name.find_first_of('[');
|
||||||
start = name.find_first_of('=', start);
|
start = name.find_first_of('=', start);
|
||||||
@ -75,7 +86,6 @@ namespace detail {
|
|||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline std::string ctti_get_type_name() {
|
inline std::string ctti_get_type_name() {
|
||||||
static const std::array<std::string, 7> removals = {{"public:", "private:", "protected:", "struct ", "class ", "`anonymous-namespace'", "`anonymous namespace'"}};
|
|
||||||
std::string name = __FUNCSIG__;
|
std::string name = __FUNCSIG__;
|
||||||
std::size_t start = name.find("get_type_name");
|
std::size_t start = name.find("get_type_name");
|
||||||
if (start == std::string::npos)
|
if (start == std::string::npos)
|
||||||
|
@ -58,7 +58,7 @@ namespace sol {
|
|||||||
const char* name = lua_tolstring(L, -1, &sz);
|
const char* name = lua_tolstring(L, -1, &sz);
|
||||||
std::string tn(name, static_cast<std::string::size_type>(sz));
|
std::string tn(name, static_cast<std::string::size_type>(sz));
|
||||||
lua_pop(L, 2);
|
lua_pop(L, 2);
|
||||||
return name;
|
return std::move(tn);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -202,6 +202,14 @@ namespace sol {
|
|||||||
struct record;
|
struct record;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(SOL_USE_BOOST) || (SOL_USE_BOOST == 0)
|
||||||
|
template <class T>
|
||||||
|
class optional;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class optional<T&>;
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace sol
|
} // namespace sol
|
||||||
|
|
||||||
#define SOL_BASE_CLASSES(T, ...) \
|
#define SOL_BASE_CLASSES(T, ...) \
|
||||||
|
@ -36,22 +36,19 @@ namespace sol {
|
|||||||
friend class state_view;
|
friend class state_view;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
basic_metatable(detail::no_safety_tag, lua_nil_t n)
|
basic_metatable(detail::no_safety_tag, lua_nil_t n) : base_t(n) {
|
||||||
: base_t(n) {
|
|
||||||
}
|
}
|
||||||
basic_metatable(detail::no_safety_tag, lua_State* L, int index)
|
basic_metatable(detail::no_safety_tag, lua_State* L, int index) : base_t(L, index) {
|
||||||
: base_t(L, index) {
|
|
||||||
}
|
}
|
||||||
basic_metatable(detail::no_safety_tag, lua_State* L, ref_index index)
|
basic_metatable(detail::no_safety_tag, lua_State* L, ref_index index) : base_t(L, index) {
|
||||||
: base_t(L, index) {
|
|
||||||
}
|
}
|
||||||
template <typename T, meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_metatable>>, meta::neg<std::is_same<base_type, stack_reference>>, meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
template <typename T,
|
||||||
basic_metatable(detail::no_safety_tag, T&& r) noexcept
|
meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_metatable>>, meta::neg<std::is_same<base_type, stack_reference>>,
|
||||||
: base_t(std::forward<T>(r)) {
|
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||||
|
basic_metatable(detail::no_safety_tag, T&& r) noexcept : base_t(std::forward<T>(r)) {
|
||||||
}
|
}
|
||||||
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||||
basic_metatable(detail::no_safety_tag, lua_State* L, T&& r) noexcept
|
basic_metatable(detail::no_safety_tag, lua_State* L, T&& r) noexcept : base_t(L, std::forward<T>(r)) {
|
||||||
: base_t(L, std::forward<T>(r)) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -62,39 +59,35 @@ namespace sol {
|
|||||||
basic_metatable(basic_metatable&&) = default;
|
basic_metatable(basic_metatable&&) = default;
|
||||||
basic_metatable& operator=(const basic_metatable&) = default;
|
basic_metatable& operator=(const basic_metatable&) = default;
|
||||||
basic_metatable& operator=(basic_metatable&&) = default;
|
basic_metatable& operator=(basic_metatable&&) = default;
|
||||||
basic_metatable(const stack_reference& r)
|
basic_metatable(const stack_reference& r) : basic_metatable(r.lua_state(), r.stack_index()) {
|
||||||
: basic_metatable(r.lua_state(), r.stack_index()) {
|
|
||||||
}
|
}
|
||||||
basic_metatable(stack_reference&& r)
|
basic_metatable(stack_reference&& r) : basic_metatable(r.lua_state(), r.stack_index()) {
|
||||||
: basic_metatable(r.lua_state(), r.stack_index()) {
|
|
||||||
}
|
}
|
||||||
template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||||
basic_metatable(lua_State* L, T&& r)
|
basic_metatable(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
|
||||||
: base_t(L, std::forward<T>(r)) {
|
|
||||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||||
auto pp = stack::push_pop(*this);
|
auto pp = stack::push_pop(*this);
|
||||||
constructor_handler handler{};
|
constructor_handler handler{};
|
||||||
stack::check<basic_metatable>(lua_state(), -1, handler);
|
stack::check<basic_metatable>(lua_state(), -1, handler);
|
||||||
#endif // Safety
|
#endif // Safety
|
||||||
}
|
}
|
||||||
basic_metatable(lua_State* L, int index = -1)
|
basic_metatable(lua_State* L, int index = -1) : basic_metatable(detail::no_safety, L, index) {
|
||||||
: basic_metatable(detail::no_safety, L, index) {
|
|
||||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||||
constructor_handler handler{};
|
constructor_handler handler{};
|
||||||
stack::check<basic_metatable>(L, index, handler);
|
stack::check<basic_metatable>(L, index, handler);
|
||||||
#endif // Safety
|
#endif // Safety
|
||||||
}
|
}
|
||||||
basic_metatable(lua_State* L, ref_index index)
|
basic_metatable(lua_State* L, ref_index index) : basic_metatable(detail::no_safety, L, index) {
|
||||||
: basic_metatable(detail::no_safety, L, index) {
|
|
||||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||||
auto pp = stack::push_pop(*this);
|
auto pp = stack::push_pop(*this);
|
||||||
constructor_handler handler{};
|
constructor_handler handler{};
|
||||||
stack::check<basic_metatable>(lua_state(), -1, handler);
|
stack::check<basic_metatable>(lua_state(), -1, handler);
|
||||||
#endif // Safety
|
#endif // Safety
|
||||||
}
|
}
|
||||||
template <typename T, meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_metatable>>, meta::neg<std::is_same<base_type, stack_reference>>, meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
template <typename T,
|
||||||
basic_metatable(T&& r) noexcept
|
meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_metatable>>, meta::neg<std::is_same<base_type, stack_reference>>,
|
||||||
: basic_metatable(detail::no_safety, std::forward<T>(r)) {
|
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||||
|
basic_metatable(T&& r) noexcept : basic_metatable(detail::no_safety, std::forward<T>(r)) {
|
||||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||||
if (!is_table<meta::unqualified_t<T>>::value) {
|
if (!is_table<meta::unqualified_t<T>>::value) {
|
||||||
auto pp = stack::push_pop(*this);
|
auto pp = stack::push_pop(*this);
|
||||||
@ -103,8 +96,7 @@ namespace sol {
|
|||||||
}
|
}
|
||||||
#endif // Safety
|
#endif // Safety
|
||||||
}
|
}
|
||||||
basic_metatable(lua_nil_t r) noexcept
|
basic_metatable(lua_nil_t r) noexcept : basic_metatable(detail::no_safety, r) {
|
||||||
: basic_metatable(detail::no_safety, r) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Key, typename Value>
|
template <typename Key, typename Value>
|
||||||
@ -128,11 +120,11 @@ namespace sol {
|
|||||||
}
|
}
|
||||||
ustorage_base& base_storage = *static_cast<ustorage_base*>(stack::get<void*>(L, -1));
|
ustorage_base& base_storage = *static_cast<ustorage_base*>(stack::get<void*>(L, -1));
|
||||||
base_storage.clear();
|
base_storage.clear();
|
||||||
stack_reference gnt(L, -1);
|
stack_reference gc_names_table(L, -1);
|
||||||
std::array<const char*, 6> registry_traits;
|
std::array<const char*, 6> registry_traits;
|
||||||
for (int i = 0; i < registry_traits.size(); ++i) {
|
for (int i = 0; i < registry_traits.size(); ++i) {
|
||||||
u_detail::submetatable_type smt = static_cast<u_detail::submetatable_type>(i);
|
u_detail::submetatable_type smt = static_cast<u_detail::submetatable_type>(i);
|
||||||
stack::get_field(L, smt, gnt.stack_index());
|
stack::get_field(L, smt, gc_names_table.stack_index());
|
||||||
registry_traits[i] = stack::get<const char*>(L, -1);
|
registry_traits[i] = stack::get<const char*>(L, -1);
|
||||||
}
|
}
|
||||||
// get the registry
|
// get the registry
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#ifndef SOL_OPTIONAL_HPP
|
#ifndef SOL_OPTIONAL_HPP
|
||||||
#define SOL_OPTIONAL_HPP
|
#define SOL_OPTIONAL_HPP
|
||||||
|
|
||||||
#include "compatibility.hpp"
|
#include "forward.hpp"
|
||||||
#include "in_place.hpp"
|
#include "in_place.hpp"
|
||||||
#if defined(SOL_USE_BOOST) && SOL_USE_BOOST
|
#if defined(SOL_USE_BOOST) && SOL_USE_BOOST
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
@ -32,6 +32,10 @@
|
|||||||
#include "optional_implementation.hpp"
|
#include "optional_implementation.hpp"
|
||||||
#endif // Boost vs. Better optional
|
#endif // Boost vs. Better optional
|
||||||
|
|
||||||
|
#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES
|
||||||
|
#include <optional>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
|
|
||||||
#if defined(SOL_USE_BOOST) && SOL_USE_BOOST
|
#if defined(SOL_USE_BOOST) && SOL_USE_BOOST
|
||||||
@ -46,6 +50,10 @@ namespace sol {
|
|||||||
struct is_optional : std::false_type {};
|
struct is_optional : std::false_type {};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_optional<optional<T>> : std::true_type {};
|
struct is_optional<optional<T>> : std::true_type {};
|
||||||
|
#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES
|
||||||
|
template <typename T>
|
||||||
|
struct is_optional<std::optional<T>> : std::true_type {};
|
||||||
|
#endif
|
||||||
} // namespace meta
|
} // namespace meta
|
||||||
} // namespace sol
|
} // namespace sol
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -33,6 +33,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
|
|
||||||
template <typename base_t, bool aligned = false, typename handler_t = reference>
|
template <typename base_t, bool aligned = false, typename handler_t = reference>
|
||||||
class basic_protected_function : public base_t {
|
class basic_protected_function : public base_t {
|
||||||
public:
|
public:
|
||||||
|
@ -44,17 +44,21 @@
|
|||||||
// we'll just let this alone for now
|
// we'll just let this alone for now
|
||||||
#elif defined _MSC_VER
|
#elif defined _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4324) // structure was padded due to alignment specifier
|
//#pragma warning(disable : 4324) // structure was padded due to alignment specifier
|
||||||
#pragma warning(disable : 4503) // decorated name horse shit
|
//#pragma warning(disable : 4503) // decorated name horse shit
|
||||||
#pragma warning(disable : 4702) // unreachable code
|
//#pragma warning(disable : 4702) // unreachable code
|
||||||
#pragma warning(disable : 4127) // 'conditional expression is constant' yeah that's the point your old compilers don't have `if constexpr` you jerk
|
//#pragma warning(disable : 4127) // 'conditional expression is constant' yeah that's the point your old compilers don't have `if constexpr` you jerk
|
||||||
#pragma warning(disable : 4505) // some other nonsense warning
|
//#pragma warning(disable : 4505) // some other nonsense warning
|
||||||
#endif // clang++ vs. g++ vs. VC++
|
#endif // clang++ vs. g++ vs. VC++
|
||||||
|
|
||||||
#include "forward.hpp"
|
#include "forward.hpp"
|
||||||
|
#include "forward_detail.hpp"
|
||||||
|
#include "stack.hpp"
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
#include "function.hpp"
|
#include "function.hpp"
|
||||||
#include "protected_function.hpp"
|
#include "protected_function.hpp"
|
||||||
|
#include "usertype.hpp"
|
||||||
|
#include "table.hpp"
|
||||||
#include "state.hpp"
|
#include "state.hpp"
|
||||||
#include "coroutine.hpp"
|
#include "coroutine.hpp"
|
||||||
#include "thread.hpp"
|
#include "thread.hpp"
|
||||||
|
@ -69,6 +69,21 @@ namespace sol {
|
|||||||
return chunkname.c_str();
|
return chunkname.c_str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void clear_entries(stack_reference r) {
|
||||||
|
stack::push(r.lua_state(), lua_nil);
|
||||||
|
while (lua_next(r.lua_state(), -2)) {
|
||||||
|
absolute_index key(r.lua_state(), -2);
|
||||||
|
auto pn = stack::pop_n(r.lua_state(), 1);
|
||||||
|
stack::set_field<false, true>(r.lua_state(), key, lua_nil, r.stack_index());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void clear_entries(const reference& registry_reference) {
|
||||||
|
auto pp = stack::push_pop(registry_reference);
|
||||||
|
stack_reference ref(registry_reference.lua_state(), -1);
|
||||||
|
clear_entries(ref);
|
||||||
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
namespace stack {
|
namespace stack {
|
||||||
@ -189,13 +204,9 @@ namespace sol {
|
|||||||
template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Ret0, typename... Ret, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<meta::neg<std::is_void<Ret0>>::value>>
|
template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Ret0, typename... Ret, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<meta::neg<std::is_void<Ret0>>::value>>
|
||||||
inline int call_into_lua(types<Ret0, Ret...>, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
|
inline int call_into_lua(types<Ret0, Ret...>, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
|
||||||
decltype(auto) r = call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
decltype(auto) r = call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
||||||
typedef meta::unqualified_t<decltype(r)> R;
|
using R = meta::unqualified_t<decltype(r)>;
|
||||||
typedef meta::any<is_stack_based<R>,
|
using is_stack = meta::any<is_stack_based<R>, std::is_same<R, absolute_index>, std::is_same<R, ref_index>, std::is_same<R, raw_index>>;
|
||||||
std::is_same<R, absolute_index>,
|
if constexpr (clean_stack && !is_stack::value) {
|
||||||
std::is_same<R, ref_index>,
|
|
||||||
std::is_same<R, raw_index>>
|
|
||||||
is_stack;
|
|
||||||
if (clean_stack && !is_stack::value) {
|
|
||||||
lua_settop(L, 0);
|
lua_settop(L, 0);
|
||||||
}
|
}
|
||||||
return push_reference(L, std::forward<decltype(r)>(r));
|
return push_reference(L, std::forward<decltype(r)>(r));
|
||||||
|
@ -479,7 +479,8 @@ namespace sol { namespace stack {
|
|||||||
if (stack_detail::check_metatable<as_container_t<U>>(L, metatableindex))
|
if (stack_detail::check_metatable<as_container_t<U>>(L, metatableindex))
|
||||||
return true;
|
return true;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (derive<T>::value || weak_derive<T>::value) {
|
bool has_derived = derive<T>::value || weak_derive<T>::value;
|
||||||
|
if (has_derived) {
|
||||||
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
||||||
luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
|
luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
|
||||||
#endif // make sure stack doesn't overflow
|
#endif // make sure stack doesn't overflow
|
||||||
|
@ -1244,8 +1244,10 @@ namespace sol {
|
|||||||
else if constexpr (!std::is_pointer_v<T>) {
|
else if constexpr (!std::is_pointer_v<T>) {
|
||||||
return &usertype_alloc_destruct<T>;
|
return &usertype_alloc_destruct<T>;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
return &cannot_destruct<T>;
|
return &cannot_destruct<T>;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline lua_CFunction make_destructor(std::false_type) {
|
inline lua_CFunction make_destructor(std::false_type) {
|
||||||
@ -1321,11 +1323,20 @@ namespace sol {
|
|||||||
template <typename T, typename Op>
|
template <typename T, typename Op>
|
||||||
int comparsion_operator_wrap(lua_State* L) {
|
int comparsion_operator_wrap(lua_State* L) {
|
||||||
auto maybel = stack::unqualified_check_get<T&>(L, 1);
|
auto maybel = stack::unqualified_check_get<T&>(L, 1);
|
||||||
if (maybel) {
|
if (!maybel) {
|
||||||
|
return stack::push(L, false);
|
||||||
|
}
|
||||||
auto mayber = stack::unqualified_check_get<T&>(L, 2);
|
auto mayber = stack::unqualified_check_get<T&>(L, 2);
|
||||||
if (mayber) {
|
if (!mayber) {
|
||||||
auto& l = *maybel;
|
return stack::push(L, false);
|
||||||
auto& r = *mayber;
|
}
|
||||||
|
decltype(auto) l = *maybel;
|
||||||
|
decltype(auto) r = *mayber;
|
||||||
|
if constexpr (std::is_same_v<no_comp, Op>) {
|
||||||
|
std::equal_to<> op;
|
||||||
|
return stack::push(L, op(detail::ptr(l), detail::ptr(r)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
if constexpr (std::is_same_v<std::equal_to<>, Op> // cf-hack
|
if constexpr (std::is_same_v<std::equal_to<>, Op> // cf-hack
|
||||||
|| std::is_same_v<std::less_equal<>, Op> //
|
|| std::is_same_v<std::less_equal<>, Op> //
|
||||||
|| std::is_same_v<std::less_equal<>, Op>) { //
|
|| std::is_same_v<std::less_equal<>, Op>) { //
|
||||||
@ -1333,16 +1344,10 @@ namespace sol {
|
|||||||
return stack::push(L, true);
|
return stack::push(L, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if constexpr (std::is_same_v<no_comp, Op>) {
|
|
||||||
std::equal_to<> op;
|
|
||||||
return stack::push(L, op(detail::ptr(l), detail::ptr(r)));
|
|
||||||
}
|
|
||||||
Op op;
|
Op op;
|
||||||
return stack::push(L, op(detail::deref(l), detail::deref(r)));
|
return stack::push(L, op(detail::deref(l), detail::deref(r)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stack::push(L, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename IFx, typename Fx>
|
template <typename T, typename IFx, typename Fx>
|
||||||
void insert_default_registrations(IFx&& ifx, Fx&& fx);
|
void insert_default_registrations(IFx&& ifx, Fx&& fx);
|
||||||
|
@ -791,7 +791,8 @@ namespace sol { namespace stack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static T* get_no_lua_nil_from(lua_State* L, void* udata, int index, record&) {
|
static T* get_no_lua_nil_from(lua_State* L, void* udata, int index, record&) {
|
||||||
if (derive<T>::value || weak_derive<T>::value) {
|
bool has_derived = derive<T>::value || weak_derive<T>::value;
|
||||||
|
if (has_derived) {
|
||||||
if (lua_getmetatable(L, index) == 1) {
|
if (lua_getmetatable(L, index) == 1) {
|
||||||
lua_getfield(L, -1, &detail::base_class_cast_key()[0]);
|
lua_getfield(L, -1, &detail::base_class_cast_key()[0]);
|
||||||
if (type_of(L, -1) != type::lua_nil) {
|
if (type_of(L, -1) != type::lua_nil) {
|
||||||
|
@ -34,9 +34,11 @@ namespace stack {
|
|||||||
struct probe_field_getter {
|
struct probe_field_getter {
|
||||||
template <typename Key>
|
template <typename Key>
|
||||||
probe get(lua_State* L, Key&& key, int tableindex = -2) {
|
probe get(lua_State* L, Key&& key, int tableindex = -2) {
|
||||||
if (!b && !maybe_indexable(L, tableindex)) {
|
if constexpr(!b) {
|
||||||
|
if (!maybe_indexable(L, tableindex)) {
|
||||||
return probe(false, 0);
|
return probe(false, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
get_field<b, raw>(L, std::forward<Key>(key), tableindex);
|
get_field<b, raw>(L, std::forward<Key>(key), tableindex);
|
||||||
return probe(check<P>(L), 1);
|
return probe(check<P>(L), 1);
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,23 @@
|
|||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
namespace stack {
|
namespace stack {
|
||||||
|
namespace stack_detail {
|
||||||
|
template <typename T>
|
||||||
|
inline bool integer_value_fits(const T& value) {
|
||||||
|
if constexpr (sizeof(T) < sizeof(lua_Integer) || (std::is_signed<T>::value && sizeof(T) == sizeof(lua_Integer))) {
|
||||||
|
(void)value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto u_min = static_cast<std::intmax_t>((std::numeric_limits<lua_Integer>::min)());
|
||||||
|
auto u_max = static_cast<std::uintmax_t>((std::numeric_limits<lua_Integer>::max)());
|
||||||
|
auto t_min = static_cast<std::intmax_t>((std::numeric_limits<T>::min)());
|
||||||
|
auto t_max = static_cast<std::uintmax_t>((std::numeric_limits<T>::max)());
|
||||||
|
return (u_min <= t_min || value >= static_cast<T>(u_min)) && (u_max >= t_max || value <= static_cast<T>(u_max));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline int push_environment_of(lua_State* L, int index = -1) {
|
inline int push_environment_of(lua_State* L, int index = -1) {
|
||||||
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
||||||
luaL_checkstack(L, 1, detail::not_enough_stack_space_environment);
|
luaL_checkstack(L, 1, detail::not_enough_stack_space_environment);
|
||||||
@ -241,17 +258,7 @@ namespace sol {
|
|||||||
luaL_checkstack(L, 1, detail::not_enough_stack_space_integral);
|
luaL_checkstack(L, 1, detail::not_enough_stack_space_integral);
|
||||||
#endif // make sure stack doesn't overflow
|
#endif // make sure stack doesn't overflow
|
||||||
#if SOL_LUA_VERSION >= 503
|
#if SOL_LUA_VERSION >= 503
|
||||||
static auto integer_value_fits = [](T const& value) {
|
if (stack_detail::integer_value_fits<T>(value)) {
|
||||||
if (sizeof(T) < sizeof(lua_Integer) || (std::is_signed<T>::value && sizeof(T) == sizeof(lua_Integer))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
auto u_min = static_cast<std::intmax_t>((std::numeric_limits<lua_Integer>::min)());
|
|
||||||
auto u_max = static_cast<std::uintmax_t>((std::numeric_limits<lua_Integer>::max)());
|
|
||||||
auto t_min = static_cast<std::intmax_t>((std::numeric_limits<T>::min)());
|
|
||||||
auto t_max = static_cast<std::uintmax_t>((std::numeric_limits<T>::max)());
|
|
||||||
return (u_min <= t_min || value >= static_cast<T>(u_min)) && (u_max >= t_max || value <= static_cast<T>(u_max));
|
|
||||||
};
|
|
||||||
if (integer_value_fits(value)) {
|
|
||||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -813,7 +820,7 @@ namespace sol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int push(lua_State* L, const wchar_t* strb, const wchar_t* stre) {
|
static int push(lua_State* L, const wchar_t* strb, const wchar_t* stre) {
|
||||||
if (sizeof(wchar_t) == 2) {
|
if constexpr (sizeof(wchar_t) == 2) {
|
||||||
const char16_t* sb = reinterpret_cast<const char16_t*>(strb);
|
const char16_t* sb = reinterpret_cast<const char16_t*>(strb);
|
||||||
const char16_t* se = reinterpret_cast<const char16_t*>(stre);
|
const char16_t* se = reinterpret_cast<const char16_t*>(stre);
|
||||||
return stack::push(L, sb, se);
|
return stack::push(L, sb, se);
|
||||||
|
@ -53,11 +53,9 @@ namespace sol {
|
|||||||
basic_string_view(const std::string& r)
|
basic_string_view(const std::string& r)
|
||||||
: basic_string_view(r.data(), r.size()) {
|
: basic_string_view(r.data(), r.size()) {
|
||||||
}
|
}
|
||||||
basic_string_view(const Char* ptr)
|
constexpr basic_string_view(const Char* ptr) : basic_string_view(ptr, Traits::length(ptr)) {
|
||||||
: basic_string_view(ptr, Traits::length(ptr)) {
|
|
||||||
}
|
}
|
||||||
basic_string_view(const Char* ptr, std::size_t sz)
|
constexpr basic_string_view(const Char* ptr, std::size_t sz) : s(sz), p(ptr) {
|
||||||
: s(sz), p(ptr) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int compare(const Char* lhs_p, std::size_t lhs_sz, const Char* rhs_p, std::size_t rhs_sz) {
|
static int compare(const Char* lhs_p, std::size_t lhs_sz, const Char* rhs_p, std::size_t rhs_sz) {
|
||||||
@ -71,31 +69,31 @@ namespace sol {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Char* begin() const {
|
constexpr const Char* begin() const {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Char* end() const {
|
constexpr const Char* end() const {
|
||||||
return p + s;
|
return p + s;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Char* cbegin() const {
|
constexpr const Char* cbegin() const {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Char* cend() const {
|
constexpr const Char* cend() const {
|
||||||
return p + s;
|
return p + s;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Char* data() const {
|
constexpr const Char* data() const {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t size() const {
|
constexpr std::size_t size() const {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t length() const {
|
constexpr std::size_t length() const {
|
||||||
return size();
|
return size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,31 +66,6 @@ namespace sol {
|
|||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
using is_global = meta::all<meta::boolean<top_level>, meta::is_c_str<Args>...>;
|
using is_global = meta::all<meta::boolean<top_level>, meta::is_c_str<Args>...>;
|
||||||
|
|
||||||
template <typename Fx>
|
|
||||||
void for_each(std::true_type, Fx&& fx) const {
|
|
||||||
auto pp = stack::push_pop(*this);
|
|
||||||
stack::push(base_t::lua_state(), lua_nil);
|
|
||||||
while (lua_next(base_t::lua_state(), -2)) {
|
|
||||||
object key(base_t::lua_state(), -2);
|
|
||||||
object value(base_t::lua_state(), -1);
|
|
||||||
std::pair<object&, object&> keyvalue(key, value);
|
|
||||||
auto pn = stack::pop_n(base_t::lua_state(), 1);
|
|
||||||
fx(keyvalue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Fx>
|
|
||||||
void for_each(std::false_type, Fx&& fx) const {
|
|
||||||
auto pp = stack::push_pop(*this);
|
|
||||||
stack::push(base_t::lua_state(), lua_nil);
|
|
||||||
while (lua_next(base_t::lua_state(), -2)) {
|
|
||||||
object key(base_t::lua_state(), -2);
|
|
||||||
object value(base_t::lua_state(), -1);
|
|
||||||
auto pn = stack::pop_n(base_t::lua_state(), 1);
|
|
||||||
fx(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <bool raw, typename Ret0, typename Ret1, typename... Ret, std::size_t... I, typename Keys>
|
template <bool raw, typename Ret0, typename Ret1, typename... Ret, std::size_t... I, typename Keys>
|
||||||
auto tuple_get(types<Ret0, Ret1, Ret...>, std::index_sequence<0, 1, I...>, Keys&& keys) const
|
auto tuple_get(types<Ret0, Ret1, Ret...>, std::index_sequence<0, 1, I...>, Keys&& keys) const
|
||||||
-> decltype(stack::pop<std::tuple<Ret0, Ret1, Ret...>>(nullptr)) {
|
-> decltype(stack::pop<std::tuple<Ret0, Ret1, Ret...>>(nullptr)) {
|
||||||
@ -384,7 +359,7 @@ namespace sol {
|
|||||||
for (const auto& kvp : items) {
|
for (const auto& kvp : items) {
|
||||||
target.set(kvp.first, kvp.second);
|
target.set(kvp.first, kvp.second);
|
||||||
}
|
}
|
||||||
if (read_only) {
|
if constexpr (read_only) {
|
||||||
table x = create_with(meta_function::new_index, detail::fail_on_newindex, meta_function::index, target);
|
table x = create_with(meta_function::new_index, detail::fail_on_newindex, meta_function::index, target);
|
||||||
table shim = create_named(name, metatable_key, x);
|
table shim = create_named(name, metatable_key, x);
|
||||||
return shim;
|
return shim;
|
||||||
@ -395,10 +370,29 @@ namespace sol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fx>
|
template <typename Key = object, typename Value = object, typename Fx>
|
||||||
void for_each(Fx&& fx) const {
|
void for_each(Fx&& fx) const {
|
||||||
typedef meta::is_invokable<Fx(std::pair<object, object>)> is_paired;
|
if constexpr (std::is_invocable_v<Fx, Key, Value>) {
|
||||||
for_each(is_paired(), std::forward<Fx>(fx));
|
auto pp = stack::push_pop(*this);
|
||||||
|
stack::push(base_t::lua_state(), lua_nil);
|
||||||
|
while (lua_next(base_t::lua_state(), -2)) {
|
||||||
|
Key key(base_t::lua_state(), -2);
|
||||||
|
Value value(base_t::lua_state(), -1);
|
||||||
|
auto pn = stack::pop_n(base_t::lua_state(), 1);
|
||||||
|
fx(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto pp = stack::push_pop(*this);
|
||||||
|
stack::push(base_t::lua_state(), lua_nil);
|
||||||
|
while (lua_next(base_t::lua_state(), -2)) {
|
||||||
|
Key key(base_t::lua_state(), -2);
|
||||||
|
Value value(base_t::lua_state(), -1);
|
||||||
|
auto pn = stack::pop_n(base_t::lua_state(), 1);
|
||||||
|
std::pair<Key&, Value&> keyvalue(key, value);
|
||||||
|
fx(keyvalue);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
|
@ -800,9 +800,14 @@ namespace sol {
|
|||||||
|| std::is_base_of<stack_reference, meta::unqualified_t<T>>::value> {};
|
|| std::is_base_of<stack_reference, meta::unqualified_t<T>>::value> {};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_lua_reference_or_proxy : std::integral_constant<bool,
|
inline constexpr bool is_lua_reference_v = is_lua_reference<T>::value;
|
||||||
is_lua_reference<meta::unqualified_t<T>>::value
|
|
||||||
|| meta::is_specialization_of<meta::unqualified_t<T>, proxy>::value> {};
|
template <typename T>
|
||||||
|
struct is_lua_reference_or_proxy
|
||||||
|
: std::integral_constant<bool, is_lua_reference<meta::unqualified_t<T>>::value || meta::is_specialization_of<meta::unqualified_t<T>, proxy>::value> {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr bool is_lua_reference_or_proxy_v = is_lua_reference_or_proxy<T>::value;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_transparent_argument : std::false_type {};
|
struct is_transparent_argument : std::false_type {};
|
||||||
|
@ -44,6 +44,8 @@ namespace sol { namespace u_detail {
|
|||||||
usertype_storage<T>& get_usertype_storage(lua_State* L);
|
usertype_storage<T>& get_usertype_storage(lua_State* L);
|
||||||
|
|
||||||
using index_call_function = int(lua_State*, void*);
|
using index_call_function = int(lua_State*, void*);
|
||||||
|
using change_indexing_mem_func
|
||||||
|
= void (usertype_storage_base::*)(lua_State*, submetatable_type, void*, stack_reference&, lua_CFunction, lua_CFunction, lua_CFunction, lua_CFunction);
|
||||||
|
|
||||||
struct index_call_storage {
|
struct index_call_storage {
|
||||||
index_call_function* index;
|
index_call_function* index;
|
||||||
@ -51,6 +53,10 @@ namespace sol { namespace u_detail {
|
|||||||
void* binding_data;
|
void* binding_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct new_index_call_storage : index_call_storage {
|
||||||
|
void* new_binding_data;
|
||||||
|
};
|
||||||
|
|
||||||
struct binding_base {
|
struct binding_base {
|
||||||
virtual void* data() = 0;
|
virtual void* data() = 0;
|
||||||
virtual ~binding_base() {
|
virtual ~binding_base() {
|
||||||
@ -148,6 +154,130 @@ namespace sol { namespace u_detail {
|
|||||||
return new_index_fail(L);
|
return new_index_fail(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct string_for_each_metatable_func {
|
||||||
|
bool is_destruction = false;
|
||||||
|
bool is_index = false;
|
||||||
|
bool is_new_index = false;
|
||||||
|
bool poison_indexing = false;
|
||||||
|
bool is_unqualified_lua_CFunction = false;
|
||||||
|
bool is_unqualified_lua_reference = false;
|
||||||
|
std::string* p_key = nullptr;
|
||||||
|
reference* p_binding_ref = nullptr;
|
||||||
|
lua_CFunction call_func = nullptr;
|
||||||
|
index_call_storage* p_ics = nullptr;
|
||||||
|
usertype_storage_base* p_usb = nullptr;
|
||||||
|
void* p_derived_usb = nullptr;
|
||||||
|
lua_CFunction idx_call = nullptr,
|
||||||
|
new_idx_call = nullptr,
|
||||||
|
meta_idx_call = nullptr,
|
||||||
|
meta_new_idx_call = nullptr;
|
||||||
|
change_indexing_mem_func change_indexing;
|
||||||
|
|
||||||
|
void operator()(lua_State* L, submetatable_type smt, reference& fast_index_table) {
|
||||||
|
std::string& key = *p_key;
|
||||||
|
usertype_storage_base& usb = *p_usb;
|
||||||
|
index_call_storage& ics = *p_ics;
|
||||||
|
|
||||||
|
if (smt == submetatable_type::named) {
|
||||||
|
// do not override __call or
|
||||||
|
// other specific meta functions on named metatable:
|
||||||
|
// we need that for call construction
|
||||||
|
// and other amenities
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int fast_index_table_push = fast_index_table.push();
|
||||||
|
stack_reference t(L, -fast_index_table_push);
|
||||||
|
if (poison_indexing) {
|
||||||
|
(usb.*change_indexing)(L,
|
||||||
|
smt,
|
||||||
|
p_derived_usb,
|
||||||
|
t,
|
||||||
|
idx_call,
|
||||||
|
new_idx_call,
|
||||||
|
meta_idx_call,
|
||||||
|
meta_new_idx_call);
|
||||||
|
}
|
||||||
|
if (is_destruction
|
||||||
|
&& (smt == submetatable_type::reference || smt == submetatable_type::const_reference || smt == submetatable_type::named
|
||||||
|
|| smt == submetatable_type::unique)) {
|
||||||
|
// gc does not apply to us here
|
||||||
|
// for reference types (raw T*, std::ref)
|
||||||
|
// for the named metatable itself,
|
||||||
|
// or for unique_usertypes, which do their own custom destruction
|
||||||
|
t.pop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (is_index || is_new_index) {
|
||||||
|
// do not serialize the new_index and index functions here directly
|
||||||
|
// we control those...
|
||||||
|
t.pop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (is_unqualified_lua_CFunction) {
|
||||||
|
stack::set_field<false, true>(L, key, call_func, t.stack_index());
|
||||||
|
}
|
||||||
|
else if (is_unqualified_lua_reference) {
|
||||||
|
reference& binding_ref = *p_binding_ref;
|
||||||
|
stack::set_field<false, true>(L, key, binding_ref, t.stack_index());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
stack::set_field<false, true>(L, key, make_closure(call_func, nullptr, ics.binding_data), t.stack_index());
|
||||||
|
}
|
||||||
|
t.pop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lua_reference_func {
|
||||||
|
reference key;
|
||||||
|
reference value;
|
||||||
|
|
||||||
|
void operator()(lua_State* L, submetatable_type smt, reference& fast_index_table) {
|
||||||
|
if (smt == submetatable_type::named) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int fast_index_table_push = fast_index_table.push();
|
||||||
|
stack_reference t(L, -fast_index_table_push);
|
||||||
|
stack::set_field<false, true>(L, key, value, t.stack_index());
|
||||||
|
t.pop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct update_bases_func {
|
||||||
|
detail::inheritance_check_function base_class_check_func;
|
||||||
|
detail::inheritance_cast_function base_class_cast_func;
|
||||||
|
lua_CFunction idx_call, new_idx_call, meta_idx_call, meta_new_idx_call;
|
||||||
|
usertype_storage_base* p_usb;
|
||||||
|
void* p_derived_usb;
|
||||||
|
change_indexing_mem_func change_indexing;
|
||||||
|
|
||||||
|
void operator()(lua_State* L, submetatable_type smt, reference& fast_index_table) {
|
||||||
|
int fast_index_table_push = fast_index_table.push();
|
||||||
|
stack_reference t(L, -fast_index_table_push);
|
||||||
|
stack::set_field(L, detail::base_class_check_key(), reinterpret_cast<void*>(base_class_check_func), t.stack_index());
|
||||||
|
stack::set_field(L, detail::base_class_cast_key(), reinterpret_cast<void*>(base_class_cast_func), t.stack_index());
|
||||||
|
// change indexing, forcefully
|
||||||
|
(p_usb->*change_indexing)(L,
|
||||||
|
smt,
|
||||||
|
p_derived_usb,
|
||||||
|
t,
|
||||||
|
idx_call,
|
||||||
|
new_idx_call,
|
||||||
|
meta_idx_call,
|
||||||
|
meta_new_idx_call);
|
||||||
|
t.pop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct binding_data_equals {
|
||||||
|
void* binding_data;
|
||||||
|
|
||||||
|
binding_data_equals(void* b) : binding_data(b) {}
|
||||||
|
|
||||||
|
bool operator()(const std::unique_ptr<binding_base>& ptr) const {
|
||||||
|
return binding_data == ptr->data();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct usertype_storage_base {
|
struct usertype_storage_base {
|
||||||
public:
|
public:
|
||||||
std::vector<std::unique_ptr<binding_base>> storage;
|
std::vector<std::unique_ptr<binding_base>> storage;
|
||||||
@ -163,13 +293,10 @@ namespace sol { namespace u_detail {
|
|||||||
reference type_table;
|
reference type_table;
|
||||||
reference gc_names_table;
|
reference gc_names_table;
|
||||||
reference named_metatable;
|
reference named_metatable;
|
||||||
std::bitset<64> properties;
|
new_index_call_storage base_index;
|
||||||
index_call_storage base_index;
|
|
||||||
index_call_storage base_new_index;
|
|
||||||
lua_CFunction weak_base_index;
|
|
||||||
lua_CFunction weak_base_new_index;
|
|
||||||
bool is_using_index;
|
bool is_using_index;
|
||||||
bool is_using_new_index;
|
bool is_using_new_index;
|
||||||
|
std::bitset<64> properties;
|
||||||
|
|
||||||
usertype_storage_base(lua_State* L)
|
usertype_storage_base(lua_State* L)
|
||||||
: storage()
|
: storage()
|
||||||
@ -182,17 +309,14 @@ namespace sol { namespace u_detail {
|
|||||||
, type_table(make_reference(L, create))
|
, type_table(make_reference(L, create))
|
||||||
, gc_names_table(make_reference(L, create))
|
, gc_names_table(make_reference(L, create))
|
||||||
, named_metatable(make_reference(L, create))
|
, named_metatable(make_reference(L, create))
|
||||||
, properties()
|
|
||||||
, base_index()
|
, base_index()
|
||||||
, base_new_index()
|
|
||||||
, is_using_index(false)
|
, is_using_index(false)
|
||||||
, is_using_new_index(false) {
|
, is_using_new_index(false)
|
||||||
|
, properties() {
|
||||||
base_index.binding_data = nullptr;
|
base_index.binding_data = nullptr;
|
||||||
base_index.index = index_target_fail;
|
base_index.index = index_target_fail;
|
||||||
base_index.new_index = index_target_fail;
|
base_index.new_index = new_index_target_fail;
|
||||||
base_new_index.binding_data = nullptr;
|
base_index.new_binding_data = nullptr;
|
||||||
base_new_index.index = new_index_target_fail;
|
|
||||||
base_new_index.new_index = new_index_target_fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fx>
|
template <typename Fx>
|
||||||
@ -242,7 +366,7 @@ namespace sol { namespace u_detail {
|
|||||||
"The size of this data pointer is too small to fit the inheritance checking function: Please file "
|
"The size of this data pointer is too small to fit the inheritance checking function: Please file "
|
||||||
"a bug report.");
|
"a bug report.");
|
||||||
static_assert(!meta::any_same<T, Bases...>::value, "base classes cannot list the original class as part of the bases");
|
static_assert(!meta::any_same<T, Bases...>::value, "base classes cannot list the original class as part of the bases");
|
||||||
if (sizeof...(Bases) < 1) {
|
if constexpr (sizeof...(Bases) < 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,31 +374,18 @@ namespace sol { namespace u_detail {
|
|||||||
|
|
||||||
void* derived_this = static_cast<void*>(static_cast<usertype_storage<T>*>(this));
|
void* derived_this = static_cast<void*>(static_cast<usertype_storage<T>*>(this));
|
||||||
|
|
||||||
auto change_indexing_and_set_weak_derive = [&](lua_State* L, submetatable_type smt, reference& fast_index_table) {
|
update_bases_func for_each_fx;
|
||||||
int fast_index_table_push = fast_index_table.push();
|
for_each_fx.base_class_check_func = &detail::inheritance<T>::template type_check_with<Bases...>;
|
||||||
stack_reference t(L, -fast_index_table_push);
|
for_each_fx.base_class_cast_func = &detail::inheritance<T>::template type_cast_with<Bases...>;
|
||||||
static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function),
|
for_each_fx.idx_call = &usertype_storage<T>::template index_call_with_bases<false, Bases...>;
|
||||||
"The size of this data pointer is too small to fit the inheritance checking function: file a "
|
for_each_fx.new_idx_call = &usertype_storage<T>::template index_call_with_bases<true, Bases...>;
|
||||||
"bug report.");
|
for_each_fx.meta_idx_call = &usertype_storage<T>::template meta_index_call_with_bases<false, Bases...>;
|
||||||
static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function),
|
for_each_fx.meta_new_idx_call = &usertype_storage<T>::template meta_index_call_with_bases<true, Bases...>;
|
||||||
"The size of this data pointer is too small to fit the inheritance checking function: file a "
|
for_each_fx.p_usb = this;
|
||||||
"bug report.");
|
for_each_fx.p_derived_usb = derived_this;
|
||||||
auto base_class_check_func = &detail::inheritance<T>::template type_check_with<Bases...>;
|
for_each_fx.change_indexing = &usertype_storage_base::change_indexing;
|
||||||
auto base_class_cast_func = &detail::inheritance<T>::template type_cast_with<Bases...>;
|
for_each_fx.p_derived_usb = derived_this;
|
||||||
stack::set_field(L, detail::base_class_check_key(), reinterpret_cast<void*>(base_class_check_func), t.stack_index());
|
this->for_each_table(L, for_each_fx);
|
||||||
stack::set_field(L, detail::base_class_cast_key(), reinterpret_cast<void*>(base_class_cast_func), t.stack_index());
|
|
||||||
// change indexing, forcefully
|
|
||||||
change_indexing(L,
|
|
||||||
smt,
|
|
||||||
derived_this,
|
|
||||||
t,
|
|
||||||
&usertype_storage<T>::template index_call_with_bases<Bases...>,
|
|
||||||
&usertype_storage<T>::template new_index_call_with_bases<Bases...>,
|
|
||||||
&usertype_storage<T>::template meta_index_call_with_bases<Bases...>,
|
|
||||||
&usertype_storage<T>::template meta_new_index_call_with_bases<Bases...>);
|
|
||||||
t.pop();
|
|
||||||
};
|
|
||||||
this->for_each_table(L, change_indexing_and_set_weak_derive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
@ -286,7 +397,7 @@ namespace sol { namespace u_detail {
|
|||||||
// then replace unqualified_getter/setter
|
// then replace unqualified_getter/setter
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Base>
|
template <bool is_new_index, typename Base>
|
||||||
static void base_walk_index(lua_State* L, usertype_storage_base& self, bool& keep_going, int& base_result) {
|
static void base_walk_index(lua_State* L, usertype_storage_base& self, bool& keep_going, int& base_result) {
|
||||||
using bases = typename base<Base>::type;
|
using bases = typename base<Base>::type;
|
||||||
if (!keep_going) {
|
if (!keep_going) {
|
||||||
@ -296,25 +407,11 @@ namespace sol { namespace u_detail {
|
|||||||
(void)self;
|
(void)self;
|
||||||
// TODO: get base table, dump it out
|
// TODO: get base table, dump it out
|
||||||
usertype_storage_base& base_storage = get_usertype_storage<Base>(L);
|
usertype_storage_base& base_storage = get_usertype_storage<Base>(L);
|
||||||
base_result = self_index_call<true>(bases(), L, base_storage);
|
base_result = self_index_call<is_new_index, true>(bases(), L, base_storage);
|
||||||
keep_going = base_result == base_walking_failed_index;
|
keep_going = base_result == base_walking_failed_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Base>
|
template <bool is_new_index = false, bool base_walking = false, bool from_named_metatable = false, typename... Bases>
|
||||||
static void base_walk_new_index(lua_State* L, usertype_storage_base& self, bool& keep_going, int& base_result) {
|
|
||||||
using bases = typename base<Base>::type;
|
|
||||||
if (!keep_going) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
(void)L;
|
|
||||||
(void)self;
|
|
||||||
// TODO: get base table, dump it out
|
|
||||||
usertype_storage_base& base_storage = get_usertype_storage<Base>(L);
|
|
||||||
base_result = self_new_index_call<true>(bases(), L, base_storage);
|
|
||||||
keep_going = base_result == base_walking_failed_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <bool base_walking = false, bool from_named_metatable = false, typename... Bases>
|
|
||||||
static inline int self_index_call(types<Bases...>, lua_State* L, usertype_storage_base& self) {
|
static inline int self_index_call(types<Bases...>, lua_State* L, usertype_storage_base& self) {
|
||||||
type k_type = stack::get<type>(L, 2);
|
type k_type = stack::get<type>(L, 2);
|
||||||
if (k_type == type::string) {
|
if (k_type == type::string) {
|
||||||
@ -328,9 +425,14 @@ namespace sol { namespace u_detail {
|
|||||||
}
|
}
|
||||||
if (target != nullptr) {
|
if (target != nullptr) {
|
||||||
// let the target decide what to do
|
// let the target decide what to do
|
||||||
|
if constexpr (is_new_index) {
|
||||||
|
return (target->new_index)(L, target->binding_data);
|
||||||
|
}
|
||||||
|
else {
|
||||||
return (target->index)(L, target->binding_data);
|
return (target->index)(L, target->binding_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (k_type != type::nil && k_type != type::none) {
|
else if (k_type != type::nil && k_type != type::none) {
|
||||||
reference* target = nullptr;
|
reference* target = nullptr;
|
||||||
{
|
{
|
||||||
@ -341,96 +443,63 @@ namespace sol { namespace u_detail {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (target != nullptr) {
|
if (target != nullptr) {
|
||||||
|
if constexpr(is_new_index) {
|
||||||
|
// set value and return
|
||||||
|
*target = reference(L, 3);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
// push target to return
|
// push target to return
|
||||||
// what we found
|
// what we found
|
||||||
return stack::push(L, *target);
|
return stack::push(L, *target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// retrieve bases and walk through them.
|
// retrieve bases and walk through them.
|
||||||
bool keep_going = true;
|
bool keep_going = true;
|
||||||
int base_result;
|
int base_result;
|
||||||
detail::swallow{ 1, (base_walk_index<Bases>(L, self, keep_going, base_result), 1)... };
|
(void)keep_going;
|
||||||
if (sizeof...(Bases) > 0 && !keep_going) {
|
(void)base_result;
|
||||||
|
detail::swallow{ 1, (base_walk_index<is_new_index, Bases>(L, self, keep_going, base_result), 1)... };
|
||||||
|
if constexpr (sizeof...(Bases) > 0) {
|
||||||
|
if (!keep_going) {
|
||||||
return base_result;
|
return base_result;
|
||||||
}
|
}
|
||||||
if (base_walking) {
|
}
|
||||||
|
if constexpr (base_walking) {
|
||||||
// if we're JUST base-walking then don't index-fail, just
|
// if we're JUST base-walking then don't index-fail, just
|
||||||
// return the false bits
|
// return the false bits
|
||||||
return base_walking_failed_index;
|
return base_walking_failed_index;
|
||||||
}
|
}
|
||||||
if constexpr (from_named_metatable) {
|
else if constexpr (from_named_metatable) {
|
||||||
|
if constexpr (is_new_index) {
|
||||||
|
self.set(L, reference(L, raw_index(2)), reference(L, raw_index(3)));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
return index_fail(L);
|
return index_fail(L);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if constexpr (is_new_index) {
|
||||||
|
return self.base_index.new_index(L, self.base_index.new_binding_data);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
return self.base_index.index(L, self.base_index.binding_data);
|
return self.base_index.index(L, self.base_index.binding_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool base_walking = false, bool from_named_metatable = false, typename... Bases>
|
|
||||||
static inline int self_new_index_call(types<Bases...>, lua_State* L, usertype_storage_base& self) {
|
|
||||||
type k_type = stack::get<type>(L, 2);
|
|
||||||
if (k_type == type::string) {
|
|
||||||
index_call_storage* target = nullptr;
|
|
||||||
{
|
|
||||||
string_view k = stack::get<string_view>(L, 2);
|
|
||||||
auto it = self.string_keys.find(k);
|
|
||||||
if (it != self.string_keys.cend()) {
|
|
||||||
target = &it->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (target != nullptr) {
|
|
||||||
// set value through
|
|
||||||
// new_index call, whatever that entails,
|
|
||||||
// and return
|
|
||||||
return (target->new_index)(L, target->binding_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (k_type != type::nil && k_type != type::none) {
|
|
||||||
reference* target = nullptr;
|
|
||||||
{
|
|
||||||
stack_reference k = stack::get<stack_reference>(L, 2);
|
|
||||||
auto it = self.auxiliary_keys.find(k);
|
|
||||||
if (it != self.auxiliary_keys.cend()) {
|
|
||||||
target = &it->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (target != nullptr) {
|
|
||||||
// set value and return
|
|
||||||
*target = reference(L, 3);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// retrieve bases and walk through them.
|
void change_indexing(lua_State* L, submetatable_type submetatable, void* derived_this, stack_reference& t, lua_CFunction index,
|
||||||
bool keep_going = true;
|
|
||||||
int base_result;
|
|
||||||
detail::swallow{ 1, (base_walk_new_index<Bases>(L, self, keep_going, base_result), 1)... };
|
|
||||||
if (sizeof...(Bases) > 0 && !keep_going) {
|
|
||||||
return base_result;
|
|
||||||
}
|
|
||||||
if (base_walking) {
|
|
||||||
// if we're JUST base-walking then don't index-fail, just
|
|
||||||
// return the false bits
|
|
||||||
return base_walking_failed_index;
|
|
||||||
}
|
|
||||||
if constexpr (from_named_metatable) {
|
|
||||||
self.set(L, reference(L, raw_index(2)), reference(L, raw_index(3)));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return self.base_new_index.new_index(L, self.base_new_index.binding_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void change_indexing(lua_State* L, submetatable_type submetatable_type, void* derived_this, stack_reference& t, lua_CFunction index,
|
|
||||||
lua_CFunction new_index, lua_CFunction meta_index, lua_CFunction meta_new_index) {
|
lua_CFunction new_index, lua_CFunction meta_index, lua_CFunction meta_new_index) {
|
||||||
usertype_storage_base& this_base = *this;
|
usertype_storage_base& this_base = *this;
|
||||||
void* base_this = static_cast<void*>(&this_base);
|
void* base_this = static_cast<void*>(&this_base);
|
||||||
|
|
||||||
this->is_using_index |= true;
|
this->is_using_index |= true;
|
||||||
this->is_using_new_index |= true;
|
this->is_using_new_index |= true;
|
||||||
if (submetatable_type == submetatable_type::named) {
|
//detail::clear_entries(t);
|
||||||
|
if (submetatable == submetatable_type::named) {
|
||||||
stack::set_field(L, metatable_key, named_index_table, t.stack_index());
|
stack::set_field(L, metatable_key, named_index_table, t.stack_index());
|
||||||
stack_reference stack_metametatable(L, -named_metatable.push());
|
stack_reference stack_metametatable(L, -named_metatable.push());
|
||||||
stack::set_field<false, true>(L,
|
stack::set_field<false, true>(L,
|
||||||
@ -460,68 +529,38 @@ namespace sol { namespace u_detail {
|
|||||||
|
|
||||||
using usertype_storage_base::usertype_storage_base;
|
using usertype_storage_base::usertype_storage_base;
|
||||||
|
|
||||||
template <bool from_named_metatable>
|
template <bool is_new_index, bool from_named_metatable>
|
||||||
static inline int index_call_(lua_State* L) {
|
static inline int index_call_(lua_State* L) {
|
||||||
using bases = typename base<T>::type;
|
using bases = typename base<T>::type;
|
||||||
usertype_storage_base& self = stack::get<light<usertype_storage_base>>(L, upvalue_index(usertype_storage_index));
|
usertype_storage_base& self = stack::get<light<usertype_storage_base>>(L, upvalue_index(usertype_storage_index));
|
||||||
return self_index_call<false, from_named_metatable>(bases(), L, self);
|
return self_index_call<is_new_index, false, from_named_metatable>(bases(), L, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool from_named_metatable, typename... Bases>
|
template <bool is_new_index, bool from_named_metatable, typename... Bases>
|
||||||
static inline int index_call_with_bases_(lua_State* L) {
|
static inline int index_call_with_bases_(lua_State* L) {
|
||||||
using bases = types<Bases...>;
|
using bases = types<Bases...>;
|
||||||
usertype_storage_base& self = stack::get<light<usertype_storage_base>>(L, upvalue_index(usertype_storage_index));
|
usertype_storage_base& self = stack::get<light<usertype_storage_base>>(L, upvalue_index(usertype_storage_index));
|
||||||
return self_index_call<false, from_named_metatable>(bases(), L, self);
|
return self_index_call<is_new_index, false, from_named_metatable>(bases(), L, self);
|
||||||
}
|
|
||||||
|
|
||||||
template <bool from_named_metatable>
|
|
||||||
static inline int new_index_call_(lua_State* L) {
|
|
||||||
using bases = typename base<T>::type;
|
|
||||||
usertype_storage_base& self = stack::get<light<usertype_storage_base>>(L, upvalue_index(usertype_storage_index));
|
|
||||||
return self_new_index_call<false, from_named_metatable>(bases(), L, self);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <bool from_named_metatable, typename... Bases>
|
|
||||||
static inline int new_index_call_with_bases_(lua_State* L) {
|
|
||||||
using bases = types<Bases...>;
|
|
||||||
usertype_storage_base& self = stack::get<light<usertype_storage_base>>(L, upvalue_index(usertype_storage_index));
|
|
||||||
return self_new_index_call<false, from_named_metatable>(bases(), L, self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <bool is_new_index>
|
||||||
static inline int index_call(lua_State* L) {
|
static inline int index_call(lua_State* L) {
|
||||||
return detail::static_trampoline<&index_call_<false>>(L);
|
return detail::static_trampoline<&index_call_<is_new_index, false>>(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Bases>
|
template <bool is_new_index, typename... Bases>
|
||||||
static inline int index_call_with_bases(lua_State* L) {
|
static inline int index_call_with_bases(lua_State* L) {
|
||||||
return detail::static_trampoline<&index_call_with_bases_<false, Bases...>>(L);
|
return detail::static_trampoline<&index_call_with_bases_<is_new_index, false, Bases...>>(L);
|
||||||
}
|
|
||||||
|
|
||||||
static inline int new_index_call(lua_State* L) {
|
|
||||||
return detail::static_trampoline<&new_index_call_<false>>(L);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Bases>
|
|
||||||
static inline int new_index_call_with_bases(lua_State* L) {
|
|
||||||
return detail::static_trampoline<&new_index_call_with_bases_<false, Bases...>>(L);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <bool is_new_index>
|
||||||
static inline int meta_index_call(lua_State* L) {
|
static inline int meta_index_call(lua_State* L) {
|
||||||
return detail::static_trampoline<&index_call_<true>>(L);
|
return detail::static_trampoline<&index_call_<is_new_index, true>>(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Bases>
|
template <bool is_new_index, typename... Bases>
|
||||||
static inline int meta_index_call_with_bases(lua_State* L) {
|
static inline int meta_index_call_with_bases(lua_State* L) {
|
||||||
return detail::static_trampoline<&index_call_with_bases_<true, Bases...>>(L);
|
return detail::static_trampoline<&index_call_with_bases_<is_new_index, true, Bases...>>(L);
|
||||||
}
|
|
||||||
|
|
||||||
static inline int meta_new_index_call(lua_State* L) {
|
|
||||||
return detail::static_trampoline<&new_index_call_<true>>(L);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Bases>
|
|
||||||
static inline int meta_new_index_call_with_bases(lua_State* L) {
|
|
||||||
return detail::static_trampoline<&new_index_call_with_bases_<true, Bases...>>(L);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Key, typename Value>
|
template <typename Key, typename Value>
|
||||||
@ -557,9 +596,7 @@ namespace sol { namespace u_detail {
|
|||||||
auto string_it = this->string_keys.find(s);
|
auto string_it = this->string_keys.find(s);
|
||||||
if (string_it != this->string_keys.cend()) {
|
if (string_it != this->string_keys.cend()) {
|
||||||
const auto& binding_data = string_it->second.binding_data;
|
const auto& binding_data = string_it->second.binding_data;
|
||||||
storage_it = std::find_if(this->storage.begin(), this->storage.end(), [&binding_data](const std::unique_ptr<binding_base>& b) {
|
storage_it = std::find_if(this->storage.begin(), this->storage.end(), binding_data_equals(binding_data));
|
||||||
return b->data() == binding_data;
|
|
||||||
});
|
|
||||||
this->string_keys.erase(string_it);
|
this->string_keys.erase(string_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -580,75 +617,58 @@ namespace sol { namespace u_detail {
|
|||||||
index_call_storage ics;
|
index_call_storage ics;
|
||||||
ics.binding_data = b.data();
|
ics.binding_data = b.data();
|
||||||
ics.index = is_index ? &Binding::template call_with_<true, is_var_bind::value> : &Binding::template index_call_with_<true, is_var_bind::value>;
|
ics.index = is_index ? &Binding::template call_with_<true, is_var_bind::value> : &Binding::template index_call_with_<true, is_var_bind::value>;
|
||||||
ics.new_index = is_new_index ? &Binding::template call_with_<false, is_var_bind::value>
|
ics.new_index
|
||||||
: &Binding::template index_call_with_<false, is_var_bind::value>;
|
= is_new_index ? &Binding::template call_with_<false, is_var_bind::value> : &Binding::template index_call_with_<false, is_var_bind::value>;
|
||||||
// need to swap everything to use fast indexing here
|
|
||||||
auto for_each_backing_metatable = [&](lua_State* L, submetatable_type smt, reference& fast_index_table) {
|
string_for_each_metatable_func for_each_fx;
|
||||||
if (smt == submetatable_type::named) {
|
for_each_fx.is_destruction = is_destruction;
|
||||||
// do not override __call or
|
for_each_fx.is_index = is_index;
|
||||||
// other specific meta functions on named metatable:
|
for_each_fx.is_new_index = is_new_index;
|
||||||
// we need that for call construction
|
for_each_fx.poison_indexing = poison_indexing;
|
||||||
// and other amenities
|
for_each_fx.p_key = &s;
|
||||||
return;
|
for_each_fx.p_ics = &ics;
|
||||||
|
if constexpr (is_lua_c_function_v<ValueU>) {
|
||||||
|
for_each_fx.is_unqualified_lua_CFunction = true;
|
||||||
|
for_each_fx.call_func = *static_cast<lua_CFunction*>(ics.binding_data);
|
||||||
}
|
}
|
||||||
int fast_index_table_push = fast_index_table.push();
|
else if constexpr (is_lua_reference_or_proxy_v<ValueU>) {
|
||||||
stack_reference t(L, -fast_index_table_push);
|
for_each_fx.is_unqualified_lua_reference = true;
|
||||||
if (poison_indexing) {
|
for_each_fx.p_binding_ref = static_cast<reference*>(ics.binding_data);
|
||||||
change_indexing(L,
|
|
||||||
smt,
|
|
||||||
derived_this,
|
|
||||||
t,
|
|
||||||
&usertype_storage<T>::index_call,
|
|
||||||
&usertype_storage<T>::new_index_call,
|
|
||||||
&usertype_storage<T>::meta_index_call,
|
|
||||||
&usertype_storage<T>::meta_new_index_call);
|
|
||||||
}
|
|
||||||
if (is_destruction
|
|
||||||
&& (smt == submetatable_type::reference || smt == submetatable_type::const_reference || smt == submetatable_type::named
|
|
||||||
|| smt == submetatable_type::unique)) {
|
|
||||||
// gc does not apply to us here
|
|
||||||
// for reference types (raw T*, std::ref)
|
|
||||||
// for the named metatable itself,
|
|
||||||
// or for unique_usertypes, which do their own custom destruction
|
|
||||||
t.pop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if constexpr (is_lua_c_function_v<ValueU> || is_lua_reference_or_proxy<ValueU>::value) {
|
|
||||||
stack::set_field<false, true>(L, s, b.data_, t.stack_index());
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
stack::set_field<false, true>(L, s, make_closure(&b.template call<false, is_var_bind::value>, nullptr, ics.binding_data), t.stack_index());
|
for_each_fx.call_func = &b.template call<false, is_var_bind::value>;
|
||||||
}
|
}
|
||||||
t.pop();
|
for_each_fx.p_usb = this;
|
||||||
};
|
for_each_fx.p_derived_usb = derived_this;
|
||||||
|
for_each_fx.idx_call = &usertype_storage<T>::template index_call<false>;
|
||||||
|
for_each_fx.new_idx_call = &usertype_storage<T>::template index_call<true>;
|
||||||
|
for_each_fx.meta_idx_call = &usertype_storage<T>::template meta_index_call<false>;
|
||||||
|
for_each_fx.meta_new_idx_call = &usertype_storage<T>::template meta_index_call<true>;
|
||||||
|
for_each_fx.change_indexing = &usertype_storage_base::change_indexing;
|
||||||
|
// set base index and base new_index
|
||||||
|
// functions here
|
||||||
if (is_index) {
|
if (is_index) {
|
||||||
this->base_index = ics;
|
this->base_index.index = ics.index;
|
||||||
|
this->base_index.binding_data = ics.binding_data;
|
||||||
}
|
}
|
||||||
if (is_new_index) {
|
if (is_new_index) {
|
||||||
this->base_new_index = ics;
|
this->base_index.new_index = ics.new_index;
|
||||||
|
this->base_index.new_binding_data = ics.binding_data;
|
||||||
}
|
}
|
||||||
this->for_each_table(L, for_each_backing_metatable);
|
this->for_each_table(L, for_each_fx);
|
||||||
this->add_entry(s, std::move(ics));
|
this->add_entry(s, std::move(ics));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// the reference-based implementation might compare poorly and hash
|
// the reference-based implementation might compare poorly and hash
|
||||||
// poorly in some cases...
|
// poorly in some cases...
|
||||||
if constexpr (is_lua_reference<KeyU>::value && is_lua_reference<ValueU>::value) {
|
if constexpr (is_lua_reference_v<KeyU> && is_lua_reference_v<ValueU>) {
|
||||||
if (key.get_type() == type::string) {
|
if (key.get_type() == type::string) {
|
||||||
stack::push(L, key);
|
stack::push(L, key);
|
||||||
std::string string_key = stack::pop<std::string>(L);
|
std::string string_key = stack::pop<std::string>(L);
|
||||||
this->set<T>(L, string_key, std::forward<Value>(value));
|
this->set<T>(L, string_key, std::forward<Value>(value));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto ref_additions_fx = [&](lua_State* L, submetatable_type smt, reference& fast_index_table) {
|
lua_reference_func ref_additions_fx{ key, value };
|
||||||
if (smt == submetatable_type::named) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int fast_index_table_push = fast_index_table.push();
|
|
||||||
stack_reference t(L, -fast_index_table_push);
|
|
||||||
stack::set_field<false, true>(L, key, value, t.stack_index());
|
|
||||||
t.pop();
|
|
||||||
};
|
|
||||||
|
|
||||||
this->for_each_table(L, ref_additions_fx);
|
this->for_each_table(L, ref_additions_fx);
|
||||||
this->auxiliary_keys.insert_or_assign(std::forward<Key>(key), std::forward<Value>(value));
|
this->auxiliary_keys.insert_or_assign(std::forward<Key>(key), std::forward<Value>(value));
|
||||||
@ -657,15 +677,8 @@ namespace sol { namespace u_detail {
|
|||||||
else {
|
else {
|
||||||
reference ref_key = make_reference(L, std::forward<Key>(key));
|
reference ref_key = make_reference(L, std::forward<Key>(key));
|
||||||
reference ref_value = make_reference(L, std::forward<Value>(value));
|
reference ref_value = make_reference(L, std::forward<Value>(value));
|
||||||
auto ref_additions_fx = [&](lua_State* L, submetatable_type smt, reference& fast_index_table) {
|
lua_reference_func ref_additions_fx{ key, value };
|
||||||
if (smt == submetatable_type::named) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int fast_index_table_push = fast_index_table.push();
|
|
||||||
stack_reference t(L, -fast_index_table_push);
|
|
||||||
stack::set_field<false, true>(L, ref_key, ref_value, t.stack_index());
|
|
||||||
t.pop();
|
|
||||||
};
|
|
||||||
this->for_each_table(L, ref_additions_fx);
|
this->for_each_table(L, ref_additions_fx);
|
||||||
this->auxiliary_keys.insert_or_assign(std::move(ref_key), std::move(ref_value));
|
this->auxiliary_keys.insert_or_assign(std::move(ref_key), std::move(ref_value));
|
||||||
}
|
}
|
||||||
@ -952,11 +965,11 @@ namespace sol { namespace u_detail {
|
|||||||
stack_reference stack_metametatable(L, -storage.named_index_table.push());
|
stack_reference stack_metametatable(L, -storage.named_index_table.push());
|
||||||
stack::set_field<false, true>(L,
|
stack::set_field<false, true>(L,
|
||||||
meta_function::index,
|
meta_function::index,
|
||||||
make_closure(uts::meta_index_call, nullptr, light_storage, light_base_storage, nullptr, toplevel_magic),
|
make_closure(uts::template meta_index_call<false>, nullptr, light_storage, light_base_storage, nullptr, toplevel_magic),
|
||||||
stack_metametatable.stack_index());
|
stack_metametatable.stack_index());
|
||||||
stack::set_field<false, true>(L,
|
stack::set_field<false, true>(L,
|
||||||
meta_function::new_index,
|
meta_function::new_index,
|
||||||
make_closure(uts::meta_new_index_call, nullptr, light_storage, light_base_storage, nullptr, toplevel_magic),
|
make_closure(uts::template meta_index_call<true>, nullptr, light_storage, light_base_storage, nullptr, toplevel_magic),
|
||||||
stack_metametatable.stack_index());
|
stack_metametatable.stack_index());
|
||||||
stack_metametatable.pop();
|
stack_metametatable.pop();
|
||||||
}
|
}
|
||||||
@ -966,7 +979,7 @@ namespace sol { namespace u_detail {
|
|||||||
stack::set_field<false, true>(L, meta_function::index, t, t.stack_index());
|
stack::set_field<false, true>(L, meta_function::index, t, t.stack_index());
|
||||||
stack::set_field<false, true>(L,
|
stack::set_field<false, true>(L,
|
||||||
meta_function::new_index,
|
meta_function::new_index,
|
||||||
make_closure(uts::new_index_call, nullptr, light_storage, light_base_storage, nullptr, toplevel_magic),
|
make_closure(uts::template index_call<true>, nullptr, light_storage, light_base_storage, nullptr, toplevel_magic),
|
||||||
t.stack_index());
|
t.stack_index());
|
||||||
storage.is_using_new_index = true;
|
storage.is_using_new_index = true;
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,29 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
struct new_index_test_object {
|
||||||
|
bool new_indexed = false;
|
||||||
|
bool borf_new_indexed = false;
|
||||||
|
|
||||||
|
float GetLevel(int x) const {
|
||||||
|
return static_cast<float>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nidx(new_index_test_object& self, std::string_view key, sol::stack_object value) {
|
||||||
|
if (key == "borf" && value.is<double>() && value.as<double>() == 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") {
|
TEST_CASE("usertype/runtime-extensibility", "Check if usertypes are runtime extensible") {
|
||||||
struct thing {
|
struct thing {
|
||||||
@ -339,3 +362,44 @@ TEST_CASE("usertype/meta-key-retrievals", "allow for special meta keys (__index,
|
|||||||
REQUIRE(keys[3] == "__call");
|
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>("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);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user