commit
60051a7d41
|
@ -1,3 +1,51 @@
|
|||
[submodule "lib/assimp"]
|
||||
path = lib/assimp
|
||||
url = https://github.com/assimp/assimp/
|
||||
[submodule "glm"]
|
||||
path = lib/glm
|
||||
url = git@github.com:g-truc/glm.git
|
||||
branch = master
|
||||
[submodule "enet"]
|
||||
path = lib/enet
|
||||
url = git@github.com:zpl-c/enet.git
|
||||
branch = master
|
||||
[submodule "sol2"]
|
||||
path = lib/sol2
|
||||
url = git@github.com:ThePhD/sol2.git
|
||||
branch = develop
|
||||
[submodule "lua"]
|
||||
path = lib/lua
|
||||
url = git@github.com:lua/lua.git
|
||||
branch = master
|
||||
[submodule "assimp"]
|
||||
path = lib/assimp
|
||||
url = git@github.com:assimp/assimp.git
|
||||
branch = master
|
||||
[submodule "FastNoiseLite"]
|
||||
path = lib/FastNoiseLite
|
||||
url = git@github.com:Auburn/FastNoiseLite.git
|
||||
branch = master
|
||||
[submodule "glfw"]
|
||||
path = lib/glfw
|
||||
url = git@github.com:glfw/glfw.git
|
||||
branch = master
|
||||
[submodule "nothings-stb"]
|
||||
path = lib/nothings-stb
|
||||
url = git@github.com:nothings/stb.git
|
||||
branch = master
|
||||
[submodule "gzip-hpp"]
|
||||
path = lib/gzip-hpp
|
||||
url = git@github.com:mapbox/gzip-hpp.git
|
||||
branch = master
|
||||
[submodule "cute_headers"]
|
||||
path = lib/cute_headers
|
||||
url = git@github.com:RandyGaul/cute_headers.git
|
||||
branch = master
|
||||
[submodule "FastNoise2"]
|
||||
path = lib/FastNoise2
|
||||
url = git@github.com:Auburn/FastNoise2.git
|
||||
branch = master
|
||||
[submodule "nlohmann_json"]
|
||||
path = lib/nlohmann_json
|
||||
url = git@github.com:nlohmann/json.git
|
||||
branch = master
|
||||
|
|
151
CMakeLists.txt
151
CMakeLists.txt
|
@ -1,15 +1,28 @@
|
|||
cmake_minimum_required (VERSION 3.12 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
cmake_policy(SET CMP0077 NEW) # set() overrides option()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_BUILD_RPATH_USE_ORIGIN ON)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(ZP_BUILD_SHARED_LIBS ON)
|
||||
else()
|
||||
set(ZP_BUILD_SHARED_LIBS OFF)
|
||||
endif()
|
||||
|
||||
if(ZP_BUILD_SHARED_LIBS)
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
set(RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
endif()
|
||||
|
||||
# Set warnings
|
||||
if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
|
||||
add_compile_options(
|
||||
-Werror -Wall -Wextra -pedantic -pedantic-errors
|
||||
-Wnon-virtual-dtor -Wmisleading-indentation -Wlogical-op -Wnull-dereference
|
||||
-Wno-unused-parameter -Wno-reorder -Wno-sign-compare)
|
||||
-Werror -Wall -Wextra -pedantic -pedantic-errors
|
||||
-Wnon-virtual-dtor -Wmisleading-indentation -Wlogical-op -Wnull-dereference
|
||||
-Wno-unused-parameter -Wno-reorder -Wno-sign-compare)
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
add_compile_options(/permissive /W4 /w14640)
|
||||
endif()
|
||||
|
@ -20,123 +33,29 @@ set(MAIN_EXEC_NAME "Zepha")
|
|||
|
||||
project(${PROJECT_NAME})
|
||||
|
||||
find_path(GLEW_HEADERS GL/glew.h)
|
||||
find_path(GLFW_HEADERS GLFW/glfw3.h)
|
||||
find_path(LUA_HEADERS lua.hpp
|
||||
/usr/include/lua5.3
|
||||
/usr/local/include/lua5.3)
|
||||
find_path(ASSIMP_HEADERS assimp/Importer.hpp)
|
||||
find_path(ENET_HEADERS enet/enet.h)
|
||||
find_path(NOISE_HEADERS NAMES libnoise/noise.h libnoise/module/modulebase.h)
|
||||
find_path(GLM_HEADERS glm/glm.hpp)
|
||||
find_path(PTHREAD_HEADERS pthread.h)
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
||||
|
||||
find_library(ENET_LIB enet)
|
||||
find_library(NOISE_LIB NAMES libnoise noise)
|
||||
add_subdirectory(lib)
|
||||
|
||||
if (WIN32)
|
||||
find_library(PTHREAD_LIB pthreadVC3)
|
||||
else()
|
||||
find_library(PTHREAD_LIB pthread)
|
||||
endif()
|
||||
file(GLOB_RECURSE SOURCE_FILES src/*.hpp src/*.cpp)
|
||||
|
||||
include_directories(
|
||||
${GLM_HEADERS}
|
||||
${GLEW_HEADERS}
|
||||
${LUA_HEADERS}
|
||||
${ASSIMP_HEADERS}
|
||||
${ENET_HEADERS}
|
||||
${NOISE_HEADERS}
|
||||
${PTHREAD_HEADERS}
|
||||
lib/fastnoise2/include
|
||||
lib/catch2/include
|
||||
lib/gzip/include
|
||||
lib/cute_files/include
|
||||
lib/stb_image/include
|
||||
lib/json/include
|
||||
lib/sol/include
|
||||
)
|
||||
add_executable(${MAIN_EXEC_NAME} ${SOURCE_FILES})
|
||||
|
||||
add_subdirectory(src)
|
||||
add_executable(${MAIN_EXEC_NAME} src/Main.cpp)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} Zepha_Core)
|
||||
target_include_directories(${MAIN_EXEC_NAME} PUBLIC src)
|
||||
|
||||
target_include_directories(${MAIN_EXEC_NAME} PRIVATE ${GLFW_HEADERS})
|
||||
target_link_libraries(${MAIN_EXEC_NAME} PUBLIC glfw glm enet glad assimp FastNoise nothings-stb gzip cute_headers nlohmann_json)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} PUBLIC lua sol2)
|
||||
|
||||
# Enet
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${ENET_LIB})
|
||||
|
||||
# Find and Link OpenGL
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(GLUT REQUIRED)
|
||||
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${OPENGL_LIBRARIES} ${GLUT_LIBRARY})
|
||||
|
||||
# Build GLFW
|
||||
if (WIN32)
|
||||
find_library(GLFW_LIB glfw3dll)
|
||||
else()
|
||||
find_library(GLFW_LIB NAMES GLFW glfw glfw3)
|
||||
endif()
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${GLFW_LIB})
|
||||
|
||||
# Link GLEW
|
||||
if (WIN32)
|
||||
find_library(GLEW_LIB glew32)
|
||||
else()
|
||||
find_library(GLEW_LIB NAMES GLEW glew3)
|
||||
endif()
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${GLEW_LIB})
|
||||
|
||||
# Build and Link Assimp
|
||||
|
||||
if (WIN32)
|
||||
find_library(ASSIMP_LIB assimp-vc142-mt)
|
||||
else()
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
set(ASSIMP_NO_EXPORT ON)
|
||||
set(ASSIMP_BUILD_TESTS OFF)
|
||||
set(ASSIMP_BUILD_ASSIMP_TOOLS OFF)
|
||||
|
||||
set(ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT OFF)
|
||||
set(ASSIMP_BUILD_B3D_IMPORTER ON)
|
||||
set(ASSIMP_BUILD_X3D_IMPORTER ON) # Doesn't compile if not defined
|
||||
|
||||
add_subdirectory(lib/assimp)
|
||||
target_compile_options(assimp PRIVATE -w)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} assimp)
|
||||
endif()
|
||||
|
||||
# Build and Link FastNoise2
|
||||
|
||||
add_subdirectory(lib/fastnoise2)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} FastNoise)
|
||||
|
||||
# Link Lua 5.3.5
|
||||
find_library(LUA_LIB NAMES lua lua5.3)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${LUA_LIB})
|
||||
|
||||
# Link Noise
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${NOISE_LIB})
|
||||
|
||||
# Link PThread Dynamically
|
||||
target_link_libraries (${MAIN_EXEC_NAME} ${PTHREAD_LIB})
|
||||
|
||||
# Link Z Dynamically
|
||||
target_link_libraries (${MAIN_EXEC_NAME} z)
|
||||
|
||||
# Fix Win32 networking
|
||||
if(WIN32)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} winmm ws2_32)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} PUBLIC opengl32 gdi32)
|
||||
endif()
|
||||
|
||||
# Test Build
|
||||
# add_subdirectory(test)
|
||||
# add_executable(${TEST_EXEC_NAME} test/Main.cpp)
|
||||
# target_link_libraries(${TEST_EXEC_NAME} Zepha_Core)
|
||||
# target_link_libraries(${TEST_EXEC_NAME} Zepha_Test)
|
||||
|
||||
# target_include_directories(${TEST_EXEC_NAME} PRIVATE ${GLFW_HEADERS})
|
||||
# target_link_libraries(${TEST_EXEC_NAME} ${LUA_LIB})
|
||||
# target_link_libraries (${TEST_EXEC_NAME} z)
|
||||
# target_link_libraries(${TEST_EXEC_NAME} ${ENET_LIB})
|
||||
if(WIN32)
|
||||
foreach(DLL ${ZEPHA_DLL_TO_COPY})
|
||||
add_custom_command(TARGET ${MAIN_EXEC_NAME} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy
|
||||
${DLL}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Copying dll ${DLL} to output directory")
|
||||
endforeach(DLL)
|
||||
endif(WIN32)
|
|
@ -0,0 +1,142 @@
|
|||
cmake_minimum_required (VERSION 3.12 FATAL_ERROR)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_BUILD_RPATH_USE_ORIGIN ON)
|
||||
|
||||
# Set warnings
|
||||
if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
|
||||
add_compile_options(
|
||||
-Werror -Wall -Wextra -pedantic -pedantic-errors
|
||||
-Wnon-virtual-dtor -Wmisleading-indentation -Wlogical-op -Wnull-dereference
|
||||
-Wno-unused-parameter -Wno-reorder -Wno-sign-compare)
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
add_compile_options(/permissive /W4 /w14640)
|
||||
endif()
|
||||
|
||||
set(PROJECT_NAME "Zepha")
|
||||
set(MAIN_EXEC_NAME "Zepha")
|
||||
# set(TEST_EXEC_NAME "ZephaTest")
|
||||
|
||||
project(${PROJECT_NAME})
|
||||
|
||||
find_path(GLEW_HEADERS GL/glew.h)
|
||||
find_path(GLFW_HEADERS GLFW/glfw3.h)
|
||||
find_path(LUA_HEADERS lua.hpp
|
||||
/usr/include/lua5.3
|
||||
/usr/local/include/lua5.3)
|
||||
find_path(ASSIMP_HEADERS assimp/Importer.hpp)
|
||||
find_path(ENET_HEADERS enet/enet.h)
|
||||
find_path(NOISE_HEADERS NAMES libnoise/noise.h libnoise/module/modulebase.h)
|
||||
find_path(GLM_HEADERS glm/glm.hpp)
|
||||
find_path(PTHREAD_HEADERS pthread.h)
|
||||
|
||||
find_library(ENET_LIB enet)
|
||||
find_library(NOISE_LIB NAMES libnoise noise)
|
||||
|
||||
if (WIN32)
|
||||
find_library(PTHREAD_LIB pthreadVC3)
|
||||
else()
|
||||
find_library(PTHREAD_LIB pthread)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${GLM_HEADERS}
|
||||
${GLEW_HEADERS}
|
||||
${LUA_HEADERS}
|
||||
${ASSIMP_HEADERS}
|
||||
${ENET_HEADERS}
|
||||
${NOISE_HEADERS}
|
||||
${PTHREAD_HEADERS}
|
||||
lib/fastnoise2/include
|
||||
lib/catch2/include
|
||||
lib/gzip/include
|
||||
lib/cute_files/include
|
||||
lib/stb_image/include
|
||||
lib/json/include
|
||||
lib/sol/include
|
||||
)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_executable(${MAIN_EXEC_NAME} src/Main.cpp)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} Zepha_Core)
|
||||
|
||||
target_include_directories(${MAIN_EXEC_NAME} PRIVATE ${GLFW_HEADERS})
|
||||
|
||||
# Enet
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${ENET_LIB})
|
||||
|
||||
# Find and Link OpenGL
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(GLUT REQUIRED)
|
||||
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${OPENGL_LIBRARIES} ${GLUT_LIBRARY})
|
||||
|
||||
# Build GLFW
|
||||
if (WIN32)
|
||||
find_library(GLFW_LIB glfw3dll)
|
||||
else()
|
||||
find_library(GLFW_LIB NAMES GLFW glfw glfw3)
|
||||
endif()
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${GLFW_LIB})
|
||||
|
||||
# Link GLEW
|
||||
if (WIN32)
|
||||
find_library(GLEW_LIB glew32)
|
||||
else()
|
||||
find_library(GLEW_LIB NAMES GLEW glew3)
|
||||
endif()
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${GLEW_LIB})
|
||||
|
||||
# Build and Link Assimp
|
||||
|
||||
if (WIN32)
|
||||
find_library(ASSIMP_LIB assimp-vc142-mt)
|
||||
else()
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
set(ASSIMP_NO_EXPORT ON)
|
||||
set(ASSIMP_BUILD_TESTS OFF)
|
||||
set(ASSIMP_BUILD_ASSIMP_TOOLS OFF)
|
||||
|
||||
set(ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT OFF)
|
||||
set(ASSIMP_BUILD_B3D_IMPORTER ON)
|
||||
set(ASSIMP_BUILD_X3D_IMPORTER ON) # Doesn't compile if not defined
|
||||
|
||||
add_subdirectory(lib/assimp)
|
||||
target_compile_options(assimp PRIVATE -w)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} assimp)
|
||||
endif()
|
||||
|
||||
# Build and Link FastNoise2
|
||||
|
||||
add_subdirectory(lib/fastnoise2)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} FastNoise)
|
||||
|
||||
# Link Lua 5.3.5
|
||||
find_library(LUA_LIB NAMES lua lua5.3)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${LUA_LIB})
|
||||
|
||||
# Link Noise
|
||||
target_link_libraries(${MAIN_EXEC_NAME} ${NOISE_LIB})
|
||||
|
||||
# Link PThread Dynamically
|
||||
target_link_libraries (${MAIN_EXEC_NAME} ${PTHREAD_LIB})
|
||||
|
||||
# Link Z Dynamically
|
||||
target_link_libraries (${MAIN_EXEC_NAME} z)
|
||||
|
||||
# Fix Win32 networking
|
||||
if(WIN32)
|
||||
target_link_libraries(${MAIN_EXEC_NAME} winmm ws2_32)
|
||||
endif()
|
||||
|
||||
# Test Build
|
||||
# add_subdirectory(test)
|
||||
# add_executable(${TEST_EXEC_NAME} test/Main.cpp)
|
||||
# target_link_libraries(${TEST_EXEC_NAME} Zepha_Core)
|
||||
# target_link_libraries(${TEST_EXEC_NAME} Zepha_Test)
|
||||
|
||||
# target_include_directories(${TEST_EXEC_NAME} PRIVATE ${GLFW_HEADERS})
|
||||
# target_link_libraries(${TEST_EXEC_NAME} ${LUA_LIB})
|
||||
# target_link_libraries (${TEST_EXEC_NAME} z)
|
||||
# target_link_libraries(${TEST_EXEC_NAME} ${ENET_LIB})
|
|
@ -0,0 +1,226 @@
|
|||
#------------------------------
|
||||
# GLFW
|
||||
# Desktop Window Library
|
||||
#------------------------------
|
||||
if(NOT TARGET glfw AND NOT PLATFORM_ANDROID)
|
||||
set(GLFW_INSTALL OFF)
|
||||
set(GLFW_BUILD_EXAMPLES OFF)
|
||||
set(GLFW_BUILD_TESTS OFF)
|
||||
set(GLFW_BUILD_DOCS OFF)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
set(GLFW_USE_HYBRID_HPG ON)
|
||||
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
add_subdirectory(glfw)
|
||||
set_property(TARGET glfw PROPERTY FOLDER "GameLib")
|
||||
endif()
|
||||
|
||||
#------------------------------
|
||||
# GLM
|
||||
# Game mathematics library
|
||||
#------------------------------
|
||||
if(NOT TARGET glm)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
add_subdirectory(glm)
|
||||
set_property(TARGET glm PROPERTY FOLDER "GameLib")
|
||||
endif()
|
||||
|
||||
#------------------------------
|
||||
# zpl-c/enet
|
||||
# ENet reliable UDP networking library
|
||||
#------------------------------
|
||||
if(NOT TARGET enet)
|
||||
if(ZP_BUILD_SHARED_LIBS)
|
||||
set(ENET_STATIC OFF)
|
||||
set(ENET_SHARED ON)
|
||||
else()
|
||||
set(ENET_STATIC ON)
|
||||
set(ENET_SHARED OFF)
|
||||
endif()
|
||||
|
||||
add_subdirectory(enet)
|
||||
set_property(TARGET enet PROPERTY FOLDER "GameLib")
|
||||
endif()
|
||||
|
||||
#------------------------------
|
||||
# GLAD
|
||||
# OpenGL
|
||||
#------------------------------
|
||||
if(NOT TARGET glad AND NOT PLATFORM_ANDROID)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
add_subdirectory(glad)
|
||||
set_property(TARGET glad PROPERTY FOLDER "GameLib")
|
||||
endif()
|
||||
|
||||
#------------------------------
|
||||
# Lua
|
||||
# lua lib
|
||||
#------------------------------
|
||||
if(NOT TARGET lua)
|
||||
project(lua VERSION 4.6 LANGUAGES C)
|
||||
file(GLOB PROJECT_SOURCE lua/*.h lua/*.c)
|
||||
add_library(lua STATIC ${PROJECT_SOURCE})
|
||||
target_include_directories(lua PUBLIC lua/)
|
||||
endif()
|
||||
|
||||
#------------------------------
|
||||
# GLAD
|
||||
# OpenGL
|
||||
#------------------------------
|
||||
if(NOT TARGET sol2)
|
||||
set(SOL2_ENABLE_INSTALL OFF)
|
||||
set(SOL2_TESTS_SINGLE OFF)
|
||||
set(SOL2_TESTS_EXAMPLES OFF)
|
||||
set(SOL2_TESTS_INTEROP_EXAMPLES OFF)
|
||||
set(BUILD_LUA_AS_DLL OFF)
|
||||
set(SOL2_BUILD_LUA OFF)
|
||||
|
||||
if(ZP_BUILD_SHARED_LIBS)
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
else()
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
endif()
|
||||
|
||||
add_subdirectory(sol2)
|
||||
set_property(TARGET sol2 PROPERTY FOLDER "GameLib")
|
||||
endif()
|
||||
|
||||
#------------------------------
|
||||
# ASSIMP
|
||||
# Model loading library
|
||||
#------------------------------
|
||||
if(NOT TARGET assimp)
|
||||
if(ZP_BUILD_SHARED_LIBS)
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
else()
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
endif()
|
||||
|
||||
cmake_policy(SET CMP0077 NEW) # set() overrides option()
|
||||
|
||||
set(ASM686 OFF)
|
||||
set(AMD64 ON)
|
||||
set(ASSIMP_BUILD_ZLIB ON)
|
||||
set(ASSIMP_BUILD_TESTS OFF)
|
||||
set(ZLIB_AMD64 ON)
|
||||
set(ASSIMP_NO_EXPORT ON)
|
||||
set(ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT OFF)
|
||||
#set(ASSIMP_BUILD_FBX_IMPORTER ON)
|
||||
|
||||
set(ASSIMP_BUILD_B3D_IMPORTER ON)
|
||||
set(ASSIMP_BUILD_X3D_IMPORTER ON)
|
||||
|
||||
set(ASSIMP_BUILD_DRACO OFF)
|
||||
add_subdirectory(assimp)
|
||||
|
||||
set_property(TARGET assimp PROPERTY FOLDER "GameLib")
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
if(WIN32)
|
||||
if(MSVC)
|
||||
if(CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
set(ZEPHA_DLL_TO_COPY
|
||||
${ZEPHA_DLL_TO_COPY}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/assimp/bin/Debug/assimp-vc142-mtd.dll
|
||||
CACHE INTERNAL "ZEPHA_DLL_TO_COPY")
|
||||
else()
|
||||
set(ZEPHA_DLL_TO_COPY
|
||||
${ZEPHA_DLL_TO_COPY}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/assimp/bin/assimp-vc142-mtd.dll
|
||||
CACHE INTERNAL "ZEPHA_DLL_TO_COPY")
|
||||
endif()
|
||||
else(MSVC)
|
||||
set(ZEPHA_DLL_TO_COPY
|
||||
${ZEPHA_DLL_TO_COPY}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/assimp/bin/libassimpd.dll
|
||||
CACHE INTERNAL "ZEPHA_DLL_TO_COPY")
|
||||
endif(MSVC)
|
||||
else(WIN32)
|
||||
set(ZEPHA_DLL_TO_COPY
|
||||
${ZEPHA_DLL_TO_COPY}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/assimp/bin/libassimpd.so
|
||||
CACHE INTERNAL "ZEPHA_DLL_TO_COPY")
|
||||
endif(WIN32)
|
||||
else()
|
||||
if(WIN32)
|
||||
if(MSVC)
|
||||
if(CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
set(ZEPHA_DLL_TO_COPY
|
||||
${ZEPHA_DLL_TO_COPY}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/assimp/bin/Release/assimp-vc142-mt.dll
|
||||
CACHE INTERNAL "ZEPHA_DLL_TO_COPY")
|
||||
else()
|
||||
set(ZEPHA_DLL_TO_COPY
|
||||
${ZEPHA_DLL_TO_COPY}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/assimp/bin/assimp-vc142-mt.dll
|
||||
CACHE INTERNAL "ZEPHA_DLL_TO_COPY")
|
||||
endif()
|
||||
else(MSVC)
|
||||
set(ZEPHA_DLL_TO_COPY
|
||||
${ZEPHA_DLL_TO_COPY}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/assimp/bin/libassimp.dll
|
||||
CACHE INTERNAL "ZEPHA_DLL_TO_COPY")
|
||||
endif(MSVC)
|
||||
else(WIN32)
|
||||
set(ZEPHA_DLL_TO_COPY
|
||||
${ZEPHA_DLL_TO_COPY}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/assimp/bin/libassimp.so
|
||||
CACHE INTERNAL "ZEPHA_DLL_TO_COPY")
|
||||
endif(WIN32)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#------------------------------
|
||||
# FastNoise2
|
||||
# Modular node based noise generation library using SIMD, C++17 and templates
|
||||
#------------------------------
|
||||
if(NOT TARGET FastNoise)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
set(FASTNOISE2_NOISETOOL OFF)
|
||||
add_subdirectory(FastNoise2)
|
||||
endif()
|
||||
|
||||
#------------------------------
|
||||
# nothings stb
|
||||
# multi util library
|
||||
#------------------------------
|
||||
if(NOT TARGET nothings-stb)
|
||||
project(nothings-stb VERSION 4.6 LANGUAGES C)
|
||||
file(GLOB PROJECT_SOURCE nothings-stb/*.h nothings-stb/*.c)
|
||||
add_library(nothings-stb STATIC ${PROJECT_SOURCE})
|
||||
target_include_directories(nothings-stb PUBLIC nothings-stb/)
|
||||
endif()
|
||||
|
||||
#------------------------------
|
||||
# GZIP
|
||||
# compress library
|
||||
#------------------------------
|
||||
if(NOT TARGET gzip)
|
||||
project(gzip)
|
||||
add_library(gzip INTERFACE)
|
||||
target_include_directories(gzip INTERFACE gzip-hpp/include)
|
||||
endif()
|
||||
|
||||
#------------------------------
|
||||
# cute_headers
|
||||
# Collection of cross-platform one-file C/C++ libraries with no dependencies, primarily used for games
|
||||
#------------------------------
|
||||
if(NOT TARGET cute_headers)
|
||||
project(cute_headers)
|
||||
add_library(cute_headers INTERFACE)
|
||||
target_include_directories(cute_headers INTERFACE cute_headers)
|
||||
endif()
|
||||
|
||||
#--------------------------------
|
||||
# nlohmann JSON
|
||||
# JSON for Modern C++
|
||||
#--------------------------------
|
||||
if(NOT TARGET nlohmann_json)
|
||||
set(JSON_BuildTests OFF)
|
||||
set(JSON_Install OFF)
|
||||
add_subdirectory(nlohmann_json)
|
||||
set_property(TARGET nlohmann_json PROPERTY FOLDER "GameLib")
|
||||
endif()
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 27c556b3ff15efca133cf3e888f31b1c0f3d144b
|
|
@ -1 +1 @@
|
|||
Subproject commit 2d2889f73fa1b2ca09ba9f43c9785402d3a7fdd0
|
||||
Subproject commit 6841397798051919a23a3fbe1405fd934fb5f39c
|
|
@ -1,2 +0,0 @@
|
|||
This is a single header file which is a part of RandyGaul's cute_headers Library. The Library Repository is:
|
||||
https://github.com/RandyGaul/cute_headers
|
|
@ -1,520 +0,0 @@
|
|||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Licensing information can be found at the end of the file.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
tinyfiles.h - v1.0
|
||||
|
||||
To create implementation (the function definitions)
|
||||
#define CUTE_FILES_IMPLEMENTATION
|
||||
in *one* C/CPP file (translation unit) that includes this file
|
||||
|
||||
Summary:
|
||||
Utility header for traversing directories to apply a function on each found file.
|
||||
Recursively finds sub-directories. Can also be used to iterate over files in a
|
||||
folder manually. All operations done in a cross-platform manner (thx posix!).
|
||||
|
||||
This header does no dynamic memory allocation, and performs internally safe string
|
||||
copies as necessary. Strings for paths, file names and file extensions are all
|
||||
capped, and intended to use primarily the C run-time stack memory. Feel free to
|
||||
modify the defines in this file to adjust string size limitations.
|
||||
|
||||
Read the header for specifics on each function.
|
||||
|
||||
Here's an example to print all files in a folder:
|
||||
cf_dir_t dir;
|
||||
cf_dir_open(&dir, "a");
|
||||
|
||||
while (dir.has_next)
|
||||
{
|
||||
cf_file_t file;
|
||||
cf_read_file(&dir, &file);
|
||||
printf("%s\n", file.name);
|
||||
cf_dir_next(&dir);
|
||||
}
|
||||
|
||||
cf_dir_close(&dir);
|
||||
*/
|
||||
|
||||
#if !defined(CUTE_FILES_H)
|
||||
|
||||
#define CUTE_FILES_WINDOWS 1
|
||||
#define CUTE_FILES_MAC 2
|
||||
#define CUTE_FILES_UNIX 3
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define CUTE_FILES_PLATFORM CUTE_FILES_WINDOWS
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
#define CUTE_FILES_PLATFORM CUTE_FILES_MAC
|
||||
#else
|
||||
#define CUTE_FILES_PLATFORM CUTE_FILES_UNIX
|
||||
#endif
|
||||
|
||||
#include <string.h> // strerror, strncpy
|
||||
|
||||
// change to 0 to compile out any debug checks
|
||||
#define CUTE_FILES_DEBUG_CHECKS 1
|
||||
|
||||
#if CUTE_FILES_DEBUG_CHECKS
|
||||
|
||||
#include <stdio.h> // printf
|
||||
#include <assert.h> // assert
|
||||
#include <errno.h>
|
||||
#define CUTE_FILES_ASSERT assert
|
||||
|
||||
#else
|
||||
|
||||
#define CUTE_FILES_ASSERT(...)
|
||||
|
||||
#endif // CUTE_FILES_DEBUG_CHECKS
|
||||
|
||||
#define CUTE_FILES_MAX_PATH 1024
|
||||
#define CUTE_FILES_MAX_FILENAME 256
|
||||
#define CUTE_FILES_MAX_EXT 32
|
||||
|
||||
struct cf_file_t;
|
||||
struct cf_dir_t;
|
||||
struct cf_time_t;
|
||||
typedef struct cf_file_t cf_file_t;
|
||||
typedef struct cf_dir_t cf_dir_t;
|
||||
typedef struct cf_time_t cf_time_t;
|
||||
typedef void (cf_callback_t)(cf_file_t* file, void* udata);
|
||||
|
||||
// Stores the file extension in cf_file_t::ext, and returns a pointer to
|
||||
// cf_file_t::ext
|
||||
const char* cf_get_ext(cf_file_t* file);
|
||||
|
||||
// Applies a function (cb) to all files in a directory. Will recursively visit
|
||||
// all subdirectories. Useful for asset management, file searching, indexing, etc.
|
||||
void cf_traverse(const char* path, cf_callback_t* cb, void* udata);
|
||||
|
||||
// Fills out a cf_file_t struct with file information. Does not actually open the
|
||||
// file contents, and instead performs more lightweight OS-specific calls.
|
||||
int cf_read_file(cf_dir_t* dir, cf_file_t* file);
|
||||
|
||||
// Once a cf_dir_t is opened, this function can be used to grab another file
|
||||
// from the operating system.
|
||||
void cf_dir_next(cf_dir_t* dir);
|
||||
|
||||
// Performs lightweight OS-specific call to close internal handle.
|
||||
void cf_dir_close(cf_dir_t* dir);
|
||||
|
||||
// Performs lightweight OS-specific call to open a file handle on a directory.
|
||||
int cf_dir_open(cf_dir_t* dir, const char* path);
|
||||
|
||||
// Compares file last write times. -1 if file at path_a was modified earlier than path_b.
|
||||
// 0 if they are equal. 1 if file at path_b was modified earlier than path_a.
|
||||
int cf_compare_file_times_by_path(const char* path_a, const char* path_b);
|
||||
|
||||
// Retrieves time file was last modified, returns 0 upon failure
|
||||
int cf_get_file_time(const char* path, cf_time_t* time);
|
||||
|
||||
// Compares file last write times. -1 if time_a was modified earlier than path_b.
|
||||
// 0 if they are equal. 1 if time_b was modified earlier than path_a.
|
||||
int cf_compare_file_times(cf_time_t* time_a, cf_time_t* time_b);
|
||||
|
||||
// Returns 1 of file exists, otherwise returns 0.
|
||||
int cf_file_exists(const char* path);
|
||||
|
||||
// Returns 1 if the file's extension matches the string in ext
|
||||
// Returns 0 otherwise
|
||||
int cf_match_ext(cf_file_t* file, const char* ext);
|
||||
|
||||
// Prints detected errors to stdout
|
||||
void cf_do_unit_tests();
|
||||
|
||||
#if CUTE_FILES_PLATFORM == CUTE_FILES_WINDOWS
|
||||
|
||||
#if !defined _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
struct cf_file_t
|
||||
{
|
||||
char path[CUTE_FILES_MAX_PATH];
|
||||
char name[CUTE_FILES_MAX_FILENAME];
|
||||
char ext[CUTE_FILES_MAX_EXT];
|
||||
int is_dir;
|
||||
int is_reg;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
struct cf_dir_t
|
||||
{
|
||||
char path[CUTE_FILES_MAX_PATH];
|
||||
int has_next;
|
||||
HANDLE handle;
|
||||
WIN32_FIND_DATAA fdata;
|
||||
};
|
||||
|
||||
struct cf_time_t
|
||||
{
|
||||
FILETIME time;
|
||||
};
|
||||
|
||||
#elif CUTE_FILES_PLATFORM == CUTE_FILES_MAC || CUTE_FILES_PLATFORM == CUTE_FILES_UNIX
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
struct cf_file_t
|
||||
{
|
||||
char path[CUTE_FILES_MAX_PATH];
|
||||
char name[CUTE_FILES_MAX_FILENAME];
|
||||
char ext[CUTE_FILES_MAX_EXT];
|
||||
int is_dir;
|
||||
int is_reg;
|
||||
int size;
|
||||
struct stat info;
|
||||
};
|
||||
|
||||
struct cf_dir_t
|
||||
{
|
||||
char path[CUTE_FILES_MAX_PATH];
|
||||
int has_next;
|
||||
DIR* dir;
|
||||
struct dirent* entry;
|
||||
};
|
||||
|
||||
struct cf_time_t
|
||||
{
|
||||
time_t time;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#define CUTE_FILES_H
|
||||
#endif
|
||||
|
||||
#ifdef CUTE_FILES_IMPLEMENTATION
|
||||
#ifndef CUTE_FILES_IMPLEMENTATION_ONCE
|
||||
#define CUTE_FILES_IMPLEMENTATION_ONCE
|
||||
|
||||
#define cf_safe_strcpy(dst, src, n, max) cf_safe_strcpy_internal(dst, src, n, max, __FILE__, __LINE__)
|
||||
static int cf_safe_strcpy_internal(char* dst, const char* src, int n, int max, const char* file, int line)
|
||||
{
|
||||
int c;
|
||||
const char* original = src;
|
||||
|
||||
do
|
||||
{
|
||||
if (n >= max)
|
||||
{
|
||||
if (!CUTE_FILES_DEBUG_CHECKS) break;
|
||||
printf("ERROR: String \"%s\" too long to copy on line %d in file %s (max length of %d).\n"
|
||||
, original
|
||||
, line
|
||||
, file
|
||||
, max);
|
||||
CUTE_FILES_ASSERT(0);
|
||||
}
|
||||
|
||||
c = *src++;
|
||||
dst[n] = c;
|
||||
++n;
|
||||
} while (c);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
const char* cf_get_ext(cf_file_t* file)
|
||||
{
|
||||
char* name = file->name;
|
||||
char* period = NULL;
|
||||
while (*name++) if (*name == '.') period = name;
|
||||
if (period) cf_safe_strcpy(file->ext, period, 0, CUTE_FILES_MAX_EXT);
|
||||
else file->ext[0] = 0;
|
||||
return file->ext;
|
||||
}
|
||||
|
||||
void cf_traverse(const char* path, cf_callback_t* cb, void* udata)
|
||||
{
|
||||
cf_dir_t dir;
|
||||
cf_dir_open(&dir, path);
|
||||
|
||||
while (dir.has_next)
|
||||
{
|
||||
cf_file_t file;
|
||||
cf_read_file(&dir, &file);
|
||||
|
||||
if (file.is_dir && file.name[0] != '.')
|
||||
{
|
||||
char path2[CUTE_FILES_MAX_PATH];
|
||||
int n = cf_safe_strcpy(path2, path, 0, CUTE_FILES_MAX_PATH);
|
||||
n = cf_safe_strcpy(path2, "/", n - 1, CUTE_FILES_MAX_PATH);
|
||||
cf_safe_strcpy(path2, file.name, n -1, CUTE_FILES_MAX_PATH);
|
||||
cf_traverse(path2, cb, udata);
|
||||
}
|
||||
|
||||
if (file.is_reg) cb(&file, udata);
|
||||
cf_dir_next(&dir);
|
||||
}
|
||||
|
||||
cf_dir_close(&dir);
|
||||
}
|
||||
|
||||
int cf_match_ext(cf_file_t* file, const char* ext)
|
||||
{
|
||||
return !strcmp(file->ext, ext);
|
||||
}
|
||||
|
||||
#if CUTE_FILES_PLATFORM == CUTE_FILES_WINDOWS
|
||||
|
||||
int cf_read_file(cf_dir_t* dir, cf_file_t* file)
|
||||
{
|
||||
CUTE_FILES_ASSERT(dir->handle != INVALID_HANDLE_VALUE);
|
||||
|
||||
int n = 0;
|
||||
char* fpath = file->path;
|
||||
char* dpath = dir->path;
|
||||
|
||||
n = cf_safe_strcpy(fpath, dpath, 0, CUTE_FILES_MAX_PATH);
|
||||
n = cf_safe_strcpy(fpath, "/", n - 1, CUTE_FILES_MAX_PATH);
|
||||
|
||||
char* dname = dir->fdata.cFileName;
|
||||
char* fname = file->name;
|
||||
|
||||
cf_safe_strcpy(fname, dname, 0, CUTE_FILES_MAX_FILENAME);
|
||||
cf_safe_strcpy(fpath, fname, n - 1, CUTE_FILES_MAX_PATH);
|
||||
|
||||
size_t max_dword = MAXDWORD;
|
||||
file->size = ((size_t)dir->fdata.nFileSizeHigh * (max_dword + 1)) + (size_t)dir->fdata.nFileSizeLow;
|
||||
cf_get_ext(file);
|
||||
|
||||
file->is_dir = !!(dir->fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||
file->is_reg = !!(dir->fdata.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) ||
|
||||
!(dir->fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cf_dir_next(cf_dir_t* dir)
|
||||
{
|
||||
CUTE_FILES_ASSERT(dir->has_next);
|
||||
|
||||
if (!FindNextFileA(dir->handle, &dir->fdata))
|
||||
{
|
||||
dir->has_next = 0;
|
||||
DWORD err = GetLastError();
|
||||
CUTE_FILES_ASSERT(err == ERROR_SUCCESS || err == ERROR_NO_MORE_FILES);
|
||||
}
|
||||
}
|
||||
|
||||
void cf_dir_close(cf_dir_t* dir)
|
||||
{
|
||||
dir->path[0] = 0;
|
||||
dir->has_next = 0;
|
||||
if (dir->handle != INVALID_HANDLE_VALUE) FindClose(dir->handle);
|
||||
}
|
||||
|
||||
int cf_dir_open(cf_dir_t* dir, const char* path)
|
||||
{
|
||||
int n = cf_safe_strcpy(dir->path, path, 0, CUTE_FILES_MAX_PATH);
|
||||
n = cf_safe_strcpy(dir->path, "\\*", n - 1, CUTE_FILES_MAX_PATH);
|
||||
dir->handle = FindFirstFileA(dir->path, &dir->fdata);
|
||||
dir->path[n - 3] = 0;
|
||||
|
||||
if (dir->handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
printf("ERROR: Failed to open directory (%s): %s.\n", path, strerror(errno));
|
||||
cf_dir_close(dir);
|
||||
CUTE_FILES_ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dir->has_next = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cf_compare_file_times_by_path(const char* path_a, const char* path_b)
|
||||
{
|
||||
FILETIME time_a = { 0 };
|
||||
FILETIME time_b = { 0 };
|
||||
WIN32_FILE_ATTRIBUTE_DATA data;
|
||||
|
||||
if (GetFileAttributesExA(path_a, GetFileExInfoStandard, &data)) time_a = data.ftLastWriteTime;
|
||||
if (GetFileAttributesExA(path_b, GetFileExInfoStandard, &data)) time_b = data.ftLastWriteTime;
|
||||
return CompareFileTime(&time_a, &time_b);
|
||||
}
|
||||
|
||||
int cf_get_file_time(const char* path, cf_time_t* time)
|
||||
{
|
||||
FILETIME initialized_to_zero = { 0 };
|
||||
time->time = initialized_to_zero;
|
||||
WIN32_FILE_ATTRIBUTE_DATA data;
|
||||
if (GetFileAttributesExA(path, GetFileExInfoStandard, &data))
|
||||
{
|
||||
time->time = data.ftLastWriteTime;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cf_compare_file_times(cf_time_t* time_a, cf_time_t* time_b)
|
||||
{
|
||||
return CompareFileTime(&time_a->time, &time_b->time);
|
||||
}
|
||||
|
||||
int cf_file_exists(const char* path)
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA unused;
|
||||
return GetFileAttributesExA(path, GetFileExInfoStandard, &unused);
|
||||
}
|
||||
|
||||
#elif CUTE_FILES_PLATFORM == CUTE_FILES_MAC || CUTE_FILES_PLATFORM == CUTE_FILES_UNIX
|
||||
|
||||
int cf_read_file(cf_dir_t* dir, cf_file_t* file)
|
||||
{
|
||||
CUTE_FILES_ASSERT(dir->entry);
|
||||
|
||||
int n = 0;
|
||||
char* fpath = file->path;
|
||||
char* dpath = dir->path;
|
||||
|
||||
n = cf_safe_strcpy(fpath, dpath, 0, CUTE_FILES_MAX_PATH);
|
||||
n = cf_safe_strcpy(fpath, "/", n - 1, CUTE_FILES_MAX_PATH);
|
||||
|
||||
char* dname = dir->entry->d_name;
|
||||
char* fname = file->name;
|
||||
|
||||
cf_safe_strcpy(fname, dname, 0, CUTE_FILES_MAX_FILENAME);
|
||||
cf_safe_strcpy(fpath, fname, n - 1, CUTE_FILES_MAX_PATH);
|
||||
|
||||
if (stat(file->path, &file->info))
|
||||
return 0;
|
||||
|
||||
file->size = file->info.st_size;
|
||||
cf_get_ext(file);
|
||||
|
||||
file->is_dir = S_ISDIR(file->info.st_mode);
|
||||
file->is_reg = S_ISREG(file->info.st_mode);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cf_dir_next(cf_dir_t* dir)
|
||||
{
|
||||
CUTE_FILES_ASSERT(dir->has_next);
|
||||
dir->entry = readdir(dir->dir);
|
||||
dir->has_next = dir->entry ? 1 : 0;
|
||||
}
|
||||
|
||||
void cf_dir_close(cf_dir_t* dir)
|
||||
{
|
||||
dir->path[0] = 0;
|
||||
if (dir->dir) closedir(dir->dir);
|
||||
dir->dir = 0;
|
||||
dir->has_next = 0;
|
||||
dir->entry = 0;
|
||||
}
|
||||
|
||||
int cf_dir_open(cf_dir_t* dir, const char* path)
|
||||
{
|
||||
cf_safe_strcpy(dir->path, path, 0, CUTE_FILES_MAX_PATH);
|
||||
dir->dir = opendir(path);
|
||||
|
||||
if (!dir->dir)
|
||||
{
|
||||
printf("ERROR: Failed to open directory (%s): %s.\n", path, strerror(errno));
|
||||
cf_dir_close(dir);
|
||||
CUTE_FILES_ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dir->has_next = 1;
|
||||
dir->entry = readdir(dir->dir);
|
||||
if (!dir->dir) dir->has_next = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Warning : untested code! (let me know if it breaks)
|
||||
int cf_compare_file_times_by_path(const char* path_a, const char* path_b)
|
||||
{
|
||||
time_t time_a;
|
||||
time_t time_b;
|
||||
struct stat info;
|
||||
if (stat(path_a, &info)) return 0;
|
||||
time_a = info.st_mtime;
|
||||
if (stat(path_b, &info)) return 0;
|
||||
time_b = info.st_mtime;
|
||||
return (int)difftime(time_a, time_b);
|
||||
}
|
||||
|
||||
// Warning : untested code! (let me know if it breaks)
|
||||
int cf_get_file_time(const char* path, cf_time_t* time)
|
||||
{
|
||||
struct stat info;
|
||||
if (stat(path, &info)) return 0;
|
||||
time->time = info.st_mtime;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Warning : untested code! (let me know if it breaks)
|
||||
int cf_compare_file_times(cf_time_t* time_a, cf_time_t* time_b)
|
||||
{
|
||||
return (int)difftime(time_a->time, time_b->time);
|
||||
}
|
||||
|
||||
// Warning : untested code! (let me know if it breaks)
|
||||
int cf_file_exists(const char* path)
|
||||
{
|
||||
return access(path, F_OK) != -1;
|
||||
}
|
||||
|
||||
#endif // CUTE_FILES_PLATFORM
|
||||
|
||||
#endif // CUTE_FILES_IMPLEMENTATION_ONCE
|
||||
#endif // CUTE_FILES_IMPLEMENTATION
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
This software is available under 2 licenses - you may choose the one you like.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - zlib license
|
||||
Copyright (c) 2017 Randy Gaul http://www.randygaul.net
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from
|
||||
the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 2daadfc0b64491c040d5b9cb011b38dd8d768b6d
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 0bbff4db335ebffd6ce85e3489f356ca0266d16c
|
|
@ -0,0 +1,14 @@
|
|||
cmake_minimum_required(VERSION 3.15)
|
||||
project(glad VERSION 4.6 LANGUAGES C)
|
||||
|
||||
# https://glad.dav1d.de/
|
||||
# Language: C/C++
|
||||
# Specification: OpenGL
|
||||
# Api:
|
||||
# - gl: 4.5
|
||||
# Profile: Core
|
||||
# Extensions: <all>
|
||||
|
||||
add_library(glad STATIC ${PROJECT_SOURCE_DIR}/src/glad.c)
|
||||
|
||||
target_include_directories(glad PUBLIC ${PROJECT_SOURCE_DIR}/include/)
|
|
@ -0,0 +1,290 @@
|
|||
#ifndef __khrplatform_h_
|
||||
#define __khrplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Khronos platform-specific types and definitions.
|
||||
*
|
||||
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||
* The last semantic modification to khrplatform.h was at commit ID:
|
||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||
*
|
||||
* Adopters may modify this file to suit their platform. Adopters are
|
||||
* encouraged to submit platform specific modifications to the Khronos
|
||||
* group so that they can be included in future versions of this file.
|
||||
* Please submit changes by filing pull requests or issues on
|
||||
* the EGL Registry repository linked above.
|
||||
*
|
||||
*
|
||||
* See the Implementer's Guidelines for information about where this file
|
||||
* should be located on your system and for more details of its use:
|
||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||
*
|
||||
* This file should be included as
|
||||
* #include <KHR/khrplatform.h>
|
||||
* by Khronos client API header files that use its types and defines.
|
||||
*
|
||||
* The types in khrplatform.h should only be used to define API-specific types.
|
||||
*
|
||||
* Types defined in khrplatform.h:
|
||||
* khronos_int8_t signed 8 bit
|
||||
* khronos_uint8_t unsigned 8 bit
|
||||
* khronos_int16_t signed 16 bit
|
||||
* khronos_uint16_t unsigned 16 bit
|
||||
* khronos_int32_t signed 32 bit
|
||||
* khronos_uint32_t unsigned 32 bit
|
||||
* khronos_int64_t signed 64 bit
|
||||
* khronos_uint64_t unsigned 64 bit
|
||||
* khronos_intptr_t signed same number of bits as a pointer
|
||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||
* khronos_ssize_t signed size
|
||||
* khronos_usize_t unsigned size
|
||||
* khronos_float_t signed 32 bit floating point
|
||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||
* nanoseconds
|
||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||
* only be used as a base type when a client API's boolean type is
|
||||
* an enum. Client APIs which use an integer or other type for
|
||||
* booleans cannot use this as the base type for their boolean.
|
||||
*
|
||||
* Tokens defined in khrplatform.h:
|
||||
*
|
||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||
*
|
||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||
*
|
||||
* Calling convention macros defined in this file:
|
||||
* KHRONOS_APICALL
|
||||
* KHRONOS_APIENTRY
|
||||
* KHRONOS_APIATTRIBUTES
|
||||
*
|
||||
* These may be used in function prototypes as:
|
||||
*
|
||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||
* int arg1,
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||
# define KHRONOS_STATIC 1
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(KHRONOS_STATIC)
|
||||
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||
* header compatible with static linking. */
|
||||
# define KHRONOS_APICALL
|
||||
#elif defined(_WIN32)
|
||||
# define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined (__SYMBIAN32__)
|
||||
# define KHRONOS_APICALL IMPORT_C
|
||||
#elif defined(__ANDROID__)
|
||||
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||
#else
|
||||
# define KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIENTRY
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the return type of the function and precedes the function
|
||||
* name in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||
/* Win32 but not WinCE */
|
||||
# define KHRONOS_APIENTRY __stdcall
|
||||
#else
|
||||
# define KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIATTRIBUTES
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the closing parenthesis of the function prototype arguments.
|
||||
*/
|
||||
#if defined (__ARMCC_2__)
|
||||
#define KHRONOS_APIATTRIBUTES __softfp
|
||||
#else
|
||||
#define KHRONOS_APIATTRIBUTES
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* basic type definitions
|
||||
*-----------------------------------------------------------------------*/
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||
|
||||
|
||||
/*
|
||||
* Using <stdint.h>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__VMS ) || defined(__sgi)
|
||||
|
||||
/*
|
||||
* Using <inttypes.h>
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
|
||||
/*
|
||||
* Win32
|
||||
*/
|
||||
typedef __int32 khronos_int32_t;
|
||||
typedef unsigned __int32 khronos_uint32_t;
|
||||
typedef __int64 khronos_int64_t;
|
||||
typedef unsigned __int64 khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__sun__) || defined(__digital__)
|
||||
|
||||
/*
|
||||
* Sun or Digital
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#if defined(__arch64__) || defined(_LP64)
|
||||
typedef long int khronos_int64_t;
|
||||
typedef unsigned long int khronos_uint64_t;
|
||||
#else
|
||||
typedef long long int khronos_int64_t;
|
||||
typedef unsigned long long int khronos_uint64_t;
|
||||
#endif /* __arch64__ */
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif 0
|
||||
|
||||
/*
|
||||
* Hypothetical platform with no float or int64 support
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#define KHRONOS_SUPPORT_INT64 0
|
||||
#define KHRONOS_SUPPORT_FLOAT 0
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Generic fallback
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Types that are (so far) the same on all platforms
|
||||
*/
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
typedef signed short int khronos_int16_t;
|
||||
typedef unsigned short int khronos_uint16_t;
|
||||
|
||||
/*
|
||||
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||
* to be the only LLP64 architecture in current use.
|
||||
*/
|
||||
#ifdef _WIN64
|
||||
typedef signed long long int khronos_intptr_t;
|
||||
typedef unsigned long long int khronos_uintptr_t;
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_FLOAT
|
||||
/*
|
||||
* Float type
|
||||
*/
|
||||
typedef float khronos_float_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64
|
||||
/* Time types
|
||||
*
|
||||
* These types can be used to represent a time interval in nanoseconds or
|
||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||
* time the system booted). The Unadjusted System Time is an unsigned
|
||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||
* may be either signed or unsigned.
|
||||
*/
|
||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dummy value used to pad enum types to 32 bits.
|
||||
*/
|
||||
#ifndef KHRONOS_MAX_ENUM
|
||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerated boolean type
|
||||
*
|
||||
* Values other than zero should be considered to be true. Therefore
|
||||
* comparisons should not be made against KHRONOS_TRUE.
|
||||
*/
|
||||
typedef enum {
|
||||
KHRONOS_FALSE = 0,
|
||||
KHRONOS_TRUE = 1,
|
||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||
} khronos_boolean_enum_t;
|
||||
|
||||
#endif /* __khrplatform_h_ */
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
Subproject commit 63da04e5ced93fcb87a20513acdff5d78b1166ff
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 06ed280db4e274fa5e1f36d5ea4f7dfd654ff9b0
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 7546b35aba5917154a0e9ae43f804b57d22bb966
|
|
@ -1,24 +0,0 @@
|
|||
Copyright (c) 2017, Mapbox Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,98 +0,0 @@
|
|||
Gzip C++ lib for gzip compression and decompression. Extracted from [mapnik-vector-tile](https://github.com/mapbox/mapnik-vector-tile) for light-weight modularity.
|
||||
|
||||
[![Build Status](https://travis-ci.org/mapbox/gzip-hpp.svg?branch=master)](https://travis-ci.com/mapbox/gzip-hpp) [![hpp-skel badge](https://mapbox.s3.amazonaws.com/cpp-assets/hpp-skel-badge_blue.svg)](https://github.com/mapbox/hpp-skel)
|
||||
|
||||
## Usage
|
||||
```c++
|
||||
// Include the specific gzip headers your code needs, for example...
|
||||
#include <gzip/compress.hpp>
|
||||
#include <gzip/config.hpp>
|
||||
#include <gzip/decompress.hpp>
|
||||
#include <gzip/utils.hpp>
|
||||
#include <gzip/version.hpp>
|
||||
|
||||
// All function calls must pass in a pointer of an
|
||||
// immutable character sequence (aka a string in C) and its size
|
||||
std::string data = "hello";
|
||||
const char * pointer = data.data();
|
||||
std::size_t size = data.size();
|
||||
|
||||
// Check if compressed. Can check both gzip and zlib.
|
||||
bool c = gzip::is_compressed(pointer, size); // false
|
||||
|
||||
// Compress returns a std::string
|
||||
std::string compressed_data = gzip::compress(pointer, size);
|
||||
|
||||
// Decompress returns a std::string and decodes both zlib and gzip
|
||||
const char * compressed_pointer = compressed_data.data();
|
||||
std::string decompressed_data = gzip::decompress(compressed_pointer, compressed_data.size());
|
||||
|
||||
// Or like so
|
||||
std::string compressed_data = gzip::compress(tile->data(), tile->data.size());
|
||||
|
||||
// Or like so
|
||||
std::string value = gzip::compress(node::Buffer::Data(obj), node::Buffer::Length(obj));
|
||||
|
||||
// Or...etc
|
||||
|
||||
```
|
||||
#### Compress
|
||||
```c++
|
||||
// Optionally include compression level
|
||||
std::size_t size; // No default value, but what happens when not passed??
|
||||
int level = Z_DEFAULT_COMPRESSION; // Z_DEFAULT_COMPRESSION is the default if no arg is passed
|
||||
|
||||
std::string compressed_data = gzip::compress(tile->data(), size, level);
|
||||
```
|
||||
#### Decompress
|
||||
```c++
|
||||
// No args other than the std:string
|
||||
std::string data = "hello";
|
||||
std::string compressed_data = gzip::compress(data);
|
||||
const char * compressed_pointer = compressed_data.data();
|
||||
|
||||
std::string decompressed_data = gzip::decompress(compressed_pointer, compressed_data.size());
|
||||
|
||||
```
|
||||
|
||||
## Test
|
||||
|
||||
```shell
|
||||
# build test binaries
|
||||
make
|
||||
|
||||
# run tests
|
||||
make test
|
||||
```
|
||||
|
||||
You can make Release test binaries as well
|
||||
```shell
|
||||
BUILDTYPE=Release make
|
||||
BUILDTYPE=Release make test
|
||||
```
|
||||
|
||||
## Versioning
|
||||
|
||||
This library is semantically versioned using the /include/gzip/version.cpp file. This defines a number of macros that can be used to check the current major, minor, or patch versions, as well as the full version string.
|
||||
|
||||
Here's how you can check for a particular version to use specific API methods
|
||||
```c++
|
||||
#if GZIP_VERSION_MAJOR > 2
|
||||
// use version 2 api
|
||||
#else
|
||||
// use older verion apis
|
||||
#endif
|
||||
```
|
||||
|
||||
Here's how to check the version string
|
||||
```c++
|
||||
std::cout << "version: " << GZIP_VERSION_STRING << "/n";
|
||||
// => version: 0.2.0
|
||||
```
|
||||
|
||||
And lastly, mathematically checking for a specific version:
|
||||
```c++
|
||||
#if GZIP_VERSION_CODE > 20001
|
||||
// use feature provided in v2.0.1
|
||||
#endif
|
||||
```
|
|
@ -1 +0,0 @@
|
|||
https://github.com/mapbox/gzip-hpp
|
|
@ -1,113 +0,0 @@
|
|||
#include <gzip/config.hpp>
|
||||
|
||||
// zlib
|
||||
#include <zlib.h>
|
||||
|
||||
// std
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace gzip {
|
||||
|
||||
class Compressor
|
||||
{
|
||||
std::size_t max_;
|
||||
int level_;
|
||||
|
||||
public:
|
||||
Compressor(int level = Z_DEFAULT_COMPRESSION,
|
||||
std::size_t max_bytes = 2000000000) // by default refuse operation if uncompressed data is > 2GB
|
||||
: max_(max_bytes),
|
||||
level_(level)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename InputType>
|
||||
void compress(InputType& output,
|
||||
const char* data,
|
||||
std::size_t size) const
|
||||
{
|
||||
|
||||
#ifdef DEBUG
|
||||
// Verify if size input will fit into unsigned int, type used for zlib's avail_in
|
||||
if (size > std::numeric_limits<unsigned int>::max())
|
||||
{
|
||||
throw std::runtime_error("size arg is too large to fit into unsigned int type");
|
||||
}
|
||||
#endif
|
||||
if (size > max_)
|
||||
{
|
||||
throw std::runtime_error("size may use more memory than intended when decompressing");
|
||||
}
|
||||
|
||||
z_stream deflate_s;
|
||||
deflate_s.zalloc = Z_NULL;
|
||||
deflate_s.zfree = Z_NULL;
|
||||
deflate_s.opaque = Z_NULL;
|
||||
deflate_s.avail_in = 0;
|
||||
deflate_s.next_in = Z_NULL;
|
||||
|
||||
// The windowBits parameter is the base two logarithm of the window size (the size of the history buffer).
|
||||
// It should be in the range 8..15 for this version of the library.
|
||||
// Larger values of this parameter result in better compression at the expense of memory usage.
|
||||
// This range of values also changes the decoding type:
|
||||
// -8 to -15 for raw deflate
|
||||
// 8 to 15 for zlib
|
||||
// (8 to 15) + 16 for gzip
|
||||
// (8 to 15) + 32 to automatically detect gzip/zlib header (decompression/inflate only)
|
||||
constexpr int window_bits = 15 + 16; // gzip with windowbits of 15
|
||||
|
||||
constexpr int mem_level = 8;
|
||||
// The memory requirements for deflate are (in bytes):
|
||||
// (1 << (window_bits+2)) + (1 << (mem_level+9))
|
||||
// with a default value of 8 for mem_level and our window_bits of 15
|
||||
// this is 128Kb
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
if (deflateInit2(&deflate_s, level_, Z_DEFLATED, window_bits, mem_level, Z_DEFAULT_STRATEGY) != Z_OK)
|
||||
{
|
||||
throw std::runtime_error("deflate init failed");
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
deflate_s.next_in = reinterpret_cast<z_const Bytef*>(data);
|
||||
deflate_s.avail_in = static_cast<unsigned int>(size);
|
||||
|
||||
std::size_t size_compressed = 0;
|
||||
do
|
||||
{
|
||||
size_t increase = size / 2 + 1024;
|
||||
if (output.size() < (size_compressed + increase))
|
||||
{
|
||||
output.resize(size_compressed + increase);
|
||||
}
|
||||
// There is no way we see that "increase" would not fit in an unsigned int,
|
||||
// hence we use static cast here to avoid -Wshorten-64-to-32 error
|
||||
deflate_s.avail_out = static_cast<unsigned int>(increase);
|
||||
deflate_s.next_out = reinterpret_cast<Bytef*>((&output[0] + size_compressed));
|
||||
// From http://www.zlib.net/zlib_how.html
|
||||
// "deflate() has a return value that can indicate errors, yet we do not check it here.
|
||||
// Why not? Well, it turns out that deflate() can do no wrong here."
|
||||
// Basically only possible error is from deflateInit not working properly
|
||||
deflate(&deflate_s, Z_FINISH);
|
||||
size_compressed += (increase - deflate_s.avail_out);
|
||||
} while (deflate_s.avail_out == 0);
|
||||
|
||||
deflateEnd(&deflate_s);
|
||||
output.resize(size_compressed);
|
||||
}
|
||||
};
|
||||
|
||||
inline std::string compress(const char* data,
|
||||
std::size_t size,
|
||||
int level = Z_DEFAULT_COMPRESSION)
|
||||
{
|
||||
Compressor comp(level);
|
||||
std::string output;
|
||||
comp.compress(output, data, size);
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace gzip
|
|
@ -1,5 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef ZLIB_CONST
|
||||
#define ZLIB_CONST
|
||||
#endif
|
|
@ -1,105 +0,0 @@
|
|||
#include <gzip/config.hpp>
|
||||
|
||||
// zlib
|
||||
#include <zlib.h>
|
||||
|
||||
// std
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace gzip {
|
||||
|
||||
class Decompressor
|
||||
{
|
||||
std::size_t max_;
|
||||
|
||||
public:
|
||||
Decompressor(std::size_t max_bytes = 1000000000) // by default refuse operation if compressed data is > 1GB
|
||||
: max_(max_bytes)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename OutputType>
|
||||
void decompress(OutputType& output,
|
||||
const char* data,
|
||||
std::size_t size) const
|
||||
{
|
||||
z_stream inflate_s;
|
||||
|
||||
inflate_s.zalloc = Z_NULL;
|
||||
inflate_s.zfree = Z_NULL;
|
||||
inflate_s.opaque = Z_NULL;
|
||||
inflate_s.avail_in = 0;
|
||||
inflate_s.next_in = Z_NULL;
|
||||
|
||||
// The windowBits parameter is the base two logarithm of the window size (the size of the history buffer).
|
||||
// It should be in the range 8..15 for this version of the library.
|
||||
// Larger values of this parameter result in better compression at the expense of memory usage.
|
||||
// This range of values also changes the decoding type:
|
||||
// -8 to -15 for raw deflate
|
||||
// 8 to 15 for zlib
|
||||
// (8 to 15) + 16 for gzip
|
||||
// (8 to 15) + 32 to automatically detect gzip/zlib header
|
||||
constexpr int window_bits = 15 + 32; // auto with windowbits of 15
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
if (inflateInit2(&inflate_s, window_bits) != Z_OK)
|
||||
{
|
||||
throw std::runtime_error("inflate init failed");
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
inflate_s.next_in = reinterpret_cast<z_const Bytef*>(data);
|
||||
|
||||
#ifdef DEBUG
|
||||
// Verify if size (long type) input will fit into unsigned int, type used for zlib's avail_in
|
||||
std::uint64_t size_64 = size * 2;
|
||||
if (size_64 > std::numeric_limits<unsigned int>::max())
|
||||
{
|
||||
inflateEnd(&inflate_s);
|
||||
throw std::runtime_error("size arg is too large to fit into unsigned int type x2");
|
||||
}
|
||||
#endif
|
||||
if (size > max_ || (size * 2) > max_)
|
||||
{
|
||||
inflateEnd(&inflate_s);
|
||||
throw std::runtime_error("size may use more memory than intended when decompressing");
|
||||
}
|
||||
inflate_s.avail_in = static_cast<unsigned int>(size);
|
||||
std::size_t size_uncompressed = 0;
|
||||
do
|
||||
{
|
||||
std::size_t resize_to = size_uncompressed + 2 * size;
|
||||
if (resize_to > max_)
|
||||
{
|
||||
inflateEnd(&inflate_s);
|
||||
throw std::runtime_error("size of output string will use more memory then intended when decompressing");
|
||||
}
|
||||
output.resize(resize_to);
|
||||
inflate_s.avail_out = static_cast<unsigned int>(2 * size);
|
||||
inflate_s.next_out = reinterpret_cast<Bytef*>(&output[0] + size_uncompressed);
|
||||
int ret = inflate(&inflate_s, Z_FINISH);
|
||||
if (ret != Z_STREAM_END && ret != Z_OK && ret != Z_BUF_ERROR)
|
||||
{
|
||||
std::string error_msg = inflate_s.msg;
|
||||
inflateEnd(&inflate_s);
|
||||
throw std::runtime_error(error_msg);
|
||||
}
|
||||
|
||||
size_uncompressed += (2 * size - inflate_s.avail_out);
|
||||
} while (inflate_s.avail_out == 0);
|
||||
inflateEnd(&inflate_s);
|
||||
output.resize(size_uncompressed);
|
||||
}
|
||||
};
|
||||
|
||||
inline std::string decompress(const char* data, std::size_t size)
|
||||
{
|
||||
Decompressor decomp;
|
||||
std::string output;
|
||||
decomp.decompress(output, data, size);
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace gzip
|
|
@ -1,22 +0,0 @@
|
|||
#include <cstdlib>
|
||||
|
||||
namespace gzip {
|
||||
|
||||
// These live in gzip.hpp because it doesnt need to use deps.
|
||||
// Otherwise, they would need to live in impl files if these methods used
|
||||
// zlib structures or functions like inflate/deflate)
|
||||
inline bool is_compressed(const char* data, std::size_t size)
|
||||
{
|
||||
return size > 2 &&
|
||||
(
|
||||
// zlib
|
||||
(
|
||||
static_cast<uint8_t>(data[0]) == 0x78 &&
|
||||
(static_cast<uint8_t>(data[1]) == 0x9C ||
|
||||
static_cast<uint8_t>(data[1]) == 0x01 ||
|
||||
static_cast<uint8_t>(data[1]) == 0xDA ||
|
||||
static_cast<uint8_t>(data[1]) == 0x5E)) ||
|
||||
// gzip
|
||||
(static_cast<uint8_t>(data[0]) == 0x1F && static_cast<uint8_t>(data[1]) == 0x8B));
|
||||
}
|
||||
} // namespace gzip
|
|
@ -1,16 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
/// The major version number
|
||||
#define GZIP_VERSION_MAJOR 1
|
||||
|
||||
/// The minor version number
|
||||
#define GZIP_VERSION_MINOR 0
|
||||
|
||||
/// The patch number
|
||||
#define GZIP_VERSION_PATCH 0
|
||||
|
||||
/// The complete version number
|
||||
#define GZIP_VERSION_CODE (GZIP_VERSION_MAJOR * 10000 + GZIP_VERSION_MINOR * 100 + GZIP_VERSION_PATCH)
|
||||
|
||||
/// Version number as string
|
||||
#define GZIP_VERSION_STRING "1.0.0"
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2013-2019 Niels Lohmann
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -1 +0,0 @@
|
|||
https://github.com/nlohmann/json
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
Subproject commit eadd8c7178c79c814ecca9652973a9b9dd4cc71b
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 626e7d61e44dee32887126c8f437dd077dec09cf
|
|
@ -0,0 +1 @@
|
|||
Subproject commit c0c982601f40183e74d84a61237e968dca08380e
|
|
@ -1,20 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2019 Rapptz, ThePhD, and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -1,153 +0,0 @@
|
|||
## sol3 (sol2 v3.0.3)
|
||||
|
||||
[![Join the chat in Discord: https://discord.gg/buxkYNT](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/buxkYNT)
|
||||
|
||||
[![Linux & Max OSX Build Status](https://travis-ci.org/ThePhD/sol2.svg?branch=develop)](https://travis-ci.org/ThePhD/sol2)
|
||||
[![Windows Build status](https://ci.appveyor.com/api/projects/status/n38suofr21e9uk7h?svg=true)](https://ci.appveyor.com/project/ThePhD/sol2)
|
||||
[![Documentation Status](https://readthedocs.org/projects/sol2/badge/?version=latest)](http://sol2.readthedocs.io/en/latest/?badge=latest)
|
||||
|
||||
[![Support via Github Sponsors](https://img.shields.io/badge/Github-Become%20a%20Sponsor-ff69b4.svg?style=flat&logo=GitHub)](https://github.com/users/ThePhD/sponsorship)
|
||||
[![Support via PayPal](https://cdn.rawgit.com/twolfson/paypal-github-button/1.0.0/dist/button.svg)](https://www.paypal.me/LMeneide)
|
||||
[![Support via Ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/W7W8Q619)
|
||||
[![Support via Patreon](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.herokuapp.com%2FThePhD)](https://patreon.com/thephd)
|
||||
[![Support via Liberapay](https://img.shields.io/liberapay/patrons/ThePhD.svg)](https://liberapay.com/ThePhD/)
|
||||
|
||||
sol is a C++ library binding to Lua. It currently supports all Lua versions 5.1+ (LuaJIT 2.x included). sol aims to be easy to use and easy to add to a project.
|
||||
The library is header-only for easy integration with projects.
|
||||
|
||||
## Documentation
|
||||
|
||||
Find it [here](http://sol2.rtfd.io/). A run-through kind of tutorial is [here](http://sol2.readthedocs.io/en/latest/tutorial/all-the-things.html)! The API documentation goes over most cases (particularly, the "api/usertype" and "api/proxy" and "api/function" sections) that should still get you off your feet and going, and there's an examples directory [here](https://github.com/ThePhD/sol2/tree/develop/examples) as well.
|
||||
|
||||
## Sneak Peek
|
||||
|
||||
```cpp
|
||||
#include <sol/sol.hpp>
|
||||
#include <cassert>
|
||||
|
||||
int main() {
|
||||
sol::state lua;
|
||||
int x = 0;
|
||||
lua.set_function("beep", [&x]{ ++x; });
|
||||
lua.script("beep()");
|
||||
assert(x == 1);
|
||||
}
|
||||
```
|
||||
|
||||
```cpp
|
||||
#include <sol/sol.hpp>
|
||||
#include <cassert>
|
||||
|
||||
struct vars {
|
||||
int boop = 0;
|
||||
};
|
||||
|
||||
int main() {
|
||||
sol::state lua;
|
||||
lua.new_usertype<vars>("vars", "boop", &vars::boop);
|
||||
lua.script("beep = vars.new()\n"
|
||||
"beep.boop = 1");
|
||||
assert(lua.get<vars>("beep").boop == 1);
|
||||
}
|
||||
```
|
||||
|
||||
More examples are given in the examples directory [here](https://github.com/ThePhD/sol2/tree/develop/examples).
|
||||
|
||||
|
||||
## Supporting
|
||||
|
||||
Please use the buttons above and help this project grow.
|
||||
|
||||
You can also help out the library by submitting pull requests to fix anything or add anything you think would be helpful! This includes making small, useful examples of something you haven't seen, or fixing typos and bad code in the documentation.
|
||||
|
||||
|
||||
## Presentations
|
||||
|
||||
"A Sun For the Moon - A Zero-Overhead Lua Abstraction using C++"
|
||||
ThePhD
|
||||
Lua Workshop 2016 - Mashape, San Francisco, CA
|
||||
[Deck](https://github.com/ThePhD/sol2/blob/develop/docs/presentations/2016.10.14%20-%20ThePhD%20-%20No%20Overhead%20C%20Abstraction.pdf)
|
||||
|
||||
"Wrapping Lua C in C++ - Efficiently, Nicely, and with a Touch of Magic"
|
||||
ThePhD
|
||||
Boston C++ Meetup November 2017 - CiC (Milk Street), Boston, MA
|
||||
[Deck](https://github.com/ThePhD/sol2/blob/develop/docs/presentations/2017.11.08%20-%20ThePhD%20-%20Wrapping%20Lua%20C%20in%20C%2B%2B.pdf)
|
||||
|
||||
"Biting the CMake Bullet"
|
||||
ThePhD
|
||||
Boston C++ Meetup February 2018 - CiC (Main Street), Cambridge, MA
|
||||
[Deck](https://github.com/ThePhD/sol2/blob/develop/docs/presentations/2018.02.06%20-%20ThePhD%20-%20Biting%20the%20CMake%20Bullet.pdf)
|
||||
|
||||
"Compile Fast, Run Faster, Scale Forever: A look into the sol2 Library"
|
||||
ThePhD
|
||||
C++Now 2018 - Hudson Commons, Aspen Physics Center, Aspen, Colorado
|
||||
[Deck](https://github.com/ThePhD/sol2/blob/develop/docs/presentations/2018.05.10%20-%20ThePhD%20-%20Compile%20Fast%2C%20Run%20Faster%2C%20Scale%20Forever.pdf)
|
||||
|
||||
"Scripting at the Speed of Thought: Using Lua in C++ with sol3"
|
||||
ThePhD
|
||||
CppCon 2018 - 404 Keystone, Meydenbauer Center, Aspen, Colorado
|
||||
[Deck](https://github.com/ThePhD/sol2/blob/develop/docs/presentations/2018.09.28%20-%20ThePhD%20-%20Scripting%20at%20the%20Speed%20of%20Thought.pdf)
|
||||
|
||||
"The Plan for Tomorrow: Compile-Time Extension Points in C++"
|
||||
ThePhD
|
||||
C++Now 2019 - Flug Auditorium, Aspen Physics Center, Aspen, Colorado
|
||||
[Deck](https://github.com/ThePhD/sol2/blob/develop/docs/presentations/2019.05.10%20-%20ThePhD%20-%20The%20Plan%20for%20Tomorrow%20-%20Compile-Time%20Extension%20Points%20in%20C%2b%2b.pdf)
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- [Fastest in the land](http://sol2.readthedocs.io/en/latest/benchmarks.html) (see: sol bar in graph).
|
||||
- Supports retrieval and setting of multiple types including:
|
||||
* `std::string`, `std::wstring`, `std::u16string` and `std::u32string` support (and for views).
|
||||
* understands and works with containers such as `std::map/unordered_map`, c-style arrays, vectors, non-standard custom containers and more.
|
||||
* user-defined types, with or **without** registering that type
|
||||
* `std::unique_ptr`, `std::shared_ptr`, and optional support of other pointer types like `boost::shared_ptr`.
|
||||
* custom `optional<T>` that works with references, and support for the inferior `std::optional`.
|
||||
* C++17 support for variants and similar new types.
|
||||
- Lambda, function, and member function bindings are supported.
|
||||
- Intermediate type for checking if a variable exists.
|
||||
- Simple API that completely abstracts away the C stack API, including `protected_function` with the ability to use an error-handling function.
|
||||
- `operator[]`-style manipulation of tables
|
||||
- C++ type representations in Lua userdata as `usertype`s with guaranteed cleanup.
|
||||
- Customization points to allow your C++ objects to be pushed and retrieved from Lua as multiple consecutive objects, or anything else you desire!
|
||||
- Overloaded function calls: `my_function(1); my_function("Hello")` in the same Lua script route to different function calls based on parameters
|
||||
- Support for tables, nested tables, table iteration with `table.for_each` / `begin()` and `end()` iterators.
|
||||
- Zero string overhead for usertype function lookup.
|
||||
|
||||
|
||||
## Supported Compilers
|
||||
|
||||
sol makes use of C++17 features. GCC 7.x.x and Clang 3.9.x (with `-std=c++1z` and appropriate standard library)
|
||||
or higher should be able to compile without problems. However, the officially supported and CI-tested compilers are:
|
||||
|
||||
- GCC 7.x.x+ (MinGW 7.x.x+)
|
||||
- Clang 3.9.x+
|
||||
- Visual Studio 2017 Community (Visual C++ 15.0)+
|
||||
|
||||
Please make sure you use the `-std=c++2a`, `-std=c++1z`, `-std=c++17` or better standard flags
|
||||
(some of these flags are the defaults in later versions of GCC, such as 7+ and better).
|
||||
|
||||
If you would like support for an older compiler (at the cost of some features), use the latest tagged sol2 branch. If you would like support for an even older compiler, feel free to contact me for a Custom Solution.
|
||||
|
||||
sol3 is checked by-hand for other platforms as well, including Android-based builds with GCC and iOS-based builds out of XCode with Apple-clang. It should work on both of these platforms, so long as you have the proper standards flags.
|
||||
|
||||
|
||||
## Creating a single header
|
||||
|
||||
You can grab a single header (and the single forward header) out of the library [here](https://github.com/ThePhD/sol2/tree/develop/single). For stable version, check the releases tab on GitHub for a provided single header file for maximum ease of use. A script called [`single.py`](https://github.com/ThePhD/sol2/blob/develop/single/single.py) is provided in the repository if there's some bleeding edge change that hasn't been published on the releases page. You can run this script to create a single file version of the library so you can only include that part of it. Check `single.py --help` for more info.
|
||||
|
||||
If you use CMake, you can also configure and generate a project that will generate the `sol2_single_header` for you. You can also include the project using CMake. Run CMake for more details. Thanks @Nava2, @alkino, @mrgreywater and others for help with making the CMake build a reality.
|
||||
|
||||
|
||||
## Running the Tests
|
||||
|
||||
Testing on Travis-CI and Appveyor use CMake. You can generate the tests by running CMake and configuring `SOL2_TESTS`, `SOL2_TESTS_SINGLE`, `SOL2_TESTS_EXAMPLES`, and `SOL2_EXAMPLES` to be on. Make sure `SOL2_SINGLE` is also on.
|
||||
|
||||
You will need any flavor of python3 and an available compiler. The testing suite will build its own version of Lua and LuaJIT, so you do not have to provide one (you may provide one with the `LUA_LOCAL_DIR` variable).
|
||||
|
||||
|
||||
## License
|
||||
|
||||
sol is distributed with an MIT License. You can see LICENSE.txt for more info.
|
||||
|
||||
If you need a custom solution, feel free to contact me.
|
|
@ -1,54 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this Spermission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_AS_ARGS_HPP
|
||||
#define SOL_AS_ARGS_HPP
|
||||
|
||||
#include "stack.hpp"
|
||||
|
||||
namespace sol {
|
||||
template <typename T>
|
||||
struct as_args_t {
|
||||
T src;
|
||||
};
|
||||
|
||||
template <typename Source>
|
||||
auto as_args(Source&& source) {
|
||||
return as_args_t<Source> { std::forward<Source>(source) };
|
||||
}
|
||||
|
||||
namespace stack {
|
||||
template <typename T>
|
||||
struct unqualified_pusher<as_args_t<T>> {
|
||||
int push(lua_State* L, const as_args_t<T>& e) {
|
||||
int p = 0;
|
||||
for (const auto& i : e.src) {
|
||||
p += stack::push(L, i);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
};
|
||||
} // namespace stack
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_AS_ARGS_HPP
|
|
@ -1,56 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_AS_RETURNS_HPP
|
||||
#define SOL_AS_RETURNS_HPP
|
||||
|
||||
#include "traits.hpp"
|
||||
#include "stack.hpp"
|
||||
|
||||
namespace sol {
|
||||
template <typename T>
|
||||
struct as_returns_t {
|
||||
T src;
|
||||
};
|
||||
|
||||
template <typename Source>
|
||||
auto as_returns(Source&& source) {
|
||||
return as_returns_t<std::decay_t<Source>>{ std::forward<Source>(source) };
|
||||
}
|
||||
|
||||
namespace stack {
|
||||
template <typename T>
|
||||
struct unqualified_pusher<as_returns_t<T>> {
|
||||
int push(lua_State* L, const as_returns_t<T>& e) {
|
||||
auto& src = detail::unwrap(e.src);
|
||||
int p = 0;
|
||||
for (const auto& i : src) {
|
||||
p += stack::push(L, i);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
};
|
||||
} // namespace stack
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_AS_RETURNS_HPP
|
|
@ -1,110 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_BASE_TRAITS_HPP
|
||||
#define SOL_BASE_TRAITS_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
struct unchecked_t {};
|
||||
const unchecked_t unchecked = unchecked_t{};
|
||||
} // namespace detail
|
||||
|
||||
namespace meta {
|
||||
using sfinae_yes_t = std::true_type;
|
||||
using sfinae_no_t = std::false_type;
|
||||
|
||||
template <typename T>
|
||||
using void_t = void;
|
||||
|
||||
template <typename T>
|
||||
using unqualified = std::remove_cv<std::remove_reference_t<T>>;
|
||||
|
||||
template <typename T>
|
||||
using unqualified_t = typename unqualified<T>::type;
|
||||
|
||||
namespace meta_detail {
|
||||
template <typename T>
|
||||
struct unqualified_non_alias : unqualified<T> {};
|
||||
|
||||
template <template <class...> class Test, class, class... Args>
|
||||
struct is_detected : std::false_type {};
|
||||
|
||||
template <template <class...> class Test, class... Args>
|
||||
struct is_detected<Test, void_t<Test<Args...>>, Args...> : std::true_type {};
|
||||
} // namespace meta_detail
|
||||
|
||||
template <template <class...> class Trait, class... Args>
|
||||
using is_detected = typename meta_detail::is_detected<Trait, void, Args...>::type;
|
||||
|
||||
template <template <class...> class Trait, class... Args>
|
||||
constexpr inline bool is_detected_v = is_detected<Trait, Args...>::value;
|
||||
|
||||
template <std::size_t I>
|
||||
using index_value = std::integral_constant<std::size_t, I>;
|
||||
|
||||
template <bool>
|
||||
struct conditional {
|
||||
template <typename T, typename U>
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct conditional<false> {
|
||||
template <typename T, typename U>
|
||||
using type = U;
|
||||
};
|
||||
|
||||
template <bool B, typename T, typename U>
|
||||
using conditional_t = typename conditional<B>::template type<T, U>;
|
||||
|
||||
namespace meta_detail {
|
||||
template <typename T, template <typename...> class Templ>
|
||||
struct is_specialization_of : std::false_type {};
|
||||
template <typename... T, template <typename...> class Templ>
|
||||
struct is_specialization_of<Templ<T...>, Templ> : std::true_type {};
|
||||
} // namespace meta_detail
|
||||
|
||||
template <typename T, template <typename...> class Templ>
|
||||
using is_specialization_of = meta_detail::is_specialization_of<std::remove_cv_t<T>, Templ>;
|
||||
|
||||
template <typename T, template <typename...> class Templ>
|
||||
inline constexpr bool is_specialization_of_v = is_specialization_of<std::remove_cv_t<T>, Templ>::value;
|
||||
|
||||
template <typename T>
|
||||
struct identity {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using identity_t = typename identity<T>::type;
|
||||
|
||||
template <typename T>
|
||||
using is_builtin_type = std::integral_constant<bool, std::is_arithmetic<T>::value || std::is_pointer<T>::value || std::is_array<T>::value>;
|
||||
|
||||
} // namespace meta
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_BASE_TRAITS_HPP
|
|
@ -1,546 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_BIND_TRAITS_HPP
|
||||
#define SOL_BIND_TRAITS_HPP
|
||||
|
||||
#include "forward.hpp"
|
||||
#include "base_traits.hpp"
|
||||
#include "tuple.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace meta {
|
||||
namespace meta_detail {
|
||||
|
||||
template <class F>
|
||||
struct check_deducible_signature {
|
||||
struct nat {};
|
||||
template <class G>
|
||||
static auto test(int) -> decltype(&G::operator(), void());
|
||||
template <class>
|
||||
static auto test(...) -> nat;
|
||||
|
||||
using type = std::is_void<decltype(test<F>(0))>;
|
||||
};
|
||||
} // namespace meta_detail
|
||||
|
||||
template <class F>
|
||||
struct has_deducible_signature : meta_detail::check_deducible_signature<F>::type {};
|
||||
|
||||
namespace meta_detail {
|
||||
|
||||
template <std::size_t I, typename T>
|
||||
struct void_tuple_element : meta::tuple_element<I, T> {};
|
||||
|
||||
template <std::size_t I>
|
||||
struct void_tuple_element<I, std::tuple<>> { typedef void type; };
|
||||
|
||||
template <std::size_t I, typename T>
|
||||
using void_tuple_element_t = typename void_tuple_element<I, T>::type;
|
||||
|
||||
template <bool it_is_noexcept, bool has_c_variadic, typename T, typename R, typename... Args>
|
||||
struct basic_traits {
|
||||
private:
|
||||
using first_type = meta::conditional_t<std::is_void<T>::value, int, T>&;
|
||||
|
||||
public:
|
||||
inline static constexpr const bool is_noexcept = it_is_noexcept;
|
||||
inline static constexpr bool is_member_function = std::is_void<T>::value;
|
||||
inline static constexpr bool has_c_var_arg = has_c_variadic;
|
||||
inline static constexpr std::size_t arity = sizeof...(Args);
|
||||
inline static constexpr std::size_t free_arity = sizeof...(Args) + static_cast<std::size_t>(!std::is_void<T>::value);
|
||||
typedef types<Args...> args_list;
|
||||
typedef std::tuple<Args...> args_tuple;
|
||||
typedef T object_type;
|
||||
typedef R return_type;
|
||||
typedef tuple_types<R> returns_list;
|
||||
typedef R(function_type)(Args...);
|
||||
typedef meta::conditional_t<std::is_void<T>::value, args_list, types<first_type, Args...>> free_args_list;
|
||||
typedef meta::conditional_t<std::is_void<T>::value, R(Args...), R(first_type, Args...)> free_function_type;
|
||||
typedef meta::conditional_t<std::is_void<T>::value, R (*)(Args...), R (*)(first_type, Args...)> free_function_pointer_type;
|
||||
typedef std::remove_pointer_t<free_function_pointer_type> signature_type;
|
||||
template <std::size_t i>
|
||||
using arg_at = void_tuple_element_t<i, args_tuple>;
|
||||
};
|
||||
|
||||
template <typename Signature, bool b = has_deducible_signature<Signature>::value>
|
||||
struct fx_traits : basic_traits<false, false, void, void> {};
|
||||
|
||||
// Free Functions
|
||||
template <typename R, typename... Args>
|
||||
struct fx_traits<R(Args...), false> : basic_traits<false, false, void, R, Args...> {
|
||||
typedef R (*function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct fx_traits<R (*)(Args...), false> : basic_traits<false, false, void, R, Args...> {
|
||||
typedef R (*function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct fx_traits<R(Args..., ...), false> : basic_traits<false, true, void, R, Args...> {
|
||||
typedef R (*function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct fx_traits<R (*)(Args..., ...), false> : basic_traits<false, true, void, R, Args...> {
|
||||
typedef R (*function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
// Member Functions
|
||||
/* C-Style Variadics */
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...), false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...), false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...);
|
||||
};
|
||||
|
||||
/* Const Volatile */
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...) const, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) const;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...) const, false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) const;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...) const volatile, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) const volatile;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...) const volatile, false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) const volatile;
|
||||
};
|
||||
|
||||
/* Member Function Qualifiers */
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...)&, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) &;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...)&, false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) &;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...) const&, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) const&;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...) const&, false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) const&;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...) const volatile&, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) const volatile&;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...) const volatile&, false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) const volatile&;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...)&&, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) &&;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...)&&, false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) &&;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...) const&&, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) const&&;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...) const&&, false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) const&&;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...) const volatile&&, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) const volatile&&;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...) const volatile&&, false> : basic_traits<false, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) const volatile&&;
|
||||
};
|
||||
|
||||
#if defined(SOL_NOEXCEPT_FUNCTION_TYPE) && SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct fx_traits<R(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
|
||||
typedef R (*function_pointer_type)(Args...) noexcept;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct fx_traits<R (*)(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
|
||||
typedef R (*function_pointer_type)(Args...) noexcept;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct fx_traits<R(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
|
||||
typedef R (*function_pointer_type)(Args..., ...) noexcept;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct fx_traits<R (*)(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
|
||||
typedef R (*function_pointer_type)(Args..., ...) noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...) noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...) noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) noexcept;
|
||||
};
|
||||
|
||||
/* Const Volatile */
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...) const noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) const noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...) const noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) const noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...) const volatile noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) const volatile noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...) const volatile noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) const volatile noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...) & noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) & noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...) & noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) & noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...) const& noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) const& noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...) const& noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) const& noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...) const volatile& noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) const volatile& noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...) const volatile& noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) const volatile& noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...) && noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) && noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...) && noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) && noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...) const&& noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) const&& noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...) const&& noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) const&& noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args...) const volatile&& noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args...) const volatile&& noexcept;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (T::*)(Args..., ...) const volatile&& noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (T::*function_pointer_type)(Args..., ...) const volatile&& noexcept;
|
||||
};
|
||||
|
||||
#endif // noexcept is part of a function's type
|
||||
|
||||
#if defined(_MSC_VER) && defined(_M_IX86)
|
||||
template <typename R, typename... Args>
|
||||
struct fx_traits<R __stdcall(Args...), false> : basic_traits<false, false, void, R, Args...> {
|
||||
typedef R(__stdcall* function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct fx_traits<R(__stdcall*)(Args...), false> : basic_traits<false, false, void, R, Args...> {
|
||||
typedef R(__stdcall* function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...), false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...);
|
||||
};
|
||||
|
||||
/* Const Volatile */
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...) const, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) const;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...) const volatile, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile;
|
||||
};
|
||||
|
||||
/* Member Function Qualifiers */
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...)&, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) &;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...) const&, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) const&;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...) const volatile&, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...)&&, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) &&;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...) const&&, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) const&&;
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...) const volatile&&, false> : basic_traits<false, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&&;
|
||||
};
|
||||
|
||||
#if defined(SOL_NOEXCEPT_FUNCTION_TYPE) && SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct fx_traits<R __stdcall(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
|
||||
typedef R(__stdcall* function_pointer_type)(Args...) noexcept;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall *)(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
|
||||
typedef R(__stdcall* function_pointer_type)(Args...) noexcept;
|
||||
};
|
||||
|
||||
/* __stdcall cannot be applied to functions with varargs*/
|
||||
/*template <typename R, typename... Args>
|
||||
struct fx_traits<__stdcall R(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
|
||||
typedef R(__stdcall* function_pointer_type)(Args..., ...) noexcept;
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall *)(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
|
||||
typedef R(__stdcall* function_pointer_type)(Args..., ...) noexcept;
|
||||
};*/
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...) noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) noexcept;
|
||||
};
|
||||
|
||||
/* __stdcall does not work with varargs */
|
||||
/*template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args..., ...) noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) noexcept;
|
||||
};*/
|
||||
|
||||
/* Const Volatile */
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...) const noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) const noexcept;
|
||||
};
|
||||
|
||||
/* __stdcall does not work with varargs */
|
||||
/*template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args..., ...) const noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const noexcept;
|
||||
};*/
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...) const volatile noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile noexcept;
|
||||
};
|
||||
|
||||
/* __stdcall does not work with varargs */
|
||||
/*template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const volatile noexcept;
|
||||
};*/
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...) & noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) & noexcept;
|
||||
};
|
||||
|
||||
/* __stdcall does not work with varargs */
|
||||
/*template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args..., ...) & noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) & noexcept;
|
||||
};*/
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...) const& noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) const& noexcept;
|
||||
};
|
||||
|
||||
/* __stdcall does not work with varargs */
|
||||
/*template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args..., ...) const& noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const& noexcept;
|
||||
};*/
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...) const volatile& noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile& noexcept;
|
||||
};
|
||||
|
||||
/* __stdcall does not work with varargs */
|
||||
/*template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile& noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const volatile& noexcept;
|
||||
};*/
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...) && noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) && noexcept;
|
||||
};
|
||||
|
||||
/* __stdcall does not work with varargs */
|
||||
/*template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args..., ...) && noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) && noexcept;
|
||||
};*/
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...) const&& noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) const&& noexcept;
|
||||
};
|
||||
|
||||
/* __stdcall does not work with varargs */
|
||||
/*template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args..., ...) const&& noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const&& noexcept;
|
||||
};*/
|
||||
|
||||
template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args...) const volatile&& noexcept, false> : basic_traits<true, false, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&& noexcept;
|
||||
};
|
||||
|
||||
/* __stdcall does not work with varargs */
|
||||
/*template <typename T, typename R, typename... Args>
|
||||
struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile&& noexcept, false> : basic_traits<true, true, T, R, Args...> {
|
||||
typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const volatile&& noexcept;
|
||||
};*/
|
||||
#endif // noexcept is part of a function's type
|
||||
#endif // __stdcall x86 VC++ bug
|
||||
|
||||
template <typename Signature>
|
||||
struct fx_traits<Signature, true> : fx_traits<typename fx_traits<decltype(&Signature::operator())>::function_type, false> {};
|
||||
|
||||
template <typename Signature, bool b = std::is_member_object_pointer<Signature>::value>
|
||||
struct callable_traits : fx_traits<std::decay_t<Signature>> {
|
||||
};
|
||||
|
||||
template <typename R, typename T>
|
||||
struct callable_traits<R(T::*), true> {
|
||||
typedef meta::conditional_t<std::is_array_v<R>, std::add_lvalue_reference_t<R>, R> return_type;
|
||||
typedef return_type Arg;
|
||||
typedef T object_type;
|
||||
using signature_type = R(T::*);
|
||||
inline static constexpr bool is_noexcept = false;
|
||||
inline static constexpr bool is_member_function = false;
|
||||
inline static constexpr std::size_t arity = 1;
|
||||
inline static constexpr std::size_t free_arity = 2;
|
||||
typedef std::tuple<Arg> args_tuple;
|
||||
typedef types<Arg> args_list;
|
||||
typedef types<T, Arg> free_args_list;
|
||||
typedef meta::tuple_types<return_type> returns_list;
|
||||
typedef return_type(function_type)(T&, return_type);
|
||||
typedef return_type(*function_pointer_type)(T&, Arg);
|
||||
typedef return_type(*free_function_pointer_type)(T&, Arg);
|
||||
template <std::size_t i>
|
||||
using arg_at = void_tuple_element_t<i, args_tuple>;
|
||||
};
|
||||
|
||||
} // namespace meta_detail
|
||||
|
||||
template <typename Signature>
|
||||
struct bind_traits : meta_detail::callable_traits<Signature> {};
|
||||
|
||||
template <typename Signature>
|
||||
using function_args_t = typename bind_traits<Signature>::args_list;
|
||||
|
||||
template <typename Signature>
|
||||
using function_signature_t = typename bind_traits<Signature>::signature_type;
|
||||
|
||||
template <typename Signature>
|
||||
using function_return_t = typename bind_traits<Signature>::return_type;
|
||||
}
|
||||
} // namespace sol::meta
|
||||
|
||||
#endif // SOL_BIND_TRAITS_HPP
|
|
@ -1,121 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_BYTECODE_HPP
|
||||
#define SOL_BYTECODE_HPP
|
||||
|
||||
#include "compatibility.hpp"
|
||||
#include "string_view.hpp"
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
namespace sol {
|
||||
|
||||
template <typename Allocator = std::allocator<std::byte>>
|
||||
class basic_bytecode : private std::vector<std::byte, Allocator> {
|
||||
private:
|
||||
using base_t = std::vector<std::byte, Allocator>;
|
||||
|
||||
public:
|
||||
using typename base_t::allocator_type;
|
||||
using typename base_t::const_iterator;
|
||||
using typename base_t::const_pointer;
|
||||
using typename base_t::const_reference;
|
||||
using typename base_t::const_reverse_iterator;
|
||||
using typename base_t::difference_type;
|
||||
using typename base_t::iterator;
|
||||
using typename base_t::pointer;
|
||||
using typename base_t::reference;
|
||||
using typename base_t::reverse_iterator;
|
||||
using typename base_t::size_type;
|
||||
using typename base_t::value_type;
|
||||
|
||||
using base_t::base_t;
|
||||
using base_t::operator=;
|
||||
|
||||
using base_t::data;
|
||||
using base_t::empty;
|
||||
using base_t::max_size;
|
||||
using base_t::size;
|
||||
|
||||
using base_t::at;
|
||||
using base_t::operator[];
|
||||
using base_t::back;
|
||||
using base_t::front;
|
||||
|
||||
using base_t::begin;
|
||||
using base_t::cbegin;
|
||||
using base_t::cend;
|
||||
using base_t::end;
|
||||
|
||||
using base_t::crbegin;
|
||||
using base_t::crend;
|
||||
using base_t::rbegin;
|
||||
using base_t::rend;
|
||||
|
||||
|
||||
using base_t::get_allocator;
|
||||
using base_t::swap;
|
||||
|
||||
using base_t::clear;
|
||||
using base_t::emplace;
|
||||
using base_t::emplace_back;
|
||||
using base_t::erase;
|
||||
using base_t::insert;
|
||||
using base_t::pop_back;
|
||||
using base_t::push_back;
|
||||
using base_t::reserve;
|
||||
using base_t::resize;
|
||||
using base_t::shrink_to_fit;
|
||||
|
||||
string_view as_string_view() const {
|
||||
return string_view(reinterpret_cast<const char*>(this->data()), this->size());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Container>
|
||||
inline int basic_insert_dump_writer(lua_State*, const void* memory, size_t memory_size, void* userdata) {
|
||||
using storage_t = Container;
|
||||
const std::byte* p_code = static_cast<const std::byte*>(memory);
|
||||
storage_t& bc = *static_cast<storage_t*>(userdata);
|
||||
#if defined(SOL_NO_EXCEPTIONS) && SOL_NO_EXCEPTIONS != 0
|
||||
bc.insert(bc.cend(), p_code, p_code + memory_size);
|
||||
#else
|
||||
try {
|
||||
bc.insert(bc.cend(), p_code, p_code + memory_size);
|
||||
}
|
||||
catch (...) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
using bytecode = basic_bytecode<>;
|
||||
|
||||
constexpr inline auto bytecode_dump_writer = &basic_insert_dump_writer<bytecode>;
|
||||
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_BYTECODE_HPP
|
|
@ -1,931 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_CALL_HPP
|
||||
#define SOL_CALL_HPP
|
||||
|
||||
#include "property.hpp"
|
||||
#include "protect.hpp"
|
||||
#include "wrapper.hpp"
|
||||
#include "trampoline.hpp"
|
||||
#include "policies.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "unique_usertype_traits.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace u_detail {
|
||||
|
||||
} // namespace u_detail
|
||||
|
||||
namespace policy_detail {
|
||||
template <int I, int... In>
|
||||
inline void handle_policy(static_stack_dependencies<I, In...>, lua_State* L, int&) {
|
||||
if constexpr (sizeof...(In) == 0) {
|
||||
(void)L;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
absolute_index ai(L, I);
|
||||
if (type_of(L, ai) != type::userdata) {
|
||||
return;
|
||||
}
|
||||
lua_createtable(L, static_cast<int>(sizeof...(In)), 0);
|
||||
stack_reference deps(L, -1);
|
||||
auto per_dep = [&L, &deps](int i) {
|
||||
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
||||
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
|
||||
#endif // make sure stack doesn't overflow
|
||||
lua_pushvalue(L, i);
|
||||
luaL_ref(L, deps.stack_index());
|
||||
};
|
||||
(void)per_dep;
|
||||
(void)detail::swallow{ int(), (per_dep(In), int())... };
|
||||
lua_setuservalue(L, ai);
|
||||
}
|
||||
}
|
||||
|
||||
template <int... In>
|
||||
inline void handle_policy(returns_self_with<In...>, lua_State* L, int& pushed) {
|
||||
pushed = stack::push(L, raw_index(1));
|
||||
handle_policy(static_stack_dependencies<-1, In...>(), L, pushed);
|
||||
}
|
||||
|
||||
inline void handle_policy(const stack_dependencies& sdeps, lua_State* L, int&) {
|
||||
absolute_index ai(L, sdeps.target);
|
||||
if (type_of(L, ai) != type::userdata) {
|
||||
return;
|
||||
}
|
||||
lua_createtable(L, static_cast<int>(sdeps.size()), 0);
|
||||
stack_reference deps(L, -1);
|
||||
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
||||
luaL_checkstack(L, static_cast<int>(sdeps.size()), detail::not_enough_stack_space_generic);
|
||||
#endif // make sure stack doesn't overflow
|
||||
for (std::size_t i = 0; i < sdeps.size(); ++i) {
|
||||
lua_pushvalue(L, sdeps.stack_indices[i]);
|
||||
luaL_ref(L, deps.stack_index());
|
||||
}
|
||||
lua_setuservalue(L, ai);
|
||||
}
|
||||
|
||||
template <typename P, meta::disable<std::is_base_of<detail::policy_base_tag, meta::unqualified_t<P>>> = meta::enabler>
|
||||
inline void handle_policy(P&& p, lua_State* L, int& pushed) {
|
||||
pushed = std::forward<P>(p)(L, pushed);
|
||||
}
|
||||
} // namespace policy_detail
|
||||
|
||||
namespace function_detail {
|
||||
inline int no_construction_error(lua_State* L) {
|
||||
return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)");
|
||||
}
|
||||
} // namespace function_detail
|
||||
|
||||
namespace call_detail {
|
||||
|
||||
template <typename R, typename W>
|
||||
inline auto& pick(std::true_type, property_wrapper<R, W>& f) {
|
||||
return f.read();
|
||||
}
|
||||
|
||||
template <typename R, typename W>
|
||||
inline auto& pick(std::false_type, property_wrapper<R, W>& f) {
|
||||
return f.write();
|
||||
}
|
||||
|
||||
template <typename T, typename List>
|
||||
struct void_call : void_call<T, meta::function_args_t<List>> {};
|
||||
|
||||
template <typename T, typename... Args>
|
||||
struct void_call<T, types<Args...>> {
|
||||
static void call(Args...) {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool checked, bool clean_stack>
|
||||
struct constructor_match {
|
||||
T* obj_;
|
||||
|
||||
constructor_match(T* o) : obj_(o) {
|
||||
}
|
||||
|
||||
template <typename Fx, std::size_t I, typename... R, typename... Args>
|
||||
int operator()(types<Fx>, meta::index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) const {
|
||||
detail::default_construct func{};
|
||||
return stack::call_into_lua<checked, clean_stack>(r, a, L, start, func, obj_);
|
||||
}
|
||||
};
|
||||
|
||||
namespace overload_detail {
|
||||
template <std::size_t... M, typename Match, typename... Args>
|
||||
inline int overload_match_arity(types<>, std::index_sequence<>, std::index_sequence<M...>, Match&&, lua_State* L, int, int, Args&&...) {
|
||||
return luaL_error(L, "sol: no matching function call takes this number of arguments and the specified types");
|
||||
}
|
||||
|
||||
template <typename Fx, typename... Fxs, std::size_t I, std::size_t... In, std::size_t... M, typename Match, typename... Args>
|
||||
inline int overload_match_arity(types<Fx, Fxs...>, std::index_sequence<I, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L,
|
||||
int fxarity, int start, Args&&... args) {
|
||||
typedef lua_bind_traits<meta::unwrap_unqualified_t<Fx>> traits;
|
||||
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||
typedef typename traits::free_args_list args_list;
|
||||
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||
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<Fxs...>(),
|
||||
std::index_sequence<In...>(),
|
||||
std::index_sequence<M...>(),
|
||||
std::forward<Match>(matchfx),
|
||||
L,
|
||||
fxarity,
|
||||
start,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
if constexpr (!traits::runtime_variadics_t::value) {
|
||||
if (traits::free_arity != fxarity) {
|
||||
return overload_match_arity(types<Fxs...>(),
|
||||
std::index_sequence<In...>(),
|
||||
std::index_sequence<traits::free_arity, M...>(),
|
||||
std::forward<Match>(matchfx),
|
||||
L,
|
||||
fxarity,
|
||||
start,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
stack::record tracking{};
|
||||
if (!stack::stack_detail::check_types(args_list(), L, start, no_panic, tracking)) {
|
||||
return overload_match_arity(types<Fxs...>(),
|
||||
std::index_sequence<In...>(),
|
||||
std::index_sequence<M...>(),
|
||||
std::forward<Match>(matchfx),
|
||||
L,
|
||||
fxarity,
|
||||
start,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
return matchfx(types<Fx>(), meta::index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <std::size_t... M, typename Match, typename... Args>
|
||||
inline int overload_match_arity_single(
|
||||
types<>, std::index_sequence<>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, 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)...);
|
||||
}
|
||||
|
||||
template <typename Fx, std::size_t I, std::size_t... M, typename Match, typename... Args>
|
||||
inline int overload_match_arity_single(
|
||||
types<Fx>, std::index_sequence<I>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||
typedef lua_bind_traits<meta::unwrap_unqualified_t<Fx>> traits;
|
||||
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||
typedef typename traits::free_args_list args_list;
|
||||
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||
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)...);
|
||||
}
|
||||
if constexpr (!traits::runtime_variadics_t::value) {
|
||||
if (traits::free_arity != fxarity) {
|
||||
return overload_match_arity(types<>(),
|
||||
std::index_sequence<>(),
|
||||
std::index_sequence<traits::free_arity, M...>(),
|
||||
std::forward<Match>(matchfx),
|
||||
L,
|
||||
fxarity,
|
||||
start,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
return matchfx(types<Fx>(), meta::index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Fx, typename Fx1, typename... Fxs, std::size_t I, std::size_t I1, std::size_t... In, std::size_t... M, typename Match,
|
||||
typename... Args>
|
||||
inline int overload_match_arity_single(types<Fx, Fx1, Fxs...>, std::index_sequence<I, I1, In...>, std::index_sequence<M...>, Match&& matchfx,
|
||||
lua_State* L, int fxarity, int start, Args&&... args) {
|
||||
typedef lua_bind_traits<meta::unwrap_unqualified_t<Fx>> traits;
|
||||
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||
typedef typename traits::free_args_list args_list;
|
||||
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||
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<Fx1, Fxs...>(),
|
||||
std::index_sequence<I1, In...>(),
|
||||
std::index_sequence<M...>(),
|
||||
std::forward<Match>(matchfx),
|
||||
L,
|
||||
fxarity,
|
||||
start,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
if constexpr (!traits::runtime_variadics_t::value) {
|
||||
if (traits::free_arity != fxarity) {
|
||||
return overload_match_arity(types<Fx1, Fxs...>(),
|
||||
std::index_sequence<I1, In...>(),
|
||||
std::index_sequence<traits::free_arity, M...>(),
|
||||
std::forward<Match>(matchfx),
|
||||
L,
|
||||
fxarity,
|
||||
start,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
stack::record tracking{};
|
||||
if (!stack::stack_detail::check_types(args_list(), L, start, no_panic, tracking)) {
|
||||
return overload_match_arity(types<Fx1, Fxs...>(),
|
||||
std::index_sequence<I1, In...>(),
|
||||
std::index_sequence<M...>(),
|
||||
std::forward<Match>(matchfx),
|
||||
L,
|
||||
fxarity,
|
||||
start,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
return matchfx(types<Fx>(), meta::index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
} // namespace overload_detail
|
||||
|
||||
template <typename... Functions, typename Match, typename... Args>
|
||||
inline int overload_match_arity(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||
return overload_detail::overload_match_arity_single(types<Functions...>(),
|
||||
std::make_index_sequence<sizeof...(Functions)>(),
|
||||
std::index_sequence<>(),
|
||||
std::forward<Match>(matchfx),
|
||||
L,
|
||||
fxarity,
|
||||
start,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Functions, typename Match, typename... Args>
|
||||
inline int overload_match(Match&& matchfx, lua_State* L, int start, Args&&... args) {
|
||||
int fxarity = lua_gettop(L) - (start - 1);
|
||||
return overload_match_arity<Functions...>(std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T, typename... TypeLists, typename Match, typename... Args>
|
||||
inline int construct_match(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||
// use same overload resolution matching as all other parts of the framework
|
||||
return overload_match_arity<decltype(void_call<T, TypeLists>::call)...>(
|
||||
std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T, bool checked, bool clean_stack, typename... TypeLists>
|
||||
inline int construct_trampolined(lua_State* L) {
|
||||
static const auto& meta = usertype_traits<T>::metatable();
|
||||
int argcount = lua_gettop(L);
|
||||
call_syntax syntax = argcount > 0 ? stack::get_call_syntax(L, usertype_traits<T>::user_metatable(), 1) : call_syntax::dot;
|
||||
argcount -= static_cast<int>(syntax);
|
||||
|
||||
T* obj = detail::usertype_allocate<T>(L);
|
||||
reference userdataref(L, -1);
|
||||
stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
|
||||
umf();
|
||||
|
||||
// put userdata at the first index
|
||||
lua_insert(L, 1);
|
||||
construct_match<T, TypeLists...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, 1 + static_cast<int>(syntax));
|
||||
|
||||
userdataref.push();
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <typename T, bool checked, bool clean_stack, typename... TypeLists>
|
||||
inline int construct(lua_State* L) {
|
||||
return detail::static_trampoline<&construct_trampolined<T, checked, clean_stack, TypeLists...>>(L);
|
||||
}
|
||||
|
||||
template <typename F, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename = void>
|
||||
struct agnostic_lua_call_wrapper {
|
||||
template <typename Fx, typename... Args>
|
||||
static int call(lua_State* L, Fx&& f, Args&&... args) {
|
||||
using uFx = meta::unqualified_t<Fx>;
|
||||
static constexpr bool is_ref = is_lua_reference_v<uFx>;
|
||||
if constexpr (is_ref) {
|
||||
if constexpr (is_index) {
|
||||
return stack::push(L, std::forward<Fx>(f), std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
std::forward<Fx>(f) = stack::unqualified_get<F>(L, boost + (is_variable ? 3 : 1));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
using wrap = wrapper<uFx>;
|
||||
using traits_type = typename wrap::traits_type;
|
||||
using fp_t = typename traits_type::function_pointer_type;
|
||||
constexpr bool is_function_pointer_convertible
|
||||
= std::is_class_v<uFx> && std::is_convertible_v<std::decay_t<Fx>, fp_t>;
|
||||
if constexpr (is_function_pointer_convertible) {
|
||||
fp_t fx = f;
|
||||
return agnostic_lua_call_wrapper<fp_t, is_index, is_variable, checked, boost, clean_stack>{}.call(
|
||||
L, fx, std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
using returns_list = typename wrap::returns_list;
|
||||
using args_list = typename wrap::free_args_list;
|
||||
using caller = typename wrap::caller;
|
||||
return stack::call_into_lua<checked, clean_stack>(
|
||||
returns_list(), args_list(), L, boost + 1, caller(), std::forward<Fx>(f), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<var_wrapper<T>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
template <typename F>
|
||||
static int call(lua_State* L, F&& f) {
|
||||
if constexpr (is_index) {
|
||||
constexpr bool is_stack = is_stack_based_v<meta::unqualified_t<decltype(detail::unwrap(f.value()))>>;
|
||||
if constexpr (clean_stack && !is_stack) {
|
||||
lua_settop(L, 0);
|
||||
}
|
||||
return stack::push_reference(L, detail::unwrap(f.value()));
|
||||
}
|
||||
else {
|
||||
if constexpr (std::is_const_v<meta::unwrapped_t<T>>) {
|
||||
(void)f;
|
||||
return luaL_error(L, "sol: cannot write to a readonly (const) variable");
|
||||
}
|
||||
else {
|
||||
using R = meta::unwrapped_t<T>;
|
||||
if constexpr (std::is_assignable_v<std::add_lvalue_reference_t<meta::unqualified_t<R>>, R>) {
|
||||
detail::unwrap(f.value()) = stack::unqualified_get<meta::unwrapped_t<T>>(L, boost + (is_variable ? 3 : 1));
|
||||
if (clean_stack) {
|
||||
lua_settop(L, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return luaL_error(L, "sol: cannot write to this variable: copy assignment/constructor not available");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<lua_CFunction_ref, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
static int call(lua_State* L, lua_CFunction_ref f) {
|
||||
return f(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<lua_CFunction, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
static int call(lua_State* L, lua_CFunction f) {
|
||||
return f(L);
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(SOL_NOEXCEPT_FUNCTION_TYPE) && SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<detail::lua_CFunction_noexcept, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
static int call(lua_State* L, detail::lua_CFunction_noexcept f) {
|
||||
return f(L);
|
||||
}
|
||||
};
|
||||
#endif // noexcept function types
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<detail::no_prop, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
static int call(lua_State* L, const detail::no_prop&) {
|
||||
return luaL_error(L, is_index ? "sol: cannot read from a writeonly property" : "sol: cannot write to a readonly property");
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
static int call(lua_State* L, const no_construction&) {
|
||||
return function_detail::no_construction_error(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
static int call(lua_State*, const bases<Args...>&) {
|
||||
// Uh. How did you even call this, lul
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct agnostic_lua_call_wrapper<std::reference_wrapper<T>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
static int call(lua_State* L, std::reference_wrapper<T> f) {
|
||||
agnostic_lua_call_wrapper<T, is_index, is_variable, checked, boost, clean_stack> alcw{};
|
||||
return alcw.call(L, f.get());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked = detail::default_safe_function_calls, int boost = 0,
|
||||
bool clean_stack = true, typename = void>
|
||||
struct lua_call_wrapper {
|
||||
template <typename Fx, typename... Args>
|
||||
static int call(lua_State* L, Fx&& fx, Args&&... args) {
|
||||
if constexpr (std::is_member_function_pointer_v<F>) {
|
||||
using wrap = wrapper<F>;
|
||||
using object_type = typename wrap::object_type;
|
||||
if constexpr (sizeof...(Args) < 1) {
|
||||
using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
|
||||
static_assert(std::is_base_of_v<object_type, Ta>, "It seems like you might have accidentally bound a class type with a member function method that does not correspond to the class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one class \"T\" but then bind member methods from a complete unrelated class. Check things over!");
|
||||
#if defined(SOL_SAFE_USERTYPE) && SOL_SAFE_USERTYPE
|
||||
auto maybeo = stack::check_get<Ta*>(L, 1);
|
||||
if (!maybeo || maybeo.value() == nullptr) {
|
||||
return luaL_error(L,
|
||||
"sol: received nil for 'self' argument (use ':' for accessing member functions, make sure member variables are "
|
||||
"preceeded by the "
|
||||
"actual object with '.' syntax)");
|
||||
}
|
||||
object_type* o = static_cast<object_type*>(maybeo.value());
|
||||
return call(L, std::forward<Fx>(fx), *o);
|
||||
#else
|
||||
object_type& o = static_cast<object_type&>(*stack::unqualified_get<non_null<Ta*>>(L, 1));
|
||||
return call(L, std::forward<Fx>(fx), o);
|
||||
#endif // Safety
|
||||
}
|
||||
else {
|
||||
using returns_list = typename wrap::returns_list;
|
||||
using args_list = typename wrap::args_list;
|
||||
using caller = typename wrap::caller;
|
||||
return stack::call_into_lua<checked, clean_stack>(
|
||||
returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
else if constexpr (std::is_member_object_pointer_v<F>) {
|
||||
using wrap = wrapper<F>;
|
||||
using object_type = typename wrap::object_type;
|
||||
if constexpr (is_index) {
|
||||
if constexpr (sizeof...(Args) < 1) {
|
||||
using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
|
||||
static_assert(std::is_base_of_v<object_type, Ta>, "It seems like you might have accidentally bound a class type with a member function method that does not correspond to the class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one class \"T\" but then bind member methods from a complete unrelated class. Check things over!");
|
||||
#if defined(SOL_SAFE_USERTYPE) && SOL_SAFE_USERTYPE
|
||||
auto maybeo = stack::check_get<Ta*>(L, 1);
|
||||
if (!maybeo || maybeo.value() == nullptr) {
|
||||
if (is_variable) {
|
||||
return luaL_error(L, "sol: 'self' argument is lua_nil (bad '.' access?)");
|
||||
}
|
||||
return luaL_error(L, "sol: 'self' argument is lua_nil (pass 'self' as first argument)");
|
||||
}
|
||||
object_type* o = static_cast<object_type*>(maybeo.value());
|
||||
return call(L, std::forward<Fx>(fx), *o);
|
||||
#else
|
||||
object_type& o = static_cast<object_type&>(*stack::get<non_null<Ta*>>(L, 1));
|
||||
return call(L, std::forward<Fx>(fx), o);
|
||||
#endif // Safety
|
||||
}
|
||||
else {
|
||||
using returns_list = typename wrap::returns_list;
|
||||
using caller = typename wrap::caller;
|
||||
return stack::call_into_lua<checked, clean_stack>(returns_list(),
|
||||
types<>(),
|
||||
L,
|
||||
boost + (is_variable ? 3 : 2),
|
||||
caller(),
|
||||
std::forward<Fx>(fx),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
else {
|
||||
using traits_type = lua_bind_traits<F>;
|
||||
using return_type = typename traits_type::return_type;
|
||||
constexpr bool is_const = std::is_const_v<std::remove_reference_t<return_type>>;
|
||||
if constexpr (is_const) {
|
||||
(void)fx;
|
||||
(void)detail::swallow{ 0, (static_cast<void>(args), 0)... };
|
||||
return luaL_error(L, "sol: cannot write to a readonly (const) variable");
|
||||
}
|
||||
else {
|
||||
using u_return_type = meta::unqualified_t<return_type>;
|
||||
constexpr bool is_assignable = std::is_copy_assignable_v<u_return_type> || std::is_array_v<u_return_type>;
|
||||
if constexpr (!is_assignable) {
|
||||
(void)fx;
|
||||
(void)detail::swallow{ 0, ((void)args, 0)... };
|
||||
return luaL_error(L, "sol: cannot write to this variable: copy assignment/constructor not available");
|
||||
}
|
||||
else {
|
||||
using args_list = typename wrap::args_list;
|
||||
using caller = typename wrap::caller;
|
||||
if constexpr (sizeof...(Args) > 0) {
|
||||
return stack::call_into_lua<checked, clean_stack>(types<void>(),
|
||||
args_list(),
|
||||
L,
|
||||
boost + (is_variable ? 3 : 2),
|
||||
caller(),
|
||||
std::forward<Fx>(fx),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
|
||||
#if defined(SOL_SAFE_USERTYPE) && SOL_SAFE_USERTYPE
|
||||
auto maybeo = stack::check_get<Ta*>(L, 1);
|
||||
if (!maybeo || maybeo.value() == nullptr) {
|
||||
if (is_variable) {
|
||||
return luaL_error(L, "sol: received nil for 'self' argument (bad '.' access?)");
|
||||
}
|
||||
return luaL_error(L, "sol: received nil for 'self' argument (pass 'self' as first argument)");
|
||||
}
|
||||
object_type* po = static_cast<object_type*>(maybeo.value());
|
||||
object_type& o = *po;
|
||||
#else
|
||||
object_type& o = static_cast<object_type&>(*stack::get<non_null<Ta*>>(L, 1));
|
||||
#endif // Safety
|
||||
|
||||
return stack::call_into_lua<checked, clean_stack>(
|
||||
types<void>(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), std::forward<Fx>(fx), o);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
agnostic_lua_call_wrapper<F, is_index, is_variable, checked, boost, clean_stack> alcw{};
|
||||
return alcw.call(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename F, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, readonly_wrapper<F>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
using traits_type = lua_bind_traits<F>;
|
||||
using wrap = wrapper<F>;
|
||||
using object_type = typename wrap::object_type;
|
||||
|
||||
static int call(lua_State* L, readonly_wrapper<F>&& rw) {
|
||||
if constexpr (!is_index) {
|
||||
(void)rw;
|
||||
return luaL_error(L, "sol: cannot write to a sol::readonly variable");
|
||||
}
|
||||
else {
|
||||
lua_call_wrapper<T, F, true, is_variable, checked, boost, clean_stack, C> lcw;
|
||||
return lcw.call(L, std::move(rw.value()));
|
||||
}
|
||||
}
|
||||
|
||||
static int call(lua_State* L, readonly_wrapper<F>&& rw, object_type& o) {
|
||||
if constexpr (!is_index) {
|
||||
(void)o;
|
||||
return call(L, std::move(rw));
|
||||
}
|
||||
else {
|
||||
lua_call_wrapper<T, F, true, is_variable, checked, boost, clean_stack, C> lcw;
|
||||
return lcw.call(L, rw.value(), o);
|
||||
}
|
||||
}
|
||||
|
||||
static int call(lua_State* L, const readonly_wrapper<F>& rw) {
|
||||
if constexpr (!is_index) {
|
||||
(void)rw;
|
||||
return luaL_error(L, "sol: cannot write to a sol::readonly variable");
|
||||
}
|
||||
else {
|
||||
lua_call_wrapper<T, F, true, is_variable, checked, boost, clean_stack, C> lcw;
|
||||
return lcw.call(L, rw.value());
|
||||
}
|
||||
}
|
||||
|
||||
static int call(lua_State* L, const readonly_wrapper<F>& rw, object_type& o) {
|
||||
if constexpr (!is_index) {
|
||||
(void)o;
|
||||
return call(L, rw);
|
||||
}
|
||||
else {
|
||||
lua_call_wrapper<T, F, true, is_variable, checked, boost, clean_stack, C> lcw;
|
||||
return lcw.call(L, rw.value(), o);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Args, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, constructor_list<Args...>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
typedef constructor_list<Args...> F;
|
||||
|
||||
static int call(lua_State* L, F&) {
|
||||
const auto& meta = usertype_traits<T>::metatable();
|
||||
int argcount = lua_gettop(L);
|
||||
call_syntax syntax = argcount > 0 ? stack::get_call_syntax(L, usertype_traits<T>::user_metatable(), 1) : call_syntax::dot;
|
||||
argcount -= static_cast<int>(syntax);
|
||||
|
||||
T* obj = detail::usertype_allocate<T>(L);
|
||||
reference userdataref(L, -1);
|
||||
stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
|
||||
umf();
|
||||
|
||||
// put userdata at the first index
|
||||
lua_insert(L, 1);
|
||||
construct_match<T, Args...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, boost + 1 + 1 + static_cast<int>(syntax));
|
||||
|
||||
userdataref.push();
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Cxs, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, constructor_wrapper<Cxs...>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
typedef constructor_wrapper<Cxs...> F;
|
||||
|
||||
struct onmatch {
|
||||
template <typename Fx, std::size_t I, typename... R, typename... Args>
|
||||
int operator()(types<Fx>, meta::index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start, F& f) {
|
||||
const auto& meta = usertype_traits<T>::metatable();
|
||||
T* obj = detail::usertype_allocate<T>(L);
|
||||
reference userdataref(L, -1);
|
||||
stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
|
||||
umf();
|
||||
|
||||
auto& func = std::get<I>(f.functions);
|
||||
// put userdata at the first index
|
||||
lua_insert(L, 1);
|
||||
stack::call_into_lua<checked, clean_stack>(r, a, L, boost + 1 + start, func, detail::implicit_wrapper<T>(obj));
|
||||
|
||||
userdataref.push();
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
static int call(lua_State* L, F& f) {
|
||||
call_syntax syntax = stack::get_call_syntax(L, usertype_traits<T>::user_metatable(), 1);
|
||||
int syntaxval = static_cast<int>(syntax);
|
||||
int argcount = lua_gettop(L) - syntaxval;
|
||||
return construct_match<T, meta::pop_front_type_t<meta::function_args_t<Cxs>>...>(onmatch(), L, argcount, 1 + syntaxval, f);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, destructor_wrapper<Fx>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
|
||||
template <typename F>
|
||||
static int call(lua_State* L, F&& f) {
|
||||
if constexpr (std::is_void_v<Fx>) {
|
||||
return detail::usertype_alloc_destruct<T>(L);
|
||||
}
|
||||
else {
|
||||
using uFx = meta::unqualified_t<Fx>;
|
||||
lua_call_wrapper<T, uFx, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
||||
return lcw.call(L, std::forward<F>(f).fx);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, overload_set<Fs...>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
typedef overload_set<Fs...> F;
|
||||
|
||||
struct on_match {
|
||||
template <typename Fx, std::size_t I, typename... R, typename... Args>
|
||||
int operator()(types<Fx>, meta::index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int, F& fx) {
|
||||
auto& f = std::get<I>(fx.functions);
|
||||
return lua_call_wrapper<T, Fx, is_index, is_variable, checked, boost>{}.call(L, f);
|
||||
}
|
||||
};
|
||||
|
||||
static int call(lua_State* L, F& fx) {
|
||||
return overload_match_arity<Fs...>(on_match(), L, lua_gettop(L), 1, fx);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, factory_wrapper<Fs...>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
typedef factory_wrapper<Fs...> F;
|
||||
|
||||
struct on_match {
|
||||
template <typename Fx, std::size_t I, typename... R, typename... Args>
|
||||
int operator()(types<Fx>, meta::index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int, F& fx) {
|
||||
auto& f = std::get<I>(fx.functions);
|
||||
return lua_call_wrapper<T, Fx, is_index, is_variable, checked, boost, clean_stack>{}.call(L, f);
|
||||
}
|
||||
};
|
||||
|
||||
static int call(lua_State* L, F& fx) {
|
||||
return overload_match_arity<Fs...>(on_match(), L, lua_gettop(L) - boost, 1 + boost, fx);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename W, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, property_wrapper<R, W>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
typedef meta::conditional_t<is_index, R, W> P;
|
||||
typedef meta::unqualified_t<P> U;
|
||||
typedef wrapper<U> wrap;
|
||||
typedef lua_bind_traits<U> traits_type;
|
||||
typedef meta::unqualified_t<typename traits_type::template arg_at<0>> object_type;
|
||||
|
||||
template <typename F, typename... Args>
|
||||
static int call(lua_State* L, F&& f, Args&&... args) {
|
||||
constexpr bool is_specialized = meta::any<std::is_same<U, detail::no_prop>,
|
||||
meta::is_specialization_of<U, var_wrapper>,
|
||||
meta::is_specialization_of<U, constructor_wrapper>,
|
||||
meta::is_specialization_of<U, constructor_list>,
|
||||
std::is_member_pointer<U>>::value;
|
||||
if constexpr (is_specialized) {
|
||||
if constexpr (is_index) {
|
||||
decltype(auto) p = f.read();
|
||||
lua_call_wrapper<T, meta::unqualified_t<decltype(p)>, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
||||
return lcw.call(L, p, std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
decltype(auto) p = f.write();
|
||||
lua_call_wrapper<T, meta::unqualified_t<decltype(p)>, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
||||
return lcw.call(L, p, std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
else {
|
||||
constexpr bool non_class_object_type = meta::any<std::is_void<object_type>,
|
||||
meta::boolean<lua_type_of<meta::unwrap_unqualified_t<object_type>>::value != type::userdata>>::value;
|
||||
if constexpr (non_class_object_type) {
|
||||
// The type being void means we don't have any arguments, so it might be a free functions?
|
||||
using args_list = typename traits_type::free_args_list;
|
||||
using returns_list = typename wrap::returns_list;
|
||||
using caller = typename wrap::caller;
|
||||
if constexpr (is_index) {
|
||||
decltype(auto) pf = f.read();
|
||||
return stack::call_into_lua<checked, clean_stack>(
|
||||
returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), pf);
|
||||
}
|
||||
else {
|
||||
decltype(auto) pf = f.write();
|
||||
return stack::call_into_lua<checked, clean_stack>(
|
||||
returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), pf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
using args_list = meta::pop_front_type_t<typename traits_type::free_args_list>;
|
||||
using Ta = T;
|
||||
using Oa = std::remove_pointer_t<object_type>;
|
||||
#if defined(SOL_SAFE_USERTYPE) && SOL_SAFE_USERTYPE
|
||||
auto maybeo = stack::check_get<Ta*>(L, 1);
|
||||
if (!maybeo || maybeo.value() == nullptr) {
|
||||
if (is_variable) {
|
||||
return luaL_error(L, "sol: 'self' argument is lua_nil (bad '.' access?)");
|
||||
}
|
||||
return luaL_error(L, "sol: 'self' argument is lua_nil (pass 'self' as first argument)");
|
||||
}
|
||||
Oa* o = static_cast<Oa*>(maybeo.value());
|
||||
#else
|
||||
Oa* o = static_cast<Oa*>(stack::get<non_null<Ta*>>(L, 1));
|
||||
#endif // Safety
|
||||
using returns_list = typename wrap::returns_list;
|
||||
using caller = typename wrap::caller;
|
||||
if constexpr (is_index) {
|
||||
decltype(auto) pf = f.read();
|
||||
return stack::call_into_lua<checked, clean_stack>(
|
||||
returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), pf, detail::implicit_wrapper<Oa>(*o));
|
||||
}
|
||||
else {
|
||||
decltype(auto) pf = f.write();
|
||||
return stack::call_into_lua<checked, clean_stack>(
|
||||
returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), pf, detail::implicit_wrapper<Oa>(*o));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename V, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, protect_t<V>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
typedef protect_t<V> F;
|
||||
|
||||
template <typename... Args>
|
||||
static int call(lua_State* L, F& fx, Args&&... args) {
|
||||
return lua_call_wrapper<T, V, is_index, is_variable, true, boost, clean_stack>{}.call(L, fx.value, std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename F, typename... Policies, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, policy_wrapper<F, Policies...>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
typedef policy_wrapper<F, Policies...> P;
|
||||
|
||||
template <std::size_t... In>
|
||||
static int call(std::index_sequence<In...>, lua_State* L, P& fx) {
|
||||
int pushed = lua_call_wrapper<T, F, is_index, is_variable, checked, boost, false, C>{}.call(L, fx.value);
|
||||
(void)detail::swallow{ int(), (policy_detail::handle_policy(std::get<In>(fx.policies), L, pushed), int())... };
|
||||
return pushed;
|
||||
}
|
||||
|
||||
static int call(lua_State* L, P& fx) {
|
||||
typedef typename P::indices indices;
|
||||
return call(indices(), L, fx);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Y, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, yielding_t<Y>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
template <typename F>
|
||||
static int call(lua_State* L, F&& f) {
|
||||
return lua_call_wrapper<T, meta::unqualified_t<Y>, is_index, is_variable, checked, boost, clean_stack>{}.call(L, f.func);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Sig, typename P, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||
struct lua_call_wrapper<T, function_arguments<Sig, P>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||
static int call(lua_State* L, const function_arguments<Sig, P>& f) {
|
||||
lua_call_wrapper<T, meta::unqualified_t<P>, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
||||
return lcw.call(L, std::get<0>(f.arguments));
|
||||
}
|
||||
|
||||
static int call(lua_State* L, function_arguments<Sig, P>&& f) {
|
||||
lua_call_wrapper<T, meta::unqualified_t<P>, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
||||
return lcw.call(L, std::get<0>(std::move(f.arguments)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool is_index, bool is_variable, int boost = 0, bool checked = detail::default_safe_function_calls, bool clean_stack = true,
|
||||
typename Fx, typename... Args>
|
||||
inline int call_wrapped(lua_State* L, Fx&& fx, Args&&... args) {
|
||||
using uFx = meta::unqualified_t<Fx>;
|
||||
if constexpr (meta::is_specialization_of_v<uFx, yielding_t>) {
|
||||
using real_fx = meta::unqualified_t<decltype(std::forward<Fx>(fx).func)>;
|
||||
lua_call_wrapper<T, real_fx, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
||||
return lcw.call(L, std::forward<Fx>(fx).func, std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
lua_call_wrapper<T, uFx, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
||||
return lcw.call(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, bool is_index, bool is_variable, typename F, int start = 1, bool checked = detail::default_safe_function_calls,
|
||||
bool clean_stack = true>
|
||||
inline int call_user(lua_State* L) {
|
||||
auto& fx = stack::unqualified_get<user<F>>(L, upvalue_index(start));
|
||||
using uFx = meta::unqualified_t<F>;
|
||||
int nr = call_wrapped<T, is_index, is_variable, 0, checked, clean_stack>(L, fx);
|
||||
if constexpr (meta::is_specialization_of_v<uFx, yielding_t>) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct is_var_bind : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_var_bind<T, std::enable_if_t<std::is_member_object_pointer<T>::value>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_var_bind<T, std::enable_if_t<is_lua_reference_or_proxy<T>::value>> : std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_var_bind<detail::no_prop> : std::true_type {};
|
||||
|
||||
template <typename R, typename W>
|
||||
struct is_var_bind<property_wrapper<R, W>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_var_bind<var_wrapper<T>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_var_bind<readonly_wrapper<T>> : is_var_bind<meta::unqualified_t<T>> {};
|
||||
|
||||
template <typename F, typename... Policies>
|
||||
struct is_var_bind<policy_wrapper<F, Policies...>> : is_var_bind<meta::unqualified_t<F>> {};
|
||||
} // namespace call_detail
|
||||
|
||||
template <typename T>
|
||||
struct is_variable_binding : call_detail::is_var_bind<meta::unqualified_t<T>> {};
|
||||
|
||||
template <typename T>
|
||||
using is_var_wrapper = meta::is_specialization_of<T, var_wrapper>;
|
||||
|
||||
template <typename T>
|
||||
struct is_function_binding : meta::neg<is_variable_binding<T>> {};
|
||||
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_CALL_HPP
|
|
@ -1,52 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_COMPATIBILITY_HPP
|
||||
#define SOL_COMPATIBILITY_HPP
|
||||
|
||||
// The various pieces of the compatibility layer
|
||||
// comes from https://github.com/keplerproject/lua-compat-5.3
|
||||
// but has been modified in many places for use with sol and luajit,
|
||||
// though the core abstractions remain the same
|
||||
|
||||
#include "feature_test.hpp"
|
||||
#include "compatibility/lua_version.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
#if !defined(SOL_NO_COMPAT) || !(SOL_NO_COMPAT)
|
||||
|
||||
#if defined(SOL_USING_CXX_LUA) && SOL_USING_CXX_LUA
|
||||
#ifndef COMPAT53_LUA_CPP
|
||||
#define COMPAT53_LUA_CPP 1
|
||||
#endif // Build Lua Compat layer as C++
|
||||
#endif
|
||||
#ifndef COMPAT53_INCLUDE_SOURCE
|
||||
#define COMPAT53_INCLUDE_SOURCE 1
|
||||
#endif // Build Compat Layer Inline
|
||||
|
||||
#include "compatibility/compat-5.3.h"
|
||||
#include "compatibility/compat-5.4.h"
|
||||
|
||||
#endif // SOL_NO_COMPAT
|
||||
|
||||
#endif // SOL_COMPATIBILITY_HPP
|
|
@ -1,890 +0,0 @@
|
|||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include "compat-5.3.h"
|
||||
|
||||
/* don't compile it again if it already is included via compat53.h */
|
||||
#ifndef KEPLER_PROJECT_COMPAT53_C_
|
||||
#define KEPLER_PROJECT_COMPAT53_C_
|
||||
|
||||
|
||||
|
||||
/* definitions for Lua 5.1 only */
|
||||
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
|
||||
|
||||
#ifndef COMPAT53_FOPEN_NO_LOCK
|
||||
# if defined(_MSC_VER)
|
||||
# define COMPAT53_FOPEN_NO_LOCK 1
|
||||
# else /* otherwise */
|
||||
# define COMPAT53_FOPEN_NO_LOCK 0
|
||||
# endif /* VC++ only so far */
|
||||
#endif /* No-lock fopen_s usage if possible */
|
||||
|
||||
#if defined(_MSC_VER) && COMPAT53_FOPEN_NO_LOCK
|
||||
# include <share.h>
|
||||
#endif /* VC++ _fsopen for share-allowed file read */
|
||||
|
||||
#ifndef COMPAT53_HAVE_STRERROR_R
|
||||
# if defined(__GLIBC__) || defined(_POSIX_VERSION) || defined(__APPLE__) || \
|
||||
(!defined (__MINGW32__) && defined(__GNUC__) && (__GNUC__ < 6))
|
||||
# define COMPAT53_HAVE_STRERROR_R 1
|
||||
# else /* none of the defines matched: define to 0 */
|
||||
# define COMPAT53_HAVE_STRERROR_R 0
|
||||
# endif /* have strerror_r of some form */
|
||||
#endif /* strerror_r */
|
||||
|
||||
#ifndef COMPAT53_HAVE_STRERROR_S
|
||||
# if defined(_MSC_VER) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
|
||||
(defined(__STDC_LIB_EXT1__) && __STDC_LIB_EXT1__)
|
||||
# define COMPAT53_HAVE_STRERROR_S 1
|
||||
# else /* not VC++ or C11 */
|
||||
# define COMPAT53_HAVE_STRERROR_S 0
|
||||
# endif /* strerror_s from VC++ or C11 */
|
||||
#endif /* strerror_s */
|
||||
|
||||
#ifndef COMPAT53_LUA_FILE_BUFFER_SIZE
|
||||
# define COMPAT53_LUA_FILE_BUFFER_SIZE 4096
|
||||
#endif /* Lua File Buffer Size */
|
||||
|
||||
|
||||
static char* compat53_strerror(int en, char* buff, size_t sz) {
|
||||
#if COMPAT53_HAVE_STRERROR_R
|
||||
/* use strerror_r here, because it's available on these specific platforms */
|
||||
if (sz > 0) {
|
||||
buff[0] = '\0';
|
||||
/* we don't care whether the GNU version or the XSI version is used: */
|
||||
if (strerror_r(en, buff, sz)) {
|
||||
/* Yes, we really DO want to ignore the return value!
|
||||
* GCC makes that extra hard, not even a (void) cast will do. */
|
||||
}
|
||||
if (buff[0] == '\0') {
|
||||
/* Buffer is unchanged, so we probably have called GNU strerror_r which
|
||||
* returned a static constant string. Chances are that strerror will
|
||||
* return the same static constant string and therefore be thread-safe. */
|
||||
return strerror(en);
|
||||
}
|
||||
}
|
||||
return buff; /* sz is 0 *or* strerror_r wrote into the buffer */
|
||||
#elif COMPAT53_HAVE_STRERROR_S
|
||||
/* for MSVC and other C11 implementations, use strerror_s since it's
|
||||
* provided by default by the libraries */
|
||||
strerror_s(buff, sz, en);
|
||||
return buff;
|
||||
#else
|
||||
/* fallback, but strerror is not guaranteed to be threadsafe due to modifying
|
||||
* errno itself and some impls not locking a static buffer for it ... but most
|
||||
* known systems have threadsafe errno: this might only change if the locale
|
||||
* is changed out from under someone while this function is being called */
|
||||
(void)buff;
|
||||
(void)sz;
|
||||
return strerror(en);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API int lua_absindex(lua_State *L, int i) {
|
||||
if (i < 0 && i > LUA_REGISTRYINDEX)
|
||||
i += lua_gettop(L) + 1;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
static void compat53_call_lua(lua_State *L, char const code[], size_t len,
|
||||
int nargs, int nret) {
|
||||
lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)code);
|
||||
if (lua_type(L, -1) != LUA_TFUNCTION) {
|
||||
lua_pop(L, 1);
|
||||
if (luaL_loadbuffer(L, code, len, "=none"))
|
||||
lua_error(L);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawsetp(L, LUA_REGISTRYINDEX, (void*)code);
|
||||
}
|
||||
lua_insert(L, -nargs - 1);
|
||||
lua_call(L, nargs, nret);
|
||||
}
|
||||
|
||||
|
||||
static const char compat53_arith_code[] =
|
||||
"local op,a,b=...\n"
|
||||
"if op==0 then return a+b\n"
|
||||
"elseif op==1 then return a-b\n"
|
||||
"elseif op==2 then return a*b\n"
|
||||
"elseif op==3 then return a/b\n"
|
||||
"elseif op==4 then return a%b\n"
|
||||
"elseif op==5 then return a^b\n"
|
||||
"elseif op==6 then return -a\n"
|
||||
"end\n";
|
||||
|
||||
COMPAT53_API void lua_arith(lua_State *L, int op) {
|
||||
if (op < LUA_OPADD || op > LUA_OPUNM)
|
||||
luaL_error(L, "invalid 'op' argument for lua_arith");
|
||||
luaL_checkstack(L, 5, "not enough stack slots");
|
||||
if (op == LUA_OPUNM)
|
||||
lua_pushvalue(L, -1);
|
||||
lua_pushnumber(L, op);
|
||||
lua_insert(L, -3);
|
||||
compat53_call_lua(L, compat53_arith_code,
|
||||
sizeof(compat53_arith_code) - 1, 3, 1);
|
||||
}
|
||||
|
||||
|
||||
static const char compat53_compare_code[] =
|
||||
"local a,b=...\n"
|
||||
"return a<=b\n";
|
||||
|
||||
COMPAT53_API int lua_compare(lua_State *L, int idx1, int idx2, int op) {
|
||||
int result = 0;
|
||||
switch (op) {
|
||||
case LUA_OPEQ:
|
||||
return lua_equal(L, idx1, idx2);
|
||||
case LUA_OPLT:
|
||||
return lua_lessthan(L, idx1, idx2);
|
||||
case LUA_OPLE:
|
||||
luaL_checkstack(L, 5, "not enough stack slots");
|
||||
idx1 = lua_absindex(L, idx1);
|
||||
idx2 = lua_absindex(L, idx2);
|
||||
lua_pushvalue(L, idx1);
|
||||
lua_pushvalue(L, idx2);
|
||||
compat53_call_lua(L, compat53_compare_code,
|
||||
sizeof(compat53_compare_code) - 1, 2, 1);
|
||||
result = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return result;
|
||||
default:
|
||||
luaL_error(L, "invalid 'op' argument for lua_compare");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API void lua_copy(lua_State *L, int from, int to) {
|
||||
int abs_to = lua_absindex(L, to);
|
||||
luaL_checkstack(L, 1, "not enough stack slots");
|
||||
lua_pushvalue(L, from);
|
||||
lua_replace(L, abs_to);
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API void lua_len(lua_State *L, int i) {
|
||||
switch (lua_type(L, i)) {
|
||||
case LUA_TSTRING:
|
||||
lua_pushnumber(L, (lua_Number)lua_objlen(L, i));
|
||||
break;
|
||||
case LUA_TTABLE:
|
||||
if (!luaL_callmeta(L, i, "__len"))
|
||||
lua_pushnumber(L, (lua_Number)lua_objlen(L, i));
|
||||
break;
|
||||
case LUA_TUSERDATA:
|
||||
if (luaL_callmeta(L, i, "__len"))
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
luaL_error(L, "attempt to get length of a %s value",
|
||||
lua_typename(L, lua_type(L, i)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API int lua_rawgetp(lua_State *L, int i, const void *p) {
|
||||
int abs_i = lua_absindex(L, i);
|
||||
lua_pushlightuserdata(L, (void*)p);
|
||||
lua_rawget(L, abs_i);
|
||||
return lua_type(L, -1);
|
||||
}
|
||||
|
||||
COMPAT53_API void lua_rawsetp(lua_State *L, int i, const void *p) {
|
||||
int abs_i = lua_absindex(L, i);
|
||||
luaL_checkstack(L, 1, "not enough stack slots");
|
||||
lua_pushlightuserdata(L, (void*)p);
|
||||
lua_insert(L, -2);
|
||||
lua_rawset(L, abs_i);
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API lua_Number lua_tonumberx(lua_State *L, int i, int *isnum) {
|
||||
lua_Number n = lua_tonumber(L, i);
|
||||
if (isnum != NULL) {
|
||||
*isnum = (n != 0 || lua_isnumber(L, i));
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API void luaL_checkversion(lua_State *L) {
|
||||
(void)L;
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API void luaL_checkstack(lua_State *L, int sp, const char *msg) {
|
||||
if (!lua_checkstack(L, sp + LUA_MINSTACK)) {
|
||||
if (msg != NULL)
|
||||
luaL_error(L, "stack overflow (%s)", msg);
|
||||
else {
|
||||
lua_pushliteral(L, "stack overflow");
|
||||
lua_error(L);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API int luaL_getsubtable(lua_State *L, int i, const char *name) {
|
||||
int abs_i = lua_absindex(L, i);
|
||||
luaL_checkstack(L, 3, "not enough stack slots");
|
||||
lua_pushstring(L, name);
|
||||
lua_gettable(L, abs_i);
|
||||
if (lua_istable(L, -1))
|
||||
return 1;
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, name);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_settable(L, abs_i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API lua_Integer luaL_len(lua_State *L, int i) {
|
||||
lua_Integer res = 0;
|
||||
int isnum = 0;
|
||||
luaL_checkstack(L, 1, "not enough stack slots");
|
||||
lua_len(L, i);
|
||||
res = lua_tointegerx(L, -1, &isnum);
|
||||
lua_pop(L, 1);
|
||||
if (!isnum)
|
||||
luaL_error(L, "object length is not an integer");
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) {
|
||||
luaL_checkstack(L, nup + 1, "too many upvalues");
|
||||
for (; l->name != NULL; l++) { /* fill the table with given functions */
|
||||
int i;
|
||||
lua_pushstring(L, l->name);
|
||||
for (i = 0; i < nup; i++) /* copy upvalues to the top */
|
||||
lua_pushvalue(L, -(nup + 1));
|
||||
lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
|
||||
lua_settable(L, -(nup + 3)); /* table must be below the upvalues, the name and the closure */
|
||||
}
|
||||
lua_pop(L, nup); /* remove upvalues */
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API void luaL_setmetatable(lua_State *L, const char *tname) {
|
||||
luaL_checkstack(L, 1, "not enough stack slots");
|
||||
luaL_getmetatable(L, tname);
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API void *luaL_testudata(lua_State *L, int i, const char *tname) {
|
||||
void *p = lua_touserdata(L, i);
|
||||
luaL_checkstack(L, 2, "not enough stack slots");
|
||||
if (p == NULL || !lua_getmetatable(L, i))
|
||||
return NULL;
|
||||
else {
|
||||
int res = 0;
|
||||
luaL_getmetatable(L, tname);
|
||||
res = lua_rawequal(L, -1, -2);
|
||||
lua_pop(L, 2);
|
||||
if (!res)
|
||||
p = NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
static int compat53_countlevels(lua_State *L) {
|
||||
lua_Debug ar;
|
||||
int li = 1, le = 1;
|
||||
/* find an upper bound */
|
||||
while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
|
||||
/* do a binary search */
|
||||
while (li < le) {
|
||||
int m = (li + le) / 2;
|
||||
if (lua_getstack(L, m, &ar)) li = m + 1;
|
||||
else le = m;
|
||||
}
|
||||
return le - 1;
|
||||
}
|
||||
|
||||
static int compat53_findfield(lua_State *L, int objidx, int level) {
|
||||
if (level == 0 || !lua_istable(L, -1))
|
||||
return 0; /* not found */
|
||||
lua_pushnil(L); /* start 'next' loop */
|
||||
while (lua_next(L, -2)) { /* for each pair in table */
|
||||
if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */
|
||||
if (lua_rawequal(L, objidx, -1)) { /* found object? */
|
||||
lua_pop(L, 1); /* remove value (but keep name) */
|
||||
return 1;
|
||||
}
|
||||
else if (compat53_findfield(L, objidx, level - 1)) { /* try recursively */
|
||||
lua_remove(L, -2); /* remove table (but keep name) */
|
||||
lua_pushliteral(L, ".");
|
||||
lua_insert(L, -2); /* place '.' between the two names */
|
||||
lua_concat(L, 3);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1); /* remove value */
|
||||
}
|
||||
return 0; /* not found */
|
||||
}
|
||||
|
||||
static int compat53_pushglobalfuncname(lua_State *L, lua_Debug *ar) {
|
||||
int top = lua_gettop(L);
|
||||
lua_getinfo(L, "f", ar); /* push function */
|
||||
lua_pushvalue(L, LUA_GLOBALSINDEX);
|
||||
if (compat53_findfield(L, top + 1, 2)) {
|
||||
lua_copy(L, -1, top + 1); /* move name to proper place */
|
||||
lua_pop(L, 2); /* remove pushed values */
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
lua_settop(L, top); /* remove function and global table */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void compat53_pushfuncname(lua_State *L, lua_Debug *ar) {
|
||||
if (*ar->namewhat != '\0') /* is there a name? */
|
||||
lua_pushfstring(L, "function " LUA_QS, ar->name);
|
||||
else if (*ar->what == 'm') /* main? */
|
||||
lua_pushliteral(L, "main chunk");
|
||||
else if (*ar->what == 'C') {
|
||||
if (compat53_pushglobalfuncname(L, ar)) {
|
||||
lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
|
||||
lua_remove(L, -2); /* remove name */
|
||||
}
|
||||
else
|
||||
lua_pushliteral(L, "?");
|
||||
}
|
||||
else
|
||||
lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
|
||||
}
|
||||
|
||||
#define COMPAT53_LEVELS1 12 /* size of the first part of the stack */
|
||||
#define COMPAT53_LEVELS2 10 /* size of the second part of the stack */
|
||||
|
||||
COMPAT53_API void luaL_traceback(lua_State *L, lua_State *L1,
|
||||
const char *msg, int level) {
|
||||
lua_Debug ar;
|
||||
int top = lua_gettop(L);
|
||||
int numlevels = compat53_countlevels(L1);
|
||||
int mark = (numlevels > COMPAT53_LEVELS1 + COMPAT53_LEVELS2) ? COMPAT53_LEVELS1 : 0;
|
||||
if (msg) lua_pushfstring(L, "%s\n", msg);
|
||||
lua_pushliteral(L, "stack traceback:");
|
||||
while (lua_getstack(L1, level++, &ar)) {
|
||||
if (level == mark) { /* too many levels? */
|
||||
lua_pushliteral(L, "\n\t..."); /* add a '...' */
|
||||
level = numlevels - COMPAT53_LEVELS2; /* and skip to last ones */
|
||||
}
|
||||
else {
|
||||
lua_getinfo(L1, "Slnt", &ar);
|
||||
lua_pushfstring(L, "\n\t%s:", ar.short_src);
|
||||
if (ar.currentline > 0)
|
||||
lua_pushfstring(L, "%d:", ar.currentline);
|
||||
lua_pushliteral(L, " in ");
|
||||
compat53_pushfuncname(L, &ar);
|
||||
lua_concat(L, lua_gettop(L) - top);
|
||||
}
|
||||
}
|
||||
lua_concat(L, lua_gettop(L) - top);
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API int luaL_fileresult(lua_State *L, int stat, const char *fname) {
|
||||
const char *serr = NULL;
|
||||
int en = errno; /* calls to Lua API may change this value */
|
||||
char buf[512] = { 0 };
|
||||
if (stat) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
serr = compat53_strerror(en, buf, sizeof(buf));
|
||||
if (fname)
|
||||
lua_pushfstring(L, "%s: %s", fname, serr);
|
||||
else
|
||||
lua_pushstring(L, serr);
|
||||
lua_pushnumber(L, (lua_Number)en);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int compat53_checkmode(lua_State *L, const char *mode, const char *modename, int err) {
|
||||
if (mode && strchr(mode, modename[0]) == NULL) {
|
||||
lua_pushfstring(L, "attempt to load a %s chunk (mode is '%s')", modename, mode);
|
||||
return err;
|
||||
}
|
||||
return LUA_OK;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
lua_Reader reader;
|
||||
void *ud;
|
||||
int has_peeked_data;
|
||||
const char *peeked_data;
|
||||
size_t peeked_data_size;
|
||||
} compat53_reader_data;
|
||||
|
||||
|
||||
static const char *compat53_reader(lua_State *L, void *ud, size_t *size) {
|
||||
compat53_reader_data *data = (compat53_reader_data *)ud;
|
||||
if (data->has_peeked_data) {
|
||||
data->has_peeked_data = 0;
|
||||
*size = data->peeked_data_size;
|
||||
return data->peeked_data;
|
||||
}
|
||||
else
|
||||
return data->reader(L, data->ud, size);
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API int lua_load(lua_State *L, lua_Reader reader, void *data, const char *source, const char *mode) {
|
||||
int status = LUA_OK;
|
||||
compat53_reader_data compat53_data = { reader, data, 1, 0, 0 };
|
||||
compat53_data.peeked_data = reader(L, data, &(compat53_data.peeked_data_size));
|
||||
if (compat53_data.peeked_data && compat53_data.peeked_data_size &&
|
||||
compat53_data.peeked_data[0] == LUA_SIGNATURE[0]) /* binary file? */
|
||||
status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX);
|
||||
else
|
||||
status = compat53_checkmode(L, mode, "text", LUA_ERRSYNTAX);
|
||||
if (status != LUA_OK)
|
||||
return status;
|
||||
/* we need to call the original 5.1 version of lua_load! */
|
||||
#undef lua_load
|
||||
return lua_load(L, compat53_reader, &compat53_data, source);
|
||||
#define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
int n; /* number of pre-read characters */
|
||||
FILE *f; /* file being read */
|
||||
char buff[COMPAT53_LUA_FILE_BUFFER_SIZE]; /* area for reading file */
|
||||
} compat53_LoadF;
|
||||
|
||||
|
||||
static const char *compat53_getF(lua_State *L, void *ud, size_t *size) {
|
||||
compat53_LoadF *lf = (compat53_LoadF *)ud;
|
||||
(void)L; /* not used */
|
||||
if (lf->n > 0) { /* are there pre-read characters to be read? */
|
||||
*size = lf->n; /* return them (chars already in buffer) */
|
||||
lf->n = 0; /* no more pre-read characters */
|
||||
}
|
||||
else { /* read a block from file */
|
||||
/* 'fread' can return > 0 *and* set the EOF flag. If next call to
|
||||
'compat53_getF' called 'fread', it might still wait for user input.
|
||||
The next check avoids this problem. */
|
||||
if (feof(lf->f)) return NULL;
|
||||
*size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */
|
||||
}
|
||||
return lf->buff;
|
||||
}
|
||||
|
||||
|
||||
static int compat53_errfile(lua_State *L, const char *what, int fnameindex) {
|
||||
char buf[512] = { 0 };
|
||||
const char *serr = compat53_strerror(errno, buf, sizeof(buf));
|
||||
const char *filename = lua_tostring(L, fnameindex) + 1;
|
||||
lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
|
||||
lua_remove(L, fnameindex);
|
||||
return LUA_ERRFILE;
|
||||
}
|
||||
|
||||
|
||||
static int compat53_skipBOM(compat53_LoadF *lf) {
|
||||
const char *p = "\xEF\xBB\xBF"; /* UTF-8 BOM mark */
|
||||
int c;
|
||||
lf->n = 0;
|
||||
do {
|
||||
c = getc(lf->f);
|
||||
if (c == EOF || c != *(const unsigned char *)p++) return c;
|
||||
lf->buff[lf->n++] = (char)c; /* to be read by the parser */
|
||||
} while (*p != '\0');
|
||||
lf->n = 0; /* prefix matched; discard it */
|
||||
return getc(lf->f); /* return next character */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** reads the first character of file 'f' and skips an optional BOM mark
|
||||
** in its beginning plus its first line if it starts with '#'. Returns
|
||||
** true if it skipped the first line. In any case, '*cp' has the
|
||||
** first "valid" character of the file (after the optional BOM and
|
||||
** a first-line comment).
|
||||
*/
|
||||
static int compat53_skipcomment(compat53_LoadF *lf, int *cp) {
|
||||
int c = *cp = compat53_skipBOM(lf);
|
||||
if (c == '#') { /* first line is a comment (Unix exec. file)? */
|
||||
do { /* skip first line */
|
||||
c = getc(lf->f);
|
||||
} while (c != EOF && c != '\n');
|
||||
*cp = getc(lf->f); /* skip end-of-line, if present */
|
||||
return 1; /* there was a comment */
|
||||
}
|
||||
else return 0; /* no comment */
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API int luaL_loadfilex(lua_State *L, const char *filename, const char *mode) {
|
||||
compat53_LoadF lf;
|
||||
int status, readstatus;
|
||||
int c;
|
||||
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
|
||||
if (filename == NULL) {
|
||||
lua_pushliteral(L, "=stdin");
|
||||
lf.f = stdin;
|
||||
}
|
||||
else {
|
||||
lua_pushfstring(L, "@%s", filename);
|
||||
#if defined(_MSC_VER)
|
||||
/* This code is here to stop a deprecation error that stops builds
|
||||
* if a certain macro is defined. While normally not caring would
|
||||
* be best, some header-only libraries and builds can't afford to
|
||||
* dictate this to the user. A quick check shows that fopen_s this
|
||||
* goes back to VS 2005, and _fsopen goes back to VS 2003 .NET,
|
||||
* possibly even before that so we don't need to do any version
|
||||
* number checks, since this has been there since forever. */
|
||||
|
||||
/* TO USER: if you want the behavior of typical fopen_s/fopen,
|
||||
* which does lock the file on VC++, define the macro used below to 0 */
|
||||
#if COMPAT53_FOPEN_NO_LOCK
|
||||
lf.f = _fsopen(filename, "r", _SH_DENYNO); /* do not lock the file in any way */
|
||||
if (lf.f == NULL)
|
||||
return compat53_errfile(L, "open", fnameindex);
|
||||
#else /* use default locking version */
|
||||
if (fopen_s(&lf.f, filename, "r") != 0)
|
||||
return compat53_errfile(L, "open", fnameindex);
|
||||
#endif /* Locking vs. No-locking fopen variants */
|
||||
#else
|
||||
lf.f = fopen(filename, "r"); /* default stdlib doesn't forcefully lock files here */
|
||||
if (lf.f == NULL) return compat53_errfile(L, "open", fnameindex);
|
||||
#endif
|
||||
}
|
||||
if (compat53_skipcomment(&lf, &c)) /* read initial portion */
|
||||
lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */
|
||||
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
|
||||
#if defined(_MSC_VER)
|
||||
if (freopen_s(&lf.f, filename, "rb", lf.f) != 0)
|
||||
return compat53_errfile(L, "reopen", fnameindex);
|
||||
#else
|
||||
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
|
||||
if (lf.f == NULL) return compat53_errfile(L, "reopen", fnameindex);
|
||||
#endif
|
||||
compat53_skipcomment(&lf, &c); /* re-read initial portion */
|
||||
}
|
||||
if (c != EOF)
|
||||
lf.buff[lf.n++] = (char)c; /* 'c' is the first character of the stream */
|
||||
status = lua_load(L, &compat53_getF, &lf, lua_tostring(L, -1), mode);
|
||||
readstatus = ferror(lf.f);
|
||||
if (filename) fclose(lf.f); /* close file (even in case of errors) */
|
||||
if (readstatus) {
|
||||
lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
|
||||
return compat53_errfile(L, "read", fnameindex);
|
||||
}
|
||||
lua_remove(L, fnameindex);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API int luaL_loadbufferx(lua_State *L, const char *buff, size_t sz, const char *name, const char *mode) {
|
||||
int status = LUA_OK;
|
||||
if (sz > 0 && buff[0] == LUA_SIGNATURE[0]) {
|
||||
status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX);
|
||||
}
|
||||
else {
|
||||
status = compat53_checkmode(L, mode, "text", LUA_ERRSYNTAX);
|
||||
}
|
||||
if (status != LUA_OK)
|
||||
return status;
|
||||
return luaL_loadbuffer(L, buff, sz, name);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(l_inspectstat) && \
|
||||
(defined(unix) || defined(__unix) || defined(__unix__) || \
|
||||
defined(__TOS_AIX__) || defined(_SYSTYPE_BSD) || \
|
||||
(defined(__APPLE__) && defined(__MACH__)))
|
||||
/* some form of unix; check feature macros in unistd.h for details */
|
||||
# include <unistd.h>
|
||||
/* check posix version; the relevant include files and macros probably
|
||||
* were available before 2001, but I'm not sure */
|
||||
# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
|
||||
# include <sys/wait.h>
|
||||
# define l_inspectstat(stat,what) \
|
||||
if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
|
||||
else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* provide default (no-op) version */
|
||||
#if !defined(l_inspectstat)
|
||||
# define l_inspectstat(stat,what) ((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
COMPAT53_API int luaL_execresult(lua_State *L, int stat) {
|
||||
const char *what = "exit";
|
||||
if (stat == -1)
|
||||
return luaL_fileresult(L, 0, NULL);
|
||||
else {
|
||||
l_inspectstat(stat, what);
|
||||
if (*what == 'e' && stat == 0)
|
||||
lua_pushboolean(L, 1);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, what);
|
||||
lua_pushinteger(L, stat);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API void luaL_buffinit(lua_State *L, luaL_Buffer_53 *B) {
|
||||
/* make it crash if used via pointer to a 5.1-style luaL_Buffer */
|
||||
B->b.p = NULL;
|
||||
B->b.L = NULL;
|
||||
B->b.lvl = 0;
|
||||
/* reuse the buffer from the 5.1-style luaL_Buffer though! */
|
||||
B->ptr = B->b.buffer;
|
||||
B->capacity = LUAL_BUFFERSIZE;
|
||||
B->nelems = 0;
|
||||
B->L2 = L;
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API char *luaL_prepbuffsize(luaL_Buffer_53 *B, size_t s) {
|
||||
if (B->capacity - B->nelems < s) { /* needs to grow */
|
||||
char* newptr = NULL;
|
||||
size_t newcap = B->capacity * 2;
|
||||
if (newcap - B->nelems < s)
|
||||
newcap = B->nelems + s;
|
||||
if (newcap < B->capacity) /* overflow */
|
||||
luaL_error(B->L2, "buffer too large");
|
||||
newptr = (char*)lua_newuserdata(B->L2, newcap);
|
||||
memcpy(newptr, B->ptr, B->nelems);
|
||||
if (B->ptr != B->b.buffer)
|
||||
lua_replace(B->L2, -2); /* remove old buffer */
|
||||
B->ptr = newptr;
|
||||
B->capacity = newcap;
|
||||
}
|
||||
return B->ptr + B->nelems;
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API void luaL_addlstring(luaL_Buffer_53 *B, const char *s, size_t l) {
|
||||
memcpy(luaL_prepbuffsize(B, l), s, l);
|
||||
luaL_addsize(B, l);
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API void luaL_addvalue(luaL_Buffer_53 *B) {
|
||||
size_t len = 0;
|
||||
const char *s = lua_tolstring(B->L2, -1, &len);
|
||||
if (!s)
|
||||
luaL_error(B->L2, "cannot convert value to string");
|
||||
if (B->ptr != B->b.buffer)
|
||||
lua_insert(B->L2, -2); /* userdata buffer must be at stack top */
|
||||
luaL_addlstring(B, s, len);
|
||||
lua_remove(B->L2, B->ptr != B->b.buffer ? -2 : -1);
|
||||
}
|
||||
|
||||
|
||||
void luaL_pushresult(luaL_Buffer_53 *B) {
|
||||
lua_pushlstring(B->L2, B->ptr, B->nelems);
|
||||
if (B->ptr != B->b.buffer)
|
||||
lua_replace(B->L2, -2); /* remove userdata buffer */
|
||||
}
|
||||
|
||||
|
||||
#endif /* Lua 5.1 */
|
||||
|
||||
|
||||
|
||||
/* definitions for Lua 5.1 and Lua 5.2 */
|
||||
#if defined( LUA_VERSION_NUM ) && LUA_VERSION_NUM <= 502
|
||||
|
||||
|
||||
COMPAT53_API int lua_geti(lua_State *L, int index, lua_Integer i) {
|
||||
index = lua_absindex(L, index);
|
||||
lua_pushinteger(L, i);
|
||||
lua_gettable(L, index);
|
||||
return lua_type(L, -1);
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API int lua_isinteger(lua_State *L, int index) {
|
||||
if (lua_type(L, index) == LUA_TNUMBER) {
|
||||
lua_Number n = lua_tonumber(L, index);
|
||||
lua_Integer i = lua_tointeger(L, index);
|
||||
if (i == n)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API lua_Integer lua_tointegerx(lua_State *L, int i, int *isnum) {
|
||||
int ok = 0;
|
||||
lua_Number n = lua_tonumberx(L, i, &ok);
|
||||
if (ok) {
|
||||
if (n == (lua_Integer)n) {
|
||||
if (isnum)
|
||||
*isnum = 1;
|
||||
return (lua_Integer)n;
|
||||
}
|
||||
}
|
||||
if (isnum)
|
||||
*isnum = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void compat53_reverse(lua_State *L, int a, int b) {
|
||||
for (; a < b; ++a, --b) {
|
||||
lua_pushvalue(L, a);
|
||||
lua_pushvalue(L, b);
|
||||
lua_replace(L, a);
|
||||
lua_replace(L, b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API void lua_rotate(lua_State *L, int idx, int n) {
|
||||
int n_elems = 0;
|
||||
idx = lua_absindex(L, idx);
|
||||
n_elems = lua_gettop(L) - idx + 1;
|
||||
if (n < 0)
|
||||
n += n_elems;
|
||||
if (n > 0 && n < n_elems) {
|
||||
luaL_checkstack(L, 2, "not enough stack slots available");
|
||||
n = n_elems - n;
|
||||
compat53_reverse(L, idx, idx + n - 1);
|
||||
compat53_reverse(L, idx + n, idx + n_elems - 1);
|
||||
compat53_reverse(L, idx, idx + n_elems - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API void lua_seti(lua_State *L, int index, lua_Integer i) {
|
||||
luaL_checkstack(L, 1, "not enough stack slots available");
|
||||
index = lua_absindex(L, index);
|
||||
lua_pushinteger(L, i);
|
||||
lua_insert(L, -2);
|
||||
lua_settable(L, index);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(lua_str2number)
|
||||
# define lua_str2number(s, p) strtod((s), (p))
|
||||
#endif
|
||||
|
||||
COMPAT53_API size_t lua_stringtonumber(lua_State *L, const char *s) {
|
||||
char* endptr;
|
||||
lua_Number n = lua_str2number(s, &endptr);
|
||||
if (endptr != s) {
|
||||
while (*endptr != '\0' && isspace((unsigned char)*endptr))
|
||||
++endptr;
|
||||
if (*endptr == '\0') {
|
||||
lua_pushnumber(L, n);
|
||||
return endptr - s + 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API const char *luaL_tolstring(lua_State *L, int idx, size_t *len) {
|
||||
if (!luaL_callmeta(L, idx, "__tostring")) {
|
||||
int t = lua_type(L, idx), tt = 0;
|
||||
char const* name = NULL;
|
||||
switch (t) {
|
||||
case LUA_TNIL:
|
||||
lua_pushliteral(L, "nil");
|
||||
break;
|
||||
case LUA_TSTRING:
|
||||
case LUA_TNUMBER:
|
||||
lua_pushvalue(L, idx);
|
||||
break;
|
||||
case LUA_TBOOLEAN:
|
||||
if (lua_toboolean(L, idx))
|
||||
lua_pushliteral(L, "true");
|
||||
else
|
||||
lua_pushliteral(L, "false");
|
||||
break;
|
||||
default:
|
||||
tt = luaL_getmetafield(L, idx, "__name");
|
||||
name = (tt == LUA_TSTRING) ? lua_tostring(L, -1) : lua_typename(L, t);
|
||||
lua_pushfstring(L, "%s: %p", name, lua_topointer(L, idx));
|
||||
if (tt != LUA_TNIL)
|
||||
lua_replace(L, -2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!lua_isstring(L, -1))
|
||||
luaL_error(L, "'__tostring' must return a string");
|
||||
}
|
||||
return lua_tolstring(L, -1, len);
|
||||
}
|
||||
|
||||
|
||||
COMPAT53_API void luaL_requiref(lua_State *L, const char *modname,
|
||||
lua_CFunction openf, int glb) {
|
||||
luaL_checkstack(L, 3, "not enough stack slots available");
|
||||
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
|
||||
if (lua_getfield(L, -1, modname) == LUA_TNIL) {
|
||||
lua_pop(L, 1);
|
||||
lua_pushcfunction(L, openf);
|
||||
lua_pushstring(L, modname);
|
||||
lua_call(L, 1, 1);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -3, modname);
|
||||
}
|
||||
if (glb) {
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, modname);
|
||||
}
|
||||
lua_replace(L, -2);
|
||||
}
|
||||
|
||||
|
||||
#endif /* Lua 5.1 and 5.2 */
|
||||
|
||||
|
||||
#endif /* KEPLER_PROJECT_COMPAT53_C_ */
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* This file contains parts of Lua 5.2's and Lua 5.3's source code:
|
||||
*
|
||||
* Copyright (C) 1994-2014 Lua.org, PUC-Rio.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*********************************************************************/
|
||||
|
|
@ -1,424 +0,0 @@
|
|||
#ifndef KEPLER_PROJECT_COMPAT53_H_
|
||||
#define KEPLER_PROJECT_COMPAT53_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef COMPAT53_PREFIX
|
||||
/* we chose this name because many other lua bindings / libs have
|
||||
* their own compatibility layer, and that use the compat53 declaration
|
||||
* frequently, causing all kinds of linker / compiler issues
|
||||
*/
|
||||
# define COMPAT53_PREFIX kp_compat53
|
||||
#endif // COMPAT53_PREFIX
|
||||
|
||||
#ifndef COMPAT53_API
|
||||
# if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE
|
||||
# if defined(__GNUC__) || defined(__clang__)
|
||||
# define COMPAT53_API __attribute__((__unused__)) static inline
|
||||
# else
|
||||
# define COMPAT53_API static inline
|
||||
# endif /* Clang/GCC */
|
||||
# else /* COMPAT53_INCLUDE_SOURCE */
|
||||
/* we are not including source, so everything is extern */
|
||||
# define COMPAT53_API extern
|
||||
# endif /* COMPAT53_INCLUDE_SOURCE */
|
||||
#endif /* COMPAT53_PREFIX */
|
||||
|
||||
|
||||
#define COMPAT53_CONCAT_HELPER(a, b) a##b
|
||||
#define COMPAT53_CONCAT(a, b) COMPAT53_CONCAT_HELPER(a, b)
|
||||
|
||||
|
||||
|
||||
/* declarations for Lua 5.1 */
|
||||
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
|
||||
|
||||
/* XXX not implemented:
|
||||
* lua_arith (new operators)
|
||||
* lua_upvalueid
|
||||
* lua_upvaluejoin
|
||||
* lua_version
|
||||
* lua_yieldk
|
||||
*/
|
||||
|
||||
#ifndef LUA_OK
|
||||
# define LUA_OK 0
|
||||
#endif
|
||||
#ifndef LUA_OPADD
|
||||
# define LUA_OPADD 0
|
||||
#endif
|
||||
#ifndef LUA_OPSUB
|
||||
# define LUA_OPSUB 1
|
||||
#endif
|
||||
#ifndef LUA_OPMUL
|
||||
# define LUA_OPMUL 2
|
||||
#endif
|
||||
#ifndef LUA_OPDIV
|
||||
# define LUA_OPDIV 3
|
||||
#endif
|
||||
#ifndef LUA_OPMOD
|
||||
# define LUA_OPMOD 4
|
||||
#endif
|
||||
#ifndef LUA_OPPOW
|
||||
# define LUA_OPPOW 5
|
||||
#endif
|
||||
#ifndef LUA_OPUNM
|
||||
# define LUA_OPUNM 6
|
||||
#endif
|
||||
#ifndef LUA_OPEQ
|
||||
# define LUA_OPEQ 0
|
||||
#endif
|
||||
#ifndef LUA_OPLT
|
||||
# define LUA_OPLT 1
|
||||
#endif
|
||||
#ifndef LUA_OPLE
|
||||
# define LUA_OPLE 2
|
||||
#endif
|
||||
|
||||
/* LuaJIT/Lua 5.1 does not have the updated
|
||||
* error codes for thread status/function returns (but some patched versions do)
|
||||
* define it only if it's not found
|
||||
*/
|
||||
#if !defined(LUA_ERRGCMM)
|
||||
/* Use + 2 because in some versions of Lua (Lua 5.1)
|
||||
* LUA_ERRFILE is defined as (LUA_ERRERR+1)
|
||||
* so we need to avoid it (LuaJIT might have something at this
|
||||
* integer value too)
|
||||
*/
|
||||
# define LUA_ERRGCMM (LUA_ERRERR + 2)
|
||||
#endif /* LUA_ERRGCMM define */
|
||||
|
||||
#if !defined(MOONJIT_VERSION)
|
||||
typedef size_t lua_Unsigned;
|
||||
#endif
|
||||
|
||||
typedef struct luaL_Buffer_53 {
|
||||
luaL_Buffer b; /* make incorrect code crash! */
|
||||
char *ptr;
|
||||
size_t nelems;
|
||||
size_t capacity;
|
||||
lua_State *L2;
|
||||
} luaL_Buffer_53;
|
||||
#define luaL_Buffer luaL_Buffer_53
|
||||
|
||||
/* In PUC-Rio 5.1, userdata is a simple FILE*
|
||||
* In LuaJIT, it's a struct where the first member is a FILE*
|
||||
* We can't support the `closef` member
|
||||
*/
|
||||
typedef struct luaL_Stream {
|
||||
FILE *f;
|
||||
} luaL_Stream;
|
||||
|
||||
#define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex)
|
||||
COMPAT53_API int lua_absindex(lua_State *L, int i);
|
||||
|
||||
#define lua_arith COMPAT53_CONCAT(COMPAT53_PREFIX, _arith)
|
||||
COMPAT53_API void lua_arith(lua_State *L, int op);
|
||||
|
||||
#define lua_compare COMPAT53_CONCAT(COMPAT53_PREFIX, _compare)
|
||||
COMPAT53_API int lua_compare(lua_State *L, int idx1, int idx2, int op);
|
||||
|
||||
#define lua_copy COMPAT53_CONCAT(COMPAT53_PREFIX, _copy)
|
||||
COMPAT53_API void lua_copy(lua_State *L, int from, int to);
|
||||
|
||||
#define lua_getuservalue(L, i) \
|
||||
(lua_getfenv((L), (i)), lua_type((L), -1))
|
||||
#define lua_setuservalue(L, i) \
|
||||
(luaL_checktype((L), -1, LUA_TTABLE), lua_setfenv((L), (i)))
|
||||
|
||||
#define lua_len COMPAT53_CONCAT(COMPAT53_PREFIX, _len)
|
||||
COMPAT53_API void lua_len(lua_State *L, int i);
|
||||
|
||||
#define lua_pushstring(L, s) \
|
||||
(lua_pushstring((L), (s)), lua_tostring((L), -1))
|
||||
|
||||
#define lua_pushlstring(L, s, len) \
|
||||
((((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len))), lua_tostring((L), -1))
|
||||
|
||||
#ifndef luaL_newlibtable
|
||||
# define luaL_newlibtable(L, l) \
|
||||
(lua_createtable((L), 0, sizeof((l))/sizeof(*(l))-1))
|
||||
#endif
|
||||
#ifndef luaL_newlib
|
||||
# define luaL_newlib(L, l) \
|
||||
(luaL_newlibtable((L), (l)), luaL_register((L), NULL, (l)))
|
||||
#endif
|
||||
|
||||
#ifndef lua_pushglobaltable
|
||||
# define lua_pushglobaltable(L) \
|
||||
lua_pushvalue((L), LUA_GLOBALSINDEX)
|
||||
#endif
|
||||
#define lua_rawgetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawgetp)
|
||||
COMPAT53_API int lua_rawgetp(lua_State *L, int i, const void *p);
|
||||
|
||||
#define lua_rawsetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawsetp)
|
||||
COMPAT53_API void lua_rawsetp(lua_State *L, int i, const void *p);
|
||||
|
||||
#define lua_rawlen(L, i) lua_objlen((L), (i))
|
||||
|
||||
#define lua_tointeger(L, i) lua_tointegerx((L), (i), NULL)
|
||||
|
||||
#define lua_tonumberx COMPAT53_CONCAT(COMPAT53_PREFIX, _tonumberx)
|
||||
COMPAT53_API lua_Number lua_tonumberx(lua_State *L, int i, int *isnum);
|
||||
|
||||
#define luaL_checkversion COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkversion)
|
||||
COMPAT53_API void luaL_checkversion(lua_State *L);
|
||||
|
||||
#define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
|
||||
COMPAT53_API int lua_load(lua_State *L, lua_Reader reader, void *data, const char* source, const char* mode);
|
||||
|
||||
#define luaL_loadfilex COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadfilex)
|
||||
COMPAT53_API int luaL_loadfilex(lua_State *L, const char *filename, const char *mode);
|
||||
|
||||
#define luaL_loadbufferx COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadbufferx)
|
||||
COMPAT53_API int luaL_loadbufferx(lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
|
||||
|
||||
#define luaL_checkstack COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkstack_53)
|
||||
COMPAT53_API void luaL_checkstack(lua_State *L, int sp, const char *msg);
|
||||
|
||||
#define luaL_getsubtable COMPAT53_CONCAT(COMPAT53_PREFIX, L_getsubtable)
|
||||
COMPAT53_API int luaL_getsubtable(lua_State* L, int i, const char *name);
|
||||
|
||||
#define luaL_len COMPAT53_CONCAT(COMPAT53_PREFIX, L_len)
|
||||
COMPAT53_API lua_Integer luaL_len(lua_State *L, int i);
|
||||
|
||||
#define luaL_setfuncs COMPAT53_CONCAT(COMPAT53_PREFIX, L_setfuncs)
|
||||
COMPAT53_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup);
|
||||
|
||||
#define luaL_setmetatable COMPAT53_CONCAT(COMPAT53_PREFIX, L_setmetatable)
|
||||
COMPAT53_API void luaL_setmetatable(lua_State *L, const char *tname);
|
||||
|
||||
#define luaL_testudata COMPAT53_CONCAT(COMPAT53_PREFIX, L_testudata)
|
||||
COMPAT53_API void *luaL_testudata(lua_State *L, int i, const char *tname);
|
||||
|
||||
#define luaL_traceback COMPAT53_CONCAT(COMPAT53_PREFIX, L_traceback)
|
||||
COMPAT53_API void luaL_traceback(lua_State *L, lua_State *L1, const char *msg, int level);
|
||||
|
||||
#define luaL_fileresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_fileresult)
|
||||
COMPAT53_API int luaL_fileresult(lua_State *L, int stat, const char *fname);
|
||||
|
||||
#define luaL_execresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_execresult)
|
||||
COMPAT53_API int luaL_execresult(lua_State *L, int stat);
|
||||
|
||||
#define lua_callk(L, na, nr, ctx, cont) \
|
||||
((void)(ctx), (void)(cont), lua_call((L), (na), (nr)))
|
||||
#define lua_pcallk(L, na, nr, err, ctx, cont) \
|
||||
((void)(ctx), (void)(cont), lua_pcall((L), (na), (nr), (err)))
|
||||
|
||||
#define lua_resume(L, from, nargs) \
|
||||
((void)(from), lua_resume((L), (nargs)))
|
||||
|
||||
#define luaL_buffinit COMPAT53_CONCAT(COMPAT53_PREFIX, _buffinit_53)
|
||||
COMPAT53_API void luaL_buffinit(lua_State *L, luaL_Buffer_53 *B);
|
||||
|
||||
#define luaL_prepbuffsize COMPAT53_CONCAT(COMPAT53_PREFIX, _prepbufsize_53)
|
||||
COMPAT53_API char *luaL_prepbuffsize(luaL_Buffer_53 *B, size_t s);
|
||||
|
||||
#define luaL_addlstring COMPAT53_CONCAT(COMPAT53_PREFIX, _addlstring_53)
|
||||
COMPAT53_API void luaL_addlstring(luaL_Buffer_53 *B, const char *s, size_t l);
|
||||
|
||||
#define luaL_addvalue COMPAT53_CONCAT(COMPAT53_PREFIX, _addvalue_53)
|
||||
COMPAT53_API void luaL_addvalue(luaL_Buffer_53 *B);
|
||||
|
||||
#define luaL_pushresult COMPAT53_CONCAT(COMPAT53_PREFIX, _pushresult_53)
|
||||
COMPAT53_API void luaL_pushresult(luaL_Buffer_53 *B);
|
||||
|
||||
#undef luaL_buffinitsize
|
||||
#define luaL_buffinitsize(L, B, s) \
|
||||
(luaL_buffinit((L), (B)), luaL_prepbuffsize((B), (s)))
|
||||
|
||||
#undef luaL_prepbuffer
|
||||
#define luaL_prepbuffer(B) \
|
||||
luaL_prepbuffsize((B), LUAL_BUFFERSIZE)
|
||||
|
||||
#undef luaL_addchar
|
||||
#define luaL_addchar(B, c) \
|
||||
((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize((B), 1)), \
|
||||
((B)->ptr[(B)->nelems++] = (c)))
|
||||
|
||||
#undef luaL_addsize
|
||||
#define luaL_addsize(B, s) \
|
||||
((B)->nelems += (s))
|
||||
|
||||
#undef luaL_addstring
|
||||
#define luaL_addstring(B, s) \
|
||||
luaL_addlstring((B), (s), strlen((s)))
|
||||
|
||||
#undef luaL_pushresultsize
|
||||
#define luaL_pushresultsize(B, s) \
|
||||
(luaL_addsize((B), (s)), luaL_pushresult((B)))
|
||||
|
||||
#if defined(LUA_COMPAT_APIINTCASTS)
|
||||
#define lua_pushunsigned(L, n) \
|
||||
lua_pushinteger((L), (lua_Integer)(n))
|
||||
#define lua_tounsignedx(L, i, is) \
|
||||
((lua_Unsigned)lua_tointegerx((L), (i), (is)))
|
||||
#define lua_tounsigned(L, i) \
|
||||
lua_tounsignedx((L), (i), NULL)
|
||||
#define luaL_checkunsigned(L, a) \
|
||||
((lua_Unsigned)luaL_checkinteger((L), (a)))
|
||||
#define luaL_optunsigned(L, a, d) \
|
||||
((lua_Unsigned)luaL_optinteger((L), (a), (lua_Integer)(d)))
|
||||
#endif
|
||||
|
||||
#endif /* Lua 5.1 only */
|
||||
|
||||
|
||||
|
||||
/* declarations for Lua 5.1 and 5.2 */
|
||||
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 502
|
||||
|
||||
typedef int lua_KContext;
|
||||
|
||||
typedef int(*lua_KFunction)(lua_State *L, int status, lua_KContext ctx);
|
||||
|
||||
#define lua_dump(L, w, d, s) \
|
||||
((void)(s), lua_dump((L), (w), (d)))
|
||||
|
||||
#define lua_getfield(L, i, k) \
|
||||
(lua_getfield((L), (i), (k)), lua_type((L), -1))
|
||||
|
||||
#define lua_gettable(L, i) \
|
||||
(lua_gettable((L), (i)), lua_type((L), -1))
|
||||
|
||||
#define lua_geti COMPAT53_CONCAT(COMPAT53_PREFIX, _geti)
|
||||
COMPAT53_API int lua_geti(lua_State *L, int index, lua_Integer i);
|
||||
|
||||
#define lua_isinteger COMPAT53_CONCAT(COMPAT53_PREFIX, _isinteger)
|
||||
COMPAT53_API int lua_isinteger(lua_State *L, int index);
|
||||
|
||||
#define lua_tointegerx COMPAT53_CONCAT(COMPAT53_PREFIX, _tointegerx_53)
|
||||
COMPAT53_API lua_Integer lua_tointegerx(lua_State *L, int i, int *isnum);
|
||||
|
||||
#define lua_numbertointeger(n, p) \
|
||||
((*(p) = (lua_Integer)(n)), 1)
|
||||
|
||||
#define lua_rawget(L, i) \
|
||||
(lua_rawget((L), (i)), lua_type((L), -1))
|
||||
|
||||
#define lua_rawgeti(L, i, n) \
|
||||
(lua_rawgeti((L), (i), (n)), lua_type((L), -1))
|
||||
|
||||
#define lua_rotate COMPAT53_CONCAT(COMPAT53_PREFIX, _rotate)
|
||||
COMPAT53_API void lua_rotate(lua_State *L, int idx, int n);
|
||||
|
||||
#define lua_seti COMPAT53_CONCAT(COMPAT53_PREFIX, _seti)
|
||||
COMPAT53_API void lua_seti(lua_State *L, int index, lua_Integer i);
|
||||
|
||||
#define lua_stringtonumber COMPAT53_CONCAT(COMPAT53_PREFIX, _stringtonumber)
|
||||
COMPAT53_API size_t lua_stringtonumber(lua_State *L, const char *s);
|
||||
|
||||
#define luaL_tolstring COMPAT53_CONCAT(COMPAT53_PREFIX, L_tolstring)
|
||||
COMPAT53_API const char *luaL_tolstring(lua_State *L, int idx, size_t *len);
|
||||
|
||||
#define luaL_getmetafield(L, o, e) \
|
||||
(luaL_getmetafield((L), (o), (e)) ? lua_type((L), -1) : LUA_TNIL)
|
||||
|
||||
#define luaL_newmetatable(L, tn) \
|
||||
(luaL_newmetatable((L), (tn)) ? (lua_pushstring((L), (tn)), lua_setfield((L), -2, "__name"), 1) : 0)
|
||||
|
||||
#define luaL_requiref COMPAT53_CONCAT(COMPAT53_PREFIX, L_requiref_53)
|
||||
COMPAT53_API void luaL_requiref(lua_State *L, const char *modname,
|
||||
lua_CFunction openf, int glb);
|
||||
|
||||
#endif /* Lua 5.1 and Lua 5.2 */
|
||||
|
||||
|
||||
|
||||
/* declarations for Lua 5.2 */
|
||||
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 502
|
||||
|
||||
/* XXX not implemented:
|
||||
* lua_isyieldable
|
||||
* lua_getextraspace
|
||||
* lua_arith (new operators)
|
||||
* lua_pushfstring (new formats)
|
||||
*/
|
||||
|
||||
#define lua_getglobal(L, n) \
|
||||
(lua_getglobal((L), (n)), lua_type((L), -1))
|
||||
|
||||
#define lua_getuservalue(L, i) \
|
||||
(lua_getuservalue((L), (i)), lua_type((L), -1))
|
||||
|
||||
#define lua_pushlstring(L, s, len) \
|
||||
(((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len)))
|
||||
|
||||
#define lua_rawgetp(L, i, p) \
|
||||
(lua_rawgetp((L), (i), (p)), lua_type((L), -1))
|
||||
|
||||
#define LUA_KFUNCTION(_name) \
|
||||
static int (_name)(lua_State *L, int status, lua_KContext ctx); \
|
||||
static int (_name ## _52)(lua_State *L) { \
|
||||
lua_KContext ctx; \
|
||||
int status = lua_getctx(L, &ctx); \
|
||||
return (_name)(L, status, ctx); \
|
||||
} \
|
||||
static int (_name)(lua_State *L, int status, lua_KContext ctx)
|
||||
|
||||
#define lua_pcallk(L, na, nr, err, ctx, cont) \
|
||||
lua_pcallk((L), (na), (nr), (err), (ctx), cont ## _52)
|
||||
|
||||
#define lua_callk(L, na, nr, ctx, cont) \
|
||||
lua_callk((L), (na), (nr), (ctx), cont ## _52)
|
||||
|
||||
#define lua_yieldk(L, nr, ctx, cont) \
|
||||
lua_yieldk((L), (nr), (ctx), cont ## _52)
|
||||
|
||||
#ifdef lua_call
|
||||
# undef lua_call
|
||||
# define lua_call(L, na, nr) \
|
||||
(lua_callk)((L), (na), (nr), 0, NULL)
|
||||
#endif
|
||||
|
||||
#ifdef lua_pcall
|
||||
# undef lua_pcall
|
||||
# define lua_pcall(L, na, nr, err) \
|
||||
(lua_pcallk)((L), (na), (nr), (err), 0, NULL)
|
||||
#endif
|
||||
|
||||
#ifdef lua_yield
|
||||
# undef lua_yield
|
||||
# define lua_yield(L, nr) \
|
||||
(lua_yieldk)((L), (nr), 0, NULL)
|
||||
#endif
|
||||
|
||||
#endif /* Lua 5.2 only */
|
||||
|
||||
|
||||
|
||||
/* other Lua versions */
|
||||
#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 || LUA_VERSION_NUM > 504
|
||||
|
||||
# error "unsupported Lua version (i.e. not Lua 5.1, 5.2, 5.3, or 5.4)"
|
||||
|
||||
#endif /* other Lua versions except 5.1, 5.2, 5.3, and 5.4 */
|
||||
|
||||
|
||||
|
||||
/* helper macro for defining continuation functions (for every version
|
||||
* *except* Lua 5.2) */
|
||||
#ifndef LUA_KFUNCTION
|
||||
#define LUA_KFUNCTION(_name) \
|
||||
static int (_name)(lua_State *L, int status, lua_KContext ctx)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE == 1
|
||||
# include "compat-5.3.c.h"
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* KEPLER_PROJECT_COMPAT53_H_ */
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
#ifndef NOT_KEPLER_PROJECT_COMPAT54_H_
|
||||
#define NOT_KEPLER_PROJECT_COMPAT54_H_
|
||||
|
||||
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 504
|
||||
|
||||
#if !defined(LUA_ERRGCMM)
|
||||
/* So Lua 5.4 actually removes this, which breaks sol2...
|
||||
man, this API is quite unstable...!
|
||||
*/
|
||||
# define LUA_ERRGCMM (LUA_ERRERR + 2)
|
||||
#endif /* LUA_ERRGCMM define */
|
||||
|
||||
#endif // Lua 5.4 only
|
||||
|
||||
#endif // NOT_KEPLER_PROJECT_COMPAT54_H_
|
|
@ -1,102 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_COMPATIBILITY_VERSION_HPP
|
||||
#define SOL_COMPATIBILITY_VERSION_HPP
|
||||
|
||||
#include "../feature_test.hpp"
|
||||
|
||||
// clang-format off
|
||||
|
||||
#if defined(SOL_USING_CXX_LUA) && SOL_USING_CXX_LUA
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#if (defined(SOL_USING_CXX_LUAJIT) && SOL_USING_CXX_LUAJIT) || (defined(LUAJIT_VERSION) && LUAJIT_VERSION)
|
||||
#include <luajit.h>
|
||||
#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))
|
||||
#define SOL_EXCEPTIONS_SAFE_PROPAGATION 1
|
||||
#endif // Exceptions can be propagated safely using C++-compiled Lua
|
||||
#else
|
||||
#if defined(SOL_NO_LUA_HPP) && SOL_NO_LUA_HPP
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
#if defined(LUAJIT_VERSION) && LUAJIT_VERSION
|
||||
#include <luajit.h>
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#if defined(__has_include)
|
||||
#if __has_include(<lua.hpp>)
|
||||
#include <lua.hpp>
|
||||
#else
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
#if defined(LUAJIT_VERSION) && LUAJIT_VERSION
|
||||
#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 // Manual - have lua.hpp or not
|
||||
#endif // C++ Mangling for Lua vs. Not
|
||||
|
||||
#ifdef LUAJIT_VERSION
|
||||
#ifndef SOL_LUAJIT
|
||||
#define SOL_LUAJIT 1
|
||||
#endif // sol luajit
|
||||
#if defined(SOL_LUAJIT) && SOL_LUAJIT
|
||||
#ifndef SOL_LUAJIT_VERSION
|
||||
#define SOL_LUAJIT_VERSION LUAJIT_VERSION_NUM
|
||||
#endif // SOL_LUAJIT_VERSION definition, if not present
|
||||
#endif
|
||||
#endif // luajit
|
||||
|
||||
#if SOL_LUAJIT && SOL_LUAJIT_VERSION >= 20100
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) && (!defined(SOL_EXCEPTIONS_ALWAYS_UNSAFE) && !(SOL_EXCEPTIONS_ALWAYS_UNSAFE))
|
||||
#define SOL_EXCEPTIONS_SAFE_PROPAGATION 1
|
||||
#endif // Do not catch (...) clauses
|
||||
#endif // LuaJIT beta 02.01.00 have better exception handling on all platforms since beta3
|
||||
|
||||
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 502
|
||||
#define SOL_LUA_VERSION LUA_VERSION_NUM
|
||||
#elif defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
|
||||
#define SOL_LUA_VERSION LUA_VERSION_NUM
|
||||
#elif !defined(LUA_VERSION_NUM) || !(LUA_VERSION_NUM)
|
||||
// Definitely 5.0
|
||||
#define SOL_LUA_VERSION 500
|
||||
#else
|
||||
// ??? Not sure, assume 503?
|
||||
#define SOL_LUA_VERSION 503
|
||||
#endif // Lua Version 503, 502, 501 || luajit, 500
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // SOL_COMPATIBILITY_VERSION_HPP
|
|
@ -1,245 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_CONFIG_HPP
|
||||
#define SOL_CONFIG_HPP
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_DEBUG) && !defined(NDEBUG)
|
||||
#ifndef SOL_IN_DEBUG_DETECTED
|
||||
#define SOL_IN_DEBUG_DETECTED 1
|
||||
#endif
|
||||
#endif // VC++ Debug macros
|
||||
|
||||
#if !defined(_CPPUNWIND)
|
||||
#if !defined(SOL_NO_EXCEPTIONS)
|
||||
#define SOL_NO_EXCEPTIONS 1
|
||||
#endif
|
||||
#endif // Automatic Exceptions
|
||||
|
||||
#if !defined(_CPPRTTI)
|
||||
#if !defined(SOL_NO_RTTI)
|
||||
#define SOL_NO_RTTI 1
|
||||
#endif
|
||||
#endif // Automatic RTTI
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
#if !defined(NDEBUG) && !defined(__OPTIMIZE__)
|
||||
#if !defined(SOL_IN_DEBUG_DETECTED)
|
||||
#define SOL_IN_DEBUG_DETECTED 1
|
||||
#endif
|
||||
#endif // Not Debug && g++ optimizer flag
|
||||
|
||||
#if !defined(__EXCEPTIONS)
|
||||
#if !defined(SOL_NO_EXCEPTIONS)
|
||||
#define SOL_NO_EXCEPTIONS 1
|
||||
#endif
|
||||
#endif // No Exceptions
|
||||
|
||||
#if !defined(__GXX_RTTI)
|
||||
#if !defined(SOL_NO_RTTI)
|
||||
#define SOL_NO_RTTI 1
|
||||
#endif
|
||||
#endif // No RTTI
|
||||
|
||||
#endif // vc++ || clang++/g++
|
||||
|
||||
// Compatibility Define
|
||||
#if defined(SOL_CHECK_ARGUMENTS) && SOL_CHECK_ARGUMENTS != 0
|
||||
#if defined(SOL_ALL_SAFETIES_ON)
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#endif // turn all the safeties on
|
||||
#endif // Compatibility Define for Safety
|
||||
|
||||
// If this is defined, turn on all the safety checks automatically
|
||||
#if defined(SOL_ALL_SAFETIES_ON) && SOL_ALL_SAFETIES_ON != 0
|
||||
|
||||
// Checks low-level getter function
|
||||
// (and thusly, affects nearly entire framework)
|
||||
#if !defined(SOL_SAFE_GETTER)
|
||||
#define SOL_SAFE_GETTER 1
|
||||
#endif
|
||||
|
||||
// Checks access on usertype functions
|
||||
// local my_obj = my_type.new()
|
||||
// my_obj.my_member_function()
|
||||
// -- bad syntax and crash
|
||||
#if !defined(SOL_SAFE_USERTYPE)
|
||||
#define SOL_SAFE_USERTYPE 1
|
||||
#endif
|
||||
|
||||
// Checks sol::reference derived boundaries
|
||||
// sol::function ref(L, 1);
|
||||
// sol::userdata sref(L, 2);
|
||||
#if !defined(SOL_SAFE_REFERENCES)
|
||||
#define SOL_SAFE_REFERENCES 1
|
||||
#endif
|
||||
|
||||
// Changes all typedefs of sol::function to point to the
|
||||
// protected_function version, instead of unsafe_function
|
||||
#if !defined(SOL_SAFE_FUNCTION)
|
||||
#define SOL_SAFE_FUNCTION 1
|
||||
#endif
|
||||
|
||||
// Checks function parameters and
|
||||
// returns upon call into/from Lua
|
||||
// local a = 1
|
||||
// local b = "woof"
|
||||
// my_c_function(a, b)
|
||||
#if !defined(SOL_SAFE_FUNCTION_CALLS)
|
||||
#define SOL_SAFE_FUNCTION_CALLS 1
|
||||
#endif
|
||||
|
||||
// Checks conversions
|
||||
// int v = lua["bark"];
|
||||
// int v2 = my_sol_function();
|
||||
#if !defined(SOL_SAFE_PROXIES)
|
||||
#define SOL_SAFE_PROXIES 1
|
||||
#endif
|
||||
|
||||
// Check overflowing number conversions
|
||||
// for things like 64 bit integers that don't fit in a typical lua_Number
|
||||
// for Lua 5.1 and 5.2
|
||||
#if !defined(SOL_SAFE_NUMERICS)
|
||||
#define SOL_SAFE_NUMERICS 1
|
||||
#endif
|
||||
|
||||
// Turn off Number Precision Checks
|
||||
// if this is defined, we do not do range
|
||||
// checks on integers / unsigned integers that might
|
||||
// be bigger than what Lua can represent
|
||||
#if !defined(SOL_NO_CHECK_NUMBER_PRECISION)
|
||||
// off by default
|
||||
#define SOL_NO_CHECK_NUMBER_PRECISION 0
|
||||
#endif
|
||||
|
||||
// Print any exceptions / errors that occur
|
||||
// in debug mode to the default error stream / console
|
||||
#if !defined(SOL_SAFE_STACK_CHECK)
|
||||
#define SOL_SAFE_STACK_CHECK 1
|
||||
#endif
|
||||
|
||||
#endif // Turn on Safety for all if top-level macro is defined
|
||||
|
||||
// If we are in debug, turn on certain safety checks
|
||||
#if defined(SOL_IN_DEBUG_DETECTED) && SOL_IN_DEBUG_DETECTED != 0
|
||||
|
||||
#if !defined(SOL_SAFE_REFERENCES)
|
||||
// Ensure that references are forcefully type-checked upon construction
|
||||
#define SOL_SAFE_REFERENCES 1
|
||||
#endif
|
||||
|
||||
// Safe usertypes checks for errors such as
|
||||
// obj = my_type.new()
|
||||
// obj.f() -- note the '.' instead of ':'
|
||||
// usertypes should be safe no matter what
|
||||
#if !defined(SOL_SAFE_USERTYPE)
|
||||
#define SOL_SAFE_USERTYPE 1
|
||||
#endif
|
||||
|
||||
#if !defined(SOL_SAFE_FUNCTION_CALLS)
|
||||
// Function calls from Lua should be automatically safe in debug mode
|
||||
#define SOL_SAFE_FUNCTION_CALLS 1
|
||||
#endif
|
||||
|
||||
// Print any exceptions / errors that occur
|
||||
// in debug mode to the default error stream / console
|
||||
#if !defined(SOL_PRINT_ERRORS)
|
||||
#define SOL_PRINT_ERRORS 1
|
||||
#endif
|
||||
|
||||
// Print any exceptions / errors that occur
|
||||
// in debug mode to the default error stream / console
|
||||
#if !defined(SOL_SAFE_STACK_CHECK)
|
||||
#define SOL_SAFE_STACK_CHECK 1
|
||||
#endif
|
||||
|
||||
|
||||
#endif // DEBUG: Turn on all debug safety features for VC++ / g++ / clang++ and similar
|
||||
|
||||
// Print any exceptions / errors that occur
|
||||
// This is normally off due to relying on
|
||||
// <iostream> to get std::cerr / std::cout
|
||||
// so it is only defined in debug modes
|
||||
#if !defined(SOL_PRINT_ERRORS)
|
||||
// off by default here
|
||||
#define SOL_PRINT_ERRORS 0
|
||||
#endif
|
||||
|
||||
// The default on_error handler should not throw/assert/print/abort,
|
||||
// but simply pass the value through back to the user
|
||||
// problematic due to not having a stable [[nodiscard]] attribute in C++11,
|
||||
// off by default
|
||||
#if !defined(SOL_DEFAULT_PASS_ON_ERROR)
|
||||
// off by default here
|
||||
#define SOL_DEFAULT_PASS_ON_ERROR 0
|
||||
#endif
|
||||
|
||||
// Interop allows userdata from external systems
|
||||
// with external memory layout and metatable names
|
||||
// to be registered. It costs something to perform
|
||||
// the interop_checker / differentiation for sol3 usertypes versus
|
||||
// external ones however, so this is off by default
|
||||
#if !defined(SOL_ENABLE_INTEROP)
|
||||
// off by default here
|
||||
#define SOL_ENABLE_INTEROP 0
|
||||
#endif
|
||||
|
||||
// Mac OSX and Objective C define a nil keyword
|
||||
// we cannot use that for the sol::type::nil define
|
||||
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) || defined(__OBJC__) || defined(nil)
|
||||
#if !defined(SOL_NO_NIL)
|
||||
#define SOL_NO_NIL 1
|
||||
#endif
|
||||
#endif // avoiding nil defines / keywords
|
||||
|
||||
// For strings being serialized and
|
||||
// deserialized from and to utf8
|
||||
// this controls the size of the buffer we create on the stack,
|
||||
// in # of utf8 code units
|
||||
// a buffer of 1KB covers almost all the strings
|
||||
// we care about: anything larger and the user should know better
|
||||
#ifndef SOL_STACK_STRING_OPTIMIZATION_SIZE
|
||||
#define SOL_STACK_STRING_OPTIMIZATION_SIZE 1024
|
||||
#endif // Optimized conversion routines using a KB or so off the stack
|
||||
|
||||
// This macro ensures that we check the stack
|
||||
// on every push of a value.
|
||||
// This is only for sol3: if you want safety in your customization
|
||||
// points, you need to build it into each and every customization point you use,
|
||||
// by using luaL_checkstack or lua_checkstack
|
||||
// this is off by default,
|
||||
// but on by default for debug builds
|
||||
#if !defined(SOL_SAFE_STACK_CHECK)
|
||||
#define SOL_SAFE_STACK_CHECK 0
|
||||
#endif // use luaL_checkstack to check stack overflow / overrun
|
||||
|
||||
// This macro gives automagic type checks by default.
|
||||
// Some types don't quite conform to this, so a few people
|
||||
// want it to be turned off globally, all the time.
|
||||
// the trait can still be specialized to help with that.
|
||||
#if !defined(SOL_AUTOMAGICAL_TYPES_BY_DEFAULT)
|
||||
#define SOL_AUTOMAGICAL_TYPES_BY_DEFAULT 1
|
||||
#endif // make is_automagical on/off by default
|
||||
|
||||
#endif // SOL_CONFIG_HPP
|
|
@ -1,248 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_COROUTINE_HPP
|
||||
#define SOL_COROUTINE_HPP
|
||||
|
||||
#include "reference.hpp"
|
||||
#include "object.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "function_result.hpp"
|
||||
#include "thread.hpp"
|
||||
#include "protected_handler.hpp"
|
||||
|
||||
namespace sol {
|
||||
template <typename ref_t>
|
||||
class basic_coroutine : public basic_object<ref_t> {
|
||||
private:
|
||||
using base_t = basic_object<ref_t>;
|
||||
|
||||
public:
|
||||
typedef reference handler_t;
|
||||
handler_t error_handler;
|
||||
|
||||
private:
|
||||
call_status stats = call_status::yielded;
|
||||
|
||||
void luacall(std::ptrdiff_t argcount, std::ptrdiff_t) {
|
||||
#if SOL_LUA_VERSION >= 504
|
||||
int nresults;
|
||||
stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount), &nresults));
|
||||
#else
|
||||
stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount)));
|
||||
#endif
|
||||
}
|
||||
|
||||
template <std::size_t... I, typename... Ret>
|
||||
auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n) {
|
||||
luacall(n, sizeof...(Ret));
|
||||
return stack::pop<std::tuple<Ret...>>(lua_state());
|
||||
}
|
||||
|
||||
template <std::size_t I, typename Ret>
|
||||
Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n) {
|
||||
luacall(n, 1);
|
||||
return stack::pop<Ret>(lua_state());
|
||||
}
|
||||
|
||||
template <std::size_t I>
|
||||
void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n) {
|
||||
luacall(n, 0);
|
||||
}
|
||||
|
||||
protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n) {
|
||||
int firstreturn = 1;
|
||||
luacall(n, LUA_MULTRET);
|
||||
int poststacksize = lua_gettop(this->lua_state());
|
||||
int returncount = poststacksize - (firstreturn - 1);
|
||||
if (error()) {
|
||||
if (error_handler.valid()) {
|
||||
string_view err = stack::get<string_view>(this->lua_state(), poststacksize);
|
||||
error_handler.push();
|
||||
stack::push(this->lua_state(), err);
|
||||
lua_call(lua_state(), 1, 1);
|
||||
}
|
||||
return protected_function_result(this->lua_state(), lua_absindex(this->lua_state(), -1), 1, returncount, status());
|
||||
}
|
||||
return protected_function_result(this->lua_state(), firstreturn, returncount, returncount, status());
|
||||
}
|
||||
|
||||
public:
|
||||
using base_t::lua_state;
|
||||
|
||||
basic_coroutine() = default;
|
||||
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_coroutine>>, meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>, meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_coroutine(T&& r) noexcept
|
||||
: base_t(std::forward<T>(r)), error_handler(detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
if (!is_function<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_coroutine>(lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
basic_coroutine(const basic_coroutine&) = default;
|
||||
basic_coroutine& operator=(const basic_coroutine&) = default;
|
||||
basic_coroutine(basic_coroutine&&) = default;
|
||||
basic_coroutine& operator=(basic_coroutine&&) = default;
|
||||
basic_coroutine(const basic_function<base_t>& b)
|
||||
: basic_coroutine(b, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(b.lua_state())) {
|
||||
}
|
||||
basic_coroutine(basic_function<base_t>&& b)
|
||||
: basic_coroutine(std::move(b), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(b.lua_state())) {
|
||||
}
|
||||
basic_coroutine(const basic_function<base_t>& b, handler_t eh)
|
||||
: base_t(b), error_handler(std::move(eh)) {
|
||||
}
|
||||
basic_coroutine(basic_function<base_t>&& b, handler_t eh)
|
||||
: base_t(std::move(b)), error_handler(std::move(eh)) {
|
||||
}
|
||||
basic_coroutine(const stack_reference& r)
|
||||
: basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
|
||||
}
|
||||
basic_coroutine(stack_reference&& r)
|
||||
: basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
|
||||
}
|
||||
basic_coroutine(const stack_reference& r, handler_t eh)
|
||||
: basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
|
||||
}
|
||||
basic_coroutine(stack_reference&& r, handler_t eh)
|
||||
: basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
|
||||
}
|
||||
|
||||
template <typename Super>
|
||||
basic_coroutine(const proxy_base<Super>& p)
|
||||
: basic_coroutine(p, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) {
|
||||
}
|
||||
template <typename Super>
|
||||
basic_coroutine(proxy_base<Super>&& p)
|
||||
: basic_coroutine(std::move(p), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) {
|
||||
}
|
||||
template <typename Proxy, typename Handler, meta::enable<std::is_base_of<proxy_base_tag, meta::unqualified_t<Proxy>>, meta::neg<is_lua_index<meta::unqualified_t<Handler>>>> = meta::enabler>
|
||||
basic_coroutine(Proxy&& p, Handler&& eh)
|
||||
: basic_coroutine(detail::force_cast<base_t>(p), std::forward<Handler>(eh)) {
|
||||
}
|
||||
|
||||
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_coroutine(lua_State* L, T&& r)
|
||||
: basic_coroutine(L, std::forward<T>(r), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
|
||||
}
|
||||
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_coroutine(lua_State* L, T&& r, handler_t eh)
|
||||
: base_t(L, std::forward<T>(r)), error_handler(std::move(eh)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_coroutine>(lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
basic_coroutine(lua_nil_t n)
|
||||
: base_t(n), error_handler(n) {
|
||||
}
|
||||
|
||||
basic_coroutine(lua_State* L, int index = -1)
|
||||
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
|
||||
}
|
||||
basic_coroutine(lua_State* L, int index, handler_t eh)
|
||||
: base_t(L, index), error_handler(std::move(eh)) {
|
||||
#ifdef SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_coroutine>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_coroutine(lua_State* L, absolute_index index)
|
||||
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
|
||||
}
|
||||
basic_coroutine(lua_State* L, absolute_index index, handler_t eh)
|
||||
: base_t(L, index), error_handler(std::move(eh)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_coroutine>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_coroutine(lua_State* L, raw_index index)
|
||||
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
|
||||
}
|
||||
basic_coroutine(lua_State* L, raw_index index, handler_t eh)
|
||||
: base_t(L, index), error_handler(std::move(eh)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_coroutine>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_coroutine(lua_State* L, ref_index index)
|
||||
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
|
||||
}
|
||||
basic_coroutine(lua_State* L, ref_index index, handler_t eh)
|
||||
: base_t(L, index), error_handler(std::move(eh)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_coroutine>(lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
call_status status() const noexcept {
|
||||
return stats;
|
||||
}
|
||||
|
||||
bool error() const noexcept {
|
||||
call_status cs = status();
|
||||
return cs != call_status::ok && cs != call_status::yielded;
|
||||
}
|
||||
|
||||
bool runnable() const noexcept {
|
||||
return base_t::valid()
|
||||
&& (status() == call_status::yielded);
|
||||
}
|
||||
|
||||
explicit operator bool() const noexcept {
|
||||
return runnable();
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
protected_function_result operator()(Args&&... args) {
|
||||
return call<>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Ret, typename... Args>
|
||||
decltype(auto) operator()(types<Ret...>, Args&&... args) {
|
||||
return call<Ret...>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Ret, typename... Args>
|
||||
decltype(auto) call(Args&&... args) {
|
||||
// some users screw up coroutine.create
|
||||
// and try to use it with sol::coroutine without ever calling the first resume in Lua
|
||||
// this makes the stack incompatible with other kinds of stacks: protect against this
|
||||
// make sure coroutines don't screw us over
|
||||
base_t::push();
|
||||
int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
|
||||
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount);
|
||||
}
|
||||
};
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_COUROUTINE_HPP
|
|
@ -1,56 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_DEBUG_HPP
|
||||
#define SOL_DEBUG_HPP
|
||||
|
||||
#include "stack.hpp"
|
||||
#include <iostream>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
namespace debug {
|
||||
inline std::string dump_types(lua_State* L) {
|
||||
std::string visual;
|
||||
std::size_t size = lua_gettop(L) + 1;
|
||||
for (std::size_t i = 1; i < size; ++i) {
|
||||
if (i != 1) {
|
||||
visual += " | ";
|
||||
}
|
||||
visual += type_name(L, stack::get<type>(L, static_cast<int>(i)));
|
||||
}
|
||||
return visual;
|
||||
}
|
||||
|
||||
inline void print_stack(lua_State* L) {
|
||||
std::cout << dump_types(L) << std::endl;
|
||||
}
|
||||
|
||||
inline void print_section(const std::string& message, lua_State* L) {
|
||||
std::cout << "-- " << message << " -- [ " << dump_types(L) << " ]" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace sol::detail::debug
|
||||
|
||||
#endif // SOL_DEBUG_HPP
|
|
@ -1,192 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_DEMANGLE_HPP
|
||||
#define SOL_DEMANGLE_HPP
|
||||
|
||||
#include "string_view.hpp"
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <cctype>
|
||||
#if defined(__GNUC__) && defined(__MINGW32__) && (__GNUC__ < 6)
|
||||
extern "C" {
|
||||
#include <ctype.h>
|
||||
}
|
||||
#endif // MinGW is on some stuff
|
||||
#include <locale>
|
||||
|
||||
namespace sol {
|
||||
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__)
|
||||
inline std::string ctti_get_type_name_from_sig(std::string name) {
|
||||
// cardinal sins from MINGW
|
||||
using namespace std;
|
||||
std::size_t start = name.find_first_of('[');
|
||||
start = name.find_first_of('=', start);
|
||||
std::size_t end = name.find_last_of(']');
|
||||
if (end == std::string::npos)
|
||||
end = name.size();
|
||||
if (start == std::string::npos)
|
||||
start = 0;
|
||||
if (start < name.size() - 1)
|
||||
start += 1;
|
||||
name = name.substr(start, end - start);
|
||||
start = name.rfind("seperator_mark");
|
||||
if (start != std::string::npos) {
|
||||
name.erase(start - 2, name.length());
|
||||
}
|
||||
while (!name.empty() && isblank(name.front()))
|
||||
name.erase(name.begin());
|
||||
while (!name.empty() && isblank(name.back()))
|
||||
name.pop_back();
|
||||
|
||||
for (std::size_t r = 0; r < removals.size(); ++r) {
|
||||
auto found = name.find(removals[r]);
|
||||
while (found != std::string::npos) {
|
||||
name.erase(found, removals[r].size());
|
||||
found = name.find(removals[r]);
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
template <typename T, class seperator_mark = int>
|
||||
inline std::string ctti_get_type_name() {
|
||||
return ctti_get_type_name_from_sig(__PRETTY_FUNCTION__);
|
||||
}
|
||||
#elif defined(_MSC_VER)
|
||||
inline std::string ctti_get_type_name_from_sig(std::string name) {
|
||||
std::size_t start = name.find("get_type_name");
|
||||
if (start == std::string::npos)
|
||||
start = 0;
|
||||
else
|
||||
start += 13;
|
||||
if (start < name.size() - 1)
|
||||
start += 1;
|
||||
std::size_t end = name.find_last_of('>');
|
||||
if (end == std::string::npos)
|
||||
end = name.size();
|
||||
name = name.substr(start, end - start);
|
||||
if (name.find("struct", 0) == 0)
|
||||
name.replace(0, 6, "", 0);
|
||||
if (name.find("class", 0) == 0)
|
||||
name.replace(0, 5, "", 0);
|
||||
while (!name.empty() && isblank(name.front()))
|
||||
name.erase(name.begin());
|
||||
while (!name.empty() && isblank(name.back()))
|
||||
name.pop_back();
|
||||
|
||||
for (std::size_t r = 0; r < removals.size(); ++r) {
|
||||
auto found = name.find(removals[r]);
|
||||
while (found != std::string::npos) {
|
||||
name.erase(found, removals[r].size());
|
||||
found = name.find(removals[r]);
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string ctti_get_type_name() {
|
||||
return ctti_get_type_name_from_sig(__FUNCSIG__);
|
||||
}
|
||||
#else
|
||||
#error Compiler not supported for demangling
|
||||
#endif // compilers
|
||||
|
||||
template <typename T>
|
||||
std::string demangle_once() {
|
||||
std::string realname = ctti_get_type_name<T>();
|
||||
return realname;
|
||||
}
|
||||
|
||||
inline std::string short_demangle_from_type_name(std::string realname) {
|
||||
// This isn't the most complete but it'll do for now...?
|
||||
static const std::array<std::string, 10> ops = {{"operator<", "operator<<", "operator<<=", "operator<=", "operator>", "operator>>", "operator>>=", "operator>=", "operator->", "operator->*"}};
|
||||
int level = 0;
|
||||
std::ptrdiff_t idx = 0;
|
||||
for (idx = static_cast<std::ptrdiff_t>(realname.empty() ? 0 : realname.size() - 1); idx > 0; --idx) {
|
||||
if (level == 0 && realname[idx] == ':') {
|
||||
break;
|
||||
}
|
||||
bool isleft = realname[idx] == '<';
|
||||
bool isright = realname[idx] == '>';
|
||||
if (!isleft && !isright)
|
||||
continue;
|
||||
bool earlybreak = false;
|
||||
for (const auto& op : ops) {
|
||||
std::size_t nisop = realname.rfind(op, idx);
|
||||
if (nisop == std::string::npos)
|
||||
continue;
|
||||
std::size_t nisopidx = idx - op.size() + 1;
|
||||
if (nisop == nisopidx) {
|
||||
idx = static_cast<std::ptrdiff_t>(nisopidx);
|
||||
earlybreak = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (earlybreak) {
|
||||
continue;
|
||||
}
|
||||
level += isleft ? -1 : 1;
|
||||
}
|
||||
if (idx > 0) {
|
||||
realname.erase(0, realname.length() < static_cast<std::size_t>(idx) ? realname.length() : idx + 1);
|
||||
}
|
||||
return realname;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string short_demangle_once() {
|
||||
std::string realname = ctti_get_type_name<T>();
|
||||
return short_demangle_from_type_name(realname);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const std::string& demangle() {
|
||||
static const std::string d = demangle_once<T>();
|
||||
return d;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const std::string& short_demangle() {
|
||||
static const std::string d = short_demangle_once<T>();
|
||||
return d;
|
||||
}
|
||||
}
|
||||
} // namespace sol::detail
|
||||
|
||||
#endif // SOL_DEMANGLE_HPP
|
|
@ -1,46 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_DEPRECATE_HPP
|
||||
#define SOL_DEPRECATE_HPP
|
||||
|
||||
#ifndef SOL_DEPRECATED
|
||||
#ifdef _MSC_VER
|
||||
#define SOL_DEPRECATED __declspec(deprecated)
|
||||
#elif __GNUC__
|
||||
#define SOL_DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
#define SOL_DEPRECATED [[deprecated]]
|
||||
#endif // compilers
|
||||
#endif // SOL_DEPRECATED
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
struct SOL_DEPRECATED deprecate_type {
|
||||
using type = T;
|
||||
};
|
||||
}
|
||||
} // namespace sol::detail
|
||||
|
||||
#endif // SOL_DEPRECATE_HPP
|
|
@ -1,77 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_DUMP_HANDLER_HPP
|
||||
#define SOL_DUMP_HANDLER_HPP
|
||||
|
||||
#include "compatibility.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
|
||||
namespace sol {
|
||||
|
||||
class dump_error : public error {
|
||||
private:
|
||||
int ec_;
|
||||
|
||||
public:
|
||||
dump_error(int error_code_) : error("dump returned non-zero error of " + std::to_string(error_code_)), ec_(error_code_) {
|
||||
}
|
||||
|
||||
int error_code() const {
|
||||
return ec_;
|
||||
}
|
||||
};
|
||||
|
||||
inline int dump_pass_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
|
||||
(void)L;
|
||||
(void)writer_function;
|
||||
(void)userdata;
|
||||
(void)strip;
|
||||
return result_code;
|
||||
}
|
||||
|
||||
inline int dump_panic_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
|
||||
(void)L;
|
||||
(void)writer_function;
|
||||
(void)userdata;
|
||||
(void)strip;
|
||||
return luaL_error(L, "a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code);
|
||||
}
|
||||
|
||||
inline int dump_throw_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
|
||||
#if defined(SOL_NO_EXCEPTIONS) && SOL_NO_EXCEPTIONS != 0
|
||||
return dump_panic_on_error(L, result_code, writer_function, userdata, strip);
|
||||
#else
|
||||
(void)L;
|
||||
(void)writer_function;
|
||||
(void)userdata;
|
||||
(void)strip;
|
||||
throw dump_error(result_code);
|
||||
#endif // no exceptions stuff
|
||||
}
|
||||
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_DUMP_HANDLER_HPP
|
|
@ -1,158 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_EBCO_HPP
|
||||
#define SOL_EBCO_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace sol { namespace detail {
|
||||
|
||||
template <typename T, std::size_t tag = 0, typename = void>
|
||||
struct ebco {
|
||||
T value_;
|
||||
|
||||
ebco() = default;
|
||||
ebco(const ebco&) = default;
|
||||
ebco(ebco&&) = default;
|
||||
ebco& operator=(const ebco&) = default;
|
||||
ebco& operator=(ebco&&) = default;
|
||||
ebco(const T& v) : value_(v){};
|
||||
ebco(T&& v) : value_(std::move(v)){};
|
||||
ebco& operator=(const T& v) {
|
||||
value_ = v;
|
||||
return *this;
|
||||
}
|
||||
ebco& operator=(T&& v) {
|
||||
value_ = std::move(v);
|
||||
return *this;
|
||||
};
|
||||
template <typename Arg, typename... Args,
|
||||
typename = std::enable_if_t<!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
|
||||
ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T>>>
|
||||
ebco(Arg&& arg, Args&&... args) : T(std::forward<Arg>(arg), std::forward<Args>(args)...){}
|
||||
|
||||
T& value() & {
|
||||
return value_;
|
||||
}
|
||||
|
||||
T const& value() const & {
|
||||
return value_;
|
||||
}
|
||||
|
||||
T&& value() && {
|
||||
return std::move(value_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, std::size_t tag>
|
||||
struct ebco<T, tag, std::enable_if_t<!std::is_reference_v<T> && std::is_class_v<T> && !std::is_final_v<T>>> : T {
|
||||
ebco() = default;
|
||||
ebco(const ebco&) = default;
|
||||
ebco(ebco&&) = default;
|
||||
ebco(const T& v) : T(v){};
|
||||
ebco(T&& v) : T(std::move(v)){};
|
||||
template <typename Arg, typename... Args,
|
||||
typename = std::enable_if_t<!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
|
||||
ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T>>>
|
||||
ebco(Arg&& arg, Args&&... args) : T(std::forward<Arg>(arg), std::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
ebco& operator=(const ebco&) = default;
|
||||
ebco& operator=(ebco&&) = default;
|
||||
ebco& operator=(const T& v) {
|
||||
static_cast<T&>(*this) = v;
|
||||
return *this;
|
||||
}
|
||||
ebco& operator=(T&& v) {
|
||||
static_cast<T&>(*this) = std::move(v);
|
||||
return *this;
|
||||
};
|
||||
|
||||
T& value() & {
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
T const& value() const & {
|
||||
return static_cast<T const&>(*this);
|
||||
}
|
||||
|
||||
T&& value() && {
|
||||
return std::move(static_cast<T&>(*this));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, std::size_t tag>
|
||||
struct ebco<T&, tag> {
|
||||
T& ref;
|
||||
|
||||
ebco() = default;
|
||||
ebco(const ebco&) = default;
|
||||
ebco(ebco&&) = default;
|
||||
ebco(T& v) : ref(v){};
|
||||
|
||||
ebco& operator=(const ebco&) = default;
|
||||
ebco& operator=(ebco&&) = default;
|
||||
ebco& operator=(T& v) {
|
||||
ref = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& value() const {
|
||||
return const_cast<ebco<T&, tag>&>(*this).ref;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, std::size_t tag>
|
||||
struct ebco<T&&, tag> {
|
||||
T&& ref;
|
||||
|
||||
ebco() = default;
|
||||
ebco(const ebco&) = default;
|
||||
ebco(ebco&&) = default;
|
||||
ebco(T&& v) : ref(v){};
|
||||
|
||||
ebco& operator=(const ebco&) = default;
|
||||
ebco& operator=(ebco&&) = default;
|
||||
ebco& operator=(T&& v) {
|
||||
ref = std::move(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& value() & {
|
||||
return ref;
|
||||
}
|
||||
|
||||
const T& value() const & {
|
||||
return ref;
|
||||
}
|
||||
|
||||
T&& value() && {
|
||||
return std::move(ref);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace sol::detail
|
||||
|
||||
#endif // SOL_EBCO_HPP
|
|
@ -1,228 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_ENVIRONMENT_HPP
|
||||
#define SOL_ENVIRONMENT_HPP
|
||||
|
||||
#include "table.hpp"
|
||||
|
||||
namespace sol {
|
||||
|
||||
template <typename base_type>
|
||||
struct basic_environment : basic_table<base_type> {
|
||||
private:
|
||||
typedef basic_table<base_type> base_t;
|
||||
|
||||
public:
|
||||
using base_t::lua_state;
|
||||
|
||||
basic_environment() noexcept = default;
|
||||
basic_environment(const basic_environment&) = default;
|
||||
basic_environment(basic_environment&&) = default;
|
||||
basic_environment& operator=(const basic_environment&) = default;
|
||||
basic_environment& operator=(basic_environment&&) = default;
|
||||
basic_environment(const stack_reference& r)
|
||||
: basic_environment(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
basic_environment(stack_reference&& r)
|
||||
: basic_environment(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
|
||||
basic_environment(lua_State* L, new_table nt)
|
||||
: base_t(L, std::move(nt)) {
|
||||
}
|
||||
template <bool b>
|
||||
basic_environment(lua_State* L, new_table t, const basic_reference<b>& fallback)
|
||||
: basic_environment(L, std::move(t)) {
|
||||
stack_table mt(L, new_table(0, 1));
|
||||
mt.set(meta_function::index, fallback);
|
||||
this->set(metatable_key, mt);
|
||||
mt.pop();
|
||||
}
|
||||
|
||||
basic_environment(env_key_t, const stack_reference& extraction_target)
|
||||
: base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<env_key_t>(this->lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
lua_pop(this->lua_state(), 2);
|
||||
}
|
||||
template <bool b>
|
||||
basic_environment(env_key_t, const basic_reference<b>& extraction_target)
|
||||
: base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<env_key_t>(this->lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
lua_pop(this->lua_state(), 2);
|
||||
}
|
||||
basic_environment(lua_State* L, int index = -1)
|
||||
: base_t(detail::no_safety, L, index) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_environment>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_environment(lua_State* L, ref_index index)
|
||||
: base_t(detail::no_safety, L, index) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_environment>(L, -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
template <typename T, meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_environment>>, 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>
|
||||
basic_environment(T&& r) noexcept
|
||||
: base_t(detail::no_safety, std::forward<T>(r)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
if (!is_environment<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_environment>(lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
basic_environment(lua_nil_t r) noexcept
|
||||
: base_t(detail::no_safety, r) {
|
||||
}
|
||||
|
||||
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_environment(lua_State* L, T&& r) noexcept
|
||||
: base_t(detail::no_safety, L, std::forward<T>(r)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
if (!is_environment<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_environment>(lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void set_on(const T& target) const {
|
||||
lua_State* L = target.lua_state();
|
||||
auto pp = stack::push_pop(target);
|
||||
#if SOL_LUA_VERSION < 502
|
||||
// Use lua_setfenv
|
||||
this->push();
|
||||
lua_setfenv(L, -2);
|
||||
#else
|
||||
// Use upvalues as explained in Lua 5.2 and beyond's manual
|
||||
this->push();
|
||||
const char* name = lua_setupvalue(L, -2, 1);
|
||||
if (name == nullptr) {
|
||||
this->pop();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename E>
|
||||
void set_environment(const basic_environment<E>& env, const T& target) {
|
||||
env.set_on(target);
|
||||
}
|
||||
|
||||
template <typename E = reference, typename T>
|
||||
basic_environment<E> get_environment(const T& target) {
|
||||
lua_State* L = target.lua_state();
|
||||
auto pp = stack::pop_n(L, stack::push_environment_of(target));
|
||||
return basic_environment<E>(L, -1);
|
||||
}
|
||||
|
||||
struct this_environment {
|
||||
optional<environment> env;
|
||||
|
||||
this_environment()
|
||||
: env(nullopt) {
|
||||
}
|
||||
this_environment(environment e)
|
||||
: env(std::move(e)) {
|
||||
}
|
||||
this_environment(const this_environment&) = default;
|
||||
this_environment(this_environment&&) = default;
|
||||
this_environment& operator=(const this_environment&) = default;
|
||||
this_environment& operator=(this_environment&&) = default;
|
||||
|
||||
explicit operator bool() const {
|
||||
return static_cast<bool>(env);
|
||||
}
|
||||
|
||||
operator optional<environment>&() {
|
||||
return env;
|
||||
}
|
||||
|
||||
operator const optional<environment>&() const {
|
||||
return env;
|
||||
}
|
||||
|
||||
operator environment&() {
|
||||
return env.value();
|
||||
}
|
||||
|
||||
operator const environment&() const {
|
||||
return env.value();
|
||||
}
|
||||
};
|
||||
|
||||
namespace stack {
|
||||
template <>
|
||||
struct unqualified_getter<env_key_t> {
|
||||
static environment get(lua_State* L, int index, record& tracking) {
|
||||
tracking.use(1);
|
||||
return get_environment(stack_reference(L, raw_index(index)));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unqualified_getter<this_environment> {
|
||||
static this_environment get(lua_State* L, int, record& tracking) {
|
||||
tracking.use(0);
|
||||
lua_Debug info;
|
||||
// Level 0 means current function (this C function, which may or may not be useful for us?)
|
||||
// Level 1 means next call frame up the stack. (Can be nothing if function called directly from C++ with lua_p/call)
|
||||
int pre_stack_size = lua_gettop(L);
|
||||
if (lua_getstack(L, 1, &info) != 1) {
|
||||
if (lua_getstack(L, 0, &info) != 1) {
|
||||
lua_settop(L, pre_stack_size);
|
||||
return this_environment();
|
||||
}
|
||||
}
|
||||
if (lua_getinfo(L, "f", &info) == 0) {
|
||||
lua_settop(L, pre_stack_size);
|
||||
return this_environment();
|
||||
}
|
||||
|
||||
stack_reference f(L, -1);
|
||||
environment env(env_key, f);
|
||||
if (!env.valid()) {
|
||||
lua_settop(L, pre_stack_size);
|
||||
return this_environment();
|
||||
}
|
||||
return this_environment(std::move(env));
|
||||
}
|
||||
};
|
||||
} // namespace stack
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_ENVIRONMENT_HPP
|
|
@ -1,89 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_ERROR_HPP
|
||||
#define SOL_ERROR_HPP
|
||||
|
||||
#include "compatibility.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <array>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
struct direct_error_tag {};
|
||||
const auto direct_error = direct_error_tag{};
|
||||
|
||||
struct error_result {
|
||||
int results;
|
||||
const char* format_string;
|
||||
std::array<const char*, 4> args_strings;
|
||||
|
||||
error_result() : results(0), format_string(nullptr) {
|
||||
}
|
||||
|
||||
error_result(int results) : results(results), format_string(nullptr) {
|
||||
}
|
||||
|
||||
error_result(const char* fmt, const char* msg) : results(0), format_string(fmt) {
|
||||
args_strings[0] = msg;
|
||||
}
|
||||
};
|
||||
|
||||
inline int handle_errors(lua_State* L, const error_result& er) {
|
||||
if (er.format_string == nullptr) {
|
||||
return er.results;
|
||||
}
|
||||
return luaL_error(L, er.format_string, er.args_strings[0], er.args_strings[1], er.args_strings[2], er.args_strings[3]);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
class error : public std::runtime_error {
|
||||
private:
|
||||
// Because VC++ is upsetting, most of the time!
|
||||
std::string what_reason;
|
||||
|
||||
public:
|
||||
error(const std::string& str) : error(detail::direct_error, "lua: error: " + str) {
|
||||
}
|
||||
error(std::string&& str) : error(detail::direct_error, "lua: error: " + std::move(str)) {
|
||||
}
|
||||
error(detail::direct_error_tag, const std::string& str) : std::runtime_error(""), what_reason(str) {
|
||||
}
|
||||
error(detail::direct_error_tag, std::string&& str) : std::runtime_error(""), what_reason(std::move(str)) {
|
||||
}
|
||||
|
||||
error(const error& e) = default;
|
||||
error(error&& e) = default;
|
||||
error& operator=(const error& e) = default;
|
||||
error& operator=(error&& e) = default;
|
||||
|
||||
virtual const char* what() const noexcept override {
|
||||
return what_reason.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_ERROR_HPP
|
|
@ -1,175 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_ERROR_HANDLER_HPP
|
||||
#define SOL_ERROR_HANDLER_HPP
|
||||
|
||||
#include "types.hpp"
|
||||
#include "demangle.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
namespace sol {
|
||||
|
||||
namespace detail {
|
||||
constexpr const char* not_a_number = "not a numeric type";
|
||||
constexpr const char* not_a_number_or_number_string = "not a numeric type or numeric string";
|
||||
constexpr const char* not_a_number_integral = "not a numeric type that fits exactly an integer (number maybe has significant decimals)";
|
||||
constexpr const char* not_a_number_or_number_string_integral
|
||||
= "not a numeric type or a numeric string that fits exactly an integer (e.g. number maybe has significant decimals)";
|
||||
|
||||
constexpr const char* not_enough_stack_space = "not enough space left on Lua stack";
|
||||
constexpr const char* not_enough_stack_space_floating = "not enough space left on Lua stack for a floating point number";
|
||||
constexpr const char* not_enough_stack_space_integral = "not enough space left on Lua stack for an integral number";
|
||||
constexpr const char* not_enough_stack_space_string = "not enough space left on Lua stack for a string";
|
||||
constexpr const char* not_enough_stack_space_meta_function_name = "not enough space left on Lua stack for the name of a meta_function";
|
||||
constexpr const char* not_enough_stack_space_userdata = "not enough space left on Lua stack to create a sol3 userdata";
|
||||
constexpr const char* not_enough_stack_space_generic = "not enough space left on Lua stack to push valuees";
|
||||
constexpr const char* not_enough_stack_space_environment = "not enough space left on Lua stack to retrieve environment";
|
||||
constexpr const char* protected_function_error = "caught (...) unknown error during protected_function call";
|
||||
|
||||
inline void accumulate_and_mark(const std::string& n, std::string& aux_message, int& marker) {
|
||||
if (marker > 0) {
|
||||
aux_message += ", ";
|
||||
}
|
||||
aux_message += n;
|
||||
++marker;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
inline std::string associated_type_name(lua_State* L, int index, type t) {
|
||||
switch (t) {
|
||||
case type::poly:
|
||||
return "anything";
|
||||
case type::userdata: {
|
||||
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
||||
luaL_checkstack(L, 2, "not enough space to push get the type name");
|
||||
#endif // make sure stack doesn't overflow
|
||||
if (lua_getmetatable(L, index) == 0) {
|
||||
break;
|
||||
}
|
||||
lua_pushlstring(L, "__name", 6);
|
||||
lua_rawget(L, -2);
|
||||
size_t sz;
|
||||
const char* name = lua_tolstring(L, -1, &sz);
|
||||
std::string tn(name, static_cast<std::string::size_type>(sz));
|
||||
lua_pop(L, 2);
|
||||
return tn;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return lua_typename(L, static_cast<int>(t));
|
||||
}
|
||||
|
||||
inline int push_type_panic_string(lua_State* L, int index, type expected, type actual, string_view message, string_view aux_message) noexcept {
|
||||
const char* err = message.size() == 0
|
||||
? (aux_message.size() == 0 ? "stack index %d, expected %s, received %s" : "stack index %d, expected %s, received %s: %s")
|
||||
: "stack index %d, expected %s, received %s: %s %s";
|
||||
const char* type_name = expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected));
|
||||
{
|
||||
std::string actual_name = associated_type_name(L, index, actual);
|
||||
lua_pushfstring(L, err, index, type_name, actual_name.c_str(), message.data(), aux_message.data());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int type_panic_string(lua_State* L, int index, type expected, type actual, string_view message = "") noexcept(false) {
|
||||
push_type_panic_string(L, index, expected, actual, message, "");
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
inline int type_panic_c_str(lua_State* L, int index, type expected, type actual, const char* message = nullptr) noexcept(false) {
|
||||
push_type_panic_string(L, index, expected, actual, message == nullptr ? "" : message, "");
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
struct type_panic_t {
|
||||
int operator()(lua_State* L, int index, type expected, type actual) const noexcept(false) {
|
||||
return type_panic_c_str(L, index, expected, actual, nullptr);
|
||||
}
|
||||
int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
|
||||
return type_panic_c_str(L, index, expected, actual, message.data());
|
||||
}
|
||||
};
|
||||
|
||||
const type_panic_t type_panic = {};
|
||||
|
||||
struct constructor_handler {
|
||||
int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
|
||||
push_type_panic_string(L, index, expected, actual, message, "(type check failed in constructor)");
|
||||
return lua_error(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F = void>
|
||||
struct argument_handler {
|
||||
int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
|
||||
push_type_panic_string(L, index, expected, actual, message, "(bad argument to variable or function call)");
|
||||
return lua_error(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct argument_handler<types<R, Args...>> {
|
||||
int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
|
||||
{
|
||||
std::string aux_message = "(bad argument into '";
|
||||
aux_message += detail::demangle<R>();
|
||||
aux_message += "(";
|
||||
int marker = 0;
|
||||
(void)detail::swallow { int(), (detail::accumulate_and_mark(detail::demangle<Args>(), aux_message, marker), int())... };
|
||||
aux_message += ")')";
|
||||
push_type_panic_string(L, index, expected, actual, message, aux_message);
|
||||
}
|
||||
return lua_error(L);
|
||||
}
|
||||
};
|
||||
|
||||
// Specify this function as the handler for lua::check if you know there's nothing wrong
|
||||
inline int no_panic(lua_State*, int, type, type, const char* = nullptr) noexcept {
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void type_error(lua_State* L, int expected, int actual) noexcept(false) {
|
||||
luaL_error(L, "expected %s, received %s", lua_typename(L, expected), lua_typename(L, actual));
|
||||
}
|
||||
|
||||
inline void type_error(lua_State* L, type expected, type actual) noexcept(false) {
|
||||
type_error(L, static_cast<int>(expected), static_cast<int>(actual));
|
||||
}
|
||||
|
||||
inline void type_assert(lua_State* L, int index, type expected, type actual) noexcept(false) {
|
||||
if (expected != type::poly && expected != actual) {
|
||||
type_panic_c_str(L, index, expected, actual, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
inline void type_assert(lua_State* L, int index, type expected) {
|
||||
type actual = type_of(L, index);
|
||||
type_assert(L, index, expected, actual);
|
||||
}
|
||||
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_ERROR_HANDLER_HPP
|
|
@ -1,54 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_FEATURE_TEST_HPP
|
||||
#define SOL_FEATURE_TEST_HPP
|
||||
|
||||
#if (defined(__cplusplus) && __cplusplus >= 201703L) \
|
||||
|| (defined(_MSC_VER) && _MSC_VER > 1900 && ((defined(_HAS_CXX17) && _HAS_CXX17 == 1) || (defined(_MSVC_LANG) && (_MSVC_LANG > 201402L))))
|
||||
#endif // C++17 features check
|
||||
|
||||
// There is a bug in the VC++ compiler??
|
||||
// on /std:c++latest under x86 conditions (VS 15.5.2),
|
||||
// compiler errors are tossed for noexcept markings being on function types
|
||||
// that are identical in every other way to their non-noexcept marked types function types...
|
||||
// 2020: There is absolutely a bug.
|
||||
#if defined(__cpp_noexcept_function_type) || ((defined(_MSC_VER) && _MSC_VER > 1911) && (defined(_MSVC_LANG) && ((_MSVC_LANG >= 201403L))))
|
||||
#ifndef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
#define SOL_NOEXCEPT_FUNCTION_TYPE 1
|
||||
#endif // noexcept is part of a function's type
|
||||
#endif // compiler-specific checks
|
||||
#if defined(__clang__) && defined(__APPLE__)
|
||||
#if defined(__has_include)
|
||||
#if __has_include(<variant>)
|
||||
#define SOL_STD_VARIANT 1
|
||||
#endif // has include nonsense
|
||||
#endif // __has_include
|
||||
#else
|
||||
#define SOL_STD_VARIANT 1
|
||||
#endif // Clang screws up variant
|
||||
|
||||
#include <sol/config.hpp>
|
||||
#include "version.hpp"
|
||||
|
||||
#endif // SOL_FEATURE_TEST_HPP
|
|
@ -1,480 +0,0 @@
|
|||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// This file was generated with a script.
|
||||
// Generated 2019-05-29 20:53:05.788092 UTC
|
||||
// This header was generated with sol v3.0.2 (revision 46a2b01)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP
|
||||
#define SOL_SINGLE_INCLUDE_FORWARD_HPP
|
||||
|
||||
// beginning of sol/forward.hpp
|
||||
|
||||
#ifndef SOL_FORWARD_HPP
|
||||
#define SOL_FORWARD_HPP
|
||||
|
||||
// beginning of sol/feature_test.hpp
|
||||
|
||||
#if (defined(__cplusplus) && __cplusplus == 201703L) || (defined(_MSC_VER) && _MSC_VER > 1900 && ((defined(_HAS_CXX17) && _HAS_CXX17 == 1) || (defined(_MSVC_LANG) && (_MSVC_LANG > 201402L))))
|
||||
#ifndef SOL_CXX17_FEATURES
|
||||
#define SOL_CXX17_FEATURES 1
|
||||
#endif // C++17 features macro
|
||||
#endif // C++17 features check
|
||||
|
||||
#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES
|
||||
#if defined(__cpp_noexcept_function_type) || ((defined(_MSC_VER) && _MSC_VER > 1911) && (defined(_MSVC_LANG) && ((_MSVC_LANG >= 201403L))))
|
||||
#ifndef SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
#define SOL_NOEXCEPT_FUNCTION_TYPE 1
|
||||
#endif // noexcept is part of a function's type
|
||||
#endif // compiler-specific checks
|
||||
#if defined(__clang__) && defined(__APPLE__)
|
||||
#if defined(__has_include)
|
||||
#if __has_include(<variant>)
|
||||
#define SOL_STD_VARIANT 1
|
||||
#endif // has include nonsense
|
||||
#endif // __has_include
|
||||
#else
|
||||
#define SOL_STD_VARIANT 1
|
||||
#endif // Clang screws up variant
|
||||
#endif // C++17 only
|
||||
|
||||
// beginning of sol/config.hpp
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_DEBUG) && !defined(NDEBUG)
|
||||
#ifndef SOL_IN_DEBUG_DETECTED
|
||||
#define SOL_IN_DEBUG_DETECTED 1
|
||||
#endif
|
||||
#endif // VC++ Debug macros
|
||||
|
||||
#if !defined(_CPPUNWIND)
|
||||
#if !defined(SOL_NO_EXCEPTIONS)
|
||||
#define SOL_NO_EXCEPTIONS 1
|
||||
#endif
|
||||
#endif // Automatic Exceptions
|
||||
|
||||
#if !defined(_CPPRTTI)
|
||||
#if !defined(SOL_NO_RTTI)
|
||||
#define SOL_NO_RTTI 1
|
||||
#endif
|
||||
#endif // Automatic RTTI
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
#if !defined(NDEBUG) && !defined(__OPTIMIZE__)
|
||||
#if !defined(SOL_IN_DEBUG_DETECTED)
|
||||
#define SOL_IN_DEBUG_DETECTED 1
|
||||
#endif
|
||||
#endif // Not Debug && g++ optimizer flag
|
||||
|
||||
#if !defined(__EXCEPTIONS)
|
||||
#if !defined(SOL_NO_EXCEPTIONS)
|
||||
#define SOL_NO_EXCEPTIONS 1
|
||||
#endif
|
||||
#endif // No Exceptions
|
||||
|
||||
#if !defined(__GXX_RTTI)
|
||||
#if !defined(SOL_NO_RTTI)
|
||||
#define SOL_NO_RTTI 1
|
||||
#endif
|
||||
#endif // No RTTI
|
||||
|
||||
#endif // vc++ || clang++/g++
|
||||
|
||||
#if defined(SOL_CHECK_ARGUMENTS) && SOL_CHECK_ARGUMENTS
|
||||
#if defined(SOL_ALL_SAFETIES_ON)
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
#endif // turn all the safeties on
|
||||
#endif // Compatibility define
|
||||
|
||||
#if defined(SOL_ALL_SAFETIES_ON) && SOL_ALL_SAFETIES_ON
|
||||
|
||||
// Checks low-level getter function
|
||||
// (and thusly, affects nearly entire framework)
|
||||
#if !defined(SOL_SAFE_GETTER)
|
||||
#define SOL_SAFE_GETTER 1
|
||||
#endif
|
||||
|
||||
// Checks access on usertype functions
|
||||
// local my_obj = my_type.new()
|
||||
// my_obj.my_member_function()
|
||||
// -- bad syntax and crash
|
||||
#if !defined(SOL_SAFE_USERTYPE)
|
||||
#define SOL_SAFE_USERTYPE 1
|
||||
#endif
|
||||
|
||||
// Checks sol::reference derived boundaries
|
||||
// sol::function ref(L, 1);
|
||||
// sol::userdata sref(L, 2);
|
||||
#if !defined(SOL_SAFE_REFERENCES)
|
||||
#define SOL_SAFE_REFERENCES 1
|
||||
#endif
|
||||
|
||||
// Changes all typedefs of sol::function to point to the
|
||||
// protected_function version, instead of unsafe_function
|
||||
#if !defined(SOL_SAFE_FUNCTION)
|
||||
#define SOL_SAFE_FUNCTION 1
|
||||
#endif
|
||||
|
||||
// Checks function parameters and
|
||||
// returns upon call into/from Lua
|
||||
// local a = 1
|
||||
// local b = "woof"
|
||||
// my_c_function(a, b)
|
||||
#if !defined(SOL_SAFE_FUNCTION_CALLS)
|
||||
#define SOL_SAFE_FUNCTION_CALLS 1
|
||||
#endif
|
||||
|
||||
// Checks conversions
|
||||
// int v = lua["bark"];
|
||||
// int v2 = my_sol_function();
|
||||
#if !defined(SOL_SAFE_PROXIES)
|
||||
#define SOL_SAFE_PROXIES 1
|
||||
#endif
|
||||
|
||||
// Check overflowing number conversions
|
||||
// for things like 64 bit integers that don't fit in a typical lua_Number
|
||||
// for Lua 5.1 and 5.2
|
||||
#if !defined(SOL_SAFE_NUMERICS)
|
||||
#define SOL_SAFE_NUMERICS 1
|
||||
#endif
|
||||
|
||||
// Turn off Number Precision Checks
|
||||
// if this is defined, we do not do range
|
||||
// checks on integers / unsigned integers that might
|
||||
// be bigger than what Lua can represent
|
||||
#if !defined(SOL_NO_CHECK_NUMBER_PRECISION)
|
||||
// off by default
|
||||
#define SOL_NO_CHECK_NUMBER_PRECISION 0
|
||||
#endif
|
||||
|
||||
// Print any exceptions / errors that occur
|
||||
// in debug mode to the default error stream / console
|
||||
#if !defined(SOL_SAFE_STACK_CHECK)
|
||||
#define SOL_SAFE_STACK_CHECK 1
|
||||
#endif
|
||||
|
||||
#endif // Turn on Safety for all if top-level macro is defined
|
||||
|
||||
#if defined(SOL_IN_DEBUG_DETECTED) && SOL_IN_DEBUG_DETECTED
|
||||
|
||||
#if !defined(SOL_SAFE_REFERENCES)
|
||||
// Ensure that references are forcefully type-checked upon construction
|
||||
#define SOL_SAFE_REFERENCES 1
|
||||
#endif
|
||||
|
||||
// Safe usertypes checks for errors such as
|
||||
// obj = my_type.new()
|
||||
// obj.f() -- note the '.' instead of ':'
|
||||
// usertypes should be safe no matter what
|
||||
#if !defined(SOL_SAFE_USERTYPE)
|
||||
#define SOL_SAFE_USERTYPE 1
|
||||
#endif
|
||||
|
||||
#if !defined(SOL_SAFE_FUNCTION_CALLS)
|
||||
// Function calls from Lua should be automatically safe in debug mode
|
||||
#define SOL_SAFE_FUNCTION_CALLS 1
|
||||
#endif
|
||||
|
||||
// Print any exceptions / errors that occur
|
||||
// in debug mode to the default error stream / console
|
||||
#if !defined(SOL_PRINT_ERRORS)
|
||||
#define SOL_PRINT_ERRORS 1
|
||||
#endif
|
||||
|
||||
// Print any exceptions / errors that occur
|
||||
// in debug mode to the default error stream / console
|
||||
#if !defined(SOL_SAFE_STACK_CHECK)
|
||||
#define SOL_SAFE_STACK_CHECK 1
|
||||
#endif
|
||||
|
||||
#endif // DEBUG: Turn on all debug safety features for VC++ / g++ / clang++ and similar
|
||||
|
||||
#if !defined(SOL_PRINT_ERRORS)
|
||||
#define SOL_PRINT_ERRORS 0
|
||||
#endif
|
||||
|
||||
#if !defined(SOL_DEFAULT_PASS_ON_ERROR)
|
||||
#define SOL_DEFAULT_PASS_ON_ERROR 0
|
||||
#endif
|
||||
|
||||
#if !defined(SOL_ENABLE_INTEROP)
|
||||
#define SOL_ENABLE_INTEROP 0
|
||||
#endif
|
||||
|
||||
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) || defined(__OBJC__) || defined(nil)
|
||||
#if !defined(SOL_NO_NIL)
|
||||
#define SOL_NO_NIL 1
|
||||
#endif
|
||||
#endif // avoiding nil defines / keywords
|
||||
|
||||
#if defined(SOL_USE_BOOST) && SOL_USE_BOOST
|
||||
#if !defined(SOL_UNORDERED_MAP_COMPATIBLE_HASH)
|
||||
#define SOL_UNORDERED_MAP_COMPATIBLE_HASH 1
|
||||
#endif // SOL_UNORDERED_MAP_COMPATIBLE_HASH
|
||||
#endif
|
||||
|
||||
#ifndef SOL_STACK_STRING_OPTIMIZATION_SIZE
|
||||
#define SOL_STACK_STRING_OPTIMIZATION_SIZE 1024
|
||||
#endif // Optimized conversion routines using a KB or so off the stack
|
||||
|
||||
#if !defined(SOL_SAFE_STACK_CHECK)
|
||||
#define SOL_SAFE_STACK_CHECK 0
|
||||
#endif // use luaL_checkstack to check stack overflow / overrun
|
||||
|
||||
// end of sol/config.hpp
|
||||
|
||||
// beginning of sol/config_setup.hpp
|
||||
|
||||
// end of sol/config_setup.hpp
|
||||
|
||||
// end of sol/feature_test.hpp
|
||||
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
#if defined(SOL_USING_CXX_LUA) && SOL_USING_CXX_LUA
|
||||
struct lua_State;
|
||||
#else
|
||||
extern "C" {
|
||||
struct lua_State;
|
||||
}
|
||||
#endif // C++ Mangling for Lua vs. Not
|
||||
|
||||
namespace sol {
|
||||
|
||||
template <bool b>
|
||||
class basic_reference;
|
||||
using reference = basic_reference<false>;
|
||||
using main_reference = basic_reference<true>;
|
||||
class stack_reference;
|
||||
|
||||
template <typename A>
|
||||
class basic_bytecode;
|
||||
|
||||
struct lua_value;
|
||||
|
||||
struct proxy_base_tag;
|
||||
template <typename>
|
||||
struct proxy_base;
|
||||
template <typename, typename>
|
||||
struct proxy;
|
||||
|
||||
template <bool, typename>
|
||||
class basic_table_core;
|
||||
template <bool b>
|
||||
using table_core = basic_table_core<b, reference>;
|
||||
template <bool b>
|
||||
using main_table_core = basic_table_core<b, main_reference>;
|
||||
template <bool b>
|
||||
using stack_table_core = basic_table_core<b, stack_reference>;
|
||||
template <typename base_type>
|
||||
using basic_table = basic_table_core<false, base_type>;
|
||||
using table = table_core<false>;
|
||||
using global_table = table_core<true>;
|
||||
using main_table = main_table_core<false>;
|
||||
using main_global_table = main_table_core<true>;
|
||||
using stack_table = stack_table_core<false>;
|
||||
using stack_global_table = stack_table_core<true>;
|
||||
|
||||
template <typename>
|
||||
struct basic_lua_table;
|
||||
using lua_table = basic_lua_table<reference>;
|
||||
using stack_lua_table = basic_lua_table<stack_reference>;
|
||||
|
||||
template <typename T, typename base_type>
|
||||
class basic_usertype;
|
||||
template <typename T>
|
||||
using usertype = basic_usertype<T, reference>;
|
||||
template <typename T>
|
||||
using stack_usertype = basic_usertype<T, stack_reference>;
|
||||
|
||||
template <typename base_type>
|
||||
class basic_metatable;
|
||||
using metatable = basic_metatable<reference>;
|
||||
using stack_metatable = basic_metatable<stack_reference>;
|
||||
|
||||
template <typename base_t>
|
||||
struct basic_environment;
|
||||
using environment = basic_environment<reference>;
|
||||
using main_environment = basic_environment<main_reference>;
|
||||
using stack_environment = basic_environment<stack_reference>;
|
||||
|
||||
template <typename T, bool>
|
||||
class basic_function;
|
||||
template <typename T, bool, typename H>
|
||||
class basic_protected_function;
|
||||
using unsafe_function = basic_function<reference, false>;
|
||||
using safe_function = basic_protected_function<reference, false, reference>;
|
||||
using main_unsafe_function = basic_function<main_reference, false>;
|
||||
using main_safe_function = basic_protected_function<main_reference, false, reference>;
|
||||
using stack_unsafe_function = basic_function<stack_reference, false>;
|
||||
using stack_safe_function = basic_protected_function<stack_reference, false, reference>;
|
||||
using stack_aligned_unsafe_function = basic_function<stack_reference, true>;
|
||||
using stack_aligned_safe_function = basic_protected_function<stack_reference, true, reference>;
|
||||
using protected_function = safe_function;
|
||||
using main_protected_function = main_safe_function;
|
||||
using stack_protected_function = stack_safe_function;
|
||||
using stack_aligned_protected_function = stack_aligned_safe_function;
|
||||
#if defined(SOL_SAFE_FUNCTION) && SOL_SAFE_FUNCTION
|
||||
using function = protected_function;
|
||||
using main_function = main_protected_function;
|
||||
using stack_function = stack_protected_function;
|
||||
#else
|
||||
using function = unsafe_function;
|
||||
using main_function = main_unsafe_function;
|
||||
using stack_function = stack_unsafe_function;
|
||||
#endif
|
||||
using stack_aligned_function = stack_aligned_unsafe_function;
|
||||
using stack_aligned_stack_handler_function = basic_protected_function<stack_reference, true, stack_reference>;
|
||||
|
||||
struct unsafe_function_result;
|
||||
struct protected_function_result;
|
||||
using safe_function_result = protected_function_result;
|
||||
#if defined(SOL_SAFE_FUNCTION) && SOL_SAFE_FUNCTION
|
||||
using function_result = safe_function_result;
|
||||
#else
|
||||
using function_result = unsafe_function_result;
|
||||
#endif
|
||||
|
||||
template <typename base_t>
|
||||
class basic_object_base;
|
||||
template <typename base_t>
|
||||
class basic_object;
|
||||
template <typename base_t>
|
||||
class basic_userdata;
|
||||
template <typename base_t>
|
||||
class basic_lightuserdata;
|
||||
template <typename base_t>
|
||||
class basic_coroutine;
|
||||
template <typename base_t>
|
||||
class basic_thread;
|
||||
|
||||
using object = basic_object<reference>;
|
||||
using userdata = basic_userdata<reference>;
|
||||
using lightuserdata = basic_lightuserdata<reference>;
|
||||
using thread = basic_thread<reference>;
|
||||
using coroutine = basic_coroutine<reference>;
|
||||
using main_object = basic_object<main_reference>;
|
||||
using main_userdata = basic_userdata<main_reference>;
|
||||
using main_lightuserdata = basic_lightuserdata<main_reference>;
|
||||
using main_coroutine = basic_coroutine<main_reference>;
|
||||
using stack_object = basic_object<stack_reference>;
|
||||
using stack_userdata = basic_userdata<stack_reference>;
|
||||
using stack_lightuserdata = basic_lightuserdata<stack_reference>;
|
||||
using stack_thread = basic_thread<stack_reference>;
|
||||
using stack_coroutine = basic_coroutine<stack_reference>;
|
||||
|
||||
struct stack_proxy_base;
|
||||
struct stack_proxy;
|
||||
struct variadic_args;
|
||||
struct variadic_results;
|
||||
struct stack_count;
|
||||
struct this_state;
|
||||
struct this_main_state;
|
||||
struct this_environment;
|
||||
|
||||
class state_view;
|
||||
class state;
|
||||
|
||||
template <typename T>
|
||||
struct as_table_t;
|
||||
template <typename T>
|
||||
struct as_container_t;
|
||||
template <typename T>
|
||||
struct nested;
|
||||
template <typename T>
|
||||
struct light;
|
||||
template <typename T>
|
||||
struct user;
|
||||
template <typename T>
|
||||
struct as_args_t;
|
||||
template <typename T>
|
||||
struct protect_t;
|
||||
template <typename F, typename... Policies>
|
||||
struct policy_wrapper;
|
||||
|
||||
template <typename T>
|
||||
struct usertype_traits;
|
||||
template <typename T>
|
||||
struct unique_usertype_traits;
|
||||
|
||||
template <typename... Args>
|
||||
struct types {
|
||||
typedef std::make_index_sequence<sizeof...(Args)> indices;
|
||||
static constexpr std::size_t size() {
|
||||
return sizeof...(Args);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct derive : std::false_type {
|
||||
typedef types<> type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct base : std::false_type {
|
||||
typedef types<> type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct weak_derive {
|
||||
static bool value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool weak_derive<T>::value = false;
|
||||
|
||||
namespace stack {
|
||||
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
|
||||
|
||||
#define SOL_BASE_CLASSES(T, ...) \
|
||||
namespace sol { \
|
||||
template <> \
|
||||
struct base<T> : std::true_type { \
|
||||
typedef ::sol::types<__VA_ARGS__> type; \
|
||||
}; \
|
||||
} \
|
||||
void a_sol3_detail_function_decl_please_no_collide()
|
||||
#define SOL_DERIVED_CLASSES(T, ...) \
|
||||
namespace sol { \
|
||||
template <> \
|
||||
struct derive<T> : std::true_type { \
|
||||
typedef ::sol::types<__VA_ARGS__> type; \
|
||||
}; \
|
||||
} \
|
||||
void a_sol3_detail_function_decl_please_no_collide()
|
||||
|
||||
#endif // SOL_FORWARD_HPP
|
||||
// end of sol/forward.hpp
|
||||
|
||||
#endif // SOL_SINGLE_INCLUDE_FORWARD_HPP
|
|
@ -1,59 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_FORWARD_DETAIL_HPP
|
||||
#define SOL_FORWARD_DETAIL_HPP
|
||||
|
||||
#include "feature_test.hpp"
|
||||
#include "forward.hpp"
|
||||
#include "traits.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
const bool default_safe_function_calls =
|
||||
#if defined(SOL_SAFE_FUNCTION_CALLS) && SOL_SAFE_FUNCTION_CALLS
|
||||
true;
|
||||
#else
|
||||
false;
|
||||
#endif
|
||||
} // namespace detail
|
||||
|
||||
|
||||
namespace meta {
|
||||
namespace meta_detail {
|
||||
}
|
||||
} // namespace meta::meta_detail
|
||||
|
||||
namespace stack {
|
||||
namespace stack_detail {
|
||||
using undefined_method_func = void (*)(stack_reference);
|
||||
|
||||
template <typename T>
|
||||
void set_undefined_methods_on(stack_reference);
|
||||
|
||||
struct undefined_metatable;
|
||||
}
|
||||
} // namespace stack::stack_detail
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_FORWARD_DETAIL_HPP
|
|
@ -1,142 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_FUNCTION_HPP
|
||||
#define SOL_FUNCTION_HPP
|
||||
|
||||
#include "stack.hpp"
|
||||
#include "unsafe_function.hpp"
|
||||
#include "protected_function.hpp"
|
||||
#include "bytecode.hpp"
|
||||
#include <functional>
|
||||
|
||||
namespace sol {
|
||||
template <typename... Ret, typename... Args>
|
||||
decltype(auto) stack_proxy::call(Args&&... args) {
|
||||
stack_function sf(this->lua_state(), this->stack_index());
|
||||
return sf.template call<Ret...>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
inline protected_function_result::protected_function_result(unsafe_function_result&& o) noexcept
|
||||
: L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()), popcount(o.return_count()), err(o.status()) {
|
||||
// Must be manual, otherwise destructor will screw us
|
||||
// return count being 0 is enough to keep things clean
|
||||
// but we will be thorough
|
||||
o.abandon();
|
||||
}
|
||||
|
||||
inline protected_function_result& protected_function_result::operator=(unsafe_function_result&& o) noexcept {
|
||||
L = o.lua_state();
|
||||
index = o.stack_index();
|
||||
returncount = o.return_count();
|
||||
popcount = o.return_count();
|
||||
err = o.status();
|
||||
// Must be manual, otherwise destructor will screw us
|
||||
// return count being 0 is enough to keep things clean
|
||||
// but we will be thorough
|
||||
o.abandon();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline unsafe_function_result::unsafe_function_result(protected_function_result&& o) noexcept
|
||||
: L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()) {
|
||||
// Must be manual, otherwise destructor will screw us
|
||||
// return count being 0 is enough to keep things clean
|
||||
// but we will be thorough
|
||||
o.abandon();
|
||||
}
|
||||
inline unsafe_function_result& unsafe_function_result::operator=(protected_function_result&& o) noexcept {
|
||||
L = o.lua_state();
|
||||
index = o.stack_index();
|
||||
returncount = o.return_count();
|
||||
// Must be manual, otherwise destructor will screw us
|
||||
// return count being 0 is enough to keep things clean
|
||||
// but we will be thorough
|
||||
o.abandon();
|
||||
return *this;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <typename... R>
|
||||
struct std_shim {
|
||||
unsafe_function lua_func_;
|
||||
|
||||
std_shim(unsafe_function lua_func) : lua_func_(std::move(lua_func)) {
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
meta::return_type_t<R...> operator()(Args&&... args) {
|
||||
return lua_func_.call<R...>(std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std_shim<void> {
|
||||
unsafe_function lua_func_;
|
||||
|
||||
std_shim(unsafe_function lua_func) : lua_func_(std::move(lua_func)) {
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void operator()(Args&&... args) {
|
||||
lua_func_.call<void>(std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
namespace stack {
|
||||
template <typename Signature>
|
||||
struct unqualified_getter<std::function<Signature>> {
|
||||
typedef meta::bind_traits<Signature> fx_t;
|
||||
typedef typename fx_t::args_list args_lists;
|
||||
typedef meta::tuple_types<typename fx_t::return_type> return_types;
|
||||
|
||||
template <typename... R>
|
||||
static std::function<Signature> get_std_func(types<R...>, lua_State* L, int index) {
|
||||
detail::std_shim<R...> fx(unsafe_function(L, index));
|
||||
return fx;
|
||||
}
|
||||
|
||||
static std::function<Signature> get(lua_State* L, int index, record& tracking) {
|
||||
tracking.use(1);
|
||||
type t = type_of(L, index);
|
||||
if (t == type::none || t == type::lua_nil) {
|
||||
return nullptr;
|
||||
}
|
||||
return get_std_func(return_types(), L, index);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Allocator>
|
||||
struct unqualified_getter<basic_bytecode<Allocator>> {
|
||||
static basic_bytecode<Allocator> get(lua_State* L, int index, record& tracking) {
|
||||
tracking.use(1);
|
||||
stack_function sf(L, index);
|
||||
return sf.dump(&dump_panic_on_error);
|
||||
}
|
||||
};
|
||||
} // namespace stack
|
||||
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_FUNCTION_HPP
|
|
@ -1,78 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_FUNCTION_RESULT_HPP
|
||||
#define SOL_FUNCTION_RESULT_HPP
|
||||
|
||||
#include "protected_function_result.hpp"
|
||||
#include "unsafe_function_result.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace sol {
|
||||
|
||||
namespace detail {
|
||||
template <>
|
||||
struct is_speshul<unsafe_function_result> : std::true_type {};
|
||||
template <>
|
||||
struct is_speshul<protected_function_result> : std::true_type {};
|
||||
|
||||
template <std::size_t I, typename... Args, typename T>
|
||||
stack_proxy get(types<Args...>, meta::index_value<0>, meta::index_value<I>, const T& fr) {
|
||||
return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
|
||||
}
|
||||
|
||||
template <std::size_t I, std::size_t N, typename Arg, typename... Args, typename T, meta::enable<meta::boolean<(N > 0)>> = meta::enabler>
|
||||
stack_proxy get(types<Arg, Args...>, meta::index_value<N>, meta::index_value<I>, const T& fr) {
|
||||
return get(types<Args...>(), meta::index_value<N - 1>(), meta::index_value<I + lua_size<Arg>::value>(), fr);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <>
|
||||
struct tie_size<unsafe_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
|
||||
|
||||
template <>
|
||||
struct tie_size<protected_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
|
||||
|
||||
template <std::size_t I>
|
||||
stack_proxy get(const unsafe_function_result& fr) {
|
||||
return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
|
||||
}
|
||||
|
||||
template <std::size_t I, typename... Args>
|
||||
stack_proxy get(types<Args...> t, const unsafe_function_result& fr) {
|
||||
return detail::get(t, meta::index_value<I>(), meta::index_value<0>(), fr);
|
||||
}
|
||||
|
||||
template <std::size_t I>
|
||||
stack_proxy get(const protected_function_result& fr) {
|
||||
return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
|
||||
}
|
||||
|
||||
template <std::size_t I, typename... Args>
|
||||
stack_proxy get(types<Args...> t, const protected_function_result& fr) {
|
||||
return detail::get(t, meta::index_value<I>(), meta::index_value<0>(), fr);
|
||||
}
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_FUNCTION_RESULT_HPP
|
|
@ -1,686 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_FUNCTION_TYPES_HPP
|
||||
#define SOL_FUNCTION_TYPES_HPP
|
||||
|
||||
#include "function_types_core.hpp"
|
||||
#include "function_types_templated.hpp"
|
||||
#include "function_types_stateless.hpp"
|
||||
#include "function_types_stateful.hpp"
|
||||
#include "function_types_overloaded.hpp"
|
||||
#include "resolve.hpp"
|
||||
#include "call.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace function_detail {
|
||||
template <typename T>
|
||||
struct class_indicator {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
struct call_indicator {};
|
||||
|
||||
template <bool yielding>
|
||||
int lua_c_wrapper(lua_State* L) {
|
||||
lua_CFunction cf = lua_tocfunction(L, lua_upvalueindex(2));
|
||||
int nr = cf(L);
|
||||
if constexpr (yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
template <bool yielding>
|
||||
int lua_c_noexcept_wrapper(lua_State* L) noexcept {
|
||||
detail::lua_CFunction_noexcept cf = reinterpret_cast<detail::lua_CFunction_noexcept>(lua_tocfunction(L, lua_upvalueindex(2)));
|
||||
int nr = cf(L);
|
||||
if constexpr (yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
struct c_function_invocation {};
|
||||
|
||||
template <bool is_yielding, typename Fx, typename... Args>
|
||||
void select(lua_State* L, Fx&& fx, Args&&... args);
|
||||
|
||||
template <bool is_yielding, bool no_trampoline, typename Fx, typename... Args>
|
||||
void select_set_fx(lua_State* L, Args&&... args) {
|
||||
lua_CFunction freefunc = no_trampoline ?
|
||||
detail::static_trampoline<function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>>
|
||||
: function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<Fx>>(L, std::forward<Args>(args)...);
|
||||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
|
||||
template <bool is_yielding, typename R, typename... A, typename Fx, typename... Args>
|
||||
void select_convertible(types<R(A...)>, lua_State* L, Fx&& fx, Args&&... args) {
|
||||
using dFx = std::decay_t<meta::unwrap_unqualified_t<Fx>>;
|
||||
using fx_ptr_t = R (*)(A...);
|
||||
constexpr bool is_convertible = std::is_convertible_v<dFx, fx_ptr_t>;
|
||||
if constexpr (is_convertible) {
|
||||
fx_ptr_t fxptr = detail::unwrap(std::forward<Fx>(fx));
|
||||
select<is_yielding>(L, std::move(fxptr), std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
using F = function_detail::functor_function<dFx, false, true>;
|
||||
select_set_fx<is_yielding, false, F>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <bool is_yielding, typename Fx, typename... Args>
|
||||
void select_convertible(types<>, lua_State* L, Fx&& fx, Args&&... args) {
|
||||
typedef meta::function_signature_t<meta::unwrap_unqualified_t<Fx>> Sig;
|
||||
select_convertible<is_yielding>(types<Sig>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <bool is_yielding, typename Fx, typename... Args>
|
||||
void select_member_variable(lua_State* L, Fx&& fx, Args&&... args) {
|
||||
using uFx = meta::unqualified_t<Fx>;
|
||||
if constexpr (sizeof...(Args) < 1) {
|
||||
using C = typename meta::bind_traits<uFx>::object_type;
|
||||
lua_CFunction freefunc = &function_detail::upvalue_this_member_variable<C, Fx, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::stack_detail::push_as_upvalues(L, fx);
|
||||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
else if constexpr (sizeof...(Args) < 2) {
|
||||
using Tu = typename meta::meta_detail::unqualified_non_alias<Args...>::type;
|
||||
constexpr bool is_reference = meta::is_specialization_of_v<Tu, std::reference_wrapper> || std::is_pointer_v<Tu>;
|
||||
if constexpr (meta::is_specialization_of_v<Tu, function_detail::class_indicator>) {
|
||||
lua_CFunction freefunc = &function_detail::upvalue_this_member_variable<typename Tu::type, Fx, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::stack_detail::push_as_upvalues(L, fx);
|
||||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
else if constexpr (is_reference) {
|
||||
typedef std::decay_t<Fx> dFx;
|
||||
dFx memfxptr(std::forward<Fx>(fx));
|
||||
auto userptr = detail::ptr(std::forward<Args>(args)...);
|
||||
lua_CFunction freefunc
|
||||
= &function_detail::upvalue_member_variable<std::decay_t<decltype(*userptr)>, meta::unqualified_t<Fx>, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::stack_detail::push_as_upvalues(L, memfxptr);
|
||||
upvalues += stack::push(L, static_cast<void const*>(userptr));
|
||||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
else {
|
||||
using clean_fx = std::remove_pointer_t<std::decay_t<Fx>>;
|
||||
using F = function_detail::member_variable<Tu, clean_fx, is_yielding>;
|
||||
select_set_fx<false, false, F>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
else {
|
||||
using C = typename meta::bind_traits<uFx>::object_type;
|
||||
using clean_fx = std::remove_pointer_t<std::decay_t<Fx>>;
|
||||
using F = function_detail::member_variable<C, clean_fx, is_yielding>;
|
||||
select_set_fx<false, false, F>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <bool is_yielding, typename Fx, typename T, typename... Args>
|
||||
void select_member_function_with(lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
|
||||
using dFx = std::decay_t<Fx>;
|
||||
using Tu = meta::unqualified_t<T>;
|
||||
if constexpr (meta::is_specialization_of_v<Tu, function_detail::class_indicator>) {
|
||||
(void)obj;
|
||||
using C = typename Tu::type;
|
||||
lua_CFunction freefunc = &function_detail::upvalue_this_member_function<C, dFx, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<dFx>>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
else {
|
||||
constexpr bool is_reference = meta::is_specialization_of_v<Tu, std::reference_wrapper> || std::is_pointer_v<Tu>;
|
||||
if constexpr (is_reference) {
|
||||
auto userptr = detail::ptr(std::forward<T>(obj));
|
||||
lua_CFunction freefunc = &function_detail::upvalue_member_function<std::decay_t<decltype(*userptr)>, dFx, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<dFx>>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
upvalues += stack::push(L, lightuserdata_value(static_cast<void*>(userptr)));
|
||||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
else {
|
||||
using F = function_detail::member_function<Tu, dFx, is_yielding>;
|
||||
select_set_fx<false, false, F>(L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <bool is_yielding, typename Fx, typename... Args>
|
||||
void select_member_function(lua_State* L, Fx&& fx, Args&&... args) {
|
||||
using dFx = std::decay_t<Fx>;
|
||||
if constexpr (sizeof...(Args) < 1) {
|
||||
using C = typename meta::bind_traits<meta::unqualified_t<Fx>>::object_type;
|
||||
lua_CFunction freefunc = &function_detail::upvalue_this_member_function<C, dFx, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<dFx>>(L, std::forward<Fx>(fx));
|
||||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
else {
|
||||
select_member_function_with<is_yielding>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <bool is_yielding, typename Fx, typename... Args>
|
||||
void select(lua_State* L, Fx&& fx, Args&&... args) {
|
||||
using uFx = meta::unqualified_t<Fx>;
|
||||
if constexpr (is_lua_reference_v<uFx>) {
|
||||
// TODO: hoist into lambda in this case for yielding???
|
||||
stack::push(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
else if constexpr (is_lua_c_function_v<uFx>) {
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push(L, std::forward<Fx>(fx));
|
||||
#if defined(SOL_NOEXCEPT_FUNCTION_TYPE) && SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
if constexpr (std::is_nothrow_invocable_r_v<int, uFx, lua_State*>) {
|
||||
detail::lua_CFunction_noexcept cf = &lua_c_noexcept_wrapper<is_yielding>;
|
||||
lua_pushcclosure(L, reinterpret_cast<lua_CFunction>(cf), 2);
|
||||
}
|
||||
else {
|
||||
lua_CFunction cf = &lua_c_wrapper<is_yielding>;
|
||||
lua_pushcclosure(L, cf, 2);
|
||||
}
|
||||
#else
|
||||
lua_CFunction cf = &function_detail::lua_c_wrapper<is_yielding>;
|
||||
lua_pushcclosure(L, cf, 2);
|
||||
#endif
|
||||
}
|
||||
else if constexpr (std::is_function_v<std::remove_pointer_t<uFx>>) {
|
||||
std::decay_t<Fx> target(std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
lua_CFunction freefunc = &function_detail::upvalue_free_function<Fx, is_yielding>::call;
|
||||
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::stack_detail::push_as_upvalues(L, target);
|
||||
stack::push(L, c_closure(freefunc, upvalues));
|
||||
}
|
||||
else if constexpr (std::is_member_function_pointer_v<uFx>) {
|
||||
select_member_function<is_yielding>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
else if constexpr (meta::is_member_object_v<uFx>) {
|
||||
select_member_variable<is_yielding>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
select_convertible<is_yielding>(types<>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
} // namespace function_detail
|
||||
|
||||
namespace stack {
|
||||
template <typename... Sigs>
|
||||
struct unqualified_pusher<function_sig<Sigs...>> {
|
||||
template <bool is_yielding, typename Arg0, typename... Args>
|
||||
static int push(lua_State* L, Arg0&& arg0, Args&&... args) {
|
||||
if constexpr (meta::is_specialization_of_v<meta::unqualified_t<Arg0>, std::function>) {
|
||||
if constexpr (is_yielding) {
|
||||
return stack::push<meta::unqualified_t<Arg0>>(L, detail::yield_tag, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
return stack::push(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
else {
|
||||
function_detail::select<is_yielding>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Arg0, typename... Args>
|
||||
static int push(lua_State* L, Arg0&& arg0, Args&&... args) {
|
||||
if constexpr (std::is_same_v<meta::unqualified_t<Arg0>, detail::yield_tag_t>) {
|
||||
push<true>(L, std::forward<Args>(args)...);
|
||||
}
|
||||
else if constexpr (meta::is_specialization_of_v<meta::unqualified_t<Arg0>, yielding_t>) {
|
||||
push<true>(L, std::forward<Arg0>(arg0).func, std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
push<false>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unqualified_pusher<yielding_t<T>> {
|
||||
template <typename... Args>
|
||||
static int push(lua_State* L, const yielding_t<T>& f, Args&&... args) {
|
||||
if constexpr (meta::is_specialization_of_v<meta::unqualified_t<T>, std::function>) {
|
||||
return stack::push<T>(L, detail::yield_tag, f.func, std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
function_detail::select<true>(L, f.func, std::forward<Args>(args)...);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static int push(lua_State* L, yielding_t<T>&& f, Args&&... args) {
|
||||
if constexpr (meta::is_specialization_of_v<meta::unqualified_t<T>, std::function>) {
|
||||
return stack::push<T>(L, detail::yield_tag, std::move(f.func), std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
function_detail::select<true>(L, std::move(f.func), std::forward<Args>(args)...);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Args>
|
||||
struct unqualified_pusher<function_arguments<T, Args...>> {
|
||||
template <std::size_t... I, typename FP>
|
||||
static int push_func(std::index_sequence<I...>, lua_State* L, FP&& fp) {
|
||||
return stack::push<T>(L, std::get<I>(std::forward<FP>(fp).arguments)...);
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const function_arguments<T, Args...>& fp) {
|
||||
return push_func(std::make_index_sequence<sizeof...(Args)>(), L, fp);
|
||||
}
|
||||
|
||||
static int push(lua_State* L, function_arguments<T, Args...>&& fp) {
|
||||
return push_func(std::make_index_sequence<sizeof...(Args)>(), L, std::move(fp));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Signature>
|
||||
struct unqualified_pusher<std::function<Signature>> {
|
||||
static int push(lua_State* L, detail::yield_tag_t, const std::function<Signature>& fx) {
|
||||
if (fx) {
|
||||
function_detail::select<true>(L, fx);
|
||||
return 1;
|
||||
}
|
||||
return stack::push(L, lua_nil);
|
||||
}
|
||||
|
||||
static int push(lua_State* L, detail::yield_tag_t, std::function<Signature>&& fx) {
|
||||
if (fx) {
|
||||
function_detail::select<true>(L, std::move(fx));
|
||||
return 1;
|
||||
}
|
||||
return stack::push(L, lua_nil);
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const std::function<Signature>& fx) {
|
||||
if (fx) {
|
||||
function_detail::select<false>(L, fx);
|
||||
return 1;
|
||||
}
|
||||
return stack::push(L, lua_nil);
|
||||
}
|
||||
|
||||
static int push(lua_State* L, std::function<Signature>&& fx) {
|
||||
if (fx) {
|
||||
function_detail::select<false>(L, std::move(fx));
|
||||
return 1;
|
||||
}
|
||||
return stack::push(L, lua_nil);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Signature>
|
||||
struct unqualified_pusher<Signature, std::enable_if_t<std::is_member_pointer<Signature>::value>> {
|
||||
template <typename... Args>
|
||||
static int push(lua_State* L, Args&&... args) {
|
||||
function_detail::select<false>(L, std::forward<Args>(args)...);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Signature>
|
||||
struct unqualified_pusher<Signature,
|
||||
std::enable_if_t<meta::all<std::is_function<std::remove_pointer_t<Signature>>, meta::neg<std::is_same<Signature, lua_CFunction>>,
|
||||
meta::neg<std::is_same<Signature, std::remove_pointer_t<lua_CFunction>>>
|
||||
#if defined(SOL_NOEXCEPT_FUNCTION_TYPE) && SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
,
|
||||
meta::neg<std::is_same<Signature, detail::lua_CFunction_noexcept>>,
|
||||
meta::neg<std::is_same<Signature, std::remove_pointer_t<detail::lua_CFunction_noexcept>>>
|
||||
#endif // noexcept function types
|
||||
>::value>> {
|
||||
template <typename F>
|
||||
static int push(lua_State* L, F&& f) {
|
||||
function_detail::select<false>(L, std::forward<F>(f));
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Functions>
|
||||
struct unqualified_pusher<overload_set<Functions...>> {
|
||||
static int push(lua_State* L, overload_set<Functions...>&& set) {
|
||||
using F = function_detail::overloaded_function<0, Functions...>;
|
||||
function_detail::select_set_fx<false, false, F>(L, std::move(set.functions));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const overload_set<Functions...>& set) {
|
||||
using F = function_detail::overloaded_function<0, Functions...>;
|
||||
function_detail::select_set_fx<false, false, F>(L, set.functions);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unqualified_pusher<protect_t<T>> {
|
||||
static int push(lua_State* L, protect_t<T>&& pw) {
|
||||
lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>, 2>;
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<protect_t<T>>>(L, std::move(pw.value));
|
||||
return stack::push(L, c_closure(cf, upvalues));
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const protect_t<T>& pw) {
|
||||
lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>, 2>;
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<protect_t<T>>>(L, pw.value);
|
||||
return stack::push(L, c_closure(cf, upvalues));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F, typename G>
|
||||
struct unqualified_pusher<property_wrapper<F, G>> {
|
||||
static int push(lua_State* L, property_wrapper<F, G>&& pw) {
|
||||
if constexpr (std::is_void_v<F>) {
|
||||
return stack::push(L, std::move(pw.write()));
|
||||
}
|
||||
else if constexpr (std::is_void_v<G>) {
|
||||
return stack::push(L, std::move(pw.read()));
|
||||
}
|
||||
else {
|
||||
return stack::push(L, overload(std::move(pw.read()), std::move(pw.write())));
|
||||
}
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const property_wrapper<F, G>& pw) {
|
||||
if constexpr (std::is_void_v<F>) {
|
||||
return stack::push(L, pw.write);
|
||||
}
|
||||
else if constexpr (std::is_void_v<G>) {
|
||||
return stack::push(L, pw.read);
|
||||
}
|
||||
else {
|
||||
return stack::push(L, overload(pw.read, pw.write));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unqualified_pusher<var_wrapper<T>> {
|
||||
static int push(lua_State* L, var_wrapper<T>&& vw) {
|
||||
return stack::push(L, std::move(vw.value()));
|
||||
}
|
||||
static int push(lua_State* L, const var_wrapper<T>& vw) {
|
||||
return stack::push(L, vw.value());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Functions>
|
||||
struct unqualified_pusher<factory_wrapper<Functions...>> {
|
||||
static int push(lua_State* L, const factory_wrapper<Functions...>& fw) {
|
||||
using F = function_detail::overloaded_function<0, Functions...>;
|
||||
function_detail::select_set_fx<false, false, F>(L, fw.functions);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int push(lua_State* L, factory_wrapper<Functions...>&& fw) {
|
||||
using F = function_detail::overloaded_function<0, Functions...>;
|
||||
function_detail::select_set_fx<false, false, F>(L, std::move(fw.functions));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const factory_wrapper<Functions...>& fw, function_detail::call_indicator) {
|
||||
using F = function_detail::overloaded_function<1, Functions...>;
|
||||
function_detail::select_set_fx<false, false, F>(L, fw.functions);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int push(lua_State* L, factory_wrapper<Functions...>&& fw, function_detail::call_indicator) {
|
||||
using F = function_detail::overloaded_function<1, Functions...>;
|
||||
function_detail::select_set_fx<false, false, F>(L, std::move(fw.functions));
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unqualified_pusher<no_construction> {
|
||||
static int push(lua_State* L, no_construction) {
|
||||
lua_CFunction cf = &function_detail::no_construction_error;
|
||||
return stack::push(L, cf);
|
||||
}
|
||||
|
||||
static int push(lua_State* L, no_construction c, function_detail::call_indicator) {
|
||||
return push(L, c);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unqualified_pusher<detail::tagged<T, no_construction>> {
|
||||
static int push(lua_State* L, no_construction) {
|
||||
lua_CFunction cf = &function_detail::no_construction_error;
|
||||
return stack::push(L, cf);
|
||||
}
|
||||
|
||||
static int push(lua_State* L, no_construction c, function_detail::call_indicator) {
|
||||
return push(L, c);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Lists>
|
||||
struct unqualified_pusher<detail::tagged<T, constructor_list<Lists...>>> {
|
||||
static int push(lua_State* L, detail::tagged<T, constructor_list<Lists...>>) {
|
||||
lua_CFunction cf = call_detail::construct<T, detail::default_safe_function_calls, true, Lists...>;
|
||||
return stack::push(L, cf);
|
||||
}
|
||||
|
||||
static int push(lua_State* L, constructor_list<Lists...>) {
|
||||
lua_CFunction cf = call_detail::construct<T, detail::default_safe_function_calls, true, Lists...>;
|
||||
return stack::push(L, cf);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename L0, typename... Lists>
|
||||
struct unqualified_pusher<constructor_list<L0, Lists...>> {
|
||||
typedef constructor_list<L0, Lists...> cl_t;
|
||||
static int push(lua_State* L, cl_t cl) {
|
||||
typedef typename meta::bind_traits<L0>::return_type T;
|
||||
return stack::push<detail::tagged<T, cl_t>>(L, cl);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... Fxs>
|
||||
struct unqualified_pusher<detail::tagged<T, constructor_wrapper<Fxs...>>> {
|
||||
static int push(lua_State* L, detail::tagged<T, constructor_wrapper<Fxs...>>&& c) {
|
||||
return push(L, std::move(c.value()));
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const detail::tagged<T, const constructor_wrapper<Fxs...>>& c) {
|
||||
return push(L, c.value());
|
||||
}
|
||||
|
||||
static int push(lua_State* L, constructor_wrapper<Fxs...>&& c) {
|
||||
lua_CFunction cf = call_detail::call_user<T, false, false, constructor_wrapper<Fxs...>, 2>;
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<constructor_wrapper<Fxs...>>>(L, std::move(c));
|
||||
return stack::push(L, c_closure(cf, upvalues));
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const constructor_wrapper<Fxs...>& c) {
|
||||
lua_CFunction cf = call_detail::call_user<T, false, false, constructor_wrapper<Fxs...>, 2>;
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<constructor_wrapper<Fxs...>>>(L, c);
|
||||
return stack::push(L, c_closure(cf, upvalues));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F, typename... Fxs>
|
||||
struct unqualified_pusher<constructor_wrapper<F, Fxs...>> {
|
||||
static int push(lua_State* L, const constructor_wrapper<F, Fxs...>& c) {
|
||||
typedef typename meta::bind_traits<F>::template arg_at<0> arg0;
|
||||
typedef meta::unqualified_t<std::remove_pointer_t<arg0>> T;
|
||||
return stack::push<detail::tagged<T, constructor_wrapper<F, Fxs...>>>(L, c);
|
||||
}
|
||||
|
||||
static int push(lua_State* L, constructor_wrapper<F, Fxs...>&& c) {
|
||||
typedef typename meta::bind_traits<F>::template arg_at<0> arg0;
|
||||
typedef meta::unqualified_t<std::remove_pointer_t<arg0>> T;
|
||||
return stack::push<detail::tagged<T, constructor_wrapper<F, Fxs...>>>(L, std::move(c));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unqualified_pusher<detail::tagged<T, destructor_wrapper<void>>> {
|
||||
static int push(lua_State* L, destructor_wrapper<void>) {
|
||||
lua_CFunction cf = detail::usertype_alloc_destruct<T>;
|
||||
return stack::push(L, cf);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Fx>
|
||||
struct unqualified_pusher<detail::tagged<T, destructor_wrapper<Fx>>> {
|
||||
static int push(lua_State* L, destructor_wrapper<Fx>&& c) {
|
||||
lua_CFunction cf = call_detail::call_user<T, false, false, destructor_wrapper<Fx>, 2>;
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<destructor_wrapper<Fx>>>(L, std::move(c));
|
||||
return stack::push(L, c_closure(cf, upvalues));
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const destructor_wrapper<Fx>& c) {
|
||||
lua_CFunction cf = call_detail::call_user<T, false, false, destructor_wrapper<Fx>, 2>;
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<destructor_wrapper<Fx>>>(L, c);
|
||||
return stack::push(L, c_closure(cf, upvalues));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Fx>
|
||||
struct unqualified_pusher<destructor_wrapper<Fx>> {
|
||||
static int push(lua_State* L, destructor_wrapper<Fx>&& c) {
|
||||
lua_CFunction cf = call_detail::call_user<void, false, false, destructor_wrapper<Fx>, 2>;
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<destructor_wrapper<Fx>>>(L, std::move(c));
|
||||
return stack::push(L, c_closure(cf, upvalues));
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const destructor_wrapper<Fx>& c) {
|
||||
lua_CFunction cf = call_detail::call_user<void, false, false, destructor_wrapper<Fx>, 2>;
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<destructor_wrapper<Fx>>>(L, c);
|
||||
return stack::push(L, c_closure(cf, upvalues));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F, typename... Policies>
|
||||
struct unqualified_pusher<policy_wrapper<F, Policies...>> {
|
||||
using P = policy_wrapper<F, Policies...>;
|
||||
|
||||
static int push(lua_State* L, const P& p) {
|
||||
lua_CFunction cf = call_detail::call_user<void, false, false, P, 2>;
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<P>>(L, p);
|
||||
return stack::push(L, c_closure(cf, upvalues));
|
||||
}
|
||||
|
||||
static int push(lua_State* L, P&& p) {
|
||||
lua_CFunction cf = call_detail::call_user<void, false, false, P, 2>;
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<P>>(L, std::move(p));
|
||||
return stack::push(L, c_closure(cf, upvalues));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename F, typename... Policies>
|
||||
struct unqualified_pusher<detail::tagged<T, policy_wrapper<F, Policies...>>> {
|
||||
using P = policy_wrapper<F, Policies...>;
|
||||
using Tagged = detail::tagged<T, P>;
|
||||
|
||||
static int push(lua_State* L, const Tagged& p) {
|
||||
lua_CFunction cf = call_detail::call_user<T, false, false, P, 2>;
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<P>>(L, p.value());
|
||||
return stack::push(L, c_closure(cf, upvalues));
|
||||
}
|
||||
|
||||
static int push(lua_State* L, Tagged&& p) {
|
||||
lua_CFunction cf = call_detail::call_user<T, false, false, P, 2>;
|
||||
int upvalues = 0;
|
||||
upvalues += stack::push(L, nullptr);
|
||||
upvalues += stack::push<user<P>>(L, std::move(p.value()));
|
||||
return stack::push(L, c_closure(cf, upvalues));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unqualified_pusher<push_invoke_t<T>> {
|
||||
static int push(lua_State* L, push_invoke_t<T>&& pi) {
|
||||
if constexpr (std::is_invocable_v<std::add_rvalue_reference_t<T>, lua_State*>) {
|
||||
return stack::push(L, std::move(pi.value())(L));
|
||||
}
|
||||
else {
|
||||
return stack::push(L, std::move(pi.value())());
|
||||
}
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const push_invoke_t<T>& pi) {
|
||||
if constexpr (std::is_invocable_v<const T, lua_State*>) {
|
||||
return stack::push(L, pi.value()(L));
|
||||
}
|
||||
else {
|
||||
return stack::push(L, pi.value()());
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace stack
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_FUNCTION_TYPES_HPP
|
|
@ -1,48 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_FUNCTION_TYPES_CORE_HPP
|
||||
#define SOL_FUNCTION_TYPES_CORE_HPP
|
||||
|
||||
#include "stack.hpp"
|
||||
#include "wrapper.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace sol {
|
||||
namespace function_detail {
|
||||
template <typename Fx, int start = 1, bool is_yielding = false>
|
||||
int call(lua_State* L) {
|
||||
Fx& fx = stack::get<user<Fx>>(L, upvalue_index(start));
|
||||
int nr = fx(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace sol::function_detail
|
||||
|
||||
#endif // SOL_FUNCTION_TYPES_CORE_HPP
|
|
@ -1,62 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_FUNCTION_TYPES_OVERLOAD_HPP
|
||||
#define SOL_FUNCTION_TYPES_OVERLOAD_HPP
|
||||
|
||||
#include "overload.hpp"
|
||||
#include "call.hpp"
|
||||
#include "function_types_core.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace function_detail {
|
||||
template <int start_skew, typename... Functions>
|
||||
struct overloaded_function {
|
||||
typedef std::tuple<Functions...> overload_list;
|
||||
typedef std::make_index_sequence<sizeof...(Functions)> indices;
|
||||
overload_list overloads;
|
||||
|
||||
overloaded_function(overload_list set)
|
||||
: overloads(std::move(set)) {
|
||||
}
|
||||
|
||||
overloaded_function(Functions... fxs)
|
||||
: overloads(fxs...) {
|
||||
}
|
||||
|
||||
template <typename Fx, std::size_t I, typename... R, typename... Args>
|
||||
static int call(types<Fx>, meta::index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int, overload_list& ol) {
|
||||
auto& func = std::get<I>(ol);
|
||||
int nr = call_detail::call_wrapped<void, true, false, start_skew>(L, func);
|
||||
return nr;
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
auto mfx = [](auto&&... args) { return call(std::forward<decltype(args)>(args)...); };
|
||||
return call_detail::overload_match<Functions...>(mfx, L, 1 + start_skew, overloads);
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace sol::function_detail
|
||||
|
||||
#endif // SOL_FUNCTION_TYPES_OVERLOAD_HPP
|
|
@ -1,138 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_FUNCTION_TYPES_STATEFUL_HPP
|
||||
#define SOL_FUNCTION_TYPES_STATEFUL_HPP
|
||||
|
||||
#include "function_types_core.hpp"
|
||||
#include "call.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace function_detail {
|
||||
template <typename Func, bool is_yielding, bool no_trampoline>
|
||||
struct functor_function {
|
||||
typedef std::decay_t<meta::unwrap_unqualified_t<Func>> function_type;
|
||||
function_type fx;
|
||||
|
||||
template <typename... Args>
|
||||
functor_function(function_type f, Args&&... args)
|
||||
: fx(std::move(f), std::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
int call(lua_State* L) {
|
||||
int nr = call_detail::call_wrapped<void, true, false>(L, fx);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
if (!no_trampoline) {
|
||||
auto f = [&](lua_State*) -> int { return this->call(L); };
|
||||
return detail::trampoline(L, f);
|
||||
}
|
||||
else {
|
||||
return call(L);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct member_function {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef meta::function_return_t<function_type> return_type;
|
||||
typedef meta::function_args_t<function_type> args_lists;
|
||||
function_type invocation;
|
||||
T member;
|
||||
|
||||
template <typename... Args>
|
||||
member_function(function_type f, Args&&... args)
|
||||
: invocation(std::move(f)), member(std::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
int call(lua_State* L) {
|
||||
int nr = call_detail::call_wrapped<T, true, false, -1>(L, invocation, detail::unwrap(detail::deref(member)));
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
auto f = [&](lua_State*) -> int { return this->call(L); };
|
||||
return detail::trampoline(L, f);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct member_variable {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef typename meta::bind_traits<function_type>::return_type return_type;
|
||||
typedef typename meta::bind_traits<function_type>::args_list args_lists;
|
||||
function_type var;
|
||||
T member;
|
||||
typedef std::add_lvalue_reference_t<meta::unwrapped_t<std::remove_reference_t<decltype(detail::deref(member))>>> M;
|
||||
|
||||
template <typename... Args>
|
||||
member_variable(function_type v, Args&&... args)
|
||||
: var(std::move(v)), member(std::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
int call(lua_State* L) {
|
||||
int nr;
|
||||
{
|
||||
M mem = detail::unwrap(detail::deref(member));
|
||||
switch (lua_gettop(L)) {
|
||||
case 0:
|
||||
nr = call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
|
||||
break;
|
||||
case 1:
|
||||
nr = call_detail::call_wrapped<T, false, false, -1>(L, var, mem);
|
||||
break;
|
||||
default:
|
||||
nr = luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
auto f = [&](lua_State*) -> int { return this->call(L); };
|
||||
return detail::trampoline(L, f);
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace sol::function_detail
|
||||
|
||||
#endif // SOL_FUNCTION_TYPES_STATEFUL_HPP
|
|
@ -1,264 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_FUNCTION_TYPES_STATELESS_HPP
|
||||
#define SOL_FUNCTION_TYPES_STATELESS_HPP
|
||||
|
||||
#include "stack.hpp"
|
||||
#include "call.hpp"
|
||||
#include "bind_traits.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace function_detail {
|
||||
template <typename Function, bool is_yielding>
|
||||
struct upvalue_free_function {
|
||||
using function_type = std::remove_pointer_t<std::decay_t<Function>>;
|
||||
using traits_type = meta::bind_traits<function_type>;
|
||||
|
||||
static int real_call(lua_State* L) noexcept(traits_type::is_noexcept) {
|
||||
auto udata = stack::stack_detail::get_as_upvalues<function_type*>(L);
|
||||
function_type* fx = udata.first;
|
||||
return call_detail::call_wrapped<void, true, false>(L, fx);
|
||||
}
|
||||
|
||||
static int call(lua_State* L) {
|
||||
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
return call(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct upvalue_member_function {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef lua_bind_traits<function_type> traits_type;
|
||||
|
||||
static int real_call(lua_State* L) noexcept(traits_type::is_noexcept) {
|
||||
// Layout:
|
||||
// idx 1...n: verbatim data of member function pointer
|
||||
// idx n + 1: is the object's void pointer
|
||||
// We don't need to store the size, because the other side is templated
|
||||
// with the same member function pointer type
|
||||
function_type& memfx = stack::get<user<function_type>>(L, upvalue_index(2));
|
||||
auto& item = *static_cast<T*>(stack::get<void*>(L, upvalue_index(3)));
|
||||
return call_detail::call_wrapped<T, true, false, -1>(L, memfx, item);
|
||||
}
|
||||
|
||||
static int call(lua_State* L) noexcept(traits_type::is_noexcept) {
|
||||
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
return call(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct upvalue_member_variable {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef lua_bind_traits<function_type> traits_type;
|
||||
|
||||
static int real_call(lua_State* L) noexcept(traits_type::is_noexcept) {
|
||||
// Layout:
|
||||
// idx 1...n: verbatim data of member variable pointer
|
||||
// idx n + 1: is the object's void pointer
|
||||
// We don't need to store the size, because the other side is templated
|
||||
// with the same member function pointer type
|
||||
auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
|
||||
auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
|
||||
auto& mem = *objdata.first;
|
||||
function_type& var = memberdata.first;
|
||||
switch (lua_gettop(L)) {
|
||||
case 0:
|
||||
return call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
|
||||
case 1:
|
||||
return call_detail::call_wrapped<T, false, false, -1>(L, var, mem);
|
||||
default:
|
||||
return luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
||||
}
|
||||
}
|
||||
|
||||
static int call(lua_State* L) noexcept(traits_type::is_noexcept) {
|
||||
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
return call(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct upvalue_member_variable<T, readonly_wrapper<Function>, is_yielding> {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef lua_bind_traits<function_type> traits_type;
|
||||
|
||||
static int real_call(lua_State* L) noexcept(traits_type::is_noexcept) {
|
||||
// Layout:
|
||||
// idx 1...n: verbatim data of member variable pointer
|
||||
// idx n + 1: is the object's void pointer
|
||||
// We don't need to store the size, because the other side is templated
|
||||
// with the same member function pointer type
|
||||
auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
|
||||
auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
|
||||
auto& mem = *objdata.first;
|
||||
function_type& var = memberdata.first;
|
||||
switch (lua_gettop(L)) {
|
||||
case 0:
|
||||
return call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
|
||||
default:
|
||||
return luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
||||
}
|
||||
}
|
||||
|
||||
static int call(lua_State* L) {
|
||||
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
return call(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct upvalue_this_member_function {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef lua_bind_traits<function_type> traits_type;
|
||||
|
||||
static int real_call(lua_State* L) noexcept(traits_type::is_noexcept) {
|
||||
// Layout:
|
||||
// idx 1...n: verbatim data of member variable pointer
|
||||
function_type& memfx = stack::get<user<function_type>>(L, upvalue_index(2));
|
||||
return call_detail::call_wrapped<T, false, false>(L, memfx);
|
||||
}
|
||||
|
||||
static int call(lua_State* L) {
|
||||
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
return call(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct upvalue_this_member_variable {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
|
||||
static int real_call(lua_State* L) noexcept(false) {
|
||||
// Layout:
|
||||
// idx 1...n: verbatim data of member variable pointer
|
||||
auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
|
||||
function_type& var = memberdata.first;
|
||||
switch (lua_gettop(L)) {
|
||||
case 1:
|
||||
return call_detail::call_wrapped<T, true, false>(L, var);
|
||||
case 2:
|
||||
return call_detail::call_wrapped<T, false, false>(L, var);
|
||||
default:
|
||||
return luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
||||
}
|
||||
}
|
||||
|
||||
static int call(lua_State* L) {
|
||||
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
return call(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Function, bool is_yielding>
|
||||
struct upvalue_this_member_variable<T, readonly_wrapper<Function>, is_yielding> {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef lua_bind_traits<function_type> traits_type;
|
||||
|
||||
static int real_call(lua_State* L) noexcept(false) {
|
||||
// Layout:
|
||||
// idx 1...n: verbatim data of member variable pointer
|
||||
auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L);
|
||||
function_type& var = memberdata.first;
|
||||
switch (lua_gettop(L)) {
|
||||
case 1:
|
||||
return call_detail::call_wrapped<T, true, false>(L, var);
|
||||
default:
|
||||
return luaL_error(L, "sol: incorrect number of arguments to member variable function");
|
||||
}
|
||||
}
|
||||
|
||||
static int call(lua_State* L) {
|
||||
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
|
||||
if (is_yielding) {
|
||||
return lua_yield(L, nr);
|
||||
}
|
||||
else {
|
||||
return nr;
|
||||
}
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
return call(L);
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace sol::function_detail
|
||||
|
||||
#endif // SOL_FUNCTION_TYPES_STATELESS_HPP
|
|
@ -1,154 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_FUNCTION_TYPES_TEMPLATED_HPP
|
||||
#define SOL_FUNCTION_TYPES_TEMPLATED_HPP
|
||||
|
||||
#include "call.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace function_detail {
|
||||
template <typename F, F fx>
|
||||
inline int call_wrapper_variable(std::false_type, lua_State* L) {
|
||||
typedef meta::bind_traits<meta::unqualified_t<F>> traits_type;
|
||||
typedef typename traits_type::args_list args_list;
|
||||
typedef meta::tuple_types<typename traits_type::return_type> return_type;
|
||||
return stack::call_into_lua(return_type(), args_list(), L, 1, fx);
|
||||
}
|
||||
|
||||
template <typename R, typename V, V, typename T>
|
||||
inline int call_set_assignable(std::false_type, T&&, lua_State* L) {
|
||||
return luaL_error(L, "cannot write to this type: copy assignment/constructor not available");
|
||||
}
|
||||
|
||||
template <typename R, typename V, V variable, typename T>
|
||||
inline int call_set_assignable(std::true_type, lua_State* L, T&& mem) {
|
||||
(mem.*variable) = stack::get<R>(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename R, typename V, V, typename T>
|
||||
inline int call_set_variable(std::false_type, lua_State* L, T&&) {
|
||||
return luaL_error(L, "cannot write to a const variable");
|
||||
}
|
||||
|
||||
template <typename R, typename V, V variable, typename T>
|
||||
inline int call_set_variable(std::true_type, lua_State* L, T&& mem) {
|
||||
return call_set_assignable<R, V, variable>(std::is_assignable<std::add_lvalue_reference_t<R>, R>(), L, std::forward<T>(mem));
|
||||
}
|
||||
|
||||
template <typename V, V variable>
|
||||
inline int call_wrapper_variable(std::true_type, lua_State* L) {
|
||||
typedef meta::bind_traits<meta::unqualified_t<V>> traits_type;
|
||||
typedef typename traits_type::object_type T;
|
||||
typedef typename traits_type::return_type R;
|
||||
auto& mem = stack::get<T>(L, 1);
|
||||
switch (lua_gettop(L)) {
|
||||
case 1: {
|
||||
decltype(auto) r = (mem.*variable);
|
||||
stack::push_reference(L, std::forward<decltype(r)>(r));
|
||||
return 1;
|
||||
}
|
||||
case 2:
|
||||
return call_set_variable<R, V, variable>(meta::neg<std::is_const<R>>(), L, mem);
|
||||
default:
|
||||
return luaL_error(L, "incorrect number of arguments to member variable function call");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename F, F fx>
|
||||
inline int call_wrapper_function(std::false_type, lua_State* L) {
|
||||
return call_wrapper_variable<F, fx>(std::is_member_object_pointer<F>(), L);
|
||||
}
|
||||
|
||||
template <typename F, F fx>
|
||||
inline int call_wrapper_function(std::true_type, lua_State* L) {
|
||||
return call_detail::call_wrapped<void, false, false>(L, fx);
|
||||
}
|
||||
|
||||
template <typename F, F fx>
|
||||
int call_wrapper_entry(lua_State* L) noexcept(meta::bind_traits<F>::is_noexcept) {
|
||||
return call_wrapper_function<F, fx>(std::is_member_function_pointer<meta::unqualified_t<F>>(), L);
|
||||
}
|
||||
|
||||
template <typename... Fxs>
|
||||
struct c_call_matcher {
|
||||
template <typename Fx, std::size_t I, typename R, typename... Args>
|
||||
int operator()(types<Fx>, meta::index_value<I>, types<R>, types<Args...>, lua_State* L, int, int) const {
|
||||
typedef meta::at_in_pack_t<I, Fxs...> target;
|
||||
return target::call(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F, F fx>
|
||||
inline int c_call_raw(std::true_type, lua_State* L) {
|
||||
return fx(L);
|
||||
}
|
||||
|
||||
template <typename F, F fx>
|
||||
inline int c_call_raw(std::false_type, lua_State* L) {
|
||||
#ifdef __clang__
|
||||
return detail::trampoline(L, function_detail::call_wrapper_entry<F, fx>);
|
||||
#else
|
||||
return detail::typed_static_trampoline<decltype(&function_detail::call_wrapper_entry<F, fx>), (&function_detail::call_wrapper_entry<F, fx>)>(L);
|
||||
#endif // fuck you clang :c
|
||||
}
|
||||
|
||||
} // namespace function_detail
|
||||
|
||||
template <typename F, F fx>
|
||||
inline int c_call(lua_State* L) {
|
||||
typedef meta::unqualified_t<F> Fu;
|
||||
typedef std::integral_constant<bool,
|
||||
std::is_same<Fu, lua_CFunction>::value
|
||||
#if defined(SOL_NOEXCEPT_FUNCTION_TYPE) && SOL_NOEXCEPT_FUNCTION_TYPE
|
||||
|| std::is_same<Fu, detail::lua_CFunction_noexcept>::value
|
||||
#endif
|
||||
>
|
||||
is_raw;
|
||||
return function_detail::c_call_raw<F, fx>(is_raw(), L);
|
||||
}
|
||||
|
||||
template <typename F, F f>
|
||||
struct wrap {
|
||||
typedef F type;
|
||||
|
||||
static int call(lua_State* L) {
|
||||
return c_call<type, f>(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Fxs>
|
||||
inline int c_call(lua_State* L) {
|
||||
if constexpr (sizeof...(Fxs) < 2) {
|
||||
using target = meta::at_in_pack_t<0, Fxs...>;
|
||||
return target::call(L);
|
||||
}
|
||||
else {
|
||||
return call_detail::overload_match_arity<typename Fxs::type...>(function_detail::c_call_matcher<Fxs...>(), L, lua_gettop(L), 1);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_FUNCTION_TYPES_TEMPLATED_HPP
|
|
@ -1,48 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_IN_PLACE_HPP
|
||||
#define SOL_IN_PLACE_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
namespace sol {
|
||||
|
||||
using in_place_t = std::in_place_t;
|
||||
constexpr std::in_place_t in_place {};
|
||||
constexpr std::in_place_t in_place_of {};
|
||||
|
||||
template <typename T>
|
||||
using in_place_type_t = std::in_place_type_t<T>;
|
||||
template <typename T>
|
||||
constexpr std::in_place_type_t<T> in_place_type {};
|
||||
|
||||
template <size_t I>
|
||||
using in_place_index_t = std::in_place_index_t<I>;
|
||||
template <size_t I>
|
||||
constexpr in_place_index_t<I> in_place_index {};
|
||||
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_IN_PLACE_HPP
|
|
@ -1,196 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_INHERITANCE_HPP
|
||||
#define SOL_INHERITANCE_HPP
|
||||
|
||||
#include "types.hpp"
|
||||
#include "usertype_traits.hpp"
|
||||
#include "unique_usertype_traits.hpp"
|
||||
|
||||
namespace sol {
|
||||
template <typename... Args>
|
||||
struct base_list {};
|
||||
template <typename... Args>
|
||||
using bases = base_list<Args...>;
|
||||
|
||||
typedef bases<> base_classes_tag;
|
||||
const auto base_classes = base_classes_tag();
|
||||
|
||||
template <typename... Args>
|
||||
struct is_to_stringable<base_list<Args...>> : std::false_type {};
|
||||
|
||||
namespace detail {
|
||||
|
||||
inline decltype(auto) base_class_check_key() {
|
||||
static const auto& key = "class_check";
|
||||
return key;
|
||||
}
|
||||
|
||||
inline decltype(auto) base_class_cast_key() {
|
||||
static const auto& key = "class_cast";
|
||||
return key;
|
||||
}
|
||||
|
||||
inline decltype(auto) base_class_index_propogation_key() {
|
||||
static const auto& key = u8"\xF0\x9F\x8C\xB2.index";
|
||||
return key;
|
||||
}
|
||||
|
||||
inline decltype(auto) base_class_new_index_propogation_key() {
|
||||
static const auto& key = u8"\xF0\x9F\x8C\xB2.new_index";
|
||||
return key;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct inheritance {
|
||||
typedef typename base<T>::type bases_t;
|
||||
|
||||
static bool type_check_bases(types<>, const string_view&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Base, typename... Args>
|
||||
static bool type_check_bases(types<Base, Args...>, const string_view& ti) {
|
||||
return ti == usertype_traits<Base>::qualified_name() || type_check_bases(types<Args...>(), ti);
|
||||
}
|
||||
|
||||
static bool type_check(const string_view& ti) {
|
||||
return ti == usertype_traits<T>::qualified_name() || type_check_bases(bases_t(), ti);
|
||||
}
|
||||
|
||||
template <typename ...Bases>
|
||||
static bool type_check_with(const string_view& ti) {
|
||||
return ti == usertype_traits<T>::qualified_name() || type_check_bases(types<Bases...>(), ti);
|
||||
}
|
||||
|
||||
static void* type_cast_bases(types<>, T*, const string_view&) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename Base, typename... Args>
|
||||
static void* type_cast_bases(types<Base, Args...>, T* data, const string_view& ti) {
|
||||
// Make sure to convert to T first, and then dynamic cast to the proper type
|
||||
return ti != usertype_traits<Base>::qualified_name() ? type_cast_bases(types<Args...>(), data, ti) : static_cast<void*>(static_cast<Base*>(data));
|
||||
}
|
||||
|
||||
static void* type_cast(void* voiddata, const string_view& ti) {
|
||||
T* data = static_cast<T*>(voiddata);
|
||||
return static_cast<void*>(ti != usertype_traits<T>::qualified_name() ? type_cast_bases(bases_t(), data, ti) : data);
|
||||
}
|
||||
|
||||
template <typename... Bases>
|
||||
static void* type_cast_with(void* voiddata, const string_view& ti) {
|
||||
T* data = static_cast<T*>(voiddata);
|
||||
return static_cast<void*>(ti != usertype_traits<T>::qualified_name() ? type_cast_bases(types<Bases...>(), data, ti) : data);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
static bool type_unique_cast_bases(types<>, void*, void*, const string_view&) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename U, typename Base, typename... Args>
|
||||
static int type_unique_cast_bases(types<Base, Args...>, void* source_data, void* target_data, const string_view& ti) {
|
||||
using uu_traits = unique_usertype_traits<U>;
|
||||
using base_ptr = typename uu_traits::template rebind_base<Base>;
|
||||
string_view base_ti = usertype_traits<Base>::qualified_name();
|
||||
if (base_ti == ti) {
|
||||
if (target_data != nullptr) {
|
||||
U* source = static_cast<U*>(source_data);
|
||||
base_ptr* target = static_cast<base_ptr*>(target_data);
|
||||
// perform proper derived -> base conversion
|
||||
*target = *source;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
return type_unique_cast_bases<U>(types<Args...>(), source_data, target_data, ti);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
static int type_unique_cast(void* source_data, void* target_data, const string_view& ti, const string_view& rebind_ti) {
|
||||
typedef unique_usertype_traits<U> uu_traits;
|
||||
if constexpr (is_base_rebindable_v<uu_traits>) {
|
||||
typedef typename uu_traits::template rebind_base<void> rebind_t;
|
||||
typedef meta::conditional_t<std::is_void<rebind_t>::value, types<>, bases_t> cond_bases_t;
|
||||
string_view this_rebind_ti = usertype_traits<rebind_t>::qualified_name();
|
||||
if (rebind_ti != this_rebind_ti) {
|
||||
// this is not even of the same unique type
|
||||
return 0;
|
||||
}
|
||||
string_view this_ti = usertype_traits<T>::qualified_name();
|
||||
if (ti == this_ti) {
|
||||
// direct match, return 1
|
||||
return 1;
|
||||
}
|
||||
return type_unique_cast_bases<U>(cond_bases_t(), source_data, target_data, ti);
|
||||
}
|
||||
else {
|
||||
(void)rebind_ti;
|
||||
string_view this_ti = usertype_traits<T>::qualified_name();
|
||||
if (ti == this_ti) {
|
||||
// direct match, return 1
|
||||
return 1;
|
||||
}
|
||||
return type_unique_cast_bases<U>(types<>(), source_data, target_data, ti);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename U, typename... Bases>
|
||||
static int type_unique_cast_with(void* source_data, void* target_data, const string_view& ti, const string_view& rebind_ti) {
|
||||
using uc_bases_t = types<Bases...>;
|
||||
typedef unique_usertype_traits<U> uu_traits;
|
||||
if constexpr (is_base_rebindable_v<uu_traits>) {
|
||||
using rebind_t = typename uu_traits::template rebind_base<void>;
|
||||
using cond_bases_t = meta::conditional_t<std::is_void<rebind_t>::value, types<>, uc_bases_t>;
|
||||
string_view this_rebind_ti = usertype_traits<rebind_t>::qualified_name();
|
||||
if (rebind_ti != this_rebind_ti) {
|
||||
// this is not even of the same unique type
|
||||
return 0;
|
||||
}
|
||||
string_view this_ti = usertype_traits<T>::qualified_name();
|
||||
if (ti == this_ti) {
|
||||
// direct match, return 1
|
||||
return 1;
|
||||
}
|
||||
return type_unique_cast_bases<U>(cond_bases_t(), source_data, target_data, ti);
|
||||
}
|
||||
else {
|
||||
(void)rebind_ti;
|
||||
string_view this_ti = usertype_traits<T>::qualified_name();
|
||||
if (ti == this_ti) {
|
||||
// direct match, return 1
|
||||
return 1;
|
||||
}
|
||||
return type_unique_cast_bases<U>(types<>(), source_data, target_data, ti);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
using inheritance_check_function = decltype(&inheritance<void>::type_check);
|
||||
using inheritance_cast_function = decltype(&inheritance<void>::type_cast);
|
||||
using inheritance_unique_cast_function = decltype(&inheritance<void>::type_unique_cast<void>);
|
||||
} // namespace detail
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_INHERITANCE_HPP
|
|
@ -1,149 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_LOAD_RESULT_HPP
|
||||
#define SOL_LOAD_RESULT_HPP
|
||||
|
||||
#include "stack.hpp"
|
||||
#include "function.hpp"
|
||||
#include "proxy_base.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace sol {
|
||||
struct load_result : public proxy_base<load_result> {
|
||||
private:
|
||||
lua_State* L;
|
||||
int index;
|
||||
int returncount;
|
||||
int popcount;
|
||||
load_status err;
|
||||
|
||||
public:
|
||||
load_result() = default;
|
||||
load_result(lua_State* Ls, int stackindex = -1, int retnum = 0, int popnum = 0, load_status lerr = load_status::ok) noexcept
|
||||
: L(Ls), index(stackindex), returncount(retnum), popcount(popnum), err(lerr) {
|
||||
}
|
||||
load_result(const load_result&) = default;
|
||||
load_result& operator=(const load_result&) = default;
|
||||
load_result(load_result&& o) noexcept : L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) {
|
||||
// Must be manual, otherwise destructor will screw us
|
||||
// return count being 0 is enough to keep things clean
|
||||
// but we will be thorough
|
||||
o.L = nullptr;
|
||||
o.index = 0;
|
||||
o.returncount = 0;
|
||||
o.popcount = 0;
|
||||
o.err = load_status::syntax;
|
||||
}
|
||||
load_result& operator=(load_result&& o) noexcept {
|
||||
L = o.L;
|
||||
index = o.index;
|
||||
returncount = o.returncount;
|
||||
popcount = o.popcount;
|
||||
err = o.err;
|
||||
// Must be manual, otherwise destructor will screw us
|
||||
// return count being 0 is enough to keep things clean
|
||||
// but we will be thorough
|
||||
o.L = nullptr;
|
||||
o.index = 0;
|
||||
o.returncount = 0;
|
||||
o.popcount = 0;
|
||||
o.err = load_status::syntax;
|
||||
return *this;
|
||||
}
|
||||
|
||||
load_status status() const noexcept {
|
||||
return err;
|
||||
}
|
||||
|
||||
bool valid() const noexcept {
|
||||
return status() == load_status::ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get() const {
|
||||
using UT = meta::unqualified_t<T>;
|
||||
if constexpr (meta::is_optional_v<UT>) {
|
||||
using ValueType = typename UT::value_type;
|
||||
if constexpr (std::is_same_v<ValueType, error>) {
|
||||
if (valid()) {
|
||||
return UT(nullopt);
|
||||
}
|
||||
return error(detail::direct_error, stack::get<std::string>(L, index));
|
||||
}
|
||||
else {
|
||||
if (!valid()) {
|
||||
return UT(nullopt);
|
||||
}
|
||||
return stack::get<UT>(L, index);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if constexpr (std::is_same_v<T, error>) {
|
||||
#if defined(SOL_SAFE_PROXIES) && SOL_SAFE_PROXIES != 0
|
||||
if (valid()) {
|
||||
type_panic_c_str(L, index, type_of(L, index), type::none, "expecting an error type (a string, from Lua)");
|
||||
}
|
||||
#endif // Check proxy type's safety
|
||||
return error(detail::direct_error, stack::get<std::string>(L, index));
|
||||
}
|
||||
else {
|
||||
#if defined(SOL_SAFE_PROXIES) && SOL_SAFE_PROXIES != 0
|
||||
if (!valid()) {
|
||||
type_panic_c_str(L, index, type_of(L, index), type::none);
|
||||
}
|
||||
#endif // Check proxy type's safety
|
||||
return stack::get<T>(L, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Ret, typename... Args>
|
||||
decltype(auto) call(Args&&... args) {
|
||||
#if !defined(__clang__) && defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 191200000
|
||||
// MSVC is ass sometimes
|
||||
return get<protected_function>().call<Ret...>(std::forward<Args>(args)...);
|
||||
#else
|
||||
return get<protected_function>().template call<Ret...>(std::forward<Args>(args)...);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
decltype(auto) operator()(Args&&... args) {
|
||||
return call<>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
lua_State* lua_state() const noexcept {
|
||||
return L;
|
||||
};
|
||||
int stack_index() const noexcept {
|
||||
return index;
|
||||
};
|
||||
|
||||
~load_result() {
|
||||
stack::remove(L, index, popcount);
|
||||
}
|
||||
};
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_LOAD_RESULT_HPP
|
|
@ -1,95 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_LUA_TABLE_HPP
|
||||
#define SOL_LUA_TABLE_HPP
|
||||
|
||||
#include "table_core.hpp"
|
||||
|
||||
namespace sol {
|
||||
|
||||
template <typename ref_t>
|
||||
struct basic_lua_table : basic_table_core<false, ref_t> {
|
||||
private:
|
||||
using base_t = basic_table_core<false, ref_t>;
|
||||
|
||||
friend class state;
|
||||
friend class state_view;
|
||||
|
||||
public:
|
||||
using base_t::lua_state;
|
||||
|
||||
basic_lua_table() noexcept = default;
|
||||
basic_lua_table(const basic_lua_table&) = default;
|
||||
basic_lua_table(basic_lua_table&&) = default;
|
||||
basic_lua_table& operator=(const basic_lua_table&) = default;
|
||||
basic_lua_table& operator=(basic_lua_table&&) = default;
|
||||
basic_lua_table(const stack_reference& r) : basic_lua_table(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
basic_lua_table(stack_reference&& r) : basic_lua_table(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_lua_table(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_lua_table>(lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_lua_table(lua_State* L, const new_table& nt) : base_t(L, nt) {
|
||||
if (!is_stack_based<meta::unqualified_t<ref_t>>::value) {
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
basic_lua_table(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_lua_table>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_lua_table(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_lua_table>(lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
template <typename T,
|
||||
meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_lua_table>>, meta::neg<std::is_same<ref_t, stack_reference>>,
|
||||
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_lua_table(T&& r) noexcept : basic_lua_table(detail::no_safety, std::forward<T>(r)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
if (!is_table<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_lua_table>(lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
basic_lua_table(lua_nil_t r) noexcept : basic_lua_table(detail::no_safety, r) {
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SOL_LUA_TABLE_HPP
|
|
@ -1,162 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_LUA_VALUE_HPP
|
||||
#define SOL_LUA_VALUE_HPP
|
||||
|
||||
#include "stack.hpp"
|
||||
#include "reference.hpp"
|
||||
#include "make_reference.hpp"
|
||||
|
||||
namespace sol {
|
||||
struct lua_value {
|
||||
public:
|
||||
struct arr : detail::ebco<std::initializer_list<lua_value>> {
|
||||
private:
|
||||
using base_t = detail::ebco<std::initializer_list<lua_value>>;
|
||||
|
||||
public:
|
||||
using base_t::base_t;
|
||||
};
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
using is_reference_or_lua_value_init_list
|
||||
= meta::any<meta::is_specialization_of<T, std::initializer_list>, std::is_same<T, reference>, std::is_same<T, arr>>;
|
||||
|
||||
template <typename T>
|
||||
using is_lua_value_single_constructible = meta::any<std::is_same<T, lua_value>, is_reference_or_lua_value_init_list<T>>;
|
||||
|
||||
static lua_State*& thread_local_lua_state() {
|
||||
#if SOL_ON(SOL_USE_THREAD_LOCAL_)
|
||||
static thread_local lua_State* L = nullptr;
|
||||
#else
|
||||
static lua_State* L = nullptr;
|
||||
#endif
|
||||
return L;
|
||||
}
|
||||
|
||||
reference ref_value;
|
||||
|
||||
public:
|
||||
static void set_lua_state(lua_State* L) {
|
||||
thread_local_lua_state() = L;
|
||||
}
|
||||
|
||||
template <typename T, meta::disable<is_reference_or_lua_value_init_list<meta::unqualified_t<T>>> = meta::enabler>
|
||||
lua_value(lua_State* L_, T&& value) : lua_value(((set_lua_state(L_)), std::forward<T>(value))) {
|
||||
}
|
||||
|
||||
template <typename T, meta::disable<is_lua_value_single_constructible<meta::unqualified_t<T>>> = meta::enabler>
|
||||
lua_value(T&& value) : ref_value(make_reference(thread_local_lua_state(), std::forward<T>(value))) {
|
||||
}
|
||||
|
||||
lua_value(lua_State* L_, std::initializer_list<std::pair<lua_value, lua_value>> il)
|
||||
: lua_value([&L_, &il]() {
|
||||
set_lua_state(L_);
|
||||
return std::move(il);
|
||||
}()) {
|
||||
}
|
||||
|
||||
lua_value(std::initializer_list<std::pair<lua_value, lua_value>> il) : ref_value(make_reference(thread_local_lua_state(), std::move(il))) {
|
||||
}
|
||||
|
||||
lua_value(lua_State* L_, arr il)
|
||||
: lua_value([&L_, &il]() {
|
||||
set_lua_state(L_);
|
||||
return std::move(il);
|
||||
}()) {
|
||||
}
|
||||
|
||||
lua_value(arr il) : ref_value(make_reference(thread_local_lua_state(), std::move(il.value()))) {
|
||||
}
|
||||
|
||||
lua_value(lua_State* L_, reference r)
|
||||
: lua_value([&L_, &r]() {
|
||||
set_lua_state(L_);
|
||||
return std::move(r);
|
||||
}()) {
|
||||
}
|
||||
|
||||
lua_value(reference r) : ref_value(std::move(r)) {
|
||||
}
|
||||
|
||||
lua_value(const lua_value&) noexcept = default;
|
||||
lua_value(lua_value&&) = default;
|
||||
lua_value& operator=(const lua_value&) = default;
|
||||
lua_value& operator=(lua_value&&) = default;
|
||||
|
||||
const reference& value() const& {
|
||||
return ref_value;
|
||||
}
|
||||
|
||||
reference& value() & {
|
||||
return ref_value;
|
||||
}
|
||||
|
||||
reference&& value() && {
|
||||
return std::move(ref_value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) as() const {
|
||||
ref_value.push();
|
||||
return stack::pop<T>(ref_value.lua_state());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is() const {
|
||||
int r = ref_value.registry_index();
|
||||
if (r == LUA_REFNIL)
|
||||
return meta::any_same<meta::unqualified_t<T>, lua_nil_t, nullopt_t, std::nullptr_t>::value ? true : false;
|
||||
if (r == LUA_NOREF)
|
||||
return false;
|
||||
auto pp = stack::push_pop(ref_value);
|
||||
return stack::check<T>(ref_value.lua_state(), -1, no_panic);
|
||||
}
|
||||
};
|
||||
|
||||
using array_value = typename lua_value::arr;
|
||||
|
||||
namespace stack {
|
||||
template <>
|
||||
struct unqualified_pusher<lua_value> {
|
||||
static int push(lua_State* L, const lua_value& lv) {
|
||||
return stack::push(L, lv.value());
|
||||
}
|
||||
|
||||
static int push(lua_State* L, lua_value&& lv) {
|
||||
return stack::push(L, std::move(lv).value());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unqualified_getter<lua_value> {
|
||||
static lua_value get(lua_State* L, int index, record& tracking) {
|
||||
return lua_value(L, stack::get<reference>(L, index, tracking));
|
||||
}
|
||||
};
|
||||
} // namespace stack
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_LUA_VALUE_HPP
|
|
@ -1,74 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_MAKE_REFERENCE_HPP
|
||||
#define SOL_MAKE_REFERENCE_HPP
|
||||
|
||||
#include "reference.hpp"
|
||||
#include "stack.hpp"
|
||||
|
||||
namespace sol {
|
||||
|
||||
template <typename R = reference, bool should_pop = !is_stack_based_v<R>, typename T>
|
||||
R make_reference(lua_State* L, T&& value) {
|
||||
int backpedal = stack::push(L, std::forward<T>(value));
|
||||
R r = stack::get<R>(L, -backpedal);
|
||||
if (should_pop) {
|
||||
lua_pop(L, backpedal);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename T, typename R = reference, bool should_pop = !is_stack_based_v<R>, typename... Args>
|
||||
R make_reference(lua_State* L, Args&&... args) {
|
||||
int backpedal = stack::push<T>(L, std::forward<Args>(args)...);
|
||||
R r = stack::get<R>(L, -backpedal);
|
||||
if (should_pop) {
|
||||
lua_pop(L, backpedal);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename R = reference, bool should_pop = !is_stack_based_v<R>, typename T>
|
||||
R make_reference_userdata(lua_State* L, T&& value) {
|
||||
int backpedal = stack::push_userdata(L, std::forward<T>(value));
|
||||
R r = stack::get<R>(L, -backpedal);
|
||||
if (should_pop) {
|
||||
lua_pop(L, backpedal);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename T, typename R = reference, bool should_pop = !is_stack_based_v<R>, typename... Args>
|
||||
R make_reference_userdata(lua_State* L, Args&&... args) {
|
||||
int backpedal = stack::push_userdata<T>(L, std::forward<Args>(args)...);
|
||||
R r = stack::get<R>(L, -backpedal);
|
||||
if (should_pop) {
|
||||
lua_pop(L, backpedal);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_MAKE_REFERENCE_HPP
|
|
@ -1,43 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_MAP_HPP
|
||||
#define SOL_MAP_HPP
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#if defined(SOL_USE_BOOST)
|
||||
#include <boost/unordered_map.hpp>
|
||||
#endif // Use boost here: transparent hash ability is good
|
||||
|
||||
namespace sol { namespace detail {
|
||||
#if defined(SOL_USE_BOOST)
|
||||
template <typename K, typename V, typename H = boost::hash<K>, typename E = std::equal_to<>>
|
||||
using unordered_map = boost::unordered_map<K, V, H, E>;
|
||||
#else
|
||||
template <typename K, typename V, typename H = std::hash<K>, typename E = std::equal_to<>>
|
||||
using unordered_map = std::unordered_map<K, V, H, E>;
|
||||
#endif // Boost map target
|
||||
}} // namespace sol::detail
|
||||
|
||||
#endif // SOL_MAP_HPP
|
|
@ -1,168 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_METATABLE_HPP
|
||||
#define SOL_METATABLE_HPP
|
||||
|
||||
#include "table_core.hpp"
|
||||
#include "usertype.hpp"
|
||||
|
||||
namespace sol {
|
||||
|
||||
template <typename base_type>
|
||||
class basic_metatable : public basic_table<base_type> {
|
||||
typedef basic_table<base_type> base_t;
|
||||
friend class state;
|
||||
friend class state_view;
|
||||
|
||||
protected:
|
||||
basic_metatable(detail::no_safety_tag, lua_nil_t n) : base_t(n) {
|
||||
}
|
||||
basic_metatable(detail::no_safety_tag, lua_State* L, int index) : base_t(L, index) {
|
||||
}
|
||||
basic_metatable(detail::no_safety_tag, lua_State* L, ref_index 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>
|
||||
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>
|
||||
basic_metatable(detail::no_safety_tag, lua_State* L, T&& r) noexcept : base_t(L, std::forward<T>(r)) {
|
||||
}
|
||||
|
||||
public:
|
||||
using base_t::lua_state;
|
||||
|
||||
basic_metatable() noexcept = default;
|
||||
basic_metatable(const basic_metatable&) = default;
|
||||
basic_metatable(basic_metatable&&) = default;
|
||||
basic_metatable& operator=(const basic_metatable&) = default;
|
||||
basic_metatable& operator=(basic_metatable&&) = default;
|
||||
basic_metatable(const stack_reference& r) : basic_metatable(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
basic_metatable(stack_reference&& r) : basic_metatable(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_metatable(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_metatable>(lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_metatable(lua_State* L, int index = -1) : basic_metatable(detail::no_safety, L, index) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_metatable>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_metatable(lua_State* L, ref_index index) : basic_metatable(detail::no_safety, L, index) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_metatable>(lua_state(), -1, handler);
|
||||
#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>
|
||||
basic_metatable(T&& r) noexcept : basic_metatable(detail::no_safety, std::forward<T>(r)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
if (!is_table<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_metatable>(base_t::lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
basic_metatable(lua_nil_t r) noexcept : basic_metatable(detail::no_safety, r) {
|
||||
}
|
||||
|
||||
template <typename Key, typename Value>
|
||||
void set(Key&& key, Value&& value);
|
||||
|
||||
void unregister() {
|
||||
using ustorage_base = u_detail::usertype_storage_base;
|
||||
|
||||
lua_State* L = this->lua_state();
|
||||
|
||||
auto pp = stack::push_pop(*this);
|
||||
int top = lua_gettop(L);
|
||||
|
||||
stack_reference mt(L, -1);
|
||||
stack::get_field(L, meta_function::gc_names, mt.stack_index());
|
||||
if (type_of(L, -1) != type::table) {
|
||||
return;
|
||||
}
|
||||
stack_reference gc_names_table(L, -1);
|
||||
stack::get_field(L, meta_function::storage, mt.stack_index());
|
||||
if (type_of(L, -1) != type::lightuserdata) {
|
||||
return;
|
||||
}
|
||||
ustorage_base& base_storage = *static_cast<ustorage_base*>(stack::get<void*>(L, -1));
|
||||
std::array<string_view, 6> registry_traits;
|
||||
for (std::size_t i = 0; i < registry_traits.size(); ++i) {
|
||||
u_detail::submetatable_type smt = static_cast<u_detail::submetatable_type>(i);
|
||||
stack::get_field<false, true>(L, smt, gc_names_table.stack_index());
|
||||
registry_traits[i] = stack::get<string_view>(L, -1);
|
||||
}
|
||||
|
||||
// get the registry
|
||||
stack_reference registry(L, raw_index(LUA_REGISTRYINDEX));
|
||||
registry.push();
|
||||
// eliminate all named entries for this usertype
|
||||
// in the registry (luaL_newmetatable does
|
||||
// [name] = new table
|
||||
// in registry upon creation)
|
||||
for (std::size_t i = 0; i < registry_traits.size(); ++i) {
|
||||
u_detail::submetatable_type smt = static_cast<u_detail::submetatable_type>(i);
|
||||
const string_view& gcmetakey = registry_traits[i];
|
||||
if (smt == u_detail::submetatable_type::named) {
|
||||
// use .data() to make it treat it like a c string,
|
||||
// which it is...
|
||||
stack::set_field<true>(L, gcmetakey.data(), lua_nil);
|
||||
}
|
||||
else {
|
||||
// do not change the values in the registry: they need to be present
|
||||
// no matter what, for safety's sake
|
||||
//stack::set_field(L, gcmetakey, lua_nil, registry.stack_index());
|
||||
}
|
||||
}
|
||||
|
||||
// destroy all storage and tables
|
||||
base_storage.clear();
|
||||
|
||||
// 6 strings from gc_names table,
|
||||
// + 1 registry,
|
||||
// + 1 gc_names table
|
||||
// + 1 light userdata of storage
|
||||
// + 1 registry
|
||||
// 10 total, 4 left since popping off 6 gc_names tables
|
||||
lua_settop(L, top);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_METATABLE_HPP
|
|
@ -1,161 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_OBJECT_HPP
|
||||
#define SOL_OBJECT_HPP
|
||||
|
||||
#include "make_reference.hpp"
|
||||
#include "reference.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "object_base.hpp"
|
||||
|
||||
namespace sol {
|
||||
|
||||
template <typename base_type>
|
||||
class basic_object : public basic_object_base<base_type> {
|
||||
private:
|
||||
typedef basic_object_base<base_type> base_t;
|
||||
|
||||
template <bool invert_and_pop = false>
|
||||
basic_object(std::integral_constant<bool, invert_and_pop>, lua_State* L, int index = -1) noexcept
|
||||
: base_t(L, index) {
|
||||
if (invert_and_pop) {
|
||||
lua_pop(L, -index);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
basic_object(detail::no_safety_tag, lua_nil_t n) : base_t(n) {
|
||||
}
|
||||
basic_object(detail::no_safety_tag, lua_State* L, int index) : base_t(L, index) {
|
||||
}
|
||||
basic_object(lua_State* L, detail::global_tag t) : base_t(L, t) {
|
||||
}
|
||||
basic_object(detail::no_safety_tag, lua_State* L, ref_index index) : base_t(L, index) {
|
||||
}
|
||||
template <typename T,
|
||||
meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_object>>, 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>
|
||||
basic_object(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>
|
||||
basic_object(detail::no_safety_tag, lua_State* L, T&& r) noexcept : base_t(L, std::forward<T>(r)) {
|
||||
}
|
||||
|
||||
public:
|
||||
basic_object() noexcept = default;
|
||||
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_object>>, meta::neg<std::is_same<base_type, stack_reference>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_object(T&& r)
|
||||
: base_t(std::forward<T>(r)) {
|
||||
}
|
||||
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_object(lua_State* L, T&& r)
|
||||
: base_t(L, std::forward<T>(r)) {
|
||||
}
|
||||
basic_object(lua_nil_t r)
|
||||
: base_t(r) {
|
||||
}
|
||||
basic_object(const basic_object&) = default;
|
||||
basic_object(basic_object&&) = default;
|
||||
basic_object(const stack_reference& r) noexcept
|
||||
: basic_object(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
basic_object(stack_reference&& r) noexcept
|
||||
: basic_object(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
template <typename Super>
|
||||
basic_object(const proxy_base<Super>& r) noexcept
|
||||
: basic_object(r.operator basic_object()) {
|
||||
}
|
||||
template <typename Super>
|
||||
basic_object(proxy_base<Super>&& r) noexcept
|
||||
: basic_object(r.operator basic_object()) {
|
||||
}
|
||||
basic_object(lua_State* L, lua_nil_t r) noexcept
|
||||
: base_t(L, r) {
|
||||
}
|
||||
basic_object(lua_State* L, int index = -1) noexcept
|
||||
: base_t(L, index) {
|
||||
}
|
||||
basic_object(lua_State* L, absolute_index index) noexcept
|
||||
: base_t(L, index) {
|
||||
}
|
||||
basic_object(lua_State* L, raw_index index) noexcept
|
||||
: base_t(L, index) {
|
||||
}
|
||||
basic_object(lua_State* L, ref_index index) noexcept
|
||||
: base_t(L, index) {
|
||||
}
|
||||
template <typename T, typename... Args>
|
||||
basic_object(lua_State* L, in_place_type_t<T>, Args&&... args) noexcept
|
||||
: basic_object(std::integral_constant<bool, !is_stack_based<base_t>::value>(), L, -stack::push<T>(L, std::forward<Args>(args)...)) {
|
||||
}
|
||||
template <typename T, typename... Args>
|
||||
basic_object(lua_State* L, in_place_t, T&& arg, Args&&... args) noexcept
|
||||
: basic_object(L, in_place_type<T>, std::forward<T>(arg), std::forward<Args>(args)...) {
|
||||
}
|
||||
basic_object& operator=(const basic_object&) = default;
|
||||
basic_object& operator=(basic_object&&) = default;
|
||||
basic_object& operator=(const base_type& b) {
|
||||
base_t::operator=(b);
|
||||
return *this;
|
||||
}
|
||||
basic_object& operator=(base_type&& b) {
|
||||
base_t::operator=(std::move(b));
|
||||
return *this;
|
||||
}
|
||||
template <typename Super>
|
||||
basic_object& operator=(const proxy_base<Super>& r) {
|
||||
this->operator=(r.operator basic_object());
|
||||
return *this;
|
||||
}
|
||||
template <typename Super>
|
||||
basic_object& operator=(proxy_base<Super>&& r) {
|
||||
this->operator=(r.operator basic_object());
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
object make_object(lua_State* L, T&& value) {
|
||||
return make_reference<object, true>(L, std::forward<T>(value));
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
object make_object(lua_State* L, Args&&... args) {
|
||||
return make_reference<T, object, true>(L, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
object make_object_userdata(lua_State* L, T&& value) {
|
||||
return make_reference_userdata<object, true>(L, std::forward<T>(value));
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
object make_object_userdata(lua_State* L, Args&&... args) {
|
||||
return make_reference_userdata<T, object, true>(L, std::forward<Args>(args)...);
|
||||
}
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_OBJECT_HPP
|
|
@ -1,87 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_OBJECT_BASE_HPP
|
||||
#define SOL_OBJECT_BASE_HPP
|
||||
|
||||
#include "reference.hpp"
|
||||
#include "stack.hpp"
|
||||
|
||||
namespace sol {
|
||||
|
||||
template <typename ref_t>
|
||||
class basic_object_base : public ref_t {
|
||||
private:
|
||||
using base_t = ref_t;
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) as_stack(std::true_type) const {
|
||||
return stack::get<T>(base_t::lua_state(), base_t::stack_index());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) as_stack(std::false_type) const {
|
||||
base_t::push();
|
||||
return stack::pop<T>(base_t::lua_state());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is_stack(std::true_type) const {
|
||||
return stack::check<T>(base_t::lua_state(), base_t::stack_index(), no_panic);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is_stack(std::false_type) const {
|
||||
int r = base_t::registry_index();
|
||||
if (r == LUA_REFNIL)
|
||||
return meta::any_same<meta::unqualified_t<T>, lua_nil_t, nullopt_t, std::nullptr_t>::value ? true : false;
|
||||
if (r == LUA_NOREF)
|
||||
return false;
|
||||
auto pp = stack::push_pop(*this);
|
||||
return stack::check<T>(base_t::lua_state(), -1, no_panic);
|
||||
}
|
||||
|
||||
public:
|
||||
basic_object_base() noexcept = default;
|
||||
basic_object_base(const basic_object_base&) = default;
|
||||
basic_object_base(basic_object_base&&) = default;
|
||||
basic_object_base& operator=(const basic_object_base&) = default;
|
||||
basic_object_base& operator=(basic_object_base&&) = default;
|
||||
template <typename T, typename... Args, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_object_base>>> = meta::enabler>
|
||||
basic_object_base(T&& arg, Args&&... args)
|
||||
: base_t(std::forward<T>(arg), std::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) as() const {
|
||||
return as_stack<T>(is_stack_based<base_t>());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is() const {
|
||||
return is_stack<T>(is_stack_based<base_t>());
|
||||
}
|
||||
};
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_OBJECT_BASE_HPP
|
|
@ -1,73 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_OPTIONAL_HPP
|
||||
#define SOL_OPTIONAL_HPP
|
||||
|
||||
#include "forward.hpp"
|
||||
#include "in_place.hpp"
|
||||
#include "traits.hpp"
|
||||
#if defined(SOL_USE_BOOST) && SOL_USE_BOOST
|
||||
#include <boost/optional.hpp>
|
||||
#else
|
||||
#include "optional_implementation.hpp"
|
||||
#endif // Boost vs. Better optional
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace sol {
|
||||
|
||||
#if defined(SOL_USE_BOOST) && SOL_USE_BOOST
|
||||
template <typename T>
|
||||
using optional = boost::optional<T>;
|
||||
using nullopt_t = boost::none_t;
|
||||
const nullopt_t nullopt = boost::none;
|
||||
#endif // Boost vs. Better optional
|
||||
|
||||
namespace meta {
|
||||
template <typename T>
|
||||
using is_optional = any<is_specialization_of<T, optional>, is_specialization_of<T, std::optional>>;
|
||||
|
||||
template <typename T>
|
||||
constexpr inline bool is_optional_v = is_optional<T>::value;
|
||||
} // namespace meta
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
struct associated_nullopt {
|
||||
inline static constexpr std::nullopt_t value = std::nullopt;
|
||||
};
|
||||
|
||||
#if defined(SOL_USE_BOOST) && SOL_USE_BOOST
|
||||
template <typename T>
|
||||
struct associated_nullopt<boost::optional<T>> {
|
||||
inline static constexpr std::nullopt_t value = boost::nullopt;
|
||||
};
|
||||
#endif // Boost nullopt
|
||||
|
||||
template <typename T>
|
||||
inline constexpr auto associated_nullopt_v = associated_nullopt<T>::value;
|
||||
} // namespace detail
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_OPTIONAL_HPP
|
File diff suppressed because it is too large
Load Diff
|
@ -1,50 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_OVERLOAD_HPP
|
||||
#define SOL_OVERLOAD_HPP
|
||||
|
||||
#include "traits.hpp"
|
||||
#include <utility>
|
||||
|
||||
namespace sol {
|
||||
template <typename... Functions>
|
||||
struct overload_set {
|
||||
std::tuple<Functions...> functions;
|
||||
template <typename Arg, typename... Args, meta::disable<std::is_same<overload_set, meta::unqualified_t<Arg>>> = meta::enabler>
|
||||
overload_set(Arg&& arg, Args&&... args)
|
||||
: functions(std::forward<Arg>(arg), std::forward<Args>(args)...) {
|
||||
}
|
||||
overload_set(const overload_set&) = default;
|
||||
overload_set(overload_set&&) = default;
|
||||
overload_set& operator=(const overload_set&) = default;
|
||||
overload_set& operator=(overload_set&&) = default;
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
decltype(auto) overload(Args&&... args) {
|
||||
return overload_set<std::decay_t<Args>...>(std::forward<Args>(args)...);
|
||||
}
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_OVERLOAD_HPP
|
|
@ -1,101 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_POINTER_LIKE_HPP
|
||||
#define SOL_POINTER_LIKE_HPP
|
||||
|
||||
#include "base_traits.hpp"
|
||||
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
namespace sol {
|
||||
|
||||
namespace meta {
|
||||
namespace meta_detail {
|
||||
template <typename T>
|
||||
using is_dereferenceable_test = decltype(*std::declval<T>());
|
||||
|
||||
template <typename T>
|
||||
using is_explicitly_dereferenceable_test = decltype(std::declval<T>().operator*());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
using is_pointer_like = std::integral_constant<bool, !std::is_array_v<T> && (std::is_pointer_v<T> || is_detected_v<meta_detail::is_explicitly_dereferenceable_test, T>)>;
|
||||
|
||||
template <typename T>
|
||||
constexpr inline bool is_pointer_like_v = is_pointer_like<T>::value;
|
||||
} // namespace meta
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
auto unwrap(T&& item) -> decltype(std::forward<T>(item)) {
|
||||
return std::forward<T>(item);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& unwrap(std::reference_wrapper<T> arg) {
|
||||
return arg.get();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline decltype(auto) deref(T&& item) {
|
||||
using Tu = meta::unqualified_t<T>;
|
||||
if constexpr (meta::is_pointer_like_v<Tu>) {
|
||||
return *std::forward<T>(item);
|
||||
}
|
||||
else {
|
||||
return std::forward<T>(item);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline decltype(auto) deref_move_only(T&& item) {
|
||||
using Tu = meta::unqualified_t<T>;
|
||||
if constexpr (meta::is_pointer_like_v<Tu> && !std::is_pointer_v<Tu> && !std::is_copy_constructible_v<Tu>) {
|
||||
return *std::forward<T>(item);
|
||||
}
|
||||
else {
|
||||
return std::forward<T>(item);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T* ptr(T& val) {
|
||||
return std::addressof(val);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T* ptr(std::reference_wrapper<T> val) {
|
||||
return std::addressof(val.get());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T* ptr(T* val) {
|
||||
return val;
|
||||
}
|
||||
} // namespace detail
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_POINTER_LIKE_HPP
|
|
@ -1,98 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_FILTERS_HPP
|
||||
#define SOL_FILTERS_HPP
|
||||
|
||||
#include "traits.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
struct policy_base_tag {};
|
||||
} // namespace detail
|
||||
|
||||
template <int Target, int... In>
|
||||
struct static_stack_dependencies : detail::policy_base_tag {};
|
||||
typedef static_stack_dependencies<-1, 1> self_dependency;
|
||||
template <int... In>
|
||||
struct returns_self_with : detail::policy_base_tag {};
|
||||
typedef returns_self_with<> returns_self;
|
||||
|
||||
struct stack_dependencies : detail::policy_base_tag {
|
||||
int target;
|
||||
std::array<int, 64> stack_indices;
|
||||
std::size_t len;
|
||||
|
||||
template <typename... Args>
|
||||
stack_dependencies(int stack_target, Args&&... args) : target(stack_target), stack_indices(), len(sizeof...(Args)) {
|
||||
std::size_t i = 0;
|
||||
(void)detail::swallow{ int(), (stack_indices[i++] = static_cast<int>(std::forward<Args>(args)), int())... };
|
||||
}
|
||||
|
||||
int& operator[](std::size_t i) {
|
||||
return stack_indices[i];
|
||||
}
|
||||
|
||||
const int& operator[](std::size_t i) const {
|
||||
return stack_indices[i];
|
||||
}
|
||||
|
||||
std::size_t size() const {
|
||||
return len;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F, typename... Policies>
|
||||
struct policy_wrapper {
|
||||
typedef std::index_sequence_for<Policies...> indices;
|
||||
|
||||
F value;
|
||||
std::tuple<Policies...> policies;
|
||||
|
||||
template <typename Fx, typename... Args, meta::enable<meta::neg<std::is_same<meta::unqualified_t<Fx>, policy_wrapper>>> = meta::enabler>
|
||||
policy_wrapper(Fx&& fx, Args&&... args) : value(std::forward<Fx>(fx)), policies(std::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
policy_wrapper(const policy_wrapper&) = default;
|
||||
policy_wrapper& operator=(const policy_wrapper&) = default;
|
||||
policy_wrapper(policy_wrapper&&) = default;
|
||||
policy_wrapper& operator=(policy_wrapper&&) = default;
|
||||
};
|
||||
|
||||
template <typename F, typename... Args>
|
||||
auto policies(F&& f, Args&&... args) {
|
||||
return policy_wrapper<std::decay_t<F>, std::decay_t<Args>...>(std::forward<F>(f), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
using is_policy = meta::is_specialization_of<T, policy_wrapper>;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_policy_v = is_policy<T>::value;
|
||||
} // namespace detail
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_FILTERS_HPP
|
|
@ -1,149 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_PROPERTY_HPP
|
||||
#define SOL_PROPERTY_HPP
|
||||
|
||||
#include "types.hpp"
|
||||
#include "ebco.hpp"
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
struct no_prop {};
|
||||
}
|
||||
|
||||
template <typename R, typename W>
|
||||
struct property_wrapper : detail::ebco<R, 0>, detail::ebco<W, 1> {
|
||||
private:
|
||||
using read_base_t = detail::ebco<R, 0>;
|
||||
using write_base_t = detail::ebco<W, 1>;
|
||||
|
||||
public:
|
||||
template <typename Rx, typename Wx>
|
||||
property_wrapper(Rx&& r, Wx&& w)
|
||||
: read_base_t(std::forward<Rx>(r)), write_base_t(std::forward<Wx>(w)) {
|
||||
}
|
||||
|
||||
W& write() {
|
||||
return write_base_t::value();
|
||||
}
|
||||
|
||||
const W& write() const {
|
||||
return write_base_t::value();
|
||||
}
|
||||
|
||||
R& read() {
|
||||
return read_base_t::value();
|
||||
}
|
||||
|
||||
const R& read() const {
|
||||
return read_base_t::value();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F, typename G>
|
||||
inline decltype(auto) property(F&& f, G&& g) {
|
||||
typedef lua_bind_traits<meta::unqualified_t<F>> left_traits;
|
||||
typedef lua_bind_traits<meta::unqualified_t<G>> right_traits;
|
||||
if constexpr (left_traits::free_arity < right_traits::free_arity) {
|
||||
return property_wrapper<std::decay_t<F>, std::decay_t<G>>(std::forward<F>(f), std::forward<G>(g));
|
||||
}
|
||||
else {
|
||||
return property_wrapper<std::decay_t<G>, std::decay_t<F>>(std::forward<G>(g), std::forward<F>(f));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
inline decltype(auto) property(F&& f) {
|
||||
typedef lua_bind_traits<meta::unqualified_t<F>> left_traits;
|
||||
if constexpr (left_traits::free_arity < 2) {
|
||||
return property_wrapper<std::decay_t<F>, detail::no_prop>(std::forward<F>(f), detail::no_prop());
|
||||
}
|
||||
else {
|
||||
return property_wrapper<detail::no_prop, std::decay_t<F>>(detail::no_prop(), std::forward<F>(f));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
inline decltype(auto) readonly_property(F&& f) {
|
||||
return property_wrapper<std::decay_t<F>, detail::no_prop>(std::forward<F>(f), detail::no_prop());
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
inline decltype(auto) writeonly_property(F&& f) {
|
||||
return property_wrapper<detail::no_prop, std::decay_t<F>>(detail::no_prop(), std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct readonly_wrapper : detail::ebco<T> {
|
||||
private:
|
||||
using base_t = detail::ebco<T>;
|
||||
|
||||
public:
|
||||
using base_t::base_t;
|
||||
|
||||
operator T&() {
|
||||
return base_t::value();
|
||||
}
|
||||
operator const T&() const {
|
||||
return base_t::value();
|
||||
}
|
||||
};
|
||||
|
||||
// Allow someone to make a member variable readonly (const)
|
||||
template <typename R, typename T>
|
||||
inline auto readonly(R T::*v) {
|
||||
return readonly_wrapper<meta::unqualified_t<decltype(v)>>(v);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct var_wrapper : detail::ebco<T> {
|
||||
private:
|
||||
using base_t = detail::ebco<T>;
|
||||
|
||||
public:
|
||||
using base_t::base_t;
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
inline auto var(V&& v) {
|
||||
typedef std::decay_t<V> T;
|
||||
return var_wrapper<T>(std::forward<V>(v));
|
||||
}
|
||||
|
||||
namespace meta {
|
||||
template <typename T>
|
||||
struct is_member_object : std::is_member_object_pointer<T> {};
|
||||
|
||||
template <typename T>
|
||||
struct is_member_object<readonly_wrapper<T>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_member_object_v = is_member_object<T>::value;
|
||||
} // namespace meta
|
||||
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_PROPERTY_HPP
|
|
@ -1,54 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_PROTECT_HPP
|
||||
#define SOL_PROTECT_HPP
|
||||
|
||||
#include "traits.hpp"
|
||||
#include <utility>
|
||||
|
||||
namespace sol {
|
||||
|
||||
template <typename T>
|
||||
struct protect_t {
|
||||
T value;
|
||||
|
||||
template <typename Arg, typename... Args, meta::disable<std::is_same<protect_t, meta::unqualified_t<Arg>>> = meta::enabler>
|
||||
protect_t(Arg&& arg, Args&&... args)
|
||||
: value(std::forward<Arg>(arg), std::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
protect_t(const protect_t&) = default;
|
||||
protect_t(protect_t&&) = default;
|
||||
protect_t& operator=(const protect_t&) = default;
|
||||
protect_t& operator=(protect_t&&) = default;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
auto protect(T&& value) {
|
||||
return protect_t<std::decay_t<T>>(std::forward<T>(value));
|
||||
}
|
||||
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_PROTECT_HPP
|
|
@ -1,351 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_PROTECTED_FUNCTION_HPP
|
||||
#define SOL_PROTECTED_FUNCTION_HPP
|
||||
|
||||
#include "reference.hpp"
|
||||
#include "object.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "protected_function_result.hpp"
|
||||
#include "unsafe_function.hpp"
|
||||
#include "protected_handler.hpp"
|
||||
#include "bytecode.hpp"
|
||||
#include "dump_handler.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
|
||||
namespace sol {
|
||||
|
||||
namespace detail {
|
||||
template <bool b, typename handler_t>
|
||||
inline void handle_protected_exception(lua_State* L, optional<const std::exception&> maybe_ex, const char* error, detail::protected_handler<b, handler_t>& h) {
|
||||
h.stackindex = 0;
|
||||
if (b) {
|
||||
h.target.push();
|
||||
detail::call_exception_handler(L, maybe_ex, error);
|
||||
lua_call(L, 1, 1);
|
||||
}
|
||||
else {
|
||||
detail::call_exception_handler(L, maybe_ex, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ref_t, bool aligned = false, typename handler_t = reference>
|
||||
class basic_protected_function : public basic_object<ref_t> {
|
||||
private:
|
||||
using base_t = basic_object<ref_t>;
|
||||
|
||||
public:
|
||||
using is_stack_handler = is_stack_based<handler_t>;
|
||||
|
||||
static handler_t get_default_handler(lua_State* L) {
|
||||
return detail::get_default_handler<handler_t, is_main_threaded<base_t>::value>(L);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void set_default_handler(const T& ref) {
|
||||
detail::set_default_handler(ref.lua_state(), ref);
|
||||
}
|
||||
|
||||
private:
|
||||
template <bool b>
|
||||
call_status luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount, detail::protected_handler<b, handler_t>& h) const {
|
||||
return static_cast<call_status>(lua_pcall(lua_state(), static_cast<int>(argcount), static_cast<int>(resultcount), h.stackindex));
|
||||
}
|
||||
|
||||
template <std::size_t... I, bool b, typename... Ret>
|
||||
auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
|
||||
luacall(n, sizeof...(Ret), h);
|
||||
return stack::pop<std::tuple<Ret...>>(lua_state());
|
||||
}
|
||||
|
||||
template <std::size_t I, bool b, typename Ret>
|
||||
Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
|
||||
luacall(n, 1, h);
|
||||
return stack::pop<Ret>(lua_state());
|
||||
}
|
||||
|
||||
template <std::size_t I, bool b>
|
||||
void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
|
||||
luacall(n, 0, h);
|
||||
}
|
||||
|
||||
template <bool b>
|
||||
protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n, detail::protected_handler<b, handler_t>& h) const {
|
||||
int stacksize = lua_gettop(lua_state());
|
||||
int poststacksize = stacksize;
|
||||
int firstreturn = 1;
|
||||
int returncount = 0;
|
||||
call_status code = call_status::ok;
|
||||
#if !defined(SOL_NO_EXCEPTIONS) || !SOL_NO_EXCEPTIONS
|
||||
#if (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !SOL_NO_EXCEPTIONS_SAFE_PROPAGATION) || (defined(SOL_LUAJIT) && SOL_LUAJIT)
|
||||
try {
|
||||
#endif // Safe Exception Propagation
|
||||
#endif // No Exceptions
|
||||
firstreturn = (std::max)(1, static_cast<int>(stacksize - n - static_cast<int>(h.valid() && !is_stack_handler::value)));
|
||||
code = luacall(n, LUA_MULTRET, h);
|
||||
poststacksize = lua_gettop(lua_state()) - static_cast<int>(h.valid() && !is_stack_handler::value);
|
||||
returncount = poststacksize - (firstreturn - 1);
|
||||
#ifndef SOL_NO_EXCEPTIONS
|
||||
#if (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !SOL_NO_EXCEPTIONS_SAFE_PROPAGATION) || (defined(SOL_LUAJIT) && SOL_LUAJIT)
|
||||
}
|
||||
// Handle C++ errors thrown from C++ functions bound inside of lua
|
||||
catch (const char* error) {
|
||||
detail::handle_protected_exception(lua_state(), optional<const std::exception&>(nullopt), error, h);
|
||||
firstreturn = lua_gettop(lua_state());
|
||||
return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
|
||||
}
|
||||
catch (const std::string& error) {
|
||||
detail::handle_protected_exception(lua_state(), optional<const std::exception&>(nullopt), error.c_str(), h);
|
||||
firstreturn = lua_gettop(lua_state());
|
||||
return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
|
||||
}
|
||||
catch (const std::exception& error) {
|
||||
detail::handle_protected_exception(lua_state(), optional<const std::exception&>(error), error.what(), h);
|
||||
firstreturn = lua_gettop(lua_state());
|
||||
return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
|
||||
}
|
||||
#if (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !SOL_NO_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
// LuaJIT cannot have the catchall when the safe propagation is on
|
||||
// but LuaJIT will swallow all C++ errors
|
||||
// if we don't at least catch std::exception ones
|
||||
catch (...) {
|
||||
detail::handle_protected_exception(lua_state(), optional<const std::exception&>(nullopt), detail::protected_function_error, h);
|
||||
firstreturn = lua_gettop(lua_state());
|
||||
return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
|
||||
}
|
||||
#endif // LuaJIT
|
||||
#else
|
||||
// do not handle exceptions: they can be propogated into C++ and keep all type information / rich information
|
||||
#endif // Safe Exception Propagation
|
||||
#endif // Exceptions vs. No Exceptions
|
||||
return protected_function_result(lua_state(), firstreturn, returncount, returncount, code);
|
||||
}
|
||||
|
||||
public:
|
||||
using base_t::lua_state;
|
||||
|
||||
handler_t error_handler;
|
||||
|
||||
basic_protected_function() = default;
|
||||
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_protected_function>>, meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>, meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_protected_function(T&& r) noexcept
|
||||
: base_t(std::forward<T>(r)), error_handler(get_default_handler(r.lua_state())) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
if (!is_function<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
basic_protected_function(const basic_protected_function&) = default;
|
||||
basic_protected_function& operator=(const basic_protected_function&) = default;
|
||||
basic_protected_function(basic_protected_function&&) = default;
|
||||
basic_protected_function& operator=(basic_protected_function&&) = default;
|
||||
basic_protected_function(const basic_function<base_t>& b)
|
||||
: basic_protected_function(b, get_default_handler(b.lua_state())) {
|
||||
}
|
||||
basic_protected_function(basic_function<base_t>&& b)
|
||||
: basic_protected_function(std::move(b), get_default_handler(b.lua_state())) {
|
||||
}
|
||||
basic_protected_function(const basic_function<base_t>& b, handler_t eh)
|
||||
: base_t(b), error_handler(std::move(eh)) {
|
||||
}
|
||||
basic_protected_function(basic_function<base_t>&& b, handler_t eh)
|
||||
: base_t(std::move(b)), error_handler(std::move(eh)) {
|
||||
}
|
||||
basic_protected_function(const stack_reference& r)
|
||||
: basic_protected_function(r.lua_state(), r.stack_index(), get_default_handler(r.lua_state())) {
|
||||
}
|
||||
basic_protected_function(stack_reference&& r)
|
||||
: basic_protected_function(r.lua_state(), r.stack_index(), get_default_handler(r.lua_state())) {
|
||||
}
|
||||
basic_protected_function(const stack_reference& r, handler_t eh)
|
||||
: basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {
|
||||
}
|
||||
basic_protected_function(stack_reference&& r, handler_t eh)
|
||||
: basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {
|
||||
}
|
||||
|
||||
template <typename Super>
|
||||
basic_protected_function(const proxy_base<Super>& p)
|
||||
: basic_protected_function(p, get_default_handler(p.lua_state())) {
|
||||
}
|
||||
template <typename Super>
|
||||
basic_protected_function(proxy_base<Super>&& p)
|
||||
: basic_protected_function(std::move(p), get_default_handler(p.lua_state())) {
|
||||
}
|
||||
template <typename Proxy, typename Handler, meta::enable<std::is_base_of<proxy_base_tag, meta::unqualified_t<Proxy>>, meta::neg<is_lua_index<meta::unqualified_t<Handler>>>> = meta::enabler>
|
||||
basic_protected_function(Proxy&& p, Handler&& eh)
|
||||
: basic_protected_function(detail::force_cast<base_t>(p), std::forward<Handler>(eh)) {
|
||||
}
|
||||
|
||||
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_protected_function(lua_State* L, T&& r)
|
||||
: basic_protected_function(L, std::forward<T>(r), get_default_handler(L)) {
|
||||
}
|
||||
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
|
||||
basic_protected_function(lua_State* L, T&& r, handler_t eh)
|
||||
: base_t(L, std::forward<T>(r)), error_handler(std::move(eh)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
basic_protected_function(lua_nil_t n)
|
||||
: base_t(n), error_handler(n) {
|
||||
}
|
||||
|
||||
basic_protected_function(lua_State* L, int index = -1)
|
||||
: basic_protected_function(L, index, get_default_handler(L)) {
|
||||
}
|
||||
basic_protected_function(lua_State* L, int index, handler_t eh)
|
||||
: base_t(L, index), error_handler(std::move(eh)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_protected_function(lua_State* L, absolute_index index)
|
||||
: basic_protected_function(L, index, get_default_handler(L)) {
|
||||
}
|
||||
basic_protected_function(lua_State* L, absolute_index index, handler_t eh)
|
||||
: base_t(L, index), error_handler(std::move(eh)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_protected_function(lua_State* L, raw_index index)
|
||||
: basic_protected_function(L, index, get_default_handler(L)) {
|
||||
}
|
||||
basic_protected_function(lua_State* L, raw_index index, handler_t eh)
|
||||
: base_t(L, index), error_handler(std::move(eh)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(L, index, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
basic_protected_function(lua_State* L, ref_index index)
|
||||
: basic_protected_function(L, index, get_default_handler(L)) {
|
||||
}
|
||||
basic_protected_function(lua_State* L, ref_index index, handler_t eh)
|
||||
: base_t(L, index), error_handler(std::move(eh)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_protected_function>(lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
}
|
||||
|
||||
template <typename Fx>
|
||||
int dump(lua_Writer writer, void* userdata, bool strip, Fx&& on_error) const {
|
||||
this->push();
|
||||
auto ppn = stack::push_popper_n<false>(this->lua_state(), 1);
|
||||
int r = lua_dump(this->lua_state(), writer, userdata, strip ? 1 : 0);
|
||||
if (r != 0) {
|
||||
return on_error(this->lua_state(), r, writer, userdata, strip);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int dump(lua_Writer writer, void* userdata, bool strip = false) const {
|
||||
return dump(writer, userdata, strip, &dump_pass_on_error);
|
||||
}
|
||||
|
||||
template <typename Container = bytecode>
|
||||
Container dump() const {
|
||||
Container bc;
|
||||
(void)dump(static_cast<lua_Writer>(&basic_insert_dump_writer<Container>), static_cast<void*>(&bc), false, &dump_throw_on_error);
|
||||
return bc;
|
||||
}
|
||||
|
||||
template <typename Container = bytecode, typename Fx>
|
||||
Container dump(Fx&& on_error) const {
|
||||
Container bc;
|
||||
(void)dump(static_cast<lua_Writer>(&basic_insert_dump_writer<Container>), static_cast<void*>(&bc), false, std::forward<Fx>(on_error));
|
||||
return bc;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
protected_function_result operator()(Args&&... args) const {
|
||||
return call<>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Ret, typename... Args>
|
||||
decltype(auto) operator()(types<Ret...>, Args&&... args) const {
|
||||
return call<Ret...>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Ret, typename... Args>
|
||||
decltype(auto) call(Args&&... args) const {
|
||||
if constexpr (!aligned) {
|
||||
// we do not expect the function to already be on the stack: push it
|
||||
if (error_handler.valid()) {
|
||||
detail::protected_handler<true, handler_t> h(error_handler);
|
||||
base_t::push();
|
||||
int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
|
||||
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
|
||||
}
|
||||
else {
|
||||
detail::protected_handler<false, handler_t> h(error_handler);
|
||||
base_t::push();
|
||||
int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
|
||||
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// the function is already on the stack at the right location
|
||||
if (error_handler.valid()) {
|
||||
// the handler will be pushed onto the stack manually,
|
||||
// since it's not already on the stack this means we need to push our own
|
||||
// function on the stack too and swap things to be in-place
|
||||
if constexpr (!is_stack_handler::value) {
|
||||
// so, we need to remove the function at the top and then dump the handler out ourselves
|
||||
base_t::push();
|
||||
}
|
||||
detail::protected_handler<true, handler_t> h(error_handler);
|
||||
if constexpr (!is_stack_handler::value) {
|
||||
lua_replace(lua_state(), -3);
|
||||
h.stackindex = lua_absindex(lua_state(), -2);
|
||||
}
|
||||
int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
|
||||
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
|
||||
}
|
||||
else {
|
||||
detail::protected_handler<false, handler_t> h(error_handler);
|
||||
int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
|
||||
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_FUNCTION_HPP
|
|
@ -1,225 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_PROTECTED_FUNCTION_RESULT_HPP
|
||||
#define SOL_PROTECTED_FUNCTION_RESULT_HPP
|
||||
|
||||
#include "reference.hpp"
|
||||
#include "tuple.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "proxy_base.hpp"
|
||||
#include "stack_iterator.hpp"
|
||||
#include "stack_proxy.hpp"
|
||||
#include "error.hpp"
|
||||
#include "stack.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace sol {
|
||||
struct protected_function_result : public proxy_base<protected_function_result> {
|
||||
private:
|
||||
lua_State* L;
|
||||
int index;
|
||||
int returncount;
|
||||
int popcount;
|
||||
call_status err;
|
||||
|
||||
public:
|
||||
typedef stack_proxy reference_type;
|
||||
typedef stack_proxy value_type;
|
||||
typedef stack_proxy* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef stack_iterator<stack_proxy, false> iterator;
|
||||
typedef stack_iterator<stack_proxy, true> const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
protected_function_result() = default;
|
||||
protected_function_result(lua_State* Ls, int idx = -1, int retnum = 0, int popped = 0, call_status pferr = call_status::ok) noexcept
|
||||
: L(Ls), index(idx), returncount(retnum), popcount(popped), err(pferr) {
|
||||
}
|
||||
protected_function_result(const protected_function_result&) = default;
|
||||
protected_function_result& operator=(const protected_function_result&) = default;
|
||||
protected_function_result(protected_function_result&& o) noexcept
|
||||
: L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) {
|
||||
// Must be manual, otherwise destructor will screw us
|
||||
// return count being 0 is enough to keep things clean
|
||||
// but we will be thorough
|
||||
o.abandon();
|
||||
}
|
||||
protected_function_result& operator=(protected_function_result&& o) noexcept {
|
||||
L = o.L;
|
||||
index = o.index;
|
||||
returncount = o.returncount;
|
||||
popcount = o.popcount;
|
||||
err = o.err;
|
||||
// Must be manual, otherwise destructor will screw us
|
||||
// return count being 0 is enough to keep things clean
|
||||
// but we will be thorough
|
||||
o.abandon();
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected_function_result(const unsafe_function_result& o) = delete;
|
||||
protected_function_result& operator=(const unsafe_function_result& o) = delete;
|
||||
protected_function_result(unsafe_function_result&& o) noexcept;
|
||||
protected_function_result& operator=(unsafe_function_result&& o) noexcept;
|
||||
|
||||
call_status status() const noexcept {
|
||||
return err;
|
||||
}
|
||||
|
||||
bool valid() const noexcept {
|
||||
return status() == call_status::ok || status() == call_status::yielded;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) get(int index_offset = 0) const {
|
||||
using UT = meta::unqualified_t<T>;
|
||||
int target = index + index_offset;
|
||||
if constexpr (meta::is_optional_v<UT>) {
|
||||
using ValueType = typename UT::value_type;
|
||||
if constexpr (std::is_same_v<ValueType, error>) {
|
||||
if (valid()) {
|
||||
return UT();
|
||||
}
|
||||
return UT(error(detail::direct_error, stack::get<std::string>(L, target)));
|
||||
}
|
||||
else {
|
||||
if (!valid()) {
|
||||
return UT();
|
||||
}
|
||||
return stack::get<UT>(L, target);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if constexpr (std::is_same_v<T, error>) {
|
||||
#if defined(SOL_SAFE_PROXIES) && SOL_SAFE_PROXIES
|
||||
if (valid()) {
|
||||
type t = type_of(L, target);
|
||||
type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is an error)");
|
||||
}
|
||||
#endif // Check Argument Safety
|
||||
return error(detail::direct_error, stack::get<std::string>(L, target));
|
||||
}
|
||||
else {
|
||||
#if defined(SOL_SAFE_PROXIES) && SOL_SAFE_PROXIES
|
||||
if (!valid()) {
|
||||
type t = type_of(L, target);
|
||||
type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is not an error)");
|
||||
}
|
||||
#endif // Check Argument Safety
|
||||
return stack::get<T>(L, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type get_type(int index_offset = 0) const noexcept {
|
||||
return type_of(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
stack_proxy operator[](difference_type index_offset) const {
|
||||
return stack_proxy(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
iterator begin() {
|
||||
return iterator(L, index, stack_index() + return_count());
|
||||
}
|
||||
iterator end() {
|
||||
return iterator(L, stack_index() + return_count(), stack_index() + return_count());
|
||||
}
|
||||
const_iterator begin() const {
|
||||
return const_iterator(L, index, stack_index() + return_count());
|
||||
}
|
||||
const_iterator end() const {
|
||||
return const_iterator(L, stack_index() + return_count(), stack_index() + return_count());
|
||||
}
|
||||
const_iterator cbegin() const {
|
||||
return begin();
|
||||
}
|
||||
const_iterator cend() const {
|
||||
return end();
|
||||
}
|
||||
|
||||
reverse_iterator rbegin() {
|
||||
return std::reverse_iterator<iterator>(begin());
|
||||
}
|
||||
reverse_iterator rend() {
|
||||
return std::reverse_iterator<iterator>(end());
|
||||
}
|
||||
const_reverse_iterator rbegin() const {
|
||||
return std::reverse_iterator<const_iterator>(begin());
|
||||
}
|
||||
const_reverse_iterator rend() const {
|
||||
return std::reverse_iterator<const_iterator>(end());
|
||||
}
|
||||
const_reverse_iterator crbegin() const {
|
||||
return std::reverse_iterator<const_iterator>(cbegin());
|
||||
}
|
||||
const_reverse_iterator crend() const {
|
||||
return std::reverse_iterator<const_iterator>(cend());
|
||||
}
|
||||
|
||||
lua_State* lua_state() const noexcept {
|
||||
return L;
|
||||
};
|
||||
int stack_index() const noexcept {
|
||||
return index;
|
||||
};
|
||||
int return_count() const noexcept {
|
||||
return returncount;
|
||||
};
|
||||
int pop_count() const noexcept {
|
||||
return popcount;
|
||||
};
|
||||
void abandon() noexcept {
|
||||
// L = nullptr;
|
||||
index = 0;
|
||||
returncount = 0;
|
||||
popcount = 0;
|
||||
err = call_status::runtime;
|
||||
}
|
||||
~protected_function_result() {
|
||||
stack::remove(L, index, popcount);
|
||||
}
|
||||
};
|
||||
|
||||
namespace stack {
|
||||
template <>
|
||||
struct unqualified_pusher<protected_function_result> {
|
||||
static int push(lua_State* L, const protected_function_result& pfr) {
|
||||
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
||||
luaL_checkstack(L, static_cast<int>(pfr.pop_count()), detail::not_enough_stack_space_generic);
|
||||
#endif // make sure stack doesn't overflow
|
||||
int p = 0;
|
||||
for (int i = 0; i < pfr.pop_count(); ++i) {
|
||||
lua_pushvalue(L, i + pfr.stack_index());
|
||||
++p;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
};
|
||||
} // namespace stack
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_PROTECTED_FUNCTION_RESULT_HPP
|
|
@ -1,113 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_PROTECTED_HANDLER_HPP
|
||||
#define SOL_PROTECTED_HANDLER_HPP
|
||||
|
||||
#include "reference.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "protected_function_result.hpp"
|
||||
#include "unsafe_function.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
inline const char(&default_handler_name())[9]{
|
||||
static const char name[9] = "sol.\xF0\x9F\x94\xA9";
|
||||
return name;
|
||||
}
|
||||
|
||||
template <bool b, typename target_t = reference>
|
||||
struct protected_handler {
|
||||
typedef is_stack_based<target_t> is_stack;
|
||||
const target_t& target;
|
||||
int stackindex;
|
||||
|
||||
protected_handler(std::false_type, const target_t& target)
|
||||
: target(target), stackindex(0) {
|
||||
if (b) {
|
||||
stackindex = lua_gettop(target.lua_state()) + 1;
|
||||
target.push();
|
||||
}
|
||||
}
|
||||
|
||||
protected_handler(std::true_type, const target_t& target)
|
||||
: target(target), stackindex(0) {
|
||||
if (b) {
|
||||
stackindex = target.stack_index();
|
||||
}
|
||||
}
|
||||
|
||||
protected_handler(const target_t& target)
|
||||
: protected_handler(is_stack(), target) {
|
||||
}
|
||||
|
||||
bool valid() const noexcept {
|
||||
return b;
|
||||
}
|
||||
|
||||
~protected_handler() {
|
||||
if constexpr (!is_stack::value) {
|
||||
if (stackindex != 0) {
|
||||
lua_remove(target.lua_state(), stackindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename base_t, typename T>
|
||||
basic_function<base_t> force_cast(T& p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
template <typename Reference, bool is_main_ref = false>
|
||||
static Reference get_default_handler(lua_State* L) {
|
||||
if (is_stack_based<Reference>::value || L == nullptr)
|
||||
return Reference(L, lua_nil);
|
||||
L = is_main_ref ? main_thread(L, L) : L;
|
||||
lua_getglobal(L, default_handler_name());
|
||||
auto pp = stack::pop_n(L, 1);
|
||||
return Reference(L, -1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void set_default_handler(lua_State* L, const T& ref) {
|
||||
if (L == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (!ref.valid()) {
|
||||
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
||||
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
|
||||
#endif // make sure stack doesn't overflow
|
||||
lua_pushnil(L);
|
||||
lua_setglobal(L, default_handler_name());
|
||||
}
|
||||
else {
|
||||
ref.push(L);
|
||||
lua_setglobal(L, default_handler_name());
|
||||
}
|
||||
}
|
||||
} // namespace detail
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_PROTECTED_HANDLER_HPP
|
|
@ -1,66 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_PROXY_BASE_HPP
|
||||
#define SOL_PROXY_BASE_HPP
|
||||
|
||||
#include "reference.hpp"
|
||||
#include "tuple.hpp"
|
||||
#include "stack.hpp"
|
||||
|
||||
namespace sol {
|
||||
struct proxy_base_tag {};
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
using proxy_key_t = meta::conditional_t<meta::is_specialization_of_v<meta::unqualified_t<T>, std::tuple>, T,
|
||||
std::tuple<meta::conditional_t<std::is_array_v<meta::unqualified_t<T>>, std::remove_reference_t<T>&, meta::unqualified_t<T>>>>;
|
||||
}
|
||||
|
||||
template <typename Super>
|
||||
struct proxy_base : proxy_base_tag {
|
||||
operator std::string() const {
|
||||
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
|
||||
return super.template get<std::string>();
|
||||
}
|
||||
|
||||
template <typename T, meta::enable<meta::neg<meta::is_string_constructible<T>>, is_proxy_primitive<meta::unqualified_t<T>>> = meta::enabler>
|
||||
operator T() const {
|
||||
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
|
||||
return super.template get<T>();
|
||||
}
|
||||
|
||||
template <typename T, meta::enable<meta::neg<meta::is_string_constructible<T>>, meta::neg<is_proxy_primitive<meta::unqualified_t<T>>>> = meta::enabler>
|
||||
operator T&() const {
|
||||
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
|
||||
return super.template get<T&>();
|
||||
}
|
||||
|
||||
lua_State* lua_state() const {
|
||||
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
|
||||
return super.lua_state();
|
||||
}
|
||||
};
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_PROXY_BASE_HPP
|
|
@ -1,166 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_RAII_HPP
|
||||
#define SOL_RAII_HPP
|
||||
|
||||
#include "traits.hpp"
|
||||
#include "compatibility.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
struct default_construct {
|
||||
template <typename T, typename... Args>
|
||||
static void construct(T&& obj, Args&&... args) {
|
||||
typedef meta::unqualified_t<T> Tu;
|
||||
std::allocator<Tu> alloc{};
|
||||
std::allocator_traits<std::allocator<Tu>>::construct(alloc, std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
void operator()(T&& obj, Args&&... args) const {
|
||||
construct(std::forward<T>(obj), std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
struct default_destruct {
|
||||
template <typename T>
|
||||
static void destroy(T&& obj) {
|
||||
std::allocator<meta::unqualified_t<T>> alloc{};
|
||||
alloc.destroy(obj);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void operator()(T&& obj) const {
|
||||
destroy(std::forward<T>(obj));
|
||||
}
|
||||
};
|
||||
|
||||
struct deleter {
|
||||
template <typename T>
|
||||
void operator()(T* p) const {
|
||||
delete p;
|
||||
}
|
||||
};
|
||||
|
||||
struct state_deleter {
|
||||
void operator()(lua_State* L) const {
|
||||
lua_close(L);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Dx, typename... Args>
|
||||
inline std::unique_ptr<T, Dx> make_unique_deleter(Args&&... args) {
|
||||
return std::unique_ptr<T, Dx>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template <typename Tag, typename T>
|
||||
struct tagged {
|
||||
private:
|
||||
T value_;
|
||||
|
||||
public:
|
||||
template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, tagged>> = meta::enabler>
|
||||
tagged(Arg&& arg, Args&&... args)
|
||||
: value_(std::forward<Arg>(arg), std::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
T& value() & {
|
||||
return value_;
|
||||
}
|
||||
|
||||
T const& value() const& {
|
||||
return value_;
|
||||
}
|
||||
|
||||
T&& value() && {
|
||||
return std::move(value_);
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <typename... Args>
|
||||
struct constructor_list {};
|
||||
|
||||
template <typename... Args>
|
||||
using constructors = constructor_list<Args...>;
|
||||
|
||||
const auto default_constructor = constructors<types<>>{};
|
||||
|
||||
struct no_construction {};
|
||||
const auto no_constructor = no_construction{};
|
||||
|
||||
struct call_construction {};
|
||||
const auto call_constructor = call_construction{};
|
||||
|
||||
template <typename... Functions>
|
||||
struct constructor_wrapper {
|
||||
std::tuple<Functions...> functions;
|
||||
template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, constructor_wrapper>> = meta::enabler>
|
||||
constructor_wrapper(Arg&& arg, Args&&... args)
|
||||
: functions(std::forward<Arg>(arg), std::forward<Args>(args)...) {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Functions>
|
||||
inline auto initializers(Functions&&... functions) {
|
||||
return constructor_wrapper<std::decay_t<Functions>...>(std::forward<Functions>(functions)...);
|
||||
}
|
||||
|
||||
template <typename... Functions>
|
||||
struct factory_wrapper {
|
||||
std::tuple<Functions...> functions;
|
||||
template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, factory_wrapper>> = meta::enabler>
|
||||
factory_wrapper(Arg&& arg, Args&&... args)
|
||||
: functions(std::forward<Arg>(arg), std::forward<Args>(args)...) {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Functions>
|
||||
inline auto factories(Functions&&... functions) {
|
||||
return factory_wrapper<std::decay_t<Functions>...>(std::forward<Functions>(functions)...);
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
struct destructor_wrapper {
|
||||
Function fx;
|
||||
destructor_wrapper(Function f)
|
||||
: fx(std::move(f)) {
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct destructor_wrapper<void> {};
|
||||
|
||||
const destructor_wrapper<void> default_destructor{};
|
||||
|
||||
template <typename Fx>
|
||||
inline auto destructor(Fx&& fx) {
|
||||
return destructor_wrapper<std::decay_t<Fx>>(std::forward<Fx>(fx));
|
||||
}
|
||||
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_RAII_HPP
|
|
@ -1,749 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_REFERENCE_HPP
|
||||
#define SOL_REFERENCE_HPP
|
||||
|
||||
#include "types.hpp"
|
||||
#include "stack_reference.hpp"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
inline const char (&default_main_thread_name())[9] {
|
||||
static const char name[9] = "sol.\xF0\x9F\x93\x8C";
|
||||
return name;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
namespace stack {
|
||||
inline void remove(lua_State* L, int rawindex, int count) {
|
||||
if (count < 1)
|
||||
return;
|
||||
int top = lua_gettop(L);
|
||||
if (top < 1) {
|
||||
return;
|
||||
}
|
||||
if (rawindex == -count || top == rawindex) {
|
||||
// Slice them right off the top
|
||||
lua_pop(L, static_cast<int>(count));
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove each item one at a time using stack operations
|
||||
// Probably slower, maybe, haven't benchmarked,
|
||||
// but necessary
|
||||
int index = lua_absindex(L, rawindex);
|
||||
if (index < 0) {
|
||||
index = lua_gettop(L) + (index + 1);
|
||||
}
|
||||
int last = index + count;
|
||||
for (int i = index; i < last; ++i) {
|
||||
lua_remove(L, index);
|
||||
}
|
||||
}
|
||||
|
||||
struct push_popper_at {
|
||||
lua_State* L;
|
||||
int index;
|
||||
int count;
|
||||
push_popper_at(lua_State* luastate, int index = -1, int count = 1)
|
||||
: L(luastate), index(index), count(count) {
|
||||
}
|
||||
~push_popper_at() {
|
||||
remove(L, index, count);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool top_level>
|
||||
struct push_popper_n {
|
||||
lua_State* L;
|
||||
int t;
|
||||
push_popper_n(lua_State* luastate, int x)
|
||||
: L(luastate), t(x) {
|
||||
}
|
||||
push_popper_n(const push_popper_n&) = delete;
|
||||
push_popper_n(push_popper_n&&) = default;
|
||||
push_popper_n& operator=(const push_popper_n&) = delete;
|
||||
push_popper_n& operator=(push_popper_n&&) = default;
|
||||
~push_popper_n() {
|
||||
lua_pop(L, t);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct push_popper_n<true> {
|
||||
push_popper_n(lua_State*, int) {
|
||||
}
|
||||
};
|
||||
|
||||
template <bool, typename T, typename = void>
|
||||
struct push_popper {
|
||||
using Tu = meta::unqualified_t<T>;
|
||||
T t;
|
||||
int idx;
|
||||
|
||||
push_popper(T x)
|
||||
: t(x), idx(lua_absindex(t.lua_state(), -t.push())) {
|
||||
|
||||
}
|
||||
|
||||
int index_of(const Tu&) {
|
||||
return idx;
|
||||
}
|
||||
|
||||
~push_popper() {
|
||||
t.pop();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename C>
|
||||
struct push_popper<true, T, C> {
|
||||
using Tu = meta::unqualified_t<T>;
|
||||
|
||||
push_popper(T) {
|
||||
}
|
||||
|
||||
int index_of(const Tu&) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
~push_popper() {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct push_popper<false, T, std::enable_if_t<is_stack_based_v<meta::unqualified_t<T>>>> {
|
||||
using Tu = meta::unqualified_t<T>;
|
||||
|
||||
push_popper(T) {
|
||||
}
|
||||
|
||||
int index_of(const Tu& r) {
|
||||
return r.stack_index();
|
||||
}
|
||||
|
||||
~push_popper() {
|
||||
}
|
||||
};
|
||||
|
||||
template <bool top_level = false, typename T>
|
||||
push_popper<top_level, T> push_pop(T&& x) {
|
||||
return push_popper<top_level, T>(std::forward<T>(x));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
push_popper_at push_pop_at(T&& x) {
|
||||
int c = x.push();
|
||||
lua_State* L = x.lua_state();
|
||||
return push_popper_at(L, lua_absindex(L, -c), c);
|
||||
}
|
||||
|
||||
template <bool top_level = false>
|
||||
push_popper_n<top_level> pop_n(lua_State* L, int x) {
|
||||
return push_popper_n<top_level>(L, x);
|
||||
}
|
||||
} // namespace stack
|
||||
|
||||
inline lua_State* main_thread(lua_State* L, lua_State* backup_if_unsupported = nullptr) {
|
||||
#if SOL_LUA_VERSION < 502
|
||||
if (L == nullptr)
|
||||
return backup_if_unsupported;
|
||||
lua_getglobal(L, detail::default_main_thread_name());
|
||||
auto pp = stack::pop_n(L, 1);
|
||||
if (type_of(L, -1) == type::thread) {
|
||||
return lua_tothread(L, -1);
|
||||
}
|
||||
return backup_if_unsupported;
|
||||
#else
|
||||
if (L == nullptr)
|
||||
return backup_if_unsupported;
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD);
|
||||
lua_State* Lmain = lua_tothread(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return Lmain;
|
||||
#endif // Lua 5.2+ has the main thread unqualified_getter
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
struct global_tag {
|
||||
} const global_ {};
|
||||
struct no_safety_tag {
|
||||
} const no_safety {};
|
||||
|
||||
template <bool b>
|
||||
inline lua_State* pick_main_thread(lua_State* L, lua_State* backup_if_unsupported = nullptr) {
|
||||
(void)L;
|
||||
(void)backup_if_unsupported;
|
||||
if (b) {
|
||||
return main_thread(L, backup_if_unsupported);
|
||||
}
|
||||
return L;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
class stateless_reference {
|
||||
private:
|
||||
template <bool o_main_only>
|
||||
friend class basic_reference;
|
||||
|
||||
int ref = LUA_NOREF;
|
||||
|
||||
int copy(lua_State* L) const noexcept {
|
||||
if (ref == LUA_NOREF)
|
||||
return LUA_NOREF;
|
||||
push(L);
|
||||
return luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
lua_State* copy_assign(lua_State* L, lua_State* rL, const stateless_reference& r) {
|
||||
if (valid(L)) {
|
||||
deref(L);
|
||||
}
|
||||
ref = r.copy(L);
|
||||
return rL;
|
||||
}
|
||||
|
||||
lua_State* move_assign(lua_State* L, lua_State* rL, stateless_reference&& r) {
|
||||
if (valid(L)) {
|
||||
deref(L);
|
||||
}
|
||||
ref = r.ref;
|
||||
r.ref = LUA_NOREF;
|
||||
return rL;
|
||||
}
|
||||
|
||||
protected:
|
||||
int stack_index () const noexcept {
|
||||
return -1;
|
||||
}
|
||||
|
||||
stateless_reference(lua_State* L, detail::global_tag) noexcept {
|
||||
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
||||
luaL_checkstack(L, 1, "not enough Lua stack space to push this reference value");
|
||||
#endif // make sure stack doesn't overflow
|
||||
lua_pushglobaltable(L);
|
||||
ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
stateless_reference(int raw_ref_index) noexcept : ref(raw_ref_index) {
|
||||
}
|
||||
|
||||
public:
|
||||
stateless_reference() noexcept = default;
|
||||
stateless_reference(lua_nil_t) noexcept : stateless_reference() {
|
||||
}
|
||||
stateless_reference(const stack_reference& r) noexcept : stateless_reference(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
stateless_reference(stack_reference&& r) noexcept : stateless_reference(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
stateless_reference(lua_State* L, const stateless_reference& r) noexcept {
|
||||
if (r.ref == LUA_REFNIL) {
|
||||
ref = LUA_REFNIL;
|
||||
return;
|
||||
}
|
||||
if (r.ref == LUA_NOREF || L == nullptr) {
|
||||
ref = LUA_NOREF;
|
||||
return;
|
||||
}
|
||||
ref = r.copy(L);
|
||||
}
|
||||
|
||||
stateless_reference(lua_State* L, stateless_reference&& r) noexcept {
|
||||
if (r.ref == LUA_REFNIL) {
|
||||
ref = LUA_REFNIL;
|
||||
return;
|
||||
}
|
||||
if (r.ref == LUA_NOREF || L == nullptr) {
|
||||
ref = LUA_NOREF;
|
||||
return;
|
||||
}
|
||||
ref = r.ref;
|
||||
r.ref = LUA_NOREF;
|
||||
}
|
||||
|
||||
stateless_reference(lua_State* L, const stack_reference& r) noexcept {
|
||||
if (L == nullptr || r.lua_state() == nullptr || r.get_type() == type::none) {
|
||||
ref = LUA_NOREF;
|
||||
return;
|
||||
}
|
||||
if (r.get_type() == type::lua_nil) {
|
||||
ref = LUA_REFNIL;
|
||||
return;
|
||||
}
|
||||
if (L != r.lua_state() && !detail::xmovable(L, r.lua_state())) {
|
||||
return;
|
||||
}
|
||||
r.push(L);
|
||||
ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
stateless_reference(lua_State* L, int index = -1) noexcept {
|
||||
// use L to stick with that state's execution stack
|
||||
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
||||
luaL_checkstack(L, 1, "not enough Lua stack space to push this reference value");
|
||||
#endif // make sure stack doesn't overflow
|
||||
lua_pushvalue(L, index);
|
||||
ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
stateless_reference(lua_State* L, ref_index index) noexcept {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, index.index);
|
||||
ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
stateless_reference(lua_State*, lua_nil_t) noexcept {
|
||||
}
|
||||
|
||||
~stateless_reference() noexcept = default;
|
||||
|
||||
stateless_reference(const stateless_reference& o) noexcept = delete;
|
||||
stateless_reference& operator=(const stateless_reference& r) noexcept = delete;
|
||||
|
||||
stateless_reference(stateless_reference&& o) noexcept
|
||||
: ref(o.ref) {
|
||||
o.ref = LUA_NOREF;
|
||||
}
|
||||
|
||||
stateless_reference& operator=(stateless_reference&& o) noexcept {
|
||||
ref = o.ref;
|
||||
o.ref = LUA_NOREF;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
int push(lua_State* L) const noexcept {
|
||||
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
||||
luaL_checkstack(L, 1, "not enough Lua stack space to push this reference value");
|
||||
#endif // make sure stack doesn't overflow
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void pop(lua_State* L, int n = 1) const noexcept {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
|
||||
int registry_index() const noexcept {
|
||||
return ref;
|
||||
}
|
||||
|
||||
bool valid(lua_State*) const noexcept {
|
||||
return !(ref == LUA_NOREF || ref == LUA_REFNIL);
|
||||
}
|
||||
|
||||
const void* pointer(lua_State* L) const noexcept {
|
||||
int si = push(L);
|
||||
const void* vp = lua_topointer(L, -si);
|
||||
lua_pop(L, si);
|
||||
return vp;
|
||||
}
|
||||
|
||||
type get_type(lua_State* L) const noexcept {
|
||||
int p = push(L);
|
||||
int result = lua_type(L, -1);
|
||||
pop(L, p);
|
||||
return static_cast<type>(result);
|
||||
}
|
||||
|
||||
void abandon(lua_State* = nullptr) {
|
||||
ref = LUA_NOREF;
|
||||
}
|
||||
|
||||
void deref(lua_State* L) const noexcept {
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, ref);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool main_only = false>
|
||||
class basic_reference : public stateless_reference {
|
||||
private:
|
||||
template <bool o_main_only>
|
||||
friend class basic_reference;
|
||||
lua_State* luastate = nullptr; // non-owning
|
||||
|
||||
template <bool r_main_only>
|
||||
void copy_assign(const basic_reference<r_main_only>& r) {
|
||||
if (valid()) {
|
||||
deref();
|
||||
}
|
||||
if (r.ref == LUA_REFNIL) {
|
||||
luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
|
||||
ref = LUA_REFNIL;
|
||||
return;
|
||||
}
|
||||
if (r.ref == LUA_NOREF) {
|
||||
luastate = r.luastate;
|
||||
ref = LUA_NOREF;
|
||||
return;
|
||||
}
|
||||
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||
r.push(lua_state());
|
||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||
return;
|
||||
}
|
||||
luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
|
||||
ref = r.copy();
|
||||
}
|
||||
|
||||
template <bool r_main_only>
|
||||
void move_assign(basic_reference<r_main_only>&& r) {
|
||||
if (valid()) {
|
||||
deref();
|
||||
}
|
||||
if (r.ref == LUA_REFNIL) {
|
||||
luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
|
||||
ref = LUA_REFNIL;
|
||||
return;
|
||||
}
|
||||
if (r.ref == LUA_NOREF) {
|
||||
luastate = r.luastate;
|
||||
ref = LUA_NOREF;
|
||||
return;
|
||||
}
|
||||
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||
r.push(lua_state());
|
||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||
return;
|
||||
}
|
||||
|
||||
luastate = detail::pick_main_thread < main_only && !r_main_only > (r.lua_state(), r.lua_state());
|
||||
ref = r.ref;
|
||||
r.ref = LUA_NOREF;
|
||||
r.luastate = nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
basic_reference(lua_State* L, detail::global_tag) noexcept
|
||||
: basic_reference(detail::pick_main_thread<main_only>(L, L), detail::global_, detail::global_) {
|
||||
}
|
||||
|
||||
basic_reference(lua_State* L, detail::global_tag, detail::global_tag) noexcept
|
||||
: stateless_reference(L, detail::global_), luastate(L) {
|
||||
}
|
||||
|
||||
basic_reference(lua_State* oL, const basic_reference<!main_only>& o) noexcept : stateless_reference(oL, o), luastate(oL) {
|
||||
}
|
||||
|
||||
void deref() const noexcept {
|
||||
return stateless_reference::deref(lua_state());
|
||||
}
|
||||
|
||||
int copy() const noexcept {
|
||||
return copy(lua_state());
|
||||
}
|
||||
|
||||
int copy(lua_State* L) const noexcept {
|
||||
return stateless_reference::copy(L);
|
||||
}
|
||||
|
||||
public:
|
||||
basic_reference() noexcept = default;
|
||||
basic_reference(lua_nil_t) noexcept
|
||||
: basic_reference() {
|
||||
}
|
||||
basic_reference(const stack_reference& r) noexcept
|
||||
: basic_reference(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
basic_reference(stack_reference&& r) noexcept
|
||||
: basic_reference(r.lua_state(), r.stack_index()) {
|
||||
}
|
||||
template <bool r_main_only>
|
||||
basic_reference(lua_State* L, const basic_reference<r_main_only>& r) noexcept
|
||||
: luastate(detail::pick_main_thread<main_only>(L, L)) {
|
||||
if (r.ref == LUA_REFNIL) {
|
||||
ref = LUA_REFNIL;
|
||||
return;
|
||||
}
|
||||
if (r.ref == LUA_NOREF || lua_state() == nullptr) {
|
||||
ref = LUA_NOREF;
|
||||
return;
|
||||
}
|
||||
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||
r.push(lua_state());
|
||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||
return;
|
||||
}
|
||||
ref = r.copy();
|
||||
}
|
||||
|
||||
template <bool r_main_only>
|
||||
basic_reference(lua_State* L, basic_reference<r_main_only>&& r) noexcept
|
||||
: luastate(detail::pick_main_thread<main_only>(L, L)) {
|
||||
if (r.ref == LUA_REFNIL) {
|
||||
ref = LUA_REFNIL;
|
||||
return;
|
||||
}
|
||||
if (r.ref == LUA_NOREF || lua_state() == nullptr) {
|
||||
ref = LUA_NOREF;
|
||||
return;
|
||||
}
|
||||
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||
r.push(lua_state());
|
||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||
return;
|
||||
}
|
||||
ref = r.ref;
|
||||
r.ref = LUA_NOREF;
|
||||
r.luastate = nullptr;
|
||||
}
|
||||
|
||||
basic_reference(lua_State* L, const stack_reference& r) noexcept
|
||||
: luastate(detail::pick_main_thread<main_only>(L, L)) {
|
||||
if (lua_state() == nullptr || r.lua_state() == nullptr || r.get_type() == type::none) {
|
||||
ref = LUA_NOREF;
|
||||
return;
|
||||
}
|
||||
if (r.get_type() == type::lua_nil) {
|
||||
ref = LUA_REFNIL;
|
||||
return;
|
||||
}
|
||||
if (lua_state() != r.lua_state() && !detail::xmovable(lua_state(), r.lua_state())) {
|
||||
return;
|
||||
}
|
||||
r.push(lua_state());
|
||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||
}
|
||||
basic_reference(lua_State* L, int index = -1) noexcept
|
||||
: luastate(detail::pick_main_thread<main_only>(L, L)) {
|
||||
// use L to stick with that state's execution stack
|
||||
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
||||
luaL_checkstack(L, 1, "not enough Lua stack space to push this reference value");
|
||||
#endif // make sure stack doesn't overflow
|
||||
lua_pushvalue(L, index);
|
||||
ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
basic_reference(lua_State* L, ref_index index) noexcept
|
||||
: luastate(detail::pick_main_thread<main_only>(L, L)) {
|
||||
lua_rawgeti(lua_state(), LUA_REGISTRYINDEX, index.index);
|
||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||
}
|
||||
basic_reference(lua_State* L, lua_nil_t) noexcept
|
||||
: luastate(detail::pick_main_thread<main_only>(L, L)) {
|
||||
}
|
||||
|
||||
~basic_reference() noexcept {
|
||||
if (lua_state() == nullptr || ref == LUA_NOREF)
|
||||
return;
|
||||
deref();
|
||||
}
|
||||
|
||||
basic_reference(const basic_reference& o) noexcept
|
||||
: stateless_reference(o.copy()), luastate(o.lua_state()) {
|
||||
}
|
||||
|
||||
basic_reference(basic_reference&& o) noexcept
|
||||
: stateless_reference(std::move(o)), luastate(o.lua_state()) {
|
||||
o.luastate = nullptr;
|
||||
}
|
||||
|
||||
basic_reference(const basic_reference<!main_only>& o) noexcept
|
||||
: basic_reference(detail::pick_main_thread<main_only>(o.lua_state(), o.lua_state()), o) {
|
||||
}
|
||||
|
||||
basic_reference(basic_reference<!main_only>&& o) noexcept
|
||||
: stateless_reference(std::move(o)), luastate(detail::pick_main_thread<main_only>(o.lua_state(), o.lua_state())) {
|
||||
o.luastate = nullptr;
|
||||
o.ref = LUA_NOREF;
|
||||
}
|
||||
|
||||
basic_reference& operator=(basic_reference&& r) noexcept {
|
||||
move_assign(std::move(r));
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_reference& operator=(const basic_reference& r) noexcept {
|
||||
copy_assign(r);
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_reference& operator=(basic_reference<!main_only>&& r) noexcept {
|
||||
move_assign(std::move(r));
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_reference& operator=(const basic_reference<!main_only>& r) noexcept {
|
||||
copy_assign(r);
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_reference& operator=(const lua_nil_t&) noexcept {
|
||||
if (valid()) {
|
||||
deref();
|
||||
}
|
||||
luastate = nullptr;
|
||||
ref = LUA_NOREF;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Super>
|
||||
basic_reference& operator=(proxy_base<Super>&& r);
|
||||
|
||||
template <typename Super>
|
||||
basic_reference& operator=(const proxy_base<Super>& r);
|
||||
|
||||
int push() const noexcept {
|
||||
return push(lua_state());
|
||||
}
|
||||
|
||||
int push(lua_State* L) const noexcept {
|
||||
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
||||
luaL_checkstack(L, 1, "not enough Lua stack space to push this reference value");
|
||||
#endif // make sure stack doesn't overflow
|
||||
if (lua_state() == nullptr) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
lua_rawgeti(lua_state(), LUA_REGISTRYINDEX, ref);
|
||||
if (L != lua_state()) {
|
||||
lua_xmove(lua_state(), L, 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void pop() const noexcept {
|
||||
pop(lua_state());
|
||||
}
|
||||
|
||||
void pop(lua_State* L, int n = 1) const noexcept {
|
||||
stateless_reference::pop(L, n);
|
||||
}
|
||||
|
||||
int registry_index() const noexcept {
|
||||
return stateless_reference::registry_index();
|
||||
}
|
||||
|
||||
bool valid() const noexcept {
|
||||
return stateless_reference::valid(lua_state());
|
||||
}
|
||||
|
||||
const void* pointer() const noexcept {
|
||||
return stateless_reference::pointer(lua_state());
|
||||
}
|
||||
|
||||
explicit operator bool() const noexcept {
|
||||
return valid();
|
||||
}
|
||||
|
||||
type get_type() const noexcept {
|
||||
return stateless_reference::get_type(lua_state());
|
||||
}
|
||||
|
||||
lua_State* lua_state() const noexcept {
|
||||
return luastate;
|
||||
}
|
||||
};
|
||||
|
||||
template <bool lb, bool rb>
|
||||
inline bool operator==(const basic_reference<lb>& l, const basic_reference<rb>& r) {
|
||||
auto ppl = stack::push_pop(l);
|
||||
auto ppr = stack::push_pop(r);
|
||||
return lua_compare(l.lua_state(), -1, -2, LUA_OPEQ) == 1;
|
||||
}
|
||||
|
||||
template <bool lb, bool rb>
|
||||
inline bool operator!=(const basic_reference<lb>& l, const basic_reference<rb>& r) {
|
||||
return !operator==(l, r);
|
||||
}
|
||||
|
||||
template <bool lb>
|
||||
inline bool operator==(const basic_reference<lb>& l, const stack_reference& r) {
|
||||
auto ppl = stack::push_pop(l);
|
||||
return lua_compare(l.lua_state(), -1, r.stack_index(), LUA_OPEQ) == 1;
|
||||
}
|
||||
|
||||
template <bool lb>
|
||||
inline bool operator!=(const basic_reference<lb>& l, const stack_reference& r) {
|
||||
return !operator==(l, r);
|
||||
}
|
||||
|
||||
template <bool rb>
|
||||
inline bool operator==(const stack_reference& l, const basic_reference<rb>& r) {
|
||||
auto ppr = stack::push_pop(r);
|
||||
return lua_compare(l.lua_state(), -1, r.stack_index(), LUA_OPEQ) == 1;
|
||||
}
|
||||
|
||||
template <bool rb>
|
||||
inline bool operator!=(const stack_reference& l, const basic_reference<rb>& r) {
|
||||
return !operator==(l, r);
|
||||
}
|
||||
|
||||
template <bool lb>
|
||||
inline bool operator==(const basic_reference<lb>& lhs, const lua_nil_t&) {
|
||||
return !lhs.valid();
|
||||
}
|
||||
|
||||
template <bool rb>
|
||||
inline bool operator==(const lua_nil_t&, const basic_reference<rb>& rhs) {
|
||||
return !rhs.valid();
|
||||
}
|
||||
|
||||
template <bool lb>
|
||||
inline bool operator!=(const basic_reference<lb>& lhs, const lua_nil_t&) {
|
||||
return lhs.valid();
|
||||
}
|
||||
|
||||
template <bool rb>
|
||||
inline bool operator!=(const lua_nil_t&, const basic_reference<rb>& rhs) {
|
||||
return rhs.valid();
|
||||
}
|
||||
|
||||
struct reference_equals : public stack_reference_equals {
|
||||
template <bool rb>
|
||||
bool operator()(const lua_nil_t& lhs, const basic_reference<rb>& rhs) const {
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
template <bool lb>
|
||||
bool operator()(const basic_reference<lb>& lhs, const lua_nil_t& rhs) const {
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
template <bool lb, bool rb>
|
||||
bool operator()(const basic_reference<lb>& lhs, const basic_reference<rb>& rhs) const {
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
template <bool lb>
|
||||
bool operator()(const basic_reference<lb>& lhs, const stack_reference& rhs) const {
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
template <bool rb>
|
||||
bool operator()(const stack_reference& lhs, const basic_reference<rb>& rhs) const {
|
||||
return lhs == rhs;
|
||||
}
|
||||
};
|
||||
|
||||
struct reference_hash : public stack_reference_hash {
|
||||
typedef reference argument_type;
|
||||
typedef std::size_t result_type;
|
||||
|
||||
template <bool lb>
|
||||
result_type operator()(const basic_reference<lb>& lhs) const {
|
||||
std::hash<const void*> h;
|
||||
return h(lhs.pointer());
|
||||
}
|
||||
};
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_REFERENCE_HPP
|
|
@ -1,175 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_RESOLVE_HPP
|
||||
#define SOL_RESOLVE_HPP
|
||||
|
||||
#include "traits.hpp"
|
||||
#include "tuple.hpp"
|
||||
|
||||
namespace sol {
|
||||
|
||||
#ifndef __clang__
|
||||
// constexpr is fine for not-clang
|
||||
|
||||
namespace detail {
|
||||
template <typename R, typename... Args, typename F, typename = std::invoke_result_t<meta::unqualified_t<F>, Args...>>
|
||||
inline constexpr auto resolve_i(types<R(Args...)>, F &&) -> R (meta::unqualified_t<F>::*)(Args...) {
|
||||
using Sig = R(Args...);
|
||||
typedef meta::unqualified_t<F> Fu;
|
||||
return static_cast<Sig Fu::*>(&Fu::operator());
|
||||
}
|
||||
|
||||
template <typename F, typename U = meta::unqualified_t<F>>
|
||||
inline constexpr auto resolve_f(std::true_type, F&& f)
|
||||
-> decltype(resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
|
||||
return resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
inline constexpr void resolve_f(std::false_type, F&&) {
|
||||
static_assert(
|
||||
meta::has_deducible_signature<F>::value, "Cannot use no-template-parameter call with an overloaded functor: specify the signature");
|
||||
}
|
||||
|
||||
template <typename F, typename U = meta::unqualified_t<F>>
|
||||
inline constexpr auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::has_deducible_signature<U>(), std::forward<F>(f))) {
|
||||
return resolve_f(meta::has_deducible_signature<U> {}, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <typename... Args, typename F, typename R = std::invoke_result_t<F&, Args...>>
|
||||
inline constexpr auto resolve_i(types<Args...>, F&& f) -> decltype(resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
|
||||
return resolve_i(types<R(Args...)>(), std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <typename Sig, typename C>
|
||||
inline constexpr Sig C::*resolve_v(std::false_type, Sig C::*mem_func_ptr) {
|
||||
return mem_func_ptr;
|
||||
}
|
||||
|
||||
template <typename Sig, typename C>
|
||||
inline constexpr Sig C::*resolve_v(std::true_type, Sig C::*mem_variable_ptr) {
|
||||
return mem_variable_ptr;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <typename... Args, typename R>
|
||||
inline constexpr auto resolve(R fun_ptr(Args...)) -> R (*)(Args...) {
|
||||
return fun_ptr;
|
||||
}
|
||||
|
||||
template <typename Sig>
|
||||
inline constexpr Sig* resolve(Sig* fun_ptr) {
|
||||
return fun_ptr;
|
||||
}
|
||||
|
||||
template <typename... Args, typename R, typename C>
|
||||
inline constexpr auto resolve(R (C::*mem_ptr)(Args...)) -> R (C::*)(Args...) {
|
||||
return mem_ptr;
|
||||
}
|
||||
|
||||
template <typename Sig, typename C>
|
||||
inline constexpr Sig C::*resolve(Sig C::*mem_ptr) {
|
||||
return detail::resolve_v(std::is_member_object_pointer<Sig C::*>(), mem_ptr);
|
||||
}
|
||||
|
||||
template <typename... Sig, typename F, meta::disable<std::is_function<meta::unqualified_t<F>>> = meta::enabler>
|
||||
inline constexpr auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
|
||||
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
||||
}
|
||||
#else
|
||||
|
||||
// Clang has distinct problems with constexpr arguments,
|
||||
// so don't use the constexpr versions inside of clang.
|
||||
|
||||
namespace detail {
|
||||
template <typename R, typename... Args, typename F, typename = std::invoke_result_t<meta::unqualified_t<F>, Args...>>
|
||||
inline auto resolve_i(types<R(Args...)>, F &&) -> R (meta::unqualified_t<F>::*)(Args...) {
|
||||
using Sig = R(Args...);
|
||||
typedef meta::unqualified_t<F> Fu;
|
||||
return static_cast<Sig Fu::*>(&Fu::operator());
|
||||
}
|
||||
|
||||
template <typename F, typename U = meta::unqualified_t<F>>
|
||||
inline auto resolve_f(std::true_type, F&& f)
|
||||
-> decltype(resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
|
||||
return resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
inline void resolve_f(std::false_type, F&&) {
|
||||
static_assert(
|
||||
meta::has_deducible_signature<F>::value, "Cannot use no-template-parameter call with an overloaded functor: specify the signature");
|
||||
}
|
||||
|
||||
template <typename F, typename U = meta::unqualified_t<F>>
|
||||
inline auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::has_deducible_signature<U>(), std::forward<F>(f))) {
|
||||
return resolve_f(meta::has_deducible_signature<U> {}, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <typename... Args, typename F, typename R = std::invoke_result_t<F&, Args...>>
|
||||
inline auto resolve_i(types<Args...>, F&& f) -> decltype(resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
|
||||
return resolve_i(types<R(Args...)>(), std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <typename Sig, typename C>
|
||||
inline Sig C::*resolve_v(std::false_type, Sig C::*mem_func_ptr) {
|
||||
return mem_func_ptr;
|
||||
}
|
||||
|
||||
template <typename Sig, typename C>
|
||||
inline Sig C::*resolve_v(std::true_type, Sig C::*mem_variable_ptr) {
|
||||
return mem_variable_ptr;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <typename... Args, typename R>
|
||||
inline auto resolve(R fun_ptr(Args...)) -> R (*)(Args...) {
|
||||
return fun_ptr;
|
||||
}
|
||||
|
||||
template <typename Sig>
|
||||
inline Sig* resolve(Sig* fun_ptr) {
|
||||
return fun_ptr;
|
||||
}
|
||||
|
||||
template <typename... Args, typename R, typename C>
|
||||
inline auto resolve(R (C::*mem_ptr)(Args...)) -> R (C::*)(Args...) {
|
||||
return mem_ptr;
|
||||
}
|
||||
|
||||
template <typename Sig, typename C>
|
||||
inline Sig C::*resolve(Sig C::*mem_ptr) {
|
||||
return detail::resolve_v(std::is_member_object_pointer<Sig C::*>(), mem_ptr);
|
||||
}
|
||||
|
||||
template <typename... Sig, typename F>
|
||||
inline auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
|
||||
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_RESOLVE_HPP
|
File diff suppressed because it is too large
Load Diff
|
@ -1,304 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_STACK_HPP
|
||||
#define SOL_STACK_HPP
|
||||
|
||||
#include "trampoline.hpp"
|
||||
#include "stack_core.hpp"
|
||||
#include "stack_reference.hpp"
|
||||
#include "stack_check.hpp"
|
||||
#include "stack_get.hpp"
|
||||
#include "stack_check_get.hpp"
|
||||
#include "stack_push.hpp"
|
||||
#include "stack_pop.hpp"
|
||||
#include "stack_field.hpp"
|
||||
#include "stack_probe.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <array>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
using typical_chunk_name_t = char[SOL_ID_SIZE_];
|
||||
using typical_file_chunk_name_t = char[SOL_FILE_ID_SIZE_];
|
||||
|
||||
inline const std::string& default_chunk_name() {
|
||||
static const std::string name = "";
|
||||
return name;
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
const char* make_chunk_name(const string_view& code, const std::string& chunkname, char (&basechunkname)[N]) {
|
||||
if (chunkname.empty()) {
|
||||
auto it = code.cbegin();
|
||||
auto e = code.cend();
|
||||
std::size_t i = 0;
|
||||
static const std::size_t n = N - 4;
|
||||
for (i = 0; i < n && it != e; ++i, ++it) {
|
||||
basechunkname[i] = *it;
|
||||
}
|
||||
if (it != e) {
|
||||
for (std::size_t c = 0; c < 3; ++i, ++c) {
|
||||
basechunkname[i] = '.';
|
||||
}
|
||||
}
|
||||
basechunkname[i] = '\0';
|
||||
return &basechunkname[0];
|
||||
}
|
||||
else {
|
||||
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 stack {
|
||||
namespace stack_detail {
|
||||
template <typename T>
|
||||
inline int push_as_upvalues(lua_State* L, T& item) {
|
||||
typedef std::decay_t<T> TValue;
|
||||
static const std::size_t itemsize = sizeof(TValue);
|
||||
static const std::size_t voidsize = sizeof(void*);
|
||||
static const std::size_t voidsizem1 = voidsize - 1;
|
||||
static const std::size_t data_t_count = (sizeof(TValue) + voidsizem1) / voidsize;
|
||||
typedef std::array<void*, data_t_count> data_t;
|
||||
|
||||
data_t data { {} };
|
||||
std::memcpy(&data[0], std::addressof(item), itemsize);
|
||||
int pushcount = 0;
|
||||
for (auto&& v : data) {
|
||||
pushcount += push(L, lightuserdata_value(v));
|
||||
}
|
||||
return pushcount;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::pair<T, int> get_as_upvalues(lua_State* L, int index = 2) {
|
||||
static const std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*);
|
||||
typedef std::array<void*, data_t_count> data_t;
|
||||
data_t voiddata { {} };
|
||||
for (std::size_t i = 0, d = 0; d < sizeof(T); ++i, d += sizeof(void*)) {
|
||||
voiddata[i] = get<lightuserdata_value>(L, upvalue_index(index++));
|
||||
}
|
||||
return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index);
|
||||
}
|
||||
|
||||
template <typename Fx, typename... Args>
|
||||
static decltype(auto) eval(types<>, std::index_sequence<>, lua_State*, int, record&, Fx&& fx, Args&&... args) {
|
||||
return std::forward<Fx>(fx)(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Fx, typename Arg, typename... Args, std::size_t I, std::size_t... Is, typename... FxArgs>
|
||||
static decltype(auto) eval(
|
||||
types<Arg, Args...>, std::index_sequence<I, Is...>, lua_State* L, int start, record& tracking, Fx&& fx, FxArgs&&... fxargs) {
|
||||
return eval(types<Args...>(),
|
||||
std::index_sequence<Is...>(),
|
||||
L,
|
||||
start,
|
||||
tracking,
|
||||
std::forward<Fx>(fx),
|
||||
std::forward<FxArgs>(fxargs)...,
|
||||
stack_detail::unchecked_get<Arg>(L, start + tracking.used, tracking));
|
||||
}
|
||||
|
||||
template <bool checkargs = detail::default_safe_function_calls, std::size_t... I, typename R, typename... Args, typename Fx, typename... FxArgs>
|
||||
inline decltype(auto) call(types<R>, types<Args...> ta, std::index_sequence<I...> tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
|
||||
static_assert(meta::all<meta::is_not_move_only<Args>...>::value,
|
||||
"One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take "
|
||||
"a reference and std::move it manually if this was your intention.");
|
||||
if constexpr (checkargs) {
|
||||
argument_handler<types<R, Args...>> handler {};
|
||||
multi_check<Args...>(L, start, handler);
|
||||
}
|
||||
record tracking {};
|
||||
if constexpr (std::is_void_v<R>) {
|
||||
eval(ta, tai, L, start, tracking, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
||||
}
|
||||
else {
|
||||
return eval(ta, tai, L, start, tracking, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
||||
}
|
||||
}
|
||||
} // namespace stack_detail
|
||||
|
||||
template <typename T>
|
||||
int set_ref(lua_State* L, T&& arg, int tableindex = -2) {
|
||||
push(L, std::forward<T>(arg));
|
||||
return luaL_ref(L, tableindex);
|
||||
}
|
||||
|
||||
template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
|
||||
inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
|
||||
using args_indices = std::make_index_sequence<sizeof...(Args)>;
|
||||
if constexpr (std::is_void_v<R>) {
|
||||
stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
||||
}
|
||||
else {
|
||||
return stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
|
||||
inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
|
||||
if constexpr (std::is_void_v<R>) {
|
||||
call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
||||
}
|
||||
else {
|
||||
return call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
|
||||
inline decltype(auto) call_from_top(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
|
||||
using expected_count_t = meta::count_for_pack<lua_size, Args...>;
|
||||
if constexpr (std::is_void_v<R>) {
|
||||
call<check_args>(tr,
|
||||
ta,
|
||||
L,
|
||||
(std::max)(static_cast<int>(lua_gettop(L) - expected_count_t::value), static_cast<int>(0)),
|
||||
std::forward<Fx>(fx),
|
||||
std::forward<FxArgs>(args)...);
|
||||
}
|
||||
else {
|
||||
return call<check_args>(tr,
|
||||
ta,
|
||||
L,
|
||||
(std::max)(static_cast<int>(lua_gettop(L) - expected_count_t::value), static_cast<int>(0)),
|
||||
std::forward<Fx>(fx),
|
||||
std::forward<FxArgs>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Ret0, typename... Ret, typename... Args,
|
||||
typename Fx, typename... FxArgs>
|
||||
inline int call_into_lua(types<Ret0, Ret...> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
|
||||
if constexpr (std::is_void_v<Ret0>) {
|
||||
call<check_args>(tr, ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
||||
if constexpr (clean_stack) {
|
||||
lua_settop(L, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
(void)tr;
|
||||
decltype(auto) r
|
||||
= call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
||||
using R = meta::unqualified_t<decltype(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>>;
|
||||
if constexpr (clean_stack && !is_stack::value) {
|
||||
lua_settop(L, 0);
|
||||
}
|
||||
return push_reference(L, std::forward<decltype(r)>(r));
|
||||
}
|
||||
}
|
||||
|
||||
template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Fx, typename... FxArgs>
|
||||
inline int call_lua(lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
|
||||
using traits_type = lua_bind_traits<meta::unqualified_t<Fx>>;
|
||||
using args_list = typename traits_type::args_list;
|
||||
using returns_list = typename traits_type::returns_list;
|
||||
return call_into_lua<check_args, clean_stack>(returns_list(), args_list(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
||||
}
|
||||
|
||||
inline call_syntax get_call_syntax(lua_State* L, const string_view& key, int index) {
|
||||
if (lua_gettop(L) < 1) {
|
||||
return call_syntax::dot;
|
||||
}
|
||||
luaL_getmetatable(L, key.data());
|
||||
auto pn = pop_n(L, 1);
|
||||
if (lua_compare(L, -1, index, LUA_OPEQ) != 1) {
|
||||
return call_syntax::dot;
|
||||
}
|
||||
return call_syntax::colon;
|
||||
}
|
||||
|
||||
inline void script(
|
||||
lua_State* L, lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
|
||||
detail::typical_chunk_name_t basechunkname = {};
|
||||
const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
|
||||
if (lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
|
||||
lua_error(L);
|
||||
}
|
||||
}
|
||||
|
||||
inline void script(
|
||||
lua_State* L, const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
|
||||
|
||||
detail::typical_chunk_name_t basechunkname = {};
|
||||
const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
|
||||
if (luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
|
||||
lua_error(L);
|
||||
}
|
||||
}
|
||||
|
||||
inline void script_file(lua_State* L, const std::string& filename, load_mode mode = load_mode::any) {
|
||||
if (luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
|
||||
lua_error(L);
|
||||
}
|
||||
}
|
||||
|
||||
inline void luajit_exception_handler(lua_State* L, int (*handler)(lua_State*, lua_CFunction) = detail::c_trampoline) {
|
||||
#if defined(SOL_LUAJIT) && (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !(SOL_EXCEPTIONS_SAFE_PROPAGATION))
|
||||
if (L == nullptr) {
|
||||
return;
|
||||
}
|
||||
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
||||
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
|
||||
#endif // make sure stack doesn't overflow
|
||||
lua_pushlightuserdata(L, (void*)handler);
|
||||
auto pn = pop_n(L, 1);
|
||||
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON);
|
||||
#else
|
||||
(void)L;
|
||||
(void)handler;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void luajit_exception_off(lua_State* L) {
|
||||
#if defined(SOL_LUAJIT)
|
||||
if (L == nullptr) {
|
||||
return;
|
||||
}
|
||||
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_OFF);
|
||||
#else
|
||||
(void)L;
|
||||
#endif
|
||||
}
|
||||
} // namespace stack
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_STACK_HPP
|
|
@ -1,30 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_STACK_CHECK_HPP
|
||||
#define SOL_STACK_CHECK_HPP
|
||||
|
||||
#include "stack_check_unqualified.hpp"
|
||||
#include "stack_check_qualified.hpp"
|
||||
|
||||
#endif // SOL_STACK_CHECK_HPP
|
|
@ -1,30 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_STACK_CHECK_GET_HPP
|
||||
#define SOL_STACK_CHECK_GET_HPP
|
||||
|
||||
#include "stack_check_get_unqualified.hpp"
|
||||
#include "stack_check_get_qualified.hpp"
|
||||
|
||||
#endif // SOL_STACK_CHECK_GET_HPP
|
|
@ -1,87 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_STACK_CHECK_QUALIFIED_GET_HPP
|
||||
#define SOL_STACK_CHECK_QUALIFIED_GET_HPP
|
||||
|
||||
#include "stack_core.hpp"
|
||||
#include "stack_check_get_unqualified.hpp"
|
||||
#include "optional.hpp"
|
||||
|
||||
namespace sol { namespace stack {
|
||||
template <typename T, typename C>
|
||||
struct qualified_check_getter {
|
||||
typedef decltype(stack_detail::unchecked_get<T>(nullptr, -1, std::declval<record&>())) R;
|
||||
|
||||
template <typename Handler>
|
||||
static optional<R> get(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
if constexpr (is_lua_reference_v<T>) {
|
||||
// actually check if it's none here, otherwise
|
||||
// we'll have a none object inside an optional!
|
||||
bool success = lua_isnoneornil(L, index) == 0 && stack::check<T>(L, index, no_panic);
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
tracking.use(static_cast<int>(success));
|
||||
handler(L, index, type::poly, type_of(L, index), "");
|
||||
return nullopt;
|
||||
}
|
||||
return stack_detail::unchecked_get<T>(L, index, tracking);
|
||||
}
|
||||
else {
|
||||
if (!check<T>(L, index, std::forward<Handler>(handler))) {
|
||||
tracking.use(static_cast<int>(!lua_isnone(L, index)));
|
||||
return nullopt;
|
||||
}
|
||||
return stack_detail::unchecked_get<T>(L, index, tracking);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct qualified_getter<T, std::enable_if_t<meta::is_optional_v<T>>> {
|
||||
static T get(lua_State* L, int index, record& tracking) {
|
||||
using ValueType = typename meta::unqualified_t<T>::value_type;
|
||||
if constexpr (is_lua_reference_v<ValueType>) {
|
||||
// actually check if it's none here, otherwise
|
||||
// we'll have a none object inside an optional!
|
||||
bool success = lua_isnoneornil(L, index) == 0 && stack::check<ValueType>(L, index, no_panic);
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
tracking.use(static_cast<int>(success));
|
||||
return {};
|
||||
}
|
||||
return stack_detail::unchecked_get<ValueType>(L, index, tracking);
|
||||
}
|
||||
else {
|
||||
if (!check<ValueType>(L, index, &no_panic)) {
|
||||
tracking.use(static_cast<int>(!lua_isnone(L, index)));
|
||||
return {};
|
||||
}
|
||||
return stack_detail::unchecked_get<ValueType>(L, index, tracking);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace sol::stack
|
||||
|
||||
#endif // SOL_STACK_CHECK_QUALIFIED_GET_HPP
|
|
@ -1,177 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_STACK_CHECK_UNQUALIFIED_GET_HPP
|
||||
#define SOL_STACK_CHECK_UNQUALIFIED_GET_HPP
|
||||
|
||||
#include "stack_core.hpp"
|
||||
#include "stack_get.hpp"
|
||||
#include "stack_check.hpp"
|
||||
#include "optional.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <optional>
|
||||
#if SOL_ON(SOL_STD_VARIANT_)
|
||||
#include <variant>
|
||||
#endif // variant shenanigans (thanks, Mac OSX)
|
||||
|
||||
|
||||
namespace sol { namespace stack {
|
||||
template <typename T, typename>
|
||||
struct unqualified_check_getter {
|
||||
typedef decltype(stack_detail::unchecked_unqualified_get<T>(nullptr, -1, std::declval<record&>())) R;
|
||||
|
||||
template <typename Optional, typename Handler>
|
||||
static Optional get_using(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
if constexpr (!meta::meta_detail::is_adl_sol_lua_check_v<T> && !meta::meta_detail::is_adl_sol_lua_get_v<T>) {
|
||||
if constexpr (is_lua_reference_v<T>) {
|
||||
// actually check if it's none here, otherwise
|
||||
// we'll have a none object inside an optional!
|
||||
bool success = lua_isnoneornil(L, index) == 0 && stack::check<T>(L, index, no_panic);
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
tracking.use(static_cast<int>(success));
|
||||
handler(L, index, type::poly, type_of(L, index), "");
|
||||
return detail::associated_nullopt_v<Optional>;
|
||||
}
|
||||
return stack_detail::unchecked_get<T>(L, index, tracking);
|
||||
}
|
||||
else if constexpr ((std::is_integral_v<T> || std::is_same_v<T, lua_Integer>)&&!std::is_same_v<T, bool>) {
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
if (lua_isinteger(L, index) != 0) {
|
||||
tracking.use(1);
|
||||
return static_cast<T>(lua_tointeger(L, index));
|
||||
}
|
||||
#endif
|
||||
int isnum = 0;
|
||||
const lua_Number value = lua_tonumberx(L, index, &isnum);
|
||||
if (isnum != 0) {
|
||||
#if (defined(SOL_SAFE_NUMERICS) && SOL_SAFE_NUMERICS) && !(defined(SOL_NO_CHECK_NUMBER_PRECISION) && SOL_NO_CHECK_NUMBER_PRECISION)
|
||||
const auto integer_value = llround(value);
|
||||
if (static_cast<lua_Number>(integer_value) == value) {
|
||||
tracking.use(1);
|
||||
return static_cast<T>(integer_value);
|
||||
}
|
||||
#else
|
||||
tracking.use(1);
|
||||
return static_cast<T>(value);
|
||||
#endif
|
||||
}
|
||||
const type t = type_of(L, index);
|
||||
tracking.use(static_cast<int>(t != type::none));
|
||||
handler(L, index, type::number, t, "not an integer");
|
||||
return detail::associated_nullopt_v<Optional>;
|
||||
}
|
||||
else if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, lua_Number>) {
|
||||
int isnum = 0;
|
||||
lua_Number value = lua_tonumberx(L, index, &isnum);
|
||||
if (isnum == 0) {
|
||||
type t = type_of(L, index);
|
||||
tracking.use(static_cast<int>(t != type::none));
|
||||
handler(L, index, type::number, t, "not a valid floating point number");
|
||||
return detail::associated_nullopt_v<Optional>;
|
||||
}
|
||||
tracking.use(1);
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
else if constexpr (std::is_enum_v<T> && !meta::any_same_v<T, meta_function, type>) {
|
||||
int isnum = 0;
|
||||
lua_Integer value = lua_tointegerx(L, index, &isnum);
|
||||
if (isnum == 0) {
|
||||
type t = type_of(L, index);
|
||||
tracking.use(static_cast<int>(t != type::none));
|
||||
handler(L, index, type::number, t, "not a valid enumeration value");
|
||||
return detail::associated_nullopt_v<Optional>;
|
||||
}
|
||||
tracking.use(1);
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
else {
|
||||
if (!unqualified_check<T>(L, index, std::forward<Handler>(handler))) {
|
||||
tracking.use(static_cast<int>(!lua_isnone(L, index)));
|
||||
return detail::associated_nullopt_v<Optional>;
|
||||
}
|
||||
return stack_detail::unchecked_unqualified_get<T>(L, index, tracking);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!unqualified_check<T>(L, index, std::forward<Handler>(handler))) {
|
||||
tracking.use(static_cast<int>(!lua_isnone(L, index)));
|
||||
return detail::associated_nullopt_v<Optional>;
|
||||
}
|
||||
return stack_detail::unchecked_unqualified_get<T>(L, index, tracking);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
static optional<R> get(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
return get_using<optional<R>>(L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
};
|
||||
|
||||
#if SOL_ON(SOL_STD_VARIANT_)
|
||||
template <typename... Tn, typename C>
|
||||
struct unqualified_check_getter<std::variant<Tn...>, C> {
|
||||
typedef std::variant<Tn...> V;
|
||||
typedef std::variant_size<V> V_size;
|
||||
typedef std::integral_constant<bool, V_size::value == 0> V_is_empty;
|
||||
|
||||
template <typename Handler>
|
||||
static optional<V> get_empty(std::true_type, lua_State*, int, Handler&&, record&) {
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
static optional<V> get_empty(std::false_type, lua_State* L, int index, Handler&& handler, record&) {
|
||||
// This should never be reached...
|
||||
// please check your code and understand what you did to bring yourself here
|
||||
// maybe file a bug report, or 5
|
||||
handler(
|
||||
L, index, type::poly, type_of(L, index), "this variant code should never be reached: if it has, you have done something so terribly wrong");
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
static optional<V> get_one(std::integral_constant<std::size_t, 0>, lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
return get_empty(V_is_empty(), L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
|
||||
template <std::size_t I, typename Handler>
|
||||
static optional<V> get_one(std::integral_constant<std::size_t, I>, lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
typedef std::variant_alternative_t<I - 1, V> T;
|
||||
if (stack::check<T>(L, index, no_panic, tracking)) {
|
||||
return V(std::in_place_index<I - 1>, stack::get<T>(L, index));
|
||||
}
|
||||
return get_one(std::integral_constant<std::size_t, I - 1>(), L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
static optional<V> get(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
return get_one(std::integral_constant<std::size_t, V_size::value>(), L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
};
|
||||
#endif // standard variant
|
||||
}} // namespace sol::stack
|
||||
|
||||
#endif // SOL_STACK_CHECK_UNQUALIFIED_GET_HPP
|
|
@ -1,91 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_STACK_CHECK_QUALIFIED_HPP
|
||||
#define SOL_STACK_CHECK_QUALIFIED_HPP
|
||||
|
||||
#include "stack_check_unqualified.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace stack {
|
||||
|
||||
template <typename X, type expected, typename>
|
||||
struct qualified_checker {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
if constexpr (!std::is_reference_v<X> && is_unique_usertype_v<X>) {
|
||||
using u_traits = unique_usertype_traits<meta::unqualified_t<X>>;
|
||||
using T = typename u_traits::type;
|
||||
if constexpr (is_base_rebindable_non_void_v<u_traits>) {
|
||||
using rebind_t = typename u_traits::template rebind_base<void>;
|
||||
// we have a unique pointer type that can be
|
||||
// rebound to a base/derived type
|
||||
const type indextype = type_of(L, index);
|
||||
tracking.use(1);
|
||||
if (indextype != type::userdata) {
|
||||
handler(L, index, type::userdata, indextype, "value is not a userdata");
|
||||
return false;
|
||||
}
|
||||
void* memory = lua_touserdata(L, index);
|
||||
memory = detail::align_usertype_unique_destructor(memory);
|
||||
detail::unique_destructor& pdx = *static_cast<detail::unique_destructor*>(memory);
|
||||
if (&detail::usertype_unique_alloc_destroy<T, X> == pdx) {
|
||||
return true;
|
||||
}
|
||||
if constexpr (derive<T>::value) {
|
||||
memory = detail::align_usertype_unique_tag<true, false>(memory);
|
||||
detail::unique_tag& ic = *reinterpret_cast<detail::unique_tag*>(memory);
|
||||
string_view ti = usertype_traits<T>::qualified_name();
|
||||
string_view rebind_ti = usertype_traits<rebind_t>::qualified_name();
|
||||
if (ic(nullptr, nullptr, ti, rebind_ti) != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
handler(L, index, type::userdata, indextype, "value is a userdata but is not the correct unique usertype");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return stack::unqualified_check<X>(L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
}
|
||||
else if constexpr (!std::is_reference_v<X> && is_container_v<X>) {
|
||||
if (type_of(L, index) == type::userdata) {
|
||||
return stack::unqualified_check<X>(L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
else {
|
||||
return stack::unqualified_check<nested<X>>(L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
}
|
||||
else if constexpr (!std::is_reference_v<X> && meta::is_specialization_of_v<X, nested>) {
|
||||
using NestedX = typename meta::unqualified_t<X>::nested_type;
|
||||
return stack::check<NestedX>(L, index, ::std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
else {
|
||||
return stack::unqualified_check<X>(L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace sol::stack
|
||||
|
||||
#endif // SOL_STACK_CHECK_HPP
|
|
@ -1,614 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_STACK_CHECK_UNQUALIFIED_HPP
|
||||
#define SOL_STACK_CHECK_UNQUALIFIED_HPP
|
||||
|
||||
#include "stack_core.hpp"
|
||||
#include "usertype_traits.hpp"
|
||||
#include "inheritance.hpp"
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
#include <cmath>
|
||||
#include <optional>
|
||||
#if SOL_ON(SOL_STD_VARIANT_)
|
||||
#include <variant>
|
||||
#endif // variant shenanigans
|
||||
|
||||
namespace sol { namespace stack {
|
||||
namespace stack_detail {
|
||||
inline bool impl_check_metatable(lua_State* L, int index, const std::string& metakey, bool poptable) {
|
||||
luaL_getmetatable(L, &metakey[0]);
|
||||
const type expectedmetatabletype = static_cast<type>(lua_type(L, -1));
|
||||
if (expectedmetatabletype != type::lua_nil) {
|
||||
if (lua_rawequal(L, -1, index) == 1) {
|
||||
lua_pop(L, 1 + static_cast<int>(poptable));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T, bool poptable = true>
|
||||
inline bool check_metatable(lua_State* L, int index = -2) {
|
||||
return impl_check_metatable(L, index, usertype_traits<T>::metatable(), poptable);
|
||||
}
|
||||
|
||||
template <type expected, int (*check_func)(lua_State*, int)>
|
||||
struct basic_check {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
bool success = check_func(L, index) == 1;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, expected, type_of(L, index), "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
};
|
||||
} // namespace stack_detail
|
||||
|
||||
template <typename T, typename>
|
||||
struct unqualified_interop_checker {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State*, int, type, Handler&&, record&) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename>
|
||||
struct qualified_interop_checker {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, type index_type, Handler&& handler, record& tracking) {
|
||||
return stack_detail::unqualified_interop_check<T>(L, index, index_type, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, type expected, typename>
|
||||
struct unqualified_checker {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
if constexpr (std::is_same_v<T, bool>) {
|
||||
tracking.use(1);
|
||||
bool success = lua_isboolean(L, index) == 1;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, expected, type_of(L, index), "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
else if constexpr (meta::any_same_v<T, char /* , char8_t*/, char16_t, char32_t>) {
|
||||
return stack::check<std::basic_string<T>>(L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
else if constexpr (std::is_integral_v<T> || std::is_same_v<T, lua_Integer>) {
|
||||
tracking.use(1);
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
#if defined(SOL_STRINGS_ARE_NUMBERS) && SOL_STRINGS_ARE_NUMBERS
|
||||
int isnum = 0;
|
||||
lua_tointegerx(L, index, &isnum);
|
||||
const bool success = isnum != 0;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, type_of(L, index), detail::not_a_number_or_number_string_integral);
|
||||
}
|
||||
#elif (defined(SOL_SAFE_NUMERICS) && SOL_SAFE_NUMERICS) && !(defined(SOL_NO_CHECK_NUMBER_PRECISION) && SOL_NO_CHECK_NUMBER_PRECISION)
|
||||
// this check is precise, does not convert
|
||||
if (lua_isinteger(L, index) == 1) {
|
||||
return true;
|
||||
}
|
||||
const bool success = false;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, type_of(L, index), detail::not_a_number_integral);
|
||||
}
|
||||
#else
|
||||
type t = type_of(L, index);
|
||||
const bool success = t == type::number;
|
||||
#endif // If numbers are enabled, use the imprecise check
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, type_of(L, index), detail::not_a_number);
|
||||
}
|
||||
return success;
|
||||
#else
|
||||
#if !defined(SOL_STRINGS_ARE_NUMBERS) || !SOL_STRINGS_ARE_NUMBERS
|
||||
// must pre-check, because it will convert
|
||||
type t = type_of(L, index);
|
||||
if (t != type::number) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, t, detail::not_a_number);
|
||||
return false;
|
||||
}
|
||||
#endif // Do not allow strings to be numbers
|
||||
#if (defined(SOL_SAFE_NUMERICS) && SOL_SAFE_NUMERICS) && !(defined(SOL_NO_CHECK_NUMBER_PRECISION) && SOL_NO_CHECK_NUMBER_PRECISION)
|
||||
int isnum = 0;
|
||||
const lua_Number v = lua_tonumberx(L, index, &isnum);
|
||||
const bool success = isnum != 0 && static_cast<lua_Number>(llround(v)) == v;
|
||||
#else
|
||||
const bool success = true;
|
||||
#endif // Safe numerics and number precision checking
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
#if defined(SOL_STRINGS_ARE_NUMBERS) && SOL_STRINGS_ARE_NUMBERS
|
||||
handler(L, index, type::number, type_of(L, index), detail::not_a_number_or_number_string);
|
||||
#elif (defined(SOL_SAFE_NUMERICS) && SOL_SAFE_NUMERICS)
|
||||
handler(L, index, type::number, t, detail::not_a_number_or_number_string);
|
||||
#else
|
||||
handler(L, index, type::number, t, detail::not_a_number);
|
||||
#endif
|
||||
}
|
||||
return success;
|
||||
#endif // Lua Version 5.3 versus others
|
||||
}
|
||||
else if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, lua_Number>) {
|
||||
tracking.use(1);
|
||||
#if defined(SOL_STRINGS_ARE_NUMBERS) && SOL_STRINGS_ARE_NUMBERS
|
||||
bool success = lua_isnumber(L, index) == 1;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, type_of(L, index), detail::not_a_number_or_number_string);
|
||||
}
|
||||
return success;
|
||||
#else
|
||||
type t = type_of(L, index);
|
||||
bool success = t == type::number;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::number, t, detail::not_a_number);
|
||||
}
|
||||
return success;
|
||||
#endif // Strings are Numbers
|
||||
}
|
||||
else if constexpr (meta::any_same_v<T, type, this_state, this_main_state, this_environment, variadic_args>) {
|
||||
(void)L;
|
||||
(void)index;
|
||||
(void)handler;
|
||||
tracking.use(0);
|
||||
return true;
|
||||
}
|
||||
else if constexpr (is_unique_usertype_v<T>) {
|
||||
using proper_T = typename unique_usertype_traits<T>::type;
|
||||
const type indextype = type_of(L, index);
|
||||
tracking.use(1);
|
||||
if (indextype != type::userdata) {
|
||||
handler(L, index, type::userdata, indextype, "value is not a userdata");
|
||||
return false;
|
||||
}
|
||||
if (lua_getmetatable(L, index) == 0) {
|
||||
return true;
|
||||
}
|
||||
int metatableindex = lua_gettop(L);
|
||||
if (stack_detail::check_metatable<detail::unique_usertype<proper_T>>(L, metatableindex)) {
|
||||
void* memory = lua_touserdata(L, index);
|
||||
memory = detail::align_usertype_unique_destructor(memory);
|
||||
detail::unique_destructor& pdx = *static_cast<detail::unique_destructor*>(memory);
|
||||
bool success = &detail::usertype_unique_alloc_destroy<proper_T, T> == pdx;
|
||||
if (!success) {
|
||||
memory = detail::align_usertype_unique_tag<true>(memory);
|
||||
#if 0
|
||||
// New version
|
||||
#else
|
||||
const char*& name_tag = *static_cast<const char**>(memory);
|
||||
success = usertype_traits<T>::qualified_name() == name_tag;
|
||||
#endif
|
||||
if (!success) {
|
||||
handler(L, index, type::userdata, indextype, "value is a userdata but is not the correct unique usertype");
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, type::userdata, indextype, "unrecognized userdata (not pushed by sol?)");
|
||||
return false;
|
||||
}
|
||||
else if constexpr (meta::any_same_v<T,
|
||||
lua_nil_t,
|
||||
#if defined(SOL_CXX_17_FEATURES) && SOL_CXX_17_FEATURES
|
||||
std::nullopt_t,
|
||||
#endif
|
||||
nullopt_t>) {
|
||||
bool success = lua_isnil(L, index);
|
||||
if (success) {
|
||||
tracking.use(1);
|
||||
return success;
|
||||
}
|
||||
tracking.use(0);
|
||||
success = lua_isnone(L, index);
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, expected, type_of(L, index), "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, env_key_t>) {
|
||||
tracking.use(1);
|
||||
type t = type_of(L, index);
|
||||
if (t == type::table || t == type::none || t == type::lua_nil || t == type::userdata) {
|
||||
return true;
|
||||
}
|
||||
handler(L, index, type::table, t, "value cannot not have a valid environment");
|
||||
return true;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, detail::non_lua_nil_t>) {
|
||||
return !stack::unqualified_check<lua_nil_t>(L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
else if constexpr (meta::is_specialization_of_v<T, basic_lua_table>) {
|
||||
tracking.use(1);
|
||||
type t = type_of(L, index);
|
||||
if (t != type::table) {
|
||||
handler(L, index, type::table, t, "value is not a table");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if constexpr (meta::is_specialization_of_v<T, basic_bytecode>) {
|
||||
tracking.use(1);
|
||||
type t = type_of(L, index);
|
||||
if (t != type::function) {
|
||||
handler(L, index, type::function, t, "value is not a function that can be dumped");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if constexpr (meta::is_specialization_of_v<T, basic_environment>) {
|
||||
tracking.use(1);
|
||||
if (lua_getmetatable(L, index) == 0) {
|
||||
return true;
|
||||
}
|
||||
type t = type_of(L, -1);
|
||||
if (t == type::table || t == type::none || t == type::lua_nil) {
|
||||
lua_pop(L, 1);
|
||||
return true;
|
||||
}
|
||||
if (t != type::userdata) {
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, type::table, t, "value does not have a valid metatable");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, metatable_key_t>) {
|
||||
tracking.use(1);
|
||||
if (lua_getmetatable(L, index) == 0) {
|
||||
return true;
|
||||
}
|
||||
type t = type_of(L, -1);
|
||||
if (t == type::table || t == type::none || t == type::lua_nil) {
|
||||
lua_pop(L, 1);
|
||||
return true;
|
||||
}
|
||||
if (t != type::userdata) {
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, expected, t, "value does not have a valid metatable");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, luaL_Stream*> || std::is_same_v<T, luaL_Stream>) {
|
||||
if (lua_getmetatable(L, index) == 0) {
|
||||
type t = type_of(L, index);
|
||||
handler(L, index, expected, t, "value is not a valid luaL_Stream (has no metatable/is not a valid value)");
|
||||
return false;
|
||||
}
|
||||
luaL_getmetatable(L, LUA_FILEHANDLE);
|
||||
if (type_of(L, index) != type::table) {
|
||||
type t = type_of(L, index);
|
||||
lua_pop(L, 1);
|
||||
handler(L,
|
||||
index,
|
||||
expected,
|
||||
t,
|
||||
"value is not a valid luaL_Stream (there is no metatable for luaL_Stream -- did you forget to "
|
||||
"my_lua_state.open_libraries(sol::lib::state) or equivalent?)");
|
||||
return false;
|
||||
}
|
||||
int is_stream_table = lua_compare(L, -1, -2, LUA_OPEQ);
|
||||
lua_pop(L, 2);
|
||||
if (is_stream_table == 0) {
|
||||
type t = type_of(L, index);
|
||||
handler(L, index, expected, t, "value is not a valid luaL_Stream (incorrect metatable)");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if constexpr (meta::is_optional_v<T>) {
|
||||
using ValueType = typename T::value_type;
|
||||
(void)handler;
|
||||
type t = type_of(L, index);
|
||||
if (t == type::none) {
|
||||
tracking.use(0);
|
||||
return true;
|
||||
}
|
||||
if (t == type::lua_nil) {
|
||||
tracking.use(1);
|
||||
return true;
|
||||
}
|
||||
return stack::unqualified_check<ValueType>(L, index, no_panic, tracking);
|
||||
}
|
||||
else if constexpr (expected == type::userdata) {
|
||||
if constexpr (meta::any_same_v<T, userdata_value> || meta::is_specialization_of_v<T, basic_userdata>) {
|
||||
tracking.use(1);
|
||||
type t = type_of(L, index);
|
||||
bool success = t == type::userdata;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::userdata, t, "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
else if constexpr (meta::is_specialization_of_v<T, user>) {
|
||||
unqualified_checker<lightuserdata_value, type::userdata> c;
|
||||
(void)c;
|
||||
return c.check(L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
else {
|
||||
if constexpr (std::is_pointer_v<T>) {
|
||||
return check_usertype<T>(L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
else if constexpr (meta::is_specialization_of_v<T, std::reference_wrapper>) {
|
||||
using T_internal = typename T::type;
|
||||
return stack::check<T_internal>(L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
else {
|
||||
return check_usertype<T>(L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if constexpr (expected == type::poly) {
|
||||
tracking.use(1);
|
||||
bool success = is_lua_reference_v<T> || !lua_isnone(L, index);
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::poly, type_of(L, index), "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
else if constexpr (expected == type::lightuserdata) {
|
||||
tracking.use(1);
|
||||
type t = type_of(L, index);
|
||||
bool success = t == type::userdata || t == type::lightuserdata;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, type::lightuserdata, t, "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
else if constexpr (expected == type::function) {
|
||||
if constexpr (meta::any_same_v<T, lua_CFunction, std::remove_pointer_t<lua_CFunction>, c_closure>) {
|
||||
tracking.use(1);
|
||||
bool success = lua_iscfunction(L, index) == 1;
|
||||
if (!success) {
|
||||
// expected type, actual type
|
||||
handler(L, index, expected, type_of(L, index), "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
else {
|
||||
tracking.use(1);
|
||||
type t = type_of(L, index);
|
||||
if (t == type::lua_nil || t == type::none || t == type::function) {
|
||||
// allow for lua_nil to be returned
|
||||
return true;
|
||||
}
|
||||
if (t != type::userdata && t != type::table) {
|
||||
handler(L, index, type::function, t, "must be a function or table or a userdata");
|
||||
return false;
|
||||
}
|
||||
// Do advanced check for call-style userdata?
|
||||
static const auto& callkey = to_string(meta_function::call);
|
||||
if (lua_getmetatable(L, index) == 0) {
|
||||
// No metatable, no __call key possible
|
||||
handler(L, index, type::function, t, "value is not a function and does not have overriden metatable");
|
||||
return false;
|
||||
}
|
||||
if (lua_isnoneornil(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
handler(L, index, type::function, t, "value is not a function and does not have valid metatable");
|
||||
return false;
|
||||
}
|
||||
lua_getfield(L, -1, &callkey[0]);
|
||||
if (lua_isnoneornil(L, -1)) {
|
||||
lua_pop(L, 2);
|
||||
handler(L, index, type::function, t, "value's metatable does not have __call overridden in metatable, cannot call this type");
|
||||
return false;
|
||||
}
|
||||
// has call, is definitely a function
|
||||
lua_pop(L, 2);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if constexpr (expected == type::table) {
|
||||
tracking.use(1);
|
||||
type t = type_of(L, index);
|
||||
if (t == type::table) {
|
||||
return true;
|
||||
}
|
||||
if (t != type::userdata) {
|
||||
handler(L, index, type::table, t, "value is not a table or a userdata that can behave like one");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
tracking.use(1);
|
||||
const type indextype = type_of(L, index);
|
||||
bool success = expected == indextype;
|
||||
if (!success) {
|
||||
// expected type, actual type, message
|
||||
handler(L, index, expected, indextype, "");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unqualified_checker<non_null<T>, type::userdata> : unqualified_checker<T, lua_type_of_v<T>> { };
|
||||
|
||||
template <typename T>
|
||||
struct unqualified_checker<detail::as_value_tag<T>, type::userdata> {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
const type indextype = type_of(L, index);
|
||||
return check(types<T>(), L, index, indextype, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
|
||||
template <typename U, typename Handler>
|
||||
static bool check(types<U>, lua_State* L, int index, type indextype, Handler&& handler, record& tracking) {
|
||||
if constexpr (
|
||||
std::is_same_v<T,
|
||||
lightuserdata_value> || std::is_same_v<T, userdata_value> || std::is_same_v<T, userdata> || std::is_same_v<T, lightuserdata>) {
|
||||
tracking.use(1);
|
||||
if (indextype != type::userdata) {
|
||||
handler(L, index, type::userdata, indextype, "value is not a valid userdata");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
#if defined(SOL_ENABLE_INTEROP) && SOL_ENABLE_INTEROP
|
||||
if (stack_detail::interop_check<U>(L, index, indextype, handler, tracking)) {
|
||||
return true;
|
||||
}
|
||||
#endif // interop extensibility
|
||||
tracking.use(1);
|
||||
if (indextype != type::userdata) {
|
||||
handler(L, index, type::userdata, indextype, "value is not a valid userdata");
|
||||
return false;
|
||||
}
|
||||
if (lua_getmetatable(L, index) == 0) {
|
||||
return true;
|
||||
}
|
||||
int metatableindex = lua_gettop(L);
|
||||
if (stack_detail::check_metatable<U>(L, metatableindex))
|
||||
return true;
|
||||
if (stack_detail::check_metatable<U*>(L, metatableindex))
|
||||
return true;
|
||||
if (stack_detail::check_metatable<detail::unique_usertype<U>>(L, metatableindex))
|
||||
return true;
|
||||
if (stack_detail::check_metatable<as_container_t<U>>(L, metatableindex))
|
||||
return true;
|
||||
bool success = false;
|
||||
bool has_derived = derive<T>::value || weak_derive<T>::value;
|
||||
if (has_derived) {
|
||||
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
||||
luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
|
||||
#endif // make sure stack doesn't overflow
|
||||
auto pn = stack::pop_n(L, 1);
|
||||
lua_pushstring(L, &detail::base_class_check_key()[0]);
|
||||
lua_rawget(L, metatableindex);
|
||||
if (type_of(L, -1) != type::lua_nil) {
|
||||
void* basecastdata = lua_touserdata(L, -1);
|
||||
detail::inheritance_check_function ic = reinterpret_cast<detail::inheritance_check_function>(basecastdata);
|
||||
success = ic(usertype_traits<T>::qualified_name());
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
if (!success) {
|
||||
handler(L, index, type::userdata, indextype, "value at this index does not properly reflect the desired type");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unqualified_checker<detail::as_pointer_tag<T>, type::userdata> {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, type indextype, Handler&& handler, record& tracking) {
|
||||
if (indextype == type::lua_nil) {
|
||||
tracking.use(1);
|
||||
return true;
|
||||
}
|
||||
return check_usertype<std::remove_pointer_t<T>>(L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
const type indextype = type_of(L, index);
|
||||
return check(L, index, indextype, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
struct unqualified_checker<std::tuple<Args...>, type::poly> {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
return stack::multi_check<Args...>(L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
struct unqualified_checker<std::pair<A, B>, type::poly> {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
return stack::multi_check<A, B>(L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
};
|
||||
|
||||
#if SOL_ON(SOL_STD_VARIANT_)
|
||||
|
||||
template <typename... Tn>
|
||||
struct unqualified_checker<std::variant<Tn...>, type::poly> {
|
||||
typedef std::variant<Tn...> V;
|
||||
typedef std::variant_size<V> V_size;
|
||||
typedef std::integral_constant<bool, V_size::value == 0> V_is_empty;
|
||||
|
||||
template <typename Handler>
|
||||
static bool is_one(std::integral_constant<std::size_t, 0>, lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
if constexpr (V_is_empty::value) {
|
||||
if (lua_isnone(L, index)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
tracking.use(1);
|
||||
handler(L, index, type::poly, type_of(L, index), "value does not fit any type present in the variant");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <std::size_t I, typename Handler>
|
||||
static bool is_one(std::integral_constant<std::size_t, I>, lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
typedef std::variant_alternative_t<I - 1, V> T;
|
||||
record temp_tracking = tracking;
|
||||
if (stack::check<T>(L, index, no_panic, temp_tracking)) {
|
||||
tracking = temp_tracking;
|
||||
return true;
|
||||
}
|
||||
return is_one(std::integral_constant<std::size_t, I - 1>(), L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
return is_one(std::integral_constant<std::size_t, V_size::value>(), L, index, std::forward<Handler>(handler), tracking);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // variant shenanigans
|
||||
|
||||
}} // namespace sol::stack
|
||||
|
||||
#endif // SOL_STACK_CHECK_UNQUALIFIED_HPP
|
File diff suppressed because it is too large
Load Diff
|
@ -1,248 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_STACK_FIELD_HPP
|
||||
#define SOL_STACK_FIELD_HPP
|
||||
|
||||
#include "stack_core.hpp"
|
||||
#include "stack_push.hpp"
|
||||
#include "stack_get.hpp"
|
||||
#include "stack_check_get.hpp"
|
||||
|
||||
namespace sol { namespace stack {
|
||||
template <typename T, bool global, bool raw, typename>
|
||||
struct field_getter {
|
||||
static constexpr int default_table_index = meta::conditional_t < meta::is_c_str_v<T>
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
|| (std::is_integral_v<T> && !std::is_same_v<T, bool>)
|
||||
#endif // integer global keys 5.3 or better
|
||||
|| (raw && std::is_void_v<std::remove_pointer_t<T>>),
|
||||
std::integral_constant<int, -1>, std::integral_constant<int, -2>> ::value;
|
||||
|
||||
template <typename Key>
|
||||
void get(lua_State* L, Key&& key, int tableindex = default_table_index) {
|
||||
if constexpr (std::is_same_v<T, update_if_empty_t> || std::is_same_v<T, override_value_t> || std::is_same_v<T, create_if_nil_t>) {
|
||||
(void)L;
|
||||
(void)key;
|
||||
(void)tableindex;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, env_key_t>) {
|
||||
(void)key;
|
||||
#if SOL_LUA_VERSION < 502
|
||||
// Use lua_setfenv
|
||||
lua_getfenv(L, tableindex);
|
||||
#else
|
||||
// Use upvalues as explained in Lua 5.2 and beyond's manual
|
||||
if (lua_getupvalue(L, tableindex, 1) == nullptr) {
|
||||
push(L, lua_nil);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, metatable_key_t>) {
|
||||
(void)key;
|
||||
if (lua_getmetatable(L, tableindex) == 0)
|
||||
push(L, lua_nil);
|
||||
}
|
||||
else if constexpr (raw) {
|
||||
if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
|
||||
lua_rawgeti(L, tableindex, static_cast<lua_Integer>(key));
|
||||
}
|
||||
#if SOL_LUA_VERSION >= 502
|
||||
else if constexpr (std::is_void_v<std::remove_pointer_t<T>>) {
|
||||
lua_rawgetp(L, tableindex, key);
|
||||
}
|
||||
#endif // Lua 5.2.x+
|
||||
else {
|
||||
push(L, std::forward<Key>(key));
|
||||
lua_rawget(L, tableindex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if constexpr (meta::is_c_str_v<T>) {
|
||||
if constexpr (global) {
|
||||
(void)tableindex;
|
||||
lua_getglobal(L, &key[0]);
|
||||
}
|
||||
else {
|
||||
lua_getfield(L, tableindex, &key[0]);
|
||||
}
|
||||
}
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
else if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
|
||||
lua_geti(L, tableindex, static_cast<lua_Integer>(key));
|
||||
}
|
||||
#endif // Lua 5.3.x+
|
||||
else {
|
||||
push(L, std::forward<Key>(key));
|
||||
lua_gettable(L, tableindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args, bool b, bool raw, typename C>
|
||||
struct field_getter<std::tuple<Args...>, b, raw, C> {
|
||||
template <std::size_t... I, typename Keys>
|
||||
void apply(std::index_sequence<0, I...>, lua_State* L, Keys&& keys, int tableindex) {
|
||||
get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)), tableindex);
|
||||
void(detail::swallow{ (get_field<false, raw>(L, std::get<I>(std::forward<Keys>(keys))), 0)... });
|
||||
reference saved(L, -1);
|
||||
lua_pop(L, static_cast<int>(sizeof...(I)));
|
||||
saved.push();
|
||||
}
|
||||
|
||||
template <typename Keys>
|
||||
void get(lua_State* L, Keys&& keys) {
|
||||
apply(std::make_index_sequence<sizeof...(Args)>(), L, std::forward<Keys>(keys), lua_absindex(L, -1));
|
||||
}
|
||||
|
||||
template <typename Keys>
|
||||
void get(lua_State* L, Keys&& keys, int tableindex) {
|
||||
apply(std::make_index_sequence<sizeof...(Args)>(), L, std::forward<Keys>(keys), tableindex);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename A, typename B, bool b, bool raw, typename C>
|
||||
struct field_getter<std::pair<A, B>, b, raw, C> {
|
||||
template <typename Keys>
|
||||
void get(lua_State* L, Keys&& keys, int tableindex) {
|
||||
get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)), tableindex);
|
||||
get_field<false, raw>(L, std::get<1>(std::forward<Keys>(keys)));
|
||||
reference saved(L, -1);
|
||||
lua_pop(L, static_cast<int>(2));
|
||||
saved.push();
|
||||
}
|
||||
|
||||
template <typename Keys>
|
||||
void get(lua_State* L, Keys&& keys) {
|
||||
get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)));
|
||||
get_field<false, raw>(L, std::get<1>(std::forward<Keys>(keys)));
|
||||
reference saved(L, -1);
|
||||
lua_pop(L, static_cast<int>(2));
|
||||
saved.push();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool global, bool raw, typename>
|
||||
struct field_setter {
|
||||
static constexpr int default_table_index
|
||||
= meta::conditional_t < (meta::is_c_str_v<T> || meta::is_string_of_v<T, char>) || (std::is_integral_v<T> && !std::is_same_v<T, bool>)
|
||||
|| (std::is_integral_v<T> && !std::is_same_v<T, bool>) || (raw && std::is_void_v<std::remove_pointer_t<T>>),
|
||||
std::integral_constant<int, -2>, std::integral_constant<int, -3>> ::value;
|
||||
|
||||
template <typename Key, typename Value>
|
||||
void set(lua_State* L, Key&& key, Value&& value, int tableindex = default_table_index) {
|
||||
if constexpr (std::is_same_v<T, update_if_empty_t> || std::is_same_v<T, override_value_t>) {
|
||||
(void)L;
|
||||
(void)key;
|
||||
(void)value;
|
||||
(void)tableindex;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, metatable_key_t>) {
|
||||
(void)key;
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_setmetatable(L, tableindex);
|
||||
}
|
||||
else if constexpr (raw) {
|
||||
if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_rawseti(L, tableindex, static_cast<lua_Integer>(key));
|
||||
}
|
||||
#if SOL_LUA_VERSION >= 502
|
||||
else if constexpr (std::is_void_v<std::remove_pointer_t<T>>) {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_rawsetp(L, tableindex, std::forward<Key>(key));
|
||||
}
|
||||
#endif // Lua 5.2.x
|
||||
else {
|
||||
push(L, std::forward<Key>(key));
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_rawset(L, tableindex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if constexpr (meta::is_c_str_v<T> || meta::is_string_of_v<T, char>) {
|
||||
if constexpr (global) {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_setglobal(L, &key[0]);
|
||||
(void)tableindex;
|
||||
}
|
||||
else {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_setfield(L, tableindex, &key[0]);
|
||||
}
|
||||
}
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
else if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_seti(L, tableindex, static_cast<lua_Integer>(key));
|
||||
}
|
||||
#endif // Lua 5.3.x
|
||||
else {
|
||||
push(L, std::forward<Key>(key));
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_settable(L, tableindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args, bool b, bool raw, typename C>
|
||||
struct field_setter<std::tuple<Args...>, b, raw, C> {
|
||||
template <bool g, std::size_t I, typename Keys, typename Value>
|
||||
void apply(std::index_sequence<I>, lua_State* L, Keys&& keys, Value&& value, int tableindex) {
|
||||
I < 1 ? set_field<g, raw>(L, std::get<I>(std::forward<Keys>(keys)), std::forward<Value>(value), tableindex)
|
||||
: set_field<g, raw>(L, std::get<I>(std::forward<Keys>(keys)), std::forward<Value>(value));
|
||||
}
|
||||
|
||||
template <bool g, std::size_t I0, std::size_t I1, std::size_t... I, typename Keys, typename Value>
|
||||
void apply(std::index_sequence<I0, I1, I...>, lua_State* L, Keys&& keys, Value&& value, int tableindex) {
|
||||
I0 < 1 ? get_field<g, raw>(L, std::get<I0>(std::forward<Keys>(keys)), tableindex)
|
||||
: get_field<g, raw>(L, std::get<I0>(std::forward<Keys>(keys)), -1);
|
||||
apply<false>(std::index_sequence<I1, I...>(), L, std::forward<Keys>(keys), std::forward<Value>(value), -1);
|
||||
}
|
||||
|
||||
template <bool g, std::size_t I0, std::size_t... I, typename Keys, typename Value>
|
||||
void top_apply(std::index_sequence<I0, I...>, lua_State* L, Keys&& keys, Value&& value, int tableindex) {
|
||||
apply<g>(std::index_sequence<I0, I...>(), L, std::forward<Keys>(keys), std::forward<Value>(value), tableindex);
|
||||
lua_pop(L, static_cast<int>(sizeof...(I)));
|
||||
}
|
||||
|
||||
template <typename Keys, typename Value>
|
||||
void set(lua_State* L, Keys&& keys, Value&& value, int tableindex = -3) {
|
||||
top_apply<b>(std::make_index_sequence<sizeof...(Args)>(), L, std::forward<Keys>(keys), std::forward<Value>(value), tableindex);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename A, typename B, bool b, bool raw, typename C>
|
||||
struct field_setter<std::pair<A, B>, b, raw, C> {
|
||||
template <typename Keys, typename Value>
|
||||
void set(lua_State* L, Keys&& keys, Value&& value, int tableindex = -1) {
|
||||
get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)), tableindex);
|
||||
set_field<false, raw>(L, std::get<1>(std::forward<Keys>(keys)), std::forward<Value>(value), lua_gettop(L));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
};
|
||||
}} // namespace sol::stack
|
||||
|
||||
#endif // SOL_STACK_FIELD_HPP
|
|
@ -1,30 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2019 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_STACK_GET_HPP
|
||||
#define SOL_STACK_GET_HPP
|
||||
|
||||
#include "stack_get_unqualified.hpp"
|
||||
#include "stack_get_qualified.hpp"
|
||||
|
||||
#endif // SOL_STACK_GET_HPP
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue