Merge pull request #917 from EQEmu/revert-916-build

Revert "Build System Updated"
This commit is contained in:
Alex 2019-10-12 21:08:09 -07:00 committed by GitHub
commit 7edfdbd9db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
193 changed files with 14124 additions and 10507 deletions

1
.gitignore vendored
View File

@ -27,7 +27,6 @@ install_manifest.txt
log/ log/
logs/ logs/
vcpkg/ vcpkg/
perl/
.idea/* .idea/*
*cbp *cbp

View File

@ -1,64 +0,0 @@
# Guide To Building From Source Without Installer
This guide is far from exhaustive, you should expect to have some experience with building C++ code before considering compiling the code from scratch. You should instead consider using the installer scripts if you don't want to hack on the code directly.
### CMake
EQEmu uses CMake as the build system on all platforms. You will need CMake 3.2 or higher to build from source.
### Dependencies
The following libraries are required to build from source:
- [boost](https://www.boost.org/ "boost")
- [zlib](https://www.zlib.net/ "zlib") (If not included the source will build [zlib-ng](https://github.com/zlib-ng/zlib-ng "zlib-ng") instead)
- [libmysql](https://dev.mysql.com/downloads/connector/c/ "libmysql") or [libmariadb](https://github.com/MariaDB/mariadb-connector-c "libmariadb")
The following libraries are not strictly required but in many cased recommended.
- [OpenSSL](https://www.openssl.org/ "OpenSSL") or [mbedTLS](https://tls.mbed.org/ "mbedTLS") (Required for the loginserver and headless client)
- [libsodium](https://github.com/jedisct1/libsodium "libsodium") (Required for strong password hashing on the loginserver)
- [Lua 5.1](https://www.lua.org/ "Lua 5.1") or [LuaJit](http://luajit.org/ "LuaJit") (Required for Lua Quest Scripting)
- [Perl](https://www.perl.org/ "Perl") (Required for Perl Quest Scripting)
##### Windows
For windows it is suggested you make use of [vcpkg](https://github.com/microsoft/vcpkg "vcpkg") if you wish to build your own dependencies.
If you wish to use Perl then you should use whichever version of Perl you have installed on the target system.
You can also download a vcpkg export from our releases section for Visual Studio [x86](https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x86.zip "x86") or [x64](https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x64.zip "x64") that includes a toolchain file you can pass to CMake.
##### Linux
For Linux you simply can install the dependencies from your package manager, below is an example of doing it on Ubuntu using apt-get.
sudo apt-get install libmysqlclient-dev libperl-dev libboost-dev liblua5.1-0-dev zlib1g-dev uuid-dev libssl-dev
### Running CMake
##### Windows
The following is a modified command our automated build server uses to run CMake via the release vcpkg export and its toolchain file.
Assuming it is starting in c:/projects/eqemu and the x64 dependencies were extracted to c:/projects/eqemu/vcpkg.
mkdir build
cd build
cmake -G "Visual Studio 15 2017 Win64" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_ZLIB=ON -DEQEMU_ENABLE_BOTS=ON -DCMAKE_TOOLCHAIN_FILE="c:/projects/eqemu/vcpkg/vcpkg-export-20180828-145455/scripts/buildsystems/vcpkg.cmake" ..
##### Linux
Similarly to Windows running CMake on Linux is simple it just omits the toolchain file and uses a different generator.
mkdir build
cd build
cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON ..
### Building
##### Windows
Inside the build directory a file EQEmu.sln should be produced by a successful run of the CMake command. You can either open this with Visual Studio or build it directly with MSBuild via the command line.
msbuild EQEmu.sln /p:Configuration=Release
##### Linux
From the build directory you can simply call make to build.
For example.
make -j4

View File

@ -1,28 +1,120 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2) #EQEmu CMake
#Variables used:
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH}) #EQEMU_DISABLE_CRT_SECURE_WARNINGS
#EQEMU_FAST_FLOATINGPOINT
#EQEMU_ENABLE_CRASH_LOGGING
#EQEMU_DISABLE_SAFESEH
#EQEMU_BUILD_MSVC_MP
#EQEMU_DEBUG_LEVEL
#EQEMU_LOG_LEVEL_DEBUG
#EQEMU_ENABLE_BOTS
#EQEMU_COMMANDS_LOGGING
#EQEMU_BUILD_SERVER
#EQEMU_BUILD_LOGIN
#EQEMU_BUILD_TESTS
#EQEMU_BUILD_PERL
#EQEMU_BUILD_LUA
#EQEMU_SANITIZE_LUA_LIBS
#EQEMU_BUILD_CLIENT_FILES
#EQEMU_USE_MAP_MMFS
#EQEMU_MAP_DIR
#EQEMU_ARCH
#EQEMU_ARCH_ALT
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
IF(POLICY CMP0074) IF(POLICY CMP0074)
CMAKE_POLICY(SET CMP0074 NEW) cmake_policy(SET CMP0074 NEW)
ENDIF() ENDIF()
#FindMySQL is located here so lets make it so CMake can find it
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
#Our project name is EQEmu
PROJECT(EQEmu) PROJECT(EQEmu)
#Default build type is set to RelWithDebInfo for generators that honor that like makefiles
IF(NOT CMAKE_BUILD_TYPE) IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE) SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE) ENDIF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/dependencies" "${CMAKE_PREFIX_PATH}")
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_CXX_EXTENSIONS OFF) #Add our various windows definitions
IF(MSVC OR MINGW)
ADD_DEFINITIONS(-D_WINDOWS)
IF(CMAKE_CL_64)
ADD_DEFINITIONS(-DWIN64)
ELSE(CMAKE_CL_64)
ADD_DEFINITIONS(-DWIN32)
ENDIF(CMAKE_CL_64)
ENDIF(MSVC OR MINGW)
IF(MSVC) IF(MSVC)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) IF(CMAKE_CL_64)
ADD_DEFINITIONS(-DNOMINMAX) SET(EQEMU_ARCH "x64")
ADD_DEFINITIONS(-DCRASH_LOGGING) SET(EQEMU_ARCH_ALT "x64")
ELSE(CMAKE_CL_64)
SET(EQEMU_ARCH "x86")
SET(EQEMU_ARCH_ALT "Win32")
ENDIF(CMAKE_CL_64)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") SET(MYSQL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/mysql_${EQEMU_ARCH}")
IF(VCPKG_TOOLCHAIN)
IF(NOT MSVC_VERSION GREATER 1800)
SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include")
ENDIF()
ELSE(VCPKG_TOOLCHAIN)
SET(ZLIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zlib_${EQEMU_ARCH}")
SET(LUA_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/luaj_${EQEMU_ARCH}")
SET(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/openssl_${EQEMU_ARCH}")
SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include")
ENDIF(VCPKG_TOOLCHAIN)
IF(SODIUM_INCLUDE_HINTS)
IF(MSVC_VERSION GREATER 1800)
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/${EQEMU_ARCH_ALT}/Release/v140/dynamic")
ELSEIF(MSVC_VERSION EQUAL 1800)
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/${EQEMU_ARCH_ALT}/Release/v120/dynamic")
ELSE()
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/${EQEMU_ARCH_ALT}/Release/v110/dynamic")
ENDIF()
ENDIF(SODIUM_INCLUDE_HINTS)
#disable CRT warnings on windows cause they're annoying as shit and we use C functions everywhere
OPTION(EQEMU_DISABLE_CRT_SECURE_WARNINGS "Disable Secure CRT Warnings" ON)
IF(EQEMU_DISABLE_CRT_SECURE_WARNINGS)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
ENDIF(EQEMU_DISABLE_CRT_SECURE_WARNINGS)
#fast FP if you'd like it
OPTION(EQEMU_FAST_FLOATINGPOINT "Use MSVC /fp:fast option" ON)
IF(EQEMU_FAST_FLOATINGPOINT)
ADD_DEFINITIONS(/fp:fast)
ENDIF(EQEMU_FAST_FLOATINGPOINT)
#crash logging currently only works on windows x86/x64
OPTION(EQEMU_ENABLE_CRASH_LOGGING "Enable crash logging" ON)
IF(EQEMU_ENABLE_CRASH_LOGGING)
ADD_DEFINITIONS(-DCRASH_LOGGING)
ENDIF(EQEMU_ENABLE_CRASH_LOGGING)
OPTION(EQEMU_BUILD_MSVC_MP "Enable build with multiple processes." ON)
IF(EQEMU_BUILD_MSVC_MP)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
ENDIF(EQEMU_BUILD_MSVC_MP)
#We want to compile /MT not /MD so we change that
FOREACH(flag_var CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO)
IF(${flag_var} MATCHES "/MD")
STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
ENDIF(${flag_var} MATCHES "/MD")
ENDFOREACH(flag_var)
ADD_DEFINITIONS(-DNOMINMAX)
ELSE(MSVC) ELSE(MSVC)
#Normally set by perl but we don't use the perl flags anymore so we set it.
ADD_DEFINITIONS(-DHAS_UNION_SEMUN) ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
ENDIF(MSVC) ENDIF(MSVC)
@ -39,277 +131,128 @@ IF(UNIX)
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Darwin") ENDIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
ENDIF(UNIX) ENDIF(UNIX)
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS) #debug level, 5 is default. Most people wont ever change this but it's there if you want to
ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT) SET(EQEMU_DEBUG_LEVEL 5 CACHE STRING "EQEmu debug level:
ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL) 0 - Quiet mode Errors to file Status and Normal ignored
1 - Status and Normal to console, Errors to logfile
2 - Status, Normal, and Error to console and logfile
3 - Light debug release errors and status
4 - Moderate debug release errors and status
5 - Maximum debug release errors and status
10 - More errors than you ever wanted to see"
)
#MSVC can fetch dependencies automatically. SET(EQEMU_LOG_LEVEL_DEBUG 3 CACHE STRING "EQEmu logging level for [Debug]:
IF(MSVC) 0 - Disabled
INCLUDE("${CMAKE_SOURCE_DIR}/cmake/DependencyHelperMSVC.cmake") 1 - Ouput to File Enabled
ENDIF() 2 - Output to stdout Enabled
3 - Output to File and stdout Enabled
8 - Output to stderr Enabled
9 - Output to File and stderr Enabled
11 - Output to File, stdout and stderr Enabled"
)
#Find everything we need OPTION(EQEMU_LSPX "" OFF)
FIND_PACKAGE(MySQL) MARK_AS_ADVANCED(EQEMU_LSPX)
FIND_PACKAGE(MariaDB)
FIND_PACKAGE(ZLIB)
FIND_PACKAGE(OpenSSL)
FIND_PACKAGE(Lua51)
FIND_PACKAGE(PerlLibs)
FIND_PACKAGE(Sodium)
FIND_PACKAGE(mbedTLS)
MESSAGE(STATUS "**************************************************") MARK_AS_ADVANCED(EQEMU_LOG_LEVEL_DEBUG)
MESSAGE(STATUS "* Library Detection *")
MESSAGE(STATUS "**************************************************")
IF(MYSQL_FOUND) #Bots are a compile time option so on/off
MESSAGE(STATUS "* MySQL: FOUND *")
ELSE()
MESSAGE(STATUS "* MySQL: MISSING *")
ENDIF()
IF(MARIADB_FOUND)
MESSAGE(STATUS "* MariaDB: FOUND *")
ELSE()
MESSAGE(STATUS "* MariaDB: MISSING *")
ENDIF()
IF(ZLIB_FOUND)
MESSAGE(STATUS "* ZLIB: FOUND *")
ELSE()
MESSAGE(STATUS "* ZLIB: MISSING *")
ENDIF()
IF(Lua51_FOUND)
MESSAGE(STATUS "* Lua: FOUND *")
ELSE()
MESSAGE(STATUS "* Lua: MISSING *")
ENDIF()
IF(PerlLibs_FOUND)
MESSAGE(STATUS "* Perl: FOUND *")
ELSE()
MESSAGE(STATUS "* Perl: MISSING *")
ENDIF()
IF(SODIUM_FOUND)
MESSAGE(STATUS "* libsodium: FOUND *")
ELSE()
MESSAGE(STATUS "* libsodium: MISSING *")
ENDIF()
IF(OpenSSL_FOUND)
MESSAGE(STATUS "* OpenSSL: FOUND *")
ELSE()
MESSAGE(STATUS "* OpenSSL: MISSING *")
ENDIF()
IF(MBEDTLS_FOUND)
MESSAGE(STATUS "* mbedTLS: FOUND *")
ELSE()
MESSAGE(STATUS "* mbedTLS: MISSING *")
ENDIF()
MESSAGE(STATUS "**************************************************")
#options
OPTION(EQEMU_DEPOP_INVALIDATES_CACHE "#repop invalidates the npc_types cache (will cause a larger database hit on #repop but is more convienent)." ON)
OPTION(EQEMU_ENABLE_BOTS "Enable Bots" OFF) OPTION(EQEMU_ENABLE_BOTS "Enable Bots" OFF)
#Enable GM Command log system
OPTION(EQEMU_COMMANDS_LOGGING "Enable GM Command logs" ON) OPTION(EQEMU_COMMANDS_LOGGING "Enable GM Command logs" ON)
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
OPTION(EQEMU_BUILD_LOGIN "Build the login server." ON)
OPTION(EQEMU_BUILD_HC "Build the headless client." OFF)
OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
IF(EQEMU_COMMANDS_LOGGING) IF(EQEMU_COMMANDS_LOGGING)
ADD_DEFINITIONS(-DCOMMANDS_LOGGING) ADD_DEFINITIONS(-DCOMMANDS_LOGGING)
ENDIF(EQEMU_COMMANDS_LOGGING) ENDIF(EQEMU_COMMANDS_LOGGING)
IF(EQEMU_LSPX)
ADD_DEFINITIONS(-DLSPX=ON)
ENDIF(EQEMU_LSPX)
IF(EQEMU_ENABLE_BOTS) IF(EQEMU_ENABLE_BOTS)
ADD_DEFINITIONS(-DBOTS) ADD_DEFINITIONS(-DBOTS)
ENDIF(EQEMU_ENABLE_BOTS) ENDIF(EQEMU_ENABLE_BOTS)
#database #What to build
IF(MySQL_FOUND AND MariaDB_FOUND) OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
SET(DATABASE_LIBRARY_SELECTION MySQL CACHE STRING "Database library to use: OPTION(EQEMU_BUILD_LOGIN "Build the login server." OFF)
MySQL OPTION(EQEMU_BUILD_HC "Build the headless client." OFF)
MariaDB" OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
) OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
IF(DATABASE_LIBRARY_SELECTION STREQUAL "MySQL") OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
SET(DATABASE_LIBRARY_TYPE " MySQL")
SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES})
SET(DATABASE_LIBRARY_INCLUDE ${MySQL_INCLUDE_DIR})
ELSEIF(DATABASE_LIBRARY_SELECTION STREQUAL "MariaDB")
SET(DATABASE_LIBRARY_TYPE "MariaDB")
SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES})
SET(DATABASE_LIBRARY_INCLUDE ${MariaDB_INCLUDE_DIR})
ELSE()
MESSAGE(FATAL_ERROR "Unknown database library set, should be one of: MySQL, MariaDB")
ENDIF()
ELSEIF(MariaDB_FOUND)
SET(DATABASE_LIBRARY_TYPE "MariaDB")
SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES})
SET(DATABASE_LIBRARY_INCLUDE ${MariaDB_INCLUDE_DIR})
ELSEIF(MySQL_FOUND)
SET(DATABASE_LIBRARY_TYPE " MySQL")
SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES})
SET(DATABASE_LIBRARY_INCLUDE ${MySQL_INCLUDE_DIR})
ELSE()
MESSAGE(FATAL_ERROR "One of MySQL or MariaDB is a required dependency.")
ENDIF()
#security #C++11 stuff
#prefer openssl to mbedtls (arbitrary) IF(NOT MSVC)
IF(OpenSSL_FOUND AND MBEDTLS_FOUND) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
SET(TLS_LIBRARY_SELECTION OpenSSL CACHE STRING "TLS library to use: IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
OpenSSL SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reserved-user-defined-literal")
mbedTLS"
)
IF(TLS_LIBRARY_SELECTION STREQUAL "OpenSSL")
SET(TLS_LIBRARY_TYPE " OpenSSL")
SET(TLS_LIBRARY_ENABLED ON)
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
ELSEIF(TLS_LIBRARY_SELECTION STREQUAL "mbedTLS")
SET(TLS_LIBRARY_TYPE " mbedTLS")
SET(TLS_LIBRARY_ENABLED ON)
SET(TLS_LIBRARY_LIBS ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
SET(TLS_LIBRARY_INCLUDE ${MBEDTLS_INCLUDE_DIR})
ADD_DEFINITIONS(-DEQEMU_USE_MBEDTLS)
ELSE()
MESSAGE(FATAL_ERROR "Unknown TLS library set, should be one of: OpenSSL, mbedTLS")
ENDIF() ENDIF()
ELSEIF(OpenSSL_FOUND) ENDIF(NOT MSVC)
SET(TLS_LIBRARY_TYPE " OpenSSL")
SET(TLS_LIBRARY_ENABLED ON)
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
ELSEIF(MBEDTLS_FOUND)
SET(TLS_LIBRARY_TYPE " mbedTLS")
SET(TLS_LIBRARY_ENABLED ON)
SET(TLS_LIBRARY_LIBS ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
SET(TLS_LIBRARY_INCLUDE ${MBEDTLS_INCLUDE_DIR})
ADD_DEFINITIONS(-DEQEMU_USE_MBEDTLS)
ELSE()
SET(TLS_LIBRARY_TYPE "Disabled")
SET(TLS_LIBRARY_ENABLED OFF)
ENDIF()
#Various definitions
IF(EQEMU_BUILD_PERL)
ADD_DEFINITIONS(-DEMBPERL)
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
ENDIF(EQEMU_BUILD_PERL)
IF(EQEMU_BUILD_LUA)
ADD_DEFINITIONS(-DLUA_EQEMU)
ENDIF(EQEMU_BUILD_LUA)
#Disabled until reevaluation performed
#OPTION(EQEMU_USE_MAP_MMFS "Create and use Zone Map MMF files." OFF)
#IF(EQEMU_USE_MAP_MMFS)
# ADD_DEFINITIONS(-DUSE_MAP_MMFS)
#ENDIF(EQEMU_USE_MAP_MMFS)
SET(EQEMU_MAP_DIR "./Maps" CACHE STRING "The dir that maps, water maps, and paths are located in.")
ADD_DEFINITIONS(-DEQDEBUG=${EQEMU_DEBUG_LEVEL})
ADD_DEFINITIONS(-DINVERSEXY)
ADD_DEFINITIONS(-DFIELD_ITEMS)
ADD_DEFINITIONS(-DMAP_DIR="${EQEMU_MAP_DIR}")
ADD_DEFINITIONS(-DLOG_LEVEL_DEBUG=${EQEMU_LOG_LEVEL_DEBUG})
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT)
ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL)
#Find everything we need
FIND_PACKAGE(ZLIB)
FIND_PACKAGE(MySQL REQUIRED)
IF(EQEMU_BUILD_PERL)
FIND_PACKAGE(PerlLibs REQUIRED)
INCLUDE_DIRECTORIES(SYSTEM "${PERL_INCLUDE_PATH}")
ENDIF(EQEMU_BUILD_PERL)
SET(SERVER_LIBS common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} uv_a fmt RecastNavigation::Detour)
FIND_PACKAGE(Sodium REQUIRED)
IF(SODIUM_FOUND) IF(SODIUM_FOUND)
SET(SODIUM_LIBRARY_TYPE "Libsodium") OPTION(EQEMU_ENABLE_SECURITY "Use Encryption For TCP Connections" ON)
SET(SODIUM_LIBRARY_ENABLED ON) IF(EQEMU_ENABLE_SECURITY)
SET(SODIUM_LIBRARY_LIBS ${SODIUM_LIBRARIES}) INCLUDE_DIRECTORIES(SYSTEM "${SODIUM_INCLUDE_DIRS}")
SET(SODIUM_LIBRARY_INCLUDE ${SODIUM_INCLUDE_DIRS}) ADD_DEFINITIONS(-DENABLE_SECURITY)
ADD_DEFINITIONS(-DENABLE_SECURITY) SET(SERVER_LIBS ${SERVER_LIBS} ${SODIUM_LIBRARIES})
ELSE() ENDIF()
SET(SODIUM_LIBRARY_TYPE " Disabled")
SET(SODIUM_LIBRARY_ENABLED OFF)
ENDIF() ENDIF()
IF(Lua51_FOUND)
SET(LUA_LIBRARY_TYPE " Lua 5.1")
SET(LUA_LIBRARY_ENABLED ON)
SET(LUA_LIBRARY_LIBS ${LUA_LIBRARY} luabind)
SET(LUA_LIBRARY_INCLUDE ${LUA_INCLUDE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind")
ELSE()
SET(LUA_LIBRARY_TYPE "Disabled")
SET(LUA_LIBRARY_ENABLED OFF)
ENDIF()
IF(PerlLibs_FOUND)
SET(PERL_LIBRARY_TYPE " Perl")
SET(PERL_LIBRARY_ENABLED ON)
SET(PERL_LIBRARY_LIBS ${PERL_LIBRARY})
SET(PERL_LIBRARY_INCLUDE ${PERL_INCLUDE_PATH})
ELSE()
SET(PERL_LIBRARY_TYPE "Disabled")
SET(PERL_LIBRARY_ENABLED OFF)
ENDIF()
#use zlib if exists
IF(ZLIB_FOUND) IF(ZLIB_FOUND)
OPTION(EQEMU_BUILD_ZLIB "Build internal version of zlib." ON) OPTION(EQEMU_BUILD_ZLIB "Build internal version of zlib." OFF)
IF(EQEMU_BUILD_ZLIB) IF(EQEMU_BUILD_ZLIB)
SET(ZLIB_LIBRARY_TYPE "zlib-ng") INCLUDE_DIRECTORIES(BEFORE SYSTEM "${CMAKE_CURRENT_BINARY_DIR}/libs/zlibng" "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
SET(ZLIB_LIBRARY_LIBS "zlibstatic") SET(SERVER_LIBS ${SERVER_LIBS} "zlibstatic")
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
ELSE() ELSE()
SET(ZLIB_LIBRARY_TYPE " zlib") INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_INCLUDE_DIRS}")
SET(ZLIB_LIBRARY_LIBS ${ZLIB_LIBRARY}) SET(SERVER_LIBS ${SERVER_LIBS} ${ZLIB_LIBRARY})
SET(ZLIB_LIBRARY_INCLUDE ${ZLIB_INCLUDE_DIRS})
ENDIF() ENDIF()
ELSE() ELSE()
SET(ZLIB_LIBRARY_TYPE "zlib-ng") MESSAGE(STATUS "Could NOT find ZLIB - using ZLIBSTATIC package.")
SET(ZLIB_LIBRARY_LIBS "zlibstatic") SET(EQEMU_BUILD_ZLIB ON)
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng") INCLUDE_DIRECTORIES(BEFORE SYSTEM "${CMAKE_CURRENT_BINARY_DIR}/libs/zlibng" "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
ENDIF() SET(SERVER_LIBS ${SERVER_LIBS} "zlibstatic")
MESSAGE(STATUS "")
MESSAGE(STATUS "**************************************************")
MESSAGE(STATUS "* Library Usage *")
MESSAGE(STATUS "**************************************************")
MESSAGE(STATUS "* Database: ${DATABASE_LIBRARY_TYPE} *")
MESSAGE(STATUS "* TLS: ${TLS_LIBRARY_TYPE} *")
MESSAGE(STATUS "* Sodium: ${SODIUM_LIBRARY_TYPE} *")
MESSAGE(STATUS "* Lua: ${LUA_LIBRARY_TYPE} *")
MESSAGE(STATUS "* Perl: ${PERL_LIBRARY_TYPE} *")
MESSAGE(STATUS "* zlib: ${ZLIB_LIBRARY_TYPE} *")
MESSAGE(STATUS "**************************************************")
#setup server libs and headers
SET(SERVER_LIBS common ${DATABASE_LIBRARY_LIBS} ${ZLIB_LIBRARY_LIBS} uv_a fmt RecastNavigation::Detour)
INCLUDE_DIRECTORIES(SYSTEM "${DATABASE_LIBRARY_INCLUDE}")
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_LIBRARY_INCLUDE}")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/glm")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/cereal/include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/fmt/include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/libuv/include" )
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DebugUtils/Include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Detour/Include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourCrowd/Include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourTileCache/Include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Recast/Include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/websocketpp")
IF(TLS_LIBRARY_ENABLED)
SET(SERVER_LIBS ${SERVER_LIBS} ${TLS_LIBRARY_LIBS})
INCLUDE_DIRECTORIES(SYSTEM "${TLS_LIBRARY_INCLUDE}")
ENDIF()
IF(SODIUM_LIBRARY_ENABLED)
SET(SERVER_LIBS ${SERVER_LIBS} ${SODIUM_LIBRARY_LIBS})
INCLUDE_DIRECTORIES(SYSTEM "${SODIUM_LIBRARY_INCLUDE}")
ENDIF()
IF(LUA_LIBRARY_ENABLED)
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
IF(EQEMU_BUILD_LUA)
ADD_DEFINITIONS(-DLUA_EQEMU)
SET(SERVER_LIBS ${SERVER_LIBS} ${LUA_LIBRARY_LIBS})
INCLUDE_DIRECTORIES(SYSTEM "${LUA_LIBRARY_INCLUDE}")
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON)
IF(EQEMU_SANITIZE_LUA_LIBS)
ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS)
ENDIF()
ENDIF()
ENDIF()
IF(PERL_LIBRARY_ENABLED)
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
IF(EQEMU_BUILD_PERL)
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS})
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
ADD_DEFINITIONS(-DEMBPERL)
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
ENDIF()
ENDIF() ENDIF()
IF(WIN32) IF(WIN32)
@ -324,32 +267,52 @@ IF(UNIX)
SET(SERVER_LIBS ${SERVER_LIBS} "uuid") SET(SERVER_LIBS ${SERVER_LIBS} "uuid")
ENDIF() ENDIF()
IF(EQEMU_BUILD_LOGIN AND NOT TLS_LIBRARY_ENABLED) IF(EQEMU_BUILD_LUA)
MESSAGE(FATAL_ERROR "Login server requires a TLS Library to build.") FIND_PACKAGE(EQLua51 REQUIRED)
ENDIF() SET(Boost_USE_STATIC_LIBS OFF)
SET(Boost_USE_MULTITHREADED ON)
SET(Boost_USE_STATIC_RUNTIME OFF)
SET(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/boost")
IF(EQEMU_BUILD_HC AND NOT TLS_LIBRARY_ENABLED) FIND_PACKAGE(Boost REQUIRED)
MESSAGE(FATAL_ERROR "Headless client requires a TLS Library to build.") INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}" "${Boost_INCLUDE_DIRS}")
ENDIF() INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind")
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON)
IF(EQEMU_SANITIZE_LUA_LIBS)
ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS)
ENDIF(EQEMU_SANITIZE_LUA_LIBS)
ENDIF(EQEMU_BUILD_LUA)
INCLUDE_DIRECTORIES(SYSTEM "${MySQL_INCLUDE_DIR}")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/glm")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/cereal/include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/fmt/include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/libuv/include" )
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DebugUtils/Include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Detour/Include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourCrowd/Include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourTileCache/Include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Recast/Include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/websocketpp")
IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC) IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
ADD_SUBDIRECTORY(common) ADD_SUBDIRECTORY(common)
ADD_SUBDIRECTORY(libs) ADD_SUBDIRECTORY(libs)
ADD_SUBDIRECTORY(submodules/fmt) ADD_SUBDIRECTORY(submodules/fmt)
ADD_SUBDIRECTORY(submodules/libuv) ADD_SUBDIRECTORY(submodules/libuv)
SET(RECASTNAVIGATION_DEMO OFF CACHE BOOL "Build demo")
SET(RECASTNAVIGATION_TESTS OFF CACHE BOOL "Build tests")
SET(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "Build examples")
ADD_SUBDIRECTORY(submodules/recastnavigation)
IF(EQEMU_BUILD_ZLIB) IF(EQEMU_BUILD_ZLIB)
SET(ZLIB_COMPAT ON CACHE BOOL "Compile with zlib compatible API") SET(ZLIB_COMPAT ON CACHE BOOL "Compile with zlib compatible API")
SET(ZLIB_ENABLE_TESTS OFF CACHE BOOL "Build test binaries") SET(ZLIB_ENABLE_TESTS OFF CACHE BOOL "Build test binaries")
ADD_SUBDIRECTORY(libs/zlibng) ADD_SUBDIRECTORY(libs/zlibng)
ENDIF() ENDIF()
SET(RECASTNAVIGATION_DEMO OFF CACHE BOOL "Build demo")
SET(RECASTNAVIGATION_TESTS OFF CACHE BOOL "Build tests")
SET(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "Build examples")
ADD_SUBDIRECTORY(submodules/recastnavigation)
ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC) ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
IF(EQEMU_BUILD_SERVER) IF(EQEMU_BUILD_SERVER)
ADD_SUBDIRECTORY(shared_memory) ADD_SUBDIRECTORY(shared_memory)
ADD_SUBDIRECTORY(world) ADD_SUBDIRECTORY(world)
@ -358,7 +321,6 @@ IF(EQEMU_BUILD_SERVER)
ADD_SUBDIRECTORY(queryserv) ADD_SUBDIRECTORY(queryserv)
ADD_SUBDIRECTORY(eqlaunch) ADD_SUBDIRECTORY(eqlaunch)
ENDIF(EQEMU_BUILD_SERVER) ENDIF(EQEMU_BUILD_SERVER)
IF(EQEMU_BUILD_LOGIN) IF(EQEMU_BUILD_LOGIN)
ADD_SUBDIRECTORY(loginserver) ADD_SUBDIRECTORY(loginserver)
ENDIF(EQEMU_BUILD_LOGIN) ENDIF(EQEMU_BUILD_LOGIN)

View File

@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2) CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
add_subdirectory(import) add_subdirectory(import)
add_subdirectory(export) add_subdirectory(export)

View File

@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2) CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(export_sources SET(export_sources
main.cpp main.cpp

View File

@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2) CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(import_sources SET(import_sources
main.cpp main.cpp

View File

@ -1,94 +0,0 @@
OPTION(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG "Automatically fetch vcpkg dependencies for MSCV" ON)
OPTION(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL "Automatically fetch perl dependencies for MSCV" ON)
MARK_AS_ADVANCED(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG)
MARK_AS_ADVANCED(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL)
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86 "https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x86.zip")
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64 "https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x64.zip")
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86 "http://strawberryperl.com/download/5.24.4.1/strawberry-perl-5.24.4.1-32bit-portable.zip")
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64 "http://strawberryperl.com/download/5.24.4.1/strawberry-perl-5.24.4.1-64bit-portable.zip")
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_ZIP "vcpkg-export-x86.zip")
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_ZIP "vcpkg-export-x64.zip")
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_DIR "vcpkg-export-20180828-145854")
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_DIR "vcpkg-export-20180828-145455")
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86_ZIP "strawberry-perl-5.24.4.1-32bit-portable.zip")
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64_ZIP "strawberry-perl-5.24.4.1-64bit-portable.zip")
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86_DIR "x86")
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64_DIR "x64")
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
SET(EQEMU_VCPKG_URL ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64})
SET(EQEMU_PERL_URL ${EQEMU_MSVC_DEPENDENCIES_PERL_X64})
SET(EQEMU_VCPKG_ZIP ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_ZIP})
SET(EQEMU_VCPKG_DIR ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_DIR})
SET(EQEMU_PERL_ZIP ${EQEMU_MSVC_DEPENDENCIES_PERL_X64_ZIP})
SET(EQEMU_PERL_DIR ${EQEMU_MSVC_DEPENDENCIES_PERL_X64_DIR})
ELSE()
SET(EQEMU_VCPKG_URL ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86})
SET(EQEMU_PERL_URL ${EQEMU_MSVC_DEPENDENCIES_PERL_X86})
SET(EQEMU_VCPKG_ZIP ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_ZIP})
SET(EQEMU_VCPKG_DIR ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_DIR})
SET(EQEMU_PERL_ZIP ${EQEMU_MSVC_DEPENDENCIES_PERL_X86_ZIP})
SET(EQEMU_PERL_DIR ${EQEMU_MSVC_DEPENDENCIES_PERL_X86_DIR})
ENDIF()
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG)
MESSAGE(STATUS "Resolving vcpkg dependencies...")
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP})
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/vcpkg)
MESSAGE(STATUS "Downloading existing vcpkg dependencies from releases...")
FILE(DOWNLOAD ${EQEMU_VCPKG_URL} ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
SHOW_PROGRESS
STATUS DOWNLOAD_STATUS)
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
IF(NOT STATUS_CODE EQUAL 0)
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_VCPKG_URL}")
ENDIF()
MESSAGE(STATUS "Extracting files...")
EXECUTE_PROCESS(
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vcpkg
)
ENDIF()
INCLUDE(${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake)
ENDIF()
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL)
#Try to find perl first, (so you can use your active install first)
FIND_PACKAGE(PerlLibs)
IF(NOT PerlLibs_FOUND)
MESSAGE(STATUS "Resolving perl dependencies...")
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP})
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl)
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR})
MESSAGE(STATUS "Downloading portable perl...")
FILE(DOWNLOAD ${EQEMU_PERL_URL} ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
SHOW_PROGRESS
STATUS DOWNLOAD_STATUS)
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
IF(NOT STATUS_CODE EQUAL 0)
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_PERL_URL}")
ENDIF()
MESSAGE(STATUS "Extracting files...")
EXECUTE_PROCESS(
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}
)
ENDIF()
SET(PERL_EXECUTABLE ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/bin/perl.exe CACHE FILEPATH "Path to perl program" FORCE)
SET(PERL_INCLUDE_PATH ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE CACHE PATH "Path to perl include files" FORCE)
SET(PERL_LIBRARY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE/libperl524.a CACHE FILEPATH "Path to perl library" FORCE)
ENDIF()
ENDIF()

124
cmake/FindEQLua51.cmake Normal file
View File

@ -0,0 +1,124 @@
#CMake - Cross Platform Makefile Generator
#Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
#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.
#
#* Neither the names of Kitware, Inc., the Insight Software Consortium,
# nor the names of their contributors may be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
#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.
# This module defines
# LUA51_FOUND, if false, do not try to link to Lua
# LUA_LIBRARIES
# LUA_INCLUDE_DIR, where to find lua.h
# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
IF(LUA_ROOT)
FIND_PATH(LUA_INCLUDE_DIR
NAMES lua.h
HINTS
ENV LUA_DIR
PATHS
${LUA_ROOT}
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include src
)
FIND_LIBRARY(LUA_LIBRARY
NAMES lua51 lua5.1 lua-5.1 lua
HINTS
ENV LUA_DIR
PATHS
${LUA_ROOT}
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
PATH_SUFFIXES lib bin
)
ELSE(LUA_ROOT)
FIND_PATH(LUA_INCLUDE_DIR
NAMES lua.h
HINTS
ENV LUA_DIR
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include
)
FIND_LIBRARY(LUA_LIBRARY
NAMES lua51 lua5.1 lua-5.1 lua
HINTS
ENV LUA_DIR
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
PATH_SUFFIXES lib bin
)
ENDIF(LUA_ROOT)
IF(LUA_LIBRARY)
# include the math library for Unix
IF(UNIX AND NOT APPLE)
FIND_LIBRARY(LUA_MATH_LIBRARY m)
SET(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
# For Windows and Mac, don't need to explicitly include the math library
ELSE()
SET( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries")
ENDIF()
ENDIF()
IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
FILE(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
STRING(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
UNSET(lua_version_str)
ENDIF()
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua51
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
VERSION_VAR LUA_VERSION_STRING)
MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)

View File

@ -1,91 +0,0 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
# Modified from the FindLua51 that comes with CMake
#[=======================================================================[.rst:
FindLua51
---------
Locate Lua51 library This module defines
::
LUA51_FOUND, if false, do not try to link to Lua
LUA_LIBRARIES
LUA_INCLUDE_DIR, where to find lua.h
LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
Note that the expected include convention is
::
#include "lua.h"
and not
::
#include <lua/lua.h>
This is because, the lua location is not standardized and may exist in
locations other than lua/
#]=======================================================================]
find_path(LUA_INCLUDE_DIR lua.h
HINTS
ENV LUA_DIR
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua-5.1 include/lua include/luajit include
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
)
find_library(LUA_LIBRARY
NAMES lua51 lua5.1 lua-5.1 lua luajit
HINTS
ENV LUA_DIR
PATH_SUFFIXES lib
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
)
if(LUA_LIBRARY)
# include the math library for Unix
if(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU)
find_library(LUA_MATH_LIBRARY m)
set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
# For Windows and Mac, don't need to explicitly include the math library
else()
set( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries")
endif()
endif()
if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
unset(lua_version_str)
endif()
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
# handle the QUIETLY and REQUIRED arguments and set LUA51_FOUND to TRUE if
# all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua51
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
VERSION_VAR LUA_VERSION_STRING)
mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)

View File

@ -1,87 +0,0 @@
# - Find mariadbclient
#
# -*- cmake -*-
#
# Find the native MariaDB includes and library
#
# MariaDB_INCLUDE_DIR - where to find mysql.h, etc.
# MariaDB_LIBRARIES - List of libraries when using MariaDB.
# MariaDB_FOUND - True if MariaDB found.
# The following can be used as a hint as to where to search:
# MARIADB_ROOT
IF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARIES)
# Already in cache, be silent
SET(MariaDB_FIND_QUIETLY TRUE)
ENDIF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARIES)
# Include dir
IF(MARIADB_ROOT)
FIND_PATH(MariaDB_INCLUDE_DIR
NAMES mariadb_version.h
PATHS ${MARIADB_ROOT}/include
PATH_SUFFIXES mysql mariadb
NO_DEFAULT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
)
FIND_PATH(MariaDB_INCLUDE_DIR
NAMES mariadb_version.h
PATH_SUFFIXES mysql mariadb
)
ELSE(MARIADB_ROOT)
FIND_PATH(MariaDB_INCLUDE_DIR
NAMES mariadb_version.h
PATH_SUFFIXES mysql mariadb
)
ENDIF(MARIADB_ROOT)
# Library
SET(MariaDB_NAMES libmariadb)
IF(MARIADB_ROOT)
FIND_LIBRARY(MariaDB_LIBRARY
NAMES ${MariaDB_NAMES}
PATHS ${MARIADB_ROOT}/lib
PATH_SUFFIXES mysql mariadb
NO_DEFAULT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
)
FIND_LIBRARY(MariaDB_LIBRARY
NAMES ${MariaDB_NAMES}
PATH_SUFFIXES mysql mariadb
)
ELSE(MARIADB_ROOT)
FIND_LIBRARY(MariaDB_LIBRARY
NAMES ${MariaDB_NAMES} mariadbclient_r mariadbclient
PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
PATH_SUFFIXES mysql mariadb
)
ENDIF(MARIADB_ROOT)
IF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
SET(MariaDB_FOUND TRUE)
SET(MariaDB_LIBRARIES ${MariaDB_LIBRARY})
ELSE (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
SET(MariaDB_FOUND FALSE)
SET(MariaDB_LIBRARIES)
ENDIF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
# handle the QUIETLY and REQUIRED arguments and set MariaDB_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MariaDB DEFAULT_MSG MariaDB_LIBRARY MariaDB_INCLUDE_DIR)
IF(MariaDB_FOUND)
SET( MariaDB_LIBRARY_RELEASE ${MariaDB_LIBRARY} )
SET( MariaDB_LIBRARY_DEBUG ${MariaDB_LIBRARY} )
SET( MariaDB_LIBRARIES ${MariaDB_LIBRARY_RELEASE} ${MariaDB_LIBRARY_DEBUG} )
ELSE(MariaDB_FOUND)
SET( MariaDB_LIBRARIES )
ENDIF(MariaDB_FOUND)
MARK_AS_ADVANCED(
MariaDB_LIBRARY_DEBUG
MariaDB_LIBRARY_RELEASE
MariaDB_INCLUDE_DIR
)

View File

@ -1,93 +0,0 @@
# - Try to find mbedTLS
# Once done this will define
#
# Read-Only variables
# MBEDTLS_FOUND - system has mbedTLS
# MBEDTLS_INCLUDE_DIR - the mbedTLS include directory
# MBEDTLS_LIBRARY_DIR - the mbedTLS library directory
# MBEDTLS_LIBRARIES - Link these to use mbedTLS
# MBEDTLS_LIBRARY - path to mbedTLS library
# MBEDX509_LIBRARY - path to mbedTLS X.509 library
# MBEDCRYPTO_LIBRARY - path to mbedTLS Crypto library
#
# Hint
# MBEDTLS_ROOT_DIR can be pointed to a local mbedTLS installation.
SET(_MBEDTLS_ROOT_HINTS
${MBEDTLS_ROOT_DIR}
ENV MBEDTLS_ROOT_DIR
)
SET(_MBEDTLS_ROOT_HINTS_AND_PATHS
HINTS ${_MBEDTLS_ROOT_HINTS}
PATHS ${_MBEDTLS_ROOT_PATHS}
)
FIND_PATH(MBEDTLS_INCLUDE_DIR
NAMES mbedtls/version.h
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES include
)
IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARIES)
# Already in cache, be silent
SET(MBEDTLS_FIND_QUIETLY TRUE)
ENDIF()
FIND_LIBRARY(MBEDTLS_LIBRARY
NAMES mbedtls libmbedtls
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES library
)
FIND_LIBRARY(MBEDX509_LIBRARY
NAMES mbedx509 libmbedx509
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES library
)
FIND_LIBRARY(MBEDCRYPTO_LIBRARY
NAMES mbedcrypto libmbedcrypto
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES library
)
IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND MBEDX509_LIBRARY AND MBEDCRYPTO_LIBRARY)
SET(MBEDTLS_FOUND TRUE)
ENDIF()
IF(MBEDTLS_FOUND)
# split mbedTLS into -L and -l linker options, so we can set them for pkg-config
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_DIR ${MBEDTLS_LIBRARY} PATH)
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY} NAME_WE)
GET_FILENAME_COMPONENT(MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY} NAME_WE)
GET_FILENAME_COMPONENT(MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY} NAME_WE)
STRING(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE})
STRING(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE})
STRING(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE})
SET(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}")
IF(NOT MBEDTLS_FIND_QUIETLY)
MESSAGE(STATUS "Found mbedTLS:")
FILE(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT)
STRING(REGEX MATCH "MBEDTLS_VERSION_STRING +\"[0-9|.]+\"" MBEDTLSMATCH ${MBEDTLSCONTENT})
IF (MBEDTLSMATCH)
STRING(REGEX REPLACE "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"" "\\1" MBEDTLS_VERSION ${MBEDTLSMATCH})
MESSAGE(STATUS " version ${MBEDTLS_VERSION}")
ENDIF(MBEDTLSMATCH)
MESSAGE(STATUS " TLS: ${MBEDTLS_LIBRARY}")
MESSAGE(STATUS " X509: ${MBEDX509_LIBRARY}")
MESSAGE(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}")
ENDIF(NOT MBEDTLS_FIND_QUIETLY)
ELSE(MBEDTLS_FOUND)
IF(MBEDTLS_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find mbedTLS")
ENDIF(MBEDTLS_FIND_REQUIRED)
ENDIF(MBEDTLS_FOUND)
MARK_AS_ADVANCED(
MBEDTLS_INCLUDE_DIR
MBEDTLS_LIBRARY_DIR
MBEDTLS_LIBRARIES
MBEDTLS_LIBRARY
MBEDX509_LIBRARY
MBEDCRYPTO_LIBRARY
)

View File

@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2) CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(common_sources SET(common_sources
base_packet.cpp base_packet.cpp

View File

@ -13,10 +13,6 @@
#ifndef WIN32 #ifndef WIN32
extern "C" { //the perl headers dont do this for us... extern "C" { //the perl headers dont do this for us...
#endif #endif
#if _MSC_VER
#define __inline__ __inline
#define __builtin_expect
#endif
#include <perl.h> #include <perl.h>
#include <XSUB.h> #include <XSUB.h>
#ifndef WIN32 #ifndef WIN32

View File

@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2) CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(eqlaunch_sources SET(eqlaunch_sources
eqlaunch.cpp eqlaunch.cpp

View File

@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2) CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(hc_sources SET(hc_sources
eq.cpp eq.cpp
@ -13,10 +13,14 @@ SET(hc_headers
world.h world.h
) )
FIND_PACKAGE(OpenSSL REQUIRED)
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
ADD_EXECUTABLE(hc ${hc_sources} ${hc_headers}) ADD_EXECUTABLE(hc ${hc_sources} ${hc_headers})
INSTALL(TARGETS hc RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) INSTALL(TARGETS hc RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
TARGET_LINK_LIBRARIES(hc ${SERVER_LIBS}) TARGET_LINK_LIBRARIES(hc ${SERVER_LIBS} ${OPENSSL_LIBRARIES})
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -1,61 +1,38 @@
# Build for LuaBind CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
# Ryan Pavlik <rpavlik@iastate.edu>
# http://academic.cleardefinition.com/
# Iowa State University HCI Graduate Program/VRAC
cmake_minimum_required(VERSION 3.0) SET(lb_sources
project(LuaBind) src/class.cpp
src/class_info.cpp
set(CPACK_PACKAGE_VERSION_MAJOR "0") src/class_registry.cpp
set(CPACK_PACKAGE_VERSION_MINOR "9") src/class_rep.cpp
set(CPACK_PACKAGE_VERSION_PATCH "1") src/create_class.cpp
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") src/error.cpp
src/exception_handler.cpp
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) src/function.cpp
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) src/inheritance.cpp
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) src/link_compatibility.cpp
src/object_rep.cpp
if(NOT LUA_FOUND AND NOT LUA51_FOUND) src/open.cpp
find_package(Lua51 REQUIRED) src/pcall.cpp
set(LUA_INCLUDE_DIRS "${LUA_INCLUDE_DIR}") src/scope.cpp
endif() src/stack_content_by_name.cpp
src/weak_ref.cpp
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) src/wrapper_base.cpp
# We are the top-level project
include(CTest)
option(LUABIND_INSTALL "Install the LuaBind library and headers" ON)
option(LUABIND_BUILD_DOCS "Build documentation files" OFF)
option(LUABIND_BUILD_SHARED "Build luabind as a shared library?" OFF)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Requiring C++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()
if(MSVC)
# Requiring C++11
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++11")
# set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /std:c++11")
endif()
set(BUILD_SHARED_LIBS ${LUABIND_BUILD_SHARED})
if(BUILD_SHARED_LIBS)
add_definitions(-DLUABIND_DYNAMIC_LINK)
endif()
include_directories(
"${CMAKE_CURRENT_SOURCE_DIR}"
${LUA_INCLUDE_DIRS}
) )
add_subdirectory(src) SET(lb_headers
if(BUILD_TESTING) )
add_subdirectory(test)
endif()
if(LUABIND_BUILD_DOCS) ADD_LIBRARY(luabind ${lb_sources} ${lb_headers})
add_subdirectory(doc)
endif()
IF(UNIX)
set_source_files_properties(${lb_sources} PROPERTY COMPILE_FLAGS -Wno-deprecated-declarations)
ENDIF(UNIX)
IF(MSVC)
set_source_files_properties(${lb_sources} PROPERTY COMPILE_FLAGS " /W0 " )
ENDIF(MSVC)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -1,54 +0,0 @@
{
"configurations": [
{
"name": "x32-debug",
"generator": "Visual Studio 15 2017",
"buildRoot": "${projectDir}/temp/x32-debug",
"cmakeCommandArgs": "",
"configurationType": "Debug",
"variables": [
{
"name": "LUA_INCLUDE_DIR",
"value": "C:/gitprojects/LuaJIT-2.1.0-beta3/src"
},
{
"name": "LUA_LIBRARIES",
"value": "C:/gitprojects/LuaJIT-2.1.0-beta3/src/lua51.lib"
},
{
"name": "LUABIND_INSTALL",
"value": "ON"
},
{
"name": "CMAKE_INSTALL_PREFIX",
"value": "${projectDir}/build/debug"
}
]
},
{
"name": "x32-release",
"generator": "Visual Studio 15 2017",
"buildRoot": "${projectDir}/temp/x32-release",
"cmakeCommandArgs": "",
"configurationType": "Release",
"variables": [
{
"name": "LUA_INCLUDE_DIR",
"value": "C:/gitprojects/LuaJIT-2.1.0-beta3/src"
},
{
"name": "LUA_LIBRARIES",
"value": "C:/gitprojects/LuaJIT-2.1.0-beta3/src/lua51.lib"
},
{
"name": "LUABIND_INSTALL",
"value": "ON"
},
{
"name": "CMAKE_INSTALL_PREFIX",
"value": "${projectDir}/build/release"
}
]
}
]
}

View File

@ -28,111 +28,114 @@
#include <luabind/wrapper_base.hpp> #include <luabind/wrapper_base.hpp>
#include <luabind/detail/policy.hpp> #include <luabind/detail/policy.hpp>
#include <luabind/back_reference_fwd.hpp> #include <luabind/back_reference_fwd.hpp>
#include <luabind/wrapper_base.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
namespace luabind { namespace luabind { namespace detail
namespace detail { {
template <class T>
void adjust_backref_ownership(T* ptr, mpl::true_)
{
if (wrap_base* p = dynamic_cast<wrap_base*>(ptr))
{
wrapped_self_t& wrapper = wrap_access::ref(*p);
wrapper.get(wrapper.state());
wrapper.m_strong_ref.set(wrapper.state());
}
}
template <class T> inline void adjust_backref_ownership(void*, mpl::false_)
void adjust_backref_ownership(T* ptr, std::true_type) {}
template<class Direction = lua_to_cpp>
struct adopt_pointer : pointer_converter
{
typedef adopt_pointer type;
int const consumed_args(...)
{
return 1;
}
template<class T>
T* apply(lua_State* L, by_pointer<T>, int index)
{ {
if(wrap_base* p = dynamic_cast<wrap_base*>(ptr)) T* ptr = pointer_converter::apply(
{ L, LUABIND_DECORATE_TYPE(T*), index);
wrapped_self_t& wrapper = wrap_access::ref(*p);
wrapper.get(wrapper.state()); object_rep* obj = static_cast<object_rep*>(
wrapper.m_strong_ref.set(wrapper.state()); lua_touserdata(L, index));
} obj->release();
adjust_backref_ownership(ptr, boost::is_polymorphic<T>());
return ptr;
} }
inline void adjust_backref_ownership(void*, std::false_type) template<class T>
{} int match(lua_State* L, by_pointer<T>, int index)
template <class Pointer, class Direction = lua_to_cpp>
struct adopt_pointer : pointer_converter
{ {
using type = adopt_pointer; return pointer_converter::match(
L, LUABIND_DECORATE_TYPE(T*), index);
}
enum { consumed_args = 1 }; template<class T>
void converter_postcall(lua_State*, T, int) {}
};
template<class T> template<>
T* to_cpp(lua_State* L, by_pointer<T>, int index) struct adopt_pointer<cpp_to_lua>
{
typedef adopt_pointer type;
template<class T>
void apply(lua_State* L, T* ptr)
{
if (ptr == 0)
{ {
T* ptr = pointer_converter::to_cpp(L, decorate_type_t<T*>(), index); lua_pushnil(L);
return;
object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
obj->release();
adjust_backref_ownership(ptr, std::is_polymorphic<T>());
return ptr;
} }
template<class T> // if there is a back_reference, then the
int match(lua_State* L, by_pointer<T>, int index) // ownership will be removed from the
{ // back reference and put on the lua stack.
return pointer_converter::match(L, decorate_type_t<T*>(), index); if (luabind::move_back_reference(L, ptr))
} return;
template<class T> make_instance(L, std::auto_ptr<T>(ptr));
void converter_postcall(lua_State*, T, int) {} }
}; };
template <class Pointer, class T> template<int N>
struct pointer_or_default // struct adopt_policy : converter_policy_tag
struct adopt_policy : conversion_policy<N>
{
// BOOST_STATIC_CONSTANT(int, index = N);
static void precall(lua_State*, const index_map&) {}
static void postcall(lua_State*, const index_map&) {}
struct only_accepts_nonconst_pointers {};
template<class T, class Direction>
struct apply
{ {
using type = Pointer; typedef luabind::detail::is_nonconst_pointer<T> is_nonconst_p;
typedef typename boost::mpl::if_<is_nonconst_p, adopt_pointer<Direction>, only_accepts_nonconst_pointers>::type type;
}; };
};
template <class T> }}
struct pointer_or_default<void, T>
{
using type = std::unique_ptr<T>;
};
template <class Pointer>
struct adopt_pointer<Pointer, cpp_to_lua>
{
using type = adopt_pointer;
template<class T>
void to_lua(lua_State* L, T* ptr)
{
if(ptr == 0)
{
lua_pushnil(L);
return;
}
// if there is a back_reference, then the
// ownership will be removed from the
// back reference and put on the lua stack.
if(luabind::move_back_reference(L, ptr))
return;
using pointer_type = typename pointer_or_default<Pointer, T>::type;
make_pointer_instance(L, pointer_type(ptr));
}
};
template <class Pointer>
struct adopt_policy_impl
{
template<class T, class Direction>
struct specialize
{
static_assert(detail::is_nonconst_pointer<T>::value, "Adopt policy only accepts non-const pointers");
using type = adopt_pointer<Pointer, Direction>;
};
};
}
}
namespace luabind namespace luabind
{ {
// Caution: if we use the aliased type "policy_list" here, MSVC crashes. template<int N>
template<unsigned int N, typename Pointer = void> detail::policy_cons<detail::adopt_policy<N>, detail::null_type>
using adopt_policy = meta::type_list<converter_policy_injector<N, detail::adopt_policy_impl<Pointer>>>; adopt(LUABIND_PLACEHOLDER_ARG(N))
{
return detail::policy_cons<detail::adopt_policy<N>, detail::null_type>();
}
} }
#endif // LUABIND_ADOPT_POLICY_HPP_INCLUDE #endif // LUABIND_ADOPT_POLICY_HPP_INCLUDE

View File

@ -23,86 +23,88 @@
#ifndef LUABIND_BACK_REFERENCE_040510_HPP #ifndef LUABIND_BACK_REFERENCE_040510_HPP
#define LUABIND_BACK_REFERENCE_040510_HPP #define LUABIND_BACK_REFERENCE_040510_HPP
#include <luabind/config.hpp> #include <luabind/lua_include.hpp>
#include <luabind/lua_state_fwd.hpp>
#include <type_traits>
#if !defined(LUABIND_NO_RTTI) && !defined(LUABIND_WRAPPER_BASE_HPP_INCLUDED)
#include <luabind/wrapper_base.hpp> #include <luabind/wrapper_base.hpp>
#endif #include <luabind/detail/has_get_pointer.hpp>
#include <luabind/get_pointer.hpp>
#include <luabind/pointer_traits.hpp> #include <boost/type_traits/is_polymorphic.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/mpl/if.hpp>
namespace luabind { namespace luabind {
struct wrap_base;
namespace detail namespace detail
{ {
template<class T> namespace mpl = boost::mpl;
wrap_base const* get_back_reference_aux0(T const* p, std::true_type)
{ template<class T>
return dynamic_cast<wrap_base const*>(p); wrap_base const* get_back_reference_aux0(T const* p, mpl::true_)
} {
return dynamic_cast<wrap_base const*>(p);
}
template<class T> template<class T>
wrap_base const* get_back_reference_aux0(T const*, std::false_type) wrap_base const* get_back_reference_aux0(T const*, mpl::false_)
{ {
return 0; return 0;
} }
template<class T> template<class T>
wrap_base const* get_back_reference_aux1(T const* p) wrap_base const* get_back_reference_aux1(T const* p)
{ {
return get_back_reference_aux0(p, std::is_polymorphic<T>()); return get_back_reference_aux0(p, boost::is_polymorphic<T>());
} }
template<class T> template<class T>
wrap_base const* get_back_reference_aux2(T const& x, std::true_type) wrap_base const* get_back_reference_aux2(T const& x, mpl::true_)
{ {
return get_back_reference_aux1(get_pointer(x)); return get_back_reference_aux1(get_pointer(x));
} }
template<class T> template<class T>
wrap_base const* get_back_reference_aux2(T const& x, std::false_type) wrap_base const* get_back_reference_aux2(T const& x, mpl::false_)
{ {
return get_back_reference_aux1(&x); return get_back_reference_aux1(&x);
} }
template<class T> template<class T>
wrap_base const* get_back_reference(T const& x) wrap_base const* get_back_reference(T const& x)
{ {
return detail::get_back_reference_aux2(x, has_get_pointer<T>()); return detail::get_back_reference_aux2(
} x
, has_get_pointer<T>()
);
}
} // namespace detail
} // namespace detail template<class T>
bool get_back_reference(lua_State* L, T const& x)
template<class T> {
bool get_back_reference(lua_State* L, T const& x)
{
#ifndef LUABIND_NO_RTTI #ifndef LUABIND_NO_RTTI
if(wrap_base const* w = detail::get_back_reference(x)) if (wrap_base const* w = detail::get_back_reference(x))
{ {
detail::wrap_access::ref(*w).get(L); detail::wrap_access::ref(*w).get(L);
return true; return true;
} }
#endif #endif
return false; return false;
} }
template<class T> template<class T>
bool move_back_reference(lua_State* L, T const& x) bool move_back_reference(lua_State* L, T const& x)
{ {
#ifndef LUABIND_NO_RTTI #ifndef LUABIND_NO_RTTI
if(wrap_base* w = const_cast<wrap_base*>(detail::get_back_reference(x))) if (wrap_base* w = const_cast<wrap_base*>(detail::get_back_reference(x)))
{ {
assert(detail::wrap_access::ref(*w).m_strong_ref.is_valid()); assert(detail::wrap_access::ref(*w).m_strong_ref.is_valid());
detail::wrap_access::ref(*w).get(L); detail::wrap_access::ref(*w).get(L);
detail::wrap_access::ref(*w).m_strong_ref.reset(); detail::wrap_access::ref(*w).m_strong_ref.reset();
return true; return true;
} }
#endif #endif
return false; return false;
} }
} // namespace luabind } // namespace luabind

View File

@ -23,15 +23,13 @@
#ifndef LUABIND_BACK_REFERENCE_FWD_040510_HPP #ifndef LUABIND_BACK_REFERENCE_FWD_040510_HPP
#define LUABIND_BACK_REFERENCE_FWD_040510_HPP #define LUABIND_BACK_REFERENCE_FWD_040510_HPP
#include <luabind/lua_state_fwd.hpp>
namespace luabind { namespace luabind {
template<class T> template<class T>
bool get_back_reference(lua_State* L, T const& x); bool get_back_reference(lua_State* L, T const& x);
template<class T> template<class T>
bool move_back_reference(lua_State* L, T const& x); bool move_back_reference(lua_State* L, T const& x);
} // namespace luabind } // namespace luabind

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE. // OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_CLASS_INFO_HPP_INCLUDED #ifndef LUABIND_CLASS_INFO_HPP_INCLUDED
#define LUABIND_CLASS_INFO_HPP_INCLUDED #define LUABIND_CLASS_INFO_HPP_INCLUDED
@ -31,16 +32,16 @@
namespace luabind namespace luabind
{ {
struct LUABIND_API class_info struct LUABIND_API class_info
{ {
std::string name; std::string name;
object methods; object methods;
object attributes; object attributes;
}; };
LUABIND_API class_info get_class_info(argument const&); LUABIND_API class_info get_class_info(argument const&);
// returns a table of bound class names // returns a table of bound class names
LUABIND_API object get_class_names(lua_State* L); LUABIND_API object get_class_names(lua_State* L);
LUABIND_API void bind_class_info(lua_State*); LUABIND_API void bind_class_info(lua_State*);
} }

View File

@ -20,26 +20,57 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE. // OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_CONFIG_HPP_INCLUDED #ifndef LUABIND_CONFIG_HPP_INCLUDED
#define LUABIND_CONFIG_HPP_INCLUDED #define LUABIND_CONFIG_HPP_INCLUDED
#include <boost/config.hpp>
#ifdef BOOST_MSVC
#define LUABIND_ANONYMOUS_FIX static
#else
#define LUABIND_ANONYMOUS_FIX
#endif
#if defined (BOOST_MSVC) && (BOOST_MSVC <= 1200)
#define for if (false) {} else for
#include <cstring>
namespace std
{
using ::strlen;
using ::strcmp;
using ::type_info;
}
#endif
#if defined (BOOST_MSVC) && (BOOST_MSVC <= 1300)
#define LUABIND_MSVC_TYPENAME
#else
#define LUABIND_MSVC_TYPENAME typename
#endif
// the maximum number of arguments of functions that's // the maximum number of arguments of functions that's
// registered. Must at least be 2 // registered. Must at least be 2
#ifndef LUABIND_MAX_ARITY #ifndef LUABIND_MAX_ARITY
#define LUABIND_MAX_ARITY 100 #define LUABIND_MAX_ARITY 10
#elif LUABIND_MAX_ARITY <= 1 #elif LUABIND_MAX_ARITY <= 1
#undef LUABIND_MAX_ARITY #undef LUABIND_MAX_ARITY
#define LUABIND_MAX_ARITY 2 #define LUABIND_MAX_ARITY 2
#endif #endif
// the maximum number of classes one class // the maximum number of classes one class
// can derive from // can derive from
// max bases must at least be 1 // max bases must at least be 1
#ifndef LUABIND_MAX_BASES #ifndef LUABIND_MAX_BASES
#define LUABIND_MAX_BASES 100 #define LUABIND_MAX_BASES 4
#elif LUABIND_MAX_BASES <= 0 #elif LUABIND_MAX_BASES <= 0
#undef LUABIND_MAX_BASES #undef LUABIND_MAX_BASES
#define LUABIND_MAX_BASES 1 #define LUABIND_MAX_BASES 1
#endif #endif
// LUABIND_NO_ERROR_CHECKING // LUABIND_NO_ERROR_CHECKING
@ -70,18 +101,12 @@
// C code has undefined behavior, lua is written in C). // C code has undefined behavior, lua is written in C).
#ifdef LUABIND_DYNAMIC_LINK #ifdef LUABIND_DYNAMIC_LINK
# if defined (_WIN32) # ifdef BOOST_WINDOWS
# ifdef LUABIND_BUILDING # ifdef LUABIND_BUILDING
# define LUABIND_API __declspec(dllexport) # define LUABIND_API __declspec(dllexport)
# else # else
# define LUABIND_API __declspec(dllimport) # define LUABIND_API __declspec(dllimport)
# endif # endif
# elif defined (__CYGWIN__)
# ifdef LUABIND_BUILDING
# define LUABIND_API __attribute__ ((dllexport))
# else
# define LUABIND_API __attribute__ ((dllimport))
# endif
# else # else
# if defined(_GNUC_) && _GNUC_ >=4 # if defined(_GNUC_) && _GNUC_ >=4
# define LUABIND_API __attribute__ ((visibility("default"))) # define LUABIND_API __attribute__ ((visibility("default")))
@ -93,19 +118,9 @@
# define LUABIND_API # define LUABIND_API
#endif #endif
// This switches between using tag arguments / structure specialization for code size tests
#define LUABIND_NO_INTERNAL_TAG_ARGUMENTS
namespace luabind { namespace luabind {
LUABIND_API void disable_super_deprecation(); LUABIND_API void disable_super_deprecation();
namespace detail {
const int max_argument_count = 100;
const int max_hierarchy_depth = 100;
}
const int no_match = -(detail::max_argument_count*detail::max_hierarchy_depth + 1);
} // namespace luabind } // namespace luabind

View File

@ -20,111 +20,124 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE. // OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_CONTAINER_POLICY_HPP_INCLUDED #ifndef LUABIND_CONTAINER_POLICY_HPP_INCLUDED
#define LUABIND_CONTAINER_POLICY_HPP_INCLUDED #define LUABIND_CONTAINER_POLICY_HPP_INCLUDED
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/detail/policy.hpp> #include <luabind/detail/policy.hpp>
#include <luabind/detail/decorate_type.hpp> // for decorated_type #include <boost/mpl/apply_wrap.hpp>
#include <luabind/detail/primitives.hpp> // for null_type (ptr only), etc
namespace luabind { namespace luabind { namespace detail {
namespace detail {
template<class Policies> namespace mpl = boost::mpl;
struct container_converter_lua_to_cpp
template<class Policies>
struct container_converter_lua_to_cpp
{
int const consumed_args(...)
{
return 1;
}
template<class T>
T apply(lua_State* L, by_const_reference<T>, int index)
{ {
enum { consumed_args = 1 }; typedef typename T::value_type value_type;
template<class T> typedef typename find_conversion_policy<1, Policies>::type converter_policy;
T to_cpp(lua_State* L, by_const_reference<T>, int index) typename mpl::apply_wrap2<converter_policy,value_type,lua_to_cpp>::type converter;
T container;
lua_pushnil(L);
while (lua_next(L, index))
{ {
using value_type = typename T::value_type; container.push_back(converter.apply(L, LUABIND_DECORATE_TYPE(value_type), -1));
specialized_converter_policy_n<1, Policies, value_type, lua_to_cpp> converter; lua_pop(L, 1); // pop value
T container;
lua_pushnil(L);
while(lua_next(L, index - 1))
{
container.push_back(converter.apply(L, decorated_type<value_type>(), -1));
lua_pop(L, 1); // pop value
}
return container;
} }
template<class T> return container;
T to_cpp(lua_State* L, by_value<T>, int index) }
{
return to_cpp(L, by_const_reference<T>(), index);
}
template<class T> template<class T>
static int match(lua_State* L, by_const_reference<T>, int index) T apply(lua_State* L, by_value<T>, int index)
{
if(lua_istable(L, index)) return 0; else return no_match;
}
template<class T>
static int match(lua_State* L, by_value<T>, int index)
{
return match(L, by_const_reference<T>(), index);
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
template<class Policies>
struct container_converter_cpp_to_lua
{ {
template<class T> return apply(L, by_const_reference<T>(), index);
void to_lua(lua_State* L, const T& container) }
{
using value_type = typename T::value_type;
specialized_converter_policy_n<1, Policies, value_type, lua_to_cpp> converter;
lua_newtable(L); template<class T>
static int match(lua_State* L, by_const_reference<T>, int index)
int index = 1;
for(const auto& element : container)
{
converter.apply(L, element);
lua_rawseti(L, -2, index);
++index;
}
}
};
template<class Policies = no_policies>
struct container_policy
{ {
struct only_accepts_nonconst_pointers {}; if (lua_istable(L, index)) return 0; else return -1;
}
template<class T, class Direction> template<class T>
struct specialize; void converter_postcall(lua_State*, T, int) {}
};
template<class T> template<class Policies>
struct specialize<T, lua_to_cpp> { struct container_converter_cpp_to_lua
using type = container_converter_lua_to_cpp<Policies>; {
}; template<class T>
void apply(lua_State* L, const T& container)
{
typedef typename T::value_type value_type;
template<class T> typedef typename find_conversion_policy<1, Policies>::type converter_policy;
struct specialize<T, cpp_to_lua> { typename mpl::apply_wrap2<converter_policy,value_type,lua_to_cpp>::type converter;
using type = container_converter_cpp_to_lua<Policies>;
}; lua_newtable(L);
int index = 1;
for (typename T::const_iterator i = container.begin(); i != container.end(); ++i)
{
converter.apply(L, *i);
lua_rawseti(L, -2, index);
++index;
}
}
};
template<int N, class Policies>
// struct container_policy : converter_policy_tag
struct container_policy : conversion_policy<N>
{
// BOOST_STATIC_CONSTANT(int, index = N);
static void precall(lua_State*, const index_map&) {}
static void postcall(lua_State*, const index_map&) {}
struct only_accepts_nonconst_pointers {};
template<class T, class Direction>
struct apply
{
typedef typename boost::mpl::if_<boost::is_same<lua_to_cpp, Direction>
, container_converter_lua_to_cpp<Policies>
, container_converter_cpp_to_lua<Policies>
>::type type;
}; };
};
} }}
}
namespace luabind namespace luabind
{ {
template<unsigned int N, typename ElementPolicies = no_policies > template<int N>
using container_policy = meta::type_list<converter_policy_injector<N, detail::container_policy<ElementPolicies>>>; detail::policy_cons<detail::container_policy<N, detail::null_type>, detail::null_type>
container(LUABIND_PLACEHOLDER_ARG(N))
{
return detail::policy_cons<detail::container_policy<N, detail::null_type>, detail::null_type>();
}
template<int N, class Policies>
detail::policy_cons<detail::container_policy<N, Policies>, detail::null_type>
container(LUABIND_PLACEHOLDER_ARG(N), const Policies&)
{
return detail::policy_cons<detail::container_policy<N, Policies>, detail::null_type>();
}
} }
#endif // LUABIND_CONTAINER_POLICY_HPP_INCLUDED #endif // LUABIND_CONTAINER_POLICY_HPP_INCLUDED

View File

@ -8,41 +8,52 @@
# include <luabind/detail/policy.hpp> # include <luabind/detail/policy.hpp>
namespace luabind { namespace luabind {
namespace detail {
struct copy_converter namespace detail
{ {
template <class T>
void to_lua(lua_State* L, T const& x)
{
value_converter().to_lua(L, x);
}
template <class T> struct copy_converter
void to_lua(lua_State* L, T* x) {
{ template <class T>
if(!x) void apply(lua_State* L, T const& x)
lua_pushnil(L); {
else value_converter().apply(L, x);
to_lua(L, *x); }
}
};
struct copy_policy template <class T>
{ void apply(lua_State* L, T* x)
template <class T, class Direction> {
struct specialize if (!x)
{ lua_pushnil(L);
static_assert(std::is_same<Direction, cpp_to_lua>::value, "Copy policy only supports cpp -> lua"); else
using type = copy_converter; apply(L, *x);
}; }
}; };
} // namespace detail template <int N>
struct copy_policy : conversion_policy<N>
{
static void precall(lua_State*, index_map const&)
{}
// Caution: If we use the aliased type "policy_list" here, MSVC crashes. static void postcall(lua_State*, index_map const&)
template< unsigned int N > {}
using copy_policy = meta::type_list< converter_policy_injector< N, detail::copy_policy > >;
template <class T, class Direction>
struct apply
{
typedef copy_converter type;
};
};
} // namespace detail
template <int N>
detail::policy_cons<detail::copy_policy<N>, detail::null_type>
copy(LUABIND_PLACEHOLDER_ARG(N))
{
return detail::policy_cons<detail::copy_policy<N>, detail::null_type>();
}
} // namespace luabind } // namespace luabind

View File

@ -25,75 +25,95 @@
#define LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED #define LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/detail/policy.hpp> // for policy_cons, etc #include <luabind/detail/policy.hpp>
#include <luabind/detail/object_rep.hpp> // for object_rep
#include <luabind/detail/primitives.hpp> // for null_type
namespace luabind { namespace luabind { namespace detail
namespace detail { {
// makes A dependent on B, meaning B will outlive A.
// makes A dependent on B, meaning B will outlive A. // internally A stores a reference to B
// internally A stores a reference to B template<int A, int B>
template<int A, int B> struct dependency_policy
struct dependency_policy {
static void postcall(lua_State* L, const index_map& indices)
{ {
template< unsigned int... StackIndices > int nurse_index = indices[A];
static void postcall(lua_State* L, int results, meta::index_list<StackIndices...>) int patient = indices[B];
{
object_rep* nurse = static_cast<object_rep*>(lua_touserdata(L, meta::get<meta::index_list<StackIndices...>, A>::value));
// If the nurse isn't an object_rep, just make this a nop. object_rep* nurse = static_cast<object_rep*>(lua_touserdata(L, nurse_index));
if(nurse == 0)
return;
nurse->add_dependency(L, meta::get<meta::index_list<StackIndices...>, B>::value); // If the nurse isn't an object_rep, just make this a nop.
} if (nurse == 0)
}; return;
template<int B> nurse->add_dependency(L, patient);
struct dependency_policy<0, B> }
{ };
template< unsigned int... StackIndices >
static void postcall(lua_State* L, int results, meta::index_list<StackIndices...>)
{
object_rep* nurse = static_cast<object_rep*>(lua_touserdata(L, meta::get<meta::index_list<StackIndices...>, 0>::value + results));
// If the nurse isn't an object_rep, just make this a nop. }}
if(nurse == 0)
return;
nurse->add_dependency(L, meta::get<meta::index_list<StackIndices...>, B>::value); #if defined (BOOST_MSVC) && (BOOST_MSVC <= 1200)
}
};
template<int A>
struct dependency_policy<A, 0>
{
template< unsigned int... StackIndices >
static void postcall(lua_State* L, int results, meta::index_list<StackIndices...>)
{
object_rep* nurse = static_cast<object_rep*>(lua_touserdata(L, meta::get<meta::index_list<StackIndices...>, A>::value));
// If the nurse isn't an object_rep, just make this a nop.
if(nurse == 0)
return;
nurse->add_dependency(L, meta::get<meta::index_list<StackIndices...>, 0>::value + results);
}
};
}
}
namespace luabind namespace luabind
{ {
// Caution: If we use the aliased type "policy_list" here, MSVC crashes. // most absurd workaround of all time?
template<unsigned int A, unsigned int B> namespace detail
using dependency_policy = meta::type_list<call_policy_injector<detail::dependency_policy<A, B>>>; {
template<int N>
struct size_char_array
{
char storage[N + 2];
};
template<unsigned int A> template<int N>
using return_internal_reference = meta::type_list<call_policy_injector<detail::dependency_policy<0, A>>>; size_char_array<N> deduce_size(LUABIND_PLACEHOLDER_ARG(N));
template<class T>
struct get_index_workaround
{
static T t;
BOOST_STATIC_CONSTANT(int, value = sizeof(deduce_size(t)) - 2);
};
}
template<class A, class B>
detail::policy_cons<detail::dependency_policy<detail::get_index_workaround<A>::value
, detail::get_index_workaround<B>::value>, detail::null_type> dependency(A,B)
{
return detail::policy_cons<detail::dependency_policy<
detail::get_index_workaround<A>::value, detail::get_index_workaround<B>::value>
, detail::null_type>();
}
template<class A>
detail::policy_cons<detail::dependency_policy<0
, detail::get_index_workaround<A>::value>, detail::null_type>
return_internal_reference(A)
{
return detail::policy_cons<detail::dependency_policy<0
, detail::get_index_workaround<A>::value>, detail::null_type>();
}
} }
#else
namespace luabind
{
template<int A, int B>
detail::policy_cons<detail::dependency_policy<A, B>, detail::null_type>
dependency(LUABIND_PLACEHOLDER_ARG(A), LUABIND_PLACEHOLDER_ARG(B))
{
return detail::policy_cons<detail::dependency_policy<A, B>, detail::null_type>();
}
template<int A>
detail::policy_cons<detail::dependency_policy<0, A>, detail::null_type>
return_internal_reference(LUABIND_PLACEHOLDER_ARG(A))
{
return detail::policy_cons<detail::dependency_policy<0, A>, detail::null_type>();
}
}
#endif
#endif // LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED #endif // LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED

View File

@ -20,46 +20,42 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE. // OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_CALL_SHARED_HPP_INCLUDED #if !BOOST_PP_IS_ITERATING
#define LUABIND_CALL_SHARED_HPP_INCLUDED
namespace luabind { # include <luabind/detail/signature_match.hpp>
namespace detail {
inline void call_error(lua_State* L) #ifndef LUABIND_CALC_ARITY_HPP_INCLUDED
#define LUABIND_CALC_ARITY_HPP_INCLUDED
#define LUABIND_FIND_CONV(z,n,text) typedef typename find_conversion_policy<n + 1, Policies>::type p##n;
#define LUABIND_CALC_ARITY(z,n,text) + BOOST_PP_CAT(p,n)::has_arg
namespace luabind { namespace detail
{
template<int N> struct calc_arity;
#define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/calc_arity.hpp>, 1))
#include BOOST_PP_ITERATE()
}}
#undef LUABIND_CALC_ARITY
#undef LUABIND_FIND_CONV
#endif // LUABIND_CALC_ARITY_HPP_INCLUDED
#else // BOOST_PP_ITERATE
template<>
struct calc_arity<BOOST_PP_ITERATION()>
{
template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
static int apply(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>, Policies*)
{ {
#ifndef LUABIND_NO_EXCEPTIONS BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_FIND_CONV, _)
throw luabind::error(L); return 0 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_CALC_ARITY, _);
#else
error_callback_fun e = get_error_callback();
if(e) e(L);
assert(0 && "the lua function threw an error and exceptions are disabled."
" If you want to handle the error you can use luabind::set_error_callback()");
std::terminate();
#endif
} }
};
template<typename T>
void cast_error(lua_State* L)
{
#ifndef LUABIND_NO_EXCEPTIONS
throw cast_failed(L, typeid(T));
#else
cast_failed_callback_fun e = get_cast_failed_callback();
if(e) e(L, typeid(T));
assert(0 && "the lua function's return value could not be converted."
" If you want to handle the error you can use luabind::set_cast_failed_callback()");
std::terminate();
#endif
}
template< typename... Args >
void expand_hack(Args... /*args*/)
{}
}
}
#endif #endif

View File

@ -1,547 +1,323 @@
// Copyright Daniel Wallin 208.Use, modification and distribution is // Copyright Daniel Wallin 2008. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying // subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef LUABIND_CALL2_080911_HPP #if !BOOST_PP_IS_ITERATING
#define LUABIND_CALL2_080911_HPP
# ifndef LUABIND_CALL2_080911_HPP
#include <luabind/config.hpp> # define LUABIND_CALL2_080911_HPP
#include <typeinfo>
#include <luabind/detail/meta.hpp> # include <boost/mpl/apply_wrap.hpp>
#include <luabind/detail/policy.hpp> # include <boost/mpl/begin_end.hpp>
#include <luabind/yield_policy.hpp> # include <boost/mpl/deref.hpp>
#include <luabind/detail/decorate_type.hpp> # include <boost/mpl/front.hpp>
#include <luabind/detail/object.hpp> # include <boost/mpl/long.hpp>
# include <boost/mpl/size.hpp>
#ifdef LUABIND_NO_INTERNAL_TAG_ARGUMENTS # include <boost/preprocessor/control/if.hpp>
#include <tuple> # include <boost/preprocessor/iteration/iterate.hpp>
#endif # include <boost/preprocessor/iteration/local.hpp>
# include <boost/preprocessor/repetition/enum.hpp>
namespace luabind { # include <boost/preprocessor/repetition/enum_trailing_params.hpp>
namespace detail { # include <boost/type_traits/is_void.hpp>
struct invoke_context; # include <luabind/config.hpp>
# include <luabind/detail/policy.hpp>
struct LUABIND_API function_object # include <luabind/yield_policy.hpp>
{
function_object(lua_CFunction entry) namespace luabind { namespace detail {
: entry(entry)
, next(0) struct invoke_context;
{}
struct LUABIND_API function_object
virtual ~function_object() {
{} function_object(lua_CFunction entry)
: entry(entry)
virtual int call(lua_State* L, invoke_context& ctx) /* const */ = 0; , next(0)
virtual void format_signature(lua_State* L, char const* function) const = 0; {}
lua_CFunction entry; virtual ~function_object()
std::string name; {}
function_object* next;
object keepalive; virtual int call(
}; lua_State* L, invoke_context& ctx) const = 0;
virtual void format_signature(lua_State* L, char const* function) const = 0;
struct LUABIND_API invoke_context
{ lua_CFunction entry;
invoke_context() std::string name;
: best_score((std::numeric_limits<int>::max)()) function_object* next;
//This need to avoid static analyzer's treats object keepalive;
, candidates{ nullptr,nullptr,nullptr,nullptr,nullptr, };
nullptr,nullptr,nullptr,nullptr,nullptr }
, candidate_index(0) struct LUABIND_API invoke_context
{} {
invoke_context()
operator bool() const : best_score((std::numeric_limits<int>::max)())
{ , candidate_index(0)
return candidate_index == 1; {}
}
operator bool() const
void format_error(lua_State* L, function_object const* overloads) const; {
return candidate_index == 1;
int best_score; }
function_object const* candidates[10]; // This looks like it could crash if you provide too many overloads?
int candidate_index; void format_error(lua_State* L, function_object const* overloads) const;
};
int best_score;
namespace call_detail_new { function_object const* candidates[10];
int candidate_index;
/* };
Compute Stack Indices
Given the list of argument converter arities, computes the stack indices that each converter addresses. template <class F, class Signature, class Policies, class IsVoid>
*/ inline int invoke0(
lua_State* L, function_object const& self, invoke_context& ctx
template< typename ConsumedList, unsigned int CurrentSum, unsigned int... StackIndices > , F const& f, Signature, Policies const& policies, IsVoid, mpl::true_)
struct compute_stack_indices; {
return invoke_member(
template< unsigned int Consumed0, unsigned int... Consumeds, unsigned int CurrentSum, unsigned int... StackIndices > L, self, ctx, f, Signature(), policies
struct compute_stack_indices< meta::index_list< Consumed0, Consumeds... >, CurrentSum, StackIndices... > , mpl::long_<mpl::size<Signature>::value - 1>(), IsVoid()
{ );
using type = typename compute_stack_indices< meta::index_list< Consumeds... >, CurrentSum + Consumed0, StackIndices..., CurrentSum >::type; }
};
template <class F, class Signature, class Policies, class IsVoid>
template< unsigned int CurrentSum, unsigned int... StackIndices > inline int invoke0(
struct compute_stack_indices< meta::index_list< >, CurrentSum, StackIndices... > lua_State* L, function_object const& self, invoke_context& ctx,
{ F const& f, Signature, Policies const& policies, IsVoid, mpl::false_)
using type = meta::index_list< StackIndices... >; {
}; return invoke_normal(
L, self, ctx, f, Signature(), policies
template< typename Foo > , mpl::long_<mpl::size<Signature>::value - 1>(), IsVoid()
struct FooFoo { // Foo! );
enum { consumed_args = Foo::consumed_args }; }
};
template <class F, class Signature, class Policies>
inline int invoke(
template< typename PolicyList, typename StackIndexList > lua_State* L, function_object const& self, invoke_context& ctx
struct policy_list_postcall; , F const& f, Signature, Policies const& policies)
{
template< typename Policy0, typename... Policies, typename StackIndexList > return invoke0(
struct policy_list_postcall< meta::type_list< call_policy_injector<Policy0>, Policies... >, StackIndexList > { L, self, ctx, f, Signature(), policies
static void postcall(lua_State* L, int results) { , boost::is_void<typename mpl::front<Signature>::type>()
Policy0::postcall(L, results, StackIndexList()); , boost::is_member_function_pointer<F>()
policy_list_postcall< meta::type_list< Policies... >, StackIndexList >::postcall(L, results); );
} }
};
inline int maybe_yield_aux(lua_State*, int results, mpl::false_)
template< typename ConverterPolicy, typename StackIndexList, bool has_postcall > {
struct converter_policy_postcall { return results;
static void postcall(lua_State* L, int results) { }
ConverterPolicy::postcall(L, results, StackIndexList());
} inline int maybe_yield_aux(lua_State* L, int results, mpl::true_)
}; {
return lua_yield(L, results);
template< typename ConverterPolicy, typename StackIndexList > }
struct converter_policy_postcall< ConverterPolicy, StackIndexList, false > {
static void postcall(lua_State* /*L*/, int /*results*/) { template <class Policies>
} int maybe_yield(lua_State* L, int results, Policies*)
}; {
return maybe_yield_aux(
template< unsigned int Index, typename Policy, typename... Policies, typename StackIndexList > L, results, mpl::bool_<has_yield<Policies>::value>());
struct policy_list_postcall< meta::type_list< converter_policy_injector< Index, Policy >, Policies... >, StackIndexList > { }
static void postcall(lua_State* L, int results) {
converter_policy_postcall < Policy, StackIndexList, converter_policy_injector< Index, Policy >::has_postcall >::postcall(L, results); inline int sum_scores(int const* first, int const* last)
policy_list_postcall< meta::type_list< Policies... >, StackIndexList >::postcall(L, results); {
} int result = 0;
};
for (; first != last; ++first)
template< typename StackIndexList > {
struct policy_list_postcall< meta::type_list< >, StackIndexList > { if (*first < 0)
static void postcall(lua_State* /*L*/, int /*results*/) {} return *first;
}; result += *first;
}
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
template< typename... ArgumentConverters > return result;
struct compute_invoke_values { }
using consumed_list = meta::index_list< FooFoo<ArgumentConverters>::consumed_args... >;
using stack_index_list = typename compute_stack_indices< consumed_list, 1 >::type; # define LUABIND_INVOKE_NEXT_ITER(n) \
enum { arity = meta::sum<consumed_list>::value }; typename mpl::next< \
}; BOOST_PP_IF( \
#endif n, BOOST_PP_CAT(iter,BOOST_PP_DEC(n)), first) \
>::type
} # define LUABIND_INVOKE_NEXT_INDEX(n) \
BOOST_PP_IF( \
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS n \
inline int match_deferred(lua_State* L, meta::index_list<>, meta::type_list<>) , BOOST_PP_CAT(index,BOOST_PP_DEC(n)) + \
{ BOOST_PP_CAT(c,BOOST_PP_DEC(n)).consumed_args() \
return 0; , 1 \
} )
template< unsigned int StackIndex0, unsigned int... StackIndices, # define LUABIND_INVOKE_COMPUTE_ARITY(n) + BOOST_PP_CAT(c,n).consumed_args()
typename ArgumentType0, typename... ArgumentTypes,
typename ArgumentConverter0, typename... ArgumentConverters > # define LUABIND_INVOKE_DECLARE_CONVERTER(n) \
int match_deferred(lua_State* L, typedef LUABIND_INVOKE_NEXT_ITER(n) BOOST_PP_CAT(iter,n); \
meta::index_list< StackIndex0, StackIndices... >, typedef typename mpl::deref<BOOST_PP_CAT(iter,n)>::type \
meta::type_list< ArgumentType0, ArgumentTypes... >, BOOST_PP_CAT(a,n); \
ArgumentConverter0& converter0, ArgumentConverters&... converters typedef typename find_conversion_policy<n + 1, Policies>::type \
) BOOST_PP_CAT(p,n); \
{ typename mpl::apply_wrap2< \
const int this_match = converter0.match(L, decorated_type<ArgumentType0>(), StackIndex0); BOOST_PP_CAT(p,n), BOOST_PP_CAT(a,n), lua_to_cpp>::type BOOST_PP_CAT(c,n); \
const int other_match = match_deferred(L, meta::index_list<StackIndices...>(), meta::type_list<ArgumentTypes...>(), converters...); int const BOOST_PP_CAT(index,n) = LUABIND_INVOKE_NEXT_INDEX(n);
return (this_match >= 0) ? // could also sum them all up unconditionally
this_match + match_deferred(L, meta::index_list<StackIndices...>(), meta::type_list<ArgumentTypes...>(), converters...) # define LUABIND_INVOKE_COMPUTE_SCORE(n) \
: no_match; , BOOST_PP_CAT(c,n).match( \
} L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,n)), BOOST_PP_CAT(index,n))
template< typename T, bool isvoid, bool memfun = std::is_member_function_pointer<T>::value > struct do_call_struct; # define LUABIND_INVOKE_ARG(z, n, base) \
BOOST_PP_CAT(c,base(n)).apply( \
template< typename T > L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,base(n))), BOOST_PP_CAT(index,base(n)))
struct do_call_struct< T, true, true /*memfun*/> {
template< typename F, typename ArgumentType0, typename... ArgumentTypes, unsigned int StackIndex0, unsigned int... StackIndices, typename ReturnConverter, typename Argument0Converter, typename... ArgumentConverters > # define LUABIND_INVOKE_CONVERTER_POSTCALL(n) \
static void do_call(lua_State* L, F& f, BOOST_PP_CAT(c,n).converter_postcall( \
meta::index_list<StackIndex0, StackIndices...>, meta::type_list<ArgumentType0, ArgumentTypes...>, L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,n)), BOOST_PP_CAT(index,n));
ReturnConverter& result_converter, Argument0Converter& arg0_converter, ArgumentConverters&... arg_converters
) # define BOOST_PP_ITERATION_PARAMS_1 \
{ (3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
((arg0_converter.to_cpp(L, decorated_type<ArgumentType0>(), StackIndex0)).*f)( # include BOOST_PP_ITERATE()
arg_converters.to_cpp(L, decorated_type<ArgumentTypes>(), StackIndices)...
); # define LUABIND_INVOKE_VOID
} # define BOOST_PP_ITERATION_PARAMS_1 \
}; (3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
# include BOOST_PP_ITERATE()
template< typename T >
struct do_call_struct< T, false, true /*memfun*/> { # undef LUABIND_INVOKE_VOID
template< typename F, typename ArgumentType0, typename... ArgumentTypes, unsigned int StackIndex0, unsigned int... StackIndices, typename ReturnConverter, typename Argument0Converter, typename... ArgumentConverters > # define LUABIND_INVOKE_MEMBER
static void do_call(lua_State* L, F& f, # define BOOST_PP_ITERATION_PARAMS_1 \
meta::index_list<StackIndex0, StackIndices...>, meta::type_list<ArgumentType0, ArgumentTypes...>, (3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
ReturnConverter& result_converter, Argument0Converter& arg0_converter, ArgumentConverters&... arg_converters # include BOOST_PP_ITERATE()
)
{ # define LUABIND_INVOKE_VOID
result_converter.to_lua(L, # define BOOST_PP_ITERATION_PARAMS_1 \
((arg0_converter.to_cpp(L, decorated_type<ArgumentType0>(), StackIndex0)).*f)( (3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
arg_converters.to_cpp(L, decorated_type<ArgumentTypes>(), StackIndices)... # include BOOST_PP_ITERATE()
)
); }} // namespace luabind::detail
}
};
template< typename T >
struct do_call_struct< T, true, false > {
template<
typename F,
typename... ArgumentTypes, unsigned int... StackIndices,
typename ReturnConverter, typename... ArgumentConverters
>
static void do_call(lua_State* L, F& f,
meta::index_list<StackIndices...>, meta::type_list<ArgumentTypes...>,
ReturnConverter& result_converter, ArgumentConverters&... arg_converters)
{
f(arg_converters.to_cpp(L, decorated_type<ArgumentTypes>(), StackIndices)...);
}
};
template< typename T >
struct do_call_struct< T, false, false > {
template<
typename F,
typename... ArgumentTypes, unsigned int... StackIndices,
typename ReturnConverter, typename... ArgumentConverters
>
static void do_call(lua_State* L, F& f,
meta::index_list<StackIndices...>, meta::type_list<ArgumentTypes...>,
ReturnConverter& result_converter, ArgumentConverters&... arg_converters)
{
result_converter.to_lua(L,
f(arg_converters.to_cpp(L, decorated_type<ArgumentTypes>(), StackIndices)...)
);
}
};
template< typename F, typename ReturnType, typename... Arguments,
typename ReturnConverter, typename... ArgumentConverters,
unsigned int Index0, unsigned int... Indices, typename PolicyList
>
int invoke3(lua_State* L, function_object const& self, invoke_context& ctx, F& f,
PolicyList, meta::index_list< Index0, Indices... > index_list, meta::type_list<ReturnType, Arguments...> signature_list,
ReturnConverter return_converter, ArgumentConverters... argument_converters)
{
using invoke_values = typename call_detail_new::compute_invoke_values< ArgumentConverters... >;
using argument_list_type = meta::type_list<Arguments...>;
using argument_index_list = meta::index_list<Indices...>;
int const arguments = lua_gettop(L);
int score = no_match;
if(invoke_values::arity == arguments) {
score = match_deferred(L, typename invoke_values::stack_index_list(), argument_list_type(), argument_converters...);
}
if(score >= 0 && score < ctx.best_score) {
ctx.best_score = score;
ctx.candidates[0] = &self;
ctx.candidate_index = 1;
} else if(score == ctx.best_score) {
ctx.candidates[ctx.candidate_index++] = &self;
}
int results = 0;
if(self.next)
{
results = self.next->call(L, ctx);
}
if(score == ctx.best_score && ctx.candidate_index == 1)
{
do_call_struct<F, std::is_void<ReturnType>::value>::do_call(L, f, typename invoke_values::stack_index_list(), argument_list_type(), return_converter, argument_converters...);
meta::init_order{ (argument_converters.converter_postcall(L, decorated_type<Arguments>(), meta::get< typename invoke_values::stack_index_list, Indices - 1 >::value), 0)... };
results = lua_gettop(L) - invoke_values::arity;
if(has_call_policy<PolicyList, yield_policy>::value) {
results = lua_yield(L, results);
}
// call policiy list postcall
call_detail_new::policy_list_postcall < PolicyList, typename meta::push_front< typename invoke_values::stack_index_list, meta::index<invoke_values::arity> >::type >::postcall(L, results);
}
return results;
}
template< typename F, typename ReturnType, typename... Arguments, unsigned int Index0, unsigned int... Indices, typename PolicyList >
int invoke2(lua_State* L, function_object const& self, invoke_context& ctx, F& f,
meta::type_list<ReturnType, Arguments...> signature, meta::index_list<Index0, Indices...>, PolicyList)
{
using signature_type = meta::type_list<ReturnType, Arguments...>;
using return_converter = specialized_converter_policy_n<0, PolicyList, ReturnType, cpp_to_lua>;
return invoke3(L, self, ctx, f,
PolicyList(), meta::index_list<Index0, Indices...>(), signature,
return_converter(), specialized_converter_policy_n<Indices, PolicyList, Arguments, lua_to_cpp>()...
);
}
template <class F, class Signature, typename... PolicyInjectors>
// boost::bind's operator() is const, std::bind's is not
inline int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f, Signature,
meta::type_list< PolicyInjectors... > const& injectors)
{
return invoke2(L, self, ctx, f, Signature(), typename meta::make_index_range<0, meta::size<Signature>::value>::type(), injectors);
}
#endif
#ifdef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
// VC2013RC doesn't support expanding a template and its member template in one expression, that's why we have to to incrementally build
// the converter list instead of a single combined expansion.
template< typename ArgumentList, typename PolicyList, typename CurrentList = meta::type_list<>, unsigned int Counter = 1 >
struct compute_argument_converter_list;
template< typename Argument0, typename... Arguments, typename PolicyList, typename... CurrentConverters, unsigned int Counter >
struct compute_argument_converter_list< meta::type_list<Argument0, Arguments... >, PolicyList, meta::type_list<CurrentConverters...>, Counter >
{
using converter_type = typename policy_detail::get_converter_policy<Counter, PolicyList>::type;
using this_specialized = typename converter_type::template specialize<Argument0, lua_to_cpp >::type;
using type = typename compute_argument_converter_list<meta::type_list<Arguments...>, PolicyList, meta::type_list<CurrentConverters..., this_specialized>, Counter + 1>::type;
};
template<typename PolicyList, typename... CurrentConverters, unsigned int Counter >
struct compute_argument_converter_list< meta::type_list<>, PolicyList, meta::type_list<CurrentConverters...>, Counter >
{
using type = meta::type_list<CurrentConverters...>;
};
template< typename ConverterList >
struct build_consumed_list;
template< typename... Converters >
struct build_consumed_list< meta::type_list< Converters... > > {
using consumed_list = meta::index_list< call_detail_new::FooFoo<Converters>::consumed_args... >;
};
template< typename SignatureList, typename PolicyList >
struct invoke_traits;
// Specialization for free functions
template< typename ResultType, typename... Arguments, typename PolicyList >
struct invoke_traits< meta::type_list<ResultType, Arguments... >, PolicyList >
{
using signature_list = meta::type_list<ResultType, Arguments...>;
using policy_list = PolicyList;
using result_type = ResultType;
using result_converter = specialized_converter_policy_n<0, PolicyList, result_type, cpp_to_lua >;
using argument_list = meta::type_list<Arguments...>;
using decorated_argument_list = meta::type_list< decorate_type_t<Arguments>... >;
// note that this is 0-based, so whenever you want to fetch from the converter list, you need to add 1
using argument_index_list = typename meta::make_index_range< 0, sizeof...(Arguments) >::type;
using argument_converter_list = typename compute_argument_converter_list<argument_list, PolicyList>::type;
using argument_converter_tuple_type = typename meta::make_tuple<argument_converter_list>::type;
using consumed_list = typename build_consumed_list<argument_converter_list>::consumed_list;
using stack_index_list = typename call_detail_new::compute_stack_indices< consumed_list, 1 >::type;
enum { arity = meta::sum<consumed_list>::value };
};
template< typename StackIndexList, typename SignatureList, unsigned int End = meta::size<SignatureList>::value, unsigned int Index = 1 >
struct match_struct {
template< typename TupleType >
static int match(lua_State* L, TupleType& tuple)
{
const int this_match = std::get<Index - 1>(tuple).match(L, decorate_type_t<typename SignatureList::template at<Index>>(), meta::get<StackIndexList, Index - 1>::value);
return this_match >= 0 ? // could also sum them up unconditionally
this_match + match_struct<StackIndexList, SignatureList, End, Index + 1>::match(L, tuple)
: no_match;
}
};
template< typename StackIndexList, typename SignatureList, unsigned int Index >
struct match_struct< StackIndexList, SignatureList, Index, Index >
{
template< typename TupleType >
static int match(lua_State* /*L*/, TupleType&) {
return 0;
}
};
template< typename PolicyList, typename Signature, typename F >
struct invoke_struct
{
using traits = invoke_traits< Signature, PolicyList >;
template< bool IsMember, bool IsVoid, typename IndexList >
struct call_struct;
template< unsigned int... ArgumentIndices >
struct call_struct< false /*member*/, false /*void*/, meta::index_list<ArgumentIndices...> >
{
static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple)
{
using decorated_list = typename traits::decorated_argument_list;
using stack_indices = typename traits::stack_index_list;
using result_converter = typename traits::result_converter;
result_converter().to_lua(L,
f((std::get<ArgumentIndices>(argument_tuple).to_cpp(L,
typename meta::get<decorated_list, ArgumentIndices>::type(),
meta::get<stack_indices, ArgumentIndices>::value))...
)
);
meta::init_order{
(std::get<ArgumentIndices>(argument_tuple).converter_postcall(L,
typename meta::get<typename traits::decorated_argument_list, ArgumentIndices>::type(),
meta::get<typename traits::stack_index_list, ArgumentIndices>::value), 0)...
};
}
};
template< unsigned int... ArgumentIndices >
struct call_struct< false /*member*/, true /*void*/, meta::index_list<ArgumentIndices...> >
{
static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple)
{
using decorated_list = typename traits::decorated_argument_list;
using stack_indices = typename traits::stack_index_list;
// This prevents unused warnings with empty parameter lists
(void)L;
f(std::get<ArgumentIndices>(argument_tuple).to_cpp(L,
typename meta::get<decorated_list, ArgumentIndices>::type(),
meta::get<stack_indices, ArgumentIndices>::value)...
);
meta::init_order{
(std::get<ArgumentIndices>(argument_tuple).converter_postcall(L,
typename meta::get<typename traits::decorated_argument_list, ArgumentIndices>::type(),
meta::get<typename traits::stack_index_list, ArgumentIndices>::value), 0)...
};
}
};
template< unsigned int ClassIndex, unsigned int... ArgumentIndices >
struct call_struct< true /*member*/, false /*void*/, meta::index_list<ClassIndex, ArgumentIndices...> >
{
static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple)
{
using decorated_list = typename traits::decorated_argument_list;
using stack_indices = typename traits::stack_index_list;
using result_converter = typename traits::result_converter;
auto& object = std::get<0>(argument_tuple).to_cpp(L,
typename meta::get<typename traits::decorated_argument_list, 0>::type(), 1);
result_converter().to_lua(L,
(object.*f)(std::get<ArgumentIndices>(argument_tuple).to_cpp(L,
typename meta::get<decorated_list, ArgumentIndices>::type(),
meta::get<stack_indices, ArgumentIndices>::value)...
)
);
meta::init_order{
(std::get<ArgumentIndices>(argument_tuple).converter_postcall(L,
typename meta::get<typename traits::decorated_argument_list, ArgumentIndices>::type(),
meta::get<typename traits::stack_index_list, ArgumentIndices>::value), 0)...
};
}
};
template< unsigned int ClassIndex, unsigned int... ArgumentIndices >
struct call_struct< true /*member*/, true /*void*/, meta::index_list<ClassIndex, ArgumentIndices...> >
{
static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple)
{
using decorated_list = typename traits::decorated_argument_list;
using stack_indices = typename traits::stack_index_list;
auto& object = std::get<0>(argument_tuple).to_cpp(L, typename meta::get<typename traits::decorated_argument_list, 0>::type(), 1);
(object.*f)(std::get<ArgumentIndices>(argument_tuple).to_cpp(L,
typename meta::get<decorated_list, ArgumentIndices>::type(),
meta::get<stack_indices, ArgumentIndices>::value)...
);
meta::init_order{
(std::get<ArgumentIndices>(argument_tuple).converter_postcall(L,
typename meta::get<typename traits::decorated_argument_list, ArgumentIndices>::type(),
meta::get<typename traits::stack_index_list, ArgumentIndices>::value), 0)...
};
}
};
static int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f) {
int const arguments = lua_gettop(L);
int score = no_match;
// Even match needs the tuple, since pointer_converters buffer the cast result
typename traits::argument_converter_tuple_type converter_tuple;
if(traits::arity == arguments) {
// Things to remember:
// 0 is the perfect match. match > 0 means that objects had to be casted, where the value
// is the total distance of all arguments to their given types (graph distance).
// This is why we can say MaxArguments = 100, MaxDerivationDepth = 100, so no match will be > 100*100=10k and -10k1 absorbs every match.
// This gets rid of the awkward checks during converter match traversal.
using struct_type = match_struct< typename traits::stack_index_list, typename traits::signature_list >;
score = struct_type::match(L, converter_tuple);
}
if(score >= 0 && score < ctx.best_score) {
ctx.best_score = score;
ctx.candidates[0] = &self;
ctx.candidate_index = 1;
} else if(score == ctx.best_score) {
ctx.candidates[ctx.candidate_index++] = &self;
}
int results = 0;
if(self.next)
{
results = self.next->call(L, ctx);
}
if(score == ctx.best_score && ctx.candidate_index == 1)
{
call_struct<
std::is_member_function_pointer<F>::value,
std::is_void<typename traits::result_type>::value,
typename traits::argument_index_list
>::call(L, f, converter_tuple);
results = lua_gettop(L) - traits::arity;
if(has_call_policy<PolicyList, yield_policy>::value) {
results = lua_yield(L, results);
}
call_detail_new::policy_list_postcall < PolicyList, typename meta::push_front< typename traits::stack_index_list, meta::index<traits::arity> >::type >::postcall(L, results);
}
return results;
}
};
template< typename PolicyList, typename Signature, typename F>
inline int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f)
{
return invoke_struct<PolicyList, Signature, F>::invoke(L, self, ctx, f);
}
#endif
}
} // namespace luabind::detail
# endif // LUABIND_CALL2_080911_HPP # endif // LUABIND_CALL2_080911_HPP
#else // BOOST_PP_IS_ITERATING
# ifdef LUABIND_INVOKE_MEMBER
# define N BOOST_PP_INC(BOOST_PP_ITERATION())
# else
# define N BOOST_PP_ITERATION()
# endif
template <class F, class Signature, class Policies>
inline int
# ifdef LUABIND_INVOKE_MEMBER
invoke_member
# else
invoke_normal
# endif
(
lua_State* L, function_object const& self, invoke_context& ctx
, F const& f, Signature, Policies const&, mpl::long_<N>
# ifdef LUABIND_INVOKE_VOID
, mpl::true_
# else
, mpl::false_
# endif
)
{
typedef typename mpl::begin<Signature>::type first;
# ifndef LUABIND_INVOKE_VOID
typedef typename mpl::deref<first>::type result_type;
typedef typename find_conversion_policy<0, Policies>::type result_policy;
typename mpl::apply_wrap2<
result_policy, result_type, cpp_to_lua>::type result_converter;
# endif
# if N > 0
# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_DECLARE_CONVERTER(n)
# define BOOST_PP_LOCAL_LIMITS (0,N-1)
# include BOOST_PP_LOCAL_ITERATE()
# endif
int const arity = 0
# if N > 0
# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_COMPUTE_ARITY(n)
# define BOOST_PP_LOCAL_LIMITS (0,N-1)
# include BOOST_PP_LOCAL_ITERATE()
# endif
;
int const arguments = lua_gettop(L);
int score = -1;
if (arity == arguments)
{
int const scores[] = {
0
# if N > 0
# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_COMPUTE_SCORE(n)
# define BOOST_PP_LOCAL_LIMITS (0,N-1)
# include BOOST_PP_LOCAL_ITERATE()
# endif
};
score = sum_scores(scores + 1, scores + 1 + N);
}
if (score >= 0 && score < ctx.best_score)
{
ctx.best_score = score;
ctx.candidates[0] = &self;
ctx.candidate_index = 1;
}
else if (score == ctx.best_score)
{
ctx.candidates[ctx.candidate_index++] = &self;
}
int results = 0;
if (self.next)
{
results = self.next->call(L, ctx);
}
if (score == ctx.best_score && ctx.candidate_index == 1)
{
# ifndef LUABIND_INVOKE_VOID
result_converter.apply(
L,
# endif
# ifdef LUABIND_INVOKE_MEMBER
(c0.apply(L, LUABIND_DECORATE_TYPE(a0), index0).*f)(
BOOST_PP_ENUM(BOOST_PP_DEC(N), LUABIND_INVOKE_ARG, BOOST_PP_INC)
)
# else
# define LUABIND_INVOKE_IDENTITY(x) x
f(
BOOST_PP_ENUM(N, LUABIND_INVOKE_ARG, LUABIND_INVOKE_IDENTITY)
)
# undef LUABIND_INVOKE_IDENTITY
# endif
# ifndef LUABIND_INVOKE_VOID
)
# endif
;
# if N > 0
# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_CONVERTER_POSTCALL(n)
# define BOOST_PP_LOCAL_LIMITS (0,N-1)
# include BOOST_PP_LOCAL_ITERATE()
# endif
results = maybe_yield(L, lua_gettop(L) - arguments, (Policies*)0);
int const indices[] = {
arguments + results BOOST_PP_ENUM_TRAILING_PARAMS(N, index)
};
policy_list_postcall<Policies>::apply(L, indices);
}
return results;
}
# undef N
#endif

View File

@ -20,175 +20,423 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE. // OR OTHER DEALINGS IN THE SOFTWARE.
#if !BOOST_PP_IS_ITERATING
#ifndef LUABIND_CALL_FUNCTION_HPP_INCLUDED #ifndef LUABIND_CALL_FUNCTION_HPP_INCLUDED
#define LUABIND_CALL_FUNCTION_HPP_INCLUDED #define LUABIND_CALL_FUNCTION_HPP_INCLUDED
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <boost/mpl/if.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/mpl/or.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <luabind/error.hpp> #include <luabind/error.hpp>
#include <luabind/detail/push_to_lua.hpp> #include <luabind/detail/convert_to_lua.hpp>
#include <luabind/detail/pcall.hpp> #include <luabind/detail/pcall.hpp>
#include <luabind/detail/call_shared.hpp>
#include <luabind/detail/stack_utils.hpp>
namespace luabind namespace luabind
{ {
namespace adl { namespace detail
class object; {
}
using adl::object; // if the proxy_function_caller returns non-void
template<class Ret, class Tuple>
class proxy_function_caller
{
// friend class luabind::object;
public:
namespace detail { typedef int(*function_t)(lua_State*, int, int);
template< typename PolicyList, unsigned int pos > proxy_function_caller(
void push_arguments(lua_State* /*L*/) {} lua_State* L
, int params
, function_t fun
, const Tuple args)
: m_state(L)
, m_params(params)
, m_fun(fun)
, m_args(args)
, m_called(false)
{
}
template< typename PolicyList, unsigned int Pos, typename Arg0, typename... Args > proxy_function_caller(const proxy_function_caller& rhs)
void push_arguments(lua_State* L, Arg0&& arg0, Args&&... args) : m_state(rhs.m_state)
{ , m_params(rhs.m_params)
using converter_type = specialized_converter_policy< fetched_converter_policy<Pos, PolicyList>, Arg0, cpp_to_lua >; , m_fun(rhs.m_fun)
converter_type().to_lua(L, unwrapped<Arg0>::get(std::forward<Arg0>(arg0))); , m_args(rhs.m_args)
push_arguments<PolicyList, Pos + 1>(L, std::forward<Args>(args)...); , m_called(rhs.m_called)
} {
rhs.m_called = true;
}
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS ~proxy_function_caller()
template<typename Ret, typename PolicyList, typename... Args, unsigned int... Indices, typename Fn> {
void call_function_impl(lua_State* L, int m_params, Fn fn, std::true_type /* void */, meta::index_list<Indices...>, Args&&... args) if (m_called) return;
{
int top = lua_gettop(L);
push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...); m_called = true;
lua_State* L = m_state;
if(fn(L, sizeof...(Args), 0)) { int top = lua_gettop(L);
assert(lua_gettop(L) == top - m_params + 1);
call_error(L);
}
// pops the return values from the function call
stack_pop pop(L, lua_gettop(L) - top + m_params);
}
template<typename Ret, typename PolicyList, typename... Args, unsigned int... Indices, typename Fn> push_args_from_tuple<1>::apply(L, m_args);
Ret call_function_impl(lua_State* L, int m_params, Fn fn, std::false_type /* void */, meta::index_list<Indices...>, Args&&... args) if (m_fun(L, boost::tuples::length<Tuple>::value, 0))
{ {
int top = lua_gettop(L); assert(lua_gettop(L) == top - m_params + 1);
#ifndef LUABIND_NO_EXCEPTIONS
push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...); throw luabind::error(L);
if(fn(L, sizeof...(Args), 1)) {
assert(lua_gettop(L) == top - m_params + 1);
call_error(L);
}
// pops the return values from the function call
stack_pop pop(L, lua_gettop(L) - top + m_params);
specialized_converter_policy_n<0, PolicyList, Ret, lua_to_cpp> converter;
if(converter.match(L, decorate_type_t<Ret>(), -1) < 0) {
cast_error<Ret>(L);
}
return converter.to_cpp(L, decorate_type_t<Ret>(), -1);
}
#else #else
template<typename Ret, typename PolicyList, typename IndexList, unsigned int NumParams, int(*Function)(lua_State*, int, int), bool IsVoid = std::is_void<Ret>::value> error_callback_fun e = get_error_callback();
struct call_function_struct; if (e) e(L);
template<typename Ret, typename PolicyList, unsigned int NumParams, int(*Function)(lua_State*, int, int), unsigned int... Indices > assert(0 && "the lua function threw an error and exceptions are disabled."
struct call_function_struct< Ret, PolicyList, meta::index_list<Indices...>, NumParams, Function, true /* void */ > " If you want to handle the error you can use luabind::set_error_callback()");
{ std::terminate();
template< typename... Args >
static void call(lua_State* L, Args&&... args) {
int top = lua_gettop(L);
push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...); #endif
if(Function(L, sizeof...(Args), 0)) {
if(Function == &detail::pcall) {
assert(lua_gettop(L) == static_cast<int>(top - NumParams + 1));
} }
call_error(L);
// pops the return values from the function call
stack_pop pop(L, lua_gettop(L) - top + m_params);
} }
// pops the return values from the function call
stack_pop pop(L, lua_gettop(L) - top + NumParams);
}
};
template<typename Ret, typename PolicyList, unsigned int NumParams, int(*Function)(lua_State*, int, int), unsigned int... Indices > operator Ret()
struct call_function_struct< Ret, PolicyList, meta::index_list<Indices...>, NumParams, Function, false /* void */ > {
{ typename mpl::apply_wrap2<default_policy,Ret,lua_to_cpp>::type converter;
template< typename... Args >
static Ret call(lua_State* L, Args&&... args) {
int top = lua_gettop(L);
push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...); m_called = true;
lua_State* L = m_state;
if(Function(L, sizeof...(Args), 1)) { int top = lua_gettop(L);
if(Function == &detail::pcall) {
assert(lua_gettop(L) == static_cast<int>(top - NumParams + 1)); push_args_from_tuple<1>::apply(L, m_args);
if (m_fun(L, boost::tuples::length<Tuple>::value, 1))
{
assert(lua_gettop(L) == top - m_params + 1);
#ifndef LUABIND_NO_EXCEPTIONS
throw luabind::error(L);
#else
error_callback_fun e = get_error_callback();
if (e) e(L);
assert(0 && "the lua function threw an error and exceptions are disabled."
" If you want to handle the error you can use luabind::set_error_callback()");
std::terminate();
#endif
} }
call_error(L);
}
// pops the return values from the function call
stack_pop pop(L, lua_gettop(L) - top + NumParams);
specialized_converter_policy_n<0, PolicyList, Ret, lua_to_cpp> converter; // pops the return values from the function call
if(converter.match(L, decorate_type_t<Ret>(), -1) < 0) { stack_pop pop(L, lua_gettop(L) - top + m_params);
cast_error<Ret>(L);
#ifndef LUABIND_NO_ERROR_CHECKING
if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0)
{
#ifndef LUABIND_NO_EXCEPTIONS
throw cast_failed(L, typeid(Ret));
#else
cast_failed_callback_fun e = get_cast_failed_callback();
if (e) e(L, typeid(Ret));
assert(0 && "the lua function's return value could not be converted."
" If you want to handle the error you can use luabind::set_error_callback()");
std::terminate();
#endif
}
#endif
return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1);
} }
return converter.to_cpp(L, decorate_type_t<Ret>(), -1); template<class Policies>
} Ret operator[](const Policies& p)
}; {
#endif typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy;
} typename mpl::apply_wrap2<converter_policy,Ret,lua_to_cpp>::type converter;
template<class R, typename PolicyList = no_policies, typename... Args> m_called = true;
R call_pushed_function(lua_State* L, Args&&... args) lua_State* L = m_state;
{
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS int top = lua_gettop(L);
return detail::call_function_impl<R, PolicyList>(L, 1, &detail::pcall, std::is_void<R>(), meta::index_range<1, sizeof...(Args)+1>(), std::forward<Args>(args)...);
detail::push_args_from_tuple<1>::apply(L, m_args, p);
if (m_fun(L, boost::tuples::length<Tuple>::value, 1))
{
assert(lua_gettop(L) == top - m_params + 1);
#ifndef LUABIND_NO_EXCEPTIONS
throw error(L);
#else #else
return detail::call_function_struct<R, PolicyList, meta::index_range<1, sizeof...(Args)+1>, 1, &detail::pcall >::call(L, std::forward<Args>(args)...); error_callback_fun e = get_error_callback();
if (e) e(L);
assert(0 && "the lua function threw an error and exceptions are disabled."
" If you want to handle the error you can use luabind::set_error_callback()");
std::terminate();
#endif #endif
} }
template<class R, typename PolicyList = no_policies, typename... Args> // pops the return values from the function call
R call_function(lua_State* L, const char* name, Args&&... args) stack_pop pop(L, lua_gettop(L) - top + m_params);
{
assert(name && "luabind::call_function() expects a function name");
lua_getglobal(L, name);
return call_pushed_function<R, PolicyList>(L, std::forward<Args>(args)...);
}
template<class R, typename PolicyList = no_policies, typename... Args> #ifndef LUABIND_NO_ERROR_CHECKING
R resume_pushed_function(lua_State* L, Args&&... args)
{ if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0)
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS {
return detail::call_function_impl<R, PolicyList>(L, 1, &detail::resume_impl, std::is_void<R>(), meta::index_range<1, sizeof...(Args)+1>(), std::forward<Args>(args)...); #ifndef LUABIND_NO_EXCEPTIONS
throw cast_failed(L, typeid(Ret));
#else #else
return detail::call_function_struct<R, PolicyList, meta::index_range<1, sizeof...(Args)+1>, 1, &detail::resume_impl >::call(L, std::forward<Args>(args)...); cast_failed_callback_fun e = get_cast_failed_callback();
if (e) e(L, typeid(Ret));
assert(0 && "the lua function's return value could not be converted."
" If you want to handle the error you can use luabind::set_error_callback()");
std::terminate();
#endif #endif
} }
#endif
return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1);
}
template<class R, typename PolicyList = no_policies, typename... Args> private:
R resume_function(lua_State* L, const char* name, Args&&... args)
{
assert(name && "luabind::resume_function() expects a function name");
lua_getglobal(L, name);
return resume_pushed_function<R, PolicyList>(L, std::forward<Args>(args)...);
}
template<class R, typename PolicyList = no_policies, typename... Args> lua_State* m_state;
R resume(lua_State* L, Args&&... args) int m_params;
{ function_t m_fun;
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS Tuple m_args;
return detail::call_function_impl<R, PolicyList>(L, 0, &detail::resume_impl, std::is_void<R>(), meta::index_range<1, sizeof...(Args)+1>(), std::forward<Args>(args)...); mutable bool m_called;
};
// if the proxy_member_caller returns void
template<class Tuple>
class proxy_function_void_caller
{
friend class luabind::object;
public:
typedef int(*function_t)(lua_State*, int, int);
proxy_function_void_caller(
lua_State* L
, int params
, function_t fun
, const Tuple args)
: m_state(L)
, m_params(params)
, m_fun(fun)
, m_args(args)
, m_called(false)
{
}
proxy_function_void_caller(const proxy_function_void_caller& rhs)
: m_state(rhs.m_state)
, m_params(rhs.m_params)
, m_fun(rhs.m_fun)
, m_args(rhs.m_args)
, m_called(rhs.m_called)
{
rhs.m_called = true;
}
~proxy_function_void_caller()
{
if (m_called) return;
m_called = true;
lua_State* L = m_state;
int top = lua_gettop(L);
push_args_from_tuple<1>::apply(L, m_args);
if (m_fun(L, boost::tuples::length<Tuple>::value, 0))
{
assert(lua_gettop(L) == top - m_params + 1);
#ifndef LUABIND_NO_EXCEPTIONS
throw luabind::error(L);
#else #else
return detail::call_function_struct<R, PolicyList, meta::index_range<1, sizeof...(Args)+1>, 0, &detail::resume_impl >::call(L, std::forward<Args>(args)...); error_callback_fun e = get_error_callback();
if (e) e(L);
assert(0 && "the lua function threw an error and exceptions are disabled."
" If you want to handle the error you can use luabind::set_error_callback()");
std::terminate();
#endif #endif
}
// pops the return values from the function call
stack_pop pop(L, lua_gettop(L) - top + m_params);
}
template<class Policies>
void operator[](const Policies& p)
{
m_called = true;
lua_State* L = m_state;
int top = lua_gettop(L);
detail::push_args_from_tuple<1>::apply(L, m_args, p);
if (m_fun(L, boost::tuples::length<Tuple>::value, 0))
{
assert(lua_gettop(L) == top - m_params + 1);
#ifndef LUABIND_NO_EXCEPTIONS
throw error(L);
#else
error_callback_fun e = get_error_callback();
if (e) e(L);
assert(0 && "the lua function threw an error and exceptions are disabled."
" If you want to handle the error you can use luabind::set_error_callback()");
std::terminate();
#endif
}
// pops the return values from the function call
stack_pop pop(L, lua_gettop(L) - top + m_params);
}
private:
lua_State* m_state;
int m_params;
function_t m_fun;
Tuple m_args;
mutable bool m_called;
};
} }
#define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/call_function.hpp>, 1))
#include BOOST_PP_ITERATE()
} }
#endif // LUABIND_CALL_FUNCTION_HPP_INCLUDED #endif // LUABIND_CALL_FUNCTION_HPP_INCLUDED
#else
#if BOOST_PP_ITERATION_FLAGS() == 1
#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
template<class Ret BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
typename boost::mpl::if_<boost::is_void<Ret>
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type
call_function(lua_State* L, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) )
{
assert(name && "luabind::call_function() expects a function name");
typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
#if BOOST_PP_ITERATION() == 0
tuple_t args;
#else
tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
#endif
typedef typename boost::mpl::if_<boost::is_void<Ret>
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type proxy_type;
lua_getglobal(L, name);
return proxy_type(L, 1, &detail::pcall, args);
}
template<class Ret BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
typename boost::mpl::if_<boost::is_void<Ret>
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type
call_function(luabind::object const& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) )
{
typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
#if BOOST_PP_ITERATION() == 0
tuple_t args;
#else
tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
#endif
typedef typename boost::mpl::if_<boost::is_void<Ret>
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type proxy_type;
obj.push(obj.interpreter());
return proxy_type(obj.interpreter(), 1, &detail::pcall, args);
}
template<class Ret BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
typename boost::mpl::if_<boost::is_void<Ret>
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type
resume_function(lua_State* L, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) )
{
assert(name && "luabind::resume_function() expects a function name");
typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
#if BOOST_PP_ITERATION() == 0
tuple_t args;
#else
tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
#endif
typedef typename boost::mpl::if_<boost::is_void<Ret>
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type proxy_type;
lua_getglobal(L, name);
return proxy_type(L, 1, &detail::resume_impl, args);
}
template<class Ret BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
typename boost::mpl::if_<boost::is_void<Ret>
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type
resume_function(luabind::object const& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) )
{
typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
#if BOOST_PP_ITERATION() == 0
tuple_t args;
#else
tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
#endif
typedef typename boost::mpl::if_<boost::is_void<Ret>
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type proxy_type;
obj.push(obj.interpreter());
return proxy_type(obj.interpreter(), 1, &detail::resume_impl, args);
}
template<class Ret BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
typename boost::mpl::if_<boost::is_void<Ret>
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type
resume(lua_State* L BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) )
{
typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
#if BOOST_PP_ITERATION() == 0
tuple_t args;
#else
tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
#endif
typedef typename boost::mpl::if_<boost::is_void<Ret>
, luabind::detail::proxy_function_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
, luabind::detail::proxy_function_caller<Ret, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type proxy_type;
return proxy_type(L, 0, &detail::resume_impl, args);
}
#undef LUABIND_OPERATOR_PARAMS
#undef LUABIND_TUPLE_PARAMS
#endif
#endif

View File

@ -20,82 +20,325 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE. // OR OTHER DEALINGS IN THE SOFTWARE.
#if !BOOST_PP_IS_ITERATING
#ifndef LUABIND_CALL_MEMBER_HPP_INCLUDED #ifndef LUABIND_CALL_MEMBER_HPP_INCLUDED
#define LUABIND_CALL_MEMBER_HPP_INCLUDED #define LUABIND_CALL_MEMBER_HPP_INCLUDED
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/detail/push_to_lua.hpp> #include <luabind/detail/convert_to_lua.hpp>
#include <luabind/detail/pcall.hpp> #include <luabind/detail/pcall.hpp>
#include <luabind/error.hpp> #include <luabind/error.hpp>
#include <luabind/detail/stack_utils.hpp> #include <luabind/detail/stack_utils.hpp>
#include <luabind/detail/call_shared.hpp> #include <luabind/object.hpp> // TODO: REMOVE DEPENDENCY
#include <luabind/object.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/facilities/expand.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/mpl/apply_wrap.hpp>
namespace luabind namespace luabind
{ {
using adl::object; namespace detail
{
namespace detail { namespace mpl = boost::mpl;
template<class R, typename PolicyList, unsigned int... Indices, typename... Args> // if the proxy_member_caller returns non-void
R call_member_impl(lua_State* L, std::true_type /*void*/, meta::index_list<Indices...>, Args&&... args) template<class Ret, class Tuple>
{ class proxy_member_caller
// don't count the function and self-reference {
// since those will be popped by pcall // friend class luabind::object;
int top = lua_gettop(L) - 2; public:
// pcall will pop the function and self reference proxy_member_caller(lua_State* L_, const Tuple args)
// and all the parameters : L(L_)
, m_args(args)
, m_called(false)
{
}
proxy_member_caller(const proxy_member_caller& rhs)
: L(rhs.L)
, m_args(rhs.m_args)
, m_called(rhs.m_called)
{
rhs.m_called = true;
}
~proxy_member_caller()
{
if (m_called) return;
m_called = true;
// don't count the function and self-reference
// since those will be popped by pcall
int top = lua_gettop(L) - 2;
// pcall will pop the function and self reference
// and all the parameters
push_args_from_tuple<1>::apply(L, m_args);
if (pcall(L, boost::tuples::length<Tuple>::value + 1, 0))
{
assert(lua_gettop(L) == top + 1);
#ifndef LUABIND_NO_EXCEPTIONS
throw luabind::error(L);
#else
error_callback_fun e = get_error_callback();
if (e) e(L);
assert(0 && "the lua function threw an error and exceptions are disabled."
"If you want to handle this error use luabind::set_error_callback()");
std::terminate();
#endif
}
// pops the return values from the function
stack_pop pop(L, lua_gettop(L) - top);
}
operator Ret()
{
typename mpl::apply_wrap2<default_policy,Ret,lua_to_cpp>::type converter;
m_called = true;
// don't count the function and self-reference
// since those will be popped by pcall
int top = lua_gettop(L) - 2;
// pcall will pop the function and self reference
// and all the parameters
push_args_from_tuple<1>::apply(L, m_args);
if (pcall(L, boost::tuples::length<Tuple>::value + 1, 1))
{
assert(lua_gettop(L) == top + 1);
#ifndef LUABIND_NO_EXCEPTIONS
throw luabind::error(L);
#else
error_callback_fun e = get_error_callback();
if (e) e(L);
assert(0 && "the lua function threw an error and exceptions are disabled."
"If you want to handle this error use luabind::set_error_callback()");
std::terminate();
#endif
}
// pops the return values from the function
stack_pop pop(L, lua_gettop(L) - top);
#ifndef LUABIND_NO_ERROR_CHECKING
if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0)
{
assert(lua_gettop(L) == top + 1);
#ifndef LUABIND_NO_EXCEPTIONS
throw cast_failed(L, typeid(Ret));
#else
cast_failed_callback_fun e = get_cast_failed_callback();
if (e) e(L, typeid(Ret));
assert(0 && "the lua function's return value could not be converted."
"If you want to handle this error use luabind::set_error_callback()");
std::terminate();
#endif
}
#endif
return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1);
}
template<class Policies>
Ret operator[](const Policies& p)
{
typedef typename find_conversion_policy<0, Policies>::type converter_policy;
typename mpl::apply_wrap2<converter_policy,Ret,lua_to_cpp>::type converter;
m_called = true;
// don't count the function and self-reference
// since those will be popped by pcall
int top = lua_gettop(L) - 2;
// pcall will pop the function and self reference
// and all the parameters
detail::push_args_from_tuple<1>::apply(L, m_args, p);
if (pcall(L, boost::tuples::length<Tuple>::value + 1, 1))
{
assert(lua_gettop(L) == top + 1);
#ifndef LUABIND_NO_EXCEPTIONS
throw error(L);
#else
error_callback_fun e = get_error_callback();
if (e) e(L);
assert(0 && "the lua function threw an error and exceptions are disabled."
"If you want to handle this error use luabind::set_error_callback()");
std::terminate();
#endif
}
// pops the return values from the function
stack_pop pop(L, lua_gettop(L) - top);
#ifndef LUABIND_NO_ERROR_CHECKING
if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0)
{
assert(lua_gettop(L) == top + 1);
#ifndef LUABIND_NO_EXCEPTIONS
throw cast_failed(L, typeid(Ret));
#else
cast_failed_callback_fun e = get_cast_failed_callback();
if (e) e(L, typeid(Ret));
assert(0 && "the lua function's return value could not be converted."
"If you want to handle this error use luabind::set_error_callback()");
std::terminate();
#endif
}
#endif
return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1);
}
private:
lua_State* L;
Tuple m_args;
mutable bool m_called;
meta::init_order{ (
specialized_converter_policy_n<Indices, PolicyList, typename unwrapped<Args>::type, cpp_to_lua>().to_lua(L, unwrapped<Args>::get(std::forward<Args>(args))), 0)...
}; };
if(pcall(L, sizeof...(Args)+1, 0)) // if the proxy_member_caller returns void
template<class Tuple>
class proxy_member_void_caller
{ {
assert(lua_gettop(L) == top + 1); friend class luabind::object;
call_error(L); public:
}
// pops the return values from the function
stack_pop pop(L, lua_gettop(L) - top);
}
template<class R, typename PolicyList, unsigned int... Indices, typename... Args> proxy_member_void_caller(lua_State* L_, const Tuple args)
R call_member_impl(lua_State* L, std::false_type /*void*/, meta::index_list<Indices...>, Args&&... args) : L(L_)
{ , m_args(args)
// don't count the function and self-reference , m_called(false)
// since those will be popped by pcall {
int top = lua_gettop(L) - 2; }
// pcall will pop the function and self reference proxy_member_void_caller(const proxy_member_void_caller& rhs)
// and all the parameters : L(rhs.L)
, m_args(rhs.m_args)
, m_called(rhs.m_called)
{
rhs.m_called = true;
}
~proxy_member_void_caller()
{
if (m_called) return;
m_called = true;
// don't count the function and self-reference
// since those will be popped by pcall
int top = lua_gettop(L) - 2;
// pcall will pop the function and self reference
// and all the parameters
push_args_from_tuple<1>::apply(L, m_args);
if (pcall(L, boost::tuples::length<Tuple>::value + 1, 0))
{
assert(lua_gettop(L) == top + 1);
#ifndef LUABIND_NO_EXCEPTIONS
throw luabind::error(L);
#else
error_callback_fun e = get_error_callback();
if (e) e(L);
assert(0 && "the lua function threw an error and exceptions are disabled."
"If you want to handle this error use luabind::set_error_callback()");
std::terminate();
#endif
}
// pops the return values from the function
stack_pop pop(L, lua_gettop(L) - top);
}
template<class Policies>
void operator[](const Policies& p)
{
m_called = true;
// don't count the function and self-reference
// since those will be popped by pcall
int top = lua_gettop(L) - 2;
// pcall will pop the function and self reference
// and all the parameters
detail::push_args_from_tuple<1>::apply(L, m_args, p);
if (pcall(L, boost::tuples::length<Tuple>::value + 1, 0))
{
assert(lua_gettop(L) == top + 1);
#ifndef LUABIND_NO_EXCEPTIONS
throw error(L);
#else
error_callback_fun e = get_error_callback();
if (e) e(L);
assert(0 && "the lua function threw an error and exceptions are disabled."
"If you want to handle this error use luabind::set_error_callback()");
std::terminate();
#endif
}
// pops the return values from the function
stack_pop pop(L, lua_gettop(L) - top);
}
private:
lua_State* L;
Tuple m_args;
mutable bool m_called;
meta::init_order{ (
specialized_converter_policy_n<Indices, PolicyList, typename unwrapped<Args>::type, cpp_to_lua>().to_lua(L, unwrapped<Args>::get(std::forward<Args>(args))), 0)...
}; };
if(pcall(L, sizeof...(Args)+1, 1))
{
assert(lua_gettop(L) == top + 1);
call_error(L);
}
// pops the return values from the function
stack_pop pop(L, lua_gettop(L) - top);
specialized_converter_policy_n<0, PolicyList, R, lua_to_cpp> converter;
if(converter.match(L, decorate_type_t<R>(), -1) < 0) {
cast_error<R>(L);
}
return converter.to_cpp(L, decorate_type_t<R>(), -1);
}
} // detail } // detail
template<class R, typename PolicyList = no_policies, typename... Args> #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/call_member.hpp>, 1))
R call_member(object const& obj, const char* name, Args&&... args) #include BOOST_PP_ITERATE()
}
#endif // LUABIND_CALL_MEMBER_HPP_INCLUDED
#else
#if BOOST_PP_ITERATION_FLAGS() == 1
#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
template<class R BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
typename boost::mpl::if_<boost::is_void<R>
, luabind::detail::proxy_member_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
, luabind::detail::proxy_member_caller<R, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type
call_member(object const& obj, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _))
{ {
typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
#if BOOST_PP_ITERATION() == 0
tuple_t args;
#else
tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
#endif
typedef typename boost::mpl::if_<boost::is_void<R>
, luabind::detail::proxy_member_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
, luabind::detail::proxy_member_caller<R, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type proxy_type;
// this will be cleaned up by the proxy object // this will be cleaned up by the proxy object
// once the call has been made // once the call has been made
@ -111,17 +354,12 @@ namespace luabind
// now the function and self objects // now the function and self objects
// are on the stack. These will both // are on the stack. These will both
// be popped by pcall // be popped by pcall
return proxy_type(obj.interpreter(), args);
return detail::call_member_impl<R, PolicyList>(obj.interpreter(), std::is_void<R>(), meta::index_range<1, sizeof...(Args)+1>(), std::forward<Args>(args)...);
} }
template <class R, typename... Args> #undef LUABIND_OPERATOR_PARAMS
R call_member(wrap_base const* self, char const* fn, Args&&... args) #undef LUABIND_TUPLE_PARAMS
{
return self->call<R>(fn, std::forward<Args>(args)...);
}
} #endif
#endif
#endif // LUABIND_CALL_MEMBER_HPP_INCLUDED

View File

@ -0,0 +1,66 @@
// Copyright (c) 2004 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#define N BOOST_PP_ITERATION()
#define LUABIND_UNWRAP_PARAMETER(z, n, _) \
typename detail::unwrap_parameter_type<T, BOOST_PP_CAT(A, n)>::type \
BOOST_PP_CAT(_, n)
template<class Self BOOST_PP_ENUM_TRAILING_PARAMS(N, class A)>
struct BOOST_PP_CAT(call_operator, N)
: detail::operator_<
BOOST_PP_CAT(call_operator, N)<
Self BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
>
>
{
BOOST_PP_CAT(call_operator, N)(int) {}
template<class T, class Policies>
struct apply
{
static void execute(
lua_State* L
, typename detail::unwrap_parameter_type<T, Self>::type self
BOOST_PP_ENUM_TRAILING(N, LUABIND_UNWRAP_PARAMETER, _)
)
{
using namespace detail;
operator_result(
L
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
, self(BOOST_PP_ENUM_PARAMS(N, _))
#else
, (self(BOOST_PP_ENUM_PARAMS(N, _)), detail::operator_void_return())
#endif
, (Policies*)0
);
}
};
static char const* name() { return "__call"; }
};
#undef LUABIND_UNWRAP_PARAMETER
#undef N

View File

@ -1,113 +0,0 @@
// This has been stripped from boost minus the compatibility for borland etc.
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
// See http://www.boost.org/libs/utility for most recent version including documentation.
// call_traits: defines typedefs for function usage
// (see libs/utility/call_traits.htm)
/* Release notes:
23rd July 2000:
Fixed array specialization. (JM)
Added Borland specific fixes for reference types
(issue raised by Steve Cleary).
*/
#ifndef LUABIND_CALL_TRAITS_HPP_INCLUDED
#define LUABIND_CALL_TRAITS_HPP_INCLUDED
namespace luabind {
namespace detail {
template <typename T, bool small_>
struct ct_imp2
{
using param_type = const T&;
};
template <typename T>
struct ct_imp2<T, true>
{
using param_type = const T;
};
template <typename T, bool isp, bool b1, bool b2>
struct ct_imp
{
using param_type = const T&;
};
template <typename T, bool isp, bool b2>
struct ct_imp<T, isp, true, b2>
{
using param_type = typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type;
};
template <typename T, bool isp, bool b1>
struct ct_imp<T, isp, b1, true>
{
using param_type = typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type;
};
template <typename T, bool b1, bool b2>
struct ct_imp<T, true, b1, b2>
{
using param_type = const T;
};
template <typename T>
struct call_traits
{
public:
using value_type = T;
using reference = T&;
using const_reference = const T&;
using param_type = typename ct_imp<
T,
std::is_pointer<T>::value,
std::is_integral<T>::value || std::is_floating_point<T>::value,
std::is_enum<T>::value
>::param_type;
};
template <typename T>
struct call_traits<T&>
{
using value_type = T&;
using reference = T&;
using const_reference = const T&;
using param_type = T&;
};
template <typename T, std::size_t N>
struct call_traits<T[N]>
{
private:
using array_type = T[N];
public:
using value_type = const T*;
using reference = array_type&;
using const_reference = const array_type&;
using param_type = const T* const;
};
template <typename T, std::size_t N>
struct call_traits<const T[N]>
{
private:
using array_type = const T[N];
public:
using value_type = const T*;
using reference = array_type&;
using const_reference = const array_type&;
using param_type = const T* const;
};
}
}
#endif

View File

@ -0,0 +1,89 @@
// Copyright (c) 2004 Daniel Wallin
// 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 CLASS_CACHE_040218_HPP
#define CLASS_CACHE_040218_HPP
#include <luabind/prefix.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/add_const.hpp>
namespace luabind { namespace detail {
#ifdef LUABIND_NOT_THREADSAFE
class class_rep;
template<class T>
struct class_cache_impl
{
static lua_State* state;
static class_rep* class_;
};
template<class T>
lua_State* class_cache_impl<T>::state = 0;
template<class T>
class_rep* class_cache_impl<T>::class_ = 0;
template<class T>
struct class_cache
: class_cache_impl<
typename boost::add_reference<
typename boost::add_const<
T
>::type
>::type
>
{
};
template<class T>
class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0)
{
if (class_cache<T>::state != L)
{
class_cache<T>::state = L;
class_registry* registry = class_registry::get_registry(L);
class_cache<T>::class_ = registry->find_class(typeid(T));
}
return class_cache<T>::class_;
}
#else
template<class T>
class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0)
{
class_registry* registry = class_registry::get_registry(L);
return registry->find_class(typeid(T));
}
#endif
}} // namespace luabind::detail
#endif // CLASS_CACHE_040218_HPP

View File

@ -30,58 +30,56 @@
#include <luabind/open.hpp> #include <luabind/open.hpp>
#include <luabind/typeid.hpp> #include <luabind/typeid.hpp>
namespace luabind { namespace luabind { namespace detail
namespace detail { {
class class_rep;
class class_rep; struct LUABIND_API class_registry
{
class_registry(lua_State* L);
struct LUABIND_API class_registry static class_registry* get_registry(lua_State* L);
{
class_registry(lua_State* L);
static class_registry* get_registry(lua_State* L); int cpp_instance() const { return m_instance_metatable; }
int cpp_class() const { return m_cpp_class_metatable; }
int cpp_instance() const { return m_instance_metatable; } int lua_instance() const { return m_instance_metatable; }
int cpp_class() const { return m_cpp_class_metatable; } int lua_class() const { return m_lua_class_metatable; }
int lua_function() const { return m_lua_function_metatable; }
int lua_instance() const { return m_instance_metatable; } void add_class(type_id const& info, class_rep* crep);
int lua_class() const { return m_lua_class_metatable; }
int lua_function() const { return m_lua_function_metatable; }
void add_class(type_id const& info, class_rep* crep); class_rep* find_class(type_id const& info) const;
class_rep* find_class(type_id const& info) const; std::map<type_id, class_rep*> const& get_classes() const
{
return m_classes;
}
std::map<type_id, class_rep*> const& get_classes() const private:
{
return m_classes;
}
private: std::map<type_id, class_rep*> m_classes;
std::map<type_id, class_rep*> m_classes; // this is a lua reference that points to the lua table
// that is to be used as meta table for all C++ class
// instances. It is a kind of v-table.
int m_instance_metatable;
// this is a lua reference that points to the lua table // this is a lua reference to the metatable to be used
// that is to be used as meta table for all C++ class // for all classes defined in C++.
// instances. It is a kind of v-table. int m_cpp_class_metatable;
int m_instance_metatable;
// this is a lua reference to the metatable to be used // this is a lua reference to the metatable to be used
// for all classes defined in C++. // for all classes defined in lua
int m_cpp_class_metatable; int m_lua_class_metatable;
// this is a lua reference to the metatable to be used // this metatable only contains a destructor
// for all classes defined in lua // for luabind::Detail::free_functions::function_rep
int m_lua_class_metatable; int m_lua_function_metatable;
// this metatable only contains a destructor };
// for luabind::Detail::free_functions::function_rep
int m_lua_function_metatable;
}; }}
}
}
#endif // LUABIND_CLASS_REGISTRY_HPP_INCLUDED #endif // LUABIND_CLASS_REGISTRY_HPP_INCLUDED

View File

@ -1,4 +1,4 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"), // copy of this software and associated documentation files (the "Software"),
@ -24,12 +24,16 @@
#ifndef LUABIND_CLASS_REP_HPP_INCLUDED #ifndef LUABIND_CLASS_REP_HPP_INCLUDED
#define LUABIND_CLASS_REP_HPP_INCLUDED #define LUABIND_CLASS_REP_HPP_INCLUDED
#include <boost/limits.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/lua_include.hpp> #include <luabind/lua_include.hpp>
#include <luabind/detail/object_rep.hpp>
#include <luabind/detail/garbage_collector.hpp> #include <luabind/detail/garbage_collector.hpp>
#include <luabind/detail/operator_id.hpp> #include <luabind/detail/operator_id.hpp>
#include <luabind/detail/class_registry.hpp> #include <luabind/detail/class_registry.hpp>
@ -39,174 +43,171 @@
#include <luabind/typeid.hpp> #include <luabind/typeid.hpp>
#include <luabind/detail/ref.hpp> #include <luabind/detail/ref.hpp>
namespace luabind { namespace luabind { namespace detail
namespace detail { {
LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
struct class_registration; struct class_registration;
struct conversion_storage; struct conversion_storage;
// This function is used as a tag to identify "properties". // This function is used as a tag to identify "properties".
LUABIND_API int property_tag(lua_State*); LUABIND_API int property_tag(lua_State*);
// this is class-specific information, poor man's vtable // this is class-specific information, poor man's vtable
// this is allocated statically (removed by the compiler) // this is allocated statically (removed by the compiler)
// a pointer to this structure is stored in the lua tables' // a pointer to this structure is stored in the lua tables'
// metatable with the name __classrep // metatable with the name __classrep
// it is used when matching parameters to function calls // it is used when matching parameters to function calls
// to determine possible implicit casts // to determine possible implicit casts
// it is also used when finding the best match for overloaded // it is also used when finding the best match for overloaded
// methods // methods
class cast_graph; class cast_graph;
class class_id_map; class class_id_map;
class LUABIND_API class_rep class LUABIND_API class_rep
{
friend struct class_registration;
friend int super_callback(lua_State*);
//TODO: avoid the lua-prefix
friend int lua_class_gettable(lua_State*);
friend int lua_class_settable(lua_State*);
friend int static_class_gettable(lua_State*);
public:
enum class_type
{ {
friend struct class_registration; cpp_class = 0,
friend int super_callback(lua_State*); lua_class = 1
//TODO: avoid the lua-prefix
friend int lua_class_gettable(lua_State*);
friend int lua_class_settable(lua_State*);
friend int static_class_gettable(lua_State*);
public:
enum class_type
{
cpp_class = 0,
lua_class = 1
};
// EXPECTS THE TOP VALUE ON THE LUA STACK TO
// BE THE USER DATA WHERE THIS CLASS IS BEING
// INSTANTIATED!
class_rep(type_id const& type
, const char* name
, lua_State* L
);
// used when creating a lua class
// EXPECTS THE TOP VALUE ON THE LUA STACK TO
// BE THE USER DATA WHERE THIS CLASS IS BEING
// INSTANTIATED!
class_rep(lua_State* L, const char* name);
~class_rep();
std::pair<void*, void*> allocate(lua_State* L) const;
// this is called as metamethod __call on the class_rep.
static int constructor_dispatcher(lua_State* L);
struct base_info
{
int pointer_offset; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance)
class_rep* base;
};
void add_base_class(const base_info& binfo);
const std::vector<base_info>& bases() const throw() { return m_bases; }
void set_type(type_id const& t) { m_type = t; }
type_id const& type() const throw() { return m_type; }
const char* name() const throw() { return m_name; }
// the lua reference to the metatable for this class' instances
int metatable_ref() const throw() { return m_instance_metatable; }
void get_table(lua_State* L) const { m_table.push(L); }
void get_default_table(lua_State* L) const { m_default_table.push(L); }
class_type get_class_type() const { return m_class_type; }
void add_static_constant(const char* name, int val);
static int super_callback(lua_State* L);
static int lua_settable_dispatcher(lua_State* L);
// called from the metamethod for __index
// obj is the object pointer
static int static_class_gettable(lua_State* L);
bool has_operator_in_lua(lua_State*, int id);
cast_graph const& casts() const
{
return *m_casts;
}
class_id_map const& classes() const
{
return *m_classes;
}
private:
// Code common to both constructors
void shared_init(lua_State * L);
void cache_operators(lua_State*);
// this is a pointer to the type_info structure for
// this type
// warning: this may be a problem when using dll:s, since
// typeid() may actually return different pointers for the same
// type.
type_id m_type;
// a list of info for every class this class derives from
// the information stored here is sufficient to do
// type casts to the base classes
std::vector<base_info> m_bases;
// the class' name (as given when registered to lua with class_)
const char* m_name;
// a reference to this structure itself. Since this struct
// is kept inside lua (to let lua collect it when lua_close()
// is called) we need to lock it to prevent collection.
// the actual reference is not currently used.
detail::lua_reference m_self_ref;
// this should always be used when accessing
// members in instances of a class.
// this table contains c closures for all
// member functions in this class, they
// may point to both static and virtual functions
handle m_table;
// this table contains default implementations of the
// virtual functions in m_table.
handle m_default_table;
// the type of this class.. determines if it's written in c++ or lua
class_type m_class_type;
// this is a lua reference that points to the lua table
// that is to be used as meta table for all instances
// of this class.
int m_instance_metatable;
std::map<const char*, int, ltstr> m_static_constants;
// the first time an operator is invoked
// we check the associated lua table
// and cache the result
int m_operator_cache;
cast_graph* m_casts;
class_id_map* m_classes;
}; };
LUABIND_API bool is_class_rep(lua_State* L, int index); // EXPECTS THE TOP VALUE ON THE LUA STACK TO
// BE THE USER DATA WHERE THIS CLASS IS BEING
// INSTANTIATED!
class_rep(type_id const& type
, const char* name
, lua_State* L
);
} // used when creating a lua class
} // EXPECTS THE TOP VALUE ON THE LUA STACK TO
// BE THE USER DATA WHERE THIS CLASS IS BEING
// INSTANTIATED!
class_rep(lua_State* L, const char* name);
~class_rep();
std::pair<void*,void*> allocate(lua_State* L) const;
// this is called as metamethod __call on the class_rep.
static int constructor_dispatcher(lua_State* L);
struct base_info
{
int pointer_offset; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance)
class_rep* base;
};
void add_base_class(const base_info& binfo);
const std::vector<base_info>& bases() const throw() { return m_bases; }
void set_type(type_id const& t) { m_type = t; }
type_id const& type() const throw() { return m_type; }
const char* name() const throw() { return m_name; }
// the lua reference to the metatable for this class' instances
int metatable_ref() const throw() { return m_instance_metatable; }
void get_table(lua_State* L) const { m_table.push(L); }
void get_default_table(lua_State* L) const { m_default_table.push(L); }
class_type get_class_type() const { return m_class_type; }
void add_static_constant(const char* name, int val);
static int super_callback(lua_State* L);
static int lua_settable_dispatcher(lua_State* L);
// called from the metamethod for __index
// obj is the object pointer
static int static_class_gettable(lua_State* L);
bool has_operator_in_lua(lua_State*, int id);
cast_graph const& casts() const
{
return *m_casts;
}
class_id_map const& classes() const
{
return *m_classes;
}
private:
void cache_operators(lua_State*);
// this is a pointer to the type_info structure for
// this type
// warning: this may be a problem when using dll:s, since
// typeid() may actually return different pointers for the same
// type.
type_id m_type;
// a list of info for every class this class derives from
// the information stored here is sufficient to do
// type casts to the base classes
std::vector<base_info> m_bases;
// the class' name (as given when registered to lua with class_)
const char* m_name;
// a reference to this structure itself. Since this struct
// is kept inside lua (to let lua collect it when lua_close()
// is called) we need to lock it to prevent collection.
// the actual reference is not currently used.
detail::lua_reference m_self_ref;
// this should always be used when accessing
// members in instances of a class.
// this table contains c closures for all
// member functions in this class, they
// may point to both static and virtual functions
handle m_table;
// this table contains default implementations of the
// virtual functions in m_table.
handle m_default_table;
// the type of this class.. determines if it's written in c++ or lua
class_type m_class_type;
// this is a lua reference that points to the lua table
// that is to be used as meta table for all instances
// of this class.
int m_instance_metatable;
std::map<const char*, int, ltstr> m_static_constants;
// the first time an operator is invoked
// we check the associated lua table
// and cache the result
int m_operator_cache;
cast_graph* m_casts;
class_id_map* m_classes;
};
bool is_class_rep(lua_State* L, int index);
}}
//#include <luabind/detail/overload_rep_impl.hpp>
#endif // LUABIND_CLASS_REP_HPP_INCLUDED #endif // LUABIND_CLASS_REP_HPP_INCLUDED

View File

@ -0,0 +1,73 @@
// Copyright Daniel Wallin 2008. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef LUABIND_COMPUTE_RANK_081006_HPP
# define LUABIND_COMPUTE_RANK_081006_HPP
# include <luabind/config.hpp>
# include <luabind/detail/policy.hpp>
# include <boost/mpl/apply_wrap.hpp>
# include <boost/mpl/begin_end.hpp>
# include <boost/mpl/int.hpp>
# include <boost/mpl/next.hpp>
namespace luabind { namespace detail {
namespace mpl = boost::mpl;
template <class Idx, class Iter, class End, class Policies>
int compute_score_aux(
lua_State*L, int index, Idx, Iter, End end, Policies const& policies)
{
typedef typename Iter::type arg_type;
typedef typename find_conversion_policy<Idx::value, Policies>::type
conversion_policy;
typedef typename mpl::apply_wrap2<
conversion_policy, arg_type, lua_to_cpp>::type converter;
int score = converter::match(L, LUABIND_DECORATE_TYPE(arg_type), index);
if (score < 0)
return score;
if (conversion_policy::has_arg)
++index;
int next = compute_score_aux(
L
, index
, typename mpl::next<Idx>::type()
, typename mpl::next<Iter>::type()
, end
, policies
);
if (next < 0)
return next;
return score + next;
}
template <class Idx, class End, class Policies>
int compute_score_aux(lua_State*, int, Idx, End, End, Policies const&)
{
return 0;
}
template <class Signature, class Policies>
int compute_score(lua_State* L, Signature, Policies const& policies)
{
return compute_score_aux(
L
, 1
, mpl::int_<1>()
, typename mpl::next<typename mpl::begin<Signature>::type>::type()
, typename mpl::end<Signature>::type()
, policies
);
}
}} // namespace luabind::detail
#endif // LUABIND_COMPUTE_RANK_081006_HPP

View File

@ -2,64 +2,110 @@
// subject to the Boost Software License, Version 1.0. (See accompanying // subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef LUABIND_DETAIL_CONSTRUCTOR_081018_HPP #if !BOOST_PP_IS_ITERATING
#define LUABIND_DETAIL_CONSTRUCTOR_081018_HPP
#include <luabind/get_main_thread.hpp> # ifndef LUABIND_DETAIL_CONSTRUCTOR_081018_HPP
#include <luabind/lua_argument_proxy.hpp> # define LUABIND_DETAIL_CONSTRUCTOR_081018_HPP
#include <luabind/wrapper_base.hpp>
#include <luabind/detail/inheritance.hpp>
namespace luabind { # include <luabind/get_main_thread.hpp>
namespace detail { # include <luabind/object.hpp>
# include <luabind/wrapper_base.hpp>
# include <luabind/detail/inheritance.hpp>
inline void inject_backref(lua_State*, void*, void*) # include <boost/preprocessor/iteration/iterate.hpp>
{} # include <boost/preprocessor/iteration/local.hpp>
# include <boost/preprocessor/repetition/enum_params.hpp>
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
template <class T> namespace luabind { namespace detail {
void inject_backref(lua_State* L, T* p, wrap_base*)
{
weak_ref(get_main_thread(L), L, 1).swap(wrap_access::ref(*p));
}
template< class T, class Pointer, class Signature, class Arguments, class ArgumentIndices > inline void inject_backref(lua_State*, void*, void*)
struct construct_aux_helper; {}
template< class T, class Pointer, class Signature, typename... Arguments, unsigned int... ArgumentIndices > template <class T>
struct construct_aux_helper< T, Pointer, Signature, meta::type_list< Arguments... >, meta::index_list< ArgumentIndices... > > void inject_backref(lua_State* L, T* p, wrap_base*)
{ {
using holder_type = pointer_holder<Pointer, T>; weak_ref(get_main_thread(L), L, 1).swap(wrap_access::ref(*p));
}
void operator()(argument const& self_, Arguments... args) const template <std::size_t Arity, class T, class Pointer, class Signature>
{ struct construct_aux;
object_rep* self = touserdata<object_rep>(self_);
std::unique_ptr<T> instance(new T(args...)); template <class T, class Pointer, class Signature>
inject_backref(self_.interpreter(), instance.get(), instance.get()); struct construct
: construct_aux<mpl::size<Signature>::value - 2, T, Pointer, Signature>
{};
void* naked_ptr = instance.get(); template <class T, class Pointer, class Signature>
Pointer ptr(instance.release()); struct construct_aux<0, T, Pointer, Signature>
{
typedef pointer_holder<Pointer, T> holder_type;
void* storage = self->allocate(sizeof(holder_type)); void operator()(argument const& self_) const
{
object_rep* self = touserdata<object_rep>(self_);
class_rep* cls = self->crep();
self->set_instance(new (storage) holder_type(std::move(ptr), registered_class<T>::id, naked_ptr)); std::auto_ptr<T> instance(new T);
} inject_backref(self_.interpreter(), instance.get(), instance.get());
};
void* naked_ptr = instance.get();
Pointer ptr(instance.release());
template< class T, class Pointer, class Signature > void* storage = self->allocate(sizeof(holder_type));
struct construct :
public construct_aux_helper <
T,
Pointer,
Signature, typename meta::sub_range< Signature, 2, meta::size<Signature>::value >::type,
typename meta::make_index_range<0, meta::size<Signature>::value - 2>::type >
{
};
} // namespace detail self->set_instance(new (storage) holder_type(
ptr, registered_class<T>::id, naked_ptr, cls));
}
};
} // namespace luabind # define BOOST_PP_ITERATION_PARAMS_1 \
(3, (1, LUABIND_MAX_ARITY, <luabind/detail/constructor.hpp>))
# include BOOST_PP_ITERATE()
}} // namespace luabind::detail
# endif // LUABIND_DETAIL_CONSTRUCTOR_081018_HPP # endif // LUABIND_DETAIL_CONSTRUCTOR_081018_HPP
#else // !BOOST_PP_IS_ITERATING
# define N BOOST_PP_ITERATION()
template <class T, class Pointer, class Signature>
struct construct_aux<N, T, Pointer, Signature>
{
typedef typename mpl::begin<Signature>::type first;
typedef typename mpl::next<first>::type iter0;
# define BOOST_PP_LOCAL_MACRO(n) \
typedef typename mpl::next< \
BOOST_PP_CAT(iter,BOOST_PP_DEC(n))>::type BOOST_PP_CAT(iter,n); \
typedef typename BOOST_PP_CAT(iter,n)::type BOOST_PP_CAT(a,BOOST_PP_DEC(n));
# define BOOST_PP_LOCAL_LIMITS (1,N)
# include BOOST_PP_LOCAL_ITERATE()
typedef pointer_holder<Pointer, T> holder_type;
void operator()(argument const& self_, BOOST_PP_ENUM_BINARY_PARAMS(N,a,_)) const
{
object_rep* self = touserdata<object_rep>(self_);
class_rep* cls = self->crep();
std::auto_ptr<T> instance(new T(BOOST_PP_ENUM_PARAMS(N,_)));
inject_backref(self_.interpreter(), instance.get(), instance.get());
void* naked_ptr = instance.get();
Pointer ptr(instance.release());
void* storage = self->allocate(sizeof(holder_type));
self->set_instance(new (storage) holder_type(
ptr, registered_class<T>::id, naked_ptr, cls));
}
};
# undef N
#endif

View File

@ -1,81 +0,0 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// 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 LUABIND_CONVERSION_BASE_HPP_INCLUDED
#define LUABIND_CONVERSION_BASE_HPP_INCLUDED
#include <type_traits>
#include <luabind/lua_include.hpp>
#include <luabind/detail/decorate_type.hpp>
#include <luabind/detail/make_instance.hpp>
#include <luabind/pointer_traits.hpp>
#include <luabind/from_stack.hpp>
namespace luabind {
namespace detail {
// Something's strange with the references here... need to know when to copy :(
template <class T, class Clone>
void make_pointee_instance(lua_State* L, T&& x, std::true_type, Clone)
{
if(get_pointer(x))
{
make_pointer_instance(L, std::forward<T>(x));
}
else
{
lua_pushnil(L);
}
}
template <class T>
void make_pointee_instance(lua_State* L, T&& x, std::false_type, std::true_type)
{
using value_type = typename std::remove_reference<T>::type;
std::unique_ptr<value_type> ptr(new value_type(std::move(x)));
make_pointer_instance(L, std::move(ptr));
}
template <class T>
void make_pointee_instance(lua_State* L, T&& x, std::false_type, std::false_type)
{
// need a second make_instance that moves x into place
make_pointer_instance(L, &x);
}
template <class T, class Clone>
void make_pointee_instance(lua_State* L, T&& x, Clone)
{
make_pointee_instance(L, std::forward<T>(x), has_get_pointer<T>(), Clone());
}
}
template <class T, class Enable>
struct default_converter;
}
#endif

View File

@ -1,89 +0,0 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// 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 LUABIND_CONVERSION_POLICIES_HPP_INCLUDED
#define LUABIND_CONVERSION_POLICIES_HPP_INCLUDED
#include <luabind/detail/type_traits.hpp>
#include <luabind/detail/meta.hpp>
#include <luabind/detail/policy.hpp>
#include <luabind/detail/conversion_policies/conversion_base.hpp>
#include <luabind/detail/conversion_policies/enum_converter.hpp>
#include <luabind/detail/conversion_policies/pointer_converter.hpp>
#include <luabind/detail/conversion_policies/reference_converter.hpp>
#include <luabind/detail/conversion_policies/value_converter.hpp>
#include <luabind/detail/conversion_policies/lua_proxy_converter.hpp>
#include <luabind/detail/conversion_policies/native_converter.hpp>
#include <luabind/detail/conversion_policies/function_converter.hpp>
#include <luabind/shared_ptr_converter.hpp>
namespace luabind {
template <>
struct default_converter<lua_State*>
{
enum { consumed_args = 0 };
template <class U>
lua_State* to_cpp(lua_State* L, U, int /*index*/)
{
return L;
}
template <class U>
static int match(lua_State*, U, int /*index*/)
{
return 0;
}
template <class U>
void converter_postcall(lua_State*, U, int) {}
};
namespace detail {
// This is the one that gets hit, if default_policy doesn't hit one of the specializations defined all over the place
template< class T >
struct default_converter_generator
: public meta::select_ <
meta::case_< is_lua_proxy_arg<T>, lua_proxy_converter<T> >,
meta::case_< std::is_enum<typename std::remove_reference<T>::type>, enum_converter >,
meta::case_< is_nonconst_pointer<T>, pointer_converter >,
meta::case_< is_const_pointer<T>, const_pointer_converter >,
meta::case_< is_nonconst_reference<T>, ref_converter >,
meta::case_< is_const_reference<T>, const_ref_converter >,
meta::default_< value_converter >
> ::type
{
};
}
template <class T, class Enable>
struct default_converter
: detail::default_converter_generator<T>::type
{};
}
#endif

View File

@ -1,82 +0,0 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// 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 LUABIND_ENUM_CONVERTER_HPP_INCLUDED
#define LUABIND_ENUM_CONVERTER_HPP_INCLUDED
#include <type_traits>
#include <luabind/detail/type_traits.hpp>
#include <luabind/detail/conversion_policies/conversion_base.hpp>
namespace luabind {
namespace detail {
struct enum_converter
{
using type = enum_converter;
using is_native = std::false_type;
enum { consumed_args = 1 };
void to_lua(lua_State* L, int val)
{
lua_pushnumber(L, val);
}
template<class T>
T to_cpp(lua_State* L, by_value<T>, int index)
{
return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
}
template<class T>
static int match(lua_State* L, by_value<T>, int index)
{
if(lua_isnumber(L, index)) {
return 0;
} else {
return no_match;
}
}
template<class T>
T to_cpp(lua_State* L, by_const_reference<T>, int index)
{
return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
}
template<class T>
static int match(lua_State* L, by_const_reference<T>, int index)
{
if(lua_isnumber(L, index)) return 0; else return no_match;
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
}
}
#endif

View File

@ -1,93 +0,0 @@
// Copyright Christian Neumüller 2013. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef LUABIND_FUNCTION_CONVERTER_HPP_INCLUDED
#define LUABIND_FUNCTION_CONVERTER_HPP_INCLUDED
#include <functional>
#include <luabind/detail/deduce_signature.hpp>
#include <luabind/detail/conversion_policies/conversion_base.hpp>
#include <luabind/make_function.hpp>
#include <luabind/detail/call_function.hpp>
namespace luabind {
template <typename R = object>
struct function
{
using result_type = R;
function(luabind::object const& obj)
: m_func(obj)
{
}
template< typename... Args>
R operator() (Args&&... args)
{
return call_function<R>(m_func, std::forward<Args>(args)...);
}
private:
object m_func;
};
namespace detail {
template< typename T >
struct is_function : public std::false_type {};
template< typename T >
struct is_function< std::function< T > > : public std::true_type {};
}
template< typename R, typename... Args, typename WrappedType >
struct deduce_signature <std::function< R(Args...) >, WrappedType >
{
using type = meta::type_list< R, Args... >;
};
template <typename F>
struct default_converter<F, typename std::enable_if<detail::is_function<remove_const_reference_t<F>>::value>::type>
{
using is_native = std::true_type;
enum { consumed_args = 1 };
template <class U>
void converter_postcall(lua_State*, U const&, int)
{}
template <class U>
static int match(lua_State* L, U, int index)
{
if(lua_type(L, index) == LUA_TFUNCTION)
return 0;
if(luaL_getmetafield(L, index, "__call")) {
lua_pop(L, 1);
return 1;
}
return no_match;
}
template <class U>
F to_cpp(lua_State* L, U, int index)
{
// If you get a compiler error here, you are probably trying to
// get a function pointer from Lua. This is not supported:
// you must use a type which is constructible from a
// luabind::function, e.g. std::function or boost::function.
return function<typename F::result_type>(object(from_stack(L, index)));
}
void to_lua(lua_State* L, F value)
{
make_function(L, value).push(L);
}
};
} // namespace luabind
#endif // LUABIND_FUNCTION_CONVERTER_HPP_INCLUDED

View File

@ -1,73 +0,0 @@
// 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 LUABIND_VALUE_WRAPPER_CONVERTER_HPP_INCLUDED
#define LUABIND_VALUE_WRAPPER_CONVERTER_HPP_INCLUDED
#include <luabind/lua_proxy.hpp>
#include <type_traits>
namespace luabind {
namespace detail {
template <class U>
struct lua_proxy_converter
{
using type = lua_proxy_converter<U>;
using is_native = std::true_type;
enum { consumed_args = 1 };
template<class T>
T to_cpp(lua_State* L, by_const_reference<T>, int index)
{
return T(from_stack(L, index));
}
template<class T>
T to_cpp(lua_State* L, by_value<T>, int index)
{
return to_cpp(L, by_const_reference<T>(), index);
}
template<class T>
static int match(lua_State* L, by_const_reference<T>, int index)
{
return lua_proxy_traits<T>::check(L, index)
? max_hierarchy_depth
: no_match;
}
template<class T>
static int match(lua_State* L, by_value<T>, int index)
{
return match(L, by_const_reference<T>(), index);
}
void converter_postcall(...) {}
template<class T>
void to_lua(lua_State* interpreter, T const& value_wrapper)
{
lua_proxy_traits<T>::unwrap(interpreter, value_wrapper);
}
};
}
}
#endif

View File

@ -1,302 +0,0 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// 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 LUABIND_NATIVE_CONVERTER_HPP_INCLUDED
#define LUABIND_NATIVE_CONVERTER_HPP_INCLUDED
#include <type_traits>
#include <string>
#include <luabind/detail/policy.hpp>
#include <luabind/detail/conversion_policies/conversion_base.hpp>
#include <luabind/detail/type_traits.hpp>
#include <luabind/detail/call_traits.hpp>
#include <luabind/lua_include.hpp>
#if LUA_VERSION_NUM < 502
# define lua_rawlen lua_objlen
#endif
namespace luabind {
template <class T, class Derived = default_converter<T> >
struct native_converter_base
{
using is_native = std::true_type;
using value_type = typename detail::call_traits<T>::value_type;
using param_type = typename detail::call_traits<T>::param_type;
enum { consumed_args = 1 };
template <class U>
void converter_postcall(lua_State*, U const&, int)
{}
int match(lua_State* L, by_value<T>, int index)
{
return Derived::compute_score(L, index);
}
int match(lua_State* L, by_value<T const>, int index)
{
return Derived::compute_score(L, index);
}
int match(lua_State* L, by_const_reference<T>, int index)
{
return Derived::compute_score(L, index);
}
value_type to_cpp(lua_State* L, by_value<T>, int index)
{
return derived().to_cpp_deferred(L, index);
}
value_type to_cpp(lua_State* L, by_const_reference<T>, int index)
{
return derived().to_cpp_deferred(L, index);
}
void to_lua(lua_State* L, param_type value)
{
derived().to_lua_deferred(L, value);
}
Derived& derived()
{
return static_cast<Derived&>(*this);
}
};
template <typename QualifiedT>
struct integer_converter
: native_converter_base<remove_const_reference_t<QualifiedT>>
{
using T = remove_const_reference_t<QualifiedT>;
using value_type = typename native_converter_base<T>::value_type;
using param_type = typename native_converter_base<T>::param_type;
static int compute_score(lua_State* L, int index)
{
return lua_type(L, index) == LUA_TNUMBER ? 0 : no_match;
}
static value_type to_cpp_deferred(lua_State* L, int index)
{
if((std::is_unsigned<value_type>::value && sizeof(value_type) >= sizeof(lua_Integer)) || (sizeof(value_type) > sizeof(lua_Integer))) {
return static_cast<T>(lua_tonumber(L, index));
} else {
return static_cast<T>(lua_tointeger(L, index));
}
}
void to_lua_deferred(lua_State* L, param_type value)
{
if((std::is_unsigned<value_type>::value && sizeof(value_type) >= sizeof(lua_Integer)) || (sizeof(value_type) > sizeof(lua_Integer)))
{
lua_pushnumber(L, (lua_Number)value);
} else {
lua_pushinteger(L, static_cast<lua_Integer>(value));
}
}
};
template <typename QualifiedT>
struct number_converter
: native_converter_base<remove_const_reference_t<QualifiedT>>
{
using T = remove_const_reference_t<QualifiedT>;
using value_type = typename native_converter_base<T>::value_type;
using param_type = typename native_converter_base<T>::param_type;
static int compute_score(lua_State* L, int index)
{
return lua_type(L, index) == LUA_TNUMBER ? 0 : no_match;
}
static value_type to_cpp_deferred(lua_State* L, int index)
{
return static_cast<T>(lua_tonumber(L, index));
}
static void to_lua_deferred(lua_State* L, param_type value)
{
lua_pushnumber(L, static_cast<lua_Number>(value));
}
};
template <>
struct default_converter<bool>
: native_converter_base<bool>
{
static int compute_score(lua_State* L, int index)
{
return lua_type(L, index) == LUA_TBOOLEAN ? 0 : no_match;
}
static bool to_cpp_deferred(lua_State* L, int index)
{
return lua_toboolean(L, index) == 1;
}
static void to_lua_deferred(lua_State* L, bool value)
{
lua_pushboolean(L, value);
}
};
template <>
struct default_converter<bool const>
: default_converter<bool>
{};
template <>
struct default_converter<bool const&>
: default_converter<bool>
{};
template <>
struct default_converter<std::string>
: native_converter_base<std::string>
{
static int compute_score(lua_State* L, int index)
{
return lua_type(L, index) == LUA_TSTRING ? 0 : no_match;
}
static std::string to_cpp_deferred(lua_State* L, int index)
{
return std::string(lua_tostring(L, index), lua_rawlen(L, index));
}
static void to_lua_deferred(lua_State* L, std::string const& value)
{
lua_pushlstring(L, value.data(), value.size());
}
};
template <>
struct default_converter<std::string&>
: default_converter<std::string>
{};
template <>
struct default_converter<std::string const>
: default_converter<std::string>
{};
template <>
struct default_converter<std::string const&>
: default_converter<std::string>
{};
template <>
struct default_converter<char const*>
{
using is_native = std::true_type;
enum { consumed_args = 1 };
template <class U>
static int match(lua_State* L, U, int index)
{
int type = lua_type(L, index);
return (type == LUA_TSTRING || type == LUA_TNIL) ? 0 : no_match;
}
template <class U>
static char const* to_cpp(lua_State* L, U, int index)
{
return lua_tostring(L, index);
}
static void to_lua(lua_State* L, char const* str)
{
lua_pushstring(L, str);
}
template <class U>
void converter_postcall(lua_State*, U, int)
{}
};
template <>
struct default_converter<const char* const>
: default_converter<char const*>
{};
template <>
struct default_converter<const char* const&>
: default_converter<char const*>
{};
template <>
struct default_converter<const char*&>
: default_converter<char const*>
{};
template <>
struct default_converter<char*>
: default_converter<char const*>
{};
template <std::size_t N>
struct default_converter<char const[N]>
: default_converter<char const*>
{};
template <std::size_t N>
struct default_converter<char[N]>
: default_converter<char const*>
{};
template <std::size_t N>
struct default_converter <char(&)[N]>
: default_converter<char const*>
{};
template <std::size_t N>
struct default_converter <const char(&)[N]>
: default_converter<char const*>
{};
template <typename T>
struct default_converter < T, typename std::enable_if< std::is_integral<remove_const_reference_t<T>>::value >::type >
: integer_converter<T>
{
};
template <typename T>
struct default_converter < T, typename std::enable_if< std::is_floating_point<remove_const_reference_t<T>>::value >::type >
: number_converter<T>
{
};
}
#if LUA_VERSION_NUM < 502
# undef lua_rawlen
#endif
#endif

View File

@ -1,143 +0,0 @@
// 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 LUABIND_POINTER_CONVERTER_HPP_INCLUDED
#define LUABIND_POINTER_CONVERTER_HPP_INCLUDED
#include <type_traits>
#include <luabind/lua_include.hpp>
#include <luabind/detail/make_instance.hpp>
#include <luabind/back_reference.hpp>
namespace luabind {
/*
Todo: Remove code duplication
*/
namespace detail {
struct pointer_converter
{
using type = pointer_converter;
using is_native = std::false_type;
pointer_converter()
: result(0)
{}
void* result;
enum { consumed_args = 1 };
template<class T>
static void to_lua(lua_State* L, T* ptr)
{
if(ptr == 0)
{
lua_pushnil(L);
return;
}
if(luabind::get_back_reference(L, ptr))
return;
make_pointer_instance(L, ptr);
}
template<class T>
T* to_cpp(lua_State*, by_pointer<T>, int /*index*/)
{
return static_cast<T*>(result);
}
template<class T>
int match(lua_State* L, by_pointer<T>, int index)
{
if(lua_isnil(L, index)) return 0;
object_rep* obj = get_instance(L, index);
if(obj == 0) return no_match;
if(obj->is_const())
return no_match;
std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
result = s.first;
return s.second;
}
template<class T>
void converter_postcall(lua_State*, by_pointer<T>, int /*index*/)
{}
};
struct const_pointer_converter
{
using type = const_pointer_converter;
using is_native = std::false_type;
enum { consumed_args = 1 };
const_pointer_converter()
: result(0)
{}
void* result;
template<class T>
void to_lua(lua_State* L, const T* ptr)
{
if(ptr == 0)
{
lua_pushnil(L);
return;
}
if(luabind::get_back_reference(L, ptr))
return;
make_pointer_instance(L, ptr);
}
template<class T>
T const* to_cpp(lua_State*, by_const_pointer<T>, int)
{
return static_cast<T const*>(result);
}
template<class T>
int match(lua_State* L, by_const_pointer<T>, int index)
{
if(lua_isnil(L, index)) return 0;
object_rep* obj = get_instance(L, index);
if(obj == 0) return no_match; // if the type is not one of our own registered types, classify it as a non-match
std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
if(s.second >= 0 && !obj->is_const())
s.second += 10;
result = s.first;
return s.second;
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
}
}
#endif

View File

@ -1,124 +0,0 @@
// 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 LUABIND_REFERENCE_CONVERTER_HPP_INCLUDED
#define LUABIND_REFERENCE_CONVERTER_HPP_INCLUDED
#include <type_traits>
#include <luabind/detail/conversion_policies/conversion_base.hpp>
#include <luabind/detail/conversion_policies/pointer_converter.hpp>
#include <luabind/back_reference.hpp>
namespace luabind {
/*
TODO: Remove code duplication
*/
namespace detail {
struct ref_converter : pointer_converter
{
using type = ref_converter;
using is_native = std::false_type;
enum { consumed_args = 1 };
template<class T>
void to_lua(lua_State* L, T& ref)
{
if(luabind::get_back_reference(L, ref))
return;
make_pointee_instance(L, ref, std::false_type());
}
template<class T>
T& to_cpp(lua_State* L, by_reference<T>, int index)
{
assert(!lua_isnil(L, index));
return *pointer_converter::to_cpp(L, by_pointer<T>(), index);
}
template<class T>
int match(lua_State* L, by_reference<T>, int index)
{
object_rep* obj = get_instance(L, index);
if(obj == 0) return no_match;
if(obj->is_const())
return no_match;
std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
result = s.first;
return s.second;
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
struct const_ref_converter
{
using type = const_ref_converter;
using is_native = std::false_type;
enum { consumed_args = 1 };
const_ref_converter()
: result(0)
{}
void* result;
template<class T>
void to_lua(lua_State* L, T const& ref)
{
if(luabind::get_back_reference(L, ref))
return;
make_pointee_instance(L, ref, std::false_type());
}
template<class T>
T const& to_cpp(lua_State*, by_const_reference<T>, int)
{
return *static_cast<T*>(result);
}
template<class T>
int match(lua_State* L, by_const_reference<T>, int index)
{
object_rep* obj = get_instance(L, index);
if(obj == 0) return no_match; // if the type is not one of our own registered types, classify it as a non-match
std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
if(s.second >= 0 && !obj->is_const())
s.second += 10;
result = s.first;
return s.second;
}
template<class T>
void converter_postcall(lua_State*, by_const_reference<T>, int)
{
}
};
}
}
#endif

View File

@ -1,79 +0,0 @@
// 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 LUABIND_VALUE_CONVERTER_HPP_INCLUDED
#define LUABIND_VALUE_CONVERTER_HPP_INCLUDED
#include <type_traits>
#include <luabind/lua_include.hpp>
#include <luabind/back_reference.hpp>
#include <luabind/detail/object_rep.hpp>
namespace luabind {
namespace detail {
struct value_converter
{
using type = value_converter;
using is_native = std::false_type;
enum { consumed_args = 1 };
value_converter()
: result(0)
{}
void* result;
template<class T>
void to_lua(lua_State* L, T&& x)
{
if(luabind::get_back_reference(L, x))
return;
make_value_instance(L, std::forward<T>(x));
}
template<class T>
T to_cpp(lua_State*, by_value<T>, int)
{
return *static_cast<T*>(result);
}
template<class T>
int match(lua_State* L, by_value<T>, int index)
{
// special case if we get nil in, try to match the holder type
if(lua_isnil(L, index))
return no_match;
object_rep* obj = get_instance(L, index);
if(obj == 0) return no_match;
std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
result = s.first;
return s.second;
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
}
}
#endif

View File

@ -6,38 +6,36 @@
# define LUABIND_CONVERSION_STORAGE_080930_HPP # define LUABIND_CONVERSION_STORAGE_080930_HPP
# include <luabind/config.hpp> # include <luabind/config.hpp>
# include <type_traits> # include <boost/aligned_storage.hpp>
namespace luabind { namespace luabind { namespace detail {
namespace detail {
using destruction_function = void(*)(void*); typedef void(*destruction_function)(void*);
// This is used by the converters in policy.hpp, and // This is used by the converters in policy.hpp, and
// class_rep::convert_to as temporary storage when constructing // class_rep::convert_to as temporary storage when constructing
// holders. // holders.
struct conversion_storage struct conversion_storage
{ {
conversion_storage() conversion_storage()
: destructor(0) : destructor(0)
{} {}
~conversion_storage() ~conversion_storage()
{ {
if(destructor) if (destructor)
destructor(&data); destructor(&data);
} }
// Unfortunately the converters currently doesn't have access to // Unfortunately the converters currently doesn't have access to
// the actual type being converted when this is instantiated, so // the actual type being converted when this is instantiated, so
// we have to guess a max size. // we have to guess a max size.
std::aligned_storage<128> data; boost::aligned_storage<128> data;
destruction_function destructor; destruction_function destructor;
}; };
} }} // namespace luabind::detail
} // namespace luabind::detail
#endif // LUABIND_CONVERSION_STORAGE_080930_HPP #endif // LUABIND_CONVERSION_STORAGE_080930_HPP

View File

@ -0,0 +1,92 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// 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 LUABIND_CONVERT_TO_LUA_HPP_INCLUDED
#define LUABIND_CONVERT_TO_LUA_HPP_INCLUDED
#include <luabind/config.hpp>
#include <luabind/detail/policy.hpp>
#include <boost/ref.hpp>
#include <boost/mpl/apply_wrap.hpp>
namespace luabind { namespace detail
{
template<bool IsReferenceWrapper = false>
struct unwrap_ref
{
template<class T>
static const T& get(const T& r) { return r; }
template<class T>
struct apply
{
typedef T type;
};
};
template<>
struct unwrap_ref<true>
{
template<class T>
static T& get(const boost::reference_wrapper<T>& r) { return r.get(); }
template<class T>
struct apply
{
typedef typename T::type& type;
};
};
namespace mpl = boost::mpl;
template<class T>
void convert_to_lua(lua_State* L, const T& v)
{
typedef typename mpl::apply_wrap1<
unwrap_ref<boost::is_reference_wrapper<T>::value>
, T
>::type value_type;
typename mpl::apply_wrap2<default_policy,value_type,cpp_to_lua>::type converter;
converter.apply(L, unwrap_ref<boost::is_reference_wrapper<T>::value>::get(v));
}
template<int Index, class T, class Policies>
void convert_to_lua_p(lua_State* L, const T& v, const Policies&)
{
typedef typename mpl::apply_wrap1<
unwrap_ref<boost::is_reference_wrapper<T>::value>
, T
>::type value_type;
typedef typename find_conversion_policy<Index, Policies>::type converter_policy;
typename mpl::apply_wrap2<converter_policy,value_type,cpp_to_lua>::type converter;
converter.apply(L, unwrap_ref<boost::is_reference_wrapper<T>::value>::get(v));
}
}}
#endif

View File

@ -1,58 +0,0 @@
#ifndef LUABIND_CRTP_ITERATOR_HPP_INCLUDED
#define LUABIND_CRTP_ITERATOR_HPP_INCLUDED
#include <iterator>
namespace luabind {
namespace detail {
template< typename CRTP, typename Category, typename ValueType, typename ReferenceType = ValueType&, typename DifferenceType = ptrdiff_t >
class crtp_iterator :
public std::iterator<Category, ValueType, DifferenceType, ValueType*, ReferenceType >
{
public:
using base_type = std::iterator<Category, ValueType, DifferenceType, ValueType*, ReferenceType >;
CRTP& operator++()
{
upcast().increment();
return upcast();
}
CRTP operator++(int)
{
CRTP tmp(upcast());
upcast().increment();
return tmp;
}
bool operator==(const CRTP& rhs)
{
return upcast().equal(rhs);
}
bool operator!=(const CRTP& rhs)
{
return !upcast().equal(rhs);
}
typename base_type::reference operator*()
{
return upcast().dereference();
}
typename base_type::reference operator->()
{
return upcast().dereference();
}
private:
CRTP& upcast() { return static_cast<CRTP&>(*this); }
const CRTP& upcast() const { return static_cast<const CRTP&>(*this); }
};
}
}
#endif

View File

@ -28,32 +28,28 @@
#include <luabind/lua_include.hpp> #include <luabind/lua_include.hpp>
#include <cassert> #include <cassert>
namespace luabind { namespace luabind { namespace detail
namespace detail { {
struct stack_checker_type
{
stack_checker_type(lua_State* L)
: m_L(L)
, m_stack(lua_gettop(m_L))
{}
struct stack_checker_type ~stack_checker_type()
{ {
stack_checker_type(lua_State* L) assert(m_stack == lua_gettop(m_L));
: m_L(L) }
, m_stack(lua_gettop(m_L))
{}
~stack_checker_type() lua_State* m_L;
{ int m_stack;
assert(m_stack == lua_gettop(m_L)); };
}
lua_State* m_L;
int m_stack;
};
}
}
}}
#define LUABIND_CHECK_STACK(L) luabind::detail::stack_checker_type stack_checker_object(L) #define LUABIND_CHECK_STACK(L) luabind::detail::stack_checker_type stack_checker_object(L)
#else #else
#define LUABIND_CHECK_STACK(L) do {} while (0) #define LUABIND_CHECK_STACK(L) do {} while (0)
#endif #endif
#endif // LUABIND_DEBUG_HPP_INCLUDED #endif // LUABIND_DEBUG_HPP_INCLUDED

View File

@ -25,62 +25,242 @@
#define LUABIND_DECORATE_TYPE_HPP_INCLUDED #define LUABIND_DECORATE_TYPE_HPP_INCLUDED
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/detail/primitives.hpp>
namespace luabind { namespace luabind { namespace detail
{
template<class T> struct by_value {}; #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<class T> struct by_const_reference {};
template<class T> struct by_reference {};
template<class T> struct by_rvalue_reference {};
template<class T> struct by_pointer {};
template<class T> struct by_const_pointer {};
template<class T> template<class T>
struct decorate_type struct decorated_type
{ {
using type = by_value<T>; static by_value<T> t;
static inline by_value<T>& get() { return /*by_value<T>()*/t; }
}; };
template<class T> template<class T>
struct decorate_type<T*> by_value<T> decorated_type<T>::t;
template<class T>
struct decorated_type<T*>
{ {
using type = by_pointer<T>; static by_pointer<T> t;
static inline by_pointer<T>& get() { return /*by_pointer<T>()*/t; }
}; };
template<class T> template<class T>
struct decorate_type<const T*> by_pointer<T> decorated_type<T*>::t;
template<class T>
struct decorated_type<const T*>
{ {
using type = by_const_pointer<T>; static by_const_pointer<T> t;
static inline by_const_pointer<T> get() { return /*by_const_pointer<T>()*/t; }
}; };
template<class T> template<class T>
struct decorate_type<const T* const> by_const_pointer<T> decorated_type<const T*>::t;
template<class T>
struct decorated_type<const T* const>
{ {
using type = by_const_pointer<T>; static by_const_pointer<T> t;
static inline by_const_pointer<T>& get() { return /*by_const_pointer<T>()*/t; }
}; };
template<class T> template<class T>
struct decorate_type<T&> by_const_pointer<T> decorated_type<const T* const>::t;
template<class T>
struct decorated_type<T&>
{ {
using type = by_reference<T>; static by_reference<T> t;
static inline by_reference<T>& get() { return /*by_reference<T>()*/t; }
}; };
template<class T> template<class T>
struct decorate_type<const T&> by_reference<T> decorated_type<T&>::t;
template<class T>
struct decorated_type<const T&>
{ {
using type = by_const_reference<T>; static by_const_reference<T> t;
static inline by_const_reference<T>& get() { return /*by_const_reference<T>()*/t; }
}; };
template<class T> template<class T>
struct decorate_type<T&&> by_const_reference<T> decorated_type<const T&>::t;
#define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type<t>::get()
#else
#include <boost/type_traits/is_array.hpp>
namespace
{ {
using type = by_rvalue_reference<T>; LUABIND_ANONYMOUS_FIX char decorated_type_array[64];
}
template<class T>
struct decorated_type_cref_impl
{
#if defined(BOOST_MSVC) && BOOST_MSVC == 1200
template<class U>
static by_const_reference<U> get(const U&)
{
return by_const_reference<U>();
}
static T data() { return reinterpret_cast<T>(decorated_type_array); }
#else
static void(*data())(T)
{ return (void(*)(T))0; }
template<class U>
static by_const_reference<U> get(void(*f)(const U&))
{ return by_const_reference<U>(); }
#endif
}; };
template< typename T > template<class T>
using decorate_type_t = typename decorate_type<T>::type; struct decorated_type_ref_impl
{
#if defined(BOOST_MSVC) && BOOST_MSVC == 1200
template<class U>
static by_reference<U> get(U&)
{
return by_reference<U>();
}
static T data() { return reinterpret_cast<T>(decorated_type_array); }
#else
static void(*data())(T)
{ return (void(*)(T))0; }
} template<class U>
static by_reference<U> get(void(*)(U&))
{ return by_reference<U>(); }
#endif
};
template<class T>
struct decorated_type_cptr_impl
{
#if defined(BOOST_MSVC) && BOOST_MSVC == 1200
template<class U>
static by_const_pointer<U> get(const U*)
{
return by_const_pointer<U>();
}
static T& data() { return reinterpret_cast<T&>(decorated_type_array); }
#else
static void(*data())(T)
{ return (void(*)(T))0; }
template<class U>
static by_const_pointer<U> get(void(*)(const U*))
{ return by_const_pointer<U>(); }
#endif
};
template<class T>
struct decorated_type_ptr_impl
{
#if defined(BOOST_MSVC) && BOOST_MSVC == 1200
template<class U>
static by_pointer<U> get(U*)
{
return by_pointer<U>();
}
static T& data() { return reinterpret_cast<T&>(decorated_type_array); }
#else
static void(*data())(T)
{ return (void(*)(T))0; }
template<class U>
static by_pointer<U> get(void(*)(U*))
{ return by_pointer<U>(); }
#endif
};
template<class T>
struct decorated_type_value_impl
{
#if defined(BOOST_MSVC) && BOOST_MSVC == 1200
template<class U>
static by_value<U> get(U&)
{
return by_value<U>();
}
static T& data() { return reinterpret_cast<T&>(decorated_type_array); }
#else
static void(*data())(T&)
{ return (void(*)(T&))0; }
template<class U>
static by_value<U> get(void(*)(U&))
{ return by_value<U>(); }
#endif
};
template<>
struct decorated_type_value_impl<void>
{
static by_value<void> get(int)
{
return by_value<void>();
}
static int data() { return 0; }
};
template<class T>
struct decorated_type_array_impl
{
template<class U>
static by_pointer<U> get(U*)
{
return by_pointer<U>();
}
template<class U>
static by_pointer<U> get(void(*)(U))
{ return by_pointer<U>(); }
static T& data() { return reinterpret_cast<T&>(decorated_type_array); }
};
template<class T>
struct decorated_type
// : boost::mpl::if_<boost::is_array<T>
// , decorated_type_array_impl<T>
: boost::mpl::if_<luabind::detail::is_const_reference<T>
, decorated_type_cref_impl<T>
, typename boost::mpl::if_<luabind::detail::is_nonconst_reference<T>
, decorated_type_ref_impl<T>
, typename boost::mpl::if_<luabind::detail::is_nonconst_pointer<T>
, decorated_type_ptr_impl<T>
, typename boost::mpl::if_<luabind::detail::is_const_pointer<T>
, decorated_type_cptr_impl<T>
, decorated_type_value_impl<T>
>::type
>::type
>::type
>::type
// >::type
{
};
#if defined(BOOST_MSVC) && BOOST_MSVC == 1200
#define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type<t>::get(luabind::detail::decorated_type<t>::data())
#else
// #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type<t>::get((void(*)(type<t>))0)
#define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type<t>::get(luabind::detail::decorated_type<t>::data())
//#define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type<t>::get(type<t>())
#endif
#endif
}}
#endif // LUABIND_DECORATE_TYPE_HPP_INCLUDED #endif // LUABIND_DECORATE_TYPE_HPP_INCLUDED

View File

@ -2,19 +2,117 @@
// subject to the Boost Software License, Version 1.0. (See accompanying // subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !BOOST_PP_IS_ITERATING
# ifndef LUABIND_DEDUCE_SIGNATURE_080911_HPP # ifndef LUABIND_DEDUCE_SIGNATURE_080911_HPP
# define LUABIND_DEDUCE_SIGNATURE_080911_HPP # define LUABIND_DEDUCE_SIGNATURE_080911_HPP
#include <luabind/detail/meta.hpp> # include <luabind/detail/most_derived.hpp>
#include <luabind/detail/type_traits.hpp>
namespace luabind { # if LUABIND_MAX_ARITY <= 8
namespace detail { # include <boost/mpl/vector/vector10.hpp>
# else
# include <boost/mpl/vector/vector50.hpp>
# endif
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/iteration/iterate.hpp>
# include <boost/preprocessor/repetition/enum_params.hpp>
namespace luabind { namespace detail {
} // namespace detail namespace mpl = boost::mpl;
} // namespace luabind template <class R>
mpl::vector1<R> deduce_signature(R(*)(), ...)
{
return mpl::vector1<R>();
}
template <class R, class T>
mpl::vector2<R,T&> deduce_signature(R(T::*)())
{
return mpl::vector2<R,T&>();
}
template <class R, class T, class Wrapped>
mpl::vector2<R,typename most_derived<T,Wrapped>::type&>
deduce_signature(R(T::*)(), Wrapped*)
{
return mpl::vector2<R,typename most_derived<T,Wrapped>::type&>();
}
template <class R, class T>
mpl::vector2<R,T const&> deduce_signature(R(T::*)() const)
{
return mpl::vector2<R,T const&>();
}
template <class R, class T, class Wrapped>
mpl::vector2<R,typename most_derived<T,Wrapped>::type const&>
deduce_signature(R(T::*)() const, Wrapped*)
{
return mpl::vector2<R,typename most_derived<T,Wrapped>::type const&>();
}
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (1, LUABIND_MAX_ARITY, <luabind/detail/deduce_signature.hpp>))
# include BOOST_PP_ITERATE()
}} // namespace luabind::detail
# endif // LUABIND_DEDUCE_SIGNATURE_080911_HPP # endif // LUABIND_DEDUCE_SIGNATURE_080911_HPP
#else // BOOST_PP_IS_ITERATING
# define N BOOST_PP_ITERATION()
# define NPLUS1 BOOST_PP_INC(N)
template <class R, BOOST_PP_ENUM_PARAMS(N,class A)>
BOOST_PP_CAT(mpl::vector,NPLUS1)<R, BOOST_PP_ENUM_PARAMS(N,A)>
deduce_signature(R(*)(BOOST_PP_ENUM_PARAMS(N,A)), ...)
{
return BOOST_PP_CAT(mpl::vector,NPLUS1)<R,BOOST_PP_ENUM_PARAMS(N,A)>();
}
# define NPLUS2 BOOST_PP_INC(NPLUS1)
template <class R, class T, BOOST_PP_ENUM_PARAMS(N,class A)>
BOOST_PP_CAT(mpl::vector,NPLUS2)<R, T&, BOOST_PP_ENUM_PARAMS(N,A)>
deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)))
{
return BOOST_PP_CAT(mpl::vector,NPLUS2)<R,T&,BOOST_PP_ENUM_PARAMS(N,A)>();
}
template <class R, class T, BOOST_PP_ENUM_PARAMS(N,class A), class Wrapped>
BOOST_PP_CAT(mpl::vector,NPLUS2)<
R, typename most_derived<T,Wrapped>::type&, BOOST_PP_ENUM_PARAMS(N,A)
>
deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)), Wrapped*)
{
return BOOST_PP_CAT(mpl::vector,NPLUS2)<
R,typename most_derived<T,Wrapped>::type&,BOOST_PP_ENUM_PARAMS(N,A)>();
}
template <class R, class T, BOOST_PP_ENUM_PARAMS(N,class A)>
BOOST_PP_CAT(mpl::vector,NPLUS2)<R, T const&, BOOST_PP_ENUM_PARAMS(N,A)>
deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)) const)
{
return BOOST_PP_CAT(mpl::vector,NPLUS2)<R,T const&,BOOST_PP_ENUM_PARAMS(N,A)>();
}
template <class R, class T, BOOST_PP_ENUM_PARAMS(N,class A), class Wrapped>
BOOST_PP_CAT(mpl::vector,NPLUS2)<
R, typename most_derived<T,Wrapped>::type const&, BOOST_PP_ENUM_PARAMS(N,A)
>
deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)) const, Wrapped*)
{
return BOOST_PP_CAT(mpl::vector,NPLUS2)<
R,typename most_derived<T,Wrapped>::type const&,BOOST_PP_ENUM_PARAMS(N,A)>();
}
# undef NPLUS2
# undef NPLUS1
# undef N
#endif // BOOST_PP_IS_ITERATING

View File

@ -30,8 +30,8 @@
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/detail/class_rep.hpp> #include <luabind/detail/class_rep.hpp>
namespace luabind { namespace luabind
{
struct value; struct value;
struct value_vector : public std::vector<value> struct value_vector : public std::vector<value>
@ -45,7 +45,7 @@ namespace luabind {
struct value struct value
{ {
friend class std::vector<value>; friend class std::vector<value>;
template<class T> template<class T>
value(const char* name, T v) value(const char* name, T v)
: name_(name) : name_(name)
@ -65,7 +65,7 @@ namespace luabind {
return v; return v;
} }
private: private:
value() {} value() {}
}; };
@ -93,18 +93,19 @@ namespace luabind {
template<class From> template<class From>
struct enum_maker struct enum_maker
{ {
explicit enum_maker(From& from) : from_(from) {} explicit enum_maker(From& from): from_(from) {}
From& operator[](const value& val) From& operator[](const value& val)
{ {
from_.add_static_constant(val.name_, val.val_); from_.add_static_constant(val.name_, val.val_);
return from_; return from_;
} }
From& operator[](const value_vector& values) From& operator[](const value_vector& values)
{ {
for(const auto& val : values) { for (value_vector::const_iterator i = values.begin(); i != values.end(); ++i)
from_.add_static_constant(val.name_, val.val_); {
from_.add_static_constant(i->name_, i->val_);
} }
return from_; return from_;
@ -113,11 +114,10 @@ namespace luabind {
From& from_; From& from_;
private: private:
void operator=(enum_maker const&); // C4512, assignment operator could not be generated void operator=(enum_maker const&); // C4512, assignment operator could not be generated
template<class T> void operator,(T const&) const; template<class T> void operator,(T const&) const;
}; };
} }
} }
#endif // LUABIND_ENUM_MAKER_HPP_INCLUDED #endif // LUABIND_ENUM_MAKER_HPP_INCLUDED

View File

@ -5,70 +5,73 @@
#ifndef LUABIND_FORMAT_SIGNATURE_081014_HPP #ifndef LUABIND_FORMAT_SIGNATURE_081014_HPP
# define LUABIND_FORMAT_SIGNATURE_081014_HPP # define LUABIND_FORMAT_SIGNATURE_081014_HPP
#include <luabind/config.hpp> # include <luabind/config.hpp>
#include <luabind/lua_include.hpp> # include <luabind/lua_include.hpp>
#include <luabind/typeid.hpp> # include <luabind/typeid.hpp>
#include <luabind/detail/meta.hpp>
namespace luabind { # include <boost/mpl/begin_end.hpp>
namespace adl { # include <boost/mpl/next.hpp>
# include <boost/mpl/size.hpp>
class object; namespace luabind { namespace adl {
class argument;
template <class Base>
struct table;
} // namespace adl class object;
class argument;
template <class Base>
struct table;
} // namespace adl
using adl::object; using adl::object;
using adl::argument; using adl::argument;
using adl::table; using adl::table;
namespace detail { } // namespace luabind
LUABIND_API std::string get_class_name(lua_State* L, type_id const& i); namespace luabind { namespace detail {
template <class T, class Enable = void> LUABIND_API std::string get_class_name(lua_State* L, type_id const& i);
struct type_to_string
{
static void get(lua_State* L)
{
lua_pushstring(L, get_class_name(L, typeid(T)).c_str());
}
};
template <class T> template <class T>
struct type_to_string<T*> struct type_to_string
{ {
static void get(lua_State* L) static void get(lua_State* L)
{ {
type_to_string<T>::get(L); lua_pushstring(L, get_class_name(L, typeid(T)).c_str());
lua_pushstring(L, "*"); }
lua_concat(L, 2); };
}
};
template <class T> template <class T>
struct type_to_string<T&> struct type_to_string<T*>
{ {
static void get(lua_State* L) static void get(lua_State* L)
{ {
type_to_string<T>::get(L); type_to_string<T>::get(L);
lua_pushstring(L, "&"); lua_pushstring(L, "*");
lua_concat(L, 2); lua_concat(L, 2);
} }
}; };
template <class T> template <class T>
struct type_to_string<T const> struct type_to_string<T&>
{ {
static void get(lua_State* L) static void get(lua_State* L)
{ {
type_to_string<T>::get(L); type_to_string<T>::get(L);
lua_pushstring(L, " const"); lua_pushstring(L, "&");
lua_concat(L, 2); lua_concat(L, 2);
} }
}; };
template <class T>
struct type_to_string<T const>
{
static void get(lua_State* L)
{
type_to_string<T>::get(L);
lua_pushstring(L, " const");
lua_concat(L, 2);
}
};
# define LUABIND_TYPE_TO_STRING(x) \ # define LUABIND_TYPE_TO_STRING(x) \
template <> \ template <> \
@ -84,67 +87,67 @@ namespace luabind {
LUABIND_TYPE_TO_STRING(x) \ LUABIND_TYPE_TO_STRING(x) \
LUABIND_TYPE_TO_STRING(unsigned x) LUABIND_TYPE_TO_STRING(unsigned x)
LUABIND_INTEGRAL_TYPE_TO_STRING(char) LUABIND_INTEGRAL_TYPE_TO_STRING(char)
LUABIND_INTEGRAL_TYPE_TO_STRING(short) LUABIND_INTEGRAL_TYPE_TO_STRING(short)
LUABIND_INTEGRAL_TYPE_TO_STRING(int) LUABIND_INTEGRAL_TYPE_TO_STRING(int)
LUABIND_INTEGRAL_TYPE_TO_STRING(long) LUABIND_INTEGRAL_TYPE_TO_STRING(long)
LUABIND_TYPE_TO_STRING(void) LUABIND_TYPE_TO_STRING(void)
LUABIND_TYPE_TO_STRING(bool) LUABIND_TYPE_TO_STRING(bool)
LUABIND_TYPE_TO_STRING(std::string) LUABIND_TYPE_TO_STRING(std::string)
LUABIND_TYPE_TO_STRING(lua_State) LUABIND_TYPE_TO_STRING(lua_State)
LUABIND_TYPE_TO_STRING(luabind::object) LUABIND_TYPE_TO_STRING(luabind::object)
LUABIND_TYPE_TO_STRING(luabind::argument) LUABIND_TYPE_TO_STRING(luabind::argument)
# undef LUABIND_INTEGRAL_TYPE_TO_STRING # undef LUABIND_INTEGRAL_TYPE_TO_STRING
# undef LUABIND_TYPE_TO_STRING # undef LUABIND_TYPE_TO_STRING
template <class Base> template <class Base>
struct type_to_string<table<Base> > struct type_to_string<table<Base> >
{ {
static void get(lua_State* L) static void get(lua_State* L)
{ {
lua_pushstring(L, "table"); lua_pushstring(L, "table");
} }
}; };
inline void format_signature_aux(lua_State*, bool, meta::type_list< >) template <class End>
{} void format_signature_aux(lua_State*, bool, End, End)
{}
template <class Signature> template <class Iter, class End>
void format_signature_aux(lua_State* L, bool first, Signature) void format_signature_aux(lua_State* L, bool first, Iter, End end)
{ {
if(!first) if (!first)
lua_pushstring(L, ","); lua_pushstring(L, ",");
type_to_string<typename meta::front<Signature>::type>::get(L); type_to_string<typename Iter::type>::get(L);
format_signature_aux(L, false, typename meta::pop_front<Signature>::type()); format_signature_aux(L, false, typename mpl::next<Iter>::type(), end);
} }
template <class Signature> template <class Signature>
void format_signature(lua_State* L, char const* function, Signature) void format_signature(lua_State* L, char const* function, Signature)
{ {
using first = typename meta::front<Signature>::type; typedef typename mpl::begin<Signature>::type first;
type_to_string<first>::get(L); type_to_string<typename first::type>::get(L);
lua_pushstring(L, " "); lua_pushstring(L, " ");
lua_pushstring(L, function); lua_pushstring(L, function);
lua_pushstring(L, "("); lua_pushstring(L, "(");
format_signature_aux( format_signature_aux(
L L
, true , true
, typename meta::pop_front<Signature>::type() , typename mpl::next<first>::type()
); , typename mpl::end<Signature>::type()
lua_pushstring(L, ")"); );
constexpr size_t ncat = meta::size<Signature>::value * 2 + 2 + (meta::size<Signature>::value == 1 ? 1 : 0); lua_pushstring(L, ")");
lua_concat(L, static_cast<int>(ncat));
}
} // namespace detail lua_concat(L, static_cast<int>(mpl::size<Signature>()) * 2 + 2);
}
} // namespace luabind }} // namespace luabind::detail
#endif // LUABIND_FORMAT_SIGNATURE_081014_HPP #endif // LUABIND_FORMAT_SIGNATURE_081014_HPP

View File

@ -1,4 +1,4 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"), // copy of this software and associated documentation files (the "Software"),
@ -26,31 +26,28 @@
#include <luabind/config.hpp> #include <luabind/config.hpp>
namespace luabind { namespace luabind { namespace detail
namespace detail { {
// function that is used as __gc metafunction on several objects
template<class T>
inline int garbage_collector(lua_State* L)
{
T* obj = static_cast<T*>(lua_touserdata(L, -1));
obj->~T();
return 0;
}
// function that is used as __gc metafunction on several objects template<class T>
template<class T> struct garbage_collector_s
inline int garbage_collector(lua_State* L) {
static int apply(lua_State* L)
{ {
T* obj = static_cast<T*>(lua_touserdata(L, -1)); T* obj = static_cast<T*>(lua_touserdata(L, -1));
obj->~T(); obj->~T();
return 0; return 0;
} }
};
template<class T> }}
struct garbage_collector_s
{
static int apply(lua_State* L)
{
T* obj = static_cast<T*>(lua_touserdata(L, -1));
obj->~T();
return 0;
}
};
}
}
#endif // LUABIND_GARBAGE_COLLECTOR_HPP_INCLUDED #endif // LUABIND_GARBAGE_COLLECTOR_HPP_INCLUDED

View File

@ -0,0 +1,107 @@
// Copyright (c) 2005 Daniel Wallin
// 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 LUABIND_HAS_GET_POINTER_051022_HPP
# define LUABIND_HAS_GET_POINTER_051022_HPP
# include <boost/type_traits/add_reference.hpp>
# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
# include <memory>
# endif
namespace luabind { namespace detail {
namespace has_get_pointer_
{
struct any
{
template<class T> any(T const&);
};
struct no_overload_tag
{};
typedef char (&yes)[1];
typedef char (&no)[2];
no_overload_tag operator,(no_overload_tag, int);
//
// On compilers with ADL, we need these generic overloads in this
// namespace as well as in luabind::. Otherwise get_pointer(any)
// will be found before them.
//
# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
template<class T>
T* get_pointer(T const volatile*);
template<class T>
T* get_pointer(std::auto_ptr<T> const&);
# endif
//
// On compilers that doesn't support ADL, the overload below has to
// live in luabind::.
//
# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
}} // namespace detail::has_get_pointer_
# endif
detail::has_get_pointer_::no_overload_tag
get_pointer(detail::has_get_pointer_::any);
# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
namespace detail { namespace has_get_pointer_
{
# endif
template<class T>
yes check(T const&);
no check(no_overload_tag);
template<class T>
struct impl
{
static typename boost::add_reference<T>::type x;
BOOST_STATIC_CONSTANT(bool,
value = sizeof(has_get_pointer_::check( (get_pointer(x),0) )) == 1
);
typedef boost::mpl::bool_<value> type;
};
} // namespace has_get_pointer_
template<class T>
struct has_get_pointer
: has_get_pointer_::impl<T>::type
{};
}} // namespace luabind::detail
#endif // LUABIND_HAS_GET_POINTER_051022_HPP

View File

@ -1,169 +1,168 @@
// Copyright Daniel Wallin 2009. Use, modification and distribution is // Copyright Daniel Wallin 2009. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying // subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef LUABIND_INHERITANCE_090217_HPP #ifndef LUABIND_INHERITANCE_090217_HPP
# define LUABIND_INHERITANCE_090217_HPP # define LUABIND_INHERITANCE_090217_HPP
# include <luabind/config.hpp>
# include <cassert> # include <cassert>
# include <limits> # include <limits>
# include <map> # include <map>
# include <memory> # include <memory>
# include <vector> # include <vector>
# include <luabind/typeid.hpp> # include <luabind/typeid.hpp>
# include <boost/scoped_ptr.hpp>
namespace luabind { namespace luabind { namespace detail {
namespace detail { typedef void*(*cast_function)(void*);
typedef std::size_t class_id;
using cast_function = void*(*)(void*); class_id const unknown_class = (std::numeric_limits<class_id>::max)();
using class_id = std::size_t;
constexpr class_id unknown_class = std::numeric_limits<class_id>::max(); class class_rep;
class class_rep; class LUABIND_API cast_graph
{
public:
cast_graph();
~cast_graph();
class LUABIND_API cast_graph // `src` and `p` here describe the *most derived* object. This means that
{ // for a polymorphic type, the pointer must be cast with
public: // dynamic_cast<void*> before being passed in here, and `src` has to
cast_graph(); // match typeid(*p).
~cast_graph(); std::pair<void*, int> cast(
void* p, class_id src, class_id target
, class_id dynamic_id, void const* dynamic_ptr) const;
void insert(class_id src, class_id target, cast_function cast);
// `src` and `p` here describe the *most derived* object. This means that private:
// for a polymorphic type, the pointer must be cast with class impl;
// dynamic_cast<void*> before being passed in here, and `src` has to boost::scoped_ptr<impl> m_impl;
// match typeid(*p). };
std::pair<void*, int> cast(void* p, class_id src, class_id target, class_id dynamic_id, void const* dynamic_ptr) const;
void insert(class_id src, class_id target, cast_function cast);
private: // Maps a type_id to a class_id. Note that this actually partitions the
class impl; // id-space into two, using one half for "local" ids; ids that are used only as
std::unique_ptr<impl> m_impl; // keys into the conversion cache. This is needed because we need a unique key
}; // even for types that hasn't been registered explicitly.
class LUABIND_API class_id_map
{
public:
class_id_map();
// Maps a type_id to a class_id. Note that this actually partitions the class_id get(type_id const& type) const;
// id-space into two, using one half for "local" ids; ids that are used only as class_id get_local(type_id const& type);
// keys into the conversion cache. This is needed because we need a unique key void put(class_id id, type_id const& type);
// even for types that hasn't been registered explicitly.
class LUABIND_API class_id_map
{
public:
class_id_map();
class_id get(type_id const& type) const; private:
class_id get_local(type_id const& type); typedef std::map<type_id, class_id> map_type;
void put(class_id id, type_id const& type); map_type m_classes;
class_id m_local_id;
private: static class_id const local_id_base;
using map_type = std::map<type_id, class_id>; };
map_type m_classes;
class_id m_local_id;
static class_id const local_id_base; inline class_id_map::class_id_map()
}; : m_local_id(local_id_base)
{}
inline class_id_map::class_id_map() inline class_id class_id_map::get(type_id const& type) const
: m_local_id(local_id_base) {
{} map_type::const_iterator i = m_classes.find(type);
if (i == m_classes.end() || i->second >= local_id_base)
return unknown_class;
return i->second;
}
inline class_id class_id_map::get(type_id const& type) const inline class_id class_id_map::get_local(type_id const& type)
{ {
map_type::const_iterator i = m_classes.find(type); std::pair<map_type::iterator, bool> result = m_classes.insert(
if(i == m_classes.end() || i->second >= local_id_base) { std::make_pair(type, 0));
return unknown_class;
}
else {
return i->second;
}
}
inline class_id class_id_map::get_local(type_id const& type) if (result.second)
{ result.first->second = m_local_id++;
std::pair<map_type::iterator, bool> result = m_classes.insert(std::make_pair(type, 0));
if(result.second) result.first->second = m_local_id++; assert(m_local_id >= local_id_base);
assert(m_local_id >= local_id_base);
return result.first->second;
}
inline void class_id_map::put(class_id id, type_id const& type) return result.first->second;
{ }
assert(id < local_id_base);
std::pair<map_type::iterator, bool> result = m_classes.insert( inline void class_id_map::put(class_id id, type_id const& type)
std::make_pair(type, 0)); {
assert(id < local_id_base);
assert( std::pair<map_type::iterator, bool> result = m_classes.insert(
result.second std::make_pair(type, 0));
|| result.first->second == id
|| result.first->second >= local_id_base
);
result.first->second = id; assert(
} result.second
|| result.first->second == id
|| result.first->second >= local_id_base
);
class class_map result.first->second = id;
{ }
public:
class_rep* get(class_id id) const;
void put(class_id id, class_rep* cls);
private: class class_map
std::vector<class_rep*> m_classes; {
}; public:
class_rep* get(class_id id) const;
void put(class_id id, class_rep* cls);
inline class_rep* class_map::get(class_id id) const private:
{ std::vector<class_rep*> m_classes;
if(id >= m_classes.size()) };
return 0;
return m_classes[id];
}
inline void class_map::put(class_id id, class_rep* cls) inline class_rep* class_map::get(class_id id) const
{ {
if(id >= m_classes.size()) if (id >= m_classes.size())
m_classes.resize(id + 1); return 0;
m_classes[id] = cls; return m_classes[id];
} }
template <class S, class T> inline void class_map::put(class_id id, class_rep* cls)
struct static_cast_ {
{ if (id >= m_classes.size())
static void* execute(void* p) m_classes.resize(id + 1);
{ m_classes[id] = cls;
return static_cast<T*>(static_cast<S*>(p)); }
}
};
template <class S, class T> template <class S, class T>
struct dynamic_cast_ struct static_cast_
{ {
static void* execute(void* p) static void* execute(void* p)
{ {
return dynamic_cast<T*>(static_cast<S*>(p)); return static_cast<T*>(static_cast<S*>(p));
} }
}; };
// Thread safe class_id allocation. template <class S, class T>
LUABIND_API class_id allocate_class_id(type_id const& cls); struct dynamic_cast_
{
static void* execute(void* p)
{
return dynamic_cast<T*>(static_cast<S*>(p));
}
};
template <class T> // Thread safe class_id allocation.
struct registered_class LUABIND_API class_id allocate_class_id(type_id const& cls);
{
static class_id const id;
};
template <class T> template <class T>
class_id const registered_class<T>::id = allocate_class_id(typeid(T)); struct registered_class
{
static class_id const id;
};
template <class T> template <class T>
struct registered_class<T const> class_id const registered_class<T>::id = allocate_class_id(typeid(T));
: registered_class<T>
{};
} // namespace detail template <class T>
struct registered_class<T const>
: registered_class<T>
{};
} // namespace luabind }} // namespace luabind::detail
#endif // LUABIND_INHERITANCE_090217_HPP #endif // LUABIND_INHERITANCE_090217_HPP

View File

@ -6,160 +6,126 @@
# define LUABIND_INSTANCE_HOLDER_081024_HPP # define LUABIND_INSTANCE_HOLDER_081024_HPP
# include <luabind/detail/inheritance.hpp> # include <luabind/detail/inheritance.hpp>
# include <luabind/pointer_traits.hpp> # include <luabind/detail/class_rep.hpp> // TODO
# include <luabind/get_pointer.hpp>
# include <luabind/typeid.hpp> # include <luabind/typeid.hpp>
# include <boost/type_traits/is_polymorphic.hpp>
# include <stdexcept> # include <stdexcept>
namespace luabind { namespace luabind { namespace detail {
namespace detail {
class instance_holder class instance_holder
{ {
public: public:
instance_holder(bool pointee_const) instance_holder(class_rep* cls, bool pointee_const)
: m_pointee_const(pointee_const) : m_cls(cls)
{} , m_pointee_const(pointee_const)
{}
virtual ~instance_holder() virtual ~instance_holder()
{} {}
virtual std::pair<void*, int> get(cast_graph const& casts, class_id target) const = 0; virtual std::pair<void*, int> get(class_id target) const = 0;
virtual void release() = 0;
bool pointee_const() const virtual void release() = 0;
{
return m_pointee_const;
}
private: class_rep* get_class() const
bool m_pointee_const; {
}; return m_cls;
}
template <class P, class Pointee = void const> bool pointee_const() const
class pointer_holder : public instance_holder {
{ return m_pointee_const;
public: }
pointer_holder(P p, class_id dynamic_id, void* dynamic_ptr) :
instance_holder(detail::is_pointer_to_const<P>()),
p(std::move(p)), weak(0), dynamic_id(dynamic_id), dynamic_ptr(dynamic_ptr)
{
}
std::pair<void*, int> get(cast_graph const& casts, class_id target) const override private:
{ class_rep* m_cls;
// if somebody wants the smart-ptr, he can get a reference to it bool m_pointee_const;
if(target == registered_class<P>::id) return std::pair<void*, int>(&this->p, 0); };
void* naked_ptr = const_cast<void*>(static_cast<void const*>(weak ? weak : get_pointer(p))); namespace mpl = boost::mpl;
if(!naked_ptr) return std::pair<void*, int>(nullptr, 0);
using pointee_type = typename std::remove_cv<typename std::remove_reference<decltype(*get_pointer(p))>::type>::type; inline mpl::false_ check_const_pointer(void*)
{
return mpl::false_();
}
return casts.cast(naked_ptr, inline mpl::true_ check_const_pointer(void const*)
registered_class< pointee_type >::id, {
target, dynamic_id, dynamic_ptr); return mpl::true_();
} }
explicit operator bool() const template <class T>
{ void release_ownership(std::auto_ptr<T>& p)
return p ? true : false; {
} p.release();
}
void release() override template <class P>
{ void release_ownership(P const&)
weak = const_cast<void*>(static_cast<void const*>(get_pointer(p))); {
release_ownership(p); throw std::runtime_error(
} "luabind: smart pointer does not allow ownership transfer");
}
private: template <class T>
mutable P p; class_id static_class_id(T*)
// weak will hold a possibly stale pointer to the object owned {
// by p once p has released it's owership. This is a workaround return registered_class<T>::id;
// to make adopt() work with virtual function wrapper classes. }
void* weak;
class_id dynamic_id;
void* dynamic_ptr;
};
template <class ValueType> template <class P, class Pointee = void const>
class value_holder : class pointer_holder : public instance_holder
public instance_holder {
{ public:
public: pointer_holder(
// No need for dynamic_id / dynamic_ptr, since we always get the most derived type P p, class_id dynamic_id, void* dynamic_ptr, class_rep* cls
value_holder(lua_State* /*L*/, ValueType val) )
: instance_holder(false), val_(std::move(val)) : instance_holder(cls, check_const_pointer(false ? get_pointer(p) : 0))
{} , p(p)
, weak(0)
, dynamic_id(dynamic_id)
, dynamic_ptr(dynamic_ptr)
{}
explicit operator bool() const std::pair<void*, int> get(class_id target) const
{ {
return true; if (target == registered_class<P>::id)
} return std::pair<void*, int>(&this->p, 0);
std::pair<void*, int> get(cast_graph const& casts, class_id target) const override void* naked_ptr = const_cast<void*>(static_cast<void const*>(
{ weak ? weak : get_pointer(p)));
const auto this_id = registered_class<ValueType>::id;
void* const naked_ptr = const_cast<void*>((const void*)&val_);
if(target == this_id) return std::pair<void*, int>(naked_ptr, 0);
return casts.cast(naked_ptr, this_id, target, this_id, naked_ptr);
}
void release() override if (!naked_ptr)
{} return std::pair<void*, int>((void*)0, 0);
private: return get_class()->casts().cast(
ValueType val_; naked_ptr
}; , static_class_id(false ? get_pointer(p) : 0)
, target
, dynamic_id
, dynamic_ptr
);
}
/* void release()
Pointer types should automatically convert to reference types {
*/ weak = const_cast<void*>(static_cast<void const*>(
template <class ValueType> get_pointer(p)));
class pointer_like_holder : release_ownership(p);
public instance_holder }
{
public:
// No need for dynamic_id / dynamic_ptr, since we always get the most derived type
pointer_like_holder(lua_State* /*L*/, ValueType val, class_id dynamic_id, void* dynamic_ptr)
:
instance_holder(std::is_const< decltype(*get_pointer(val)) >::value),
val_(std::move(val)),
dynamic_id_(dynamic_id),
dynamic_ptr_(dynamic_ptr)
{
}
explicit operator bool() const private:
{ mutable P p;
return val_ ? true : false; // weak will hold a possibly stale pointer to the object owned
} // by p once p has released it's owership. This is a workaround
// to make adopt() work with virtual function wrapper classes.
void* weak;
class_id dynamic_id;
void* dynamic_ptr;
};
std::pair<void*, int> get(cast_graph const& casts, class_id target) const override }} // namespace luabind::detail
{
const auto value_id = registered_class<ValueType>::id;
void* const naked_value_ptr = const_cast<void*>((const void*)&val_);
if(target == value_id) return std::pair<void*, int>(naked_value_ptr, 0);
// If we were to support automatic pointer conversion, this would be the place
using pointee_type = typename std::remove_cv<typename std::remove_reference<decltype(*get_pointer(val_))>::type >::type;
const auto pointee_id = registered_class< pointee_type >::id;
void* const naked_pointee_ptr = const_cast<void*>((const void*)get_pointer(val_));
return casts.cast(naked_pointee_ptr, pointee_id, target, dynamic_id_, dynamic_ptr_);
}
void release() override
{}
private:
ValueType val_;
class_id dynamic_id_;
void* dynamic_ptr_;
// weak? must understand what the comment up there really means
};
}
} // namespace luabind::detail
#endif // LUABIND_INSTANCE_HOLDER_081024_HPP #endif // LUABIND_INSTANCE_HOLDER_081024_HPP

View File

@ -0,0 +1,70 @@
// Copyright (c) 2004 Daniel Wallin and Arvid Norberg
// 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 IS_INDIRECT_CONST_040211_HPP
#define IS_INDIRECT_CONST_040211_HPP
#include <luabind/detail/yes_no.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/mpl/bool.hpp>
namespace luabind {
namespace detail {
template<class T>
typename boost::is_const<T>::type
is_indirect_const_check(T(*)(), int);
template<class T>
typename boost::is_const<T>::type
is_indirect_const_check(T*(*)(), long);
template<class T>
typename boost::is_const<T>::type
is_indirect_const_check(T&(*)(), long);
yes_t to_yes_no(boost::mpl::true_);
no_t to_yes_no(boost::mpl::false_);
} // namespace detail
// returns true for:
// T = U* is_const<U>
// T = U& is_const<U>
// T = U is_const<U>
template<class T>
struct is_indirect_const
{
BOOST_STATIC_CONSTANT(int, value = (
sizeof(
detail::to_yes_no(
detail::is_indirect_const_check((T(*)())0, 0L)
))
== sizeof(detail::yes_t)
));
};
} // namespace luabind
#endif // IS_INDIRECT_CONST_040211_HPP

View File

@ -25,38 +25,36 @@
#include <luabind/config.hpp> #include <luabind/config.hpp>
namespace luabind { namespace luabind { namespace detail
namespace detail { {
#ifdef LUABIND_NOT_THREADSAFE #ifdef LUABIND_NOT_THREADSAFE
LUABIND_API void not_threadsafe_defined_conflict(); LUABIND_API void not_threadsafe_defined_conflict();
#else #else
LUABIND_API void not_threadsafe_not_defined_conflict(); LUABIND_API void not_threadsafe_not_defined_conflict();
#endif #endif
#ifdef LUABIND_NO_ERROR_CHECKING #ifdef LUABIND_NO_ERROR_CHECKING
LUABIND_API void no_error_checking_defined_conflict(); LUABIND_API void no_error_checking_defined_conflict();
#else #else
LUABIND_API void no_error_checking_not_defined_conflict(); LUABIND_API void no_error_checking_not_defined_conflict();
#endif #endif
inline void check_link_compatibility() inline void check_link_compatibility()
{ {
#ifdef LUABIND_NOT_THREADSAFE #ifdef LUABIND_NOT_THREADSAFE
not_threadsafe_defined_conflict(); not_threadsafe_defined_conflict();
#else #else
not_threadsafe_not_defined_conflict(); not_threadsafe_not_defined_conflict();
#endif #endif
#ifdef LUABIND_NO_ERROR_CHECKING
no_error_checking_defined_conflict();
#else
no_error_checking_not_defined_conflict();
#endif
}
#ifdef LUABIND_NO_ERROR_CHECKING
no_error_checking_defined_conflict();
#else
no_error_checking_not_defined_conflict();
#endif
} }
}
}}
#endif #endif

View File

@ -5,167 +5,101 @@
#ifndef LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP #ifndef LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP
# define LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP # define LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP
# include <boost/type_traits/is_polymorphic.hpp>
# include <luabind/detail/inheritance.hpp> # include <luabind/detail/inheritance.hpp>
# include <luabind/detail/object_rep.hpp> # include <luabind/detail/object_rep.hpp>
namespace luabind { namespace luabind { namespace detail {
namespace detail {
template <class T> template <class T>
std::pair<class_id, void*> get_dynamic_class_aux(lua_State* L, T const* p, std::true_type) std::pair<class_id, void*> get_dynamic_class_aux(
{ lua_State* L, T const* p, mpl::true_)
lua_pushliteral(L, "__luabind_class_id_map"); {
lua_rawget(L, LUA_REGISTRYINDEX); lua_pushliteral(L, "__luabind_class_id_map");
class_id_map& class_ids = *static_cast<class_id_map*>(lua_touserdata(L, -1)); lua_rawget(L, LUA_REGISTRYINDEX);
lua_pop(L, 1);
return std::make_pair(class_ids.get_local(typeid(*p)), dynamic_cast<void*>(const_cast<T*>(p))); class_id_map& class_ids = *static_cast<class_id_map*>(
} lua_touserdata(L, -1));
template <class T> lua_pop(L, 1);
std::pair<class_id, void*> get_dynamic_class_aux(lua_State*, T const* p, std::false_type)
{
return std::make_pair(registered_class<T>::id, (void*)p);
}
template <class T> return std::make_pair(
std::pair<class_id, void*> get_dynamic_class(lua_State* L, T* p) class_ids.get_local(typeid(*p))
{ , dynamic_cast<void*>(const_cast<T*>(p))
return get_dynamic_class_aux(L, p, std::is_polymorphic<T>()); );
} }
template <class T> template <class T>
class_rep* get_pointee_class(class_map const& classes, T*) std::pair<class_id, void*> get_dynamic_class_aux(
{ lua_State*, T const* p, mpl::false_)
return classes.get(registered_class<T>::id); {
} return std::make_pair(registered_class<T>::id, (void*)p);
}
template <class P> template <class T>
class_rep* get_pointee_class(lua_State* L, P const& p, class_id dynamic_id) std::pair<class_id, void*> get_dynamic_class(lua_State* L, T* p)
{ {
lua_pushliteral(L, "__luabind_class_map"); return get_dynamic_class_aux(L, p, boost::is_polymorphic<T>());
lua_rawget(L, LUA_REGISTRYINDEX); }
class_map const& classes = *static_cast<class_map*>(lua_touserdata(L, -1)); template <class T>
class_rep* get_pointee_class(class_map const& classes, T*)
{
return classes.get(registered_class<T>::id);
}
lua_pop(L, 1); template <class P>
class_rep* get_pointee_class(lua_State* L, P const& p, class_id dynamic_id)
{
lua_pushliteral(L, "__luabind_class_map");
lua_rawget(L, LUA_REGISTRYINDEX);
class_rep* cls = classes.get(dynamic_id); class_map const& classes = *static_cast<class_map*>(
lua_touserdata(L, -1));
if(!cls) { lua_pop(L, 1);
cls = get_pointee_class(classes, get_pointer(p));
}
return cls; class_rep* cls = classes.get(dynamic_id);
}
// Create an appropriate instance holder for the given pointer like object. if (!cls)
template <class P> cls = get_pointee_class(classes, get_pointer(p));
void make_pointer_instance(lua_State* L, P p)
{
std::pair<class_id, void*> dynamic = get_dynamic_class(L, get_pointer(p));
class_rep* cls = get_pointee_class(L, p, dynamic.first); return cls;
}
if(!cls) // Create an appropriate instance holder for the given pointer like object.
{ template <class P>
throw std::runtime_error("Trying to use unregistered class: " + std::string(typeid(P).name())); void make_instance(lua_State* L, P p)
} {
std::pair<class_id, void*> dynamic = get_dynamic_class(L, get_pointer(p));
object_rep* instance = push_new_instance(L, cls); class_rep* cls = get_pointee_class(L, p, dynamic.first);
using value_type = typename std::remove_reference<P>::type; if (!cls)
using holder_type = pointer_holder<value_type>; {
throw std::runtime_error("Trying to use unregistered class");
}
void* storage = instance->allocate(sizeof(holder_type)); object_rep* instance = push_new_instance(L, cls);
try typedef pointer_holder<P> holder_type;
{
new (storage) holder_type(std::move(p), dynamic.first, dynamic.second);
}
catch(...)
{
instance->deallocate(storage);
lua_pop(L, 1);
throw;
}
instance->set_instance(static_cast<holder_type*>(storage)); void* storage = instance->allocate(sizeof(holder_type));
}
try
{
new (storage) holder_type(p, dynamic.first, dynamic.second, cls);
}
catch (...)
{
instance->deallocate(storage);
lua_pop(L, 1);
throw;
}
template< typename ValueType > instance->set_instance(static_cast<holder_type*>(storage));
void make_value_instance(lua_State* L, ValueType&& val, std::true_type /* is smart ptr */) }
{
if(get_pointer(val)) {
std::pair<class_id, void*> dynamic = get_dynamic_class(L, get_pointer(val));
class_rep* cls = get_pointee_class(L, val, dynamic.first);
using pointee_type = decltype(*get_pointer(val)); }} // namespace luabind::detail
if(!cls) {
throw std::runtime_error("Trying to use unregistered class: " + std::string(typeid(pointee_type).name()));
}
object_rep* instance = push_new_instance(L, cls);
using value_type = typename std::remove_reference<ValueType>::type;
using holder_type = pointer_like_holder<value_type>;
void* storage = instance->allocate(sizeof(holder_type));
try {
new (storage) holder_type(L, std::forward<ValueType>(val), dynamic.first, dynamic.second);
}
catch(...) {
instance->deallocate(storage);
lua_pop(L, 1);
throw;
}
instance->set_instance(static_cast<holder_type*>(storage));
} else {
lua_pushnil(L);
}
}
template< typename ValueType >
void make_value_instance(lua_State* L, ValueType&& val, std::false_type /* smart ptr */)
{
const auto value_type_id = detail::registered_class<ValueType>::id;
class_rep* cls = get_pointee_class(L, &val, value_type_id);
if(!cls) {
throw std::runtime_error("Trying to use unregistered class: " + std::string(typeid(ValueType).name()));
}
object_rep* instance = push_new_instance(L, cls);
using value_type = typename std::remove_reference<ValueType>::type;
using holder_type = value_holder<value_type>;
void* storage = instance->allocate(sizeof(holder_type));
try {
new (storage) holder_type(L, std::forward<ValueType>(val));
}
catch(...) {
instance->deallocate(storage);
lua_pop(L, 1);
throw;
}
instance->set_instance(static_cast<holder_type*>(storage));
}
template< typename ValueType >
void make_value_instance(lua_State* L, ValueType&& val)
{
make_value_instance(L, std::forward<ValueType>(val), has_get_pointer<ValueType>());
}
} // namespace detail
} // namespace luabind
#endif // LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP #endif // LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP

View File

@ -1,581 +0,0 @@
// Copyright Michael Steinberg 2013. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef LUABIND_META_HPP_INCLUDED
#define LUABIND_META_HPP_INCLUDED
#include <tuple>
namespace luabind {
namespace meta {
struct type_list_tag {};
struct index_list_tag {};
/*
Index list and type list share pretty common patterns... is there a way to unify them?
*/
template< unsigned int >
struct count
{};
template< unsigned int >
struct index
{};
template< typename Type >
struct type
{};
// Use this to unpack a parameter pack into a list of T's
template< typename T, typename DontCare >
struct unpack_helper
{
using type = T;
};
struct init_order {
init_order(std::initializer_list<int>) {}
};
// common operators
template< typename T >
struct size;
template< typename T, unsigned int Index > // Specializations so index lists can use the same syntax
struct get;
template< typename... Lists >
struct join;
template< typename List1, typename List2, typename... Lists >
struct join< List1, List2, Lists... > {
// Could try to join on both sides
using type = typename join< typename join< List1, List2 >::type, Lists... >::type;
};
// convenience
template< typename T >
struct front : public get< T, 0 >
{
};
template< typename List, typename T >
struct push_front;
template< typename List, typename T >
struct push_back;
template< typename T >
struct pop_front;
template< typename T >
struct pop_back;
template< typename List, unsigned int Index, typename T >
struct replace;
template< typename List, unsigned int Index, template< typename > class T >
struct enwrap;
template< typename List, template< typename > class T >
struct enwrap_all;
template< typename List, unsigned int Index, template< typename > class T >
struct transform;
template< typename List, unsigned int Index, template< typename > class Function >
using transform_t = typename transform< List, Index, Function >::type;
template< typename List, template< typename > class Function >
struct transform_all;
template< typename List, template< typename > class Function >
using transform_all_t = typename transform_all< List, Function >::type;
template< typename T, unsigned int start, unsigned int end >
struct sub_range;
/*
aliases
*/
template< typename T >
using pop_front_t = typename pop_front<T>::type;
template< typename T1, typename... Types >
using join_t = typename join< T1, Types... >::type;
template< typename T, unsigned int start, unsigned int end >
using sub_range_t = typename sub_range< T, start, end >::type;
template< typename T, unsigned int index >
using get_t = typename get< T, index >::type;
// Used as terminator on type and index lists
struct null_type {};
template< typename... Types >
struct type_list : public type_list_tag
{
template< unsigned int Index >
using at = typename get<type_list, Index>::type;
};
template< typename... Types1, typename... Types2 >
type_list<Types1..., Types2...> operator|(const type_list<Types1...>&, const type_list<Types2...>&) {
return type_list<Types1..., Types2...>();
}
template< typename T >
struct is_typelist : public std::false_type
{
static const bool value = false;
};
template< typename... Types >
struct is_typelist< type_list< Types... > > : public std::true_type
{
static const bool value = true;
};
/*
Find type
*/
template< typename TypeList, typename Type >
struct contains;
template< typename Type0, typename... Types, typename Type >
struct contains< type_list<Type0, Types...>, Type >
: std::conditional< std::is_same<Type0, Type>::value, std::true_type, contains< type_list<Types...>, Type > >::type
{
};
template< typename Type >
struct contains< type_list< >, Type >
: std::false_type
{
};
/*
size
*/
template< >
struct size< type_list< > > {
enum { value = 0 };
};
template< typename Type0, typename... Types >
struct size< type_list< Type0, Types... > > {
enum { value = 1 + size< type_list<Types...> >::value };
};
template< typename... Types, typename Type >
struct push_front< type_list<Types...>, Type >
{
using type = type_list< Type, Types... >;
};
template< typename... Types, typename Type >
struct push_back< type_list<Types...>, Type >
{
using type = type_list< Types..., Type >;
};
/*
pop_front
*/
template< typename Type0, typename... Types >
struct pop_front< type_list< Type0, Types... > >
{
using type = type_list< Types... >;
};
template< >
struct pop_front< type_list< > >
{
using type = type_list< >;
};
/*
Index access to type list
*/
template< typename Element0, typename... Elements, unsigned int Index >
struct get< type_list<Element0, Elements...>, Index > {
using type = typename get< type_list<Elements...>, Index - 1 >::type;
};
template< typename Element0, typename... Elements >
struct get< type_list<Element0, Elements...>, 0 >
{
using type = Element0;
};
template< unsigned int Index >
struct get< type_list< >, Index >
{
static_assert(size< type_list< int > >::value == 1, "Bad Index");
};
/*
Join Type Lists
*/
template< typename... Types1, typename... Types2 >
struct join< type_list< Types1... >, type_list< Types2... > >
{
using type = type_list< Types1..., Types2... >;
};
namespace detail {
template< typename HeadList, typename TailList, typename Type, unsigned int Index >
struct replace_helper;
template< typename... HeadTypes, typename CurrentType, typename... TailTypes, typename Type, unsigned int Index >
struct replace_helper< type_list< HeadTypes... >, type_list< CurrentType, TailTypes... >, Type, Index> {
using type = typename replace_helper< type_list< HeadTypes..., CurrentType >, type_list<TailTypes...>, Type, Index - 1 >::type;
};
template< typename... HeadTypes, typename CurrentType, typename... TailTypes, typename Type >
struct replace_helper< type_list< HeadTypes... >, type_list< CurrentType, TailTypes... >, Type, 0 > {
using type = type_list< HeadTypes..., Type, TailTypes... >;
};
}
template< typename... Types, unsigned int Index, typename Type >
struct replace< type_list< Types... >, Index, Type >
{
using TypeList = type_list< Types... >;
using type = join_t<
sub_range_t< TypeList, 0, Index >,
meta::type_list<Type>,
sub_range_t< TypeList, Index + 1, sizeof...(Types) >
>;
};
/*
Enwrap all elements of a type list in an template
*/
template< typename... Types, unsigned int Index, template< typename > class Enwrapper >
struct enwrap< type_list< Types... >, Index, Enwrapper > {
using type = join_t<
sub_range_t< type_list<Types...>, 0, Index >,
Enwrapper< get_t< type_list<Types...>, Index> >,
sub_range_t< type_list<Types...>, Index + 1, sizeof...(Types) >
>;
};
template< typename... Types, template< typename > class Enwrapper >
struct enwrap_all< type_list< Types... >, Enwrapper >
{
using type = type_list< Enwrapper< Types >... >;
};
/*
Transform a certain element of a type list
*/
template< typename T, unsigned int Index, template< typename > class Function >
struct transform;
template< typename... Types, unsigned int Index, template< typename > class Function >
struct transform< type_list< Types... >, Index, Function > {
using type = join_t<
sub_range_t< type_list<Types...>, 0, Index >,
typename Function< get_t< type_list<Types...>, Index> >::type,
sub_range_t< type_list<Types...>, Index + 1, sizeof...(Types) >
>;
};
/*
Transform all elements of a type list
*/
template< typename... Types, template< typename > class Function >
struct transform_all< type_list< Types... >, Function > {
using type = type_list< typename Function<Types>::type... >;
};
/*
Tuple from type list
*/
template< class TypeList >
struct make_tuple;
template< typename... Types >
struct make_tuple< type_list< Types... > >
{
using type = std::tuple< Types... >;
};
/*
Type selection
*/
template< typename ConvertibleToTrueFalse, typename Result >
struct case_ : public ConvertibleToTrueFalse {
using type = Result;
};
template< typename Result >
struct default_ {
using type = Result;
};
template< typename Case, typename... CaseList >
struct select_
{
using type = typename std::conditional<
std::is_convertible<Case, std::true_type>::value,
typename Case::type,
typename select_<CaseList...>::type
>::type;
};
template< typename Case >
struct select_< Case >
{
using type = typename std::conditional<
std::is_convertible<Case, std::true_type>::value,
typename Case::type,
null_type
>::type;
};
template< typename T >
struct select_< default_<T> > {
using type = typename default_<T>::type;
};
/*
Create index lists to expand on type_lists
*/
template< unsigned int... Indices >
struct index_list : public index_list_tag
{
};
/*
Index index list
*/
namespace detail {
template< unsigned int Index, unsigned int Value0, unsigned int... Values >
struct get_iterate {
static const unsigned int value = get_iterate< Index - 1, Values... >::value;
};
template< unsigned int Value0, unsigned int... Values >
struct get_iterate< 0, Value0, Values... > {
static const unsigned int value = Value0;
};
}
template< unsigned int... Values, unsigned int Index >
struct get< index_list< Values... >, Index >
{
static_assert(sizeof...(Values) > Index, "Bad Index");
static const unsigned int value = detail::get_iterate< Index, Values... >::value;
};
/*
Index list size
*/
template< unsigned int... Values >
struct size< index_list< Values... > > {
static const unsigned int value = sizeof...(Values);
};
/*
Index list push front
*/
template< unsigned int... Indices, unsigned int Index >
struct push_front< index_list< Indices... >, index<Index> >
{
using type = index_list< Index, Indices... >;
};
/*
Index list push back
*/
template< unsigned int... Indices, unsigned int Index >
struct push_back< index_list< Indices... >, index<Index> >
{
using type = index_list< Indices..., Index >;
};
/*
Index list pop_front
*/
template< unsigned int Index0, unsigned int... Indices >
struct pop_front< index_list< Index0, Indices... > > {
using type = index_list< Indices... >;
};
template< >
struct pop_front< index_list< > > {
using type = index_list< >;
};
/*
Index list range creation
*/
namespace detail {
template< unsigned int curr, unsigned int end, unsigned int... Indices >
struct make_index_range :
public make_index_range< curr + 1, end, Indices..., curr >
{
};
template< unsigned int end, unsigned int... Indices >
struct make_index_range< end, end, Indices... >
{
using type = index_list< Indices... >;
};
}
/*
make_index_range< start, end >
Creates the index list list of range [start, end)
*/
template< unsigned int start, unsigned int end >
struct make_index_range {
static_assert(end >= start, "end must be greater than or equal to start");
using type = typename detail::make_index_range< start, end >::type;
};
template< unsigned int start, unsigned int end >
using index_range = typename make_index_range<start, end>::type;
namespace detail {
// These implementation are not really efficient...
template< typename SourceList, typename IndexList >
struct sub_range_index;
template< typename SourceList, unsigned int... Indices >
struct sub_range_index< SourceList, index_list< Indices... > > {
using type = index_list< get< SourceList, Indices >::value... >;
};
template< typename SourceList, typename IndexList >
struct sub_range_type;
template< typename SourceList, unsigned int... Indices >
struct sub_range_type< SourceList, index_list< Indices... > > {
using type = type_list< typename get< SourceList, Indices >::type... >;
};
}
/*
Index list sub_range [start, end)
*/
template< unsigned int start, unsigned int end, unsigned int... Indices >
struct sub_range< index_list<Indices...>, start, end >
{
static_assert(end >= start, "end must be greater or equal to start");
using type = typename detail::sub_range_index< index_list<Indices...>, typename make_index_range<start, end>::type >::type;
};
/*
Type list sub_range [start, end)
*/
template< unsigned int start, unsigned int end, typename... Types >
struct sub_range< type_list<Types...>, start, end >
{
static_assert(end >= start, "end must be greater or equal to start");
using type = typename detail::sub_range_type< type_list<Types...>, typename make_index_range<start, end>::type >::type;
};
/*
Index list sum
*/
namespace detail {
template< typename T, T... Values >
struct sum_values;
template< typename T, T Value0, T... Values >
struct sum_values< T, Value0, Values... > {
static const T value = Value0 + sum_values< T, Values... >::value;
};
template< typename T >
struct sum_values< T >
{
static const T value = 0;
};
}
template< typename T >
struct sum;
template< unsigned int... Args >
struct sum< index_list<Args...> >
{
static const unsigned int value = detail::sum_values<unsigned int, Args...>::value;
};
/*
and_ or_
*/
template< typename... ConvertiblesToTrueFalse >
struct and_;
template< typename Convertible0, typename... Convertibles >
struct and_< Convertible0, Convertibles... >
: std::conditional <
std::is_convertible< Convertible0, std::true_type >::value,
and_< Convertibles... >,
std::false_type > ::type
{
};
template< >
struct and_< >
: std::true_type
{
};
template< typename... ConvertiblesToTrueFalse >
struct or_;
template< typename Convertible0, typename... Convertibles >
struct or_< Convertible0, Convertibles... >
: std::conditional <
std::is_convertible< Convertible0, std::true_type >::value,
std::true_type,
or_< Convertibles... >
> ::type
{
};
template< >
struct or_< >
: std::true_type
{
};
}
}
#endif

View File

@ -20,35 +20,25 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE. // OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_VALUE_WRAPPER_050419_HPP #ifndef MOST_DERIVED_051018_HPP
#define LUABIND_VALUE_WRAPPER_050419_HPP # define MOST_DERIVED_051018_HPP
#include <type_traits> # include <boost/mpl/if.hpp>
#include <luabind/detail/type_traits.hpp> # include <boost/type_traits/is_base_and_derived.hpp>
namespace luabind { namespace luabind { namespace detail {
// template<class Class, class WrappedClass>
// Concept "lua_proxy" struct most_derived
// {
typedef typename boost::mpl::if_<
boost::is_base_and_derived<Class, WrappedClass>
, WrappedClass
, Class
>::type type;
};
template<class T> }} // namespace luabind::detail
struct lua_proxy_traits
{
using is_specialized = std::false_type;
};
template<class T> #endif // MOST_DERIVED_051018_HPP
struct is_lua_proxy_type
: lua_proxy_traits<T>::is_specialized
{};
template< class T >
struct is_lua_proxy_arg
: std::conditional<is_lua_proxy_type<remove_const_reference_t<T>>::value, std::true_type, std::false_type >::type
{};
} // namespace luabind
#endif // LUABIND_VALUE_WRAPPER_050419_HPP

View File

@ -1,386 +0,0 @@
// Copyright (c) 2005 Daniel Wallin and Arvid Norberg
// 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 LUABIND_OBJECT_050419_HPP
#define LUABIND_OBJECT_050419_HPP
#include <tuple>
#include <luabind/nil.hpp>
#include <luabind/handle.hpp>
#include <luabind/from_stack.hpp>
#include <luabind/detail/stack_utils.hpp>
#include <luabind/detail/push_to_lua.hpp>
#include <luabind/typeid.hpp>
#include <luabind/detail/crtp_iterator.hpp>
#include <luabind/lua_proxy_interface.hpp>
#include <luabind/lua_index_proxy.hpp>
#include <luabind/lua_iterator_proxy.hpp>
#include <luabind/detail/class_rep.hpp>
#if LUA_VERSION_NUM < 502
# define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX)
#endif
namespace luabind {
namespace adl {
// An object holds a reference to a Lua value residing
// in the registry.
class object :
public lua_proxy_interface<object>
{
public:
object()
{}
explicit object(handle const& other)
: m_handle(other)
{}
explicit object(from_stack const& stack_reference)
: m_handle(stack_reference.interpreter, stack_reference.index)
{
}
template<class T>
object(lua_State* interpreter, T&& value)
{
detail::push_to_lua(interpreter, std::forward<T>(value));
detail::stack_pop pop(interpreter, 1);
handle(interpreter, -1).swap(m_handle);
}
template<class T, class Policies>
object(lua_State* interpreter, T&& value, Policies const&)
{
detail::push_to_lua<1, Policies>(interpreter, std::forward<T>(value));
detail::stack_pop pop(interpreter, 1);
handle(interpreter, -1).swap(m_handle);
}
void push(lua_State* interpreter) const;
lua_State* interpreter() const;
bool is_valid() const;
template<class T>
index_proxy<object> operator[](T const& key) const
{
return index_proxy<object>(
*this, m_handle.interpreter(), key
);
}
void swap(object& other)
{
m_handle.swap(other.m_handle);
}
private:
handle m_handle;
};
inline void object::push(lua_State* interpreter) const
{
m_handle.push(interpreter);
}
inline lua_State* object::interpreter() const
{
return m_handle.interpreter();
}
inline bool object::is_valid() const
{
return m_handle.interpreter() != 0;
}
} // namespace adl
using adl::object;
template<>
struct lua_proxy_traits<object>
{
using is_specialized = std::true_type;
static lua_State* interpreter(object const& value)
{
return value.interpreter();
}
static void unwrap(lua_State* interpreter, object const& value)
{
value.push(interpreter);
}
static bool check(...)
{
return true;
}
};
template<class R, typename PolicyList = no_policies, typename... Args>
R call_function(luabind::object const& obj, Args&&... args)
{
obj.push(obj.interpreter());
return call_pushed_function<R, PolicyList>(obj.interpreter(), std::forward<Args>(args)...);
}
template<class R, typename PolicyList = no_policies, typename... Args>
R resume_function(luabind::object const& obj, Args&&... args)
{
obj.push(obj.interpreter());
return resume_pushed_function<R, PolicyList>(obj.interpreter(), std::forward<Args>(args)...);
}
// declared in luabind/lua_index_proxy.hpp
template<typename Next>
adl::index_proxy<Next>::operator object()
{
detail::stack_pop pop(m_interpreter, 1);
push(m_interpreter);
return object(from_stack(m_interpreter, -1));
}
// declared in luabind/lua_proxy_interface.hpp
template<typename ProxyType>
template<typename PolicyList, typename... Args>
object adl::lua_proxy_interface<ProxyType>::call(Args&&... args)
{
return call_function<object, PolicyList>(derived(), std::forward<Args>(args)...);
}
// declared in luabind/lua_proxy_interface.hpp
template<typename ProxyType>
template<typename... Args>
object adl::lua_proxy_interface<ProxyType>::operator()(Args&&... args)
{
return call<no_policies>(std::forward<Args>(args)...);
}
// declared in luabind/lua_iterator_proxy.hpp
template<class AccessPolicy>
adl::iterator_proxy<AccessPolicy>::operator object()
{
lua_pushvalue(m_interpreter, m_key_index);
AccessPolicy::get(m_interpreter, m_table_index);
detail::stack_pop pop(m_interpreter, 1);
return object(from_stack(m_interpreter, -1));
}
// declared in luabind/lua_iterator_proxy.hpp
template<class AccessPolicy>
object detail::basic_iterator<AccessPolicy>::key() const
{
return object(m_key);
}
namespace adl {
// Simple value_wrapper adaptor with the sole purpose of helping with
// overload resolution. Use this as a function parameter type instead
// of "object" or "argument" to restrict the parameter to Lua tables.
template <class Base = object>
struct table : Base
{
table(from_stack const& stack_reference)
: Base(stack_reference)
{}
};
} // namespace adl
using adl::table;
template <class Base>
struct lua_proxy_traits<adl::table<Base> >
: lua_proxy_traits<Base>
{
static bool check(lua_State* L, int idx)
{
return lua_proxy_traits<Base>::check(L, idx) &&
lua_istable(L, idx);
}
};
inline object newtable(lua_State* interpreter)
{
lua_newtable(interpreter);
detail::stack_pop pop(interpreter, 1);
return object(from_stack(interpreter, -1));
}
// this could be optimized by returning a proxy
inline object globals(lua_State* interpreter)
{
lua_pushglobaltable(interpreter);
detail::stack_pop pop(interpreter, 1);
return object(from_stack(interpreter, -1));
}
// this could be optimized by returning a proxy
inline object registry(lua_State* interpreter)
{
lua_pushvalue(interpreter, LUA_REGISTRYINDEX);
detail::stack_pop pop(interpreter, 1);
return object(from_stack(interpreter, -1));
}
template<class ValueWrapper, class K>
inline object gettable(ValueWrapper const& table, K&& key)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(table);
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, table);
detail::stack_pop pop(interpreter, 2);
detail::push_to_lua(interpreter, std::forward<K>(key));
lua_gettable(interpreter, -2);
return object(from_stack(interpreter, -1));
}
template<class ValueWrapper, class K, class T>
inline void settable(ValueWrapper const& table, K&& key, T&& value)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(table);
// TODO: Exception safe?
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, table);
detail::stack_pop pop(interpreter, 1);
detail::push_to_lua(interpreter, std::forward<K>(key));
detail::push_to_lua(interpreter, std::forward<T>(value));
lua_settable(interpreter, -3);
}
template<class ValueWrapper, class K>
inline object rawget(ValueWrapper const& table, K&& key)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(
table
);
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, table);
detail::stack_pop pop(interpreter, 2);
detail::push_to_lua(interpreter, std::forward<K>(key));
lua_rawget(interpreter, -2);
return object(from_stack(interpreter, -1));
}
template<class ValueWrapper, class K, class T>
inline void rawset(ValueWrapper const& table, K&& key, T&& value)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(
table
);
// TODO: Exception safe?
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, table);
detail::stack_pop pop(interpreter, 1);
detail::push_to_lua(interpreter, std::forward<K>(key));
detail::push_to_lua(interpreter, std::forward<T>(value));
lua_rawset(interpreter, -3);
}
template<class ValueWrapper>
inline int type(ValueWrapper const& value)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(value);
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, value);
detail::stack_pop pop(interpreter, 1);
return lua_type(interpreter, -1);
}
template <class ValueWrapper>
inline object getmetatable(ValueWrapper const& obj)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(obj);
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, obj);
detail::stack_pop pop(interpreter, 2);
lua_getmetatable(interpreter, -1);
return object(from_stack(interpreter, -1));
}
template <class ValueWrapper1, class ValueWrapper2>
inline void setmetatable(ValueWrapper1 const& obj, ValueWrapper2 const& metatable)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper1>::interpreter(obj);
lua_proxy_traits<ValueWrapper1>::unwrap(interpreter, obj);
detail::stack_pop pop(interpreter, 1);
lua_proxy_traits<ValueWrapper2>::unwrap(interpreter, metatable);
lua_setmetatable(interpreter, -2);
}
template <class ValueWrapper>
inline std::tuple<const char*, object> getupvalue(ValueWrapper const& value, int index)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(value);
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, value);
detail::stack_pop pop(interpreter, 2);
const char* name = lua_getupvalue(interpreter, -1, index);
return std::make_tuple(name, object(from_stack(interpreter, -1)));
}
template <class ValueWrapper1, class ValueWrapper2>
inline void setupvalue(ValueWrapper1 const& function, int index, ValueWrapper2 const& value)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper1>::interpreter(function);
lua_proxy_traits<ValueWrapper1>::unwrap(interpreter, function);
detail::stack_pop pop(interpreter, 1);
lua_proxy_traits<ValueWrapper2>::unwrap(interpreter, value);
lua_setupvalue(interpreter, -2, index);
}
template <class GetValueWrapper>
object property(GetValueWrapper const& get)
{
lua_State* interpreter = lua_proxy_traits<GetValueWrapper>::interpreter(get);
lua_proxy_traits<GetValueWrapper>::unwrap(interpreter, get);
lua_pushnil(interpreter);
lua_pushcclosure(interpreter, &detail::property_tag, 2);
detail::stack_pop pop(interpreter, 1);
return object(from_stack(interpreter, -1));
}
template <class GetValueWrapper, class SetValueWrapper>
object property(GetValueWrapper const& get, SetValueWrapper const& set)
{
lua_State* interpreter = lua_proxy_traits<GetValueWrapper>::interpreter(get);
lua_proxy_traits<GetValueWrapper>::unwrap(interpreter, get);
lua_proxy_traits<SetValueWrapper>::unwrap(interpreter, set);
lua_pushcclosure(interpreter, &detail::property_tag, 2);
detail::stack_pop pop(interpreter, 1);
return object(from_stack(interpreter, -1));
}
} // namespace luabind
#if LUA_VERSION_NUM < 502
#undef lua_pushglobaltable
#endif
#include <luabind/detail/conversion_policies/conversion_policies.hpp>
#endif // LUABIND_OBJECT_050419_HPP

View File

@ -0,0 +1,52 @@
// Copyright (c) 2005 Daniel Wallin and Arvid Norberg
// 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.
#if !BOOST_PP_IS_ITERATING
# error Do not include object_call.hpp directly!
#endif
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#define N BOOST_PP_ITERATION()
template<BOOST_PP_ENUM_PARAMS(N, class A)>
call_proxy<
Derived
, boost::tuples::tuple<
BOOST_PP_ENUM_BINARY_PARAMS(N, A, const* BOOST_PP_INTERCEPT)
>
> operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a))
{
typedef boost::tuples::tuple<
BOOST_PP_ENUM_BINARY_PARAMS(N, A, const* BOOST_PP_INTERCEPT)
> arguments;
return call_proxy<Derived, arguments>(
derived()
, arguments(BOOST_PP_ENUM_PARAMS(N, &a))
);
}
#undef N

View File

@ -0,0 +1,224 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// 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 LUABIND_OBJECT_PROXY_HPP_INCLUDED
#define LUABIND_OBJECT_PROXY_HPP_INCLUDED
#include <boost/optional.hpp>
#include <luabind/config.hpp>
#include <luabind/detail/policy.hpp>
#include <luabind/error.hpp>
#include <luabind/detail/convert_to_lua.hpp>
#include <luabind/detail/debug.hpp>
#include <luabind/detail/stack_utils.hpp>
#include <boost/mpl/apply_wrap.hpp>
namespace luabind
{
namespace detail
{
namespace mpl = boost::mpl;
template<class T, class Obj, class Policies>
inline T object_cast_impl(const Obj& obj, const Policies&)
{
if (obj.lua_state() == 0)
{
#ifndef LUABIND_NO_EXCEPTIONS
throw cast_failed(0, typeid(T));
#else
lua_State* L = obj.lua_state();
cast_failed_callback_fun e = get_cast_failed_callback();
if (e) e(L, typeid(T));
assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()");
std::terminate();
#endif
}
LUABIND_CHECK_STACK(obj.lua_state());
typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy;
typename mpl::apply_wrap2<converter_policy,T,lua_to_cpp>::type converter;
obj.pushvalue();
lua_State* L = obj.lua_state();
detail::stack_pop p(L, 1);
#ifndef LUABIND_NO_ERROR_CHECKING
if (converter.match(L, LUABIND_DECORATE_TYPE(T), -1) < 0)
{
#ifndef LUABIND_NO_EXCEPTIONS
throw cast_failed(L, typeid(T));
#else
cast_failed_callback_fun e = get_cast_failed_callback();
if (e) e(L, typeid(T));
assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()");
std::terminate();
#endif
}
#endif
return converter.apply(L, LUABIND_DECORATE_TYPE(T), -1);
}
template<class T, class Obj, class Policies>
boost::optional<T> object_cast_nothrow_impl(const Obj& obj, const Policies&)
{
typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy;
typename mpl::apply_wrap2<converter_policy,T,lua_to_cpp>::type converter;
if (obj.lua_state() == 0) return boost::optional<T>();
LUABIND_CHECK_STACK(obj.lua_state());
obj.pushvalue();
lua_State* L = obj.lua_state();
detail::stack_pop p(L, 1);
#ifndef LUABIND_NO_ERROR_CHECKING
if (converter.match(L, LUABIND_DECORATE_TYPE(T), -1) < 0)
return boost::optional<T>();
#endif
return boost::optional<T>(converter.apply(L, LUABIND_DECORATE_TYPE(T), -1));
}
}
template<class T>
T object_cast(const object& obj)
{ return detail::object_cast_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
T object_cast(const object& obj, const Policies& p)
{ return detail::object_cast_impl<T>(obj, p); }
template<class T>
boost::optional<T> object_cast_nothrow(const object& obj)
{ return detail::object_cast_nothrow_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
boost::optional<T> object_cast_nothrow(const object& obj, const Policies& p)
{ return detail::object_cast_nothrow_impl<T>(obj, p); }
template<class T>
T object_cast(const detail::proxy_object& obj)
{ return detail::object_cast_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
T object_cast(const detail::proxy_object& obj, const Policies& p)
{ return detail::object_cast_impl<T>(obj, p); }
template<class T>
boost::optional<T> object_cast_nothrow(const detail::proxy_object& obj)
{ return detail::object_cast_nothrow_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
boost::optional<T> object_cast_nothrow(const detail::proxy_object& obj, const Policies& p)
{ return detail::object_cast_nothrow_impl<T>(obj, p); }
template<class T>
T object_cast(const detail::proxy_raw_object& obj)
{ return detail::object_cast_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
T object_cast(const detail::proxy_raw_object& obj, const Policies& p)
{ return detail::object_cast_impl<T>(obj, p); }
template<class T>
boost::optional<T> object_cast_nothrow(const detail::proxy_raw_object& obj)
{ return detail::object_cast_nothrow_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
boost::optional<T> object_cast_nothrow(const detail::proxy_raw_object& obj, const Policies& p)
{ return detail::object_cast_nothrow_impl<T>(obj, p); }
template<class T>
T object_cast(const detail::proxy_array_object& obj)
{ return detail::object_cast_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
T object_cast(const detail::proxy_array_object& obj, const Policies& p)
{ return detail::object_cast_impl<T>(obj, p); }
template<class T>
boost::optional<T> object_cast_nothrow(const detail::proxy_array_object& obj)
{ return detail::object_cast_nothrow_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
boost::optional<T> object_cast_nothrow(const detail::proxy_array_object& obj, const Policies& p)
{ return detail::object_cast_nothrow_impl<T>(obj, p); }
inline object get_globals(lua_State* L)
{
lua_pushvalue(L, LUA_GLOBALSINDEX);
detail::lua_reference ref;
ref.set(L);
return object(L, ref, true/*object::reference()*/);
}
inline object get_registry(lua_State* L)
{
lua_pushvalue(L, LUA_REGISTRYINDEX);
detail::lua_reference ref;
ref.set(L);
return object(L, ref, true/*object::reference()*/);
}
inline object newtable(lua_State* L)
{
lua_newtable(L);
detail::lua_reference ref;
ref.set(L);
return object(L, ref, true/*object::reference()*/);
}
}
/*
struct A
{
};
object f = class_<A>();
A* ptr = object_cast<A*>(f(), adopt(_1));
delete ptr;
*/
#endif // LUABIND_OBJECT_PROXY_HPP_INCLUDED

View File

@ -24,114 +24,110 @@
#ifndef LUABIND_OBJECT_REP_HPP_INCLUDED #ifndef LUABIND_OBJECT_REP_HPP_INCLUDED
#define LUABIND_OBJECT_REP_HPP_INCLUDED #define LUABIND_OBJECT_REP_HPP_INCLUDED
#include <boost/aligned_storage.hpp>
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/detail/class_rep.hpp>
#include <luabind/detail/instance_holder.hpp> #include <luabind/detail/instance_holder.hpp>
#include <luabind/detail/ref.hpp> #include <luabind/detail/ref.hpp>
#include <type_traits> // std::aligned_storage
#include <cstdlib> #include <cstdlib>
namespace luabind { namespace luabind { namespace detail
namespace detail { {
class class_rep;
void finalize(lua_State* L, class_rep* crep); void finalize(lua_State* L, class_rep* crep);
// this class is allocated inside lua for each pointer. // this class is allocated inside lua for each pointer.
// it contains the actual c++ object-pointer. // it contains the actual c++ object-pointer.
// it also tells if it is const or not. // it also tells if it is const or not.
class LUABIND_API object_rep class LUABIND_API object_rep
{
public:
object_rep(instance_holder* instance, class_rep* crep);
~object_rep();
const class_rep* crep() const { return m_classrep; }
class_rep* crep() { return m_classrep; }
void set_instance(instance_holder* instance) { m_instance = instance; }
void add_dependency(lua_State* L, int index);
void release_dependency_refs(lua_State* L);
std::pair<void*, int> get_instance(class_id target) const
{ {
public: if (m_instance == 0)
object_rep(instance_holder* instance, class_rep* crep); return std::pair<void*, int>((void*)0, -1);
~object_rep(); return m_instance->get(target);
}
const class_rep* crep() const { return m_classrep; } bool is_const() const
class_rep* crep() { return m_classrep; }
void set_instance(instance_holder* instance) { m_instance = instance; }
void add_dependency(lua_State* L, int index);
std::pair<void*, int> get_instance(class_id target) const
{
if(m_instance == 0)
return std::pair<void*, int>(nullptr, -1);
return m_instance->get(m_classrep->casts(), target);
}
bool is_const() const
{
return m_instance && m_instance->pointee_const();
}
void release()
{
if(m_instance)
m_instance->release();
}
void* allocate(std::size_t size)
{
if(size <= 32) {
return &m_instance_buffer;
}
else {
return std::malloc(size);
}
}
void deallocate(void* storage)
{
if(storage == &m_instance_buffer) {
return;
}
else {
std::free(storage);
}
}
private:
object_rep(object_rep const&) = delete;
void operator=(object_rep const&) = delete;
instance_holder* m_instance;
std::aligned_storage<32>::type m_instance_buffer;
class_rep* m_classrep; // the class information about this object's type
detail::lua_reference m_dependency_ref; // reference to lua table holding dependency references
};
template<class T>
struct delete_s
{ {
static void apply(void* ptr) return m_instance && m_instance->pointee_const();
{ }
delete static_cast<T*>(ptr);
}
};
template<class T> void release()
struct destruct_only_s {
if (m_instance)
m_instance->release();
}
void* allocate(std::size_t size)
{ {
static void apply(void* ptr) if (size <= 32)
{ return &m_instance_buffer;
// Removes unreferenced formal parameter warning on VC7. return std::malloc(size);
(void)ptr; }
void deallocate(void* storage)
{
if (storage == &m_instance_buffer)
return;
std::free(storage);
}
private:
object_rep(object_rep const&)
{}
void operator=(object_rep const&)
{}
instance_holder* m_instance;
boost::aligned_storage<32> m_instance_buffer;
class_rep* m_classrep; // the class information about this object's type
std::size_t m_dependency_cnt; // counts dependencies
};
template<class T>
struct delete_s
{
static void apply(void* ptr)
{
delete static_cast<T*>(ptr);
}
};
template<class T>
struct destruct_only_s
{
static void apply(void* ptr)
{
// Removes unreferenced formal parameter warning on VC7.
(void)ptr;
#ifndef NDEBUG #ifndef NDEBUG
int completeness_check[sizeof(T)]; int completeness_check[sizeof(T)];
(void)completeness_check; (void)completeness_check;
#endif #endif
static_cast<T*>(ptr)->~T(); static_cast<T*>(ptr)->~T();
} }
}; };
LUABIND_API object_rep* get_instance(lua_State* L, int index); LUABIND_API object_rep* get_instance(lua_State* L, int index);
LUABIND_API void push_instance_metatable(lua_State* L); LUABIND_API void push_instance_metatable(lua_State* L);
LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls); LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls);
} // namespace detail }}
} // namespace luabind
#endif // LUABIND_OBJECT_REP_HPP_INCLUDED #endif // LUABIND_OBJECT_REP_HPP_INCLUDED

View File

@ -26,58 +26,54 @@
#include <luabind/config.hpp> #include <luabind/config.hpp>
namespace luabind { namespace luabind { namespace detail {
namespace detail {
enum operator_id enum operator_id
{ {
op_add = 0, op_add = 0,
op_sub, op_sub,
op_mul, op_mul,
op_div, op_div,
op_mod, op_pow,
op_pow, op_lt,
op_lt, op_le,
op_le, op_eq,
op_eq, op_call,
op_call, op_unm,
op_unm, op_tostring,
op_tostring, op_concat,
op_concat, op_len,
op_len,
number_of_operators number_of_operators
}; };
inline const char* get_operator_name(int i) inline const char* get_operator_name(int i)
{ {
static const char* a[number_of_operators] = { static const char* a[number_of_operators] = {
"__add", "__sub", "__mul", "__div", "__mod", "__pow", "__add", "__sub", "__mul", "__div", "__pow",
"__lt", "__le", "__eq", "__call", "__unm", "__lt", "__le", "__eq", "__call", "__unm",
"__tostring", "__concat", "__len" }; "__tostring", "__concat", "__len" };
return a[i]; return a[i];
} }
inline const char* get_operator_symbol(int i) inline const char* get_operator_symbol(int i)
{ {
static const char* a[number_of_operators] = { static const char* a[number_of_operators] = {
"+", "-", "*", "/", "%", "^", "<", "+", "-", "*", "/", "^", "<",
"<=", "==", "()", "- (unary)", "<=", "==", "()", "- (unary)",
"tostring", "..", "#" }; "tostring", "..", "#" };
return a[i]; return a[i];
} }
inline bool is_unary(int i) inline bool is_unary(int i)
{ {
// the reason why unary minus is not considered a unary operator here is // the reason why unary minus is not considered a unary operator here is
// that it always is given two parameters, where the second parameter always // that it always is given two parameters, where the second parameter always
// is nil. // is nil.
return i == op_tostring; return i == op_tostring;
} }
} // namespace detail }}
} // namespace luabind
#endif // LUABIND_OPERATOR_ID_HPP_INCLUDED #endif // LUABIND_OPERATOR_ID_HPP_INCLUDED

View File

@ -33,34 +33,87 @@
// to its suitability for any purpose. // to its suitability for any purpose.
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <boost/config.hpp>
namespace luabind { namespace luabind
{
template<class T> template<class T>
struct other struct other
{ {
using type = T; typedef T type;
};
}
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace luabind { namespace detail
{
template<typename T>
class unwrap_other
{
public:
typedef T type;
}; };
} // namespace luabind template<typename T>
class unwrap_other<other<T> >
{
public:
typedef T type;
};
}} // namespace luabind::detail
namespace luabind { # else // no partial specialization
namespace detail {
template<typename T>
class unwrap_other
{
public:
using type = T;
};
template<typename T> #include <boost/type.hpp>
class unwrap_other<other<T> >
{ namespace luabind { namespace detail
public: {
using type = T; typedef char (&yes_other_t)[1];
}; typedef char (&no_other_t)[2];
}
} // namespace luabind::detail no_other_t is_other_test(...);
template<typename T>
yes_other_t is_other_test(type_< other<T> >);
template<bool wrapped>
struct other_unwrapper
{
template <class T>
struct apply
{
typedef T type;
};
};
template<>
struct other_unwrapper<true>
{
template <class T>
struct apply
{
typedef typename T::type type;
};
};
template<typename T>
class is_other
{
public:
BOOST_STATIC_CONSTANT(
bool, value = (
sizeof(detail::is_other_test(type_<T>()))
== sizeof(detail::yes_other_t)));
};
template <typename T>
class unwrap_other
: public detail::other_unwrapper<
is_other<T>::value
>::template apply<T>
{};
}} // namespace luabind::detail
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#endif // LUABIND_OTHER_HPP_INCLUDED #endif // LUABIND_OTHER_HPP_INCLUDED

View File

@ -25,14 +25,12 @@
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/lua_state_fwd.hpp> struct lua_State;
namespace luabind { namespace luabind { namespace detail
namespace detail { {
LUABIND_API int pcall(lua_State *L, int nargs, int nresults); LUABIND_API int pcall(lua_State *L, int nargs, int nresults);
LUABIND_API int resume_impl(lua_State *L, int nargs, int nresults); LUABIND_API int resume_impl(lua_State *L, int nargs, int nresults);
} }}
}
#endif #endif

View File

@ -0,0 +1,54 @@
// Copyright (c) 2004 Daniel Wallin and Arvid Norberg
// 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 POINTEE_SIZEOF_040211_HPP
#define POINTEE_SIZEOF_040211_HPP
#include <boost/mpl/int.hpp>
namespace luabind {
namespace detail {
template<class T> T& deref_type(T(*)(), int);
template<class T> T& deref_type(T*(*)(), long);
} // namespace detail
// returns the indirect sizeof U, as in
// sizeof(T*) = sizeof(T)
// sizeof(T&) = sizeof(T)
// sizeof(T) = sizeof(T)
template<class T>
struct pointee_sizeof
{
BOOST_STATIC_CONSTANT(int, value = (
sizeof(detail::deref_type((T(*)())0), 0L)
));
typedef boost::mpl::int_<value> type;
};
} // namespace luabind
#endif // POINTEE_SIZEOF_040211_HPP

View File

@ -1,4 +1,4 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg // Copyright (c) 2004 Daniel Wallin
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"), // copy of this software and associated documentation files (the "Software"),
@ -20,27 +20,21 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE. // OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef INCLUDED_error_callback_fun_hpp_GUID_1150976a_4348_495f_99ce_9d7edd00a0b8 #ifndef POINTEE_TYPEID_040211_HPP
#define INCLUDED_error_callback_fun_hpp_GUID_1150976a_4348_495f_99ce_9d7edd00a0b8 #define POINTEE_TYPEID_040211_HPP
// Internal Includes
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/lua_state_fwd.hpp> #include <luabind/typeid.hpp>
// Library/third-party includes namespace luabind { namespace detail {
// - none
// Standard includes template<class T>
// - none type_id pointee_typeid(T*)
{
return typeid(T);
}
namespace luabind }} // namespace luabind::detail
{
class type_id;
using error_callback_fun = void(*)(lua_State*); #endif // POINTEE_TYPEID_040211_HPP
using cast_failed_callback_fun = void(*)(lua_State*, type_id const&);
using pcall_callback_fun = void(*)(lua_State*);
}
#endif // INCLUDED_error_callback_fun_hpp_GUID_1150976a_4348_495f_99ce_9d7edd00a0b8

File diff suppressed because it is too large Load Diff

View File

@ -24,40 +24,62 @@
#ifndef LUABIND_PRIMITIVES_HPP_INCLUDED #ifndef LUABIND_PRIMITIVES_HPP_INCLUDED
#define LUABIND_PRIMITIVES_HPP_INCLUDED #define LUABIND_PRIMITIVES_HPP_INCLUDED
// std::reference_wrapper... #include <algorithm>
#include <type_traits> // std::true_type...
#include <cstring> #include <cstring>
namespace luabind { #include <luabind/config.hpp>
namespace detail { #include <luabind/detail/yes_no.hpp>
template<class T> namespace luabind { namespace detail
struct type_ {}; {
template<class T>
struct identity
{
typedef T type;
};
struct ltstr template<class T>
{ struct type_ {};
bool operator()(const char* s1, const char* s2) const { return std::strcmp(s1, s2) < 0; }
};
template<int N> struct null_type {};
struct aligned
{
char storage[N];
};
// returns the offset added to a Derived* when cast to a Base* /* typedef char yes_t;
template<class Derived, class Base> typedef double no_t;*/
ptrdiff_t ptr_offset(type_<Derived>, type_<Base>)
{
aligned<sizeof(Derived)> obj;
Derived* ptr = reinterpret_cast<Derived*>(&obj);
return ptrdiff_t(static_cast<char*>(static_cast<void*>(static_cast<Base*>(ptr))) struct lua_to_cpp {};
- static_cast<char*>(static_cast<void*>(ptr))); struct cpp_to_lua {};
}
template<class T> struct by_value {};
template<class T> struct by_reference {};
template<class T> struct by_const_reference {};
template<class T> struct by_pointer {};
template<class T> struct by_const_pointer {};
struct converter_policy_tag {};
struct ltstr
{
bool operator()(const char* s1, const char* s2) const { return std::strcmp(s1, s2) < 0; }
};
template<int N>
struct aligned
{
char storage[N];
};
// returns the offset added to a Derived* when cast to a Base*
// TODO: return ptrdiff
template<class Derived, class Base>
int ptr_offset(type_<Derived>, type_<Base>)
{
aligned<sizeof(Derived)> obj;
Derived* ptr = reinterpret_cast<Derived*>(&obj);
return int(static_cast<char*>(static_cast<void*>(static_cast<Base*>(ptr)))
- static_cast<char*>(static_cast<void*>(ptr)));
} }
}
}}
#endif // LUABIND_PRIMITIVES_HPP_INCLUDED #endif // LUABIND_PRIMITIVES_HPP_INCLUDED

View File

@ -5,31 +5,29 @@
#ifndef LUABIND_PROPERTY_081020_HPP #ifndef LUABIND_PROPERTY_081020_HPP
# define LUABIND_PROPERTY_081020_HPP # define LUABIND_PROPERTY_081020_HPP
namespace luabind { namespace luabind { namespace detail {
namespace detail {
template <class Class, class T, class Result = T> template <class Class, class T, class Result = T>
struct access_member_ptr struct access_member_ptr
{ {
access_member_ptr(T Class::* mem_ptr) access_member_ptr(T Class::* mem_ptr)
: mem_ptr(mem_ptr) : mem_ptr(mem_ptr)
{} {}
Result operator()(Class const& x) const Result operator()(Class const& x) const
{ {
return const_cast<Class&>(x).*mem_ptr; return const_cast<Class&>(x).*mem_ptr;
} }
void operator()(Class& x, T const& value) const void operator()(Class& x, T const& value) const
{ {
x.*mem_ptr = value; x.*mem_ptr = value;
} }
T Class::* mem_ptr; T Class::* mem_ptr;
}; };
} // namespace detail }} // namespace luabind::detail
} // namespace luabind
#endif // LUABIND_PROPERTY_081020_HPP #endif // LUABIND_PROPERTY_081020_HPP

View File

@ -1,74 +0,0 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// 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 LUABIND_CONVERT_TO_LUA_HPP_INCLUDED
#define LUABIND_CONVERT_TO_LUA_HPP_INCLUDED
#include <luabind/config.hpp>
#include <luabind/detail/policy.hpp>
#include <luabind/detail/type_traits.hpp>
namespace luabind {
namespace detail {
template< typename T >
struct unwrapped {
static const bool is_wrapped_ref = false;
using type = T;
static const T& get(const T& t) {
return t;
}
};
template< typename T >
struct unwrapped< std::reference_wrapper< T > >
{
static const bool is_wrapped_ref = true;
using type = T&;
static T& get(const std::reference_wrapper<T>& refwrap)
{
return refwrap.get();
}
};
template<typename T>
using unwrapped_t = typename unwrapped< T >::type;
template<unsigned int PolicyIndex = 1, typename Policies = no_policies, typename T>
void push_to_lua(lua_State* L, T&& v)
{
using value_type = unwrapped_t<remove_const_reference_t<T>>;
specialized_converter_policy_n<PolicyIndex, Policies, value_type, cpp_to_lua>()
.to_lua(L, unwrapped<T>::get(v));
}
}
}
#endif

View File

@ -33,83 +33,80 @@
namespace luabind namespace luabind
{ {
namespace detail namespace detail
{
struct lua_reference
{ {
lua_reference(lua_State* L_ = 0)
struct lua_reference : L(L_)
, m_ref(LUA_NOREF)
{}
lua_reference(lua_reference const& r)
: L(r.L)
, m_ref(LUA_NOREF)
{ {
lua_reference(lua_State* L_ = 0) if (!r.is_valid()) return;
: L(L_) r.get(L);
, m_ref(LUA_NOREF) set(L);
{} }
lua_reference(lua_reference const& r) ~lua_reference() { reset(); }
: L(r.L)
, m_ref(LUA_NOREF)
{
if(!r.is_valid()) return;
r.get(L);
set(L);
}
~lua_reference() { reset(); }
lua_State* state() const { return L; } lua_State* state() const { return L; }
void operator=(lua_reference const& r) void operator=(lua_reference const& r)
{ {
// TODO: self assignment problems // TODO: self assignment problems
reset(); reset();
if(!r.is_valid()) return; if (!r.is_valid()) return;
r.get(r.state()); r.get(r.state());
set(r.state()); set(r.state());
} }
bool is_valid() const bool is_valid() const
{ { return m_ref != LUA_NOREF; }
return m_ref != LUA_NOREF;
}
void set(lua_State* L_) void set(lua_State* L_)
{ {
reset(); reset();
L = L_; L = L_;
m_ref = luaL_ref(L, LUA_REGISTRYINDEX); m_ref = luaL_ref(L, LUA_REGISTRYINDEX);
} }
void replace(lua_State* L_) void replace(lua_State* L_)
{ {
lua_rawseti(L_, LUA_REGISTRYINDEX, m_ref); lua_rawseti(L_, LUA_REGISTRYINDEX, m_ref);
} }
// L may not be the same pointer as // L may not be the same pointer as
// was used when creating this reference // was used when creating this reference
// since it may be a thread that shares // since it may be a thread that shares
// the same globals table. // the same globals table.
void get(lua_State* L_) const void get(lua_State* L_) const
{ {
assert(m_ref != LUA_NOREF); assert(m_ref != LUA_NOREF);
assert(L_); assert(L_);
lua_rawgeti(L_, LUA_REGISTRYINDEX, m_ref); lua_rawgeti(L_, LUA_REGISTRYINDEX, m_ref);
} }
void reset() void reset()
{ {
if(L && m_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, m_ref); if (L && m_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, m_ref);
m_ref = LUA_NOREF; m_ref = LUA_NOREF;
} }
void swap(lua_reference& r) void swap(lua_reference& r)
{ {
assert(r.L == L); assert(r.L == L);
std::swap(r.m_ref, m_ref); std::swap(r.m_ref, m_ref);
} }
private: private:
lua_State* L; lua_State* L;
int m_ref; int m_ref;
}; };
} }}
}
#endif // LUABIND_REF_HPP_INCLUDED #endif // LUABIND_REF_HPP_INCLUDED

View File

@ -25,5 +25,37 @@
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <boost/config.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/remove.hpp>
namespace luabind
{
namespace adl
{
class argument;
}
template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(LUABIND_MAX_ARITY, class A, detail::null_type)>
struct constructor
{
typedef BOOST_PP_CAT(
boost::mpl::vector, BOOST_PP_INC(BOOST_PP_INC(LUABIND_MAX_ARITY)))<
void, argument const&, BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)
> signature0;
typedef typename boost::mpl::remove<
signature0, detail::null_type>::type signature;
};
}
#endif // LUABIND_SIGNATURE_MATCH_HPP_INCLUDED #endif // LUABIND_SIGNATURE_MATCH_HPP_INCLUDED

View File

@ -23,36 +23,30 @@
#ifndef LUABIND_STACK_UTILS_HPP_INCLUDED #ifndef LUABIND_STACK_UTILS_HPP_INCLUDED
#define LUABIND_STACK_UTILS_HPP_INCLUDED #define LUABIND_STACK_UTILS_HPP_INCLUDED
#ifndef LUA_INCLUDE_HPP_INCLUDED
#include <luabind/lua_include.hpp>
#endif
#include <cassert> #include <cassert>
namespace luabind { namespace luabind { namespace detail
namespace detail { {
struct stack_pop struct stack_pop
{
stack_pop(lua_State* L, int n)
: m_state(L)
, m_n(n)
{
}
~stack_pop()
{ {
stack_pop(lua_State* L, int n) lua_pop(m_state, m_n);
: m_state(L) }
, m_n(n)
{
}
~stack_pop() private:
{
lua_pop(m_state, m_n);
}
private: lua_State* m_state;
int m_n;
lua_State* m_state; };
int m_n; }}
};
} // namespace detail
} // namespace luabind
#endif // LUABIND_STACK_UTILS_HPP_INCLUDED #endif // LUABIND_STACK_UTILS_HPP_INCLUDED

View File

@ -1,189 +0,0 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// 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 LUABIND_TYPETRAITS_HPP_INCLUDED
#define LUABIND_TYPETRAITS_HPP_INCLUDED
#include <type_traits>
#include <functional> // reference_wrapper
#include <luabind/detail/meta.hpp>
namespace luabind {
namespace detail {
template< typename T >
struct is_const_reference
: public std::conditional< std::is_reference<T>::value && std::is_const<typename std::remove_reference<T>::type>::value, std::true_type, std::false_type >::type
{
};
template<class T>
struct is_nonconst_reference
: public std::conditional< std::is_reference<T>::value && !std::is_const<typename std::remove_reference<T>::type>::value, std::true_type, std::false_type >::type
{
};
template<class T>
struct is_const_pointer
: public std::conditional< std::is_const<typename std::remove_pointer<T>::type>::value && std::is_pointer<T>::value, std::true_type, std::false_type >::type
{
};
template<class T>
struct is_nonconst_pointer :
public std::conditional < std::is_pointer<T>::value && !std::is_const<typename std::remove_pointer<T>::type>::value, std::true_type, std::false_type >::type
{
};
template<int v1, int v2>
struct max_c
{
enum { value = (v1 > v2) ? v1 : v2 };
};
} // namespace detail
template< typename T >
struct remove_const_reference {
using type = typename std::remove_const<typename std::remove_reference<T>::type>::type;
};
template< typename T >
using remove_const_reference_t = typename remove_const_reference<T>::type;
//
// most_derived
//
template<class A, class B>
struct most_derived
{
using type = typename std::conditional<
std::is_base_of<A, B>::value
, B
, A
>::type;
};
template< typename A, typename B >
using most_derived_t = typename most_derived<A, B>::type;
//
// null_type
//
struct null_type {};
template< typename T >
struct is_null_type : public std::false_type {};
template< >
struct is_null_type< null_type > : public std::true_type {};
//
// deduce_signature
//
template< typename, typename > struct tagged_function;
template< typename T, typename WrappedType = null_type >
struct deduce_signature;
template< typename R, typename... Args, typename WrappedType >
struct deduce_signature < R(Args...), WrappedType >
{
using type = meta::type_list< R, Args... >;
};
template< typename R, typename... Args, typename WrappedType >
struct deduce_signature < R(*)(Args...), WrappedType >
{
using type = meta::type_list< R, Args... >;
};
template< typename R, typename Class, typename... Args >
struct deduce_signature < R(Class::*)(Args...), null_type >
{
using type = meta::type_list< R, Class&, Args... >;
};
template< typename R, typename Class, typename... Args >
struct deduce_signature < R(Class::*)(Args...) const, null_type >
{
using type = meta::type_list< R, Class const&, Args... >;
};
template< typename R, typename Class, typename... Args, class WrappedType >
struct deduce_signature < R(Class::*)(Args...), WrappedType >
{
using type = meta::type_list< R, typename most_derived<Class, WrappedType>::type&, Args... >;
};
template< typename R, typename Class, typename... Args, class WrappedType >
struct deduce_signature < R(Class::*)(Args...) const, WrappedType >
{
using type = meta::type_list< R, typename most_derived<Class, WrappedType>::type const&, Args... >;
};
template< typename Signature, typename F, class WrappedType >
struct deduce_signature< tagged_function< Signature, F >, WrappedType >
{
using type = Signature;
};
template< typename T, typename WrappedType = null_type >
using deduce_signature_t = typename deduce_signature<T, WrappedType>::type;
//
// is_reference_wrapper
//
template< typename T > struct is_reference_wrapper : public std::false_type { };
template< typename T > struct is_reference_wrapper< std::reference_wrapper<T> > : public std::true_type { };
//
// apply_reference_wrapper
//
template< typename T > struct apply_reference_wrapper { using type = T; };
template< typename T > struct apply_reference_wrapper< std::reference_wrapper<T> > { using type = T&; };
template< typename T >
using apply_reference_wrapper_t = typename apply_reference_wrapper<T>::type;
//
// identity
//
template< typename T > struct identity { using type = T; };
template< typename T >
using identity_t = typename identity<T>::type;
template< typename Dst > Dst implicit_cast(typename identity<Dst>::type t) { return t; }
} // namespace luabind
#endif // LUABIND_TYPETRAITS_HPP_INCLUDED

View File

@ -0,0 +1,190 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// 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 LUABIND_TYPETRAITS_HPP_INCLUDED
#define LUABIND_TYPETRAITS_HPP_INCLUDED
#include <luabind/config.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_const.hpp>
#include <luabind/detail/primitives.hpp>
namespace luabind { namespace detail
{
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<class T>
struct is_const_type
{
typedef typename boost::mpl::if_<boost::is_const<T>
, yes_t
, no_t
>::type type;
};
template<bool is_Reference = false>
struct is_const_reference_helper
{
template<class>
struct apply
{
enum
{
value = false
};
};
};
template<class T>
typename is_const_type<T>::type is_const_reference_tester(T&);
no_t is_const_reference_tester(...);
template<>
struct is_const_reference_helper<true>
{
template<class T>
struct apply
{
static T getT();
enum
{
value = sizeof(is_const_reference_tester(getT())) == sizeof(yes_t)
};
};
};
template<class T>
struct is_const_reference
: is_const_reference_helper<boost::is_reference<T>::value>::template apply<T>
{
typedef boost::mpl::bool_<value> type;
};
#else
template<class T>
struct is_const_reference
{
enum { value = false };
typedef boost::mpl::bool_<value> type;
};
template<class T>
struct is_const_reference<const T&>
{
enum { value = true };
typedef boost::mpl::bool_<value> type;
};
#endif
template<class T>
struct is_nonconst_reference
{
enum
{
value = boost::is_reference<T>::value && !is_const_reference<T>::value
};
typedef boost::mpl::bool_<value> type;
};
template<class A>
yes_t is_const_pointer_helper(void(*)(const A*));
no_t is_const_pointer_helper(...);
template<class T>
struct is_const_pointer
{
enum { value = sizeof(is_const_pointer_helper((void(*)(T))0)) == sizeof(yes_t) };
typedef boost::mpl::bool_<value> type;
};
template<class A>
yes_t is_nonconst_pointer_helper(void(*)(A*));
no_t is_nonconst_pointer_helper(...);
template<class T>
struct is_nonconst_pointer
{
enum { value = sizeof(is_nonconst_pointer_helper((void(*)(T))0)) == sizeof(yes_t) && !is_const_pointer<T>::value };
typedef boost::mpl::bool_<value> type;
};
/*
template<class T>
struct is_constructable_from_helper
{
static yes_t check(const T&);
static no_t check(...);
};
template<class T, class From>
struct is_constructable_from
{
static From getFrom();
enum
{
value = sizeof(is_constructable_from_helper<T>::check(getFrom())) == sizeof(yes_t)
};
};
template<class T>
struct is_const_member_function_helper
{
static no_t test(...);
template<class R>
static yes_t test(R(T::*)() const);
template<class R, class A1>
static yes_t test(R(T::*)(A1) const);
template<class R, class A1, class A2>
static yes_t test(R(T::*)(A1,A2) const);
template<class R, class A1, class A2, class A3>
static yes_t test(R(T::*)(A1,A2,A3) const);
};
template<class T, class U>
struct is_const_member_function
{
static U getU();
enum
{
value = sizeof(is_const_member_function_helper<T>::test(getU())) == sizeof(yes_t)
};
};
*/
template<int v1, int v2>
struct max_c
{
enum { value = (v1>v2)?v1:v2 };
};
}}
#endif // LUABIND_TYPETRAITS_HPP_INCLUDED

View File

@ -1,4 +1,4 @@
// Copyright (c) 2004 Daniel Wallin and Arvid Norberg // Copyright (c) 2004 Daniel Wallin
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"), // copy of this software and associated documentation files (the "Software"),
@ -20,13 +20,15 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE. // OR OTHER DEALINGS IN THE SOFTWARE.
#define LUABIND_BUILDING #ifndef YES_NO_040211_HPP
#define YES_NO_040211_HPP
#include <luabind/operator.hpp> namespace luabind { namespace detail {
namespace luabind typedef char(&yes_t)[1];
{ typedef char(&no_t)[2];
LUABIND_API self_type self;
LUABIND_API const_self_type const_self; }} // namespace luabind::detail
}
#endif // YES_NO_040211_HPP

View File

@ -20,41 +20,52 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE. // OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED #ifndef LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED
#define LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED #define LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/detail/policy.hpp> // for index_map, etc #include <luabind/detail/policy.hpp>
#include <luabind/detail/primitives.hpp> // for null_type, etc
#include <luabind/lua_include.hpp>
namespace luabind { namespace luabind { namespace detail
namespace detail { {
struct discard_converter
{
template<class T>
void apply(lua_State*, T) {}
};
struct discard_converter struct discard_result_policy : conversion_policy<0>
{
static void precall(lua_State*, const index_map&) {}
static void postcall(lua_State*, const index_map&) {}
struct can_only_convert_from_cpp_to_lua {};
template<class T, class Direction>
struct apply
{ {
template<class T> typedef typename boost::mpl::if_<boost::is_same<Direction, cpp_to_lua>
void to_lua(lua_State*, T) {} , discard_converter
, can_only_convert_from_cpp_to_lua
>::type type;
}; };
};
struct discard_result_policy }}
{
struct can_only_convert_from_cpp_to_lua {};
template<class T, class Direction>
struct specialize
{
static_assert(std::is_same< Direction, cpp_to_lua >::value, "Can only convert from cpp to lua");
using type = discard_converter;
};
};
}
}
namespace luabind namespace luabind
{ {
using discard_result = meta::type_list<converter_policy_injector<0, detail::discard_result_policy>>; detail::policy_cons<
detail::discard_result_policy, detail::null_type> const discard_result = {};
namespace detail
{
inline void ignore_unused_discard_result()
{
(void)discard_result;
}
}
} }
#endif // LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED #endif // LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED

View File

@ -26,13 +26,9 @@
#include <luabind/prefix.hpp> #include <luabind/prefix.hpp>
#include <exception> #include <exception>
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/error_callback_fun.hpp>
#include <luabind/lua_state_fwd.hpp>
#include <string>
#ifndef LUABIND_NO_EXCEPTIONS
#include <luabind/typeid.hpp> #include <luabind/typeid.hpp>
#endif
struct lua_State;
namespace luabind namespace luabind
{ {
@ -42,19 +38,22 @@ namespace luabind
// this exception usually means that the lua function you called // this exception usually means that the lua function you called
// from C++ failed with an error code. You will have to // from C++ failed with an error code. You will have to
// read the error code from the top of the lua stack // read the error code from the top of the lua stack
// note that std::string's copy constructor // the reason why this exception class doesn't contain
// the message itself is that std::string's copy constructor
// may throw, if the copy constructor of an exception that is // may throw, if the copy constructor of an exception that is
// being thrown throws another exception, terminate will be called // being thrown throws another exception, terminate will be called
// and the entire application is killed. // and the entire application is killed.
class LUABIND_API error : public std::exception class LUABIND_API error : public std::exception
{ {
public: public:
explicit error(lua_State* L); explicit error(lua_State* L): m_L(L) {}
lua_State* state() const throw() { return m_L; }
virtual const char* what() const throw(); virtual const char* what() const throw()
{
return "lua runtime error";
}
private: private:
std::string m_message; lua_State* m_L;
}; };
// if an object_cast<>() fails, this is thrown // if an object_cast<>() fails, this is thrown
@ -63,7 +62,7 @@ namespace luabind
class LUABIND_API cast_failed : public std::exception class LUABIND_API cast_failed : public std::exception
{ {
public: public:
cast_failed(lua_State* L, type_id const& i) : m_L(L), m_info(i) {} cast_failed(lua_State* L, type_id const& i): m_L(L), m_info(i) {}
lua_State* state() const throw() { return m_L; } lua_State* state() const throw() { return m_L; }
type_id info() const throw() { return m_info; } type_id info() const throw() { return m_info; }
virtual const char* what() const throw() { return "unable to make cast"; } virtual const char* what() const throw() { return "unable to make cast"; }
@ -74,6 +73,9 @@ namespace luabind
#else #else
typedef void(*error_callback_fun)(lua_State*);
typedef void(*cast_failed_callback_fun)(lua_State*, type_id const&);
LUABIND_API void set_error_callback(error_callback_fun e); LUABIND_API void set_error_callback(error_callback_fun e);
LUABIND_API void set_cast_failed_callback(cast_failed_callback_fun c); LUABIND_API void set_cast_failed_callback(cast_failed_callback_fun c);
LUABIND_API error_callback_fun get_error_callback(); LUABIND_API error_callback_fun get_error_callback();
@ -81,6 +83,7 @@ namespace luabind
#endif #endif
typedef int(*pcall_callback_fun)(lua_State*);
LUABIND_API void set_pcall_callback(pcall_callback_fun e); LUABIND_API void set_pcall_callback(pcall_callback_fun e);
LUABIND_API pcall_callback_fun get_pcall_callback(); LUABIND_API pcall_callback_fun get_pcall_callback();

View File

@ -3,73 +3,106 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef LUABIND_EXCEPTION_HANDLER_050601_HPP #ifndef LUABIND_EXCEPTION_HANDLER_050601_HPP
#define LUABIND_EXCEPTION_HANDLER_050601_HPP # define LUABIND_EXCEPTION_HANDLER_050601_HPP
#include <luabind/config.hpp> // for LUABIND_API # include <luabind/lua_include.hpp>
#include <type_traits> # include <luabind/config.hpp>
#include <luabind/lua_include.hpp> # include <boost/optional.hpp>
#include <luabind/detail/meta.hpp> # include <boost/type.hpp>
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
# include <boost/mpl/if.hpp>
# include <boost/type_traits/is_pointer.hpp>
# endif
namespace luabind { namespace luabind {
# ifndef LUABIND_NO_EXCEPTIONS # ifndef LUABIND_NO_EXCEPTIONS
namespace detail { namespace detail
{
struct LUABIND_API exception_handler_base struct LUABIND_API exception_handler_base
{ {
exception_handler_base() exception_handler_base()
: next(0) : next(0)
{} {}
virtual ~exception_handler_base() {} virtual ~exception_handler_base() {}
virtual void handle(lua_State*) const = 0; virtual void handle(lua_State*) const = 0;
void try_next(lua_State*) const; void try_next(lua_State*) const;
exception_handler_base* next; exception_handler_base* next;
}; };
template<class E, class Handler> namespace mpl = boost::mpl;
struct exception_handler : exception_handler_base
{
using argument = E const&;
exception_handler(Handler handler) template<class E, class Handler>
: handler(handler) struct exception_handler : exception_handler_base
{} {
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
typedef typename mpl::if_<
boost::is_pointer<E>, E, E const&
>::type argument;
# else
typedef E const& argument;
# endif
void handle(lua_State* L) const exception_handler(Handler handler)
{ : handler(handler)
try {}
{
try_next(L);
}
catch(argument e)
{
handler(L, e);
}
}
Handler handler; void handle(lua_State* L) const
}; {
try
{
try_next(L);
}
catch (argument e)
{
handler(L, e);
}
}
LUABIND_API void handle_exception_aux(lua_State* L); Handler handler;
LUABIND_API void register_exception_handler(exception_handler_base*); };
} // namespace detail LUABIND_API void handle_exception_aux(lua_State* L);
LUABIND_API void register_exception_handler(exception_handler_base*);
} // namespace detail
# endif # endif
template<class E, class Handler> template<class E, class Handler>
void register_exception_handler(Handler handler, meta::type<E>* = 0) void register_exception_handler(Handler handler, boost::type<E>* = 0)
{ {
# ifndef LUABIND_NO_EXCEPTIONS # ifndef LUABIND_NO_EXCEPTIONS
detail::register_exception_handler( detail::register_exception_handler(
new detail::exception_handler<E, Handler>(handler) new detail::exception_handler<E, Handler>(handler)
); );
# endif # endif
} }
template<class R, class F>
boost::optional<R> handle_exceptions(lua_State* L, F fn, boost::type<R>* = 0)
{
# ifndef LUABIND_NO_EXCEPTIONS
try
{
return fn();
}
catch (...)
{
detail::handle_exception_aux(L);
}
return boost::optional<R>();
# else
return fn();
# endif
}
} // namespace luabind } // namespace luabind

View File

@ -23,20 +23,18 @@
#ifndef LUABIND_FROM_STACK_050715_HPP #ifndef LUABIND_FROM_STACK_050715_HPP
#define LUABIND_FROM_STACK_050715_HPP #define LUABIND_FROM_STACK_050715_HPP
#include <luabind/lua_state_fwd.hpp>
namespace luabind { namespace luabind {
struct from_stack struct from_stack
{ {
from_stack(lua_State* interpreter, int index) from_stack(lua_State* interpreter, int index)
: interpreter(interpreter) : interpreter(interpreter)
, index(index) , index(index)
{} {}
lua_State* interpreter; lua_State* interpreter;
int index; int index;
}; };
} // namespace luabind } // namespace luabind

View File

@ -11,43 +11,50 @@
namespace luabind { namespace luabind {
namespace detail namespace detail
{ {
template <class F, class PolicyInjectors> template <class F, class Policies>
struct function_registration : registration struct function_registration : registration
{ {
function_registration(char const* name, F f) function_registration(char const* name, F f, Policies const& policies)
: name(name) : name(name)
, f(f) , f(f)
{} , policies(policies)
{}
void register_(lua_State* L) const void register_(lua_State* L) const
{ {
object fn = make_function(L, f, PolicyInjectors()); object fn = make_function(L, f, deduce_signature(f), policies);
add_overload(object(from_stack(L, -1)), name, fn);
}
char const* name; add_overload(
F f; object(from_stack(L, -1))
}; , name
, fn
);
}
LUABIND_API bool is_luabind_function(lua_State* L, int index); char const* name;
F f;
Policies policies;
};
} // namespace detail LUABIND_API bool is_luabind_function(lua_State* L, int index);
template <class F, typename... PolicyInjectors> } // namespace detail
scope def(char const* name, F f, policy_list<PolicyInjectors...> const&)
{
return scope(std::unique_ptr<detail::registration>(
new detail::function_registration<F, policy_list<PolicyInjectors...>>(name, f)));
}
template <class F> template <class F, class Policies>
scope def(char const* name, F f) scope def(char const* name, F f, Policies const& policies)
{ {
return def(name, f, no_policies()); return scope(std::auto_ptr<detail::registration>(
} new detail::function_registration<F, Policies>(name, f, policies)));
}
template <class F>
scope def(char const* name, F f)
{
return def(name, f, detail::null_type());
}
} // namespace luabind } // namespace luabind

View File

@ -1,56 +0,0 @@
/** @file
@brief Header
@date 2012
@author
Ryan Pavlik
<rpavlik@iastate.edu> and <abiryan@ryand.net>
http://academic.cleardefinition.com/
Iowa State University Virtual Reality Applications Center
Human-Computer Interaction Graduate Program
*/
// Copyright Iowa State University 2012.
// 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 INCLUDED_function_introspection_hpp_GUID_b55783e7_e6da_4816_925e_9256245c1065
#define INCLUDED_function_introspection_hpp_GUID_b55783e7_e6da_4816_925e_9256245c1065
// Internal Includes
#include <luabind/config.hpp>
#include <luabind/lua_state_fwd.hpp>
// Library/third-party includes
// - none
// Standard includes
// - none
namespace luabind {
LUABIND_API int bind_function_introspection(lua_State * L);
} // end of namespace luabind
#endif // INCLUDED_function_introspection_hpp_GUID_b55783e7_e6da_4816_925e_9256245c1065

View File

@ -6,13 +6,11 @@
# define LUABIND_GET_MAIN_THREAD_090321_HPP # define LUABIND_GET_MAIN_THREAD_090321_HPP
# include <luabind/config.hpp> # include <luabind/config.hpp>
# include <luabind/lua_state_fwd.hpp>
namespace luabind { namespace luabind {
LUABIND_API lua_State* get_main_thread(lua_State* L); LUABIND_API lua_State* get_main_thread(lua_State* L);
} // namespace luabind } // namespace luabind
#endif // LUABIND_GET_MAIN_THREAD_090321_HPP #endif // LUABIND_GET_MAIN_THREAD_090321_HPP

View File

@ -1,4 +1,4 @@
// Copyright (c) 2005 Daniel Wallin and Arvid Norberg // Copyright (c) 2005 Daniel Wallin
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"), // copy of this software and associated documentation files (the "Software"),
@ -20,19 +20,20 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE. // OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_LUA_STATE_FWD_HPP #ifndef LUABIND_GET_POINTER_051023_HPP
#define LUABIND_LUA_STATE_FWD_HPP # define LUABIND_GET_POINTER_051023_HPP
#ifndef LUABIND_CPLUSPLUS_LUA //
extern "C" // We need these overloads in the luabind namespace.
{ //
#endif
struct lua_State; # include <boost/get_pointer.hpp>
#ifndef LUABIND_CPLUSPLUS_LUA namespace luabind {
}
#endif
#endif // LUABIND_BACK_REFERENCE_FWD_040510_HPP using boost::get_pointer;
} // namespace luabind
#endif // LUABIND_GET_POINTER_051023_HPP

View File

@ -24,115 +24,119 @@
#define LUABIND_HANDLE_050420_HPP #define LUABIND_HANDLE_050420_HPP
#include <luabind/lua_include.hpp> #include <luabind/lua_include.hpp>
#include <luabind/lua_proxy.hpp> #include <luabind/value_wrapper.hpp>
#include <utility>
namespace luabind { namespace luabind {
// A reference to a Lua value. Represents an entry in the // A reference to a Lua value. Represents an entry in the
// registry table. // registry table.
class handle class handle
{ {
public: public:
handle(); handle();
handle(lua_State* interpreter, int stack_index); handle(lua_State* interpreter, int stack_index);
handle(lua_State* main, lua_State* interpreter, int stack_index); handle(lua_State* main, lua_State* interpreter, int stack_index);
handle(handle const& other); handle(handle const& other);
~handle(); ~handle();
handle& operator=(handle const& other); handle& operator=(handle const& other);
void swap(handle& other); void swap(handle& other);
void push(lua_State* interpreter) const; void push(lua_State* interpreter) const;
lua_State* interpreter() const; lua_State* interpreter() const;
void replace(lua_State* interpreter, int stack_index); void replace(lua_State* interpreter, int stack_index);
private: private:
lua_State* m_interpreter; lua_State* m_interpreter;
int m_index; int m_index;
}; };
inline handle::handle() inline handle::handle()
: m_interpreter(0), m_index(LUA_NOREF) : m_interpreter(0)
{} , m_index(LUA_NOREF)
{}
inline handle::handle(handle const& other) inline handle::handle(handle const& other)
: m_interpreter(other.m_interpreter), m_index(LUA_NOREF) : m_interpreter(other.m_interpreter)
{ , m_index(LUA_NOREF)
if(m_interpreter == 0) return; {
lua_rawgeti(m_interpreter, LUA_REGISTRYINDEX, other.m_index); if (m_interpreter == 0) return;
m_index = luaL_ref(m_interpreter, LUA_REGISTRYINDEX); lua_rawgeti(m_interpreter, LUA_REGISTRYINDEX, other.m_index);
} m_index = luaL_ref(m_interpreter, LUA_REGISTRYINDEX);
}
inline handle::handle(lua_State* interpreter, int stack_index) inline handle::handle(lua_State* interpreter, int stack_index)
: m_interpreter(interpreter), m_index(LUA_NOREF) : m_interpreter(interpreter)
{ , m_index(LUA_NOREF)
lua_pushvalue(interpreter, stack_index); {
m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX); lua_pushvalue(interpreter, stack_index);
} m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX);
}
inline handle::handle(lua_State* main, lua_State* interpreter, int stack_index) inline handle::handle(lua_State* main, lua_State* interpreter, int stack_index)
: m_interpreter(main), m_index(LUA_NOREF) : m_interpreter(main)
{ , m_index(LUA_NOREF)
lua_pushvalue(interpreter, stack_index); {
m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX); lua_pushvalue(interpreter, stack_index);
} m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX);
}
inline handle::~handle() inline handle::~handle()
{ {
if(m_interpreter && m_index != LUA_NOREF) luaL_unref(m_interpreter, LUA_REGISTRYINDEX, m_index); if (m_interpreter && m_index != LUA_NOREF)
} luaL_unref(m_interpreter, LUA_REGISTRYINDEX, m_index);
}
inline handle& handle::operator=(handle const& other) inline handle& handle::operator=(handle const& other)
{ {
handle(other).swap(*this); handle(other).swap(*this);
return *this; return *this;
} }
inline void handle::swap(handle& other) inline void handle::swap(handle& other)
{ {
std::swap(m_interpreter, other.m_interpreter); std::swap(m_interpreter, other.m_interpreter);
std::swap(m_index, other.m_index); std::swap(m_index, other.m_index);
} }
inline void handle::push(lua_State* interpreter) const inline void handle::push(lua_State* interpreter) const
{ {
lua_rawgeti(interpreter, LUA_REGISTRYINDEX, m_index); lua_rawgeti(interpreter, LUA_REGISTRYINDEX, m_index);
} }
inline lua_State* handle::interpreter() const inline lua_State* handle::interpreter() const
{ {
return m_interpreter; return m_interpreter;
} }
inline void handle::replace(lua_State* interpreter, int stack_index) inline void handle::replace(lua_State* interpreter, int stack_index)
{ {
lua_pushvalue(interpreter, stack_index); lua_pushvalue(interpreter, stack_index);
lua_rawseti(interpreter, LUA_REGISTRYINDEX, m_index); lua_rawseti(interpreter, LUA_REGISTRYINDEX, m_index);
} }
template<> template<>
struct lua_proxy_traits<handle> struct value_wrapper_traits<handle>
{ {
using is_specialized = std::true_type; typedef boost::mpl::true_ is_specialized;
static lua_State* interpreter(handle const& value) static lua_State* interpreter(handle const& value)
{ {
return value.interpreter(); return value.interpreter();
} }
static void unwrap(lua_State* interpreter, handle const& value)
{
value.push(interpreter);
}
static void unwrap(lua_State* interpreter, handle const& value) static bool check(...)
{ {
value.push(interpreter); return true;
} }
};
static bool check(...)
{
return true;
}
};
} // namespace luabind } // namespace luabind

View File

@ -5,105 +5,108 @@
#ifndef LUABIND_ITERATOR_POLICY__071111_HPP #ifndef LUABIND_ITERATOR_POLICY__071111_HPP
# define LUABIND_ITERATOR_POLICY__071111_HPP # define LUABIND_ITERATOR_POLICY__071111_HPP
# include <luabind/config.hpp> // for LUABIND_ANONYMOUS_FIX # include <luabind/config.hpp>
# include <luabind/detail/push_to_lua.hpp> // for convert_to_lua # include <luabind/detail/policy.hpp>
# include <luabind/detail/policy.hpp> // for index_map, etc # include <luabind/detail/convert_to_lua.hpp>
# include <new> // for operator new namespace luabind { namespace detail {
namespace luabind { template <class Iterator>
namespace detail { struct iterator
{
static int next(lua_State* L)
{
iterator* self = static_cast<iterator*>(
lua_touserdata(L, lua_upvalueindex(1)));
template <class Iterator> if (self->first != self->last)
struct iterator {
{ convert_to_lua(L, *self->first);
static int next(lua_State* L) ++self->first;
{ }
iterator* self = static_cast<iterator*>( else
lua_touserdata(L, lua_upvalueindex(1))); {
lua_pushnil(L);
}
if(self->first != self->last) return 1;
{ }
push_to_lua(L, *self->first);
++self->first;
} else
{
lua_pushnil(L);
}
return 1; static int destroy(lua_State* L)
} {
iterator* self = static_cast<iterator*>(lua_touserdata(L, 1));
self->~iterator();
return 0;
}
static int destroy(lua_State* L) iterator(Iterator first, Iterator last)
{ : first(first)
iterator* self = static_cast<iterator*>(lua_touserdata(L, 1)); , last(last)
self->~iterator(); {}
return 0;
}
iterator(Iterator first, Iterator last) Iterator first;
: first(first) Iterator last;
, last(last) };
{}
Iterator first; template <class Iterator>
Iterator last; int make_range(lua_State* L, Iterator first, Iterator last)
}; {
void* storage = lua_newuserdata(L, sizeof(iterator<Iterator>));
lua_newtable(L);
lua_pushcclosure(L, iterator<Iterator>::destroy, 0);
lua_setfield(L, -2, "__gc");
lua_setmetatable(L, -2);
lua_pushcclosure(L, iterator<Iterator>::next, 1);
new (storage) iterator<Iterator>(first, last);
return 1;
}
template <class Iterator> template <class Container>
int make_range(lua_State* L, Iterator first, Iterator last) int make_range(lua_State* L, Container& container)
{ {
void* storage = lua_newuserdata(L, sizeof(iterator<Iterator>)); return make_range(L, container.begin(), container.end());
lua_newtable(L); }
lua_pushcclosure(L, iterator<Iterator>::destroy, 0);
lua_setfield(L, -2, "__gc");
lua_setmetatable(L, -2);
lua_pushcclosure(L, iterator<Iterator>::next, 1);
new (storage) iterator<Iterator>(first, last);
return 1;
}
template <class Container> struct iterator_converter
int make_range(lua_State* L, Container& container) {
{ typedef iterator_converter type;
return make_range(L, container.begin(), container.end());
}
struct iterator_converter template <class Container>
{ void apply(lua_State* L, Container& container)
using type = iterator_converter; {
make_range(L, container);
}
template <class Container> template <class Container>
void to_lua(lua_State* L, Container& container) void apply(lua_State* L, Container const& container)
{ {
make_range(L, container); make_range(L, container);
} }
};
template <class Container> struct iterator_policy : conversion_policy<0>
void tu_lua(lua_State* L, Container const& container) {
{ static void precall(lua_State*, index_map const&)
make_range(L, container); {}
}
};
struct iterator_policy static void postcall(lua_State*, index_map const&)
{ {}
template <class T, class Direction>
struct specialize
{
static_assert(std::is_same<Direction, cpp_to_lua>::value, "Iterator policy can only convert from cpp to lua.");
using type = iterator_converter;
};
};
} // namespace detail template <class T, class Direction>
} // namespace luabind struct apply
{
typedef iterator_converter type;
};
};
namespace luabind { }} // namespace luabind::detail
using return_stl_iterator = policy_list<converter_policy_injector<0, detail::iterator_policy>>; namespace luabind { namespace {
} // namespace luabind LUABIND_ANONYMOUS_FIX detail::policy_cons<
detail::iterator_policy, detail::null_type> return_stl_iterator;
}} // namespace luabind::unnamed
#endif // LUABIND_ITERATOR_POLICY__071111_HPP #endif // LUABIND_ITERATOR_POLICY__071111_HPP

View File

@ -0,0 +1,56 @@
// Copyright (c) 2004 Daniel Wallin and Arvid Norberg
// 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 LUA_502_HPP
#define LUA_502_HPP
#if LUA_VERSION_NUM >= 502
inline LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
{
return lua_compare(L, idx1, idx2, LUA_OPEQ);
}
inline LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2)
{
return lua_compare(L, idx1, idx2, LUA_OPLT);
}
#undef lua_strlen
#define lua_strlen lua_rawlen
#undef lua_getfenv
#define lua_getfenv lua_getuservalue
#undef lua_setfenv
#define lua_setfenv lua_setuservalue
#undef lua_open
#define lua_open luaL_newstate
#else // LUA_VERSION_NUM >= 502
#define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX)
#endif // LUA_VERSION_NUM >= 502
#endif

View File

@ -1,71 +0,0 @@
#ifndef LUA_ARGUMENT_PROXY_HPP_INCLUDED
#define LUA_ARGUMENT_PROXY_HPP_INCLUDED
#include <luabind/lua_include.hpp>
#include <luabind/lua_proxy_interface.hpp>
#include <luabind/lua_index_proxy.hpp>
#include <luabind/from_stack.hpp>
namespace luabind {
namespace adl {
class argument : public lua_proxy_interface<argument>
{
public:
argument(from_stack const& stack_reference)
: m_interpreter(stack_reference.interpreter), m_index(stack_reference.index)
{
if(m_index < 0) m_index = lua_gettop(m_interpreter) - m_index + 1;
}
template<class T>
index_proxy<argument> operator[](T const& key) const
{
return index_proxy<argument>(*this, m_interpreter, key);
}
void push(lua_State* L) const
{
lua_pushvalue(L, m_index);
}
lua_State* interpreter() const
{
return m_interpreter;
}
private:
lua_State* m_interpreter;
int m_index;
};
}
using adl::argument;
template<>
struct lua_proxy_traits<argument>
{
using is_specialized = std::true_type;
static lua_State* interpreter(argument const& value)
{
return value.interpreter();
}
static void unwrap(lua_State* interpreter, argument const& value)
{
value.push(interpreter);
}
static bool check(...)
{
return true;
}
};
}
#endif

View File

@ -28,8 +28,8 @@ extern "C"
{ {
#endif #endif
#include "lua.h" #include "lua.h"
#include "lauxlib.h" #include "lauxlib.h"
#ifndef LUABIND_CPLUSPLUS_LUA #ifndef LUABIND_CPLUSPLUS_LUA
} }

View File

@ -1,137 +0,0 @@
#ifndef LUA_INDEX_PROXY_HPP_INCLUDED
#define LUA_INDEX_PROXY_HPP_INCLUDED
#include <cassert>
#include <luabind/lua_proxy_interface.hpp>
#include <luabind/detail/stack_utils.hpp>
#include <luabind/nil.hpp>
namespace luabind {
namespace adl {
class object;
template<class Next>
class index_proxy
: public lua_proxy_interface<index_proxy<Next> >
{
public:
using this_type = index_proxy<Next>;
template<class Key>
index_proxy(Next const& next, lua_State* interpreter, Key const& key)
: m_interpreter(interpreter), m_key_index(lua_gettop(interpreter) + 1), m_next(next)
{
detail::push_to_lua(m_interpreter, key);
}
index_proxy(index_proxy const& other)
: m_interpreter(other.m_interpreter), m_key_index(other.m_key_index), m_next(other.m_next)
{
other.m_interpreter = 0;
}
~index_proxy()
{
if(m_interpreter)
lua_pop(m_interpreter, 1);
}
// This is non-const to prevent conversion on lvalues.
// defined in luabind/detail/object.hpp
operator object();
// this will set the value to nil
this_type& operator=(luabind::detail::nil_type)
{
lua_proxy_traits<Next>::unwrap(m_interpreter, m_next);
detail::stack_pop pop(m_interpreter, 1);
lua_pushvalue(m_interpreter, m_key_index);
lua_pushnil(m_interpreter);
lua_settable(m_interpreter, -3);
return *this;
}
template<class T>
this_type& operator=(T&& value)
{
lua_proxy_traits<Next>::unwrap(m_interpreter, m_next);
detail::stack_pop pop(m_interpreter, 1);
lua_pushvalue(m_interpreter, m_key_index);
detail::push_to_lua(m_interpreter, std::forward<T>(value));
lua_settable(m_interpreter, -3);
return *this;
}
this_type& operator=(this_type const& value)
{
lua_proxy_traits<Next>::unwrap(m_interpreter, m_next);
detail::stack_pop pop(m_interpreter, 1);
lua_pushvalue(m_interpreter, m_key_index);
detail::push_to_lua(m_interpreter, value);
lua_settable(m_interpreter, -3);
return *this;
}
template<class T>
index_proxy<this_type> operator[](T const& key)
{
return index_proxy<this_type>(*this, m_interpreter, key);
}
void push(lua_State* interpreter);
lua_State* interpreter() const
{
return m_interpreter;
}
private:
struct hidden_type {};
mutable lua_State* m_interpreter;
int m_key_index;
Next const& m_next;
};
template<class Next>
inline void index_proxy<Next>::push(lua_State* interpreter)
{
assert(interpreter == m_interpreter);
lua_proxy_traits<Next>::unwrap(m_interpreter, m_next);
lua_pushvalue(m_interpreter, m_key_index);
lua_gettable(m_interpreter, -2);
lua_remove(m_interpreter, -2);
}
} // namespace adl
template<class T>
struct lua_proxy_traits<adl::index_proxy<T> >
{
using is_specialized = std::true_type;
template<class Next>
static lua_State* interpreter(adl::index_proxy<Next> const& proxy)
{
return proxy.interpreter();
}
template<class Next>
static void unwrap(lua_State* interpreter, adl::index_proxy<Next> const& proxy)
{
const_cast<adl::index_proxy<Next>&>(proxy).push(interpreter);
}
};
} // namespace luabind
#endif

View File

@ -1,230 +0,0 @@
#ifndef LUA_ITERATOR_PROXY_HPP_INCLUDED
#define LUA_ITERATOR_PROXY_HPP_INCLUDED
#include <luabind/lua_proxy_interface.hpp>
#include <luabind/lua_index_proxy.hpp>
#include <luabind/handle.hpp>
#include <luabind/nil.hpp>
#include <luabind/lua_include.hpp>
#include <luabind/detail/crtp_iterator.hpp>
#if LUA_VERSION_NUM < 502
# define lua_compare(L, index1, index2, fn) fn(L, index1, index2)
# define LUA_OPEQ lua_equal
#endif
namespace luabind {
namespace adl {
template<class AccessPolicy>
class iterator_proxy :
public lua_proxy_interface<iterator_proxy<AccessPolicy> >
{
public:
iterator_proxy(lua_State* interpreter, handle const& table, handle const& key)
: m_interpreter(interpreter), m_table_index(lua_gettop(interpreter) + 1), m_key_index(m_table_index + 1)
{
table.push(m_interpreter);
key.push(m_interpreter);
}
iterator_proxy(iterator_proxy const& other)
: m_interpreter(other.m_interpreter), m_table_index(other.m_table_index), m_key_index(other.m_key_index)
{
other.m_interpreter = 0;
}
~iterator_proxy()
{
if(m_interpreter) lua_pop(m_interpreter, 2);
}
// this will set the value to nil
iterator_proxy & operator=(luabind::detail::nil_type)
{
lua_pushvalue(m_interpreter, m_key_index);
lua_pushnil(m_interpreter);
AccessPolicy::set(m_interpreter, m_table_index);
return *this;
}
template<class T>
iterator_proxy& operator=(T&& value)
{
lua_pushvalue(m_interpreter, m_key_index);
detail::push_to_lua(m_interpreter, std::forward<T>(value));
AccessPolicy::set(m_interpreter, m_table_index);
return *this;
}
template<class Key>
index_proxy<iterator_proxy<AccessPolicy> > operator[](Key const& key)
{
return index_proxy<iterator_proxy<AccessPolicy> >(
*this, m_interpreter, key
);
}
// This is non-const to prevent conversion on lvalues.
// defined in luabind/object.hpp
operator object();
lua_State* interpreter() const
{
return m_interpreter;
}
// TODO: Why is it non-const?
void push(lua_State* interpreter)
{
assert(interpreter == m_interpreter);
lua_pushvalue(m_interpreter, m_key_index);
AccessPolicy::get(m_interpreter, m_table_index);
}
private:
mutable lua_State* m_interpreter;
int m_table_index;
int m_key_index;
};
}
template<class AccessPolicy>
struct lua_proxy_traits<adl::iterator_proxy<AccessPolicy> >
{
using is_specialized = std::true_type;
template<class Proxy>
static lua_State* interpreter(Proxy const& p)
{
return p.interpreter();
}
template<class Proxy>
static void unwrap(lua_State* interpreter, Proxy const& p)
{
// TODO: Why const_cast?
const_cast<Proxy&>(p).push(interpreter);
}
};
namespace detail
{
struct basic_access
{
static void set(lua_State* interpreter, int table)
{
lua_settable(interpreter, table);
}
static void get(lua_State* interpreter, int table)
{
lua_gettable(interpreter, table);
}
};
struct raw_access
{
static void set(lua_State* interpreter, int table)
{
lua_rawset(interpreter, table);
}
static void get(lua_State* interpreter, int table)
{
lua_rawget(interpreter, table);
}
};
template<class AccessPolicy>
class basic_iterator :
public detail::crtp_iterator< basic_iterator<AccessPolicy>, adl::iterator_proxy<AccessPolicy>, std::forward_iterator_tag, adl::iterator_proxy<AccessPolicy> >
{
public:
basic_iterator()
: m_interpreter(0)
{}
template<class ValueWrapper>
explicit basic_iterator(ValueWrapper const& value_wrapper)
: m_interpreter(lua_proxy_traits<ValueWrapper>::interpreter(value_wrapper))
{
detail::stack_pop pop(m_interpreter, 1);
lua_proxy_traits<ValueWrapper>::unwrap(m_interpreter, value_wrapper);
lua_pushnil(m_interpreter);
if(lua_next(m_interpreter, -2) != 0) {
detail::stack_pop pop(m_interpreter, 2);
handle(m_interpreter, -2).swap(m_key);
} else {
m_interpreter = 0;
return;
}
handle(m_interpreter, -1).swap(m_table);
}
// defined in luabind/detail/object.hpp
adl::object key() const;
private:
template< typename, typename, typename, typename, typename >
friend class detail::crtp_iterator;
void increment()
{
m_table.push(m_interpreter);
m_key.push(m_interpreter);
detail::stack_pop pop(m_interpreter, 1);
if(lua_next(m_interpreter, -2) != 0) {
m_key.replace(m_interpreter, -2);
lua_pop(m_interpreter, 2);
} else {
m_interpreter = 0;
handle().swap(m_table);
handle().swap(m_key);
}
}
bool equal(basic_iterator const& other) const
{
if(m_interpreter == 0 && other.m_interpreter == 0)
return true;
if(m_interpreter != other.m_interpreter)
return false;
detail::stack_pop pop(m_interpreter, 2);
m_key.push(m_interpreter);
other.m_key.push(m_interpreter);
return lua_compare(m_interpreter, -2, -1, LUA_OPEQ) != 0;
}
adl::iterator_proxy<AccessPolicy> dereference() const
{
return adl::iterator_proxy<AccessPolicy>(m_interpreter, m_table, m_key);
}
lua_State* m_interpreter;
handle m_table;
handle m_key;
};
} // namespace detail
using iterator = detail::basic_iterator<detail::basic_access>;
using raw_iterator = detail::basic_iterator<detail::raw_access>;
}
#if LUA_VERSION_NUM < 502
#undef LUA_OPEQ
#undef lua_compare
#endif
#endif

View File

@ -1,306 +0,0 @@
#ifndef LUA_PROXY_INTERFACE_HPP_INCLUDED
#define LUA_PROXY_INTERFACE_HPP_INCLUDED
#include <luabind/lua_proxy.hpp>
#include <luabind/detail/call_function.hpp>
#include <luabind/detail/push_to_lua.hpp>
#include <ostream>
#if LUA_VERSION_NUM < 502
# define lua_compare(L, index1, index2, fn) fn(L, index1, index2)
# define LUA_OPEQ lua_equal
# define LUA_OPLT lua_lessthan
# define lua_rawlen lua_objlen
# define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX)
#endif
namespace luabind {
namespace adl {
template <class T>
class lua_proxy_interface;
namespace check_object_interface
{
template <class T>
std::true_type check(lua_proxy_interface<T>*);
std::false_type check(void*);
} // namespace is_object_interface_aux
template <class T>
struct is_object_interface : public decltype(check_object_interface::check((remove_const_reference_t<T>*)nullptr))
{};
template <class R, class T, class U>
struct enable_binary
: std::enable_if< is_object_interface<T>::value || is_object_interface<U>::value, R >
{};
template<class T, class U>
int binary_interpreter(lua_State*& L, T const& lhs, U const& rhs, std::true_type, std::true_type)
{
L = lua_proxy_traits<T>::interpreter(lhs);
lua_State* L2 = lua_proxy_traits<U>::interpreter(rhs);
// you are comparing objects with different interpreters
// that's not allowed.
assert(L == L2 || L == 0 || L2 == 0);
// if the two objects we compare have different interpreters
// then they
if(L != L2) return -1;
if(L == 0) return 1;
return 0;
}
template<class T, class U>
int binary_interpreter(lua_State*& L, T const& x, U const&, std::true_type, std::false_type)
{
L = lua_proxy_traits<T>::interpreter(x);
return 0;
}
template<class T, class U>
int binary_interpreter(lua_State*& L, T const&, U const& x, std::false_type, std::true_type)
{
L = lua_proxy_traits<U>::interpreter(x);
return 0;
}
template<class T, class U>
int binary_interpreter(lua_State*& L, T const& x, U const& y)
{
return binary_interpreter(L, x, y, is_lua_proxy_type<T>(), is_lua_proxy_type<U>());
}
template<class LHS, class RHS>
typename enable_binary<bool, LHS, RHS>::type
operator==(LHS&& lhs, RHS&& rhs)
{
lua_State* L = 0;
switch(binary_interpreter(L, lhs, rhs)) {
case 1: return true;
case-1: return false;
}
assert(L);
detail::stack_pop pop1(L, 1);
detail::push_to_lua(L, std::forward<LHS>(lhs));
detail::stack_pop pop2(L, 1);
detail::push_to_lua(L, std::forward<RHS>(rhs));
return lua_compare(L, -1, -2, LUA_OPEQ) != 0;
}
template<class LHS, class RHS>
typename enable_binary<bool, LHS, RHS>::type
operator<(LHS&& lhs, RHS&& rhs)
{
lua_State* L = 0;
switch(binary_interpreter(L, lhs, rhs)) {
case 1: return true;
case-1: return false;
}
assert(L);
detail::stack_pop pop1(L, 1);
detail::push_to_lua(L, std::forward<LHS>(lhs));
detail::stack_pop pop2(L, 1);
detail::push_to_lua(L, std::forward<RHS>(rhs));
return lua_compare(L, -1, -2, LUA_OPLT) != 0;
}
template<class ValueWrapper>
std::ostream& operator<<(std::ostream& os, lua_proxy_interface<ValueWrapper> const& v)
{
using namespace luabind;
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(
static_cast<ValueWrapper const&>(v));
detail::stack_pop pop(interpreter, 1);
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, static_cast<ValueWrapper const&>(v));
char const* p = lua_tostring(interpreter, -1);
std::size_t len = lua_rawlen(interpreter, -1);
os.write(p, len);
//std::copy(p, p+len, std::ostream_iterator<char>(os));
return os;
}
template<class LHS, class RHS>
typename enable_binary<bool, LHS, RHS>::type
operator>(LHS const& lhs, RHS const& rhs)
{
return !(lhs < rhs || lhs == rhs);
}
template<class LHS, class RHS>
typename enable_binary<bool, LHS, RHS>::type
operator<=(LHS const& lhs, RHS const& rhs)
{
return lhs < rhs || lhs == rhs;
}
template<class LHS, class RHS>
typename enable_binary<bool, LHS, RHS>::type
operator>=(LHS const& lhs, RHS const& rhs)
{
return !(lhs < rhs);
}
template<class LHS, class RHS>
typename enable_binary<bool, LHS, RHS>::type
operator!=(LHS const& lhs, RHS const& rhs)
{
return !(lhs == rhs);
}
template<class Derived>
class lua_proxy_interface
{
public:
~lua_proxy_interface() {}
// defined in luabind/detail/object.hpp
template<typename... Args>
object operator()(Args&&... args);
// defined in luabind/detail/object.hpp
template<typename PolicyList, typename... Args>
object call(Args&&... args);
explicit operator bool() const
{
lua_State* L = lua_proxy_traits<Derived>::interpreter(derived());
if(!L) return 0;
lua_proxy_traits<Derived>::unwrap(L, derived());
detail::stack_pop pop(L, 1);
return lua_toboolean(L, -1) == 1;
}
private:
Derived& derived() { return *static_cast<Derived*>(this); }
Derived const& derived() const { return *static_cast<Derived const*>(this); }
};
}
template<class ValueWrapper>
std::string to_string(adl::lua_proxy_interface<ValueWrapper> const& v)
{
using namespace luabind;
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(static_cast<ValueWrapper const&>(v));
detail::stack_pop pop(interpreter, 1);
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, static_cast<ValueWrapper const&>(v));
char const* p = lua_tostring(interpreter, -1);
std::size_t len = lua_rawlen(interpreter, -1);
return std::string(p, len);
}
namespace detail
{
template<class T, class ValueWrapper, class Policies, class ErrorPolicy, class ReturnType >
ReturnType object_cast_aux(ValueWrapper const& value_wrapper, T*, Policies*, ErrorPolicy error_policy, ReturnType*)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(value_wrapper);
#ifndef LUABIND_NO_ERROR_CHECKING
if(!interpreter)
return error_policy.handle_error(interpreter, typeid(void));
#endif
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, value_wrapper);
detail::stack_pop pop(interpreter, 1);
specialized_converter_policy_n<0, Policies, T, lua_to_cpp> cv;
if(cv.match(interpreter, decorate_type_t<T>(), -1) < 0) {
return error_policy.handle_error(interpreter, typeid(T));
}
return cv.to_cpp(interpreter, decorate_type_t<T>(), -1);
}
template<class T>
struct throw_error_policy
{
T handle_error(lua_State* interpreter, type_id const& type_info)
{
#ifndef LUABIND_NO_EXCEPTIONS
throw cast_failed(interpreter, type_info);
#else
cast_failed_callback_fun e = get_cast_failed_callback();
if(e) e(interpreter, type_info);
assert(0 && "object_cast failed. If you want to handle this error use "
"luabind::set_error_callback()");
std::terminate();
#endif
//return *(typename std::remove_reference<T>::type*)0; //DEAD CODE!
}
};
template<class T>
struct nothrow_error_policy
{
nothrow_error_policy(T rhs) : value(rhs) {}
T handle_error(lua_State*, type_id const&)
{
return value;
}
private:
T value;
};
} // namespace detail
template<class T, class ValueWrapper> inline
T object_cast(ValueWrapper const& value_wrapper)
{
return detail::object_cast_aux(value_wrapper, (T*)0, (no_policies*)0, detail::throw_error_policy<T>(), (T*)0);
}
template<class T, class ValueWrapper, class Policies> inline
T object_cast(ValueWrapper const& value_wrapper, Policies const&)
{
return detail::object_cast_aux(value_wrapper, (T*)0, (Policies*)0, detail::throw_error_policy<T>(), (T*)0);
}
template<typename T, typename ValueWrapper, typename ReturnValue> inline
ReturnValue object_cast_nothrow(ValueWrapper const& value_wrapper, ReturnValue default_value)
{
return detail::object_cast_aux(value_wrapper, (T*)0, (no_policies*)0, detail::nothrow_error_policy<ReturnValue>(default_value), (ReturnValue*)0);
}
template<typename T, typename ValueWrapper, typename Policies, typename ReturnValue> inline
ReturnValue object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&, ReturnValue default_value)
{
return detail::object_cast_aux(value_wrapper, (T*)0, (Policies*)0, detail::nothrow_error_policy<ReturnValue>(default_value), (ReturnValue*)0);
}
template <class ValueWrapper>
inline lua_CFunction tocfunction(ValueWrapper const& value)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(value);
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, value);
detail::stack_pop pop(interpreter, 1);
return lua_tocfunction(interpreter, -1);
}
template <class T, class ValueWrapper>
inline T* touserdata(ValueWrapper const& value)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(value);
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, value);
detail::stack_pop pop(interpreter, 1);
return static_cast<T*>(lua_touserdata(interpreter, -1));
}
}
#if LUA_VERSION_NUM < 502
# undef lua_compare
# undef LUA_OPEQ
# undef LUA_OPLT
# undef lua_rawlen
# undef lua_pushglobaltable
#endif
#endif

View File

@ -28,7 +28,5 @@
#include <luabind/class.hpp> #include <luabind/class.hpp>
#include <luabind/function.hpp> #include <luabind/function.hpp>
#include <luabind/open.hpp> #include <luabind/open.hpp>
#include <luabind/detail/conversion_policies/conversion_policies.hpp>
#endif // LUABIND_BIND_HPP_INCLUDED #endif // LUABIND_BIND_HPP_INCLUDED

View File

@ -3,125 +3,119 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef LUABIND_MAKE_FUNCTION_081014_HPP #ifndef LUABIND_MAKE_FUNCTION_081014_HPP
#define LUABIND_MAKE_FUNCTION_081014_HPP # define LUABIND_MAKE_FUNCTION_081014_HPP
#include <luabind/config.hpp> # include <luabind/config.hpp>
#include <luabind/detail/object.hpp> # include <luabind/object.hpp>
#include <luabind/detail/call.hpp> # include <luabind/detail/call.hpp>
#include <luabind/detail/deduce_signature.hpp> # include <luabind/detail/compute_score.hpp>
#include <luabind/detail/format_signature.hpp> # include <luabind/detail/deduce_signature.hpp>
# include <luabind/detail/format_signature.hpp>
namespace luabind { namespace luabind {
namespace detail namespace detail
{ {
# ifndef LUABIND_NO_EXCEPTIONS # ifndef LUABIND_NO_EXCEPTIONS
LUABIND_API void handle_exception_aux(lua_State* L); LUABIND_API void handle_exception_aux(lua_State* L);
# endif # endif
// MSVC complains about member being sensitive to alignment (C4121) // MSVC complains about member being sensitive to alignment (C4121)
// when F is a pointer to member of a class with virtual bases. // when F is a pointer to member of a class with virtual bases.
# ifdef _MSC_VER # ifdef BOOST_MSVC
# pragma pack(push) # pragma pack(push)
# pragma pack(16) # pragma pack(16)
# endif # endif
template <class F, class Signature, class InjectorList> template <class F, class Signature, class Policies>
struct function_object_impl : function_object struct function_object_impl : function_object
{ {
function_object_impl(F f) function_object_impl(F f, Policies const& policies)
: function_object(&entry_point), f(f) : function_object(&entry_point)
{} , f(f)
, policies(policies)
{}
int call(lua_State* L, invoke_context& ctx) /*const*/ int call(lua_State* L, invoke_context& ctx) const
{ {
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS return invoke(L, *this, ctx, f, Signature(), policies);
return invoke(L, *this, ctx, f, Signature(), InjectorList()); }
#else
return invoke<InjectorList, Signature>(L, *this, ctx, f);
#endif
}
void format_signature(lua_State* L, char const* function) const void format_signature(lua_State* L, char const* function) const
{ {
detail::format_signature(L, function, Signature()); detail::format_signature(L, function, Signature());
} }
static bool invoke_defer(lua_State* L, function_object_impl* impl, invoke_context& ctx, int& results) static int entry_point(lua_State* L)
{ {
bool exception_caught = false; function_object_impl const* impl =
*(function_object_impl const**)lua_touserdata(L, lua_upvalueindex(1));
try { invoke_context ctx;
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
results = invoke(L, *impl, ctx, impl->f, Signature(), InjectorList());
#else
results = invoke<InjectorList, Signature>(L, *impl, ctx, impl->f);
#endif
}
catch(...) {
exception_caught = true;
handle_exception_aux(L);
}
return exception_caught; int results = 0;
}
static int entry_point(lua_State* L)
{
function_object_impl const* impl_const = *(function_object_impl const**)lua_touserdata(L, lua_upvalueindex(1));
// TODO: Can this be done differently?
function_object_impl* impl = const_cast<function_object_impl*>(impl_const);
invoke_context ctx;
int results = 0;
# ifndef LUABIND_NO_EXCEPTIONS # ifndef LUABIND_NO_EXCEPTIONS
bool exception_caught = invoke_defer(L, impl, ctx, results); bool exception_caught = false;
if(exception_caught) lua_error(L);
try
{
results = invoke(
L, *impl, ctx, impl->f, Signature(), impl->policies);
}
catch (...)
{
exception_caught = true;
handle_exception_aux(L);
}
if (exception_caught)
lua_error(L);
# else # else
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS results = invoke(L, *impl, ctx, impl->f, Signature(), impl->policies);
results = invoke(L, *impl, ctx, impl->f, Signature(), InjectorList());
#else
results = invoke<InjectorList, Signature>(L, *impl, ctx, impl->f);
#endif
# endif # endif
if(!ctx) {
ctx.format_error(L, impl);
lua_error(L);
}
return results; if (!ctx)
} {
ctx.format_error(L, impl);
lua_error(L);
}
F f; return results;
}; }
# ifdef _MSC_VER F f;
Policies policies;
};
# ifdef BOOST_MSVC
# pragma pack(pop) # pragma pack(pop)
# endif # endif
LUABIND_API object make_function_aux(lua_State* L, function_object* impl); LUABIND_API object make_function_aux(
LUABIND_API void add_overload(object const&, char const*, object const&); lua_State* L, function_object* impl
);
} // namespace detail LUABIND_API void add_overload(object const&, char const*, object const&);
template <class F, typename... SignatureElements, typename... PolicyInjectors > } // namespace detail
object make_function(lua_State* L, F f, meta::type_list< SignatureElements... >, meta::type_list< PolicyInjectors... >)
{
return detail::make_function_aux(L, new detail::function_object_impl<F, meta::type_list< SignatureElements... >, meta::type_list< PolicyInjectors...> >(f));
}
template <class F, typename... PolicyInjectors > template <class F, class Signature, class Policies>
object make_function(lua_State* L, F f, meta::type_list< PolicyInjectors... >) object make_function(lua_State* L, F f, Signature, Policies)
{ {
return make_function(L, f, deduce_signature_t<F>(), meta::type_list< PolicyInjectors... >()); return detail::make_function_aux(
} L
, new detail::function_object_impl<F, Signature, Policies>(
f, Policies()
)
);
}
template <class F> template <class F>
object make_function(lua_State* L, F f) object make_function(lua_State* L, F f)
{ {
return make_function(L, f, deduce_signature_t<F>(), no_policies()); return make_function(L, detail::deduce_signature(f), detail::null_type());
} }
} // namespace luabind } // namespace luabind

Some files were not shown because too many files have changed in this diff Show More