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/
logs/
vcpkg/
perl/
.idea/*
*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)
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
#EQEmu CMake
#Variables used:
#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)
CMAKE_POLICY(SET CMP0074 NEW)
cmake_policy(SET CMP0074 NEW)
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)
#Default build type is set to RelWithDebInfo for generators that honor that like makefiles
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_CXX_EXTENSIONS OFF)
SET(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/dependencies" "${CMAKE_PREFIX_PATH}")
#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)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
ADD_DEFINITIONS(-DNOMINMAX)
ADD_DEFINITIONS(-DCRASH_LOGGING)
IF(CMAKE_CL_64)
SET(EQEMU_ARCH "x64")
SET(EQEMU_ARCH_ALT "x64")
ELSE(CMAKE_CL_64)
SET(EQEMU_ARCH "x86")
SET(EQEMU_ARCH_ALT "Win32")
ENDIF(CMAKE_CL_64)
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)
#Normally set by perl but we don't use the perl flags anymore so we set it.
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
ENDIF(MSVC)
@ -39,279 +131,130 @@ IF(UNIX)
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
ENDIF(UNIX)
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT)
ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL)
#debug level, 5 is default. Most people wont ever change this but it's there if you want to
SET(EQEMU_DEBUG_LEVEL 5 CACHE STRING "EQEmu debug level:
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.
IF(MSVC)
INCLUDE("${CMAKE_SOURCE_DIR}/cmake/DependencyHelperMSVC.cmake")
ENDIF()
SET(EQEMU_LOG_LEVEL_DEBUG 3 CACHE STRING "EQEmu logging level for [Debug]:
0 - Disabled
1 - Ouput to File Enabled
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
FIND_PACKAGE(MySQL)
FIND_PACKAGE(MariaDB)
FIND_PACKAGE(ZLIB)
FIND_PACKAGE(OpenSSL)
FIND_PACKAGE(Lua51)
FIND_PACKAGE(PerlLibs)
FIND_PACKAGE(Sodium)
FIND_PACKAGE(mbedTLS)
OPTION(EQEMU_LSPX "" OFF)
MARK_AS_ADVANCED(EQEMU_LSPX)
MESSAGE(STATUS "**************************************************")
MESSAGE(STATUS "* Library Detection *")
MESSAGE(STATUS "**************************************************")
MARK_AS_ADVANCED(EQEMU_LOG_LEVEL_DEBUG)
IF(MYSQL_FOUND)
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)
#Bots are a compile time option so on/off
OPTION(EQEMU_ENABLE_BOTS "Enable Bots" OFF)
#Enable GM Command log system
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)
ADD_DEFINITIONS(-DCOMMANDS_LOGGING)
ENDIF(EQEMU_COMMANDS_LOGGING)
IF(EQEMU_LSPX)
ADD_DEFINITIONS(-DLSPX=ON)
ENDIF(EQEMU_LSPX)
IF(EQEMU_ENABLE_BOTS)
ADD_DEFINITIONS(-DBOTS)
ENDIF(EQEMU_ENABLE_BOTS)
#database
IF(MySQL_FOUND AND MariaDB_FOUND)
SET(DATABASE_LIBRARY_SELECTION MySQL CACHE STRING "Database library to use:
MySQL
MariaDB"
)
#What to build
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
OPTION(EQEMU_BUILD_LOGIN "Build the login server." OFF)
OPTION(EQEMU_BUILD_HC "Build the headless client." OFF)
OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
IF(DATABASE_LIBRARY_SELECTION STREQUAL "MySQL")
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")
#C++11 stuff
IF(NOT MSVC)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reserved-user-defined-literal")
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()
ENDIF(NOT MSVC)
#security
#prefer openssl to mbedtls (arbitrary)
IF(OpenSSL_FOUND AND MBEDTLS_FOUND)
SET(TLS_LIBRARY_SELECTION OpenSSL CACHE STRING "TLS library to use:
OpenSSL
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()
ELSEIF(OpenSSL_FOUND)
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()
IF(SODIUM_FOUND)
SET(SODIUM_LIBRARY_TYPE "Libsodium")
SET(SODIUM_LIBRARY_ENABLED ON)
SET(SODIUM_LIBRARY_LIBS ${SODIUM_LIBRARIES})
SET(SODIUM_LIBRARY_INCLUDE ${SODIUM_INCLUDE_DIRS})
ADD_DEFINITIONS(-DENABLE_SECURITY)
ELSE()
SET(SODIUM_LIBRARY_TYPE " Disabled")
SET(SODIUM_LIBRARY_ENABLED OFF)
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)
OPTION(EQEMU_BUILD_ZLIB "Build internal version of zlib." ON)
IF(EQEMU_BUILD_ZLIB)
SET(ZLIB_LIBRARY_TYPE "zlib-ng")
SET(ZLIB_LIBRARY_LIBS "zlibstatic")
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
ELSE()
SET(ZLIB_LIBRARY_TYPE " zlib")
SET(ZLIB_LIBRARY_LIBS ${ZLIB_LIBRARY})
SET(ZLIB_LIBRARY_INCLUDE ${ZLIB_INCLUDE_DIRS})
ENDIF()
ELSE()
SET(ZLIB_LIBRARY_TYPE "zlib-ng")
SET(ZLIB_LIBRARY_LIBS "zlibstatic")
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
ENDIF()
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}")
#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)
OPTION(EQEMU_ENABLE_SECURITY "Use Encryption For TCP Connections" ON)
IF(EQEMU_ENABLE_SECURITY)
INCLUDE_DIRECTORIES(SYSTEM "${SODIUM_INCLUDE_DIRS}")
ADD_DEFINITIONS(-DENABLE_SECURITY)
SET(SERVER_LIBS ${SERVER_LIBS} ${SODIUM_LIBRARIES})
ENDIF()
ENDIF()
IF(ZLIB_FOUND)
OPTION(EQEMU_BUILD_ZLIB "Build internal version of zlib." OFF)
IF(EQEMU_BUILD_ZLIB)
INCLUDE_DIRECTORIES(BEFORE SYSTEM "${CMAKE_CURRENT_BINARY_DIR}/libs/zlibng" "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
SET(SERVER_LIBS ${SERVER_LIBS} "zlibstatic")
ELSE()
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_INCLUDE_DIRS}")
SET(SERVER_LIBS ${SERVER_LIBS} ${ZLIB_LIBRARY})
ENDIF()
ELSE()
MESSAGE(STATUS "Could NOT find ZLIB - using ZLIBSTATIC package.")
SET(EQEMU_BUILD_ZLIB ON)
INCLUDE_DIRECTORIES(BEFORE SYSTEM "${CMAKE_CURRENT_BINARY_DIR}/libs/zlibng" "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
SET(SERVER_LIBS ${SERVER_LIBS} "zlibstatic")
ENDIF()
IF(WIN32)
SET(SERVER_LIBS ${SERVER_LIBS} "ws2_32" "psapi" "iphlpapi" "userenv")
ENDIF()
@ -324,13 +267,34 @@ IF(UNIX)
SET(SERVER_LIBS ${SERVER_LIBS} "uuid")
ENDIF()
IF(EQEMU_BUILD_LOGIN AND NOT TLS_LIBRARY_ENABLED)
MESSAGE(FATAL_ERROR "Login server requires a TLS Library to build.")
ENDIF()
IF(EQEMU_BUILD_LUA)
FIND_PACKAGE(EQLua51 REQUIRED)
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)
MESSAGE(FATAL_ERROR "Headless client requires a TLS Library to build.")
ENDIF()
FIND_PACKAGE(Boost REQUIRED)
INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}" "${Boost_INCLUDE_DIRS}")
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)
ADD_SUBDIRECTORY(common)
@ -338,18 +302,17 @@ IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_H
ADD_SUBDIRECTORY(submodules/fmt)
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)
SET(ZLIB_COMPAT ON CACHE BOOL "Compile with zlib compatible API")
SET(ZLIB_ENABLE_TESTS OFF CACHE BOOL "Build test binaries")
ADD_SUBDIRECTORY(libs/zlibng)
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)
IF(EQEMU_BUILD_SERVER)
ADD_SUBDIRECTORY(shared_memory)
ADD_SUBDIRECTORY(world)
@ -358,7 +321,6 @@ IF(EQEMU_BUILD_SERVER)
ADD_SUBDIRECTORY(queryserv)
ADD_SUBDIRECTORY(eqlaunch)
ENDIF(EQEMU_BUILD_SERVER)
IF(EQEMU_BUILD_LOGIN)
ADD_SUBDIRECTORY(loginserver)
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(export)

View File

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

View File

@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(import_sources
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
base_packet.cpp

View File

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

View File

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

View File

@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(hc_sources
eq.cpp
@ -13,10 +13,14 @@ SET(hc_headers
world.h
)
FIND_PACKAGE(OpenSSL REQUIRED)
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
ADD_EXECUTABLE(hc ${hc_sources} ${hc_headers})
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)

View File

@ -1,61 +1,38 @@
# Build for LuaBind
# Ryan Pavlik <rpavlik@iastate.edu>
# http://academic.cleardefinition.com/
# Iowa State University HCI Graduate Program/VRAC
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
cmake_minimum_required(VERSION 3.0)
project(LuaBind)
set(CPACK_PACKAGE_VERSION_MAJOR "0")
set(CPACK_PACKAGE_VERSION_MINOR "9")
set(CPACK_PACKAGE_VERSION_PATCH "1")
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
if(NOT LUA_FOUND AND NOT LUA51_FOUND)
find_package(Lua51 REQUIRED)
set(LUA_INCLUDE_DIRS "${LUA_INCLUDE_DIR}")
endif()
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
# 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}
SET(lb_sources
src/class.cpp
src/class_info.cpp
src/class_registry.cpp
src/class_rep.cpp
src/create_class.cpp
src/error.cpp
src/exception_handler.cpp
src/function.cpp
src/inheritance.cpp
src/link_compatibility.cpp
src/object_rep.cpp
src/open.cpp
src/pcall.cpp
src/scope.cpp
src/stack_content_by_name.cpp
src/weak_ref.cpp
src/wrapper_base.cpp
)
add_subdirectory(src)
SET(lb_headers
if(BUILD_TESTING)
add_subdirectory(test)
endif()
)
if(LUABIND_BUILD_DOCS)
add_subdirectory(doc)
endif()
ADD_LIBRARY(luabind ${lb_sources} ${lb_headers})
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,14 +28,15 @@
#include <luabind/wrapper_base.hpp>
#include <luabind/detail/policy.hpp>
#include <luabind/back_reference_fwd.hpp>
#include <luabind/wrapper_base.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
namespace luabind {
namespace detail {
namespace luabind { namespace detail
{
template <class T>
void adjust_backref_ownership(T* ptr, std::true_type)
void adjust_backref_ownership(T* ptr, mpl::true_)
{
if(wrap_base* p = dynamic_cast<wrap_base*>(ptr))
if (wrap_base* p = dynamic_cast<wrap_base*>(ptr))
{
wrapped_self_t& wrapper = wrap_access::ref(*p);
wrapper.get(wrapper.state());
@ -43,25 +44,30 @@ namespace luabind {
}
}
inline void adjust_backref_ownership(void*, std::false_type)
inline void adjust_backref_ownership(void*, mpl::false_)
{}
template <class Pointer, class Direction = lua_to_cpp>
template<class Direction = lua_to_cpp>
struct adopt_pointer : pointer_converter
{
using type = adopt_pointer;
typedef adopt_pointer type;
enum { consumed_args = 1 };
int const consumed_args(...)
{
return 1;
}
template<class T>
T* to_cpp(lua_State* L, by_pointer<T>, int index)
T* apply(lua_State* L, by_pointer<T>, int index)
{
T* ptr = pointer_converter::to_cpp(L, decorate_type_t<T*>(), index);
T* ptr = pointer_converter::apply(
L, LUABIND_DECORATE_TYPE(T*), index);
object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
object_rep* obj = static_cast<object_rep*>(
lua_touserdata(L, index));
obj->release();
adjust_backref_ownership(ptr, std::is_polymorphic<T>());
adjust_backref_ownership(ptr, boost::is_polymorphic<T>());
return ptr;
}
@ -69,34 +75,23 @@ namespace luabind {
template<class T>
int match(lua_State* L, by_pointer<T>, int index)
{
return pointer_converter::match(L, decorate_type_t<T*>(), index);
return pointer_converter::match(
L, LUABIND_DECORATE_TYPE(T*), index);
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
template <class Pointer, class T>
struct pointer_or_default
template<>
struct adopt_pointer<cpp_to_lua>
{
using type = Pointer;
};
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;
typedef adopt_pointer type;
template<class T>
void to_lua(lua_State* L, T* ptr)
void apply(lua_State* L, T* ptr)
{
if(ptr == 0)
if (ptr == 0)
{
lua_pushnil(L);
return;
@ -105,34 +100,42 @@ namespace luabind {
// 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))
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));
make_instance(L, std::auto_ptr<T>(ptr));
}
};
template <class Pointer>
struct adopt_policy_impl
template<int N>
// 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 specialize
struct apply
{
static_assert(detail::is_nonconst_pointer<T>::value, "Adopt policy only accepts non-const pointers");
using type = adopt_pointer<Pointer, Direction>;
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;
};
};
}
}
}}
namespace luabind
{
// Caution: if we use the aliased type "policy_list" here, MSVC crashes.
template<unsigned int N, typename Pointer = void>
using adopt_policy = meta::type_list<converter_policy_injector<N, detail::adopt_policy_impl<Pointer>>>;
template<int N>
detail::policy_cons<detail::adopt_policy<N>, detail::null_type>
adopt(LUABIND_PLACEHOLDER_ARG(N))
{
return detail::policy_cons<detail::adopt_policy<N>, detail::null_type>();
}
}
#endif // LUABIND_ADOPT_POLICY_HPP_INCLUDE

View File

@ -23,29 +23,28 @@
#ifndef LUABIND_BACK_REFERENCE_040510_HPP
#define LUABIND_BACK_REFERENCE_040510_HPP
#include <luabind/config.hpp>
#include <luabind/lua_state_fwd.hpp>
#include <type_traits>
#if !defined(LUABIND_NO_RTTI) && !defined(LUABIND_WRAPPER_BASE_HPP_INCLUDED)
#include <luabind/lua_include.hpp>
#include <luabind/wrapper_base.hpp>
#endif
#include <luabind/pointer_traits.hpp>
#include <luabind/detail/has_get_pointer.hpp>
#include <luabind/get_pointer.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/mpl/if.hpp>
namespace luabind {
struct wrap_base;
namespace detail
{
namespace detail
{
namespace mpl = boost::mpl;
template<class T>
wrap_base const* get_back_reference_aux0(T const* p, std::true_type)
wrap_base const* get_back_reference_aux0(T const* p, mpl::true_)
{
return dynamic_cast<wrap_base const*>(p);
}
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;
}
@ -53,17 +52,17 @@ namespace luabind {
template<class T>
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>
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));
}
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);
}
@ -71,29 +70,32 @@ namespace luabind {
template<class T>
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
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);
return true;
}
#endif
return false;
}
}
template<class T>
bool move_back_reference(lua_State* L, T const& x)
{
template<class T>
bool move_back_reference(lua_State* L, T const& x)
{
#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());
detail::wrap_access::ref(*w).get(L);
@ -102,7 +104,7 @@ namespace luabind {
}
#endif
return false;
}
}
} // namespace luabind

View File

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

View File

@ -75,27 +75,42 @@
#include <vector>
#include <cassert>
#include <boost/bind.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_member_object_pointer.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/logical.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/logical.hpp>
#include <luabind/config.hpp>
#include <luabind/scope.hpp>
#include <luabind/back_reference.hpp>
#include <luabind/function.hpp> // -> object.hpp
#include <luabind/function.hpp>
#include <luabind/dependency_policy.hpp>
#include <luabind/detail/constructor.hpp> // -> object.hpp
#include <luabind/detail/constructor.hpp>
#include <luabind/detail/call.hpp>
#include <luabind/detail/deduce_signature.hpp>
#include <luabind/detail/compute_score.hpp>
#include <luabind/detail/primitives.hpp>
#include <luabind/detail/property.hpp>
#include <luabind/detail/type_traits.hpp>
#include <luabind/detail/typetraits.hpp>
#include <luabind/detail/class_rep.hpp>
#include <luabind/detail/object_rep.hpp>
#include <luabind/detail/call.hpp>
#include <luabind/detail/object_rep.hpp>
#include <luabind/detail/calc_arity.hpp>
#include <luabind/detail/call_member.hpp>
#include <luabind/detail/enum_maker.hpp>
#include <luabind/detail/operator_id.hpp>
#include <luabind/detail/pointee_typeid.hpp>
#include <luabind/detail/link_compatibility.hpp>
#include <luabind/detail/inheritance.hpp>
#include <luabind/detail/signature_match.hpp>
#include <luabind/no_dependency.hpp>
#include <luabind/typeid.hpp>
#include <luabind/detail/meta.hpp>
// to remove the 'this' used in initialization list-warning
#ifdef _MSC_VER
@ -103,8 +118,17 @@
#pragma warning(disable: 4355)
#endif
namespace luabind {
namespace detail {
namespace boost
{
template <class T> class shared_ptr;
} // namespace boost
namespace luabind
{
namespace detail
{
struct unspecified {};
template<class Derived> struct operator_;
@ -112,62 +136,7 @@ namespace luabind {
struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr {};
}
template < typename... BaseClasses >
struct bases { };
using no_bases = bases< >;
using default_holder = null_type;
namespace detail {
template < typename T >
struct make_bases {
using type = bases< T >;
};
template< typename... Bases >
struct make_bases< bases< Bases... > > {
using type = bases< Bases... >;
};
}
template< typename T >
using make_bases = typename detail::make_bases< T >::type;
template< typename... Args >
struct constructor
{};
// helper for overloaded methods, only need to provide argument types (IntelliSense bug squiggles the code, but it does compile!)
template< typename... Args >
struct meth {
template< typename Class, typename Ret >
static auto use_nonconst(Ret(Class::*fn)(Args...)) -> decltype(fn)
{
return fn;
}
template< typename Class, typename Ret >
static auto use_const(Ret(Class::*fn)(Args...) const) -> decltype(fn)
{
return fn;
}
template< typename Class, typename Ret >
static auto use_auto(Ret(Class::*fn)(Args...) const) -> decltype(fn)
{
return fn;
}
template< typename Class, typename Ret >
static auto use_auto(Ret(Class::*fn)(Args...)) -> decltype(fn)
{
return fn;
}
};
// TODO: Could specialize for certain base classes to make the interface "type safe".
template<typename T, typename BaseOrBases = no_bases, typename HolderType = null_type, typename WrapperType = null_type>
template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
struct class_;
// TODO: this function will only be invoked if the user hasn't defined a correct overload
@ -179,14 +148,79 @@ namespace luabind {
}
template <class T>
std::shared_ptr<T const>* get_const_holder(std::shared_ptr<T>*)
boost::shared_ptr<T const>* get_const_holder(boost::shared_ptr<T>*)
{
return 0;
}
template <
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
LUABIND_MAX_BASES, class A, detail::null_type)
>
struct bases
{};
typedef bases<detail::null_type> no_bases;
namespace detail
{
template <class T>
struct is_bases
: mpl::false_
{};
template <BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
struct is_bases<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)> >
: mpl::true_
{};
template <class T, class P>
struct is_unspecified
: mpl::apply1<P, T>
{};
template <class P>
struct is_unspecified<unspecified, P>
: mpl::true_
{};
template <class P>
struct is_unspecified_mfn
{
template <class T>
struct apply
: is_unspecified<T, P>
{};
};
template<class Predicate>
struct get_predicate
{
typedef mpl::protect<is_unspecified_mfn<Predicate> > type;
};
template <class Result, class Default>
struct result_or_default
{
typedef Result type;
};
template <class Default>
struct result_or_default<unspecified, Default>
{
typedef Default type;
};
template<class Parameters, class Predicate, class DefaultValue>
struct extract_parameter
{
typedef typename get_predicate<Predicate>::type pred;
typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
typedef typename result_or_default<
typename iterator::type, DefaultValue
>::type type;
};
namespace detail {
// prints the types of the values on the stack, in the
// range [start_index, lua_gettop()]
@ -255,9 +289,9 @@ namespace luabind {
class_registration* m_registration;
};
// MSVC complains about member being sensitive to alignment (C4121)
// when F is a pointer to member of a class with virtual bases.
# ifdef _MSC_VER
// MSVC complains about member being sensitive to alignment (C4121)
// when F is a pointer to member of a class with virtual bases.
# ifdef BOOST_MSVC
# pragma pack(push)
# pragma pack(16)
# endif
@ -265,148 +299,267 @@ namespace luabind {
template <class Class, class F, class Policies>
struct memfun_registration : registration
{
memfun_registration(char const* name, F f)
: name(name), f(f)
memfun_registration(char const* name, F f, Policies const& policies)
: name(name)
, f(f)
, policies(policies)
{}
void register_(lua_State* L) const
{
// Need to check if the class type of the signature is a base of this class
object fn = make_function(L, f, deduce_signature_t<F, Class>(), Policies());
add_overload(object(from_stack(L, -1)), name, fn);
object fn = make_function(
L, f, deduce_signature(f, (Class*)0), policies);
add_overload(
object(from_stack(L, -1))
, name
, fn
);
}
char const* name;
F f;
Policies policies;
};
# ifdef _MSC_VER
# ifdef BOOST_MSVC
# pragma pack(pop)
# endif
template <class P, class T>
struct default_pointer
{
using type = P;
typedef P type;
};
template <class T>
struct default_pointer<null_type, T>
{
using type = std::unique_ptr<T>;
typedef std::auto_ptr<T> type;
};
template <class Class, class Pointer, class Signature, class Policies>
struct constructor_registration : registration
{
constructor_registration()
constructor_registration(Policies const& policies)
: policies(policies)
{}
void register_(lua_State* L) const
{
using pointer = typename default_pointer<Pointer, Class>::type;
object fn = make_function(L, construct<Class, pointer, Signature>(), Signature(), Policies());
add_overload(object(from_stack(L, -1)), "__init", fn);
typedef typename default_pointer<Pointer, Class>::type pointer;
object fn = make_function(
L
, construct<Class, pointer, Signature>(), Signature()
, policies
);
add_overload(
object(from_stack(L, -1))
, "__init"
, fn
);
}
Policies policies;
};
template <class T>
struct reference_result
: std::conditional< std::is_pointer<T>::value || is_primitive<T>::value, T, typename std::add_lvalue_reference< T >::type >
{};
template <class T>
struct reference_argument
: std::conditional< std::is_pointer<T>::value || is_primitive<T>::value, T, typename std::add_lvalue_reference< typename std::add_const<T>::type >::type >
: mpl::if_<
mpl::or_<boost::is_pointer<T>, is_primitive<T> >
, T
, typename boost::add_reference<T>::type
>
{};
template <class T, class Policies>
struct inject_dependency_policy
{
using type = typename std::conditional <
is_primitive<T>::value || meta::contains<Policies, call_policy_injector< detail::no_dependency_policy > >::value,
Policies,
typename meta::push_back< Policies, call_policy_injector< dependency_policy<0, 1> > >::type
>::type;
};
: mpl::if_<
is_primitive<T>
, Policies
, policy_cons<dependency_policy<0, 1>, Policies>
>
{};
template <class Class, class Get, class GetPolicies, class Set = null_type, class SetPolicies = no_policies >
template <
class Class
, class Get, class GetPolicies
, class Set = null_type, class SetPolicies = null_type
>
struct property_registration : registration
{
property_registration(char const* name, Get const& get, Set const& set = null_type())
: name(name), get(get), set(set)
property_registration(
char const* name
, Get const& get
, GetPolicies const& get_policies
, Set const& set = Set()
, SetPolicies const& set_policies = SetPolicies()
)
: name(name)
, get(get)
, get_policies(get_policies)
, set(set)
, set_policies(set_policies)
{}
template <class F>
object make_get(lua_State* L, F const& f, std::false_type /*member_ptr*/) const
void register_(lua_State* L) const
{
return make_function(L, f, GetPolicies());
}
template <class T, class D>
object make_get(lua_State* L, D T::* mem_ptr, std::true_type /*member_ptr*/) const
{
using result_type = typename reference_result<D>::type;
using get_signature = meta::type_list<result_type, Class const&>;
using injected_list = typename inject_dependency_policy< D, GetPolicies >::type;
return make_function(L, access_member_ptr<T, D, result_type>(mem_ptr), get_signature(), injected_list());
object context(from_stack(L, -1));
register_aux(
L
, context
, make_get(L, get, boost::is_member_object_pointer<Get>())
, set
);
}
template <class F>
object make_set(lua_State* L, F const& f, std::false_type /*member_ptr*/) const
object make_get(lua_State* L, F const& f, mpl::false_) const
{
return make_function(L, f, deduce_signature_t<F>(), SetPolicies());
return make_function(
L, f, deduce_signature(f, (Class*)0), get_policies);
}
template <class T, class D>
object make_set(lua_State* L, D T::* mem_ptr, std::true_type /*member_ptr*/) const
object make_get(lua_State* L, D T::* mem_ptr, mpl::true_) const
{
using argument_type = typename reference_argument<D>::type;
using signature_type = meta::type_list<void, Class&, argument_type>;
typedef typename reference_result<D>::type result_type;
typedef typename inject_dependency_policy<
D, GetPolicies>::type policies;
return make_function(L, access_member_ptr<T, D>(mem_ptr), signature_type(), SetPolicies());
return make_function(
L
, access_member_ptr<T, D, result_type>(mem_ptr)
, mpl::vector2<result_type, Class const&>()
, policies()
);
}
// if a setter was given
template <class SetterType>
void register_aux(lua_State* L, object const& context, object const& get_, SetterType const&) const
template <class F>
object make_set(lua_State* L, F const& f, mpl::false_) const
{
context[name] = property(get_, make_set(L, set, std::is_member_object_pointer<Set>()));
return make_function(
L, f, deduce_signature(f, (Class*)0), set_policies);
}
// if no setter was given
void register_aux(lua_State*, object const& context, object const& get_, null_type) const
template <class T, class D>
object make_set(lua_State* L, D T::* mem_ptr, mpl::true_) const
{
return make_function(
L
, access_member_ptr<T, D>(mem_ptr)
, mpl::vector3<void, Class&, D const&>()
, set_policies
);
}
template <class S>
void register_aux(
lua_State* L, object const& context
, object const& get_, S const&) const
{
context[name] = property(
get_
, make_set(L, set, boost::is_member_object_pointer<Set>())
);
}
void register_aux(
lua_State*, object const& context
, object const& get_, null_type) const
{
context[name] = property(get_);
}
// register entry
void register_(lua_State* L) const
{
object context(from_stack(L, -1));
register_aux(L, context, make_get(L, get, std::is_member_object_pointer<Get>()), set);
}
char const* name;
Get get;
GetPolicies get_policies;
Set set;
SetPolicies set_policies;
};
} // namespace detail
// registers a class in the lua environment
template<class T, typename BaseOrBases, typename HolderType, typename WrapperType >
struct class_
: detail::class_base
template<class T, class X1, class X2, class X3>
struct class_: detail::class_base
{
using self_t = class_<T, BaseOrBases, HolderType, WrapperType>;
using BaseList = make_bases< BaseOrBases >;
typedef class_<T, X1, X2, X3> self_t;
private:
template<class A, class B, class C, class D>
class_(const class_<A,B,C,D>&);
public:
class_(const char* name) : class_base(name), scope(*this)
typedef boost::mpl::vector4<X1, X2, X3, detail::unspecified> parameters_type;
// WrappedType MUST inherit from T
typedef typename detail::extract_parameter<
parameters_type
, boost::is_base_and_derived<T, boost::mpl::_>
, detail::null_type
>::type WrappedType;
typedef typename detail::extract_parameter<
parameters_type
, boost::mpl::not_<
boost::mpl::or_<
detail::is_bases<boost::mpl::_>
, boost::is_base_and_derived<boost::mpl::_, T>
, boost::is_base_and_derived<T, boost::mpl::_>
>
>
, detail::null_type
>::type HeldType;
template <class Src, class Target>
void add_downcast(Src*, Target*, boost::mpl::true_)
{
add_cast(
detail::registered_class<Src>::id
, detail::registered_class<Target>::id
, detail::dynamic_cast_<Src, Target>::execute
);
}
template <class Src, class Target>
void add_downcast(Src*, Target*, boost::mpl::false_)
{}
// this function generates conversion information
// in the given class_rep structure. It will be able
// to implicitly cast to the given template type
template<class To>
void gen_base_info(detail::type_<To>)
{
add_base(typeid(To), detail::static_cast_<T, To>::execute);
add_cast(
detail::registered_class<T>::id
, detail::registered_class<To>::id
, detail::static_cast_<T, To>::execute
);
add_downcast((To*)0, (T*)0, boost::is_polymorphic<To>());
}
void gen_base_info(detail::type_<detail::null_type>)
{}
#define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_<BaseClass##n>());
template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class BaseClass)>
void generate_baseclass_list(detail::type_<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, BaseClass)> >)
{
BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
}
#undef LUABIND_GEN_BASE_INFO
class_(const char* name): class_base(name), scope(*this)
{
#ifndef NDEBUG
detail::check_link_compatibility();
@ -414,78 +567,174 @@ namespace luabind {
init();
}
template<class F>
class_& def(const char* name, F f)
{
return this->virtual_def(
name, f, detail::null_type()
, detail::null_type(), boost::mpl::true_());
}
// virtual functions
template<class F, typename... Injectors>
class_& def(char const* name, F fn, policy_list< Injectors... > policies = no_policies())
template<class F, class DefaultOrPolicies>
class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies)
{
return this->virtual_def(name, fn, policies, null_type());
return this->virtual_def(
name, fn, default_or_policies, detail::null_type()
, LUABIND_MSVC_TYPENAME detail::is_policy_cons<DefaultOrPolicies>::type());
}
// IntelliSense bug squiggles the code, but it does compile!
template<typename Ret, typename C, typename... Args, typename... Injectors>
class_& def_nonconst(char const* name, Ret(C::*fn)(Args...), policy_list<Injectors...> policies = no_policies())
template<class F, class Default, class Policies>
class_& def(char const* name, F fn
, Default default_, Policies const& policies)
{
return def(name, fn, policies);
return this->virtual_def(
name, fn, default_
, policies, boost::mpl::false_());
}
// IntelliSense bug squiggles the code, but it does compile!
template<typename Ret, typename C, typename... Args, typename... Injectors>
class_& def_const(char const* name, Ret(C::*fn)(Args...) const, policy_list<Injectors...> policies = no_policies())
template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
{
return def(name, fn, policies);
return this->def_constructor(&sig, detail::null_type());
}
template<class F, class Default, typename... Injectors>
class_& def(char const* name, F fn, Default default_, policy_list< Injectors... > policies = no_policies())
template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
{
return this->virtual_def(name, fn, policies, default_);
return this->def_constructor(&sig, policies);
}
template<typename... Args, typename... Injectors>
class_& def(constructor<Args...> sig, policy_list< Injectors... > policies = no_policies())
template <class Getter>
class_& property(const char* name, Getter g)
{
return this->def_constructor(sig, policies);
}
// ======================
// Start of reworked property overloads
// ======================
template <class Getter, typename... Injectors>
class_& property(const char* name, Getter g, policy_list< Injectors... > get_injectors = no_policies())
{
return property(name, g, null_type(), get_injectors);
}
template <class Getter, class Setter, typename... GetInjectors, typename... SetInjectors>
class_& property(const char* name, Getter g, Setter s, policy_list<GetInjectors...> = no_policies(), policy_list<SetInjectors...> = no_policies())
{
using registration_type = detail::property_registration<T, Getter, policy_list<GetInjectors...>, Setter, policy_list<SetInjectors...>>;
this->add_member(new registration_type(name, g, s));
this->add_member(
new detail::property_registration<T, Getter, detail::null_type>(
name, g, detail::null_type()));
return *this;
}
template <class C, class D, typename... Injectors>
class_& def_readonly(const char* name, D C::*mem_ptr, policy_list<Injectors...> policies = no_policies())
template <class Getter, class MaybeSetter>
class_& property(const char* name, Getter g, MaybeSetter s)
{
return property(name, mem_ptr, policies);
return property_impl(
name, g, s
, boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>()
);
}
template <class C, class D, typename... GetInjectors, typename... SetInjectors>
class_& def_readwrite(const char* name, D C::*mem_ptr, policy_list<GetInjectors...> get_injectors = no_policies(), policy_list<SetInjectors...> set_injectors = no_policies())
template<class Getter, class Setter, class GetPolicies>
class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
{
return property(name, mem_ptr, mem_ptr, get_injectors, set_injectors);
typedef detail::property_registration<
T, Getter, GetPolicies, Setter, detail::null_type
> registration_type;
this->add_member(
new registration_type(name, g, get_policies, s));
return *this;
}
// =====================
// End of reworked property overloads
// =====================
template<class Derived, typename... Injectors>
class_& def(detail::operator_<Derived>, policy_list<Injectors...> policies = no_policies())
template<class Getter, class Setter, class GetPolicies, class SetPolicies>
class_& property(
const char* name
, Getter g, Setter s
, GetPolicies const& get_policies
, SetPolicies const& set_policies)
{
using policy_list_type = policy_list<Injectors...>;
return this->def(Derived::name(), &Derived::template apply<T, policy_list_type>::execute, policies);
typedef detail::property_registration<
T, Getter, GetPolicies, Setter, SetPolicies
> registration_type;
this->add_member(
new registration_type(name, g, get_policies, s, set_policies));
return *this;
}
template <class C, class D>
class_& def_readonly(const char* name, D C::*mem_ptr)
{
typedef detail::property_registration<T, D C::*, detail::null_type>
registration_type;
this->add_member(
new registration_type(name, mem_ptr, detail::null_type()));
return *this;
}
template <class C, class D, class Policies>
class_& def_readonly(const char* name, D C::*mem_ptr, Policies const& policies)
{
typedef detail::property_registration<T, D C::*, Policies>
registration_type;
this->add_member(
new registration_type(name, mem_ptr, policies));
return *this;
}
template <class C, class D>
class_& def_readwrite(const char* name, D C::*mem_ptr)
{
typedef detail::property_registration<
T, D C::*, detail::null_type, D C::*
> registration_type;
this->add_member(
new registration_type(
name, mem_ptr, detail::null_type(), mem_ptr));
return *this;
}
template <class C, class D, class GetPolicies>
class_& def_readwrite(
const char* name, D C::*mem_ptr, GetPolicies const& get_policies)
{
typedef detail::property_registration<
T, D C::*, GetPolicies, D C::*
> registration_type;
this->add_member(
new registration_type(
name, mem_ptr, get_policies, mem_ptr));
return *this;
}
template <class C, class D, class GetPolicies, class SetPolicies>
class_& def_readwrite(
const char* name
, D C::*mem_ptr
, GetPolicies const& get_policies
, SetPolicies const& set_policies
)
{
typedef detail::property_registration<
T, D C::*, GetPolicies, D C::*, SetPolicies
> registration_type;
this->add_member(
new registration_type(
name, mem_ptr, get_policies, mem_ptr, set_policies));
return *this;
}
template<class Derived, class Policies>
class_& def(detail::operator_<Derived>, Policies const& policies)
{
return this->def(
Derived::name()
, &Derived::template apply<T, Policies>::execute
, policies
);
}
template<class Derived>
class_& def(detail::operator_<Derived>)
{
return this->def(
Derived::name()
, &Derived::template apply<T, detail::null_type>::execute
);
}
detail::enum_maker<self_t> enum_(const char*)
@ -496,93 +745,125 @@ namespace luabind {
detail::static_scope<self_t> scope;
private:
void init()
{
class_base::init(typeid(T), detail::registered_class<T>::id, typeid(WrapperType), detail::registered_class<WrapperType>::id);
add_wrapper_cast((WrapperType*)0);
generate_baseclass_list();
}
template<class S, typename OtherBaseOrBases, typename OtherWrapper >
class_(const class_<S, OtherBaseOrBases, OtherWrapper>&);
template <class Src, class Target>
void add_downcast(Src*, Target*, std::true_type)
{
add_cast(detail::registered_class<Src>::id, detail::registered_class<Target>::id, detail::dynamic_cast_<Src, Target>::execute);
}
template <class Src, class Target>
void add_downcast(Src*, Target*, std::false_type)
{}
// this function generates conversion information
// in the given class_rep structure. It will be able
// to implicitly cast to the given template type
template<typename Class0, typename... Classes>
void gen_base_info(bases<Class0, Classes...>)
{
add_base(typeid(Class0), detail::static_cast_<T, Class0>::execute);
add_cast(detail::registered_class<T>::id, detail::registered_class<Class0>::id, detail::static_cast_<T, Class0>::execute);
add_downcast((Class0*)0, (T*)0, std::is_polymorphic<Class0>());
gen_base_info(bases<Classes...>());
}
void gen_base_info(bases<>)
{
}
void generate_baseclass_list()
{
gen_base_info(BaseList());
}
void operator=(class_ const&);
void add_wrapper_cast(null_type*)
void add_wrapper_cast(detail::null_type*)
{}
template <class U>
void add_wrapper_cast(U*)
{
add_cast(detail::registered_class<U>::id, detail::registered_class<T>::id, detail::static_cast_<U, T>::execute);
add_downcast((T*)0, (U*)0, std::is_polymorphic<T>());
add_cast(
detail::registered_class<U>::id
, detail::registered_class<T>::id
, detail::static_cast_<U,T>::execute
);
add_downcast((T*)0, (U*)0, boost::is_polymorphic<T>());
}
void init()
{
typedef typename detail::extract_parameter<
parameters_type
, boost::mpl::or_<
detail::is_bases<boost::mpl::_>
, boost::is_base_and_derived<boost::mpl::_, T>
>
, no_bases
>::type bases_t;
typedef typename
boost::mpl::if_<detail::is_bases<bases_t>
, bases_t
, bases<bases_t>
>::type Base;
class_base::init(
typeid(T)
, detail::registered_class<T>::id
, typeid(WrappedType)
, detail::registered_class<WrappedType>::id
);
add_wrapper_cast((WrappedType*)0);
generate_baseclass_list(detail::type_<Base>());
}
template<class Getter, class GetPolicies>
class_& property_impl(const char* name,
Getter g,
GetPolicies policies,
boost::mpl::bool_<true>)
{
this->add_member(
new detail::property_registration<T, Getter, GetPolicies>(
name, g, policies));
return *this;
}
template<class Getter, class Setter>
class_& property_impl(const char* name,
Getter g,
Setter s,
boost::mpl::bool_<false>)
{
typedef detail::property_registration<
T, Getter, detail::null_type, Setter, detail::null_type
> registration_type;
this->add_member(
new registration_type(name, g, detail::null_type(), s));
return *this;
}
// these handle default implementation of virtual functions
template<class F, class Default, typename... Injectors>
class_& virtual_def(char const* name, F const& fn, policy_list< Injectors... >, Default default_)
template<class F, class Policies>
class_& virtual_def(char const* name, F const& fn
, Policies const&, detail::null_type, boost::mpl::true_)
{
using policy_list_type = policy_list< Injectors... >;
this->add_member(new detail::memfun_registration<T, F, policy_list_type >(name, fn));
this->add_default_member(new detail::memfun_registration<T, Default, policy_list_type>(name, default_));
this->add_member(
new detail::memfun_registration<T, F, Policies>(
name, fn, Policies()));
return *this;
}
template<class F, typename... Injectors>
class_& virtual_def(char const* name, F const& fn, policy_list< Injectors... >, null_type)
template<class F, class Default, class Policies>
class_& virtual_def(char const* name, F const& fn
, Default const& default_, Policies const&, boost::mpl::false_)
{
using policy_list_type = policy_list< Injectors... >;
this->add_member(new detail::memfun_registration<T, F, policy_list_type>(name, fn));
this->add_member(
new detail::memfun_registration<T, F, Policies>(
name, fn, Policies()));
this->add_default_member(
new detail::memfun_registration<T, Default, Policies>(
name, default_, Policies()));
return *this;
}
template<typename... SignatureElements, typename... Injectors>
class_& def_constructor(constructor<SignatureElements...> const&, policy_list< Injectors... > const&)
template<class Signature, class Policies>
class_& def_constructor(Signature*, Policies const&)
{
using signature_type = meta::type_list<void, argument const&, SignatureElements...>;
using policy_list_type = policy_list< Injectors... >;
typedef typename Signature::signature signature;
using construct_type = typename std::conditional<
is_null_type<WrapperType>::value,
T,
WrapperType
>::type;
typedef typename boost::mpl::if_<
boost::is_same<WrappedType, detail::null_type>
, T
, WrappedType
>::type construct_type;
using registration_type = detail::constructor_registration<construct_type, HolderType, signature_type, policy_list_type>;
this->add_member(new registration_type());
this->add_default_member(new registration_type());
this->add_member(
new detail::constructor_registration<
construct_type, HeldType, signature, Policies>(
Policies()));
this->add_default_member(
new detail::constructor_registration<
construct_type, HeldType, signature, Policies>(
Policies()));
return *this;
}

View File

@ -20,6 +20,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_CLASS_INFO_HPP_INCLUDED
#define LUABIND_CLASS_INFO_HPP_INCLUDED

View File

@ -20,26 +20,57 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef 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
// registered. Must at least be 2
#ifndef LUABIND_MAX_ARITY
#define LUABIND_MAX_ARITY 100
#define LUABIND_MAX_ARITY 10
#elif LUABIND_MAX_ARITY <= 1
#undef LUABIND_MAX_ARITY
#define LUABIND_MAX_ARITY 2
#undef LUABIND_MAX_ARITY
#define LUABIND_MAX_ARITY 2
#endif
// the maximum number of classes one class
// can derive from
// max bases must at least be 1
#ifndef LUABIND_MAX_BASES
#define LUABIND_MAX_BASES 100
#define LUABIND_MAX_BASES 4
#elif LUABIND_MAX_BASES <= 0
#undef LUABIND_MAX_BASES
#define LUABIND_MAX_BASES 1
#undef LUABIND_MAX_BASES
#define LUABIND_MAX_BASES 1
#endif
// LUABIND_NO_ERROR_CHECKING
@ -70,18 +101,12 @@
// C code has undefined behavior, lua is written in C).
#ifdef LUABIND_DYNAMIC_LINK
# if defined (_WIN32)
# ifdef BOOST_WINDOWS
# ifdef LUABIND_BUILDING
# define LUABIND_API __declspec(dllexport)
# else
# define LUABIND_API __declspec(dllimport)
# endif
# elif defined (__CYGWIN__)
# ifdef LUABIND_BUILDING
# define LUABIND_API __attribute__ ((dllexport))
# else
# define LUABIND_API __attribute__ ((dllimport))
# endif
# else
# if defined(_GNUC_) && _GNUC_ >=4
# define LUABIND_API __attribute__ ((visibility("default")))
@ -93,19 +118,9 @@
# define LUABIND_API
#endif
// This switches between using tag arguments / structure specialization for code size tests
#define LUABIND_NO_INTERNAL_TAG_ARGUMENTS
namespace luabind {
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);
LUABIND_API void disable_super_deprecation();
} // namespace luabind

View File

@ -20,34 +20,40 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_CONTAINER_POLICY_HPP_INCLUDED
#define LUABIND_CONTAINER_POLICY_HPP_INCLUDED
#include <luabind/config.hpp>
#include <luabind/detail/policy.hpp>
#include <luabind/detail/decorate_type.hpp> // for decorated_type
#include <luabind/detail/primitives.hpp> // for null_type (ptr only), etc
#include <boost/mpl/apply_wrap.hpp>
namespace luabind {
namespace detail {
namespace luabind { namespace detail {
namespace mpl = boost::mpl;
template<class Policies>
struct container_converter_lua_to_cpp
{
enum { consumed_args = 1 };
int const consumed_args(...)
{
return 1;
}
template<class T>
T to_cpp(lua_State* L, by_const_reference<T>, int index)
T apply(lua_State* L, by_const_reference<T>, int index)
{
using value_type = typename T::value_type;
specialized_converter_policy_n<1, Policies, value_type, lua_to_cpp> converter;
typedef typename T::value_type value_type;
typedef typename find_conversion_policy<1, Policies>::type converter_policy;
typename mpl::apply_wrap2<converter_policy,value_type,lua_to_cpp>::type converter;
T container;
lua_pushnil(L);
while(lua_next(L, index - 1))
while (lua_next(L, index))
{
container.push_back(converter.apply(L, decorated_type<value_type>(), -1));
container.push_back(converter.apply(L, LUABIND_DECORATE_TYPE(value_type), -1));
lua_pop(L, 1); // pop value
}
@ -55,21 +61,15 @@ namespace luabind {
}
template<class T>
T to_cpp(lua_State* L, by_value<T>, int index)
T apply(lua_State* L, by_value<T>, int index)
{
return to_cpp(L, by_const_reference<T>(), index);
return apply(L, by_const_reference<T>(), index);
}
template<class T>
static int match(lua_State* L, by_const_reference<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);
if (lua_istable(L, index)) return 0; else return -1;
}
template<class T>
@ -80,51 +80,64 @@ namespace luabind {
struct container_converter_cpp_to_lua
{
template<class T>
void to_lua(lua_State* L, const T& container)
void apply(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;
typedef typename T::value_type value_type;
typedef typename find_conversion_policy<1, Policies>::type converter_policy;
typename mpl::apply_wrap2<converter_policy,value_type,lua_to_cpp>::type converter;
lua_newtable(L);
int index = 1;
for(const auto& element : container)
for (typename T::const_iterator i = container.begin(); i != container.end(); ++i)
{
converter.apply(L, element);
converter.apply(L, *i);
lua_rawseti(L, -2, index);
++index;
}
}
};
template<class Policies = no_policies>
struct container_policy
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 specialize;
template<class T>
struct specialize<T, lua_to_cpp> {
using type = container_converter_lua_to_cpp<Policies>;
};
template<class T>
struct specialize<T, cpp_to_lua> {
using type = container_converter_cpp_to_lua<Policies>;
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
{
template<unsigned int N, typename ElementPolicies = no_policies >
using container_policy = meta::type_list<converter_policy_injector<N, detail::container_policy<ElementPolicies>>>;
template<int N>
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

View File

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

View File

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

View File

@ -20,46 +20,42 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_CALL_SHARED_HPP_INCLUDED
#define LUABIND_CALL_SHARED_HPP_INCLUDED
#if !BOOST_PP_IS_ITERATING
namespace luabind {
namespace detail {
# include <luabind/detail/signature_match.hpp>
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()>
{
#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
}
template<typename T>
void cast_error(lua_State* L)
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
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
BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_FIND_CONV, _)
return 0 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_CALC_ARITY, _);
}
template< typename... Args >
void expand_hack(Args... /*args*/)
{}
}
}
};
#endif

View File

@ -1,29 +1,35 @@
// 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
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef LUABIND_CALL2_080911_HPP
#define LUABIND_CALL2_080911_HPP
#if !BOOST_PP_IS_ITERATING
#include <luabind/config.hpp>
#include <typeinfo>
#include <luabind/detail/meta.hpp>
#include <luabind/detail/policy.hpp>
#include <luabind/yield_policy.hpp>
#include <luabind/detail/decorate_type.hpp>
#include <luabind/detail/object.hpp>
# ifndef LUABIND_CALL2_080911_HPP
# define LUABIND_CALL2_080911_HPP
#ifdef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
#include <tuple>
#endif
# include <boost/mpl/apply_wrap.hpp>
# include <boost/mpl/begin_end.hpp>
# include <boost/mpl/deref.hpp>
# include <boost/mpl/front.hpp>
# include <boost/mpl/long.hpp>
# include <boost/mpl/size.hpp>
# include <boost/preprocessor/control/if.hpp>
# include <boost/preprocessor/iteration/iterate.hpp>
# include <boost/preprocessor/iteration/local.hpp>
# include <boost/preprocessor/repetition/enum.hpp>
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
# include <boost/type_traits/is_void.hpp>
namespace luabind {
namespace detail {
# include <luabind/config.hpp>
# include <luabind/detail/policy.hpp>
# include <luabind/yield_policy.hpp>
struct invoke_context;
namespace luabind { namespace detail {
struct LUABIND_API function_object
{
struct invoke_context;
struct LUABIND_API function_object
{
function_object(lua_CFunction entry)
: entry(entry)
, next(0)
@ -32,22 +38,20 @@ namespace luabind {
virtual ~function_object()
{}
virtual int call(lua_State* L, invoke_context& ctx) /* const */ = 0;
virtual int call(
lua_State* L, invoke_context& ctx) const = 0;
virtual void format_signature(lua_State* L, char const* function) const = 0;
lua_CFunction entry;
std::string name;
function_object* next;
object keepalive;
};
};
struct LUABIND_API invoke_context
{
struct LUABIND_API invoke_context
{
invoke_context()
: best_score((std::numeric_limits<int>::max)())
//This need to avoid static analyzer's treats
, candidates{ nullptr,nullptr,nullptr,nullptr,nullptr,
nullptr,nullptr,nullptr,nullptr,nullptr }
, candidate_index(0)
{}
@ -59,489 +63,261 @@ namespace luabind {
void format_error(lua_State* L, function_object const* overloads) const;
int best_score;
function_object const* candidates[10]; // This looks like it could crash if you provide too many overloads?
function_object const* candidates[10];
int candidate_index;
};
};
namespace call_detail_new {
/*
Compute Stack Indices
Given the list of argument converter arities, computes the stack indices that each converter addresses.
*/
template< typename ConsumedList, unsigned int CurrentSum, unsigned int... StackIndices >
struct compute_stack_indices;
template< unsigned int Consumed0, unsigned int... Consumeds, unsigned int CurrentSum, unsigned int... StackIndices >
struct compute_stack_indices< meta::index_list< Consumed0, Consumeds... >, CurrentSum, StackIndices... >
{
using type = typename compute_stack_indices< meta::index_list< Consumeds... >, CurrentSum + Consumed0, StackIndices..., CurrentSum >::type;
};
template< unsigned int CurrentSum, unsigned int... StackIndices >
struct compute_stack_indices< meta::index_list< >, CurrentSum, StackIndices... >
{
using type = meta::index_list< StackIndices... >;
};
template< typename Foo >
struct FooFoo { // Foo!
enum { consumed_args = Foo::consumed_args };
};
template< typename PolicyList, typename StackIndexList >
struct policy_list_postcall;
template< typename Policy0, typename... Policies, typename StackIndexList >
struct policy_list_postcall< meta::type_list< call_policy_injector<Policy0>, Policies... >, StackIndexList > {
static void postcall(lua_State* L, int results) {
Policy0::postcall(L, results, StackIndexList());
policy_list_postcall< meta::type_list< Policies... >, StackIndexList >::postcall(L, results);
}
};
template< typename ConverterPolicy, typename StackIndexList, bool has_postcall >
struct converter_policy_postcall {
static void postcall(lua_State* L, int results) {
ConverterPolicy::postcall(L, results, StackIndexList());
}
};
template< typename ConverterPolicy, typename StackIndexList >
struct converter_policy_postcall< ConverterPolicy, StackIndexList, false > {
static void postcall(lua_State* /*L*/, int /*results*/) {
}
};
template< unsigned int Index, typename Policy, typename... Policies, typename StackIndexList >
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);
policy_list_postcall< meta::type_list< Policies... >, StackIndexList >::postcall(L, results);
}
};
template< typename StackIndexList >
struct policy_list_postcall< meta::type_list< >, StackIndexList > {
static void postcall(lua_State* /*L*/, int /*results*/) {}
};
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
template< typename... ArgumentConverters >
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;
enum { arity = meta::sum<consumed_list>::value };
};
#endif
}
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
inline int match_deferred(lua_State* L, meta::index_list<>, meta::type_list<>)
{
return 0;
}
template< unsigned int StackIndex0, unsigned int... StackIndices,
typename ArgumentType0, typename... ArgumentTypes,
typename ArgumentConverter0, typename... ArgumentConverters >
int match_deferred(lua_State* L,
meta::index_list< StackIndex0, StackIndices... >,
meta::type_list< ArgumentType0, ArgumentTypes... >,
ArgumentConverter0& converter0, ArgumentConverters&... converters
)
{
const int this_match = converter0.match(L, decorated_type<ArgumentType0>(), StackIndex0);
const int other_match = match_deferred(L, meta::index_list<StackIndices...>(), meta::type_list<ArgumentTypes...>(), converters...);
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...)
: no_match;
}
template< typename T, bool isvoid, bool memfun = std::is_member_function_pointer<T>::value > struct do_call_struct;
template< typename T >
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 >
static void do_call(lua_State* L, F& f,
meta::index_list<StackIndex0, StackIndices...>, meta::type_list<ArgumentType0, ArgumentTypes...>,
ReturnConverter& result_converter, Argument0Converter& arg0_converter, ArgumentConverters&... arg_converters
)
{
((arg0_converter.to_cpp(L, decorated_type<ArgumentType0>(), StackIndex0)).*f)(
arg_converters.to_cpp(L, decorated_type<ArgumentTypes>(), StackIndices)...
template <class F, class Signature, class Policies, class IsVoid>
inline int invoke0(
lua_State* L, function_object const& self, invoke_context& ctx
, F const& f, Signature, Policies const& policies, IsVoid, mpl::true_)
{
return invoke_member(
L, self, ctx, f, Signature(), policies
, mpl::long_<mpl::size<Signature>::value - 1>(), IsVoid()
);
}
};
}
template< typename T >
struct do_call_struct< T, false, true /*memfun*/> {
template< typename F, typename ArgumentType0, typename... ArgumentTypes, unsigned int StackIndex0, unsigned int... StackIndices, typename ReturnConverter, typename Argument0Converter, typename... ArgumentConverters >
static void do_call(lua_State* L, F& f,
meta::index_list<StackIndex0, StackIndices...>, meta::type_list<ArgumentType0, ArgumentTypes...>,
ReturnConverter& result_converter, Argument0Converter& arg0_converter, ArgumentConverters&... arg_converters
)
{
result_converter.to_lua(L,
((arg0_converter.to_cpp(L, decorated_type<ArgumentType0>(), StackIndex0)).*f)(
arg_converters.to_cpp(L, decorated_type<ArgumentTypes>(), StackIndices)...
)
template <class F, class Signature, class Policies, class IsVoid>
inline int invoke0(
lua_State* L, function_object const& self, invoke_context& ctx,
F const& f, Signature, Policies const& policies, IsVoid, mpl::false_)
{
return invoke_normal(
L, self, ctx, f, Signature(), policies
, mpl::long_<mpl::size<Signature>::value - 1>(), IsVoid()
);
}
};
}
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 <class F, class Signature, class Policies>
inline int invoke(
lua_State* L, function_object const& self, invoke_context& ctx
, F const& f, Signature, Policies const& policies)
{
return invoke0(
L, self, ctx, f, Signature(), policies
, boost::is_void<typename mpl::front<Signature>::type>()
, boost::is_member_function_pointer<F>()
);
}
};
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);
}
}
inline int maybe_yield_aux(lua_State*, int results, mpl::false_)
{
return results;
}
inline int maybe_yield_aux(lua_State* L, int results, mpl::true_)
{
return lua_yield(L, results);
}
template <class Policies>
int maybe_yield(lua_State* L, int results, Policies*)
{
return maybe_yield_aux(
L, results, mpl::bool_<has_yield<Policies>::value>());
}
inline int sum_scores(int const* first, int const* last)
{
int result = 0;
for (; first != last; ++first)
{
if (*first < 0)
return *first;
result += *first;
}
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>()...
);
}
return result;
}
# define LUABIND_INVOKE_NEXT_ITER(n) \
typename mpl::next< \
BOOST_PP_IF( \
n, BOOST_PP_CAT(iter,BOOST_PP_DEC(n)), first) \
>::type
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))...
# define LUABIND_INVOKE_NEXT_INDEX(n) \
BOOST_PP_IF( \
n \
, BOOST_PP_CAT(index,BOOST_PP_DEC(n)) + \
BOOST_PP_CAT(c,BOOST_PP_DEC(n)).consumed_args() \
, 1 \
)
);
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)...
};
}
};
# define LUABIND_INVOKE_COMPUTE_ARITY(n) + BOOST_PP_CAT(c,n).consumed_args()
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;
# define LUABIND_INVOKE_DECLARE_CONVERTER(n) \
typedef LUABIND_INVOKE_NEXT_ITER(n) BOOST_PP_CAT(iter,n); \
typedef typename mpl::deref<BOOST_PP_CAT(iter,n)>::type \
BOOST_PP_CAT(a,n); \
typedef typename find_conversion_policy<n + 1, Policies>::type \
BOOST_PP_CAT(p,n); \
typename mpl::apply_wrap2< \
BOOST_PP_CAT(p,n), BOOST_PP_CAT(a,n), lua_to_cpp>::type BOOST_PP_CAT(c,n); \
int const BOOST_PP_CAT(index,n) = LUABIND_INVOKE_NEXT_INDEX(n);
// This prevents unused warnings with empty parameter lists
(void)L;
# define LUABIND_INVOKE_COMPUTE_SCORE(n) \
, BOOST_PP_CAT(c,n).match( \
L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,n)), BOOST_PP_CAT(index,n))
f(std::get<ArgumentIndices>(argument_tuple).to_cpp(L,
typename meta::get<decorated_list, ArgumentIndices>::type(),
meta::get<stack_indices, ArgumentIndices>::value)...
# define LUABIND_INVOKE_ARG(z, n, base) \
BOOST_PP_CAT(c,base(n)).apply( \
L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,base(n))), BOOST_PP_CAT(index,base(n)))
);
# define LUABIND_INVOKE_CONVERTER_POSTCALL(n) \
BOOST_PP_CAT(c,n).converter_postcall( \
L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,n)), BOOST_PP_CAT(index,n));
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)...
};
}
};
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
# include BOOST_PP_ITERATE()
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;
# define LUABIND_INVOKE_VOID
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
# include BOOST_PP_ITERATE()
auto& object = std::get<0>(argument_tuple).to_cpp(L,
typename meta::get<typename traits::decorated_argument_list, 0>::type(), 1);
# undef LUABIND_INVOKE_VOID
# define LUABIND_INVOKE_MEMBER
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
# include BOOST_PP_ITERATE()
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)...
)
);
# define LUABIND_INVOKE_VOID
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
# include BOOST_PP_ITERATE()
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
}} // namespace luabind::detail
# 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
// OR OTHER DEALINGS IN THE SOFTWARE.
#if !BOOST_PP_IS_ITERATING
#ifndef LUABIND_CALL_FUNCTION_HPP_INCLUDED
#define LUABIND_CALL_FUNCTION_HPP_INCLUDED
#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/detail/push_to_lua.hpp>
#include <luabind/detail/convert_to_lua.hpp>
#include <luabind/detail/pcall.hpp>
#include <luabind/detail/call_shared.hpp>
#include <luabind/detail/stack_utils.hpp>
namespace luabind
{
namespace adl {
class object;
namespace detail
{
// if the proxy_function_caller returns non-void
template<class Ret, class Tuple>
class proxy_function_caller
{
// friend class luabind::object;
public:
typedef int(*function_t)(lua_State*, int, int);
proxy_function_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)
{
}
using adl::object;
namespace detail {
template< typename PolicyList, unsigned int pos >
void push_arguments(lua_State* /*L*/) {}
template< typename PolicyList, unsigned int Pos, typename Arg0, typename... Args >
void push_arguments(lua_State* L, Arg0&& arg0, Args&&... args)
proxy_function_caller(const proxy_function_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)
{
using converter_type = specialized_converter_policy< fetched_converter_policy<Pos, PolicyList>, Arg0, cpp_to_lua >;
converter_type().to_lua(L, unwrapped<Arg0>::get(std::forward<Arg0>(arg0)));
push_arguments<PolicyList, Pos + 1>(L, std::forward<Args>(args)...);
rhs.m_called = true;
}
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
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)
~proxy_function_caller()
{
if (m_called) return;
m_called = true;
lua_State* L = m_state;
int top = lua_gettop(L);
push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...);
if(fn(L, sizeof...(Args), 0)) {
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);
call_error(L);
#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
}
// pops the return values from the function call
stack_pop pop(L, lua_gettop(L) - top + m_params);
}
operator Ret()
{
typename mpl::apply_wrap2<default_policy,Ret,lua_to_cpp>::type converter;
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, 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
}
// pops the return values from the function call
stack_pop pop(L, lua_gettop(L) - top + m_params);
#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);
}
template<class Policies>
Ret operator[](const Policies& p)
{
typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy;
typename mpl::apply_wrap2<converter_policy,Ret,lua_to_cpp>::type converter;
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, 1))
{
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);
#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);
}
private:
lua_State* m_state;
int m_params;
function_t m_fun;
Tuple m_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
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);
}
template<typename Ret, typename PolicyList, typename... Args, unsigned int... Indices, typename Fn>
Ret call_function_impl(lua_State* L, int m_params, Fn fn, std::false_type /* void */, meta::index_list<Indices...>, Args&&... args)
template<class Policies>
void operator[](const Policies& p)
{
m_called = true;
lua_State* L = m_state;
int top = lua_gettop(L);
push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...);
if(fn(L, sizeof...(Args), 1)) {
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);
call_error(L);
#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);
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
template<typename Ret, typename PolicyList, typename IndexList, unsigned int NumParams, int(*Function)(lua_State*, int, int), bool IsVoid = std::is_void<Ret>::value>
struct call_function_struct;
private:
template<typename Ret, typename PolicyList, unsigned int NumParams, int(*Function)(lua_State*, int, int), unsigned int... Indices >
struct call_function_struct< Ret, PolicyList, meta::index_list<Indices...>, NumParams, Function, true /* void */ >
{
template< typename... Args >
static void call(lua_State* L, Args&&... args) {
int top = lua_gettop(L);
lua_State* m_state;
int m_params;
function_t m_fun;
Tuple m_args;
mutable bool m_called;
push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...);
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 + NumParams);
}
};
template<typename Ret, typename PolicyList, unsigned int NumParams, int(*Function)(lua_State*, int, int), unsigned int... Indices >
struct call_function_struct< Ret, PolicyList, meta::index_list<Indices...>, NumParams, Function, false /* void */ >
{
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)...);
if(Function(L, sizeof...(Args), 1)) {
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 + NumParams);
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);
}
};
#endif
}
template<class R, typename PolicyList = no_policies, typename... Args>
R call_pushed_function(lua_State* L, Args&&... args)
{
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
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)...);
#else
return detail::call_function_struct<R, PolicyList, meta::index_range<1, sizeof...(Args)+1>, 1, &detail::pcall >::call(L, std::forward<Args>(args)...);
#endif
}
template<class R, typename PolicyList = no_policies, typename... Args>
R call_function(lua_State* L, const char* name, Args&&... args)
{
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>
R resume_pushed_function(lua_State* L, Args&&... args)
{
#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)...);
#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)...);
#endif
}
template<class R, typename PolicyList = no_policies, typename... Args>
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>
R resume(lua_State* L, Args&&... args)
{
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
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)...);
#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)...);
#endif
}
#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
#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,26 +20,62 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#if !BOOST_PP_IS_ITERATING
#ifndef LUABIND_CALL_MEMBER_HPP_INCLUDED
#define LUABIND_CALL_MEMBER_HPP_INCLUDED
#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/error.hpp>
#include <luabind/detail/stack_utils.hpp>
#include <luabind/detail/call_shared.hpp>
#include <luabind/object.hpp>
#include <luabind/object.hpp> // TODO: REMOVE DEPENDENCY
#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
{
using adl::object;
namespace detail {
template<class R, typename PolicyList, unsigned int... Indices, typename... Args>
R call_member_impl(lua_State* L, std::true_type /*void*/, meta::index_list<Indices...>, Args&&... args)
namespace detail
{
namespace mpl = boost::mpl;
// if the proxy_member_caller returns non-void
template<class Ret, class Tuple>
class proxy_member_caller
{
// friend class luabind::object;
public:
proxy_member_caller(lua_State* L_, const Tuple args)
: 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;
@ -47,22 +83,84 @@ namespace luabind
// pcall will pop the function and self reference
// and all the parameters
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))
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);
call_error(L);
#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 R, typename PolicyList, unsigned int... Indices, typename... Args>
R call_member_impl(lua_State* L, std::false_type /*void*/, meta::index_list<Indices...>, Args&&... args)
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;
@ -70,32 +168,177 @@ namespace luabind
// pcall will pop the function and self reference
// and all the parameters
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))
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);
call_error(L);
#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);
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);
#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);
}
return converter.to_cpp(L, decorate_type_t<R>(), -1);
private:
lua_State* L;
Tuple m_args;
mutable bool m_called;
};
// if the proxy_member_caller returns void
template<class Tuple>
class proxy_member_void_caller
{
friend class luabind::object;
public:
proxy_member_void_caller(lua_State* L_, const Tuple args)
: L(L_)
, m_args(args)
, m_called(false)
{
}
proxy_member_void_caller(const proxy_member_void_caller& rhs)
: 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;
};
} // detail
template<class R, typename PolicyList = no_policies, typename... Args>
R call_member(object const& obj, const char* name, Args&&... args)
#define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/call_member.hpp>, 1))
#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
// once the call has been made
@ -111,17 +354,12 @@ namespace luabind
// now the function and self objects
// are on the stack. These will both
// be popped by pcall
return detail::call_member_impl<R, PolicyList>(obj.interpreter(), std::is_void<R>(), meta::index_range<1, sizeof...(Args)+1>(), std::forward<Args>(args)...);
return proxy_type(obj.interpreter(), args);
}
template <class R, typename... Args>
R call_member(wrap_base const* self, char const* fn, Args&&... args)
{
return self->call<R>(fn, std::forward<Args>(args)...);
}
#undef LUABIND_OPERATOR_PARAMS
#undef LUABIND_TUPLE_PARAMS
}
#endif // LUABIND_CALL_MEMBER_HPP_INCLUDED
#endif
#endif

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,9 +30,8 @@
#include <luabind/open.hpp>
#include <luabind/typeid.hpp>
namespace luabind {
namespace detail {
namespace luabind { namespace detail
{
class class_rep;
struct LUABIND_API class_registry
@ -80,8 +79,7 @@ namespace luabind {
};
}
}
}}
#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
// copy of this software and associated documentation files (the "Software"),
@ -24,12 +24,16 @@
#ifndef 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 <utility>
#include <vector>
#include <luabind/config.hpp>
#include <luabind/lua_include.hpp>
#include <luabind/detail/object_rep.hpp>
#include <luabind/detail/garbage_collector.hpp>
#include <luabind/detail/operator_id.hpp>
#include <luabind/detail/class_registry.hpp>
@ -39,8 +43,8 @@
#include <luabind/typeid.hpp>
#include <luabind/detail/ref.hpp>
namespace luabind {
namespace detail {
namespace luabind { namespace detail
{
LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
@ -67,7 +71,7 @@ namespace luabind {
{
friend struct class_registration;
friend int super_callback(lua_State*);
//TODO: avoid the lua-prefix
//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*);
@ -95,7 +99,7 @@ namespace luabind {
~class_rep();
std::pair<void*, void*> allocate(lua_State* L) const;
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);
@ -147,9 +151,6 @@ namespace luabind {
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
@ -203,10 +204,10 @@ namespace luabind {
class_id_map* m_classes;
};
LUABIND_API bool is_class_rep(lua_State* L, int index);
bool is_class_rep(lua_State* L, int index);
}
}
}}
//#include <luabind/detail/overload_rep_impl.hpp>
#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,39 +2,51 @@
// 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_DETAIL_CONSTRUCTOR_081018_HPP
#define LUABIND_DETAIL_CONSTRUCTOR_081018_HPP
#if !BOOST_PP_IS_ITERATING
#include <luabind/get_main_thread.hpp>
#include <luabind/lua_argument_proxy.hpp>
#include <luabind/wrapper_base.hpp>
#include <luabind/detail/inheritance.hpp>
# ifndef LUABIND_DETAIL_CONSTRUCTOR_081018_HPP
# define LUABIND_DETAIL_CONSTRUCTOR_081018_HPP
namespace luabind {
namespace detail {
# include <luabind/get_main_thread.hpp>
# 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>
void inject_backref(lua_State* L, T* p, wrap_base*)
{
namespace luabind { namespace detail {
inline void inject_backref(lua_State*, void*, void*)
{}
template <class T>
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 >
struct construct_aux_helper;
template <std::size_t Arity, class T, class Pointer, class Signature>
struct construct_aux;
template< class T, class Pointer, class Signature, typename... Arguments, unsigned int... ArgumentIndices >
struct construct_aux_helper< T, Pointer, Signature, meta::type_list< Arguments... >, meta::index_list< ArgumentIndices... > >
{
using holder_type = pointer_holder<Pointer, T>;
template <class T, class Pointer, class Signature>
struct construct
: construct_aux<mpl::size<Signature>::value - 2, T, Pointer, Signature>
{};
void operator()(argument const& self_, Arguments... args) const
template <class T, class Pointer, class Signature>
struct construct_aux<0, T, Pointer, Signature>
{
typedef pointer_holder<Pointer, T> holder_type;
void operator()(argument const& self_) const
{
object_rep* self = touserdata<object_rep>(self_);
class_rep* cls = self->crep();
std::unique_ptr<T> instance(new T(args...));
std::auto_ptr<T> instance(new T);
inject_backref(self_.interpreter(), instance.get(), instance.get());
void* naked_ptr = instance.get();
@ -42,24 +54,58 @@ namespace luabind {
void* storage = self->allocate(sizeof(holder_type));
self->set_instance(new (storage) holder_type(std::move(ptr), registered_class<T>::id, naked_ptr));
self->set_instance(new (storage) holder_type(
ptr, registered_class<T>::id, naked_ptr, cls));
}
};
};
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (1, LUABIND_MAX_ARITY, <luabind/detail/constructor.hpp>))
# include BOOST_PP_ITERATE()
template< class T, class Pointer, class Signature >
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
} // namespace luabind
}} // namespace luabind::detail
# 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
# include <luabind/config.hpp>
# include <type_traits>
# include <boost/aligned_storage.hpp>
namespace luabind {
namespace detail {
namespace luabind { namespace detail {
using destruction_function = void(*)(void*);
typedef void(*destruction_function)(void*);
// This is used by the converters in policy.hpp, and
// class_rep::convert_to as temporary storage when constructing
// holders.
// This is used by the converters in policy.hpp, and
// class_rep::convert_to as temporary storage when constructing
// holders.
struct conversion_storage
{
struct conversion_storage
{
conversion_storage()
: destructor(0)
{}
~conversion_storage()
{
if(destructor)
if (destructor)
destructor(&data);
}
// Unfortunately the converters currently doesn't have access to
// the actual type being converted when this is instantiated, so
// we have to guess a max size.
std::aligned_storage<128> data;
boost::aligned_storage<128> data;
destruction_function destructor;
};
};
}
} // namespace luabind::detail
}} // namespace luabind::detail
#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,9 +28,8 @@
#include <luabind/lua_include.hpp>
#include <cassert>
namespace luabind {
namespace detail {
namespace luabind { namespace detail
{
struct stack_checker_type
{
stack_checker_type(lua_State* L)
@ -47,13 +46,10 @@ namespace luabind {
int m_stack;
};
}
}
}}
#define LUABIND_CHECK_STACK(L) luabind::detail::stack_checker_type stack_checker_object(L)
#else
#define LUABIND_CHECK_STACK(L) do {} while (0)
#endif
#endif // LUABIND_DEBUG_HPP_INCLUDED

View File

@ -25,62 +25,242 @@
#define LUABIND_DECORATE_TYPE_HPP_INCLUDED
#include <luabind/config.hpp>
#include <luabind/detail/primitives.hpp>
namespace luabind {
namespace luabind { namespace detail
{
template<class T> struct by_value {};
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 {};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
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>
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>
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>
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>
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>
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>
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 >
using decorate_type_t = typename decorate_type<T>::type;
template<class T>
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

View File

@ -2,19 +2,117 @@
// 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)
#if !BOOST_PP_IS_ITERATING
# ifndef LUABIND_DEDUCE_SIGNATURE_080911_HPP
# define LUABIND_DEDUCE_SIGNATURE_080911_HPP
#include <luabind/detail/meta.hpp>
#include <luabind/detail/type_traits.hpp>
# include <luabind/detail/most_derived.hpp>
namespace luabind {
namespace detail {
# if LUABIND_MAX_ARITY <= 8
# 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
#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/detail/class_rep.hpp>
namespace luabind {
namespace luabind
{
struct value;
struct value_vector : public std::vector<value>
@ -93,7 +93,7 @@ namespace luabind {
template<class From>
struct enum_maker
{
explicit enum_maker(From& from) : from_(from) {}
explicit enum_maker(From& from): from_(from) {}
From& operator[](const value& val)
{
@ -103,8 +103,9 @@ namespace luabind {
From& operator[](const value_vector& values)
{
for(const auto& val : values) {
from_.add_static_constant(val.name_, val.val_);
for (value_vector::const_iterator i = values.begin(); i != values.end(); ++i)
{
from_.add_static_constant(i->name_, i->val_);
}
return from_;
@ -120,4 +121,3 @@ namespace luabind {
}
#endif // LUABIND_ENUM_MAKER_HPP_INCLUDED

View File

@ -5,70 +5,73 @@
#ifndef LUABIND_FORMAT_SIGNATURE_081014_HPP
# define LUABIND_FORMAT_SIGNATURE_081014_HPP
#include <luabind/config.hpp>
#include <luabind/lua_include.hpp>
#include <luabind/typeid.hpp>
#include <luabind/detail/meta.hpp>
# include <luabind/config.hpp>
# include <luabind/lua_include.hpp>
# include <luabind/typeid.hpp>
namespace luabind {
namespace adl {
# include <boost/mpl/begin_end.hpp>
# include <boost/mpl/next.hpp>
# include <boost/mpl/size.hpp>
namespace luabind { namespace adl {
class object;
class argument;
template <class Base>
struct table;
} // namespace adl
} // namespace adl
using adl::object;
using adl::argument;
using adl::table;
using adl::object;
using adl::argument;
using adl::table;
} // namespace luabind
namespace detail {
namespace luabind { namespace detail {
LUABIND_API std::string get_class_name(lua_State* L, type_id const& i);
LUABIND_API std::string get_class_name(lua_State* L, type_id const& i);
template <class T, class Enable = void>
struct type_to_string
{
template <class T>
struct type_to_string
{
static void get(lua_State* L)
{
lua_pushstring(L, get_class_name(L, typeid(T)).c_str());
}
};
};
template <class T>
struct type_to_string<T*>
{
template <class T>
struct type_to_string<T*>
{
static void get(lua_State* L)
{
type_to_string<T>::get(L);
lua_pushstring(L, "*");
lua_concat(L, 2);
}
};
};
template <class T>
struct type_to_string<T&>
{
template <class T>
struct type_to_string<T&>
{
static void get(lua_State* L)
{
type_to_string<T>::get(L);
lua_pushstring(L, "&");
lua_concat(L, 2);
}
};
};
template <class T>
struct type_to_string<T const>
{
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) \
template <> \
@ -84,49 +87,50 @@ namespace luabind {
LUABIND_TYPE_TO_STRING(x) \
LUABIND_TYPE_TO_STRING(unsigned x)
LUABIND_INTEGRAL_TYPE_TO_STRING(char)
LUABIND_INTEGRAL_TYPE_TO_STRING(short)
LUABIND_INTEGRAL_TYPE_TO_STRING(int)
LUABIND_INTEGRAL_TYPE_TO_STRING(long)
LUABIND_INTEGRAL_TYPE_TO_STRING(char)
LUABIND_INTEGRAL_TYPE_TO_STRING(short)
LUABIND_INTEGRAL_TYPE_TO_STRING(int)
LUABIND_INTEGRAL_TYPE_TO_STRING(long)
LUABIND_TYPE_TO_STRING(void)
LUABIND_TYPE_TO_STRING(bool)
LUABIND_TYPE_TO_STRING(std::string)
LUABIND_TYPE_TO_STRING(lua_State)
LUABIND_TYPE_TO_STRING(void)
LUABIND_TYPE_TO_STRING(bool)
LUABIND_TYPE_TO_STRING(std::string)
LUABIND_TYPE_TO_STRING(lua_State)
LUABIND_TYPE_TO_STRING(luabind::object)
LUABIND_TYPE_TO_STRING(luabind::argument)
LUABIND_TYPE_TO_STRING(luabind::object)
LUABIND_TYPE_TO_STRING(luabind::argument)
# undef LUABIND_INTEGRAL_TYPE_TO_STRING
# undef LUABIND_TYPE_TO_STRING
template <class Base>
struct type_to_string<table<Base> >
{
template <class Base>
struct type_to_string<table<Base> >
{
static void get(lua_State* L)
{
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>
void format_signature_aux(lua_State* L, bool first, Signature)
{
if(!first)
template <class Iter, class End>
void format_signature_aux(lua_State* L, bool first, Iter, End end)
{
if (!first)
lua_pushstring(L, ",");
type_to_string<typename meta::front<Signature>::type>::get(L);
format_signature_aux(L, false, typename meta::pop_front<Signature>::type());
}
type_to_string<typename Iter::type>::get(L);
format_signature_aux(L, false, typename mpl::next<Iter>::type(), end);
}
template <class Signature>
void format_signature(lua_State* L, char const* function, Signature)
{
using first = typename meta::front<Signature>::type;
template <class Signature>
void format_signature(lua_State* L, char const* function, Signature)
{
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, function);
@ -135,16 +139,15 @@ namespace luabind {
format_signature_aux(
L
, 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_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

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
// copy of this software and associated documentation files (the "Software"),
@ -26,9 +26,8 @@
#include <luabind/config.hpp>
namespace luabind {
namespace detail {
namespace luabind { namespace detail
{
// function that is used as __gc metafunction on several objects
template<class T>
inline int garbage_collector(lua_State* L)
@ -49,8 +48,6 @@ namespace luabind {
}
};
}
}
}}
#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,31 +1,30 @@
// Copyright Daniel Wallin 2009. 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_INHERITANCE_090217_HPP
# define LUABIND_INHERITANCE_090217_HPP
# include <luabind/config.hpp>
# include <cassert>
# include <limits>
# include <map>
# include <memory>
# include <vector>
# 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*);
using class_id = std::size_t;
class_id const unknown_class = (std::numeric_limits<class_id>::max)();
constexpr class_id unknown_class = std::numeric_limits<class_id>::max();
class class_rep;
class class_rep;
class LUABIND_API cast_graph
{
public:
class LUABIND_API cast_graph
{
public:
cast_graph();
~cast_graph();
@ -33,61 +32,64 @@ namespace luabind {
// for a polymorphic type, the pointer must be cast with
// dynamic_cast<void*> before being passed in here, and `src` has to
// 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;
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:
private:
class impl;
std::unique_ptr<impl> m_impl;
};
boost::scoped_ptr<impl> m_impl;
};
// Maps a type_id to a class_id. Note that this actually partitions the
// id-space into two, using one half for "local" ids; ids that are used only as
// 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:
// Maps a type_id to a class_id. Note that this actually partitions the
// id-space into two, using one half for "local" ids; ids that are used only as
// 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();
class_id get(type_id const& type) const;
class_id get_local(type_id const& type);
void put(class_id id, type_id const& type);
private:
using map_type = std::map<type_id, class_id>;
private:
typedef std::map<type_id, class_id> map_type;
map_type m_classes;
class_id m_local_id;
static class_id const local_id_base;
};
};
inline class_id_map::class_id_map()
inline class_id_map::class_id_map()
: m_local_id(local_id_base)
{}
{}
inline class_id class_id_map::get(type_id const& type) const
{
inline class_id class_id_map::get(type_id const& type) const
{
map_type::const_iterator i = m_classes.find(type);
if(i == m_classes.end() || i->second >= local_id_base) {
if (i == m_classes.end() || i->second >= local_id_base)
return unknown_class;
}
else {
return i->second;
}
}
}
inline class_id class_id_map::get_local(type_id const& type)
{
std::pair<map_type::iterator, bool> result = m_classes.insert(std::make_pair(type, 0));
inline class_id class_id_map::get_local(type_id const& type)
{
std::pair<map_type::iterator, bool> result = m_classes.insert(
std::make_pair(type, 0));
if (result.second)
result.first->second = m_local_id++;
if(result.second) result.first->second = m_local_id++;
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;
}
inline void class_id_map::put(class_id id, type_id const& type)
{
assert(id < local_id_base);
std::pair<map_type::iterator, bool> result = m_classes.insert(
@ -100,70 +102,67 @@ namespace luabind {
);
result.first->second = id;
}
}
class class_map
{
public:
class class_map
{
public:
class_rep* get(class_id id) const;
void put(class_id id, class_rep* cls);
private:
private:
std::vector<class_rep*> m_classes;
};
};
inline class_rep* class_map::get(class_id id) const
{
if(id >= m_classes.size())
inline class_rep* class_map::get(class_id id) const
{
if (id >= m_classes.size())
return 0;
return m_classes[id];
}
}
inline void class_map::put(class_id id, class_rep* cls)
{
if(id >= m_classes.size())
inline void class_map::put(class_id id, class_rep* cls)
{
if (id >= m_classes.size())
m_classes.resize(id + 1);
m_classes[id] = cls;
}
}
template <class S, class T>
struct static_cast_
{
template <class S, class T>
struct static_cast_
{
static void* execute(void* p)
{
return static_cast<T*>(static_cast<S*>(p));
}
};
};
template <class S, class T>
struct dynamic_cast_
{
template <class S, class T>
struct dynamic_cast_
{
static void* execute(void* p)
{
return dynamic_cast<T*>(static_cast<S*>(p));
}
};
};
// Thread safe class_id allocation.
LUABIND_API class_id allocate_class_id(type_id const& cls);
// Thread safe class_id allocation.
LUABIND_API class_id allocate_class_id(type_id const& cls);
template <class T>
struct registered_class
{
template <class T>
struct registered_class
{
static class_id const id;
};
};
template <class T>
class_id const registered_class<T>::id = allocate_class_id(typeid(T));
template <class T>
class_id const registered_class<T>::id = allocate_class_id(typeid(T));
template <class T>
struct registered_class<T const>
template <class T>
struct registered_class<T const>
: registered_class<T>
{};
{};
} // namespace detail
} // namespace luabind
}} // namespace luabind::detail
#endif // LUABIND_INHERITANCE_090217_HPP

View File

@ -6,72 +6,117 @@
# define LUABIND_INSTANCE_HOLDER_081024_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 <boost/type_traits/is_polymorphic.hpp>
# include <stdexcept>
namespace luabind {
namespace detail {
namespace luabind { namespace detail {
class instance_holder
{
public:
instance_holder(bool pointee_const)
: m_pointee_const(pointee_const)
class instance_holder
{
public:
instance_holder(class_rep* cls, bool pointee_const)
: m_cls(cls)
, m_pointee_const(pointee_const)
{}
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;
class_rep* get_class() const
{
return m_cls;
}
bool pointee_const() const
{
return m_pointee_const;
}
private:
private:
class_rep* m_cls;
bool m_pointee_const;
};
};
template <class P, class Pointee = void const>
class pointer_holder : public instance_holder
{
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)
namespace mpl = boost::mpl;
inline mpl::false_ check_const_pointer(void*)
{
return mpl::false_();
}
inline mpl::true_ check_const_pointer(void const*)
{
return mpl::true_();
}
template <class T>
void release_ownership(std::auto_ptr<T>& p)
{
p.release();
}
template <class P>
void release_ownership(P const&)
{
throw std::runtime_error(
"luabind: smart pointer does not allow ownership transfer");
}
template <class T>
class_id static_class_id(T*)
{
return registered_class<T>::id;
}
template <class P, class Pointee = void const>
class pointer_holder : public instance_holder
{
public:
pointer_holder(
P p, class_id dynamic_id, void* dynamic_ptr, class_rep* cls
)
: instance_holder(cls, check_const_pointer(false ? get_pointer(p) : 0))
, p(p)
, weak(0)
, dynamic_id(dynamic_id)
, dynamic_ptr(dynamic_ptr)
{}
std::pair<void*, int> get(class_id target) 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)));
if (!naked_ptr)
return std::pair<void*, int>((void*)0, 0);
return get_class()->casts().cast(
naked_ptr
, static_class_id(false ? get_pointer(p) : 0)
, target
, dynamic_id
, dynamic_ptr
);
}
std::pair<void*, int> get(cast_graph const& casts, class_id target) const override
void release()
{
// if somebody wants the smart-ptr, he can get a reference to it
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)));
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;
return casts.cast(naked_ptr,
registered_class< pointee_type >::id,
target, dynamic_id, dynamic_ptr);
}
explicit operator bool() const
{
return p ? true : false;
}
void release() override
{
weak = const_cast<void*>(static_cast<void const*>(get_pointer(p)));
weak = const_cast<void*>(static_cast<void const*>(
get_pointer(p)));
release_ownership(p);
}
private:
private:
mutable P p;
// weak will hold a possibly stale pointer to the object owned
// by p once p has released it's owership. This is a workaround
@ -79,87 +124,8 @@ namespace luabind {
void* weak;
class_id dynamic_id;
void* dynamic_ptr;
};
};
template <class ValueType>
class value_holder :
public instance_holder
{
public:
// No need for dynamic_id / dynamic_ptr, since we always get the most derived type
value_holder(lua_State* /*L*/, ValueType val)
: instance_holder(false), val_(std::move(val))
{}
explicit operator bool() const
{
return true;
}
std::pair<void*, int> get(cast_graph const& casts, class_id target) const override
{
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
{}
private:
ValueType val_;
};
/*
Pointer types should automatically convert to reference types
*/
template <class ValueType>
class pointer_like_holder :
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
{
return val_ ? true : false;
}
std::pair<void*, int> get(cast_graph const& casts, class_id target) const override
{
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
}} // namespace luabind::detail
#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,8 +25,8 @@
#include <luabind/config.hpp>
namespace luabind {
namespace detail {
namespace luabind { namespace detail
{
#ifdef LUABIND_NOT_THREADSAFE
LUABIND_API void not_threadsafe_defined_conflict();
@ -42,21 +42,19 @@ namespace luabind {
inline void check_link_compatibility()
{
#ifdef LUABIND_NOT_THREADSAFE
#ifdef LUABIND_NOT_THREADSAFE
not_threadsafe_defined_conflict();
#else
#else
not_threadsafe_not_defined_conflict();
#endif
#endif
#ifdef LUABIND_NO_ERROR_CHECKING
#ifdef LUABIND_NO_ERROR_CHECKING
no_error_checking_defined_conflict();
#else
#else
no_error_checking_not_defined_conflict();
#endif
#endif
}
}
}
}}
#endif

View File

@ -5,85 +5,92 @@
#ifndef 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/object_rep.hpp>
namespace luabind {
namespace detail {
namespace luabind { namespace detail {
template <class T>
std::pair<class_id, void*> get_dynamic_class_aux(lua_State* L, T const* p, std::true_type)
{
template <class T>
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);
class_id_map& class_ids = *static_cast<class_id_map*>(lua_touserdata(L, -1));
class_id_map& class_ids = *static_cast<class_id_map*>(
lua_touserdata(L, -1));
lua_pop(L, 1);
return std::make_pair(class_ids.get_local(typeid(*p)), dynamic_cast<void*>(const_cast<T*>(p)));
}
return std::make_pair(
class_ids.get_local(typeid(*p))
, dynamic_cast<void*>(const_cast<T*>(p))
);
}
template <class T>
std::pair<class_id, void*> get_dynamic_class_aux(lua_State*, T const* p, std::false_type)
{
template <class T>
std::pair<class_id, void*> get_dynamic_class_aux(
lua_State*, T const* p, mpl::false_)
{
return std::make_pair(registered_class<T>::id, (void*)p);
}
}
template <class T>
std::pair<class_id, void*> get_dynamic_class(lua_State* L, T* p)
{
return get_dynamic_class_aux(L, p, std::is_polymorphic<T>());
}
template <class T>
std::pair<class_id, void*> get_dynamic_class(lua_State* L, T* p)
{
return get_dynamic_class_aux(L, p, boost::is_polymorphic<T>());
}
template <class T>
class_rep* get_pointee_class(class_map const& classes, T*)
{
template <class T>
class_rep* get_pointee_class(class_map const& classes, T*)
{
return classes.get(registered_class<T>::id);
}
}
template <class P>
class_rep* get_pointee_class(lua_State* L, P const& p, class_id dynamic_id)
{
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_map const& classes = *static_cast<class_map*>(lua_touserdata(L, -1));
class_map const& classes = *static_cast<class_map*>(
lua_touserdata(L, -1));
lua_pop(L, 1);
class_rep* cls = classes.get(dynamic_id);
if(!cls) {
if (!cls)
cls = get_pointee_class(classes, get_pointer(p));
}
return cls;
}
}
// Create an appropriate instance holder for the given pointer like object.
template <class P>
void make_pointer_instance(lua_State* L, P p)
{
// Create an appropriate instance holder for the given pointer like object.
template <class P>
void make_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);
if(!cls)
if (!cls)
{
throw std::runtime_error("Trying to use unregistered class: " + std::string(typeid(P).name()));
throw std::runtime_error("Trying to use unregistered class");
}
object_rep* instance = push_new_instance(L, cls);
using value_type = typename std::remove_reference<P>::type;
using holder_type = pointer_holder<value_type>;
typedef pointer_holder<P> holder_type;
void* storage = instance->allocate(sizeof(holder_type));
try
{
new (storage) holder_type(std::move(p), dynamic.first, dynamic.second);
new (storage) holder_type(p, dynamic.first, dynamic.second, cls);
}
catch(...)
catch (...)
{
instance->deallocate(storage);
lua_pop(L, 1);
@ -91,81 +98,8 @@ namespace luabind {
}
instance->set_instance(static_cast<holder_type*>(storage));
}
}
template< typename ValueType >
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));
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
}} // namespace luabind::detail
#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
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_VALUE_WRAPPER_050419_HPP
#define LUABIND_VALUE_WRAPPER_050419_HPP
#ifndef MOST_DERIVED_051018_HPP
# define MOST_DERIVED_051018_HPP
#include <type_traits>
#include <luabind/detail/type_traits.hpp>
# include <boost/mpl/if.hpp>
# include <boost/type_traits/is_base_and_derived.hpp>
namespace luabind {
namespace luabind { namespace detail {
//
// Concept "lua_proxy"
//
template<class Class, class WrappedClass>
struct most_derived
{
typedef typename boost::mpl::if_<
boost::is_base_and_derived<Class, WrappedClass>
, WrappedClass
, Class
>::type type;
};
template<class T>
struct lua_proxy_traits
{
using is_specialized = std::false_type;
};
}} // namespace luabind::detail
template<class T>
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
#endif // MOST_DERIVED_051018_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,15 +24,15 @@
#ifndef LUABIND_OBJECT_REP_HPP_INCLUDED
#define LUABIND_OBJECT_REP_HPP_INCLUDED
#include <boost/aligned_storage.hpp>
#include <luabind/config.hpp>
#include <luabind/detail/class_rep.hpp>
#include <luabind/detail/instance_holder.hpp>
#include <luabind/detail/ref.hpp>
#include <type_traits> // std::aligned_storage
#include <cstdlib>
namespace luabind {
namespace detail {
namespace luabind { namespace detail
{
class class_rep;
void finalize(lua_State* L, class_rep* crep);
@ -51,12 +51,13 @@ namespace luabind {
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
{
if(m_instance == 0)
return std::pair<void*, int>(nullptr, -1);
return m_instance->get(m_classrep->casts(), target);
if (m_instance == 0)
return std::pair<void*, int>((void*)0, -1);
return m_instance->get(target);
}
bool is_const() const
@ -66,39 +67,36 @@ namespace luabind {
void release()
{
if(m_instance)
if (m_instance)
m_instance->release();
}
void* allocate(std::size_t size)
{
if(size <= 32) {
if (size <= 32)
return &m_instance_buffer;
}
else {
return std::malloc(size);
}
}
void deallocate(void* storage)
{
if(storage == &m_instance_buffer) {
if (storage == &m_instance_buffer)
return;
}
else {
std::free(storage);
}
}
private:
object_rep(object_rep const&) = delete;
void operator=(object_rep const&) = delete;
object_rep(object_rep const&)
{}
void operator=(object_rep const&)
{}
instance_holder* m_instance;
std::aligned_storage<32>::type m_instance_buffer;
boost::aligned_storage<32> 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
std::size_t m_dependency_cnt; // counts dependencies
};
template<class T>
@ -129,9 +127,7 @@ namespace luabind {
LUABIND_API void push_instance_metatable(lua_State* L);
LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls);
} // namespace detail
} // namespace luabind
}}
#endif // LUABIND_OBJECT_REP_HPP_INCLUDED

View File

@ -26,8 +26,7 @@
#include <luabind/config.hpp>
namespace luabind {
namespace detail {
namespace luabind { namespace detail {
enum operator_id
{
@ -35,7 +34,6 @@ namespace luabind {
op_sub,
op_mul,
op_div,
op_mod,
op_pow,
op_lt,
op_le,
@ -52,7 +50,7 @@ namespace luabind {
inline const char* get_operator_name(int i)
{
static const char* a[number_of_operators] = {
"__add", "__sub", "__mul", "__div", "__mod", "__pow",
"__add", "__sub", "__mul", "__div", "__pow",
"__lt", "__le", "__eq", "__call", "__unm",
"__tostring", "__concat", "__len" };
return a[i];
@ -61,7 +59,7 @@ namespace luabind {
inline const char* get_operator_symbol(int i)
{
static const char* a[number_of_operators] = {
"+", "-", "*", "/", "%", "^", "<",
"+", "-", "*", "/", "^", "<",
"<=", "==", "()", "- (unary)",
"tostring", "..", "#" };
return a[i];
@ -76,8 +74,6 @@ namespace luabind {
}
} // namespace detail
} // namespace luabind
}}
#endif // LUABIND_OPERATOR_ID_HPP_INCLUDED

View File

@ -33,34 +33,87 @@
// to its suitability for any purpose.
#include <luabind/config.hpp>
#include <boost/config.hpp>
namespace luabind {
namespace luabind
{
template<class T>
struct other
{
using type = T;
typedef T type;
};
}
} // namespace luabind
namespace luabind {
namespace detail {
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace luabind { namespace detail
{
template<typename T>
class unwrap_other
{
public:
using type = T;
typedef T type;
};
template<typename T>
class unwrap_other<other<T> >
{
public:
using type = T;
typedef T type;
};
}
} // namespace luabind::detail
}} // namespace luabind::detail
# else // no partial specialization
#include <boost/type.hpp>
namespace luabind { namespace detail
{
typedef char (&yes_other_t)[1];
typedef char (&no_other_t)[2];
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

View File

@ -25,14 +25,12 @@
#include <luabind/config.hpp>
#include <luabind/lua_state_fwd.hpp>
struct lua_State;
namespace luabind {
namespace detail {
namespace luabind { namespace detail
{
LUABIND_API int pcall(lua_State *L, int nargs, int nresults);
LUABIND_API int resume_impl(lua_State *L, int nargs, int nresults);
}
}
}}
#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
// 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
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef INCLUDED_error_callback_fun_hpp_GUID_1150976a_4348_495f_99ce_9d7edd00a0b8
#define INCLUDED_error_callback_fun_hpp_GUID_1150976a_4348_495f_99ce_9d7edd00a0b8
#ifndef POINTEE_TYPEID_040211_HPP
#define POINTEE_TYPEID_040211_HPP
// Internal Includes
#include <luabind/config.hpp>
#include <luabind/lua_state_fwd.hpp>
#include <luabind/typeid.hpp>
// Library/third-party includes
// - none
namespace luabind { namespace detail {
// Standard includes
// - none
template<class T>
type_id pointee_typeid(T*)
{
return typeid(T);
}
namespace luabind
{
class type_id;
}} // namespace luabind::detail
using error_callback_fun = void(*)(lua_State*);
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
#endif // POINTEE_TYPEID_040211_HPP

File diff suppressed because it is too large Load Diff

View File

@ -24,16 +24,39 @@
#ifndef LUABIND_PRIMITIVES_HPP_INCLUDED
#define LUABIND_PRIMITIVES_HPP_INCLUDED
// std::reference_wrapper...
#include <type_traits> // std::true_type...
#include <algorithm>
#include <cstring>
namespace luabind {
namespace detail {
#include <luabind/config.hpp>
#include <luabind/detail/yes_no.hpp>
namespace luabind { namespace detail
{
template<class T>
struct identity
{
typedef T type;
};
template<class T>
struct type_ {};
struct null_type {};
/* typedef char yes_t;
typedef double no_t;*/
struct lua_to_cpp {};
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; }
@ -46,18 +69,17 @@ namespace luabind {
};
// returns the offset added to a Derived* when cast to a Base*
// TODO: return ptrdiff
template<class Derived, class Base>
ptrdiff_t ptr_offset(type_<Derived>, type_<Base>)
int 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)))
return int(static_cast<char*>(static_cast<void*>(static_cast<Base*>(ptr)))
- static_cast<char*>(static_cast<void*>(ptr)));
}
}
}
}}
#endif // LUABIND_PRIMITIVES_HPP_INCLUDED

View File

@ -5,12 +5,11 @@
#ifndef LUABIND_PROPERTY_081020_HPP
# define LUABIND_PROPERTY_081020_HPP
namespace luabind {
namespace detail {
namespace luabind { namespace detail {
template <class Class, class T, class Result = T>
struct access_member_ptr
{
template <class Class, class T, class Result = T>
struct access_member_ptr
{
access_member_ptr(T Class::* mem_ptr)
: mem_ptr(mem_ptr)
{}
@ -26,10 +25,9 @@ namespace luabind {
}
T Class::* mem_ptr;
};
};
} // namespace detail
} // namespace luabind
}} // namespace luabind::detail
#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,8 +33,8 @@
namespace luabind
{
namespace detail
{
namespace detail
{
struct lua_reference
{
@ -46,7 +46,7 @@ namespace luabind
: L(r.L)
, m_ref(LUA_NOREF)
{
if(!r.is_valid()) return;
if (!r.is_valid()) return;
r.get(L);
set(L);
}
@ -58,15 +58,13 @@ namespace luabind
{
// TODO: self assignment problems
reset();
if(!r.is_valid()) return;
if (!r.is_valid()) return;
r.get(r.state());
set(r.state());
}
bool is_valid() const
{
return m_ref != LUA_NOREF;
}
{ return m_ref != LUA_NOREF; }
void set(lua_State* L_)
{
@ -93,7 +91,7 @@ namespace luabind
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;
}
@ -108,8 +106,7 @@ namespace luabind
int m_ref;
};
}
}
}}
#endif // LUABIND_REF_HPP_INCLUDED

View File

@ -25,5 +25,37 @@
#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

View File

@ -23,14 +23,10 @@
#ifndef LUABIND_STACK_UTILS_HPP_INCLUDED
#define LUABIND_STACK_UTILS_HPP_INCLUDED
#ifndef LUA_INCLUDE_HPP_INCLUDED
#include <luabind/lua_include.hpp>
#endif
#include <cassert>
namespace luabind {
namespace detail {
namespace luabind { namespace detail
{
struct stack_pop
{
@ -50,9 +46,7 @@ namespace luabind {
lua_State* m_state;
int m_n;
};
} // namespace detail
} // namespace luabind
}}
#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
// 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
// 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
{
LUABIND_API self_type self;
LUABIND_API const_self_type const_self;
}
typedef char(&yes_t)[1];
typedef char(&no_t)[2];
}} // 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
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED
#define LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED
#include <luabind/config.hpp>
#include <luabind/detail/policy.hpp> // for index_map, etc
#include <luabind/detail/primitives.hpp> // for null_type, etc
#include <luabind/lua_include.hpp>
namespace luabind {
namespace detail {
#include <luabind/detail/policy.hpp>
namespace luabind { namespace detail
{
struct discard_converter
{
template<class T>
void to_lua(lua_State*, T) {}
void apply(lua_State*, T) {}
};
struct discard_result_policy
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 specialize
struct apply
{
static_assert(std::is_same< Direction, cpp_to_lua >::value, "Can only convert from cpp to lua");
using type = discard_converter;
typedef typename boost::mpl::if_<boost::is_same<Direction, cpp_to_lua>
, discard_converter
, can_only_convert_from_cpp_to_lua
>::type type;
};
};
}
}
}}
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

View File

@ -26,13 +26,9 @@
#include <luabind/prefix.hpp>
#include <exception>
#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>
#endif
struct lua_State;
namespace luabind
{
@ -42,19 +38,22 @@ namespace luabind
// this exception usually means that the lua function you called
// from C++ failed with an error code. You will have to
// 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
// being thrown throws another exception, terminate will be called
// and the entire application is killed.
class LUABIND_API error : public std::exception
{
public:
explicit error(lua_State* L);
virtual const char* what() const throw();
explicit error(lua_State* L): m_L(L) {}
lua_State* state() const throw() { return m_L; }
virtual const char* what() const throw()
{
return "lua runtime error";
}
private:
std::string m_message;
lua_State* m_L;
};
// if an object_cast<>() fails, this is thrown
@ -63,7 +62,7 @@ namespace luabind
class LUABIND_API cast_failed : public std::exception
{
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; }
type_id info() const throw() { return m_info; }
virtual const char* what() const throw() { return "unable to make cast"; }
@ -74,6 +73,9 @@ namespace luabind
#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_cast_failed_callback(cast_failed_callback_fun c);
LUABIND_API error_callback_fun get_error_callback();
@ -81,6 +83,7 @@ namespace luabind
#endif
typedef int(*pcall_callback_fun)(lua_State*);
LUABIND_API void set_pcall_callback(pcall_callback_fun e);
LUABIND_API pcall_callback_fun get_pcall_callback();

View File

@ -3,18 +3,24 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#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 <type_traits>
#include <luabind/lua_include.hpp>
#include <luabind/detail/meta.hpp>
# include <luabind/lua_include.hpp>
# include <luabind/config.hpp>
# include <boost/optional.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 {
# ifndef LUABIND_NO_EXCEPTIONS
namespace detail {
namespace detail
{
struct LUABIND_API exception_handler_base
{
@ -30,10 +36,18 @@ namespace luabind {
exception_handler_base* next;
};
namespace mpl = boost::mpl;
template<class E, class Handler>
struct exception_handler : exception_handler_base
{
using argument = E const&;
# 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
exception_handler(Handler handler)
: handler(handler)
@ -45,7 +59,7 @@ namespace luabind {
{
try_next(L);
}
catch(argument e)
catch (argument e)
{
handler(L, e);
}
@ -57,19 +71,38 @@ namespace luabind {
LUABIND_API void handle_exception_aux(lua_State* L);
LUABIND_API void register_exception_handler(exception_handler_base*);
} // namespace detail
} // namespace detail
# endif
template<class E, class Handler>
void register_exception_handler(Handler handler, meta::type<E>* = 0)
{
template<class E, class Handler>
void register_exception_handler(Handler handler, boost::type<E>* = 0)
{
# ifndef LUABIND_NO_EXCEPTIONS
detail::register_exception_handler(
new detail::exception_handler<E, Handler>(handler)
);
# 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

View File

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

View File

@ -11,43 +11,50 @@
namespace luabind {
namespace detail
{
namespace detail
{
template <class F, class PolicyInjectors>
template <class F, class Policies>
struct function_registration : registration
{
function_registration(char const* name, F f)
function_registration(char const* name, F f, Policies const& policies)
: name(name)
, f(f)
, policies(policies)
{}
void register_(lua_State* L) const
{
object fn = make_function(L, f, PolicyInjectors());
add_overload(object(from_stack(L, -1)), name, fn);
object fn = make_function(L, f, deduce_signature(f), policies);
add_overload(
object(from_stack(L, -1))
, name
, fn
);
}
char const* name;
F f;
Policies policies;
};
LUABIND_API bool is_luabind_function(lua_State* L, int index);
} // namespace detail
} // namespace detail
template <class F, typename... PolicyInjectors>
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, class Policies>
scope def(char const* name, F f, Policies const& 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, no_policies());
}
template <class F>
scope def(char const* name, F f)
{
return def(name, f, detail::null_type());
}
} // 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
# include <luabind/config.hpp>
# include <luabind/lua_state_fwd.hpp>
namespace luabind {
LUABIND_API lua_State* get_main_thread(lua_State* L);
LUABIND_API lua_State* get_main_thread(lua_State* L);
} // namespace luabind
#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
// 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
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_LUA_STATE_FWD_HPP
#define LUABIND_LUA_STATE_FWD_HPP
#ifndef LUABIND_GET_POINTER_051023_HPP
# define LUABIND_GET_POINTER_051023_HPP
#ifndef LUABIND_CPLUSPLUS_LUA
extern "C"
{
#endif
//
// We need these overloads in the luabind namespace.
//
struct lua_State;
# include <boost/get_pointer.hpp>
#ifndef LUABIND_CPLUSPLUS_LUA
}
#endif
namespace luabind {
#endif // LUABIND_BACK_REFERENCE_FWD_040510_HPP
using boost::get_pointer;
} // namespace luabind
#endif // LUABIND_GET_POINTER_051023_HPP

View File

@ -24,16 +24,15 @@
#define LUABIND_HANDLE_050420_HPP
#include <luabind/lua_include.hpp>
#include <luabind/lua_proxy.hpp>
#include <utility>
#include <luabind/value_wrapper.hpp>
namespace luabind {
// A reference to a Lua value. Represents an entry in the
// registry table.
class handle
{
public:
// A reference to a Lua value. Represents an entry in the
// registry table.
class handle
{
public:
handle();
handle(lua_State* interpreter, int stack_index);
handle(lua_State* main, lua_State* interpreter, int stack_index);
@ -49,74 +48,79 @@ namespace luabind {
void replace(lua_State* interpreter, int stack_index);
private:
private:
lua_State* m_interpreter;
int m_index;
};
};
inline handle::handle()
: m_interpreter(0), m_index(LUA_NOREF)
{}
inline handle::handle()
: m_interpreter(0)
, m_index(LUA_NOREF)
{}
inline handle::handle(handle const& other)
: m_interpreter(other.m_interpreter), m_index(LUA_NOREF)
{
if(m_interpreter == 0) return;
inline handle::handle(handle const& other)
: m_interpreter(other.m_interpreter)
, m_index(LUA_NOREF)
{
if (m_interpreter == 0) return;
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)
: m_interpreter(interpreter), m_index(LUA_NOREF)
{
inline handle::handle(lua_State* interpreter, int stack_index)
: m_interpreter(interpreter)
, m_index(LUA_NOREF)
{
lua_pushvalue(interpreter, stack_index);
m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX);
}
}
inline handle::handle(lua_State* main, lua_State* interpreter, int stack_index)
: m_interpreter(main), m_index(LUA_NOREF)
{
inline handle::handle(lua_State* main, lua_State* interpreter, int stack_index)
: m_interpreter(main)
, m_index(LUA_NOREF)
{
lua_pushvalue(interpreter, stack_index);
m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX);
}
}
inline handle::~handle()
{
if(m_interpreter && m_index != LUA_NOREF) luaL_unref(m_interpreter, LUA_REGISTRYINDEX, m_index);
}
inline handle::~handle()
{
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);
return *this;
}
}
inline void handle::swap(handle& other)
{
inline void handle::swap(handle& other)
{
std::swap(m_interpreter, other.m_interpreter);
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);
}
}
inline lua_State* handle::interpreter() const
{
inline lua_State* handle::interpreter() const
{
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_rawseti(interpreter, LUA_REGISTRYINDEX, m_index);
}
}
template<>
struct lua_proxy_traits<handle>
{
using is_specialized = std::true_type;
template<>
struct value_wrapper_traits<handle>
{
typedef boost::mpl::true_ is_specialized;
static lua_State* interpreter(handle const& value)
{
@ -132,7 +136,7 @@ namespace luabind {
{
return true;
}
};
};
} // namespace luabind

View File

@ -5,28 +5,26 @@
#ifndef LUABIND_ITERATOR_POLICY__071111_HPP
# define LUABIND_ITERATOR_POLICY__071111_HPP
# include <luabind/config.hpp> // for LUABIND_ANONYMOUS_FIX
# include <luabind/detail/push_to_lua.hpp> // for convert_to_lua
# include <luabind/detail/policy.hpp> // for index_map, etc
# include <luabind/config.hpp>
# include <luabind/detail/policy.hpp>
# include <luabind/detail/convert_to_lua.hpp>
# include <new> // for operator new
namespace luabind { namespace detail {
namespace luabind {
namespace detail {
template <class Iterator>
struct iterator
{
template <class Iterator>
struct iterator
{
static int next(lua_State* L)
{
iterator* self = static_cast<iterator*>(
lua_touserdata(L, lua_upvalueindex(1)));
if(self->first != self->last)
if (self->first != self->last)
{
push_to_lua(L, *self->first);
convert_to_lua(L, *self->first);
++self->first;
} else
}
else
{
lua_pushnil(L);
}
@ -48,11 +46,11 @@ namespace luabind {
Iterator first;
Iterator last;
};
};
template <class Iterator>
int make_range(lua_State* L, Iterator first, Iterator last)
{
template <class Iterator>
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);
@ -61,49 +59,54 @@ namespace luabind {
lua_pushcclosure(L, iterator<Iterator>::next, 1);
new (storage) iterator<Iterator>(first, last);
return 1;
}
}
template <class Container>
int make_range(lua_State* L, Container& container)
{
template <class Container>
int make_range(lua_State* L, Container& container)
{
return make_range(L, container.begin(), container.end());
}
}
struct iterator_converter
{
using type = iterator_converter;
struct iterator_converter
{
typedef iterator_converter type;
template <class Container>
void to_lua(lua_State* L, Container& container)
void apply(lua_State* L, Container& container)
{
make_range(L, container);
}
template <class Container>
void tu_lua(lua_State* L, Container const& container)
void apply(lua_State* L, Container const& container)
{
make_range(L, container);
}
};
};
struct iterator_policy : conversion_policy<0>
{
static void precall(lua_State*, index_map const&)
{}
static void postcall(lua_State*, index_map const&)
{}
struct iterator_policy
{
template <class T, class Direction>
struct specialize
struct apply
{
static_assert(std::is_same<Direction, cpp_to_lua>::value, "Iterator policy can only convert from cpp to lua.");
using type = iterator_converter;
};
typedef iterator_converter type;
};
};
} // namespace detail
} // namespace luabind
}} // namespace luabind::detail
namespace luabind {
namespace luabind { namespace {
using return_stl_iterator = policy_list<converter_policy_injector<0, detail::iterator_policy>>;
LUABIND_ANONYMOUS_FIX detail::policy_cons<
detail::iterator_policy, detail::null_type> return_stl_iterator;
} // namespace luabind
}} // namespace luabind::unnamed
#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
#include "lua.h"
#include "lauxlib.h"
#include "lua.h"
#include "lauxlib.h"
#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/function.hpp>
#include <luabind/open.hpp>
#include <luabind/detail/conversion_policies/conversion_policies.hpp>
#endif // LUABIND_BIND_HPP_INCLUDED

View File

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

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