From 26eb4fb6e099d44e61926ba358fddc13b1110841 Mon Sep 17 00:00:00 2001 From: Adam Martin Date: Sat, 2 Feb 2019 00:06:32 -0600 Subject: [PATCH 1/3] Swapped luabind for non-boost fork https://github.com/decimad/luabind-deboostified --- CMakeLists.txt | 8 +- libs/luabind/CMakeLists.txt | 87 +- libs/luabind/CMakeSettings.json | 54 + libs/luabind/luabind/adopt_policy.hpp | 189 ++- libs/luabind/luabind/back_reference.hpp | 132 +- libs/luabind/luabind/back_reference_fwd.hpp | 10 +- libs/luabind/luabind/class.hpp | 899 ++++------- libs/luabind/luabind/class_info.hpp | 9 +- libs/luabind/luabind/config.hpp | 63 +- libs/luabind/luabind/container_policy.hpp | 179 +-- libs/luabind/luabind/copy_policy.hpp | 71 +- libs/luabind/luabind/dependency_policy.hpp | 124 +- libs/luabind/luabind/detail/call.hpp | 790 ++++++---- libs/luabind/luabind/detail/call_function.hpp | 558 ++----- libs/luabind/luabind/detail/call_member.hpp | 360 +---- .../luabind/detail/call_operator_iterate.hpp | 66 - .../{object_call.hpp => call_shared.hpp} | 61 +- libs/luabind/luabind/detail/call_traits.hpp | 113 ++ libs/luabind/luabind/detail/class_cache.hpp | 89 -- .../luabind/luabind/detail/class_registry.hpp | 72 +- libs/luabind/luabind/detail/class_rep.hpp | 319 ++-- libs/luabind/luabind/detail/compute_score.hpp | 73 - libs/luabind/luabind/detail/constructor.hpp | 132 +- .../conversion_policies/conversion_base.hpp | 81 + .../conversion_policies.hpp | 89 ++ .../conversion_policies/enum_converter.hpp | 82 + .../function_converter.hpp | 95 ++ .../lua_proxy_converter.hpp | 73 + .../conversion_policies/native_converter.hpp | 302 ++++ .../conversion_policies/pointer_converter.hpp | 143 ++ .../reference_converter.hpp | 124 ++ .../conversion_policies/value_converter.hpp | 79 + .../luabind/detail/conversion_storage.hpp | 48 +- .../luabind/luabind/detail/convert_to_lua.hpp | 92 -- libs/luabind/luabind/detail/crtp_iterator.hpp | 58 + libs/luabind/luabind/detail/debug.hpp | 34 +- libs/luabind/luabind/detail/decorate_type.hpp | 230 +-- .../luabind/detail/deduce_signature.hpp | 112 +- libs/luabind/luabind/detail/enum_maker.hpp | 20 +- .../luabind/detail/format_signature.hpp | 205 ++- .../luabind/detail/garbage_collector.hpp | 37 +- .../luabind/detail/has_get_pointer.hpp | 107 -- libs/luabind/luabind/detail/inheritance.hpp | 245 +-- .../luabind/detail/instance_holder.hpp | 228 +-- .../luabind/detail/is_indirect_const.hpp | 70 - .../luabind/detail/link_compatibility.hpp | 42 +- libs/luabind/luabind/detail/make_instance.hpp | 208 ++- libs/luabind/luabind/detail/meta.hpp | 581 +++++++ libs/luabind/luabind/detail/object.hpp | 386 +++++ libs/luabind/luabind/detail/object_funs.hpp | 224 --- libs/luabind/luabind/detail/object_rep.hpp | 180 +-- libs/luabind/luabind/detail/operator_id.hpp | 88 +- libs/luabind/luabind/detail/other.hpp | 95 +- libs/luabind/luabind/detail/pcall.hpp | 14 +- libs/luabind/luabind/detail/policy.hpp | 1057 ++----------- libs/luabind/luabind/detail/primitives.hpp | 74 +- libs/luabind/luabind/detail/property.hpp | 38 +- .../{calc_arity.hpp => push_to_lua.hpp} | 66 +- libs/luabind/luabind/detail/ref.hpp | 127 +- .../luabind/detail/signature_match.hpp | 32 - libs/luabind/luabind/detail/stack_utils.hpp | 38 +- libs/luabind/luabind/detail/type_traits.hpp | 189 +++ libs/luabind/luabind/detail/typetraits.hpp | 190 --- .../luabind/luabind/discard_result_policy.hpp | 57 +- libs/luabind/luabind/error.hpp | 29 +- ...ntee_typeid.hpp => error_callback_fun.hpp} | 30 +- libs/luabind/luabind/exception_handler.hpp | 125 +- libs/luabind/luabind/from_stack.hpp | 20 +- libs/luabind/luabind/function.hpp | 67 +- ..._sizeof.hpp => function_introspection.hpp} | 54 +- libs/luabind/luabind/get_main_thread.hpp | 4 +- libs/luabind/luabind/handle.hpp | 180 ++- libs/luabind/luabind/iterator_policy.hpp | 165 +- libs/luabind/luabind/lua_argument_proxy.hpp | 71 + libs/luabind/luabind/lua_include.hpp | 4 +- libs/luabind/luabind/lua_index_proxy.hpp | 137 ++ libs/luabind/luabind/lua_iterator_proxy.hpp | 230 +++ .../most_derived.hpp => lua_proxy.hpp} | 42 +- libs/luabind/luabind/lua_proxy_interface.hpp | 306 ++++ .../{get_pointer.hpp => lua_state_fwd.hpp} | 25 +- libs/luabind/luabind/luabind.hpp | 2 + libs/luabind/luabind/make_function.hpp | 172 +- libs/luabind/luabind/nil.hpp | 11 +- libs/luabind/luabind/no_dependency.hpp | 28 + libs/luabind/luabind/object.hpp | 1392 +---------------- libs/luabind/luabind/open.hpp | 2 + libs/luabind/luabind/operator.hpp | 315 ++-- libs/luabind/luabind/out_value_policy.hpp | 462 +++--- libs/luabind/luabind/pointer_traits.hpp | 148 ++ libs/luabind/luabind/raw_policy.hpp | 78 +- .../luabind/return_reference_to_policy.hpp | 73 +- libs/luabind/luabind/scope.hpp | 118 +- .../{lua502.hpp => set_package_preload.hpp} | 60 +- libs/luabind/luabind/shared_ptr_converter.hpp | 118 +- libs/luabind/luabind/tag_function.hpp | 111 +- libs/luabind/luabind/typeid.hpp | 75 +- libs/luabind/luabind/value_wrapper.hpp | 168 -- libs/luabind/luabind/version.hpp | 1 + libs/luabind/luabind/weak_ref.hpp | 32 +- libs/luabind/luabind/wrapper_base.hpp | 153 +- libs/luabind/luabind/yield_policy.hpp | 38 +- libs/luabind/src/CMakeLists.txt | 182 +++ libs/luabind/src/class.cpp | 559 ++++--- libs/luabind/src/class_info.cpp | 145 +- libs/luabind/src/class_registry.cpp | 190 +-- libs/luabind/src/class_rep.cpp | 193 +-- libs/luabind/src/create_class.cpp | 202 +-- libs/luabind/src/error.cpp | 29 +- libs/luabind/src/exception_handler.cpp | 145 +- libs/luabind/src/function.cpp | 214 +-- libs/luabind/src/function_introspection.cpp | 117 ++ libs/luabind/src/headertest.cpp | 1 + libs/luabind/src/inheritance.cpp | 361 ++--- libs/luabind/src/link_compatibility.cpp | 15 +- libs/luabind/src/object_rep.cpp | 477 +++--- libs/luabind/src/open.cpp | 230 ++- .../detail/yes_no.hpp => src/operator.cpp} | 18 +- libs/luabind/src/pcall.cpp | 56 +- libs/luabind/src/scope.cpp | 300 ++-- libs/luabind/src/set_package_preload.cpp | 60 + libs/luabind/src/stack_content_by_name.cpp | 21 +- libs/luabind/src/weak_ref.cpp | 217 +-- libs/luabind/src/wrapper_base.cpp | 42 +- 123 files changed, 9408 insertions(+), 10110 deletions(-) create mode 100644 libs/luabind/CMakeSettings.json delete mode 100644 libs/luabind/luabind/detail/call_operator_iterate.hpp rename libs/luabind/luabind/detail/{object_call.hpp => call_shared.hpp} (51%) create mode 100644 libs/luabind/luabind/detail/call_traits.hpp delete mode 100644 libs/luabind/luabind/detail/class_cache.hpp delete mode 100644 libs/luabind/luabind/detail/compute_score.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/conversion_base.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/conversion_policies.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/enum_converter.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/function_converter.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/lua_proxy_converter.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/native_converter.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/pointer_converter.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/reference_converter.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/value_converter.hpp delete mode 100644 libs/luabind/luabind/detail/convert_to_lua.hpp create mode 100644 libs/luabind/luabind/detail/crtp_iterator.hpp delete mode 100644 libs/luabind/luabind/detail/has_get_pointer.hpp delete mode 100644 libs/luabind/luabind/detail/is_indirect_const.hpp create mode 100644 libs/luabind/luabind/detail/meta.hpp create mode 100644 libs/luabind/luabind/detail/object.hpp delete mode 100644 libs/luabind/luabind/detail/object_funs.hpp rename libs/luabind/luabind/detail/{calc_arity.hpp => push_to_lua.hpp} (53%) create mode 100644 libs/luabind/luabind/detail/type_traits.hpp delete mode 100644 libs/luabind/luabind/detail/typetraits.hpp rename libs/luabind/luabind/{detail/pointee_typeid.hpp => error_callback_fun.hpp} (63%) rename libs/luabind/luabind/{detail/pointee_sizeof.hpp => function_introspection.hpp} (57%) create mode 100644 libs/luabind/luabind/lua_argument_proxy.hpp create mode 100644 libs/luabind/luabind/lua_index_proxy.hpp create mode 100644 libs/luabind/luabind/lua_iterator_proxy.hpp rename libs/luabind/luabind/{detail/most_derived.hpp => lua_proxy.hpp} (64%) create mode 100644 libs/luabind/luabind/lua_proxy_interface.hpp rename libs/luabind/luabind/{get_pointer.hpp => lua_state_fwd.hpp} (77%) create mode 100644 libs/luabind/luabind/no_dependency.hpp create mode 100644 libs/luabind/luabind/pointer_traits.hpp rename libs/luabind/luabind/{lua502.hpp => set_package_preload.hpp} (56%) delete mode 100644 libs/luabind/luabind/value_wrapper.hpp create mode 100644 libs/luabind/src/CMakeLists.txt create mode 100644 libs/luabind/src/function_introspection.cpp create mode 100644 libs/luabind/src/headertest.cpp rename libs/luabind/{luabind/detail/yes_no.hpp => src/operator.cpp} (81%) create mode 100644 libs/luabind/src/set_package_preload.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ad551966..0fe7680e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -323,13 +323,7 @@ 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") - - FIND_PACKAGE(Boost REQUIRED) - INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}" "${Boost_INCLUDE_DIRS}") + INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}") 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) diff --git a/libs/luabind/CMakeLists.txt b/libs/luabind/CMakeLists.txt index de3b60c61..48a120400 100644 --- a/libs/luabind/CMakeLists.txt +++ b/libs/luabind/CMakeLists.txt @@ -1,38 +1,61 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +# Build for LuaBind +# Ryan Pavlik +# http://academic.cleardefinition.com/ +# Iowa State University HCI Graduate Program/VRAC -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 +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_headers +add_subdirectory(src) -) +if(BUILD_TESTING) + add_subdirectory(test) +endif() -ADD_LIBRARY(luabind ${lb_sources} ${lb_headers}) +if(LUABIND_BUILD_DOCS) + add_subdirectory(doc) +endif() - -IF(UNIX) - set_source_files_properties(${lb_sources} PROPERTY COMPILE_FLAGS -Wno-deprecated-declarations) -ENDIF(UNIX) - -IF(MSVC) - set_source_files_properties(${lb_sources} PROPERTY COMPILE_FLAGS " /W0 " ) -ENDIF(MSVC) - -SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) diff --git a/libs/luabind/CMakeSettings.json b/libs/luabind/CMakeSettings.json new file mode 100644 index 000000000..d85358021 --- /dev/null +++ b/libs/luabind/CMakeSettings.json @@ -0,0 +1,54 @@ +{ + "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" + } + ] + } + ] +} diff --git a/libs/luabind/luabind/adopt_policy.hpp b/libs/luabind/luabind/adopt_policy.hpp index 5e81b948b..3f4751cc3 100644 --- a/libs/luabind/luabind/adopt_policy.hpp +++ b/libs/luabind/luabind/adopt_policy.hpp @@ -28,114 +28,111 @@ #include #include #include -#include -#include -namespace luabind { namespace detail -{ - template - void adjust_backref_ownership(T* ptr, mpl::true_) - { - if (wrap_base* p = dynamic_cast(ptr)) - { - wrapped_self_t& wrapper = wrap_access::ref(*p); - wrapper.get(wrapper.state()); - wrapper.m_strong_ref.set(wrapper.state()); - } - } +namespace luabind { + namespace detail { - inline void adjust_backref_ownership(void*, mpl::false_) - {} - - template - struct adopt_pointer : pointer_converter - { - typedef adopt_pointer type; - - int const consumed_args(...) - { - return 1; - } - - template - T* apply(lua_State* L, by_pointer, int index) + template + void adjust_backref_ownership(T* ptr, std::true_type) { - T* ptr = pointer_converter::apply( - L, LUABIND_DECORATE_TYPE(T*), index); - - object_rep* obj = static_cast( - lua_touserdata(L, index)); - obj->release(); - - adjust_backref_ownership(ptr, boost::is_polymorphic()); - - return ptr; - } - - template - int match(lua_State* L, by_pointer, int index) - { - return pointer_converter::match( - L, LUABIND_DECORATE_TYPE(T*), index); - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - - template<> - struct adopt_pointer - { - typedef adopt_pointer type; - - template - void apply(lua_State* L, T* ptr) - { - if (ptr == 0) + if(wrap_base* p = dynamic_cast(ptr)) { - lua_pushnil(L); - return; + wrapped_self_t& wrapper = wrap_access::ref(*p); + wrapper.get(wrapper.state()); + wrapper.m_strong_ref.set(wrapper.state()); + } + } + + inline void adjust_backref_ownership(void*, std::false_type) + {} + + template + struct adopt_pointer : pointer_converter + { + using type = adopt_pointer; + + enum { consumed_args = 1 }; + + template + T* to_cpp(lua_State* L, by_pointer, int index) + { + T* ptr = pointer_converter::to_cpp(L, decorate_type_t(), index); + + object_rep* obj = static_cast(lua_touserdata(L, index)); + obj->release(); + + adjust_backref_ownership(ptr, std::is_polymorphic()); + + return ptr; } - // if there is a back_reference, then the - // ownership will be removed from the - // back reference and put on the lua stack. - if (luabind::move_back_reference(L, ptr)) - return; + template + int match(lua_State* L, by_pointer, int index) + { + return pointer_converter::match(L, decorate_type_t(), index); + } - make_instance(L, std::auto_ptr(ptr)); - } - }; - - template -// struct adopt_policy : converter_policy_tag - struct adopt_policy : conversion_policy - { -// 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 - struct apply - { - typedef luabind::detail::is_nonconst_pointer is_nonconst_p; - typedef typename boost::mpl::if_, only_accepts_nonconst_pointers>::type type; + template + void converter_postcall(lua_State*, T, int) {} }; - }; -}} + template + struct pointer_or_default + { + using type = Pointer; + }; + + template + struct pointer_or_default + { + using type = std::unique_ptr; + }; + + template + struct adopt_pointer + { + using type = adopt_pointer; + + template + void to_lua(lua_State* L, T* ptr) + { + if(ptr == 0) + { + lua_pushnil(L); + return; + } + + // if there is a back_reference, then the + // ownership will be removed from the + // back reference and put on the lua stack. + if(luabind::move_back_reference(L, ptr)) + return; + + using pointer_type = typename pointer_or_default::type; + + make_pointer_instance(L, pointer_type(ptr)); + } + }; + + template + struct adopt_policy_impl + { + template + struct specialize + { + static_assert(detail::is_nonconst_pointer::value, "Adopt policy only accepts non-const pointers"); + using type = adopt_pointer; + }; + }; + + } +} namespace luabind { - template - detail::policy_cons, detail::null_type> - adopt(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons, detail::null_type>(); - } + // Caution: if we use the aliased type "policy_list" here, MSVC crashes. + template + using adopt_policy = meta::type_list>>; } #endif // LUABIND_ADOPT_POLICY_HPP_INCLUDE diff --git a/libs/luabind/luabind/back_reference.hpp b/libs/luabind/luabind/back_reference.hpp index 5027618fb..1635c047f 100644 --- a/libs/luabind/luabind/back_reference.hpp +++ b/libs/luabind/luabind/back_reference.hpp @@ -23,88 +23,86 @@ #ifndef LUABIND_BACK_REFERENCE_040510_HPP #define LUABIND_BACK_REFERENCE_040510_HPP -#include +#include +#include +#include + +#if !defined(LUABIND_NO_RTTI) && !defined(LUABIND_WRAPPER_BASE_HPP_INCLUDED) #include -#include -#include -#include -#include -#include +#endif + +#include namespace luabind { + struct wrap_base; -namespace detail -{ - namespace mpl = boost::mpl; - - template - wrap_base const* get_back_reference_aux0(T const* p, mpl::true_) - { - return dynamic_cast(p); - } + namespace detail + { + template + wrap_base const* get_back_reference_aux0(T const* p, std::true_type) + { + return dynamic_cast(p); + } - template - wrap_base const* get_back_reference_aux0(T const*, mpl::false_) - { - return 0; - } + template + wrap_base const* get_back_reference_aux0(T const*, std::false_type) + { + return 0; + } - template - wrap_base const* get_back_reference_aux1(T const* p) - { - return get_back_reference_aux0(p, boost::is_polymorphic()); - } + template + wrap_base const* get_back_reference_aux1(T const* p) + { + return get_back_reference_aux0(p, std::is_polymorphic()); + } - template - wrap_base const* get_back_reference_aux2(T const& x, mpl::true_) - { - return get_back_reference_aux1(get_pointer(x)); - } + template + wrap_base const* get_back_reference_aux2(T const& x, std::true_type) + { + return get_back_reference_aux1(get_pointer(x)); + } - template - wrap_base const* get_back_reference_aux2(T const& x, mpl::false_) - { - return get_back_reference_aux1(&x); - } + template + wrap_base const* get_back_reference_aux2(T const& x, std::false_type) + { + return get_back_reference_aux1(&x); + } - template - wrap_base const* get_back_reference(T const& x) - { - return detail::get_back_reference_aux2( - x - , has_get_pointer() - ); - } - -} // namespace detail + template + wrap_base const* get_back_reference(T const& x) + { + return detail::get_back_reference_aux2(x, has_get_pointer()); + } -template -bool get_back_reference(lua_State* L, T const& x) -{ + } // namespace detail + + template + bool get_back_reference(lua_State* L, T const& x) + { #ifndef LUABIND_NO_RTTI - if (wrap_base const* w = detail::get_back_reference(x)) - { - detail::wrap_access::ref(*w).get(L); - return true; - } + if(wrap_base const* w = detail::get_back_reference(x)) + { + detail::wrap_access::ref(*w).get(L); + return true; + } #endif - return false; -} + return false; + } -template -bool move_back_reference(lua_State* L, T const& x) -{ + template + bool move_back_reference(lua_State* L, T const& x) + { #ifndef LUABIND_NO_RTTI - if (wrap_base* w = const_cast(detail::get_back_reference(x))) - { - assert(detail::wrap_access::ref(*w).m_strong_ref.is_valid()); - detail::wrap_access::ref(*w).get(L); - detail::wrap_access::ref(*w).m_strong_ref.reset(); - return true; - } + if(wrap_base* w = const_cast(detail::get_back_reference(x))) + { + assert(detail::wrap_access::ref(*w).m_strong_ref.is_valid()); + detail::wrap_access::ref(*w).get(L); + detail::wrap_access::ref(*w).m_strong_ref.reset(); + return true; + } #endif - return false; -} + return false; + } } // namespace luabind diff --git a/libs/luabind/luabind/back_reference_fwd.hpp b/libs/luabind/luabind/back_reference_fwd.hpp index ffe141dba..85cb4478e 100644 --- a/libs/luabind/luabind/back_reference_fwd.hpp +++ b/libs/luabind/luabind/back_reference_fwd.hpp @@ -23,13 +23,15 @@ #ifndef LUABIND_BACK_REFERENCE_FWD_040510_HPP #define LUABIND_BACK_REFERENCE_FWD_040510_HPP +#include + namespace luabind { -template -bool get_back_reference(lua_State* L, T const& x); + template + bool get_back_reference(lua_State* L, T const& x); -template -bool move_back_reference(lua_State* L, T const& x); + template + bool move_back_reference(lua_State* L, T const& x); } // namespace luabind diff --git a/libs/luabind/luabind/class.hpp b/libs/luabind/luabind/class.hpp index 10fb8e03d..320c8065f 100644 --- a/libs/luabind/luabind/class.hpp +++ b/libs/luabind/luabind/class.hpp @@ -52,7 +52,7 @@ TODO: ------------------------------------------------------ - finish smart pointer support + finish smart pointer support * the adopt policy should not be able to adopt pointers to held_types. This must be prohibited. * name_of_type must recognize holder_types and not return "custom" @@ -64,7 +64,7 @@ support the __concat metamethod. This is a bit tricky, since it cannot be treated as a normal operator. It is a binary operator but we want to use the __tostring implementation for both arguments. - + */ #include @@ -75,42 +75,27 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include #include #include -#include +#include // -> object.hpp #include -#include -#include -#include -#include +#include // -> object.hpp #include #include -#include +#include #include -#include #include -#include +#include #include #include #include -#include #include #include +#include +#include #include +#include // to remove the 'this' used in initialization list-warning #ifdef _MSC_VER @@ -118,17 +103,8 @@ #pragma warning(disable: 4355) #endif -namespace boost -{ - - template class shared_ptr; - -} // namespace boost - -namespace luabind -{ - namespace detail - { +namespace luabind { + namespace detail { struct unspecified {}; template struct operator_; @@ -136,96 +112,86 @@ namespace luabind struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr {}; } - template + 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 struct class_; // TODO: this function will only be invoked if the user hasn't defined a correct overload // maybe we should have a static assert in here? inline detail::you_need_to_define_a_get_const_holder_function_for_your_smart_ptr* - get_const_holder(...) + get_const_holder(...) { return 0; } template - boost::shared_ptr* get_const_holder(boost::shared_ptr*) + std::shared_ptr* get_const_holder(std::shared_ptr*) { return 0; } - template < - BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( - LUABIND_MAX_BASES, class A, detail::null_type) - > - struct bases - {}; - typedef bases no_bases; - - namespace detail - { - template - struct is_bases - : mpl::false_ - {}; - - template - struct is_bases > - : mpl::true_ - {}; - - template - struct is_unspecified - : mpl::apply1 - {}; - - template - struct is_unspecified - : mpl::true_ - {}; - - template - struct is_unspecified_mfn - { - template - struct apply - : is_unspecified - {}; - }; - - template - struct get_predicate - { - typedef mpl::protect > type; - }; - - template - struct result_or_default - { - typedef Result type; - }; - - template - struct result_or_default - { - typedef Default type; - }; - - template - struct extract_parameter - { - typedef typename get_predicate::type pred; - typedef typename boost::mpl::find_if::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()] LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); - + struct LUABIND_API create_class { static int stage1(lua_State* L); @@ -252,7 +218,7 @@ namespace luabind private: template void operator,(U const&) const; void operator=(static_scope const&); - + T& self; }; @@ -261,7 +227,7 @@ namespace luabind struct LUABIND_API class_base : scope { public: - class_base(char const* name); + class_base(char const* name); struct base_desc { @@ -270,10 +236,10 @@ namespace luabind }; void init( - type_id const& type, class_id id - , type_id const& wrapped_type, class_id wrapper_id); + type_id const& type, class_id id + , type_id const& wrapped_type, class_id wrapper_id); - void add_base(type_id const& base, cast_function cast); + void add_base(type_id const& base, cast_function cast); void add_member(registration* member); void add_default_member(registration* member); @@ -283,15 +249,15 @@ namespace luabind void add_static_constant(const char* name, int val); void add_inner_scope(scope& s); - void add_cast(class_id src, class_id target, cast_function cast); + void add_cast(class_id src, class_id target, cast_function cast); private: 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 BOOST_MSVC + // 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 # pragma pack(push) # pragma pack(16) # endif @@ -299,574 +265,327 @@ namespace luabind template struct memfun_registration : registration { - memfun_registration(char const* name, F f, Policies const& policies) - : name(name) - , f(f) - , policies(policies) + memfun_registration(char const* name, F f) + : name(name), f(f) {} void register_(lua_State* L) const { - object fn = make_function( - L, f, deduce_signature(f, (Class*)0), policies); - - add_overload( - object(from_stack(L, -1)) - , name - , fn - ); + // 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(), Policies()); + add_overload(object(from_stack(L, -1)), name, fn); } char const* name; F f; - Policies policies; }; -# ifdef BOOST_MSVC +# ifdef _MSC_VER # pragma pack(pop) # endif - template - struct default_pointer - { - typedef P type; - }; + template + struct default_pointer + { + using type = P; + }; - template - struct default_pointer - { - typedef std::auto_ptr type; - }; + template + struct default_pointer + { + using type = std::unique_ptr; + }; - template - struct constructor_registration : registration - { - constructor_registration(Policies const& policies) - : policies(policies) - {} + template + struct constructor_registration : registration + { + constructor_registration() + {} - void register_(lua_State* L) const - { - typedef typename default_pointer::type pointer; + void register_(lua_State* L) const + { + using pointer = typename default_pointer::type; + object fn = make_function(L, construct(), Signature(), Policies()); + add_overload(object(from_stack(L, -1)), "__init", fn); + } + }; - object fn = make_function( - L - , construct(), Signature() - , policies - ); + template + struct reference_result + : std::conditional< std::is_pointer::value || is_primitive::value, T, typename std::add_lvalue_reference< T >::type > + {}; - add_overload( - object(from_stack(L, -1)) - , "__init" - , fn - ); - } + template + struct reference_argument + : std::conditional< std::is_pointer::value || is_primitive::value, T, typename std::add_lvalue_reference< typename std::add_const::type >::type > + {}; - Policies policies; - }; + template + struct inject_dependency_policy + { + using type = typename std::conditional < + is_primitive::value || meta::contains >::value, + Policies, + typename meta::push_back< Policies, call_policy_injector< dependency_policy<0, 1> > >::type + >::type; + }; - template - struct reference_result - : mpl::if_< - mpl::or_, is_primitive > - , T - , typename boost::add_reference::type - > - {}; + template + struct property_registration : registration + { + property_registration(char const* name, Get const& get, Set const& set = null_type()) + : name(name), get(get), set(set) + {} - template - struct inject_dependency_policy - : mpl::if_< - is_primitive - , Policies - , policy_cons, Policies> - > - {}; + template + object make_get(lua_State* L, F const& f, std::false_type /*member_ptr*/) const + { + return make_function(L, f, GetPolicies()); + } - 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 - , 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 + object make_get(lua_State* L, D T::* mem_ptr, std::true_type /*member_ptr*/) const + { + using result_type = typename reference_result::type; + using get_signature = meta::type_list; + using injected_list = typename inject_dependency_policy< D, GetPolicies >::type; - void register_(lua_State* L) const - { - object context(from_stack(L, -1)); - register_aux( - L - , context - , make_get(L, get, boost::is_member_object_pointer()) - , set - ); - } + return make_function(L, access_member_ptr(mem_ptr), get_signature(), injected_list()); + } - template - object make_get(lua_State* L, F const& f, mpl::false_) const - { - return make_function( - L, f, deduce_signature(f, (Class*)0), get_policies); - } + template + object make_set(lua_State* L, F const& f, std::false_type /*member_ptr*/) const + { + return make_function(L, f, deduce_signature_t(), SetPolicies()); + } - template - object make_get(lua_State* L, D T::* mem_ptr, mpl::true_) const - { - typedef typename reference_result::type result_type; - typedef typename inject_dependency_policy< - D, GetPolicies>::type policies; + template + object make_set(lua_State* L, D T::* mem_ptr, std::true_type /*member_ptr*/) const + { + using argument_type = typename reference_argument::type; + using signature_type = meta::type_list; - return make_function( - L - , access_member_ptr(mem_ptr) - , mpl::vector2() - , policies() - ); - } + return make_function(L, access_member_ptr(mem_ptr), signature_type(), SetPolicies()); + } - template - object make_set(lua_State* L, F const& f, mpl::false_) const - { - return make_function( - L, f, deduce_signature(f, (Class*)0), set_policies); - } + // if a setter was given + template + void register_aux(lua_State* L, object const& context, object const& get_, SetterType const&) const + { + context[name] = property(get_, make_set(L, set, std::is_member_object_pointer())); + } - template - object make_set(lua_State* L, D T::* mem_ptr, mpl::true_) const - { - return make_function( - L - , access_member_ptr(mem_ptr) - , mpl::vector3() - , set_policies - ); - } + // if no setter was given + void register_aux(lua_State*, object const& context, object const& get_, null_type) const + { + context[name] = property(get_); + } - template - 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()) - ); - } + // 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()), set); + } - void register_aux( - lua_State*, object const& context - , object const& get_, null_type) const - { - context[name] = property(get_); - } - char const* name; - Get get; - GetPolicies get_policies; - Set set; - SetPolicies set_policies; - }; + char const* name; + Get get; + Set set; + }; } // namespace detail // registers a class in the lua environment - template - struct class_: detail::class_base + template + struct class_ + : detail::class_base { - typedef class_ self_t; + using self_t = class_; + using BaseList = make_bases< BaseOrBases >; - private: - - template - class_(const class_&); public: - - typedef boost::mpl::vector4 parameters_type; - - // WrappedType MUST inherit from T - typedef typename detail::extract_parameter< - parameters_type - , boost::is_base_and_derived - , detail::null_type - >::type WrappedType; - - typedef typename detail::extract_parameter< - parameters_type - , boost::mpl::not_< - boost::mpl::or_< - detail::is_bases - , boost::is_base_and_derived - , boost::is_base_and_derived - > - > - , detail::null_type - >::type HeldType; - - template - void add_downcast(Src*, Target*, boost::mpl::true_) - { - add_cast( - detail::registered_class::id - , detail::registered_class::id - , detail::dynamic_cast_::execute - ); - } - - template - 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 - void gen_base_info(detail::type_) - { - add_base(typeid(To), detail::static_cast_::execute); - add_cast( - detail::registered_class::id - , detail::registered_class::id - , detail::static_cast_::execute - ); - - add_downcast((To*)0, (T*)0, boost::is_polymorphic()); - } - - void gen_base_info(detail::type_) - {} - -#define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_()); - - template - void generate_baseclass_list(detail::type_ >) - { - BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _) - } - -#undef LUABIND_GEN_BASE_INFO - - class_(const char* name): class_base(name), scope(*this) + class_(const char* name) : class_base(name), scope(*this) { #ifndef NDEBUG detail::check_link_compatibility(); #endif - init(); - } - - template - class_& def(const char* name, F f) - { - return this->virtual_def( - name, f, detail::null_type() - , detail::null_type(), boost::mpl::true_()); + init(); } // virtual functions - template - class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies) + template + class_& def(char const* name, F fn, policy_list< Injectors... > policies = no_policies()) { - return this->virtual_def( - name, fn, default_or_policies, detail::null_type() - , LUABIND_MSVC_TYPENAME detail::is_policy_cons::type()); + return this->virtual_def(name, fn, policies, null_type()); } - template - class_& def(char const* name, F fn - , Default default_, Policies const& policies) + // IntelliSense bug squiggles the code, but it does compile! + template + class_& def_nonconst(char const* name, Ret(C::*fn)(Args...), policy_list policies = no_policies()) { - return this->virtual_def( - name, fn, default_ - , policies, boost::mpl::false_()); + return def(name, fn, policies); } - template - class_& def(constructor sig) + // IntelliSense bug squiggles the code, but it does compile! + template + class_& def_const(char const* name, Ret(C::*fn)(Args...) const, policy_list policies = no_policies()) { - return this->def_constructor(&sig, detail::null_type()); + return def(name, fn, policies); } - template - class_& def(constructor sig, const Policies& policies) + template + class_& def(char const* name, F fn, Default default_, policy_list< Injectors... > policies = no_policies()) { - return this->def_constructor(&sig, policies); + return this->virtual_def(name, fn, policies, default_); } - template - class_& property(const char* name, Getter g) - { - this->add_member( - new detail::property_registration( - name, g, detail::null_type())); - return *this; - } - - template - class_& property(const char* name, Getter g, MaybeSetter s) - { - return property_impl( - name, g, s - , boost::mpl::bool_::value>() - ); - } - - template - class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies) - { - 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; - } - - template - class_& property( - const char* name - , Getter g, Setter s - , GetPolicies const& get_policies - , SetPolicies const& set_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_& def_readonly(const char* name, D C::*mem_ptr) - { - typedef detail::property_registration - registration_type; - - this->add_member( - new registration_type(name, mem_ptr, detail::null_type())); - return *this; - } - - template - class_& def_readonly(const char* name, D C::*mem_ptr, Policies const& policies) - { - typedef detail::property_registration - registration_type; - - this->add_member( - new registration_type(name, mem_ptr, policies)); - return *this; - } - - template - 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_& 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_& 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_& def(detail::operator_, Policies const& policies) + template + class_& def(constructor sig, policy_list< Injectors... > policies = no_policies()) { - return this->def( - Derived::name() - , &Derived::template apply::execute - , policies - ); + return this->def_constructor(sig, policies); } - template - class_& def(detail::operator_) + // ====================== + // Start of reworked property overloads + // ====================== + + template + class_& property(const char* name, Getter g, policy_list< Injectors... > get_injectors = no_policies()) { - return this->def( - Derived::name() - , &Derived::template apply::execute - ); + return property(name, g, null_type(), get_injectors); + } + + template + class_& property(const char* name, Getter g, Setter s, policy_list = no_policies(), policy_list = no_policies()) + { + using registration_type = detail::property_registration, Setter, policy_list>; + this->add_member(new registration_type(name, g, s)); + return *this; + } + + template + class_& def_readonly(const char* name, D C::*mem_ptr, policy_list policies = no_policies()) + { + return property(name, mem_ptr, policies); + } + + template + class_& def_readwrite(const char* name, D C::*mem_ptr, policy_list get_injectors = no_policies(), policy_list set_injectors = no_policies()) + { + return property(name, mem_ptr, mem_ptr, get_injectors, set_injectors); + } + + // ===================== + // End of reworked property overloads + // ===================== + + template + class_& def(detail::operator_, policy_list policies = no_policies()) + { + using policy_list_type = policy_list; + return this->def(Derived::name(), &Derived::template apply::execute, policies); } detail::enum_maker enum_(const char*) { return detail::enum_maker(*this); } - + detail::static_scope scope; - + private: - void operator=(class_ const&); - - void add_wrapper_cast(detail::null_type*) - {} - - template - void add_wrapper_cast(U*) - { - add_cast( - detail::registered_class::id - , detail::registered_class::id - , detail::static_cast_::execute - ); - - add_downcast((T*)0, (U*)0, boost::is_polymorphic()); - } - void init() { - typedef typename detail::extract_parameter< - parameters_type - , boost::mpl::or_< - detail::is_bases - , boost::is_base_and_derived - > - , no_bases - >::type bases_t; - - typedef typename - boost::mpl::if_ - , bases_t - , bases - >::type Base; - - class_base::init( - typeid(T) - , detail::registered_class::id - , typeid(WrappedType) - , detail::registered_class::id - ); - - add_wrapper_cast((WrappedType*)0); - - generate_baseclass_list(detail::type_()); + class_base::init(typeid(T), detail::registered_class::id, typeid(WrapperType), detail::registered_class::id); + add_wrapper_cast((WrapperType*)0); + generate_baseclass_list(); } - template - class_& property_impl(const char* name, - Getter g, - GetPolicies policies, - boost::mpl::bool_) + + template + class_(const class_&); + + template + void add_downcast(Src*, Target*, std::true_type) { - this->add_member( - new detail::property_registration( - name, g, policies)); - return *this; + add_cast(detail::registered_class::id, detail::registered_class::id, detail::dynamic_cast_::execute); } - template - class_& property_impl(const char* name, - Getter g, - Setter s, - boost::mpl::bool_) - { - typedef detail::property_registration< - T, Getter, detail::null_type, Setter, detail::null_type - > registration_type; + template + void add_downcast(Src*, Target*, std::false_type) + {} - this->add_member( - new registration_type(name, g, detail::null_type(), s)); - return *this; + // this function generates conversion information + // in the given class_rep structure. It will be able + // to implicitly cast to the given template type + template + void gen_base_info(bases) + { + add_base(typeid(Class0), detail::static_cast_::execute); + add_cast(detail::registered_class::id, detail::registered_class::id, detail::static_cast_::execute); + add_downcast((Class0*)0, (T*)0, std::is_polymorphic()); + gen_base_info(bases()); + } + + void gen_base_info(bases<>) + { + } + + void generate_baseclass_list() + { + gen_base_info(BaseList()); + } + + void operator=(class_ const&); + + void add_wrapper_cast(null_type*) + {} + + template + void add_wrapper_cast(U*) + { + add_cast(detail::registered_class::id, detail::registered_class::id, detail::static_cast_::execute); + add_downcast((T*)0, (U*)0, std::is_polymorphic()); } // these handle default implementation of virtual functions - template - class_& virtual_def(char const* name, F const& fn - , Policies const&, detail::null_type, boost::mpl::true_) + template + class_& virtual_def(char const* name, F const& fn, policy_list< Injectors... >, Default default_) { - this->add_member( - new detail::memfun_registration( - name, fn, Policies())); + using policy_list_type = policy_list< Injectors... >; + this->add_member(new detail::memfun_registration(name, fn)); + this->add_default_member(new detail::memfun_registration(name, default_)); return *this; } - template - class_& virtual_def(char const* name, F const& fn - , Default const& default_, Policies const&, boost::mpl::false_) + template + class_& virtual_def(char const* name, F const& fn, policy_list< Injectors... >, null_type) { - this->add_member( - new detail::memfun_registration( - name, fn, Policies())); - - this->add_default_member( - new detail::memfun_registration( - name, default_, Policies())); - + using policy_list_type = policy_list< Injectors... >; + this->add_member(new detail::memfun_registration(name, fn)); return *this; } - template - class_& def_constructor(Signature*, Policies const&) - { - typedef typename Signature::signature signature; + template + class_& def_constructor(constructor const&, policy_list< Injectors... > const&) + { + using signature_type = meta::type_list; + using policy_list_type = policy_list< Injectors... >; - typedef typename boost::mpl::if_< - boost::is_same - , T - , WrappedType - >::type construct_type; + using construct_type = typename std::conditional< + is_null_type::value, + T, + WrapperType + >::type; - this->add_member( - new detail::constructor_registration< - construct_type, HeldType, signature, Policies>( - Policies())); + using registration_type = detail::constructor_registration; + this->add_member(new registration_type()); + this->add_default_member(new registration_type()); - this->add_default_member( - new detail::constructor_registration< - construct_type, HeldType, signature, Policies>( - Policies())); - - return *this; - } + return *this; + } }; } diff --git a/libs/luabind/luabind/class_info.hpp b/libs/luabind/luabind/class_info.hpp index a4f18a8cc..d779f250b 100644 --- a/libs/luabind/luabind/class_info.hpp +++ b/libs/luabind/luabind/class_info.hpp @@ -20,7 +20,6 @@ // 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 @@ -32,16 +31,16 @@ namespace luabind { struct LUABIND_API class_info - { + { std::string name; object methods; object attributes; }; - LUABIND_API class_info get_class_info(argument const&); + LUABIND_API class_info get_class_info(argument const&); - // returns a table of bound class names - LUABIND_API object get_class_names(lua_State* L); + // returns a table of bound class names + LUABIND_API object get_class_names(lua_State* L); LUABIND_API void bind_class_info(lua_State*); } diff --git a/libs/luabind/luabind/config.hpp b/libs/luabind/luabind/config.hpp index e8eea875c..e91c867de 100644 --- a/libs/luabind/luabind/config.hpp +++ b/libs/luabind/luabind/config.hpp @@ -20,57 +20,26 @@ // 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 - -#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 - -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 10 +#define LUABIND_MAX_ARITY 100 #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 4 +#define LUABIND_MAX_BASES 100 #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 @@ -101,12 +70,18 @@ namespace std // C code has undefined behavior, lua is written in C). #ifdef LUABIND_DYNAMIC_LINK -# ifdef BOOST_WINDOWS +# if defined (_WIN32) # 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"))) @@ -118,9 +93,19 @@ namespace std # 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(); + LUABIND_API void disable_super_deprecation(); + + namespace detail { + const int max_argument_count = 100; + const int max_hierarchy_depth = 100; + } + + const int no_match = -(detail::max_argument_count*detail::max_hierarchy_depth + 1); } // namespace luabind diff --git a/libs/luabind/luabind/container_policy.hpp b/libs/luabind/luabind/container_policy.hpp index 68ad0a90f..460096abb 100644 --- a/libs/luabind/luabind/container_policy.hpp +++ b/libs/luabind/luabind/container_policy.hpp @@ -20,124 +20,111 @@ // 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 #include -#include +#include // for decorated_type +#include // for null_type (ptr only), etc -namespace luabind { namespace detail { +namespace luabind { + namespace detail { - namespace mpl = boost::mpl; - - template - struct container_converter_lua_to_cpp - { - int const consumed_args(...) - { - return 1; - } - - template - T apply(lua_State* L, by_const_reference, int index) + template + struct container_converter_lua_to_cpp { - typedef typename T::value_type value_type; + enum { consumed_args = 1 }; - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - T container; - - lua_pushnil(L); - while (lua_next(L, index)) + template + T to_cpp(lua_State* L, by_const_reference, int index) { - container.push_back(converter.apply(L, LUABIND_DECORATE_TYPE(value_type), -1)); - lua_pop(L, 1); // pop value + using value_type = typename T::value_type; + specialized_converter_policy_n<1, Policies, value_type, lua_to_cpp> converter; + + T container; + + lua_pushnil(L); + while(lua_next(L, index - 1)) + { + container.push_back(converter.apply(L, decorated_type(), -1)); + lua_pop(L, 1); // pop value + } + + return container; } - return container; - } - - template - T apply(lua_State* L, by_value, int index) - { - return apply(L, by_const_reference(), index); - } - - template - static int match(lua_State* L, by_const_reference, int index) - { - if (lua_istable(L, index)) return 0; else return -1; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - - template - struct container_converter_cpp_to_lua - { - template - void apply(lua_State* L, const T& container) - { - typedef typename T::value_type value_type; - - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - lua_newtable(L); - - int index = 1; - - for (typename T::const_iterator i = container.begin(); i != container.end(); ++i) + template + T to_cpp(lua_State* L, by_value, int index) { - converter.apply(L, *i); - lua_rawseti(L, -2, index); - ++index; + return to_cpp(L, by_const_reference(), index); } - } - }; - template -// struct container_policy : converter_policy_tag - struct container_policy : conversion_policy - { -// BOOST_STATIC_CONSTANT(int, index = N); + template + static int match(lua_State* L, by_const_reference, int index) + { + if(lua_istable(L, index)) return 0; else return no_match; + } - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} + template + static int match(lua_State* L, by_value, int index) + { + return match(L, by_const_reference(), index); + } - struct only_accepts_nonconst_pointers {}; - - template - struct apply - { - typedef typename boost::mpl::if_ - , container_converter_lua_to_cpp - , container_converter_cpp_to_lua - >::type type; + template + void converter_postcall(lua_State*, T, int) {} }; - }; -}} + template + struct container_converter_cpp_to_lua + { + template + void to_lua(lua_State* L, const T& container) + { + using value_type = typename T::value_type; + specialized_converter_policy_n<1, Policies, value_type, lua_to_cpp> converter; -namespace luabind -{ - template - detail::policy_cons, detail::null_type> - container(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons, detail::null_type>(); - } + lua_newtable(L); + + int index = 1; + + for(const auto& element : container) + { + converter.apply(L, element); + lua_rawseti(L, -2, index); + ++index; + } + } + }; + + template + struct container_policy + { + struct only_accepts_nonconst_pointers {}; + + template + struct specialize; + + template + struct specialize { + using type = container_converter_lua_to_cpp; + }; + + template + struct specialize { + using type = container_converter_cpp_to_lua; + }; + }; - template - detail::policy_cons, detail::null_type> - container(LUABIND_PLACEHOLDER_ARG(N), const Policies&) - { - return detail::policy_cons, detail::null_type>(); } } +namespace luabind +{ + template + using container_policy = meta::type_list>>; +} + #endif // LUABIND_CONTAINER_POLICY_HPP_INCLUDED + diff --git a/libs/luabind/luabind/copy_policy.hpp b/libs/luabind/luabind/copy_policy.hpp index 1a18b729b..7115a4511 100644 --- a/libs/luabind/luabind/copy_policy.hpp +++ b/libs/luabind/luabind/copy_policy.hpp @@ -8,52 +8,41 @@ # include namespace luabind { + namespace detail { -namespace detail -{ + struct copy_converter + { + template + void to_lua(lua_State* L, T const& x) + { + value_converter().to_lua(L, x); + } - struct copy_converter - { - template - void apply(lua_State* L, T const& x) - { - value_converter().apply(L, x); - } + template + void to_lua(lua_State* L, T* x) + { + if(!x) + lua_pushnil(L); + else + to_lua(L, *x); + } + }; - template - void apply(lua_State* L, T* x) - { - if (!x) - lua_pushnil(L); - else - apply(L, *x); - } - }; + struct copy_policy + { + template + struct specialize + { + static_assert(std::is_same::value, "Copy policy only supports cpp -> lua"); + using type = copy_converter; + }; + }; - template - struct copy_policy : conversion_policy - { - static void precall(lua_State*, index_map const&) - {} + } // namespace detail - static void postcall(lua_State*, index_map const&) - {} - - template - struct apply - { - typedef copy_converter type; - }; - }; - -} // namespace detail - -template -detail::policy_cons, detail::null_type> -copy(LUABIND_PLACEHOLDER_ARG(N)) -{ - return detail::policy_cons, detail::null_type>(); -} + // 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 > >; } // namespace luabind diff --git a/libs/luabind/luabind/dependency_policy.hpp b/libs/luabind/luabind/dependency_policy.hpp index cafa49aa1..c16db1605 100644 --- a/libs/luabind/luabind/dependency_policy.hpp +++ b/libs/luabind/luabind/dependency_policy.hpp @@ -25,95 +25,75 @@ #define LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED #include -#include +#include // for policy_cons, etc +#include // for object_rep +#include // for null_type -namespace luabind { namespace detail -{ - // makes A dependent on B, meaning B will outlive A. - // internally A stores a reference to B - template - struct dependency_policy - { - static void postcall(lua_State* L, const index_map& indices) +namespace luabind { + namespace detail { + + // makes A dependent on B, meaning B will outlive A. + // internally A stores a reference to B + template + struct dependency_policy { - int nurse_index = indices[A]; - int patient = indices[B]; + template< unsigned int... StackIndices > + static void postcall(lua_State* L, int results, meta::index_list) + { + object_rep* nurse = static_cast(lua_touserdata(L, meta::get, A>::value)); - object_rep* nurse = static_cast(lua_touserdata(L, nurse_index)); + // If the nurse isn't an object_rep, just make this a nop. + if(nurse == 0) + return; - // If the nurse isn't an object_rep, just make this a nop. - if (nurse == 0) - return; - - nurse->add_dependency(L, patient); - } - }; - -}} - -#if defined (BOOST_MSVC) && (BOOST_MSVC <= 1200) - -namespace luabind -{ - // most absurd workaround of all time? - namespace detail - { - template - struct size_char_array - { - char storage[N + 2]; + nurse->add_dependency(L, meta::get, B>::value); + } }; - template - size_char_array deduce_size(LUABIND_PLACEHOLDER_ARG(N)); - - template - struct get_index_workaround + template + struct dependency_policy<0, B> { - static T t; - BOOST_STATIC_CONSTANT(int, value = sizeof(deduce_size(t)) - 2); + template< unsigned int... StackIndices > + static void postcall(lua_State* L, int results, meta::index_list) + { + object_rep* nurse = static_cast(lua_touserdata(L, meta::get, 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, B>::value); + } }; - } - template - detail::policy_cons::value - , detail::get_index_workaround::value>, detail::null_type> dependency(A,B) - { - return detail::policy_cons::value, detail::get_index_workaround::value> - , detail::null_type>(); - } + template + struct dependency_policy + { + template< unsigned int... StackIndices > + static void postcall(lua_State* L, int results, meta::index_list) + { + object_rep* nurse = static_cast(lua_touserdata(L, meta::get, 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, 0>::value + results); + } + }; - template - detail::policy_cons::value>, detail::null_type> - return_internal_reference(A) - { - return detail::policy_cons::value>, detail::null_type>(); } } -#else - namespace luabind { - template - detail::policy_cons, detail::null_type> - dependency(LUABIND_PLACEHOLDER_ARG(A), LUABIND_PLACEHOLDER_ARG(B)) - { - return detail::policy_cons, detail::null_type>(); - } + // Caution: If we use the aliased type "policy_list" here, MSVC crashes. + template + using dependency_policy = meta::type_list>>; - template - detail::policy_cons, detail::null_type> - return_internal_reference(LUABIND_PLACEHOLDER_ARG(A)) - { - return detail::policy_cons, detail::null_type>(); - } + template + using return_internal_reference = meta::type_list>>; } -#endif - #endif // LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/call.hpp b/libs/luabind/luabind/detail/call.hpp index cd9402ef3..94dbb8d4d 100644 --- a/libs/luabind/luabind/detail/call.hpp +++ b/libs/luabind/luabind/detail/call.hpp @@ -1,323 +1,547 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is +// Copyright Daniel Wallin 208.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) -#if !BOOST_PP_IS_ITERATING +#ifndef LUABIND_CALL2_080911_HPP +#define LUABIND_CALL2_080911_HPP -# ifndef LUABIND_CALL2_080911_HPP -# define LUABIND_CALL2_080911_HPP +#include +#include +#include +#include +#include +#include +#include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include +#ifdef LUABIND_NO_INTERNAL_TAG_ARGUMENTS +#include +#endif -# include -# include -# include +namespace luabind { + namespace detail { -namespace luabind { namespace detail { + struct invoke_context; -struct invoke_context; + struct LUABIND_API function_object + { + function_object(lua_CFunction entry) + : entry(entry) + , next(0) + {} -struct LUABIND_API function_object -{ - function_object(lua_CFunction entry) - : entry(entry) - , next(0) - {} + virtual ~function_object() + {} - virtual ~function_object() - {} + virtual int call(lua_State* L, invoke_context& ctx) /* const */ = 0; + virtual void format_signature(lua_State* L, char const* function) 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; + }; - lua_CFunction entry; - std::string name; - function_object* next; - object keepalive; -}; + struct LUABIND_API invoke_context + { + invoke_context() + : best_score((std::numeric_limits::max)()) + //This need to avoid static analyzer's treats + , candidates{ nullptr,nullptr,nullptr,nullptr,nullptr, + nullptr,nullptr,nullptr,nullptr,nullptr } + , candidate_index(0) + {} -struct LUABIND_API invoke_context -{ - invoke_context() - : best_score((std::numeric_limits::max)()) - , candidate_index(0) - {} + operator bool() const + { + return candidate_index == 1; + } - operator bool() const - { - return candidate_index == 1; - } + void format_error(lua_State* L, function_object const* overloads) const; - 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? + int candidate_index; + }; - int best_score; - function_object const* candidates[10]; - int candidate_index; -}; + namespace call_detail_new { -template -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_::value - 1>(), IsVoid() - ); -} + /* + Compute Stack Indices + Given the list of argument converter arities, computes the stack indices that each converter addresses. + */ -template -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_::value - 1>(), IsVoid() - ); -} + template< typename ConsumedList, unsigned int CurrentSum, unsigned int... StackIndices > + struct compute_stack_indices; -template -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::type>() - , boost::is_member_function_pointer() - ); -} + 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; + }; -inline int maybe_yield_aux(lua_State*, int results, mpl::false_) -{ - return results; -} + template< unsigned int CurrentSum, unsigned int... StackIndices > + struct compute_stack_indices< meta::index_list< >, CurrentSum, StackIndices... > + { + using type = meta::index_list< StackIndices... >; + }; -inline int maybe_yield_aux(lua_State* L, int results, mpl::true_) -{ - return lua_yield(L, results); -} + template< typename Foo > + struct FooFoo { // Foo! + enum { consumed_args = Foo::consumed_args }; + }; -template -int maybe_yield(lua_State* L, int results, Policies*) -{ - return maybe_yield_aux( - L, results, mpl::bool_::value>()); -} -inline int sum_scores(int const* first, int const* last) -{ - int result = 0; + template< typename PolicyList, typename StackIndexList > + struct policy_list_postcall; - for (; first != last; ++first) - { - if (*first < 0) - return *first; - result += *first; - } + template< typename Policy0, typename... Policies, typename StackIndexList > + struct policy_list_postcall< meta::type_list< call_policy_injector, 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); + } + }; - return result; -} + 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()); + } + }; -# define LUABIND_INVOKE_NEXT_ITER(n) \ - typename mpl::next< \ - BOOST_PP_IF( \ - n, BOOST_PP_CAT(iter,BOOST_PP_DEC(n)), first) \ - >::type + template< typename ConverterPolicy, typename StackIndexList > + struct converter_policy_postcall< ConverterPolicy, StackIndexList, false > { + static void postcall(lua_State* /*L*/, int /*results*/) { + } + }; -# 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 \ - ) + 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); + } + }; -# define LUABIND_INVOKE_COMPUTE_ARITY(n) + BOOST_PP_CAT(c,n).consumed_args() + template< typename StackIndexList > + struct policy_list_postcall< meta::type_list< >, StackIndexList > { + static void postcall(lua_State* /*L*/, int /*results*/) {} + }; -# define LUABIND_INVOKE_DECLARE_CONVERTER(n) \ - typedef LUABIND_INVOKE_NEXT_ITER(n) BOOST_PP_CAT(iter,n); \ - typedef typename mpl::deref::type \ - BOOST_PP_CAT(a,n); \ - typedef typename find_conversion_policy::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); +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + template< typename... ArgumentConverters > + struct compute_invoke_values { + using consumed_list = meta::index_list< FooFoo::consumed_args... >; + using stack_index_list = typename compute_stack_indices< consumed_list, 1 >::type; + enum { arity = meta::sum::value }; + }; +#endif -# 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)) -# 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)); +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + inline int match_deferred(lua_State* L, meta::index_list<>, meta::type_list<>) + { + return 0; + } -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() + 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(), StackIndex0); + const int other_match = match_deferred(L, meta::index_list(), meta::type_list(), converters...); + return (this_match >= 0) ? // could also sum them all up unconditionally + this_match + match_deferred(L, meta::index_list(), meta::type_list(), converters...) + : no_match; + } -# define LUABIND_INVOKE_VOID -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() + template< typename T, bool isvoid, bool memfun = std::is_member_function_pointer::value > struct do_call_struct; -# undef LUABIND_INVOKE_VOID -# define LUABIND_INVOKE_MEMBER -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() + 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, meta::type_list, + ReturnConverter& result_converter, Argument0Converter& arg0_converter, ArgumentConverters&... arg_converters + ) + { + ((arg0_converter.to_cpp(L, decorated_type(), StackIndex0)).*f)( + arg_converters.to_cpp(L, decorated_type(), StackIndices)... + ); + } + }; -# define LUABIND_INVOKE_VOID -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() + 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, meta::type_list, + ReturnConverter& result_converter, Argument0Converter& arg0_converter, ArgumentConverters&... arg_converters + ) + { + result_converter.to_lua(L, + ((arg0_converter.to_cpp(L, decorated_type(), StackIndex0)).*f)( + arg_converters.to_cpp(L, decorated_type(), StackIndices)... + ) + ); + } + }; -}} // namespace luabind::detail + + template< typename T > + struct do_call_struct< T, true, false > { + template< + typename F, + typename... ArgumentTypes, unsigned int... StackIndices, + typename ReturnConverter, typename... ArgumentConverters + > + static void do_call(lua_State* L, F& f, + meta::index_list, meta::type_list, + ReturnConverter& result_converter, ArgumentConverters&... arg_converters) + { + f(arg_converters.to_cpp(L, decorated_type(), 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, meta::type_list, + ReturnConverter& result_converter, ArgumentConverters&... arg_converters) + { + result_converter.to_lua(L, + f(arg_converters.to_cpp(L, decorated_type(), StackIndices)...) + ); + } + }; + + template< typename F, typename ReturnType, typename... Arguments, + typename ReturnConverter, typename... ArgumentConverters, + unsigned int Index0, unsigned int... Indices, typename PolicyList + > + int invoke3(lua_State* L, function_object const& self, invoke_context& ctx, F& f, + PolicyList, meta::index_list< Index0, Indices... > index_list, meta::type_list 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; + using argument_index_list = meta::index_list; + + 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::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(), meta::get< typename invoke_values::stack_index_list, Indices - 1 >::value), 0)... }; + + results = lua_gettop(L) - invoke_values::arity; + if(has_call_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 >::type >::postcall(L, results); + } + + return results; + } + + template< typename F, typename ReturnType, typename... Arguments, unsigned int Index0, unsigned int... Indices, typename PolicyList > + int invoke2(lua_State* L, function_object const& self, invoke_context& ctx, F& f, + meta::type_list signature, meta::index_list, PolicyList) + { + using signature_type = meta::type_list; + using return_converter = specialized_converter_policy_n<0, PolicyList, ReturnType, cpp_to_lua>; + return invoke3(L, self, ctx, f, + PolicyList(), meta::index_list(), signature, + return_converter(), specialized_converter_policy_n()... + ); + } + + + template + // 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::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, PolicyList, meta::type_list, Counter > + { + using converter_type = typename policy_detail::get_converter_policy::type; + using this_specialized = typename converter_type::template specialize::type; + using type = typename compute_argument_converter_list, PolicyList, meta::type_list, Counter + 1>::type; + }; + + template + struct compute_argument_converter_list< meta::type_list<>, PolicyList, meta::type_list, Counter > + { + using type = meta::type_list; + }; + + 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::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, PolicyList > + { + using signature_list = meta::type_list; + 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; + + using decorated_argument_list = meta::type_list< decorate_type_t... >; + // 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::type; + using argument_converter_tuple_type = typename meta::make_tuple::type; + using consumed_list = typename build_consumed_list::consumed_list; + using stack_index_list = typename call_detail_new::compute_stack_indices< consumed_list, 1 >::type; + enum { arity = meta::sum::value }; + }; + + template< typename StackIndexList, typename SignatureList, unsigned int End = meta::size::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(tuple).match(L, decorate_type_t>(), meta::get::value); + return this_match >= 0 ? // could also sum them up unconditionally + this_match + match_struct::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 > + { + 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(argument_tuple).to_cpp(L, + typename meta::get::type(), + meta::get::value))... + ) + ); + + meta::init_order{ + (std::get(argument_tuple).converter_postcall(L, + typename meta::get::type(), + meta::get::value), 0)... + }; + } + }; + + template< unsigned int... ArgumentIndices > + struct call_struct< false /*member*/, true /*void*/, meta::index_list > + { + static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple) + { + using decorated_list = typename traits::decorated_argument_list; + using stack_indices = typename traits::stack_index_list; + + // This prevents unused warnings with empty parameter lists + (void)L; + + f(std::get(argument_tuple).to_cpp(L, + typename meta::get::type(), + meta::get::value)... + + ); + + meta::init_order{ + (std::get(argument_tuple).converter_postcall(L, + typename meta::get::type(), + meta::get::value), 0)... + }; + } + }; + + template< unsigned int ClassIndex, unsigned int... ArgumentIndices > + struct call_struct< true /*member*/, false /*void*/, meta::index_list > + { + static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple) + { + using decorated_list = typename traits::decorated_argument_list; + using stack_indices = typename traits::stack_index_list; + using result_converter = typename traits::result_converter; + + auto& object = std::get<0>(argument_tuple).to_cpp(L, + typename meta::get::type(), 1); + + result_converter().to_lua(L, + (object.*f)(std::get(argument_tuple).to_cpp(L, + typename meta::get::type(), + meta::get::value)... + ) + ); + + meta::init_order{ + (std::get(argument_tuple).converter_postcall(L, + typename meta::get::type(), + meta::get::value), 0)... + }; + } + }; + + template< unsigned int ClassIndex, unsigned int... ArgumentIndices > + struct call_struct< true /*member*/, true /*void*/, meta::index_list > + { + 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::type(), 1); + + (object.*f)(std::get(argument_tuple).to_cpp(L, + typename meta::get::type(), + meta::get::value)... + ); + + meta::init_order{ + (std::get(argument_tuple).converter_postcall(L, + typename meta::get::type(), + meta::get::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::value, + std::is_void::value, + typename traits::argument_index_list + >::call(L, f, converter_tuple); + + results = lua_gettop(L) - traits::arity; + if(has_call_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 >::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::invoke(L, self, ctx, f); + } +#endif + + } +} // 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 -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_ -# ifdef LUABIND_INVOKE_VOID - , mpl::true_ -# else - , mpl::false_ -# endif -) -{ - typedef typename mpl::begin::type first; -# ifndef LUABIND_INVOKE_VOID - typedef typename mpl::deref::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::apply(L, indices); - } - - return results; -} - -# undef N - -#endif - diff --git a/libs/luabind/luabind/detail/call_function.hpp b/libs/luabind/luabind/detail/call_function.hpp index e3ac2b761..90a6a4e1b 100644 --- a/libs/luabind/luabind/detail/call_function.hpp +++ b/libs/luabind/luabind/detail/call_function.hpp @@ -20,423 +20,175 @@ // 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include -#include +#include #include +#include +#include namespace luabind { - namespace detail - { - - // if the proxy_function_caller returns non-void - template - 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) - { - } - - 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) - { - rhs.m_called = true; - } - - ~proxy_function_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::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); - } - - operator Ret() - { - typename mpl::apply_wrap2::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::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 - Ret operator[](const Policies& p) - { - typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy; - typename mpl::apply_wrap2::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::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 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::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 - void operator[](const Policies& p) - { - m_called = true; - lua_State* L = m_state; - - int top = lua_gettop(L); - - detail::push_args_from_tuple<1>::apply(L, m_args, p); - if (m_fun(L, boost::tuples::length::value, 0)) - { - assert(lua_gettop(L) == top - m_params + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); -#endif - } - // pops the return values from the function call - stack_pop pop(L, lua_gettop(L) - top + m_params); - } - - private: - - lua_State* m_state; - int m_params; - function_t m_fun; - Tuple m_args; - mutable bool m_called; - - }; - + namespace adl { + class object; } - #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) - #include BOOST_PP_ITERATE() + 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) + { + using converter_type = specialized_converter_policy< fetched_converter_policy, Arg0, cpp_to_lua >; + converter_type().to_lua(L, unwrapped::get(std::forward(arg0))); + push_arguments(L, std::forward(args)...); + } + +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + template + void call_function_impl(lua_State* L, int m_params, Fn fn, std::true_type /* void */, meta::index_list, Args&&... args) + { + int top = lua_gettop(L); + + push_arguments(L, std::forward(args)...); + + if(fn(L, sizeof...(Args), 0)) { + assert(lua_gettop(L) == top - m_params + 1); + call_error(L); + } + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + m_params); + } + + template + Ret call_function_impl(lua_State* L, int m_params, Fn fn, std::false_type /* void */, meta::index_list, Args&&... args) + { + int top = lua_gettop(L); + + push_arguments(L, std::forward(args)...); + + if(fn(L, sizeof...(Args), 1)) { + assert(lua_gettop(L) == top - m_params + 1); + call_error(L); + } + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + m_params); + + specialized_converter_policy_n<0, PolicyList, Ret, lua_to_cpp> converter; + if(converter.match(L, decorate_type_t(), -1) < 0) { + cast_error(L); + } + + return converter.to_cpp(L, decorate_type_t(), -1); + } +#else + template::value> + struct call_function_struct; + + template + struct call_function_struct< Ret, PolicyList, meta::index_list, NumParams, Function, true /* void */ > + { + template< typename... Args > + static void call(lua_State* L, Args&&... args) { + int top = lua_gettop(L); + + push_arguments(L, std::forward(args)...); + + if(Function(L, sizeof...(Args), 0)) { + if(Function == &detail::pcall) { + assert(lua_gettop(L) == static_cast(top - NumParams + 1)); + } + call_error(L); + } + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + NumParams); + } + }; + + template + struct call_function_struct< Ret, PolicyList, meta::index_list, NumParams, Function, false /* void */ > + { + template< typename... Args > + static Ret call(lua_State* L, Args&&... args) { + int top = lua_gettop(L); + + push_arguments(L, std::forward(args)...); + + if(Function(L, sizeof...(Args), 1)) { + if(Function == &detail::pcall) { + assert(lua_gettop(L) == static_cast(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(), -1) < 0) { + cast_error(L); + } + + return converter.to_cpp(L, decorate_type_t(), -1); + } + }; +#endif + } + + template + R call_pushed_function(lua_State* L, Args&&... args) + { +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + return detail::call_function_impl(L, 1, &detail::pcall, std::is_void(), meta::index_range<1, sizeof...(Args)+1>(), std::forward(args)...); +#else + return detail::call_function_struct, 1, &detail::pcall >::call(L, std::forward(args)...); +#endif + } + + template + 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(L, std::forward(args)...); + } + + template + R resume_pushed_function(lua_State* L, Args&&... args) + { +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + return detail::call_function_impl(L, 1, &detail::resume_impl, std::is_void(), meta::index_range<1, sizeof...(Args)+1>(), std::forward(args)...); +#else + return detail::call_function_struct, 1, &detail::resume_impl >::call(L, std::forward(args)...); +#endif + } + + template + 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(L, std::forward(args)...); + } + + template + R resume(lua_State* L, Args&&... args) + { +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + return detail::call_function_impl(L, 0, &detail::resume_impl, std::is_void(), meta::index_range<1, sizeof...(Args)+1>(), std::forward(args)...); +#else + return detail::call_function_struct, 0, &detail::resume_impl >::call(L, std::forward(args)...); +#endif + } } #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 - typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::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 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_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type proxy_type; - - lua_getglobal(L, name); - - return proxy_type(L, 1, &detail::pcall, args); - } - - template - typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::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 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_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type proxy_type; - - obj.push(obj.interpreter()); - return proxy_type(obj.interpreter(), 1, &detail::pcall, args); - } - - template - typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::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 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_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type proxy_type; - - lua_getglobal(L, name); - - return proxy_type(L, 1, &detail::resume_impl, args); - } - - template - typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::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 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_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type proxy_type; - - obj.push(obj.interpreter()); - return proxy_type(obj.interpreter(), 1, &detail::resume_impl, args); - } - - template - typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::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 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_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type proxy_type; - - return proxy_type(L, 0, &detail::resume_impl, args); - } - - -#undef LUABIND_OPERATOR_PARAMS -#undef LUABIND_TUPLE_PARAMS - -#endif -#endif - diff --git a/libs/luabind/luabind/detail/call_member.hpp b/libs/luabind/luabind/detail/call_member.hpp index e63555bc6..23b1bd496 100644 --- a/libs/luabind/luabind/detail/call_member.hpp +++ b/libs/luabind/luabind/detail/call_member.hpp @@ -20,325 +20,82 @@ // 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 -#include +#include #include #include #include -#include // TODO: REMOVE DEPENDENCY - -#include - -#include -#include -#include - -#include +#include +#include namespace luabind { - namespace detail - { + using adl::object; - namespace mpl = boost::mpl; + namespace detail { - // if the proxy_member_caller returns non-void - template - class proxy_member_caller - { -// friend class luabind::object; - public: + template + R call_member_impl(lua_State* L, std::true_type /*void*/, meta::index_list, Args&&... args) + { + // don't count the function and self-reference + // since those will be popped by pcall + int top = lua_gettop(L) - 2; - 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; - - // 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::value + 1, 0)) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - // pops the return values from the function - stack_pop pop(L, lua_gettop(L) - top); - } - - operator Ret() - { - typename mpl::apply_wrap2::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::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 - Ret operator[](const Policies& p) - { - typedef typename find_conversion_policy<0, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - m_called = true; - - // don't count the function and self-reference - // since those will be popped by pcall - int top = lua_gettop(L) - 2; - - // pcall will pop the function and self reference - // and all the parameters - - detail::push_args_from_tuple<1>::apply(L, m_args, p); - if (pcall(L, boost::tuples::length::value + 1, 1)) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - - // pops the return values from the function - stack_pop pop(L, lua_gettop(L) - top); - -#ifndef LUABIND_NO_ERROR_CHECKING - - if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(L, typeid(Ret)); -#else - cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(L, typeid(Ret)); - - assert(0 && "the lua function's return value could not be converted." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } -#endif - return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); - } - - private: - - lua_State* L; - Tuple m_args; - mutable bool m_called; + // pcall will pop the function and self reference + // and all the parameters + meta::init_order{ ( + specialized_converter_policy_n::type, cpp_to_lua>().to_lua(L, unwrapped::get(std::forward(args))), 0)... }; - // if the proxy_member_caller returns void - template - class proxy_member_void_caller + if(pcall(L, sizeof...(Args)+1, 0)) { - friend class luabind::object; - public: + assert(lua_gettop(L) == top + 1); + call_error(L); + } + // pops the return values from the function + stack_pop pop(L, lua_gettop(L) - top); + } - proxy_member_void_caller(lua_State* L_, const Tuple args) - : L(L_) - , m_args(args) - , m_called(false) - { - } + template + R call_member_impl(lua_State* L, std::false_type /*void*/, meta::index_list, Args&&... args) + { + // don't count the function and self-reference + // since those will be popped by pcall + int top = lua_gettop(L) - 2; - 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::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 - 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::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; + // pcall will pop the function and self reference + // and all the parameters + meta::init_order{ ( + specialized_converter_policy_n::type, cpp_to_lua>().to_lua(L, unwrapped::get(std::forward(args))), 0)... }; + if(pcall(L, sizeof...(Args)+1, 1)) + { + assert(lua_gettop(L) == top + 1); + call_error(L); + } + // pops the return values from the function + stack_pop pop(L, lua_gettop(L) - top); + + specialized_converter_policy_n<0, PolicyList, R, lua_to_cpp> converter; + if(converter.match(L, decorate_type_t(), -1) < 0) { + cast_error(L); + } + + return converter.to_cpp(L, decorate_type_t(), -1); + } + + } // detail - #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 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 - typename boost::mpl::if_ - , luabind::detail::proxy_member_void_caller > - , luabind::detail::proxy_member_caller > >::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, _)) + template + R call_member(object const& obj, const char* name, Args&&... args) { - typedef boost::tuples::tuple 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_ - , luabind::detail::proxy_member_void_caller > - , luabind::detail::proxy_member_caller > >::type proxy_type; - // this will be cleaned up by the proxy object // once the call has been made @@ -354,12 +111,17 @@ namespace luabind // now the function and self objects // are on the stack. These will both // be popped by pcall - return proxy_type(obj.interpreter(), args); + + return detail::call_member_impl(obj.interpreter(), std::is_void(), meta::index_range<1, sizeof...(Args)+1>(), std::forward(args)...); } -#undef LUABIND_OPERATOR_PARAMS -#undef LUABIND_TUPLE_PARAMS + template + R call_member(wrap_base const* self, char const* fn, Args&&... args) + { + return self->call(fn, std::forward(args)...); + } -#endif -#endif +} + +#endif // LUABIND_CALL_MEMBER_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/call_operator_iterate.hpp b/libs/luabind/luabind/detail/call_operator_iterate.hpp deleted file mode 100644 index c6f95a10c..000000000 --- a/libs/luabind/luabind/detail/call_operator_iterate.hpp +++ /dev/null @@ -1,66 +0,0 @@ -// 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::type \ - BOOST_PP_CAT(_, n) - -template -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 - struct apply - { - static void execute( - lua_State* L - , typename detail::unwrap_parameter_type::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 - diff --git a/libs/luabind/luabind/detail/object_call.hpp b/libs/luabind/luabind/detail/call_shared.hpp similarity index 51% rename from libs/luabind/luabind/detail/object_call.hpp rename to libs/luabind/luabind/detail/call_shared.hpp index 46ab0d958..9b33973aa 100644 --- a/libs/luabind/luabind/detail/object_call.hpp +++ b/libs/luabind/luabind/detail/call_shared.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2005 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"), @@ -20,33 +20,46 @@ // 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! +#ifndef LUABIND_CALL_SHARED_HPP_INCLUDED +#define LUABIND_CALL_SHARED_HPP_INCLUDED + +namespace luabind { + namespace detail { + + inline void call_error(lua_State* 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 + } -#include -#include -#include + template + void cast_error(lua_State* L) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(L, typeid(T)); +#else + cast_failed_callback_fun e = get_cast_failed_callback(); + if(e) e(L, typeid(T)); -#define N BOOST_PP_ITERATION() + assert(0 && "the lua function's return value could not be converted." + " If you want to handle the error you can use luabind::set_cast_failed_callback()"); + std::terminate(); +#endif + } -template -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; + template< typename... Args > + void expand_hack(Args... /*args*/) + {} - return call_proxy( - derived() - , arguments(BOOST_PP_ENUM_PARAMS(N, &a)) - ); + } } -#undef N - +#endif diff --git a/libs/luabind/luabind/detail/call_traits.hpp b/libs/luabind/luabind/detail/call_traits.hpp new file mode 100644 index 000000000..227e3662e --- /dev/null +++ b/libs/luabind/luabind/detail/call_traits.hpp @@ -0,0 +1,113 @@ +// 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 + struct ct_imp2 + { + using param_type = const T&; + }; + + template + struct ct_imp2 + { + using param_type = const T; + }; + + template + struct ct_imp + { + using param_type = const T&; + }; + + template + struct ct_imp + { + using param_type = typename ct_imp2::param_type; + }; + + template + struct ct_imp + { + using param_type = typename ct_imp2::param_type; + }; + + template + struct ct_imp + { + using param_type = const T; + }; + + template + 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::value, + std::is_integral::value || std::is_floating_point::value, + std::is_enum::value + >::param_type; + }; + + template + struct call_traits + { + using value_type = T&; + using reference = T&; + using const_reference = const T&; + using param_type = T&; + }; + + template + struct call_traits + { + 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 + struct call_traits + { + 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 + diff --git a/libs/luabind/luabind/detail/class_cache.hpp b/libs/luabind/luabind/detail/class_cache.hpp deleted file mode 100644 index f49687c30..000000000 --- a/libs/luabind/luabind/detail/class_cache.hpp +++ /dev/null @@ -1,89 +0,0 @@ -// 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 -#include -#include - -namespace luabind { namespace detail { - -#ifdef LUABIND_NOT_THREADSAFE - - class class_rep; - - template - struct class_cache_impl - { - static lua_State* state; - static class_rep* class_; - }; - - template - lua_State* class_cache_impl::state = 0; - - template - class_rep* class_cache_impl::class_ = 0; - - template - struct class_cache - : class_cache_impl< - typename boost::add_reference< - typename boost::add_const< - T - >::type - >::type - > - { - }; - - template - class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0) - { - if (class_cache::state != L) - { - class_cache::state = L; - - class_registry* registry = class_registry::get_registry(L); - class_cache::class_ = registry->find_class(typeid(T)); - } - - return class_cache::class_; - } - -#else - - template - 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 - diff --git a/libs/luabind/luabind/detail/class_registry.hpp b/libs/luabind/luabind/detail/class_registry.hpp index 12ed03cfe..da0a47080 100644 --- a/libs/luabind/luabind/detail/class_registry.hpp +++ b/libs/luabind/luabind/detail/class_registry.hpp @@ -30,56 +30,58 @@ #include #include -namespace luabind { namespace detail -{ - class class_rep; +namespace luabind { + namespace detail { - struct LUABIND_API class_registry - { - class_registry(lua_State* L); + class class_rep; - static class_registry* get_registry(lua_State* L); + struct LUABIND_API class_registry + { + class_registry(lua_State* L); - int cpp_instance() const { return m_instance_metatable; } - int cpp_class() const { return m_cpp_class_metatable; } + static class_registry* get_registry(lua_State* L); - int lua_instance() const { return m_instance_metatable; } - int lua_class() const { return m_lua_class_metatable; } - int lua_function() const { return m_lua_function_metatable; } + int cpp_instance() const { return m_instance_metatable; } + int cpp_class() const { return m_cpp_class_metatable; } - void add_class(type_id const& info, class_rep* crep); + int lua_instance() const { return m_instance_metatable; } + int lua_class() const { return m_lua_class_metatable; } + int lua_function() const { return m_lua_function_metatable; } - class_rep* find_class(type_id const& info) const; + void add_class(type_id const& info, class_rep* crep); - std::map const& get_classes() const - { - return m_classes; - } + class_rep* find_class(type_id const& info) const; - private: + std::map const& get_classes() const + { + return m_classes; + } - std::map m_classes; + private: - // this is a lua reference that points to the lua table - // that is to be used as meta table for all C++ class - // instances. It is a kind of v-table. - int m_instance_metatable; + std::map m_classes; - // this is a lua reference to the metatable to be used - // for all classes defined in C++. - int m_cpp_class_metatable; + // this is a lua reference that points to the lua table + // that is to be used as meta table for all C++ class + // instances. It is a kind of v-table. + int m_instance_metatable; - // this is a lua reference to the metatable to be used - // for all classes defined in lua - int m_lua_class_metatable; + // this is a lua reference to the metatable to be used + // for all classes defined in C++. + int m_cpp_class_metatable; - // this metatable only contains a destructor - // for luabind::Detail::free_functions::function_rep - int m_lua_function_metatable; + // this is a lua reference to the metatable to be used + // for all classes defined in lua + int m_lua_class_metatable; - }; + // this metatable only contains a destructor + // for luabind::Detail::free_functions::function_rep + int m_lua_function_metatable; -}} + }; + + } +} #endif // LUABIND_CLASS_REGISTRY_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/class_rep.hpp b/libs/luabind/luabind/detail/class_rep.hpp index aa5e866d3..119e15888 100644 --- a/libs/luabind/luabind/detail/class_rep.hpp +++ b/libs/luabind/luabind/detail/class_rep.hpp @@ -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,16 +24,12 @@ #ifndef LUABIND_CLASS_REP_HPP_INCLUDED #define LUABIND_CLASS_REP_HPP_INCLUDED -#include -#include - #include #include #include #include #include -#include #include #include #include @@ -43,171 +39,174 @@ #include #include -namespace luabind { namespace detail -{ +namespace luabind { + namespace detail { - LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); + LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); - struct class_registration; + struct class_registration; - struct conversion_storage; + struct conversion_storage; - // This function is used as a tag to identify "properties". - LUABIND_API int property_tag(lua_State*); + // This function is used as a tag to identify "properties". + LUABIND_API int property_tag(lua_State*); - // this is class-specific information, poor man's vtable - // this is allocated statically (removed by the compiler) - // a pointer to this structure is stored in the lua tables' - // metatable with the name __classrep - // it is used when matching parameters to function calls - // to determine possible implicit casts - // it is also used when finding the best match for overloaded - // methods + // this is class-specific information, poor man's vtable + // this is allocated statically (removed by the compiler) + // a pointer to this structure is stored in the lua tables' + // metatable with the name __classrep + // it is used when matching parameters to function calls + // to determine possible implicit casts + // it is also used when finding the best match for overloaded + // methods - class cast_graph; - class class_id_map; + class cast_graph; + class class_id_map; - class LUABIND_API class_rep - { - friend struct class_registration; - friend int super_callback(lua_State*); -//TODO: avoid the lua-prefix - friend int lua_class_gettable(lua_State*); - friend int lua_class_settable(lua_State*); - friend int static_class_gettable(lua_State*); - public: - - enum class_type + class LUABIND_API class_rep { - cpp_class = 0, - lua_class = 1 + friend struct class_registration; + friend int super_callback(lua_State*); + //TODO: avoid the lua-prefix + friend int lua_class_gettable(lua_State*); + friend int lua_class_settable(lua_State*); + friend int static_class_gettable(lua_State*); + public: + + enum class_type + { + cpp_class = 0, + lua_class = 1 + }; + + // EXPECTS THE TOP VALUE ON THE LUA STACK TO + // BE THE USER DATA WHERE THIS CLASS IS BEING + // INSTANTIATED! + class_rep(type_id const& type + , const char* name + , lua_State* L + ); + + // used when creating a lua class + // EXPECTS THE TOP VALUE ON THE LUA STACK TO + // BE THE USER DATA WHERE THIS CLASS IS BEING + // INSTANTIATED! + class_rep(lua_State* L, const char* name); + + ~class_rep(); + + std::pair allocate(lua_State* L) const; + + // this is called as metamethod __call on the class_rep. + static int constructor_dispatcher(lua_State* L); + + struct base_info + { + int pointer_offset; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance) + class_rep* base; + }; + + void add_base_class(const base_info& binfo); + + const std::vector& bases() const throw() { return m_bases; } + + void set_type(type_id const& t) { m_type = t; } + type_id const& type() const throw() { return m_type; } + + const char* name() const throw() { return m_name; } + + // the lua reference to the metatable for this class' instances + int metatable_ref() const throw() { return m_instance_metatable; } + + void get_table(lua_State* L) const { m_table.push(L); } + void get_default_table(lua_State* L) const { m_default_table.push(L); } + + class_type get_class_type() const { return m_class_type; } + + void add_static_constant(const char* name, int val); + + static int super_callback(lua_State* L); + + static int lua_settable_dispatcher(lua_State* L); + + // called from the metamethod for __index + // obj is the object pointer + static int static_class_gettable(lua_State* L); + + bool has_operator_in_lua(lua_State*, int id); + + cast_graph const& casts() const + { + return *m_casts; + } + + class_id_map const& classes() const + { + return *m_classes; + } + + private: + + // Code common to both constructors + void shared_init(lua_State * L); + + void cache_operators(lua_State*); + + // this is a pointer to the type_info structure for + // this type + // warning: this may be a problem when using dll:s, since + // typeid() may actually return different pointers for the same + // type. + type_id m_type; + + // a list of info for every class this class derives from + // the information stored here is sufficient to do + // type casts to the base classes + std::vector m_bases; + + // the class' name (as given when registered to lua with class_) + const char* m_name; + + // a reference to this structure itself. Since this struct + // is kept inside lua (to let lua collect it when lua_close() + // is called) we need to lock it to prevent collection. + // the actual reference is not currently used. + detail::lua_reference m_self_ref; + + // this should always be used when accessing + // members in instances of a class. + // this table contains c closures for all + // member functions in this class, they + // may point to both static and virtual functions + handle m_table; + + // this table contains default implementations of the + // virtual functions in m_table. + handle m_default_table; + + // the type of this class.. determines if it's written in c++ or lua + class_type m_class_type; + + // this is a lua reference that points to the lua table + // that is to be used as meta table for all instances + // of this class. + int m_instance_metatable; + + std::map m_static_constants; + + // the first time an operator is invoked + // we check the associated lua table + // and cache the result + int m_operator_cache; + + cast_graph* m_casts; + class_id_map* m_classes; }; - // EXPECTS THE TOP VALUE ON THE LUA STACK TO - // BE THE USER DATA WHERE THIS CLASS IS BEING - // INSTANTIATED! - class_rep(type_id const& type - , const char* name - , lua_State* L - ); + LUABIND_API bool is_class_rep(lua_State* L, int index); - // used when creating a lua class - // EXPECTS THE TOP VALUE ON THE LUA STACK TO - // BE THE USER DATA WHERE THIS CLASS IS BEING - // INSTANTIATED! - class_rep(lua_State* L, const char* name); - - ~class_rep(); - - std::pair allocate(lua_State* L) const; - - // this is called as metamethod __call on the class_rep. - static int constructor_dispatcher(lua_State* L); - - struct base_info - { - int pointer_offset; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance) - class_rep* base; - }; - - void add_base_class(const base_info& binfo); - - const std::vector& bases() const throw() { return m_bases; } - - void set_type(type_id const& t) { m_type = t; } - type_id const& type() const throw() { return m_type; } - - const char* name() const throw() { return m_name; } - - // the lua reference to the metatable for this class' instances - int metatable_ref() const throw() { return m_instance_metatable; } - - void get_table(lua_State* L) const { m_table.push(L); } - void get_default_table(lua_State* L) const { m_default_table.push(L); } - - class_type get_class_type() const { return m_class_type; } - - void add_static_constant(const char* name, int val); - - static int super_callback(lua_State* L); - - static int lua_settable_dispatcher(lua_State* L); - - // called from the metamethod for __index - // obj is the object pointer - static int static_class_gettable(lua_State* L); - - bool has_operator_in_lua(lua_State*, int id); - - cast_graph const& casts() const - { - return *m_casts; - } - - class_id_map const& classes() const - { - return *m_classes; - } - - private: - - void cache_operators(lua_State*); - - // this is a pointer to the type_info structure for - // this type - // warning: this may be a problem when using dll:s, since - // typeid() may actually return different pointers for the same - // type. - type_id m_type; - - // a list of info for every class this class derives from - // the information stored here is sufficient to do - // type casts to the base classes - std::vector m_bases; - - // the class' name (as given when registered to lua with class_) - const char* m_name; - - // a reference to this structure itself. Since this struct - // is kept inside lua (to let lua collect it when lua_close() - // is called) we need to lock it to prevent collection. - // the actual reference is not currently used. - detail::lua_reference m_self_ref; - - // this should always be used when accessing - // members in instances of a class. - // this table contains c closures for all - // member functions in this class, they - // may point to both static and virtual functions - handle m_table; - - // this table contains default implementations of the - // virtual functions in m_table. - handle m_default_table; - - // the type of this class.. determines if it's written in c++ or lua - class_type m_class_type; - - // this is a lua reference that points to the lua table - // that is to be used as meta table for all instances - // of this class. - int m_instance_metatable; - - std::map m_static_constants; - - // the first time an operator is invoked - // we check the associated lua table - // and cache the result - int m_operator_cache; - - cast_graph* m_casts; - class_id_map* m_classes; - }; - - bool is_class_rep(lua_State* L, int index); - -}} - -//#include + } +} #endif // LUABIND_CLASS_REP_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/compute_score.hpp b/libs/luabind/luabind/detail/compute_score.hpp deleted file mode 100644 index c9a7e9ea1..000000000 --- a/libs/luabind/luabind/detail/compute_score.hpp +++ /dev/null @@ -1,73 +0,0 @@ -// 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 -# include -# include -# include -# include -# include - -namespace luabind { namespace detail { - -namespace mpl = boost::mpl; - -template -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::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::type() - , typename mpl::next::type() - , end - , policies - ); - - if (next < 0) - return next; - - return score + next; -} - -template -int compute_score_aux(lua_State*, int, Idx, End, End, Policies const&) -{ - return 0; -} - -template -int compute_score(lua_State* L, Signature, Policies const& policies) -{ - return compute_score_aux( - L - , 1 - , mpl::int_<1>() - , typename mpl::next::type>::type() - , typename mpl::end::type() - , policies - ); -} - -}} // namespace luabind::detail - -#endif // LUABIND_COMPUTE_RANK_081006_HPP diff --git a/libs/luabind/luabind/detail/constructor.hpp b/libs/luabind/luabind/detail/constructor.hpp index 1cbceb789..964d07695 100644 --- a/libs/luabind/luabind/detail/constructor.hpp +++ b/libs/luabind/luabind/detail/constructor.hpp @@ -2,110 +2,64 @@ // 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_DETAIL_CONSTRUCTOR_081018_HPP +#define LUABIND_DETAIL_CONSTRUCTOR_081018_HPP -# ifndef LUABIND_DETAIL_CONSTRUCTOR_081018_HPP -# define LUABIND_DETAIL_CONSTRUCTOR_081018_HPP +#include +#include +#include +#include -# include -# include -# include -# include +namespace luabind { + namespace detail { -# include -# include -# include -# include + inline void inject_backref(lua_State*, void*, void*) + {} -namespace luabind { namespace detail { + template + void inject_backref(lua_State* L, T* p, wrap_base*) + { + weak_ref(get_main_thread(L), L, 1).swap(wrap_access::ref(*p)); + } -inline void inject_backref(lua_State*, void*, void*) -{} + template< class T, class Pointer, class Signature, class Arguments, class ArgumentIndices > + struct construct_aux_helper; -template -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, 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; -template -struct construct_aux; + void operator()(argument const& self_, Arguments... args) const + { + object_rep* self = touserdata(self_); -template -struct construct - : construct_aux::value - 2, T, Pointer, Signature> -{}; + std::unique_ptr instance(new T(args...)); + inject_backref(self_.interpreter(), instance.get(), instance.get()); -template -struct construct_aux<0, T, Pointer, Signature> -{ - typedef pointer_holder holder_type; + void* naked_ptr = instance.get(); + Pointer ptr(instance.release()); - void operator()(argument const& self_) const - { - object_rep* self = touserdata(self_); - class_rep* cls = self->crep(); + void* storage = self->allocate(sizeof(holder_type)); - std::auto_ptr instance(new T); - inject_backref(self_.interpreter(), instance.get(), instance.get()); + self->set_instance(new (storage) holder_type(std::move(ptr), registered_class::id, naked_ptr)); + } + }; - void* naked_ptr = instance.get(); - Pointer ptr(instance.release()); - void* storage = self->allocate(sizeof(holder_type)); + template< class T, class Pointer, class Signature > + struct construct : + public construct_aux_helper < + T, + Pointer, + Signature, typename meta::sub_range< Signature, 2, meta::size::value >::type, + typename meta::make_index_range<0, meta::size::value - 2>::type > + { + }; - self->set_instance(new (storage) holder_type( - ptr, registered_class::id, naked_ptr, cls)); - } -}; + } // namespace detail -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (1, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -}} // namespace luabind::detail +} // namespace luabind # endif // LUABIND_DETAIL_CONSTRUCTOR_081018_HPP -#else // !BOOST_PP_IS_ITERATING - -# define N BOOST_PP_ITERATION() - -template -struct construct_aux -{ - typedef typename mpl::begin::type first; - typedef typename mpl::next::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 holder_type; - - void operator()(argument const& self_, BOOST_PP_ENUM_BINARY_PARAMS(N,a,_)) const - { - object_rep* self = touserdata(self_); - class_rep* cls = self->crep(); - - std::auto_ptr 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::id, naked_ptr, cls)); - } -}; - -# undef N - -#endif - diff --git a/libs/luabind/luabind/detail/conversion_policies/conversion_base.hpp b/libs/luabind/luabind/detail/conversion_policies/conversion_base.hpp new file mode 100644 index 000000000..6eb7ba4b8 --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/conversion_base.hpp @@ -0,0 +1,81 @@ +// 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 +#include +#include +#include +#include +#include + + +namespace luabind { + namespace detail { + + // Something's strange with the references here... need to know when to copy :( + template + void make_pointee_instance(lua_State* L, T&& x, std::true_type, Clone) + { + if(get_pointer(x)) + { + make_pointer_instance(L, std::forward(x)); + } + else + { + lua_pushnil(L); + } + } + + template + void make_pointee_instance(lua_State* L, T&& x, std::false_type, std::true_type) + { + using value_type = typename std::remove_reference::type; + + std::unique_ptr ptr(new value_type(std::move(x))); + make_pointer_instance(L, std::move(ptr)); + } + + template + 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 + void make_pointee_instance(lua_State* L, T&& x, Clone) + { + make_pointee_instance(L, std::forward(x), has_get_pointer(), Clone()); + } + + } + + template + struct default_converter; + +} + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_policies/conversion_policies.hpp b/libs/luabind/luabind/detail/conversion_policies/conversion_policies.hpp new file mode 100644 index 000000000..936982eb3 --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/conversion_policies.hpp @@ -0,0 +1,89 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace luabind { + + template <> + struct default_converter + { + enum { consumed_args = 0 }; + + template + lua_State* to_cpp(lua_State* L, U, int /*index*/) + { + return L; + } + + template + static int match(lua_State*, U, int /*index*/) + { + return 0; + } + + template + 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, lua_proxy_converter >, + meta::case_< std::is_enum::type>, enum_converter >, + meta::case_< is_nonconst_pointer, pointer_converter >, + meta::case_< is_const_pointer, const_pointer_converter >, + meta::case_< is_nonconst_reference, ref_converter >, + meta::case_< is_const_reference, const_ref_converter >, + meta::default_< value_converter > + > ::type + { + }; + + } + + template + struct default_converter + : detail::default_converter_generator::type + {}; + +} + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_policies/enum_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/enum_converter.hpp new file mode 100644 index 000000000..dcdd82dd7 --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/enum_converter.hpp @@ -0,0 +1,82 @@ +// 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 +#include +#include + +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 + T to_cpp(lua_State* L, by_value, int index) + { + return static_cast(static_cast(lua_tonumber(L, index))); + } + + template + static int match(lua_State* L, by_value, int index) + { + if(lua_isnumber(L, index)) { + return 0; + } else { + return no_match; + } + } + + template + T to_cpp(lua_State* L, by_const_reference, int index) + { + return static_cast(static_cast(lua_tonumber(L, index))); + } + + template + static int match(lua_State* L, by_const_reference, int index) + { + if(lua_isnumber(L, index)) return 0; else return no_match; + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + + } + +} + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp new file mode 100644 index 000000000..13c27da09 --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp @@ -0,0 +1,95 @@ +// 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 +#include +#include +#include +#include + +namespace luabind { + + template + struct function + { + using result_type = R; + + function(luabind::object const& obj) + : m_func(obj) + { + } + + template< typename... Args> + R operator() (Args&&... args) + { + return call_function(m_func, std::forward(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 , WrappedType > + { + using type = meta::type_list< R, Args... >; + }; + + } + + + template + struct default_converter>::value>::type> + { + using is_native = std::true_type; + + enum { consumed_args = 1 }; + + template + void converter_postcall(lua_State*, U const&, int) + {} + + template + 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 + 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(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 + diff --git a/libs/luabind/luabind/detail/conversion_policies/lua_proxy_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/lua_proxy_converter.hpp new file mode 100644 index 000000000..302a0bffa --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/lua_proxy_converter.hpp @@ -0,0 +1,73 @@ +// 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 +#include + +namespace luabind { + namespace detail { + + template + struct lua_proxy_converter + { + using type = lua_proxy_converter; + using is_native = std::true_type; + + enum { consumed_args = 1 }; + + template + T to_cpp(lua_State* L, by_const_reference, int index) + { + return T(from_stack(L, index)); + } + + template + T to_cpp(lua_State* L, by_value, int index) + { + return to_cpp(L, by_const_reference(), index); + } + + template + static int match(lua_State* L, by_const_reference, int index) + { + return lua_proxy_traits::check(L, index) + ? max_hierarchy_depth + : no_match; + } + + template + static int match(lua_State* L, by_value, int index) + { + return match(L, by_const_reference(), index); + } + + void converter_postcall(...) {} + + template + void to_lua(lua_State* interpreter, T const& value_wrapper) + { + lua_proxy_traits::unwrap(interpreter, value_wrapper); + } + }; + + } +} + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_policies/native_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/native_converter.hpp new file mode 100644 index 000000000..35e2130e4 --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/native_converter.hpp @@ -0,0 +1,302 @@ +// 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 +#include +#include +#include +#include +#include +#include + +#if LUA_VERSION_NUM < 502 +# define lua_rawlen lua_objlen +#endif + +namespace luabind { + + template > + struct native_converter_base + { + using is_native = std::true_type; + using value_type = typename detail::call_traits::value_type; + using param_type = typename detail::call_traits::param_type; + + enum { consumed_args = 1 }; + + template + void converter_postcall(lua_State*, U const&, int) + {} + + int match(lua_State* L, by_value, int index) + { + return Derived::compute_score(L, index); + } + + int match(lua_State* L, by_value, int index) + { + return Derived::compute_score(L, index); + } + + + int match(lua_State* L, by_const_reference, int index) + { + return Derived::compute_score(L, index); + } + + value_type to_cpp(lua_State* L, by_value, int index) + { + return derived().to_cpp_deferred(L, index); + } + + value_type to_cpp(lua_State* L, by_const_reference, 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(*this); + } + }; + + template + struct integer_converter + : native_converter_base> + { + using T = remove_const_reference_t; + using value_type = typename native_converter_base::value_type; + using param_type = typename native_converter_base::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 && sizeof(value_type) >= sizeof(lua_Integer)) || (sizeof(value_type) > sizeof(lua_Integer))) { + return static_cast(lua_tonumber(L, index)); + } else { + return static_cast(lua_tointeger(L, index)); + } + } + + void to_lua_deferred(lua_State* L, param_type value) + { + if((std::is_unsigned::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(value)); + } + } + }; + + template + struct number_converter + : native_converter_base> + { + using T = remove_const_reference_t; + using value_type = typename native_converter_base::value_type; + using param_type = typename native_converter_base::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(lua_tonumber(L, index)); + } + + static void to_lua_deferred(lua_State* L, param_type value) + { + lua_pushnumber(L, static_cast(value)); + } + }; + + template <> + struct default_converter + : native_converter_base + { + 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 + : default_converter + {}; + + template <> + struct default_converter + : default_converter + {}; + + template <> + struct default_converter + : native_converter_base + { + 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 + : default_converter + {}; + + template <> + struct default_converter + : default_converter + {}; + + template <> + struct default_converter + : default_converter + {}; + + template <> + struct default_converter + { + using is_native = std::true_type; + + enum { consumed_args = 1 }; + + template + 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 + 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 + void converter_postcall(lua_State*, U, int) + {} + }; + + template <> + struct default_converter + : default_converter + {}; + + template <> + struct default_converter + : default_converter + {}; + + template <> + struct default_converter + : default_converter + {}; + + template <> + struct default_converter + : default_converter + {}; + + template + struct default_converter + : default_converter + {}; + + template + struct default_converter + : default_converter + {}; + + template + struct default_converter + : default_converter + {}; + + template + struct default_converter + : default_converter + {}; + + template + struct default_converter < T, typename std::enable_if< std::is_integral>::value >::type > + : integer_converter + { + }; + + template + struct default_converter < T, typename std::enable_if< std::is_floating_point>::value >::type > + : number_converter + { + }; + +} + +#if LUA_VERSION_NUM < 502 +# undef lua_rawlen +#endif + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_policies/pointer_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/pointer_converter.hpp new file mode 100644 index 000000000..95289811d --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/pointer_converter.hpp @@ -0,0 +1,143 @@ +// 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 +#include +#include +#include + +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 + 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 + T* to_cpp(lua_State*, by_pointer, int /*index*/) + { + return static_cast(result); + } + + template + int match(lua_State* L, by_pointer, 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 s = obj->get_instance(registered_class::id); + result = s.first; + return s.second; + } + + template + void converter_postcall(lua_State*, by_pointer, 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 + 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 + T const* to_cpp(lua_State*, by_const_pointer, int) + { + return static_cast(result); + } + + template + int match(lua_State* L, by_const_pointer, 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 s = obj->get_instance(registered_class::id); + if(s.second >= 0 && !obj->is_const()) + s.second += 10; + result = s.first; + return s.second; + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + + } + +} + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_policies/reference_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/reference_converter.hpp new file mode 100644 index 000000000..679c63692 --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/reference_converter.hpp @@ -0,0 +1,124 @@ +// 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 +#include +#include +#include + +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 + 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 + T& to_cpp(lua_State* L, by_reference, int index) + { + assert(!lua_isnil(L, index)); + return *pointer_converter::to_cpp(L, by_pointer(), index); + } + + template + int match(lua_State* L, by_reference, int index) + { + object_rep* obj = get_instance(L, index); + if(obj == 0) return no_match; + + if(obj->is_const()) + return no_match; + + std::pair s = obj->get_instance(registered_class::id); + result = s.first; + return s.second; + } + + template + 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 + 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 + T const& to_cpp(lua_State*, by_const_reference, int) + { + return *static_cast(result); + } + + template + int match(lua_State* L, by_const_reference, 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 s = obj->get_instance(registered_class::id); + if(s.second >= 0 && !obj->is_const()) + s.second += 10; + result = s.first; + return s.second; + } + + template + void converter_postcall(lua_State*, by_const_reference, int) + { + } + }; + + } +} + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_policies/value_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/value_converter.hpp new file mode 100644 index 000000000..fa91e6712 --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/value_converter.hpp @@ -0,0 +1,79 @@ +// 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 +#include +#include +#include + +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 + void to_lua(lua_State* L, T&& x) + { + if(luabind::get_back_reference(L, x)) + return; + + make_value_instance(L, std::forward(x)); + } + + template + T to_cpp(lua_State*, by_value, int) + { + return *static_cast(result); + } + + template + int match(lua_State* L, by_value, 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 s = obj->get_instance(registered_class::id); + result = s.first; + return s.second; + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + + } +} + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_storage.hpp b/libs/luabind/luabind/detail/conversion_storage.hpp index 153112d62..9fc443163 100644 --- a/libs/luabind/luabind/detail/conversion_storage.hpp +++ b/libs/luabind/luabind/detail/conversion_storage.hpp @@ -6,36 +6,38 @@ # define LUABIND_CONVERSION_STORAGE_080930_HPP # include -# include +# include -namespace luabind { namespace detail { +namespace luabind { + namespace detail { -typedef void(*destruction_function)(void*); + using destruction_function = void(*)(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 -{ - conversion_storage() - : destructor(0) - {} + struct conversion_storage + { + conversion_storage() + : destructor(0) + {} - ~conversion_storage() - { - if (destructor) - destructor(&data); - } + ~conversion_storage() + { + 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. - boost::aligned_storage<128> data; - destruction_function destructor; -}; + // 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; + destruction_function destructor; + }; -}} // namespace luabind::detail + } +} // namespace luabind::detail #endif // LUABIND_CONVERSION_STORAGE_080930_HPP diff --git a/libs/luabind/luabind/detail/convert_to_lua.hpp b/libs/luabind/luabind/detail/convert_to_lua.hpp deleted file mode 100644 index f5aa89aea..000000000 --- a/libs/luabind/luabind/detail/convert_to_lua.hpp +++ /dev/null @@ -1,92 +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 -#include -#include - -#include - -namespace luabind { namespace detail -{ - template - struct unwrap_ref - { - template - static const T& get(const T& r) { return r; } - - template - struct apply - { - typedef T type; - }; - }; - - template<> - struct unwrap_ref - { - template - static T& get(const boost::reference_wrapper& r) { return r.get(); } - - template - struct apply - { - typedef typename T::type& type; - }; - }; - - namespace mpl = boost::mpl; - - template - void convert_to_lua(lua_State* L, const T& v) - { - typedef typename mpl::apply_wrap1< - unwrap_ref::value> - , T - >::type value_type; - - typename mpl::apply_wrap2::type converter; - - converter.apply(L, unwrap_ref::value>::get(v)); - } - - template - void convert_to_lua_p(lua_State* L, const T& v, const Policies&) - { - typedef typename mpl::apply_wrap1< - unwrap_ref::value> - , T - >::type value_type; - - typedef typename find_conversion_policy::type converter_policy; - typename mpl::apply_wrap2::type converter; - - converter.apply(L, unwrap_ref::value>::get(v)); - } -}} - -#endif - diff --git a/libs/luabind/luabind/detail/crtp_iterator.hpp b/libs/luabind/luabind/detail/crtp_iterator.hpp new file mode 100644 index 000000000..7973ba5fd --- /dev/null +++ b/libs/luabind/luabind/detail/crtp_iterator.hpp @@ -0,0 +1,58 @@ +#ifndef LUABIND_CRTP_ITERATOR_HPP_INCLUDED +#define LUABIND_CRTP_ITERATOR_HPP_INCLUDED + +#include + +namespace luabind { + namespace detail { + + template< typename CRTP, typename Category, typename ValueType, typename ReferenceType = ValueType&, typename DifferenceType = ptrdiff_t > + class crtp_iterator : + public std::iterator + { + public: + using base_type = std::iterator; + + + 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(*this); } + const CRTP& upcast() const { return static_cast(*this); } + }; + + } +} + +#endif diff --git a/libs/luabind/luabind/detail/debug.hpp b/libs/luabind/luabind/detail/debug.hpp index ef13bc886..e3e1c1f14 100644 --- a/libs/luabind/luabind/detail/debug.hpp +++ b/libs/luabind/luabind/detail/debug.hpp @@ -28,28 +28,32 @@ #include #include -namespace luabind { namespace detail -{ - struct stack_checker_type - { - stack_checker_type(lua_State* L) - : m_L(L) - , m_stack(lua_gettop(m_L)) - {} +namespace luabind { + namespace detail { - ~stack_checker_type() + struct stack_checker_type { - assert(m_stack == lua_gettop(m_L)); - } + stack_checker_type(lua_State* L) + : m_L(L) + , m_stack(lua_gettop(m_L)) + {} - lua_State* m_L; - int m_stack; - }; + ~stack_checker_type() + { + assert(m_stack == lua_gettop(m_L)); + } + + lua_State* m_L; + int m_stack; + }; + + } +} -}} #define LUABIND_CHECK_STACK(L) luabind::detail::stack_checker_type stack_checker_object(L) #else #define LUABIND_CHECK_STACK(L) do {} while (0) #endif #endif // LUABIND_DEBUG_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/decorate_type.hpp b/libs/luabind/luabind/detail/decorate_type.hpp index bb144c463..7752bfd4d 100644 --- a/libs/luabind/luabind/detail/decorate_type.hpp +++ b/libs/luabind/luabind/detail/decorate_type.hpp @@ -25,242 +25,62 @@ #define LUABIND_DECORATE_TYPE_HPP_INCLUDED #include -#include -namespace luabind { namespace detail -{ +namespace luabind { -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template struct by_value {}; + template struct by_const_reference {}; + template struct by_reference {}; + template struct by_rvalue_reference {}; + template struct by_pointer {}; + template struct by_const_pointer {}; template - struct decorated_type + struct decorate_type { - static by_value t; - static inline by_value& get() { return /*by_value()*/t; } + using type = by_value; }; template - by_value decorated_type::t; - - template - struct decorated_type + struct decorate_type { - static by_pointer t; - static inline by_pointer& get() { return /*by_pointer()*/t; } + using type = by_pointer; }; template - by_pointer decorated_type::t; - - template - struct decorated_type + struct decorate_type { - static by_const_pointer t; - static inline by_const_pointer get() { return /*by_const_pointer()*/t; } + using type = by_const_pointer; }; template - by_const_pointer decorated_type::t; - - template - struct decorated_type + struct decorate_type { - static by_const_pointer t; - static inline by_const_pointer& get() { return /*by_const_pointer()*/t; } + using type = by_const_pointer; }; template - by_const_pointer decorated_type::t; - - template - struct decorated_type + struct decorate_type { - static by_reference t; - static inline by_reference& get() { return /*by_reference()*/t; } + using type = by_reference; }; template - by_reference decorated_type::t; - - template - struct decorated_type + struct decorate_type { - static by_const_reference t; - static inline by_const_reference& get() { return /*by_const_reference()*/t; } + using type = by_const_reference; }; template - by_const_reference decorated_type::t; - - #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get() - -#else - -#include - - namespace + struct decorate_type { - LUABIND_ANONYMOUS_FIX char decorated_type_array[64]; - } - - template - struct decorated_type_cref_impl - { -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - template - static by_const_reference get(const U&) - { - return by_const_reference(); - } - static T data() { return reinterpret_cast(decorated_type_array); } -#else - - static void(*data())(T) - { return (void(*)(T))0; } - - template - static by_const_reference get(void(*f)(const U&)) - { return by_const_reference(); } -#endif + using type = by_rvalue_reference; }; - template - struct decorated_type_ref_impl - { -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - template - static by_reference get(U&) - { - return by_reference(); - } - static T data() { return reinterpret_cast(decorated_type_array); } -#else - static void(*data())(T) - { return (void(*)(T))0; } + template< typename T > + using decorate_type_t = typename decorate_type::type; - template - static by_reference get(void(*)(U&)) - { return by_reference(); } -#endif - }; - - template - struct decorated_type_cptr_impl - { -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - template - static by_const_pointer get(const U*) - { - return by_const_pointer(); - } - static T& data() { return reinterpret_cast(decorated_type_array); } -#else - static void(*data())(T) - { return (void(*)(T))0; } - - template - static by_const_pointer get(void(*)(const U*)) - { return by_const_pointer(); } -#endif - }; - - template - struct decorated_type_ptr_impl - { -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - template - static by_pointer get(U*) - { - return by_pointer(); - } - static T& data() { return reinterpret_cast(decorated_type_array); } -#else - static void(*data())(T) - { return (void(*)(T))0; } - - template - static by_pointer get(void(*)(U*)) - { return by_pointer(); } -#endif - }; - - template - struct decorated_type_value_impl - { -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - template - static by_value get(U&) - { - return by_value(); - } - static T& data() { return reinterpret_cast(decorated_type_array); } -#else - static void(*data())(T&) - { return (void(*)(T&))0; } - - template - static by_value get(void(*)(U&)) - { return by_value(); } -#endif - }; - - template<> - struct decorated_type_value_impl - { - static by_value get(int) - { - return by_value(); - } - static int data() { return 0; } - }; - - template - struct decorated_type_array_impl - { - template - static by_pointer get(U*) - { - return by_pointer(); - } - - template - static by_pointer get(void(*)(U)) - { return by_pointer(); } - - static T& data() { return reinterpret_cast(decorated_type_array); } - }; - - template - struct decorated_type -// : boost::mpl::if_ -// , decorated_type_array_impl - : boost::mpl::if_ - , decorated_type_cref_impl - , typename boost::mpl::if_ - , decorated_type_ref_impl - , typename boost::mpl::if_ - , decorated_type_ptr_impl - , typename boost::mpl::if_ - , decorated_type_cptr_impl - , decorated_type_value_impl - >::type - >::type - >::type - >::type -// >::type - { - }; - -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get(luabind::detail::decorated_type::data()) -#else -// #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get((void(*)(type))0) - #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get(luabind::detail::decorated_type::data()) - //#define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get(type()) -#endif - -#endif - -}} +} #endif // LUABIND_DECORATE_TYPE_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/deduce_signature.hpp b/libs/luabind/luabind/detail/deduce_signature.hpp index e47e22f4e..012d052d5 100644 --- a/libs/luabind/luabind/detail/deduce_signature.hpp +++ b/libs/luabind/luabind/detail/deduce_signature.hpp @@ -2,117 +2,19 @@ // 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 +# define LUABIND_DEDUCE_SIGNATURE_080911_HPP -# include +#include +#include -# if LUABIND_MAX_ARITY <= 8 -# include -# else -# include -# endif -# include -# include -# include +namespace luabind { + namespace detail { -namespace luabind { namespace detail { -namespace mpl = boost::mpl; + } // namespace detail -template -mpl::vector1 deduce_signature(R(*)(), ...) -{ - return mpl::vector1(); -} - -template -mpl::vector2 deduce_signature(R(T::*)()) -{ - return mpl::vector2(); -} - -template -mpl::vector2::type&> -deduce_signature(R(T::*)(), Wrapped*) -{ - return mpl::vector2::type&>(); -} - -template -mpl::vector2 deduce_signature(R(T::*)() const) -{ - return mpl::vector2(); -} - -template -mpl::vector2::type const&> -deduce_signature(R(T::*)() const, Wrapped*) -{ - return mpl::vector2::type const&>(); -} - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (1, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -}} // namespace luabind::detail +} // namespace luabind # endif // LUABIND_DEDUCE_SIGNATURE_080911_HPP -#else // BOOST_PP_IS_ITERATING - -# define N BOOST_PP_ITERATION() -# define NPLUS1 BOOST_PP_INC(N) - -template -BOOST_PP_CAT(mpl::vector,NPLUS1) -deduce_signature(R(*)(BOOST_PP_ENUM_PARAMS(N,A)), ...) -{ - return BOOST_PP_CAT(mpl::vector,NPLUS1)(); -} - -# define NPLUS2 BOOST_PP_INC(NPLUS1) - -template -BOOST_PP_CAT(mpl::vector,NPLUS2) -deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A))) -{ - return BOOST_PP_CAT(mpl::vector,NPLUS2)(); -} - -template -BOOST_PP_CAT(mpl::vector,NPLUS2)< - R, typename most_derived::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::type&,BOOST_PP_ENUM_PARAMS(N,A)>(); -} - -template -BOOST_PP_CAT(mpl::vector,NPLUS2) -deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)) const) -{ - return BOOST_PP_CAT(mpl::vector,NPLUS2)(); -} - -template -BOOST_PP_CAT(mpl::vector,NPLUS2)< - R, typename most_derived::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::type const&,BOOST_PP_ENUM_PARAMS(N,A)>(); -} - -# undef NPLUS2 -# undef NPLUS1 -# undef N - -#endif // BOOST_PP_IS_ITERATING - diff --git a/libs/luabind/luabind/detail/enum_maker.hpp b/libs/luabind/luabind/detail/enum_maker.hpp index fadbe3e52..20161ec3f 100644 --- a/libs/luabind/luabind/detail/enum_maker.hpp +++ b/libs/luabind/luabind/detail/enum_maker.hpp @@ -30,8 +30,8 @@ #include #include -namespace luabind -{ +namespace luabind { + struct value; struct value_vector : public std::vector @@ -45,7 +45,7 @@ namespace luabind struct value { - friend class std::vector; + friend class std::vector; template value(const char* name, T v) : name_(name) @@ -65,7 +65,7 @@ namespace luabind return v; } - private: + private: value() {} }; @@ -93,19 +93,18 @@ namespace luabind template struct enum_maker { - explicit enum_maker(From& from): from_(from) {} + explicit enum_maker(From& from) : from_(from) {} From& operator[](const value& val) { from_.add_static_constant(val.name_, val.val_); return from_; } - + From& operator[](const value_vector& values) { - for (value_vector::const_iterator i = values.begin(); i != values.end(); ++i) - { - from_.add_static_constant(i->name_, i->val_); + for(const auto& val : values) { + from_.add_static_constant(val.name_, val.val_); } return from_; @@ -114,10 +113,11 @@ namespace luabind From& from_; private: - void operator=(enum_maker const&); // C4512, assignment operator could not be generated + void operator=(enum_maker const&); // C4512, assignment operator could not be generated template void operator,(T const&) const; }; } } #endif // LUABIND_ENUM_MAKER_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/format_signature.hpp b/libs/luabind/luabind/detail/format_signature.hpp index ec56b6196..bb6679dba 100644 --- a/libs/luabind/luabind/detail/format_signature.hpp +++ b/libs/luabind/luabind/detail/format_signature.hpp @@ -5,73 +5,70 @@ #ifndef LUABIND_FORMAT_SIGNATURE_081014_HPP # define LUABIND_FORMAT_SIGNATURE_081014_HPP -# include -# include -# include +#include +#include +#include +#include -# include -# include -# include +namespace luabind { + namespace adl { -namespace luabind { namespace adl { + class object; + class argument; + template + struct table; - class object; - class argument; - template - 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 + struct type_to_string + { + static void get(lua_State* L) + { + lua_pushstring(L, get_class_name(L, typeid(T)).c_str()); + } + }; -template -struct type_to_string -{ - static void get(lua_State* L) - { - lua_pushstring(L, get_class_name(L, typeid(T)).c_str()); - } -}; + template + struct type_to_string + { + static void get(lua_State* L) + { + type_to_string::get(L); + lua_pushstring(L, "*"); + lua_concat(L, 2); + } + }; -template -struct type_to_string -{ - static void get(lua_State* L) - { - type_to_string::get(L); - lua_pushstring(L, "*"); - lua_concat(L, 2); - } -}; + template + struct type_to_string + { + static void get(lua_State* L) + { + type_to_string::get(L); + lua_pushstring(L, "&"); + lua_concat(L, 2); + } + }; -template -struct type_to_string -{ - static void get(lua_State* L) - { - type_to_string::get(L); - lua_pushstring(L, "&"); - lua_concat(L, 2); - } -}; - -template -struct type_to_string -{ - static void get(lua_State* L) - { - type_to_string::get(L); - lua_pushstring(L, " const"); - lua_concat(L, 2); - } -}; + template + struct type_to_string + { + static void get(lua_State* L) + { + type_to_string::get(L); + lua_pushstring(L, " const"); + lua_concat(L, 2); + } + }; # define LUABIND_TYPE_TO_STRING(x) \ template <> \ @@ -87,67 +84,67 @@ struct type_to_string 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 -struct type_to_string > -{ - static void get(lua_State* L) - { - lua_pushstring(L, "table"); - } -}; + template + struct type_to_string > + { + static void get(lua_State* L) + { + lua_pushstring(L, "table"); + } + }; -template -void format_signature_aux(lua_State*, bool, End, End) -{} + inline void format_signature_aux(lua_State*, bool, meta::type_list< >) + {} -template -void format_signature_aux(lua_State* L, bool first, Iter, End end) -{ - if (!first) - lua_pushstring(L, ","); - type_to_string::get(L); - format_signature_aux(L, false, typename mpl::next::type(), end); -} + template + void format_signature_aux(lua_State* L, bool first, Signature) + { + if(!first) + lua_pushstring(L, ","); + type_to_string::type>::get(L); + format_signature_aux(L, false, typename meta::pop_front::type()); + } -template -void format_signature(lua_State* L, char const* function, Signature) -{ - typedef typename mpl::begin::type first; + template + void format_signature(lua_State* L, char const* function, Signature) + { + using first = typename meta::front::type; - type_to_string::get(L); + type_to_string::get(L); - lua_pushstring(L, " "); - lua_pushstring(L, function); + lua_pushstring(L, " "); + lua_pushstring(L, function); - lua_pushstring(L, "("); - format_signature_aux( - L - , true - , typename mpl::next::type() - , typename mpl::end::type() - ); - lua_pushstring(L, ")"); + lua_pushstring(L, "("); + format_signature_aux( + L + , true + , typename meta::pop_front::type() + ); + lua_pushstring(L, ")"); + constexpr size_t ncat = meta::size::value * 2 + 2 + (meta::size::value == 1 ? 1 : 0); + lua_concat(L, static_cast(ncat)); + } - lua_concat(L, static_cast(mpl::size()) * 2 + 2); -} + } // namespace detail -}} // namespace luabind::detail +} // namespace luabind #endif // LUABIND_FORMAT_SIGNATURE_081014_HPP diff --git a/libs/luabind/luabind/detail/garbage_collector.hpp b/libs/luabind/luabind/detail/garbage_collector.hpp index c0d68aa36..9e55d2b4a 100644 --- a/libs/luabind/luabind/detail/garbage_collector.hpp +++ b/libs/luabind/luabind/detail/garbage_collector.hpp @@ -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,28 +26,31 @@ #include -namespace luabind { namespace detail -{ - // function that is used as __gc metafunction on several objects - template - inline int garbage_collector(lua_State* L) - { - T* obj = static_cast(lua_touserdata(L, -1)); - obj->~T(); - return 0; - } +namespace luabind { + namespace detail { - template - struct garbage_collector_s - { - static int apply(lua_State* L) + // function that is used as __gc metafunction on several objects + template + inline int garbage_collector(lua_State* L) { T* obj = static_cast(lua_touserdata(L, -1)); obj->~T(); return 0; } - }; -}} + template + struct garbage_collector_s + { + static int apply(lua_State* L) + { + T* obj = static_cast(lua_touserdata(L, -1)); + obj->~T(); + return 0; + } + }; + + } +} #endif // LUABIND_GARBAGE_COLLECTOR_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/has_get_pointer.hpp b/libs/luabind/luabind/detail/has_get_pointer.hpp deleted file mode 100644 index 8a001ddda..000000000 --- a/libs/luabind/luabind/detail/has_get_pointer.hpp +++ /dev/null @@ -1,107 +0,0 @@ -// 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 - -# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP -# include -# endif - -namespace luabind { namespace detail { - -namespace has_get_pointer_ -{ - - struct any - { - template 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 - T* get_pointer(T const volatile*); - - template - T* get_pointer(std::auto_ptr 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 - yes check(T const&); - no check(no_overload_tag); - - template - struct impl - { - static typename boost::add_reference::type x; - - BOOST_STATIC_CONSTANT(bool, - value = sizeof(has_get_pointer_::check( (get_pointer(x),0) )) == 1 - ); - - typedef boost::mpl::bool_ type; - }; - -} // namespace has_get_pointer_ - -template -struct has_get_pointer - : has_get_pointer_::impl::type -{}; - -}} // namespace luabind::detail - -#endif // LUABIND_HAS_GET_POINTER_051022_HPP - diff --git a/libs/luabind/luabind/detail/inheritance.hpp b/libs/luabind/luabind/detail/inheritance.hpp index a7afe0156..26bde136a 100644 --- a/libs/luabind/luabind/detail/inheritance.hpp +++ b/libs/luabind/luabind/detail/inheritance.hpp @@ -1,168 +1,169 @@ // 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 # include # include # include # include # include # include -# include -namespace luabind { namespace detail { +namespace luabind { -typedef void*(*cast_function)(void*); -typedef std::size_t class_id; + namespace detail { -class_id const unknown_class = (std::numeric_limits::max)(); + using cast_function = void*(*)(void*); + using class_id = std::size_t; -class class_rep; + constexpr class_id unknown_class = std::numeric_limits::max(); -class LUABIND_API cast_graph -{ -public: - cast_graph(); - ~cast_graph(); + class class_rep; - // `src` and `p` here describe the *most derived* object. This means that - // for a polymorphic type, the pointer must be cast with - // dynamic_cast before being passed in here, and `src` has to - // match typeid(*p). - std::pair 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); + class LUABIND_API cast_graph + { + public: + cast_graph(); + ~cast_graph(); -private: - class impl; - boost::scoped_ptr m_impl; -}; + // `src` and `p` here describe the *most derived* object. This means that + // for a polymorphic type, the pointer must be cast with + // dynamic_cast before being passed in here, and `src` has to + // match typeid(*p). + std::pair 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); -// 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(); + private: + class impl; + std::unique_ptr m_impl; + }; - 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); + // 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(); -private: - typedef std::map map_type; - map_type m_classes; - class_id m_local_id; + 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); - static class_id const local_id_base; -}; + private: + using map_type = std::map; + map_type m_classes; + class_id m_local_id; -inline class_id_map::class_id_map() - : m_local_id(local_id_base) -{} + static class_id const local_id_base; + }; -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) - return unknown_class; - return i->second; -} + inline class_id_map::class_id_map() + : m_local_id(local_id_base) + {} -inline class_id class_id_map::get_local(type_id const& type) -{ - std::pair result = m_classes.insert( - std::make_pair(type, 0)); + 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) { + return unknown_class; + } + else { + return i->second; + } + } - if (result.second) - result.first->second = m_local_id++; + inline class_id class_id_map::get_local(type_id const& type) + { + std::pair result = m_classes.insert(std::make_pair(type, 0)); - assert(m_local_id >= local_id_base); + if(result.second) result.first->second = m_local_id++; + assert(m_local_id >= local_id_base); + return result.first->second; + } - return result.first->second; -} + inline void class_id_map::put(class_id id, type_id const& type) + { + assert(id < local_id_base); -inline void class_id_map::put(class_id id, type_id const& type) -{ - assert(id < local_id_base); + std::pair result = m_classes.insert( + std::make_pair(type, 0)); - std::pair result = m_classes.insert( - std::make_pair(type, 0)); + assert( + result.second + || result.first->second == id + || result.first->second >= local_id_base + ); - assert( - result.second - || result.first->second == id - || result.first->second >= local_id_base - ); + result.first->second = id; + } - result.first->second = id; -} + class class_map + { + public: + class_rep* get(class_id id) const; + void put(class_id id, class_rep* cls); -class class_map -{ -public: - class_rep* get(class_id id) const; - void put(class_id id, class_rep* cls); + private: + std::vector m_classes; + }; -private: - std::vector m_classes; -}; + inline class_rep* class_map::get(class_id id) const + { + if(id >= m_classes.size()) + return 0; + return m_classes[id]; + } -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()) + m_classes.resize(id + 1); + m_classes[id] = cls; + } -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 + struct static_cast_ + { + static void* execute(void* p) + { + return static_cast(static_cast(p)); + } + }; -template -struct static_cast_ -{ - static void* execute(void* p) - { - return static_cast(static_cast(p)); - } -}; + template + struct dynamic_cast_ + { + static void* execute(void* p) + { + return dynamic_cast(static_cast(p)); + } + }; -template -struct dynamic_cast_ -{ - static void* execute(void* p) - { - return dynamic_cast(static_cast(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 + struct registered_class + { + static class_id const id; + }; -template -struct registered_class -{ - static class_id const id; -}; + template + class_id const registered_class::id = allocate_class_id(typeid(T)); -template -class_id const registered_class::id = allocate_class_id(typeid(T)); + template + struct registered_class + : registered_class + {}; -template -struct registered_class - : registered_class -{}; + } // namespace detail -}} // namespace luabind::detail +} // namespace luabind #endif // LUABIND_INHERITANCE_090217_HPP + diff --git a/libs/luabind/luabind/detail/instance_holder.hpp b/libs/luabind/luabind/detail/instance_holder.hpp index 456e13e6b..bf51ebb06 100644 --- a/libs/luabind/luabind/detail/instance_holder.hpp +++ b/libs/luabind/luabind/detail/instance_holder.hpp @@ -6,126 +6,160 @@ # define LUABIND_INSTANCE_HOLDER_081024_HPP # include -# include // TODO -# include +# include # include -# include # include -namespace luabind { namespace detail { +namespace luabind { + namespace detail { -class instance_holder -{ -public: - instance_holder(class_rep* cls, bool pointee_const) - : m_cls(cls) - , m_pointee_const(pointee_const) - {} + class instance_holder + { + public: + instance_holder(bool pointee_const) + : m_pointee_const(pointee_const) + {} - virtual ~instance_holder() - {} + virtual ~instance_holder() + {} - virtual std::pair get(class_id target) const = 0; + virtual std::pair get(cast_graph const& casts, class_id target) const = 0; + virtual void release() = 0; - virtual void release() = 0; + bool pointee_const() const + { + return m_pointee_const; + } - class_rep* get_class() const - { - return m_cls; - } + private: + bool m_pointee_const; + }; - bool pointee_const() const - { - return m_pointee_const; - } + template + 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(std::move(p)), weak(0), dynamic_id(dynamic_id), dynamic_ptr(dynamic_ptr) + { + } -private: - class_rep* m_cls; - bool m_pointee_const; -}; + std::pair get(cast_graph const& casts, class_id target) const override + { + // if somebody wants the smart-ptr, he can get a reference to it + if(target == registered_class

::id) return std::pair(&this->p, 0); -namespace mpl = boost::mpl; + void* naked_ptr = const_cast(static_cast(weak ? weak : get_pointer(p))); + if(!naked_ptr) return std::pair(nullptr, 0); -inline mpl::false_ check_const_pointer(void*) -{ - return mpl::false_(); -} + using pointee_type = typename std::remove_cv::type>::type; -inline mpl::true_ check_const_pointer(void const*) -{ - return mpl::true_(); -} + return casts.cast(naked_ptr, + registered_class< pointee_type >::id, + target, dynamic_id, dynamic_ptr); + } -template -void release_ownership(std::auto_ptr& p) -{ - p.release(); -} + explicit operator bool() const + { + return p ? true : false; + } -template -void release_ownership(P const&) -{ - throw std::runtime_error( - "luabind: smart pointer does not allow ownership transfer"); -} + void release() override + { + weak = const_cast(static_cast(get_pointer(p))); + release_ownership(p); + } -template -class_id static_class_id(T*) -{ - return registered_class::id; -} + 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 + // to make adopt() work with virtual function wrapper classes. + void* weak; + class_id dynamic_id; + void* dynamic_ptr; + }; -template -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) - {} + template + 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)) + {} - std::pair get(class_id target) const - { - if (target == registered_class

::id) - return std::pair(&this->p, 0); + explicit operator bool() const + { + return true; + } - void* naked_ptr = const_cast(static_cast( - weak ? weak : get_pointer(p))); + std::pair get(cast_graph const& casts, class_id target) const override + { + const auto this_id = registered_class::id; + void* const naked_ptr = const_cast((const void*)&val_); + if(target == this_id) return std::pair(naked_ptr, 0); + return casts.cast(naked_ptr, this_id, target, this_id, naked_ptr); + } - if (!naked_ptr) - return std::pair((void*)0, 0); + void release() override + {} - return get_class()->casts().cast( - naked_ptr - , static_class_id(false ? get_pointer(p) : 0) - , target - , dynamic_id - , dynamic_ptr - ); - } + private: + ValueType val_; + }; - void release() - { - weak = const_cast(static_cast( - get_pointer(p))); - release_ownership(p); - } + /* + Pointer types should automatically convert to reference types + */ + template + 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) + { + } -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 - // to make adopt() work with virtual function wrapper classes. - void* weak; - class_id dynamic_id; - void* dynamic_ptr; -}; + explicit operator bool() const + { + return val_ ? true : false; + } -}} // namespace luabind::detail + std::pair get(cast_graph const& casts, class_id target) const override + { + const auto value_id = registered_class::id; + void* const naked_value_ptr = const_cast((const void*)&val_); + if(target == value_id) return std::pair(naked_value_ptr, 0); + // If we were to support automatic pointer conversion, this would be the place + + using pointee_type = typename std::remove_cv::type >::type; + const auto pointee_id = registered_class< pointee_type >::id; + void* const naked_pointee_ptr = const_cast((const void*)get_pointer(val_)); + return casts.cast(naked_pointee_ptr, pointee_id, target, dynamic_id_, dynamic_ptr_); + } + + void release() override + {} + + private: + ValueType val_; + class_id dynamic_id_; + void* dynamic_ptr_; + // weak? must understand what the comment up there really means + }; + + } + +} // namespace luabind::detail #endif // LUABIND_INSTANCE_HOLDER_081024_HPP + diff --git a/libs/luabind/luabind/detail/is_indirect_const.hpp b/libs/luabind/luabind/detail/is_indirect_const.hpp deleted file mode 100644 index b6c1282fb..000000000 --- a/libs/luabind/luabind/detail/is_indirect_const.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// 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 -#include -#include - -namespace luabind { - - namespace detail { - - template - typename boost::is_const::type - is_indirect_const_check(T(*)(), int); - - template - typename boost::is_const::type - is_indirect_const_check(T*(*)(), long); - - template - typename boost::is_const::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 - // T = U& is_const - // T = U is_const - template - 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 - diff --git a/libs/luabind/luabind/detail/link_compatibility.hpp b/libs/luabind/luabind/detail/link_compatibility.hpp index 6f0006afa..33cb9a985 100644 --- a/libs/luabind/luabind/detail/link_compatibility.hpp +++ b/libs/luabind/luabind/detail/link_compatibility.hpp @@ -25,36 +25,38 @@ #include -namespace luabind { namespace detail -{ +namespace luabind { + namespace detail { #ifdef LUABIND_NOT_THREADSAFE - LUABIND_API void not_threadsafe_defined_conflict(); + LUABIND_API void not_threadsafe_defined_conflict(); #else - LUABIND_API void not_threadsafe_not_defined_conflict(); + LUABIND_API void not_threadsafe_not_defined_conflict(); #endif #ifdef LUABIND_NO_ERROR_CHECKING - LUABIND_API void no_error_checking_defined_conflict(); + LUABIND_API void no_error_checking_defined_conflict(); #else - LUABIND_API void no_error_checking_not_defined_conflict(); + LUABIND_API void no_error_checking_not_defined_conflict(); #endif - inline void check_link_compatibility() - { - #ifdef LUABIND_NOT_THREADSAFE - not_threadsafe_defined_conflict(); - #else - not_threadsafe_not_defined_conflict(); - #endif + inline void check_link_compatibility() + { +#ifdef LUABIND_NOT_THREADSAFE + not_threadsafe_defined_conflict(); +#else + not_threadsafe_not_defined_conflict(); +#endif + +#ifdef LUABIND_NO_ERROR_CHECKING + no_error_checking_defined_conflict(); +#else + no_error_checking_not_defined_conflict(); +#endif + } - #ifdef LUABIND_NO_ERROR_CHECKING - no_error_checking_defined_conflict(); - #else - no_error_checking_not_defined_conflict(); - #endif } - -}} +} #endif + diff --git a/libs/luabind/luabind/detail/make_instance.hpp b/libs/luabind/luabind/detail/make_instance.hpp index 3150cf048..94c89330c 100644 --- a/libs/luabind/luabind/detail/make_instance.hpp +++ b/libs/luabind/luabind/detail/make_instance.hpp @@ -5,101 +5,167 @@ #ifndef LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP # define LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP -# include # include # include -namespace luabind { namespace detail { +namespace luabind { + namespace detail { -template -std::pair get_dynamic_class_aux( - lua_State* L, T const* p, mpl::true_) -{ - lua_pushliteral(L, "__luabind_class_id_map"); - lua_rawget(L, LUA_REGISTRYINDEX); + template + std::pair get_dynamic_class_aux(lua_State* L, T const* p, std::true_type) + { + lua_pushliteral(L, "__luabind_class_id_map"); + lua_rawget(L, LUA_REGISTRYINDEX); + class_id_map& class_ids = *static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); - class_id_map& class_ids = *static_cast( - lua_touserdata(L, -1)); + return std::make_pair(class_ids.get_local(typeid(*p)), dynamic_cast(const_cast(p))); + } - lua_pop(L, 1); + template + std::pair get_dynamic_class_aux(lua_State*, T const* p, std::false_type) + { + return std::make_pair(registered_class::id, (void*)p); + } - return std::make_pair( - class_ids.get_local(typeid(*p)) - , dynamic_cast(const_cast(p)) - ); -} + template + std::pair get_dynamic_class(lua_State* L, T* p) + { + return get_dynamic_class_aux(L, p, std::is_polymorphic()); + } -template -std::pair get_dynamic_class_aux( - lua_State*, T const* p, mpl::false_) -{ - return std::make_pair(registered_class::id, (void*)p); -} + template + class_rep* get_pointee_class(class_map const& classes, T*) + { + return classes.get(registered_class::id); + } -template -std::pair get_dynamic_class(lua_State* L, T* p) -{ - return get_dynamic_class_aux(L, p, boost::is_polymorphic()); -} + template + 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); -template -class_rep* get_pointee_class(class_map const& classes, T*) -{ - return classes.get(registered_class::id); -} + class_map const& classes = *static_cast(lua_touserdata(L, -1)); -template -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); + lua_pop(L, 1); - class_map const& classes = *static_cast( - lua_touserdata(L, -1)); + class_rep* cls = classes.get(dynamic_id); - lua_pop(L, 1); + if(!cls) { + cls = get_pointee_class(classes, get_pointer(p)); + } - class_rep* cls = classes.get(dynamic_id); + return cls; + } - if (!cls) - cls = get_pointee_class(classes, get_pointer(p)); + // Create an appropriate instance holder for the given pointer like object. + template + void make_pointer_instance(lua_State* L, P p) + { + std::pair dynamic = get_dynamic_class(L, get_pointer(p)); - return cls; -} + class_rep* cls = get_pointee_class(L, p, dynamic.first); -// Create an appropriate instance holder for the given pointer like object. -template -void make_instance(lua_State* L, P p) -{ - std::pair dynamic = get_dynamic_class(L, get_pointer(p)); + if(!cls) + { + throw std::runtime_error("Trying to use unregistered class: " + std::string(typeid(P).name())); + } - class_rep* cls = get_pointee_class(L, p, dynamic.first); + object_rep* instance = push_new_instance(L, cls); - if (!cls) - { - throw std::runtime_error("Trying to use unregistered class"); - } + using value_type = typename std::remove_reference

::type; + using holder_type = pointer_holder; - object_rep* instance = push_new_instance(L, cls); + void* storage = instance->allocate(sizeof(holder_type)); - typedef pointer_holder

holder_type; + try + { + new (storage) holder_type(std::move(p), dynamic.first, dynamic.second); + } + catch(...) + { + instance->deallocate(storage); + lua_pop(L, 1); + throw; + } - void* storage = instance->allocate(sizeof(holder_type)); + instance->set_instance(static_cast(storage)); + } - try - { - new (storage) holder_type(p, dynamic.first, dynamic.second, cls); - } - catch (...) - { - instance->deallocate(storage); - lua_pop(L, 1); - throw; - } - instance->set_instance(static_cast(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 dynamic = get_dynamic_class(L, get_pointer(val)); + class_rep* cls = get_pointee_class(L, val, dynamic.first); -}} // namespace luabind::detail + 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::type; + using holder_type = pointer_like_holder; + + void* storage = instance->allocate(sizeof(holder_type)); + + try { + new (storage) holder_type(L, std::forward(val), dynamic.first, dynamic.second); + } + catch(...) { + instance->deallocate(storage); + lua_pop(L, 1); + throw; + } + + instance->set_instance(static_cast(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::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::type; + using holder_type = value_holder; + + void* storage = instance->allocate(sizeof(holder_type)); + + try { + new (storage) holder_type(L, std::forward(val)); + } + catch(...) { + instance->deallocate(storage); + lua_pop(L, 1); + throw; + } + + instance->set_instance(static_cast(storage)); + } + + template< typename ValueType > + void make_value_instance(lua_State* L, ValueType&& val) + { + make_value_instance(L, std::forward(val), has_get_pointer()); + } + + } // namespace detail +} // namespace luabind #endif // LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP + diff --git a/libs/luabind/luabind/detail/meta.hpp b/libs/luabind/luabind/detail/meta.hpp new file mode 100644 index 000000000..8b6acc303 --- /dev/null +++ b/libs/luabind/luabind/detail/meta.hpp @@ -0,0 +1,581 @@ +// 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 + +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) {} + }; + + // 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::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; + }; + + template< typename... Types1, typename... Types2 > + type_list operator|(const type_list&, const type_list&) { + return type_list(); + } + + 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, Type > + : std::conditional< std::is_same::value, std::true_type, contains< type_list, 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 >::value }; + }; + + + template< typename... Types, typename Type > + struct push_front< type_list, Type > + { + using type = type_list< Type, Types... >; + }; + + template< typename... Types, typename Type > + struct push_back< type_list, 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, Index > { + using type = typename get< type_list, Index - 1 >::type; + }; + + template< typename Element0, typename... Elements > + struct get< type_list, 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, 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, + 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, 0, Index >, + Enwrapper< get_t< type_list, Index> >, + sub_range_t< type_list, 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, 0, Index >, + typename Function< get_t< type_list, Index> >::type, + sub_range_t< type_list, 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::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::value, + typename Case::type, + typename select_::type + >::type; + }; + + template< typename Case > + struct select_< Case > + { + using type = typename std::conditional< + std::is_convertible::value, + typename Case::type, + null_type + >::type; + }; + + template< typename T > + struct select_< default_ > { + using type = typename default_::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 > + { + using type = index_list< Index, Indices... >; + }; + + /* + Index list push back + */ + template< unsigned int... Indices, unsigned int Index > + struct push_back< index_list< Indices... >, 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::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, start, end > + { + static_assert(end >= start, "end must be greater or equal to start"); + using type = typename detail::sub_range_index< index_list, typename make_index_range::type >::type; + }; + + /* + Type list sub_range [start, end) + */ + template< unsigned int start, unsigned int end, typename... Types > + struct sub_range< type_list, start, end > + { + static_assert(end >= start, "end must be greater or equal to start"); + using type = typename detail::sub_range_type< type_list, typename make_index_range::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 > + { + static const unsigned int value = detail::sum_values::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 + diff --git a/libs/luabind/luabind/detail/object.hpp b/libs/luabind/luabind/detail/object.hpp new file mode 100644 index 000000000..a6fea5928 --- /dev/null +++ b/libs/luabind/luabind/detail/object.hpp @@ -0,0 +1,386 @@ +// 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + { + 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 + object(lua_State* interpreter, T&& value) + { + detail::push_to_lua(interpreter, std::forward(value)); + detail::stack_pop pop(interpreter, 1); + handle(interpreter, -1).swap(m_handle); + } + + template + object(lua_State* interpreter, T&& value, Policies const&) + { + detail::push_to_lua<1, Policies>(interpreter, std::forward(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 + index_proxy operator[](T const& key) const + { + return index_proxy( + *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 + { + 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 + R call_function(luabind::object const& obj, Args&&... args) + { + obj.push(obj.interpreter()); + return call_pushed_function(obj.interpreter(), std::forward(args)...); + } + + template + R resume_function(luabind::object const& obj, Args&&... args) + { + obj.push(obj.interpreter()); + return resume_pushed_function(obj.interpreter(), std::forward(args)...); + } + + // declared in luabind/lua_index_proxy.hpp + template + adl::index_proxy::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 + template + object adl::lua_proxy_interface::call(Args&&... args) + { + return call_function(derived(), std::forward(args)...); + } + + // declared in luabind/lua_proxy_interface.hpp + template + template + object adl::lua_proxy_interface::operator()(Args&&... args) + { + return call(std::forward(args)...); + } + + // declared in luabind/lua_iterator_proxy.hpp + template + adl::iterator_proxy::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 + object detail::basic_iterator::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 + struct table : Base + { + table(from_stack const& stack_reference) + : Base(stack_reference) + {} + }; + + } // namespace adl + + using adl::table; + + template + struct lua_proxy_traits > + : lua_proxy_traits + { + static bool check(lua_State* L, int idx) + { + return lua_proxy_traits::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 + inline object gettable(ValueWrapper const& table, K&& key) + { + lua_State* interpreter = lua_proxy_traits::interpreter(table); + + lua_proxy_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 2); + detail::push_to_lua(interpreter, std::forward(key)); + lua_gettable(interpreter, -2); + return object(from_stack(interpreter, -1)); + } + + template + inline void settable(ValueWrapper const& table, K&& key, T&& value) + { + lua_State* interpreter = lua_proxy_traits::interpreter(table); + + // TODO: Exception safe? + + lua_proxy_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 1); + detail::push_to_lua(interpreter, std::forward(key)); + detail::push_to_lua(interpreter, std::forward(value)); + lua_settable(interpreter, -3); + } + + template + inline object rawget(ValueWrapper const& table, K&& key) + { + lua_State* interpreter = lua_proxy_traits::interpreter( + table + ); + + lua_proxy_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 2); + detail::push_to_lua(interpreter, std::forward(key)); + lua_rawget(interpreter, -2); + return object(from_stack(interpreter, -1)); + } + + template + inline void rawset(ValueWrapper const& table, K&& key, T&& value) + { + lua_State* interpreter = lua_proxy_traits::interpreter( + table + ); + + // TODO: Exception safe? + + lua_proxy_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 1); + detail::push_to_lua(interpreter, std::forward(key)); + detail::push_to_lua(interpreter, std::forward(value)); + lua_rawset(interpreter, -3); + } + + template + inline int type(ValueWrapper const& value) + { + lua_State* interpreter = lua_proxy_traits::interpreter(value); + + lua_proxy_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 1); + return lua_type(interpreter, -1); + } + + template + inline object getmetatable(ValueWrapper const& obj) + { + lua_State* interpreter = lua_proxy_traits::interpreter(obj); + lua_proxy_traits::unwrap(interpreter, obj); + detail::stack_pop pop(interpreter, 2); + lua_getmetatable(interpreter, -1); + return object(from_stack(interpreter, -1)); + } + + template + inline void setmetatable(ValueWrapper1 const& obj, ValueWrapper2 const& metatable) + { + lua_State* interpreter = lua_proxy_traits::interpreter(obj); + lua_proxy_traits::unwrap(interpreter, obj); + detail::stack_pop pop(interpreter, 1); + lua_proxy_traits::unwrap(interpreter, metatable); + lua_setmetatable(interpreter, -2); + } + + template + inline std::tuple getupvalue(ValueWrapper const& value, int index) + { + lua_State* interpreter = lua_proxy_traits::interpreter(value); + lua_proxy_traits::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 + inline void setupvalue(ValueWrapper1 const& function, int index, ValueWrapper2 const& value) + { + lua_State* interpreter = lua_proxy_traits::interpreter(function); + + lua_proxy_traits::unwrap(interpreter, function); + detail::stack_pop pop(interpreter, 1); + lua_proxy_traits::unwrap(interpreter, value); + lua_setupvalue(interpreter, -2, index); + } + + template + object property(GetValueWrapper const& get) + { + lua_State* interpreter = lua_proxy_traits::interpreter(get); + lua_proxy_traits::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 + object property(GetValueWrapper const& get, SetValueWrapper const& set) + { + lua_State* interpreter = lua_proxy_traits::interpreter(get); + lua_proxy_traits::unwrap(interpreter, get); + lua_proxy_traits::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 + +#endif // LUABIND_OBJECT_050419_HPP + diff --git a/libs/luabind/luabind/detail/object_funs.hpp b/libs/luabind/luabind/detail/object_funs.hpp deleted file mode 100644 index 2600238d9..000000000 --- a/libs/luabind/luabind/detail/object_funs.hpp +++ /dev/null @@ -1,224 +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_OBJECT_PROXY_HPP_INCLUDED -#define LUABIND_OBJECT_PROXY_HPP_INCLUDED - -#include - -#include -#include -#include -#include -#include -#include - -#include - -namespace luabind -{ - - namespace detail - { - - namespace mpl = boost::mpl; - - template - 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::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 - boost::optional object_cast_nothrow_impl(const Obj& obj, const Policies&) - { - typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - if (obj.lua_state() == 0) return boost::optional(); - 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(); -#endif - - return boost::optional(converter.apply(L, LUABIND_DECORATE_TYPE(T), -1)); - } - } - - template - T object_cast(const object& obj) - { return detail::object_cast_impl(obj, detail::null_type()); } - - template - T object_cast(const object& obj, const Policies& p) - { return detail::object_cast_impl(obj, p); } - - template - boost::optional object_cast_nothrow(const object& obj) - { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } - - template - boost::optional object_cast_nothrow(const object& obj, const Policies& p) - { return detail::object_cast_nothrow_impl(obj, p); } - - - template - T object_cast(const detail::proxy_object& obj) - { return detail::object_cast_impl(obj, detail::null_type()); } - - template - T object_cast(const detail::proxy_object& obj, const Policies& p) - { return detail::object_cast_impl(obj, p); } - - template - boost::optional object_cast_nothrow(const detail::proxy_object& obj) - { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } - - template - boost::optional object_cast_nothrow(const detail::proxy_object& obj, const Policies& p) - { return detail::object_cast_nothrow_impl(obj, p); } - - - template - T object_cast(const detail::proxy_raw_object& obj) - { return detail::object_cast_impl(obj, detail::null_type()); } - - template - T object_cast(const detail::proxy_raw_object& obj, const Policies& p) - { return detail::object_cast_impl(obj, p); } - - template - boost::optional object_cast_nothrow(const detail::proxy_raw_object& obj) - { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } - - template - boost::optional object_cast_nothrow(const detail::proxy_raw_object& obj, const Policies& p) - { return detail::object_cast_nothrow_impl(obj, p); } - - - template - T object_cast(const detail::proxy_array_object& obj) - { return detail::object_cast_impl(obj, detail::null_type()); } - - template - T object_cast(const detail::proxy_array_object& obj, const Policies& p) - { return detail::object_cast_impl(obj, p); } - - template - boost::optional object_cast_nothrow(const detail::proxy_array_object& obj) - { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } - - template - boost::optional object_cast_nothrow(const detail::proxy_array_object& obj, const Policies& p) - { return detail::object_cast_nothrow_impl(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* ptr = object_cast(f(), adopt(_1)); - -delete ptr; - -*/ - -#endif // LUABIND_OBJECT_PROXY_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/object_rep.hpp b/libs/luabind/luabind/detail/object_rep.hpp index 93b3e39d6..139a1f64c 100644 --- a/libs/luabind/luabind/detail/object_rep.hpp +++ b/libs/luabind/luabind/detail/object_rep.hpp @@ -24,110 +24,114 @@ #ifndef LUABIND_OBJECT_REP_HPP_INCLUDED #define LUABIND_OBJECT_REP_HPP_INCLUDED -#include #include +#include #include #include +#include // std::aligned_storage #include -namespace luabind { namespace detail -{ - class class_rep; +namespace luabind { + namespace detail { - void finalize(lua_State* L, class_rep* crep); + void finalize(lua_State* L, class_rep* crep); - // this class is allocated inside lua for each pointer. - // it contains the actual c++ object-pointer. - // it also tells if it is const or not. - class LUABIND_API object_rep - { - public: - object_rep(instance_holder* instance, class_rep* crep); - ~object_rep(); - - const class_rep* crep() const { return m_classrep; } - class_rep* crep() { return m_classrep; } - - void set_instance(instance_holder* instance) { m_instance = instance; } - - void add_dependency(lua_State* L, int index); - void release_dependency_refs(lua_State* L); - - std::pair get_instance(class_id target) const + // this class is allocated inside lua for each pointer. + // it contains the actual c++ object-pointer. + // it also tells if it is const or not. + class LUABIND_API object_rep { - if (m_instance == 0) - return std::pair((void*)0, -1); - return m_instance->get(target); - } + public: + object_rep(instance_holder* instance, class_rep* crep); + ~object_rep(); - bool is_const() const + const class_rep* crep() const { return m_classrep; } + class_rep* crep() { return m_classrep; } + + void set_instance(instance_holder* instance) { m_instance = instance; } + + void add_dependency(lua_State* L, int index); + + std::pair get_instance(class_id target) const + { + if(m_instance == 0) + return std::pair(nullptr, -1); + return m_instance->get(m_classrep->casts(), target); + } + + bool is_const() const + { + return m_instance && m_instance->pointee_const(); + } + + void release() + { + if(m_instance) + m_instance->release(); + } + + void* allocate(std::size_t size) + { + if(size <= 32) { + return &m_instance_buffer; + } + else { + return std::malloc(size); + } + + } + + void deallocate(void* storage) + { + if(storage == &m_instance_buffer) { + return; + } + else { + std::free(storage); + } + } + + private: + object_rep(object_rep const&) = delete; + void operator=(object_rep const&) = delete; + + instance_holder* m_instance; + std::aligned_storage<32>::type m_instance_buffer; + class_rep* m_classrep; // the class information about this object's type + detail::lua_reference m_dependency_ref; // reference to lua table holding dependency references + }; + + template + struct delete_s { - return m_instance && m_instance->pointee_const(); - } + static void apply(void* ptr) + { + delete static_cast(ptr); + } + }; - void release() - { - if (m_instance) - m_instance->release(); - } - - void* allocate(std::size_t size) + template + struct destruct_only_s { - if (size <= 32) - return &m_instance_buffer; - return std::malloc(size); - } - - void deallocate(void* storage) - { - if (storage == &m_instance_buffer) - return; - std::free(storage); - } - - private: - - object_rep(object_rep const&) - {} - - void operator=(object_rep const&) - {} - - instance_holder* m_instance; - boost::aligned_storage<32> m_instance_buffer; - class_rep* m_classrep; // the class information about this object's type - std::size_t m_dependency_cnt; // counts dependencies - }; - - template - struct delete_s - { - static void apply(void* ptr) - { - delete static_cast(ptr); - } - }; - - template - struct destruct_only_s - { - static void apply(void* ptr) - { - // Removes unreferenced formal parameter warning on VC7. - (void)ptr; + static void apply(void* ptr) + { + // Removes unreferenced formal parameter warning on VC7. + (void)ptr; #ifndef NDEBUG - int completeness_check[sizeof(T)]; - (void)completeness_check; + int completeness_check[sizeof(T)]; + (void)completeness_check; #endif - static_cast(ptr)->~T(); - } - }; + static_cast(ptr)->~T(); + } + }; - LUABIND_API object_rep* get_instance(lua_State* L, int index); - LUABIND_API void push_instance_metatable(lua_State* L); - LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls); + LUABIND_API object_rep* get_instance(lua_State* L, int index); + 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 diff --git a/libs/luabind/luabind/detail/operator_id.hpp b/libs/luabind/luabind/detail/operator_id.hpp index ed64ba6d5..3b6564ac6 100644 --- a/libs/luabind/luabind/detail/operator_id.hpp +++ b/libs/luabind/luabind/detail/operator_id.hpp @@ -26,54 +26,58 @@ #include -namespace luabind { namespace detail { +namespace luabind { + namespace detail { - enum operator_id - { - op_add = 0, - op_sub, - op_mul, - op_div, - op_pow, - op_lt, - op_le, - op_eq, - op_call, - op_unm, - op_tostring, - op_concat, - op_len, + enum operator_id + { + op_add = 0, + op_sub, + op_mul, + op_div, + op_mod, + op_pow, + op_lt, + op_le, + op_eq, + op_call, + op_unm, + op_tostring, + op_concat, + op_len, - number_of_operators - }; + number_of_operators + }; - inline const char* get_operator_name(int i) - { - static const char* a[number_of_operators] = { - "__add", "__sub", "__mul", "__div", "__pow", - "__lt", "__le", "__eq", "__call", "__unm", - "__tostring", "__concat", "__len" }; - return a[i]; - } + inline const char* get_operator_name(int i) + { + static const char* a[number_of_operators] = { + "__add", "__sub", "__mul", "__div", "__mod", "__pow", + "__lt", "__le", "__eq", "__call", "__unm", + "__tostring", "__concat", "__len" }; + return a[i]; + } - inline const char* get_operator_symbol(int i) - { - static const char* a[number_of_operators] = { - "+", "-", "*", "/", "^", "<", - "<=", "==", "()", "- (unary)", - "tostring", "..", "#" }; - return a[i]; - } + inline const char* get_operator_symbol(int i) + { + static const char* a[number_of_operators] = { + "+", "-", "*", "/", "%", "^", "<", + "<=", "==", "()", "- (unary)", + "tostring", "..", "#" }; + return a[i]; + } - inline bool is_unary(int i) - { - // the reason why unary minus is not considered a unary operator here is - // that it always is given two parameters, where the second parameter always - // is nil. - return i == op_tostring; - } + inline bool is_unary(int i) + { + // the reason why unary minus is not considered a unary operator here is + // that it always is given two parameters, where the second parameter always + // is nil. + return i == op_tostring; + } -}} + } // namespace detail +} // namespace luabind #endif // LUABIND_OPERATOR_ID_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/other.hpp b/libs/luabind/luabind/detail/other.hpp index 679058c9e..d2f48c93d 100644 --- a/libs/luabind/luabind/detail/other.hpp +++ b/libs/luabind/luabind/detail/other.hpp @@ -33,87 +33,34 @@ // to its suitability for any purpose. #include -#include -namespace luabind -{ +namespace luabind { + template struct other { - typedef T type; - }; -} - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -namespace luabind { namespace detail -{ - template - class unwrap_other - { - public: - typedef T type; + using type = T; }; - template - class unwrap_other > - { - public: - typedef T type; - }; -}} // namespace luabind::detail +} // namespace luabind -# else // no partial specialization +namespace luabind { + namespace detail { + template + class unwrap_other + { + public: + using type = T; + }; -#include - -namespace luabind { namespace detail -{ - typedef char (&yes_other_t)[1]; - typedef char (&no_other_t)[2]; - - no_other_t is_other_test(...); - - template - yes_other_t is_other_test(type_< other >); - - template - struct other_unwrapper - { - template - struct apply - { - typedef T type; - }; - }; - - template<> - struct other_unwrapper - { - template - struct apply - { - typedef typename T::type type; - }; - }; - - template - class is_other - { - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_other_test(type_())) - == sizeof(detail::yes_other_t))); - }; - - template - class unwrap_other - : public detail::other_unwrapper< - is_other::value - >::template apply - {}; - -}} // namespace luabind::detail -#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + class unwrap_other > + { + public: + using type = T; + }; + } +} // namespace luabind::detail #endif // LUABIND_OTHER_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/pcall.hpp b/libs/luabind/luabind/detail/pcall.hpp index f0d72b162..ab9f63c02 100644 --- a/libs/luabind/luabind/detail/pcall.hpp +++ b/libs/luabind/luabind/detail/pcall.hpp @@ -25,12 +25,14 @@ #include -struct lua_State; +#include -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); -}} +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 + diff --git a/libs/luabind/luabind/detail/policy.hpp b/libs/luabind/luabind/detail/policy.hpp index 79577c9a4..195b369f5 100644 --- a/libs/luabind/luabind/detail/policy.hpp +++ b/libs/luabind/luabind/detail/policy.hpp @@ -25,998 +25,131 @@ #define LUABIND_POLICY_HPP_INCLUDED #include +#include +#include #include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include +#if LUA_VERSION_NUM < 502 +# define lua_rawlen lua_objlen +#endif namespace luabind { - namespace detail - { - struct conversion_policy_base {}; + template< typename... T > + using policy_list = meta::type_list< T... >; + using no_policies = policy_list< >; + + namespace detail { + + struct converter_policy_has_postcall_tag {}; + } - template - struct conversion_policy : detail::conversion_policy_base + // A converter policy injector instructs the call mechanism to use a certain converter policy for + // an element of a function call signature that is denoted by the parameter Index + // 0 stands for the return value, while 1 might denote an implicit "this" argument or the first + // actual argument of the function call. + template< unsigned int Index, typename T > + struct converter_policy_injector { - BOOST_STATIC_CONSTANT(int, index = N); - BOOST_STATIC_CONSTANT(bool, has_arg = HasArg); + static constexpr bool has_postcall = std::is_convertible::value; }; - class index_map - { - public: - index_map(const int* m): m_map(m) {} + // A call policy injector instructs the call mechanism to call certain static function "postcall" on type T + // after having executed a call. + template< typename T > + struct call_policy_injector + {}; - int operator[](int index) const + template< typename T, typename Enable = void > + struct default_converter; + + namespace detail + { + struct lua_to_cpp {}; + struct cpp_to_lua {}; + + struct default_policy { - return m_map[index]; - } - - private: - const int* m_map; - }; - -// template class functor; - class weak_ref; -} - -namespace luabind { namespace detail -{ - template - struct policy_cons - { - typedef H head; - typedef T tail; - - template - policy_cons > operator,(policy_cons) - { - return policy_cons >(); - } - - template - policy_cons > operator+(policy_cons) - { - return policy_cons >(); - } - - template - policy_cons > operator|(policy_cons) - { - return policy_cons >(); - } - }; - - struct indirection_layer - { - template - indirection_layer(const T&); - }; - - yes_t is_policy_cons_test(const null_type&); - template - yes_t is_policy_cons_test(const policy_cons&); - no_t is_policy_cons_test(...); - - template - struct is_policy_cons - { - static const T& t; - - BOOST_STATIC_CONSTANT(bool, value = - sizeof(is_policy_cons_test(t)) == sizeof(yes_t)); - - typedef boost::mpl::bool_ type; - }; - - template - struct is_string_literal - { - static no_t helper(indirection_layer); - static yes_t helper(const char*); - }; - - template<> - struct is_string_literal - { - static no_t helper(indirection_layer); - }; - - - namespace mpl = boost::mpl; - - template - void make_pointee_instance(lua_State* L, T& x, mpl::true_, Clone) - { - if (get_pointer(x)) - { - make_instance(L, x); - } - else - { - lua_pushnil(L); - } - } - - template - void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::true_) - { - std::auto_ptr ptr(new T(x)); - make_instance(L, ptr); - } - - template - void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::false_) - { - make_instance(L, &x); - } - - template - void make_pointee_instance(lua_State* L, T& x, Clone) - { - make_pointee_instance(L, x, has_get_pointer(), Clone()); - } - -// ********** pointer converter *********** - - struct pointer_converter - { - typedef pointer_converter type; - typedef mpl::false_ is_native; - - pointer_converter() - : result(0) - {} - - void* result; - - int const consumed_args(...) - { - return 1; - } - - template - void apply(lua_State* L, T* ptr) - { - if (ptr == 0) + template + struct specialize { - lua_pushnil(L); - return; - } - - if (luabind::get_back_reference(L, ptr)) - return; - - make_instance(L, ptr); - } + using type = default_converter; + }; + }; template - T* apply(lua_State*, by_pointer, int) - { - return static_cast(result); - } + struct is_primitive + : default_converter::is_native + {}; - template - int match(lua_State* L, by_pointer, int index) - { - if (lua_isnil(L, index)) return 0; - object_rep* obj = get_instance(L, index); - if (obj == 0) return -1; + namespace policy_detail { + template< unsigned int Index, typename PoliciesList > + struct get_converter_policy; - if (obj->is_const()) - return -1; - - std::pair s = obj->get_instance(registered_class::id); - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, by_pointer, int) - {} - }; - -// ******* value converter ******* - - struct value_converter - { - typedef value_converter type; - typedef mpl::false_ is_native; - - int const consumed_args(...) - { - return 1; - } - - value_converter() - : result(0) - {} - - void* result; - - template - void apply(lua_State* L, T x) - { - if (luabind::get_back_reference(L, x)) - return; - - make_pointee_instance(L, x, mpl::true_()); - } - - template - T apply(lua_State*, by_value, int) - { - return *static_cast(result); - } - - template - int match(lua_State* L, by_value, int index) - { - // special case if we get nil in, try to match the holder type - if (lua_isnil(L, index)) - return -1; - - object_rep* obj = get_instance(L, index); - if (obj == 0) return -1; - - std::pair s = obj->get_instance(registered_class::id); - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - -// ******* const pointer converter ******* - - struct const_pointer_converter - { - typedef const_pointer_converter type; - typedef mpl::false_ is_native; - - int const consumed_args(...) - { - return 1; - } - - const_pointer_converter() - : result(0) - {} - - void* result; - - template - void apply(lua_State* L, const T* ptr) - { - if (ptr == 0) + template< unsigned int Index, typename Injector0, typename... Injectors > + struct get_converter_policy< Index, meta::type_list< Injector0, Injectors... > > { - lua_pushnil(L); - return; - } + using type = typename get_converter_policy< Index, meta::type_list< Injectors... > >::type; + }; - if (luabind::get_back_reference(L, ptr)) - return; + template< unsigned int Index, typename ConverterPolicy, typename... Injectors > + struct get_converter_policy< Index, meta::type_list< converter_policy_injector< Index, ConverterPolicy >, Injectors... > > + { + using type = ConverterPolicy; + }; - make_instance(L, ptr); + template< unsigned int Index > + struct get_converter_policy< Index, meta::type_list< > > + { + using type = default_policy; + }; } - template - T const* apply(lua_State*, by_const_pointer, int) + // Fetches converter policy for Signature element [Index] from policy list [PolicyList] + template + using fetched_converter_policy = typename policy_detail::get_converter_policy::type; + + // Specializes converter policy [ConverterPolicy] for type [Type] in direction [Direction] + template + using specialized_converter_policy = typename ConverterPolicy::template specialize::type; + + // Fetches the converter policy for Signature element [Index] from the policy list [PolicyList] and specializes it + // for the concrete type [T] with [Direction] being either "lua_to_cpp" or "cpp_to_lua". + template + using specialized_converter_policy_n = typename policy_detail::get_converter_policy::type::template specialize::type; + + /* + call_policies + */ + + template< typename List, class Sought > + struct has_call_policy : public meta::contains< List, call_policy_injector< Sought > > { - return static_cast(result); - } + }; - template - int match(lua_State* L, by_const_pointer, int index) - { - if (lua_isnil(L, index)) return 0; - object_rep* obj = get_instance(L, index); - if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match - std::pair s = obj->get_instance(registered_class::id); - if (s.second >= 0 && !obj->is_const()) - s.second += 10; - result = s.first; - return s.second; - } + } +} // namespace luabind::detail - template - void converter_postcall(lua_State*, T, int) {} - }; - -// ******* reference converter ******* - - struct ref_converter : pointer_converter - { - typedef ref_converter type; - typedef mpl::false_ is_native; - - int const consumed_args(...) - { - return 1; - } - - template - void apply(lua_State* L, T& ref) - { - if (luabind::get_back_reference(L, ref)) - return; - - make_pointee_instance(L, ref, mpl::false_()); - } - - template - T& apply(lua_State* L, by_reference, int index) - { - assert(!lua_isnil(L, index)); - return *pointer_converter::apply(L, by_pointer(), index); - } - - template - int match(lua_State* L, by_reference, int index) - { - object_rep* obj = get_instance(L, index); - if (obj == 0) return -1; - - if (obj->is_const()) - return -1; - - std::pair s = obj->get_instance(registered_class::id); - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - -// ******** const reference converter ********* - - struct const_ref_converter - { - typedef const_ref_converter type; - typedef mpl::false_ is_native; - - int const consumed_args(...) - { - return 1; - } - - const_ref_converter() - : result(0) - {} - - void* result; - - template - void apply(lua_State* L, T const& ref) - { - if (luabind::get_back_reference(L, ref)) - return; - - make_pointee_instance(L, ref, mpl::false_()); - } - - template - T const& apply(lua_State*, by_const_reference, int) - { - return *static_cast(result); - } - - template - int match(lua_State* L, by_const_reference, int index) - { - object_rep* obj = get_instance(L, index); - if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match - - std::pair s = obj->get_instance(registered_class::id); - if (s.second >= 0 && !obj->is_const()) - s.second += 10; - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, by_const_reference, int) - { - } - }; - - // ****** enum converter ******** - - struct enum_converter - { - typedef enum_converter type; - typedef mpl::true_ is_native; - - int const consumed_args(...) - { - return 1; - } - - void apply(lua_State* L, int val) - { - lua_pushnumber(L, val); - } - - template - T apply(lua_State* L, by_value, int index) - { - return static_cast(static_cast(lua_tonumber(L, index))); - } - - template - static int match(lua_State* L, by_value, int index) - { - if (lua_isnumber(L, index)) return 0; else return -1; - } - - template - T apply(lua_State* L, by_const_reference, int index) - { - return static_cast(static_cast(lua_tonumber(L, index))); - } - - template - static int match(lua_State* L, by_const_reference, int index) - { - if (lua_isnumber(L, index)) return 0; else return -1; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - - template - struct value_wrapper_converter - { - typedef value_wrapper_converter type; - typedef mpl::true_ is_native; - - int const consumed_args(...) - { - return 1; - } - - template - T apply(lua_State* L, by_const_reference, int index) - { - return T(from_stack(L, index)); - } - - template - T apply(lua_State* L, by_value, int index) - { - return apply(L, by_const_reference(), index); - } - - template - static int match(lua_State* L, by_const_reference, int index) - { - return value_wrapper_traits::check(L, index) - ? (std::numeric_limits::max)() / LUABIND_MAX_ARITY - : -1; - } - - template - static int match(lua_State* L, by_value, int index) - { - return match(L, by_const_reference(), index); - } - - void converter_postcall(...) {} - - template - void apply(lua_State* interpreter, T const& value_wrapper) - { - value_wrapper_traits::unwrap(interpreter, value_wrapper); - } - }; - - template - struct default_converter_generator - : mpl::eval_if< - is_value_wrapper_arg - , value_wrapper_converter - , mpl::eval_if< - boost::is_enum::type> - , enum_converter - , mpl::eval_if< - is_nonconst_pointer - , pointer_converter - , mpl::eval_if< - is_const_pointer - , const_pointer_converter - , mpl::eval_if< - is_nonconst_reference - , ref_converter - , mpl::eval_if< - is_const_reference - , const_ref_converter - , value_converter - > - > - > - > - > - > - {}; - -} // namespace detail - -// *********** default_policy ***************** - -template -struct default_converter - : detail::default_converter_generator::type -{}; - -template > -struct native_converter_base -{ - typedef boost::mpl::true_ is_native; - - int const consumed_args(...) - { - return 1; - } - - template - void converter_postcall(lua_State*, U const&, int) - {} - - int match(lua_State* L, detail::by_value, int index) - { - return derived().compute_score(L, index); - } - - int match(lua_State* L, detail::by_value, int index) - { - return derived().compute_score(L, index); - } - - int match(lua_State* L, detail::by_const_reference, int index) - { - return derived().compute_score(L, index); - } - - T apply(lua_State* L, detail::by_value, int index) - { - return derived().from(L, index); - } - - T apply(lua_State* L, detail::by_value, int index) - { - return derived().from(L, index); - } - - T apply(lua_State* L, detail::by_const_reference, int index) - { - return derived().from(L, index); - } - - void apply(lua_State* L, T const& value) - { - derived().to(L, value); - } - - Derived& derived() - { - return static_cast(*this); - } -}; - -template -lua_Integer as_lua_integer(T v) -{ - return static_cast(v); +namespace luabind { + constexpr meta::index<0> return_value; + constexpr meta::index<0> result; + constexpr meta::index<1> _1; + constexpr meta::index<2> _2; + constexpr meta::index<3> _3; + constexpr meta::index<4> _4; + constexpr meta::index<5> _5; + constexpr meta::index<6> _6; + constexpr meta::index<7> _7; + constexpr meta::index<8> _8; + constexpr meta::index<9> _9; } -template -lua_Number as_lua_number(T v) -{ - return static_cast(v); -} - -# define LUABIND_NUMBER_CONVERTER(type, kind) \ - template <> \ -struct default_converter \ - : native_converter_base \ -{ \ - int compute_score(lua_State* L, int index) \ - { \ - return lua_type(L, index) == LUA_TNUMBER ? 0 : -1; \ - }; \ - \ - type from(lua_State* L, int index) \ - { \ - return static_cast(BOOST_PP_CAT(lua_to, kind)(L, index)); \ - } \ - \ - void to(lua_State* L, type const& value) \ - { \ - BOOST_PP_CAT(lua_push, kind)(L, BOOST_PP_CAT(as_lua_, kind)(value)); \ - } \ -}; \ -\ -template <> \ -struct default_converter \ - : default_converter \ -{}; \ -\ -template <> \ -struct default_converter \ - : default_converter \ -{}; - -LUABIND_NUMBER_CONVERTER(char, integer) -LUABIND_NUMBER_CONVERTER(signed char, integer) -LUABIND_NUMBER_CONVERTER(unsigned char, integer) -LUABIND_NUMBER_CONVERTER(signed short, integer) -LUABIND_NUMBER_CONVERTER(unsigned short, integer) -LUABIND_NUMBER_CONVERTER(signed int, integer) - -LUABIND_NUMBER_CONVERTER(unsigned int, number) -LUABIND_NUMBER_CONVERTER(unsigned long, number) - -LUABIND_NUMBER_CONVERTER(signed long, integer) -LUABIND_NUMBER_CONVERTER(float, number) -LUABIND_NUMBER_CONVERTER(double, number) -LUABIND_NUMBER_CONVERTER(long double, number) - -# undef LUABIND_NUMBER_CONVERTER - -template <> -struct default_converter - : native_converter_base -{ - static int compute_score(lua_State* L, int index) - { - return lua_type(L, index) == LUA_TBOOLEAN ? 0 : -1; - } - - bool from(lua_State* L, int index) - { - return lua_toboolean(L, index) == 1; - } - - void to(lua_State* L, bool value) - { - lua_pushboolean(L, value); - } -}; - -template <> -struct default_converter - : default_converter -{}; - -template <> -struct default_converter - : default_converter -{}; - -template <> -struct default_converter - : native_converter_base -{ - static int compute_score(lua_State* L, int index) - { - return lua_type(L, index) == LUA_TSTRING ? 0 : -1; - } - - std::string from(lua_State* L, int index) - { - return std::string(lua_tostring(L, index), lua_strlen(L, index)); - } - - void to(lua_State* L, std::string const& value) - { - lua_pushlstring(L, value.data(), value.size()); - } -}; - -template <> -struct default_converter - : default_converter -{}; - -template <> -struct default_converter - : default_converter -{}; - -template <> -struct default_converter -{ - typedef boost::mpl::true_ is_native; - - int const consumed_args(...) - { - return 1; - } - - template - static int match(lua_State* L, U, int index) - { - int type = lua_type(L, index); - return (type == LUA_TSTRING || type == LUA_TNIL) ? 0 : -1; - } - - template - char const* apply(lua_State* L, U, int index) - { - return lua_tostring(L, index); - } - - void apply(lua_State* L, char const* str) - { - lua_pushstring(L, str); - } - - template - void converter_postcall(lua_State*, U, int) - {} -}; - -template <> -struct default_converter - : default_converter -{}; - -template <> -struct default_converter - : default_converter -{}; - -template -struct default_converter - : default_converter -{}; - -template -struct default_converter - : default_converter -{}; - -template <> -struct default_converter -{ - int const consumed_args(...) - { - return 0; - } - - template - lua_State* apply(lua_State* L, U, int) - { - return L; - } - - template - static int match(lua_State*, U, int) - { - return 0; - } - - template - void converter_postcall(lua_State*, U, int) {} -}; - -namespace detail -{ - - struct default_policy : converter_policy_tag - { - BOOST_STATIC_CONSTANT(bool, has_arg = true); - - template - static void precall(lua_State*, T, int) {} - - template - struct apply - { - typedef default_converter type; - }; - }; - - template - struct is_primitive - : default_converter::is_native - {}; - -// ============== new policy system ================= - - template struct find_conversion_policy; - - template - struct find_conversion_impl - { - template - struct apply - { - typedef typename find_conversion_policy::type type; - }; - }; - - template<> - struct find_conversion_impl - { - template - struct apply - { - typedef typename Policies::head head; - typedef typename Policies::tail tail; - - BOOST_STATIC_CONSTANT(bool, found = (N == head::index)); - - typedef typename - boost::mpl::if_c::type - >::type type; - }; - }; - - template - struct find_conversion_impl2 - { - template - struct apply - : find_conversion_impl< - boost::is_base_and_derived::value - >::template apply - { - }; - }; - - template<> - struct find_conversion_impl2 - { - template - struct apply - { - typedef default_policy type; - }; - }; - - template - struct find_conversion_policy : find_conversion_impl2::template apply - { - }; - - template - struct policy_list_postcall - { - typedef typename List::head head; - typedef typename List::tail tail; - - static void apply(lua_State* L, const index_map& i) - { - head::postcall(L, i); - policy_list_postcall::apply(L, i); - } - }; - - template<> - struct policy_list_postcall - { - static void apply(lua_State*, const index_map&) {} - }; - -// ================================================== - -// ************** precall and postcall on policy_cons ********************* - - - template - struct policy_precall - { - typedef typename List::head head; - typedef typename List::tail tail; - - static void apply(lua_State* L, int index) - { - head::precall(L, index); - policy_precall::apply(L, index); - } - }; - - template<> - struct policy_precall - { - static void apply(lua_State*, int) {} - }; - - template - struct policy_postcall - { - typedef typename List::head head; - typedef typename List::tail tail; - - static void apply(lua_State* L, int index) - { - head::postcall(L, index); - policy_postcall::apply(L, index); - } - }; - - template<> - struct policy_postcall - { - static void apply(lua_State*, int) {} - }; - -}} // namespace luabind::detail - - -namespace luabind { namespace -{ -#if defined(__GNUC__) && ( \ - (BOOST_VERSION < 103500) \ - || (BOOST_VERSION < 103900 && (__GNUC__ * 100 + __GNUC_MINOR__ <= 400)) \ - || (__GNUC__ * 100 + __GNUC_MINOR__ < 400)) - static inline boost::arg<0> return_value() - { - return boost::arg<0>(); - } - - static inline boost::arg<0> result() - { - return boost::arg<0>(); - } -# define LUABIND_PLACEHOLDER_ARG(N) boost::arg(*)() -#elif defined(BOOST_MSVC) || defined(__MWERKS__) \ - || (BOOST_VERSION >= 103900 && defined(__GNUC__) \ - && (__GNUC__ * 100 + __GNUC_MINOR__ == 400)) - static boost::arg<0> return_value; - static boost::arg<0> result; -# define LUABIND_PLACEHOLDER_ARG(N) boost::arg -#else - boost::arg<0> return_value; - boost::arg<0> result; -# define LUABIND_PLACEHOLDER_ARG(N) boost::arg -#endif -}} - #endif // LUABIND_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/primitives.hpp b/libs/luabind/luabind/detail/primitives.hpp index 04ce17b87..a5fe734d8 100644 --- a/libs/luabind/luabind/detail/primitives.hpp +++ b/libs/luabind/luabind/detail/primitives.hpp @@ -24,62 +24,40 @@ #ifndef LUABIND_PRIMITIVES_HPP_INCLUDED #define LUABIND_PRIMITIVES_HPP_INCLUDED -#include + // std::reference_wrapper... +#include // std::true_type... #include -#include -#include +namespace luabind { + namespace detail { -namespace luabind { namespace detail -{ - template - struct identity - { - typedef T type; - }; + template + struct type_ {}; - template - struct type_ {}; + struct ltstr + { + bool operator()(const char* s1, const char* s2) const { return std::strcmp(s1, s2) < 0; } + }; - struct null_type {}; + template + struct aligned + { + char storage[N]; + }; -/* typedef char yes_t; - typedef double no_t;*/ + // returns the offset added to a Derived* when cast to a Base* + template + ptrdiff_t ptr_offset(type_, type_) + { + aligned obj; + Derived* ptr = reinterpret_cast(&obj); - struct lua_to_cpp {}; - struct cpp_to_lua {}; + return ptrdiff_t(static_cast(static_cast(static_cast(ptr))) + - static_cast(static_cast(ptr))); + } - template struct by_value {}; - template struct by_reference {}; - template struct by_const_reference {}; - template struct by_pointer {}; - template struct by_const_pointer {}; - - struct converter_policy_tag {}; - - struct ltstr - { - bool operator()(const char* s1, const char* s2) const { return std::strcmp(s1, s2) < 0; } - }; - - template - struct aligned - { - char storage[N]; - }; - - // returns the offset added to a Derived* when cast to a Base* - // TODO: return ptrdiff - template - int ptr_offset(type_, type_) - { - aligned obj; - Derived* ptr = reinterpret_cast(&obj); - - return int(static_cast(static_cast(static_cast(ptr))) - - static_cast(static_cast(ptr))); } - -}} +} #endif // LUABIND_PRIMITIVES_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/property.hpp b/libs/luabind/luabind/detail/property.hpp index 2c30ce000..e177df209 100644 --- a/libs/luabind/luabind/detail/property.hpp +++ b/libs/luabind/luabind/detail/property.hpp @@ -5,29 +5,31 @@ #ifndef LUABIND_PROPERTY_081020_HPP # define LUABIND_PROPERTY_081020_HPP -namespace luabind { namespace detail { +namespace luabind { + namespace detail { -template -struct access_member_ptr -{ - access_member_ptr(T Class::* mem_ptr) - : mem_ptr(mem_ptr) - {} + template + struct access_member_ptr + { + access_member_ptr(T Class::* mem_ptr) + : mem_ptr(mem_ptr) + {} - Result operator()(Class const& x) const - { - return const_cast(x).*mem_ptr; - } + Result operator()(Class const& x) const + { + return const_cast(x).*mem_ptr; + } - void operator()(Class& x, T const& value) const - { - x.*mem_ptr = value; - } + void operator()(Class& x, T const& value) const + { + x.*mem_ptr = value; + } - T Class::* mem_ptr; -}; + T Class::* mem_ptr; + }; -}} // namespace luabind::detail + } // namespace detail +} // namespace luabind #endif // LUABIND_PROPERTY_081020_HPP diff --git a/libs/luabind/luabind/detail/calc_arity.hpp b/libs/luabind/luabind/detail/push_to_lua.hpp similarity index 53% rename from libs/luabind/luabind/detail/calc_arity.hpp rename to libs/luabind/luabind/detail/push_to_lua.hpp index c2e0aad91..22ad8534f 100644 --- a/libs/luabind/luabind/detail/calc_arity.hpp +++ b/libs/luabind/luabind/detail/push_to_lua.hpp @@ -20,42 +20,54 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#if !BOOST_PP_IS_ITERATING -# include +#ifndef LUABIND_CONVERT_TO_LUA_HPP_INCLUDED +#define LUABIND_CONVERT_TO_LUA_HPP_INCLUDED -#ifndef LUABIND_CALC_ARITY_HPP_INCLUDED -#define LUABIND_CALC_ARITY_HPP_INCLUDED +#include +#include -#define LUABIND_FIND_CONV(z,n,text) typedef typename find_conversion_policy::type p##n; -#define LUABIND_CALC_ARITY(z,n,text) + BOOST_PP_CAT(p,n)::has_arg +namespace luabind { -namespace luabind { namespace detail -{ - template struct calc_arity; + namespace detail { - #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) - #include BOOST_PP_ITERATE() -}} + template< typename T > + struct unwrapped { + static const bool is_wrapped_ref = false; + using type = T; -#undef LUABIND_CALC_ARITY -#undef LUABIND_FIND_CONV + static const T& get(const T& t) { + return t; + } + }; - -#endif // LUABIND_CALC_ARITY_HPP_INCLUDED - -#else // BOOST_PP_ITERATE - - template<> - struct calc_arity - { - template - static int apply(constructor, Policies*) + template< typename T > + struct unwrapped< std::reference_wrapper< T > > { - BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_FIND_CONV, _) - return 0 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_CALC_ARITY, _); + static const bool is_wrapped_ref = true; + using type = T&; + + static T& get(const std::reference_wrapper& refwrap) + { + return refwrap.get(); + } + }; + + template + using unwrapped_t = typename unwrapped< T >::type; + + template + void push_to_lua(lua_State* L, T&& v) + { + using value_type = unwrapped_t>; + + specialized_converter_policy_n() + .to_lua(L, unwrapped::get(v)); } - }; + + } + +} #endif diff --git a/libs/luabind/luabind/detail/ref.hpp b/libs/luabind/luabind/detail/ref.hpp index 3edbfebfb..73d7b6328 100644 --- a/libs/luabind/luabind/detail/ref.hpp +++ b/libs/luabind/luabind/detail/ref.hpp @@ -33,80 +33,83 @@ namespace luabind { -namespace detail -{ - - struct lua_reference + namespace detail { - lua_reference(lua_State* L_ = 0) - : L(L_) - , m_ref(LUA_NOREF) - {} - lua_reference(lua_reference const& r) - : L(r.L) - , m_ref(LUA_NOREF) + + struct lua_reference { - if (!r.is_valid()) return; - r.get(L); - set(L); - } - ~lua_reference() { reset(); } + lua_reference(lua_State* L_ = 0) + : L(L_) + , m_ref(LUA_NOREF) + {} + lua_reference(lua_reference const& r) + : L(r.L) + , m_ref(LUA_NOREF) + { + if(!r.is_valid()) return; + r.get(L); + set(L); + } + ~lua_reference() { reset(); } - lua_State* state() const { return L; } + lua_State* state() const { return L; } - void operator=(lua_reference const& r) - { - // TODO: self assignment problems - reset(); - if (!r.is_valid()) return; - r.get(r.state()); - set(r.state()); - } + void operator=(lua_reference const& r) + { + // TODO: self assignment problems + reset(); + if(!r.is_valid()) return; + r.get(r.state()); + set(r.state()); + } - bool is_valid() const - { return m_ref != LUA_NOREF; } + bool is_valid() const + { + return m_ref != LUA_NOREF; + } - void set(lua_State* L_) - { - reset(); - L = L_; - m_ref = luaL_ref(L, LUA_REGISTRYINDEX); - } + void set(lua_State* L_) + { + reset(); + L = L_; + m_ref = luaL_ref(L, LUA_REGISTRYINDEX); + } - void replace(lua_State* L_) - { - lua_rawseti(L_, LUA_REGISTRYINDEX, m_ref); - } + void replace(lua_State* L_) + { + lua_rawseti(L_, LUA_REGISTRYINDEX, m_ref); + } - // L may not be the same pointer as - // was used when creating this reference - // since it may be a thread that shares - // the same globals table. - void get(lua_State* L_) const - { - assert(m_ref != LUA_NOREF); - assert(L_); - lua_rawgeti(L_, LUA_REGISTRYINDEX, m_ref); - } + // L may not be the same pointer as + // was used when creating this reference + // since it may be a thread that shares + // the same globals table. + void get(lua_State* L_) const + { + assert(m_ref != LUA_NOREF); + assert(L_); + lua_rawgeti(L_, LUA_REGISTRYINDEX, m_ref); + } - void reset() - { - if (L && m_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, m_ref); - m_ref = LUA_NOREF; - } + void reset() + { + if(L && m_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, m_ref); + m_ref = LUA_NOREF; + } - void swap(lua_reference& r) - { - assert(r.L == L); - std::swap(r.m_ref, m_ref); - } + void swap(lua_reference& r) + { + assert(r.L == L); + std::swap(r.m_ref, m_ref); + } - private: - lua_State* L; - int m_ref; - }; + private: + lua_State* L; + int m_ref; + }; -}} + } +} #endif // LUABIND_REF_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/signature_match.hpp b/libs/luabind/luabind/detail/signature_match.hpp index d76ed6627..f0f32f18e 100644 --- a/libs/luabind/luabind/detail/signature_match.hpp +++ b/libs/luabind/luabind/detail/signature_match.hpp @@ -25,37 +25,5 @@ #include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace luabind -{ - - namespace adl - { - class argument; - } - - template - 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 diff --git a/libs/luabind/luabind/detail/stack_utils.hpp b/libs/luabind/luabind/detail/stack_utils.hpp index 15f3a7fce..624d58975 100644 --- a/libs/luabind/luabind/detail/stack_utils.hpp +++ b/libs/luabind/luabind/detail/stack_utils.hpp @@ -23,30 +23,36 @@ #ifndef LUABIND_STACK_UTILS_HPP_INCLUDED #define LUABIND_STACK_UTILS_HPP_INCLUDED +#ifndef LUA_INCLUDE_HPP_INCLUDED +#include +#endif + #include -namespace luabind { namespace detail -{ +namespace luabind { + namespace detail { - struct stack_pop - { - stack_pop(lua_State* L, int n) - : m_state(L) - , m_n(n) + struct stack_pop + { + stack_pop(lua_State* L, int n) + : m_state(L) + , m_n(n) { } - ~stack_pop() - { - lua_pop(m_state, m_n); - } + ~stack_pop() + { + lua_pop(m_state, m_n); + } - private: + private: - lua_State* m_state; - int m_n; - }; -}} + lua_State* m_state; + int m_n; + }; + + } // namespace detail +} // namespace luabind #endif // LUABIND_STACK_UTILS_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/type_traits.hpp b/libs/luabind/luabind/detail/type_traits.hpp new file mode 100644 index 000000000..d1a0e7cb9 --- /dev/null +++ b/libs/luabind/luabind/detail/type_traits.hpp @@ -0,0 +1,189 @@ +// 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 +#include // reference_wrapper +#include + +namespace luabind { + + namespace detail { + + template< typename T > + struct is_const_reference + : public std::conditional< std::is_reference::value && std::is_const::type>::value, std::true_type, std::false_type >::type + { + }; + + template + struct is_nonconst_reference + : public std::conditional< std::is_reference::value && !std::is_const::type>::value, std::true_type, std::false_type >::type + { + }; + + template + struct is_const_pointer + : public std::conditional< std::is_const::type>::value && std::is_pointer::value, std::true_type, std::false_type >::type + { + }; + + template + struct is_nonconst_pointer : + public std::conditional < std::is_pointer::value && !std::is_const::type>::value, std::true_type, std::false_type >::type + { + }; + + template + struct max_c + { + enum { value = (v1 > v2) ? v1 : v2 }; + }; + + } // namespace detail + + template< typename T > + struct remove_const_reference { + using type = typename std::remove_const::type>::type; + }; + + template< typename T > + using remove_const_reference_t = typename remove_const_reference::type; + + // + // most_derived + // + + template + struct most_derived + { + using type = typename std::conditional< + std::is_base_of::value + , B + , A + >::type; + }; + + template< typename A, typename B > + using most_derived_t = typename most_derived::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::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::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::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 > : 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 > { using type = T&; }; + + template< typename T > + using apply_reference_wrapper_t = typename apply_reference_wrapper::type; + + // + // identity + // + + template< typename T > struct identity { using type = T; }; + + template< typename T > + using identity_t = typename identity::type; + + template< typename Dst > Dst implicit_cast(typename identity::type t) { return t; } + +} // namespace luabind + +#endif // LUABIND_TYPETRAITS_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/typetraits.hpp b/libs/luabind/luabind/detail/typetraits.hpp deleted file mode 100644 index f27934e98..000000000 --- a/libs/luabind/luabind/detail/typetraits.hpp +++ /dev/null @@ -1,190 +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 -#include -#include -#include -#include - -namespace luabind { namespace detail -{ - -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - template - struct is_const_type - { - typedef typename boost::mpl::if_ - , yes_t - , no_t - >::type type; - }; - - template - struct is_const_reference_helper - { - template - struct apply - { - enum - { - value = false - }; - }; - }; - - template - typename is_const_type::type is_const_reference_tester(T&); - no_t is_const_reference_tester(...); - - template<> - struct is_const_reference_helper - { - template - struct apply - { - static T getT(); - - enum - { - value = sizeof(is_const_reference_tester(getT())) == sizeof(yes_t) - }; - }; - }; - - template - struct is_const_reference - : is_const_reference_helper::value>::template apply - { - typedef boost::mpl::bool_ type; - }; - -#else - - template - struct is_const_reference - { - enum { value = false }; - typedef boost::mpl::bool_ type; - }; - - template - struct is_const_reference - { - enum { value = true }; - typedef boost::mpl::bool_ type; - }; - -#endif - - - template - struct is_nonconst_reference - { - enum - { - value = boost::is_reference::value && !is_const_reference::value - }; - typedef boost::mpl::bool_ type; - }; - - template - yes_t is_const_pointer_helper(void(*)(const A*)); - no_t is_const_pointer_helper(...); - - template - struct is_const_pointer - { - enum { value = sizeof(is_const_pointer_helper((void(*)(T))0)) == sizeof(yes_t) }; - typedef boost::mpl::bool_ type; - }; - - template - yes_t is_nonconst_pointer_helper(void(*)(A*)); - no_t is_nonconst_pointer_helper(...); - - template - struct is_nonconst_pointer - { - enum { value = sizeof(is_nonconst_pointer_helper((void(*)(T))0)) == sizeof(yes_t) && !is_const_pointer::value }; - typedef boost::mpl::bool_ type; - }; -/* - template - struct is_constructable_from_helper - { - static yes_t check(const T&); - static no_t check(...); - }; - - template - struct is_constructable_from - { - static From getFrom(); - - enum - { - value = sizeof(is_constructable_from_helper::check(getFrom())) == sizeof(yes_t) - }; - }; - - template - struct is_const_member_function_helper - { - static no_t test(...); - template - static yes_t test(R(T::*)() const); - template - static yes_t test(R(T::*)(A1) const); - template - static yes_t test(R(T::*)(A1,A2) const); - template - static yes_t test(R(T::*)(A1,A2,A3) const); - }; - - template - struct is_const_member_function - { - static U getU(); - - enum - { - value = sizeof(is_const_member_function_helper::test(getU())) == sizeof(yes_t) - }; - }; -*/ - - template - struct max_c - { - enum { value = (v1>v2)?v1:v2 }; - }; - -}} - -#endif // LUABIND_TYPETRAITS_HPP_INCLUDED - diff --git a/libs/luabind/luabind/discard_result_policy.hpp b/libs/luabind/luabind/discard_result_policy.hpp index 149a7b1bc..277d88137 100644 --- a/libs/luabind/luabind/discard_result_policy.hpp +++ b/libs/luabind/luabind/discard_result_policy.hpp @@ -20,52 +20,41 @@ // 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 -#include +#include // for index_map, etc +#include // for null_type, etc +#include -namespace luabind { namespace detail -{ - struct discard_converter - { - template - void apply(lua_State*, T) {} - }; +namespace luabind { + namespace detail { - 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 - struct apply + struct discard_converter { - typedef typename boost::mpl::if_ - , discard_converter - , can_only_convert_from_cpp_to_lua - >::type type; + template + void to_lua(lua_State*, T) {} }; - }; -}} + struct discard_result_policy + { + struct can_only_convert_from_cpp_to_lua {}; + + template + struct specialize + { + static_assert(std::is_same< Direction, cpp_to_lua >::value, "Can only convert from cpp to lua"); + using type = discard_converter; + }; + }; + + } +} namespace luabind { - detail::policy_cons< - detail::discard_result_policy, detail::null_type> const discard_result = {}; - - namespace detail - { - inline void ignore_unused_discard_result() - { - (void)discard_result; - } - } + using discard_result = meta::type_list>; } #endif // LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/error.hpp b/libs/luabind/luabind/error.hpp index b282a411a..cf42091aa 100644 --- a/libs/luabind/luabind/error.hpp +++ b/libs/luabind/luabind/error.hpp @@ -26,9 +26,13 @@ #include #include #include -#include +#include +#include +#include -struct lua_State; +#ifndef LUABIND_NO_EXCEPTIONS +#include +#endif namespace luabind { @@ -38,22 +42,19 @@ 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 - // the reason why this exception class doesn't contain - // the message itself is that std::string's copy constructor + // note 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): m_L(L) {} - lua_State* state() const throw() { return m_L; } - virtual const char* what() const throw() - { - return "lua runtime error"; - } + explicit error(lua_State* L); + + virtual const char* what() const throw(); + private: - lua_State* m_L; + std::string m_message; }; // if an object_cast<>() fails, this is thrown @@ -62,7 +63,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"; } @@ -73,9 +74,6 @@ 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(); @@ -83,7 +81,6 @@ 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(); diff --git a/libs/luabind/luabind/detail/pointee_typeid.hpp b/libs/luabind/luabind/error_callback_fun.hpp similarity index 63% rename from libs/luabind/luabind/detail/pointee_typeid.hpp rename to libs/luabind/luabind/error_callback_fun.hpp index ab4113711..f25e67d17 100644 --- a/libs/luabind/luabind/detail/pointee_typeid.hpp +++ b/libs/luabind/luabind/error_callback_fun.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2004 Daniel Wallin +// 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"), @@ -20,21 +20,27 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef POINTEE_TYPEID_040211_HPP -#define POINTEE_TYPEID_040211_HPP +#ifndef INCLUDED_error_callback_fun_hpp_GUID_1150976a_4348_495f_99ce_9d7edd00a0b8 +#define INCLUDED_error_callback_fun_hpp_GUID_1150976a_4348_495f_99ce_9d7edd00a0b8 +// Internal Includes #include -#include +#include -namespace luabind { namespace detail { +// Library/third-party includes +// - none - template - type_id pointee_typeid(T*) - { - return typeid(T); - } +// Standard includes +// - none -}} // namespace luabind::detail +namespace luabind +{ + class type_id; -#endif // POINTEE_TYPEID_040211_HPP + 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 diff --git a/libs/luabind/luabind/exception_handler.hpp b/libs/luabind/luabind/exception_handler.hpp index 0048563af..71d3fd20f 100644 --- a/libs/luabind/luabind/exception_handler.hpp +++ b/libs/luabind/luabind/exception_handler.hpp @@ -3,106 +3,73 @@ // 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 -# include -# include -# include - -# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) -# include -# include -# endif +#include // for LUABIND_API +#include +#include +#include namespace luabind { # ifndef LUABIND_NO_EXCEPTIONS -namespace detail -{ + namespace detail { - struct LUABIND_API exception_handler_base - { - exception_handler_base() - : next(0) - {} + struct LUABIND_API exception_handler_base + { + exception_handler_base() + : next(0) + {} - virtual ~exception_handler_base() {} - virtual void handle(lua_State*) const = 0; + virtual ~exception_handler_base() {} + virtual void handle(lua_State*) const = 0; - void try_next(lua_State*) const; + void try_next(lua_State*) const; - exception_handler_base* next; - }; + exception_handler_base* next; + }; - namespace mpl = boost::mpl; + template + struct exception_handler : exception_handler_base + { + using argument = E const&; - template - struct exception_handler : exception_handler_base - { -# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) - typedef typename mpl::if_< - boost::is_pointer, E, E const& - >::type argument; -# else - typedef E const& argument; -# endif + exception_handler(Handler handler) + : handler(handler) + {} - exception_handler(Handler handler) - : handler(handler) - {} + void handle(lua_State* L) const + { + try + { + try_next(L); + } + catch(argument e) + { + handler(L, e); + } + } - void handle(lua_State* L) const - { - try - { - try_next(L); - } - catch (argument e) - { - handler(L, e); - } - } + Handler handler; + }; - Handler handler; - }; + LUABIND_API void handle_exception_aux(lua_State* L); + LUABIND_API void register_exception_handler(exception_handler_base*); - LUABIND_API void handle_exception_aux(lua_State* L); - LUABIND_API void register_exception_handler(exception_handler_base*); - -} // namespace detail + } // namespace detail # endif -template -void register_exception_handler(Handler handler, boost::type* = 0) -{ + template + void register_exception_handler(Handler handler, meta::type* = 0) + { # ifndef LUABIND_NO_EXCEPTIONS - detail::register_exception_handler( - new detail::exception_handler(handler) - ); + detail::register_exception_handler( + new detail::exception_handler(handler) + ); # endif -} - -template -boost::optional handle_exceptions(lua_State* L, F fn, boost::type* = 0) -{ -# ifndef LUABIND_NO_EXCEPTIONS - try - { - return fn(); - } - catch (...) - { - detail::handle_exception_aux(L); - } - - return boost::optional(); -# else - return fn(); -# endif -} + } } // namespace luabind diff --git a/libs/luabind/luabind/from_stack.hpp b/libs/luabind/luabind/from_stack.hpp index 56bc268d8..cde5644a1 100644 --- a/libs/luabind/luabind/from_stack.hpp +++ b/libs/luabind/luabind/from_stack.hpp @@ -23,18 +23,20 @@ #ifndef LUABIND_FROM_STACK_050715_HPP #define LUABIND_FROM_STACK_050715_HPP +#include + namespace luabind { -struct from_stack -{ - from_stack(lua_State* interpreter, int index) - : interpreter(interpreter) - , index(index) - {} + struct from_stack + { + from_stack(lua_State* interpreter, int index) + : interpreter(interpreter) + , index(index) + {} - lua_State* interpreter; - int index; -}; + lua_State* interpreter; + int index; + }; } // namespace luabind diff --git a/libs/luabind/luabind/function.hpp b/libs/luabind/luabind/function.hpp index e156fbfcb..815108a98 100644 --- a/libs/luabind/luabind/function.hpp +++ b/libs/luabind/luabind/function.hpp @@ -11,50 +11,43 @@ namespace luabind { -namespace detail -{ + namespace detail + { - template - struct function_registration : registration - { - function_registration(char const* name, F f, Policies const& policies) - : name(name) - , f(f) - , policies(policies) - {} + template + struct function_registration : registration + { + function_registration(char const* name, F f) + : name(name) + , f(f) + {} - void register_(lua_State* L) const - { - object fn = make_function(L, f, deduce_signature(f), policies); + void register_(lua_State* L) const + { + object fn = make_function(L, f, PolicyInjectors()); + add_overload(object(from_stack(L, -1)), name, fn); + } - add_overload( - object(from_stack(L, -1)) - , name - , fn - ); - } + char const* name; + F f; + }; - char const* name; - F f; - Policies policies; - }; + LUABIND_API bool is_luabind_function(lua_State* L, int index); - LUABIND_API bool is_luabind_function(lua_State* L, int index); + } // namespace detail -} // namespace detail + template + scope def(char const* name, F f, policy_list const&) + { + return scope(std::unique_ptr( + new detail::function_registration>(name, f))); + } -template -scope def(char const* name, F f, Policies const& policies) -{ - return scope(std::auto_ptr( - new detail::function_registration(name, f, policies))); -} - -template -scope def(char const* name, F f) -{ - return def(name, f, detail::null_type()); -} + template + scope def(char const* name, F f) + { + return def(name, f, no_policies()); + } } // namespace luabind diff --git a/libs/luabind/luabind/detail/pointee_sizeof.hpp b/libs/luabind/luabind/function_introspection.hpp similarity index 57% rename from libs/luabind/luabind/detail/pointee_sizeof.hpp rename to libs/luabind/luabind/function_introspection.hpp index 3875c09dd..c18dab7df 100644 --- a/libs/luabind/luabind/detail/pointee_sizeof.hpp +++ b/libs/luabind/luabind/function_introspection.hpp @@ -1,5 +1,17 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg +/** @file + @brief Header + @date 2012 + + @author + Ryan Pavlik + and + 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 @@ -20,35 +32,25 @@ // 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 +#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 +#include + +// Library/third-party includes +// - none + +// Standard includes +// - none -#include namespace luabind { - namespace detail { + LUABIND_API int bind_function_introspection(lua_State * L); - template T& deref_type(T(*)(), int); - template T& deref_type(T*(*)(), long); +} // end of namespace luabind - } // namespace detail - - // returns the indirect sizeof U, as in - // sizeof(T*) = sizeof(T) - // sizeof(T&) = sizeof(T) - // sizeof(T) = sizeof(T) - template - struct pointee_sizeof - { - BOOST_STATIC_CONSTANT(int, value = ( - sizeof(detail::deref_type((T(*)())0), 0L) - )); - - typedef boost::mpl::int_ type; - }; - -} // namespace luabind - -#endif // POINTEE_SIZEOF_040211_HPP +#endif // INCLUDED_function_introspection_hpp_GUID_b55783e7_e6da_4816_925e_9256245c1065 diff --git a/libs/luabind/luabind/get_main_thread.hpp b/libs/luabind/luabind/get_main_thread.hpp index f94d6e4bc..80b44ef10 100644 --- a/libs/luabind/luabind/get_main_thread.hpp +++ b/libs/luabind/luabind/get_main_thread.hpp @@ -6,11 +6,13 @@ # define LUABIND_GET_MAIN_THREAD_090321_HPP # include +# include 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 + diff --git a/libs/luabind/luabind/handle.hpp b/libs/luabind/luabind/handle.hpp index 14adacbae..5aa98aa14 100644 --- a/libs/luabind/luabind/handle.hpp +++ b/libs/luabind/luabind/handle.hpp @@ -24,119 +24,115 @@ #define LUABIND_HANDLE_050420_HPP #include -#include +#include +#include namespace luabind { -// 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); - handle(handle const& other); - ~handle(); + // 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); + handle(handle const& other); + ~handle(); - handle& operator=(handle const& other); - void swap(handle& other); + handle& operator=(handle const& other); + void swap(handle& other); - void push(lua_State* interpreter) const; + void push(lua_State* interpreter) const; - lua_State* interpreter() const; + lua_State* interpreter() const; - void replace(lua_State* interpreter, int stack_index); + void replace(lua_State* interpreter, int stack_index); -private: - lua_State* m_interpreter; - int m_index; -}; + 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; - lua_rawgeti(m_interpreter, LUA_REGISTRYINDEX, other.m_index); - m_index = luaL_ref(m_interpreter, LUA_REGISTRYINDEX); -} + 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) -{ - lua_pushvalue(interpreter, stack_index); - m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX); -} + 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) -{ - 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) + { + 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) -{ - handle(other).swap(*this); - return *this; -} + inline handle& handle::operator=(handle const& other) + { + handle(other).swap(*this); + return *this; + } -inline void handle::swap(handle& other) -{ - std::swap(m_interpreter, other.m_interpreter); - std::swap(m_index, other.m_index); -} + 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 -{ - lua_rawgeti(interpreter, LUA_REGISTRYINDEX, m_index); -} + inline void handle::push(lua_State* interpreter) const + { + lua_rawgeti(interpreter, LUA_REGISTRYINDEX, m_index); + } -inline lua_State* handle::interpreter() const -{ - return m_interpreter; -} + inline lua_State* handle::interpreter() const + { + return m_interpreter; + } -inline void handle::replace(lua_State* interpreter, int stack_index) -{ - lua_pushvalue(interpreter, stack_index); - lua_rawseti(interpreter, LUA_REGISTRYINDEX, m_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 value_wrapper_traits -{ - typedef boost::mpl::true_ is_specialized; + template<> + struct lua_proxy_traits + { + using is_specialized = std::true_type; - static lua_State* interpreter(handle const& value) - { - return value.interpreter(); - } - - static void unwrap(lua_State* interpreter, handle const& value) - { - value.push(interpreter); - } + static lua_State* interpreter(handle const& value) + { + return value.interpreter(); + } - static bool check(...) - { - return true; - } -}; + static void unwrap(lua_State* interpreter, handle const& value) + { + value.push(interpreter); + } + + static bool check(...) + { + return true; + } + }; } // namespace luabind diff --git a/libs/luabind/luabind/iterator_policy.hpp b/libs/luabind/luabind/iterator_policy.hpp index b1f827fe3..03840a968 100644 --- a/libs/luabind/luabind/iterator_policy.hpp +++ b/libs/luabind/luabind/iterator_policy.hpp @@ -5,108 +5,105 @@ #ifndef LUABIND_ITERATOR_POLICY__071111_HPP # define LUABIND_ITERATOR_POLICY__071111_HPP -# include -# include -# include +# include // for LUABIND_ANONYMOUS_FIX +# include // for convert_to_lua +# include // for index_map, etc -namespace luabind { namespace detail { +# include // for operator new -template -struct iterator -{ - static int next(lua_State* L) - { - iterator* self = static_cast( - lua_touserdata(L, lua_upvalueindex(1))); +namespace luabind { + namespace detail { - if (self->first != self->last) - { - convert_to_lua(L, *self->first); - ++self->first; - } - else - { - lua_pushnil(L); - } + template + struct iterator + { + static int next(lua_State* L) + { + iterator* self = static_cast( + lua_touserdata(L, lua_upvalueindex(1))); - return 1; - } + if(self->first != self->last) + { + push_to_lua(L, *self->first); + ++self->first; + } else + { + lua_pushnil(L); + } - static int destroy(lua_State* L) - { - iterator* self = static_cast(lua_touserdata(L, 1)); - self->~iterator(); - return 0; - } + return 1; + } - iterator(Iterator first, Iterator last) - : first(first) - , last(last) - {} + static int destroy(lua_State* L) + { + iterator* self = static_cast(lua_touserdata(L, 1)); + self->~iterator(); + return 0; + } - Iterator first; - Iterator last; -}; + iterator(Iterator first, Iterator last) + : first(first) + , last(last) + {} -template -int make_range(lua_State* L, Iterator first, Iterator last) -{ - void* storage = lua_newuserdata(L, sizeof(iterator)); - lua_newtable(L); - lua_pushcclosure(L, iterator::destroy, 0); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L, -2); - lua_pushcclosure(L, iterator::next, 1); - new (storage) iterator(first, last); - return 1; -} + Iterator first; + Iterator last; + }; -template -int make_range(lua_State* L, Container& container) -{ - return make_range(L, container.begin(), container.end()); -} + template + int make_range(lua_State* L, Iterator first, Iterator last) + { + void* storage = lua_newuserdata(L, sizeof(iterator)); + lua_newtable(L); + lua_pushcclosure(L, iterator::destroy, 0); + lua_setfield(L, -2, "__gc"); + lua_setmetatable(L, -2); + lua_pushcclosure(L, iterator::next, 1); + new (storage) iterator(first, last); + return 1; + } -struct iterator_converter -{ - typedef iterator_converter type; + template + int make_range(lua_State* L, Container& container) + { + return make_range(L, container.begin(), container.end()); + } - template - void apply(lua_State* L, Container& container) - { - make_range(L, container); - } + struct iterator_converter + { + using type = iterator_converter; - template - void apply(lua_State* L, Container const& container) - { - make_range(L, container); - } -}; + template + void to_lua(lua_State* L, Container& container) + { + make_range(L, container); + } -struct iterator_policy : conversion_policy<0> -{ - static void precall(lua_State*, index_map const&) - {} + template + void tu_lua(lua_State* L, Container const& container) + { + make_range(L, container); + } + }; - static void postcall(lua_State*, index_map const&) - {} + struct iterator_policy + { + template + struct specialize + { + static_assert(std::is_same::value, "Iterator policy can only convert from cpp to lua."); + using type = iterator_converter; + }; + }; - template - struct apply - { - typedef iterator_converter type; - }; -}; + } // namespace detail +} // namespace luabind -}} // namespace luabind::detail +namespace luabind { -namespace luabind { namespace { + using return_stl_iterator = policy_list>; -LUABIND_ANONYMOUS_FIX detail::policy_cons< - detail::iterator_policy, detail::null_type> return_stl_iterator; - -}} // namespace luabind::unnamed +} // namespace luabind #endif // LUABIND_ITERATOR_POLICY__071111_HPP diff --git a/libs/luabind/luabind/lua_argument_proxy.hpp b/libs/luabind/luabind/lua_argument_proxy.hpp new file mode 100644 index 000000000..ed5997961 --- /dev/null +++ b/libs/luabind/luabind/lua_argument_proxy.hpp @@ -0,0 +1,71 @@ +#ifndef LUA_ARGUMENT_PROXY_HPP_INCLUDED +#define LUA_ARGUMENT_PROXY_HPP_INCLUDED + +#include +#include +#include +#include + +namespace luabind { + + namespace adl { + + class argument : public lua_proxy_interface + { + 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 + index_proxy operator[](T const& key) const + { + return index_proxy(*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 + { + 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 + diff --git a/libs/luabind/luabind/lua_include.hpp b/libs/luabind/luabind/lua_include.hpp index 7327b533e..64c595bf3 100644 --- a/libs/luabind/luabind/lua_include.hpp +++ b/libs/luabind/luabind/lua_include.hpp @@ -28,8 +28,8 @@ extern "C" { #endif - #include "lua.h" - #include "lauxlib.h" +#include "lua.h" +#include "lauxlib.h" #ifndef LUABIND_CPLUSPLUS_LUA } diff --git a/libs/luabind/luabind/lua_index_proxy.hpp b/libs/luabind/luabind/lua_index_proxy.hpp new file mode 100644 index 000000000..f8c726de1 --- /dev/null +++ b/libs/luabind/luabind/lua_index_proxy.hpp @@ -0,0 +1,137 @@ +#ifndef LUA_INDEX_PROXY_HPP_INCLUDED +#define LUA_INDEX_PROXY_HPP_INCLUDED + +#include +#include +#include +#include + +namespace luabind { + + namespace adl { + + class object; + + template + class index_proxy + : public lua_proxy_interface > + { + public: + using this_type = index_proxy; + + template + 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::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 + this_type& operator=(T&& value) + { + lua_proxy_traits::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(value)); + lua_settable(m_interpreter, -3); + return *this; + } + + this_type& operator=(this_type const& value) + { + lua_proxy_traits::unwrap(m_interpreter, m_next); + detail::stack_pop pop(m_interpreter, 1); + + lua_pushvalue(m_interpreter, m_key_index); + detail::push(m_interpreter, value); + lua_settable(m_interpreter, -3); + return *this; + } + + template + index_proxy operator[](T const& key) + { + return index_proxy(*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 + inline void index_proxy::push(lua_State* interpreter) + { + assert(interpreter == m_interpreter); + + lua_proxy_traits::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 + struct lua_proxy_traits > + { + using is_specialized = std::true_type; + + template + static lua_State* interpreter(adl::index_proxy const& proxy) + { + return proxy.interpreter(); + } + + template + static void unwrap(lua_State* interpreter, adl::index_proxy const& proxy) + { + const_cast&>(proxy).push(interpreter); + } + }; + + +} // namespace luabind + +#endif + diff --git a/libs/luabind/luabind/lua_iterator_proxy.hpp b/libs/luabind/luabind/lua_iterator_proxy.hpp new file mode 100644 index 000000000..155c67ef2 --- /dev/null +++ b/libs/luabind/luabind/lua_iterator_proxy.hpp @@ -0,0 +1,230 @@ +#ifndef LUA_ITERATOR_PROXY_HPP_INCLUDED +#define LUA_ITERATOR_PROXY_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include + +#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 iterator_proxy : + public lua_proxy_interface > + { + 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 + iterator_proxy& operator=(T&& value) + { + lua_pushvalue(m_interpreter, m_key_index); + detail::push_to_lua(m_interpreter, std::forward(value)); + AccessPolicy::set(m_interpreter, m_table_index); + return *this; + } + + template + index_proxy > operator[](Key const& key) + { + return index_proxy >( + *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 + struct lua_proxy_traits > + { + using is_specialized = std::true_type; + + template + static lua_State* interpreter(Proxy const& p) + { + return p.interpreter(); + } + + template + static void unwrap(lua_State* interpreter, Proxy const& p) + { + // TODO: Why const_cast? + const_cast(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 basic_iterator : + public detail::crtp_iterator< basic_iterator, adl::iterator_proxy, std::forward_iterator_tag, adl::iterator_proxy > + { + public: + basic_iterator() + : m_interpreter(0) + {} + + template + explicit basic_iterator(ValueWrapper const& value_wrapper) + : m_interpreter(lua_proxy_traits::interpreter(value_wrapper)) + { + detail::stack_pop pop(m_interpreter, 1); + lua_proxy_traits::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 dereference() const + { + return adl::iterator_proxy(m_interpreter, m_table, m_key); + } + + lua_State* m_interpreter; + handle m_table; + handle m_key; + }; + + } // namespace detail + + using iterator = detail::basic_iterator; + using raw_iterator = detail::basic_iterator; + +} + +#if LUA_VERSION_NUM < 502 +#undef LUA_OPEQ +#undef lua_compare +#endif + +#endif + diff --git a/libs/luabind/luabind/detail/most_derived.hpp b/libs/luabind/luabind/lua_proxy.hpp similarity index 64% rename from libs/luabind/luabind/detail/most_derived.hpp rename to libs/luabind/luabind/lua_proxy.hpp index 4dd9d9159..6ecdf82fc 100644 --- a/libs/luabind/luabind/detail/most_derived.hpp +++ b/libs/luabind/luabind/lua_proxy.hpp @@ -20,25 +20,35 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef MOST_DERIVED_051018_HPP -# define MOST_DERIVED_051018_HPP +#ifndef LUABIND_VALUE_WRAPPER_050419_HPP +#define LUABIND_VALUE_WRAPPER_050419_HPP -# include -# include +#include +#include -namespace luabind { namespace detail { +namespace luabind { -template -struct most_derived -{ - typedef typename boost::mpl::if_< - boost::is_base_and_derived - , WrappedClass - , Class - >::type type; -}; + // + // Concept "lua_proxy" + // -}} // namespace luabind::detail + template + struct lua_proxy_traits + { + using is_specialized = std::false_type; + }; -#endif // MOST_DERIVED_051018_HPP + template + struct is_lua_proxy_type + : lua_proxy_traits::is_specialized + {}; + + template< class T > + struct is_lua_proxy_arg + : std::conditional>::value, std::true_type, std::false_type >::type + {}; + +} // namespace luabind + +#endif // LUABIND_VALUE_WRAPPER_050419_HPP diff --git a/libs/luabind/luabind/lua_proxy_interface.hpp b/libs/luabind/luabind/lua_proxy_interface.hpp new file mode 100644 index 000000000..80f2de354 --- /dev/null +++ b/libs/luabind/luabind/lua_proxy_interface.hpp @@ -0,0 +1,306 @@ +#ifndef LUA_PROXY_INTERFACE_HPP_INCLUDED +#define LUA_PROXY_INTERFACE_HPP_INCLUDED + +#include +#include +#include +#include + +#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 lua_proxy_interface; + + namespace check_object_interface + { + template + std::true_type check(lua_proxy_interface*); + std::false_type check(void*); + } // namespace is_object_interface_aux + + template + struct is_object_interface : public decltype(check_object_interface::check((remove_const_reference_t*)nullptr)) + {}; + + template + struct enable_binary + : std::enable_if< is_object_interface::value || is_object_interface::value, R > + {}; + + template + int binary_interpreter(lua_State*& L, T const& lhs, U const& rhs, std::true_type, std::true_type) + { + L = lua_proxy_traits::interpreter(lhs); + lua_State* L2 = lua_proxy_traits::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 + int binary_interpreter(lua_State*& L, T const& x, U const&, std::true_type, std::false_type) + { + L = lua_proxy_traits::interpreter(x); + return 0; + } + + template + int binary_interpreter(lua_State*& L, T const&, U const& x, std::false_type, std::true_type) + { + L = lua_proxy_traits::interpreter(x); + return 0; + } + + template + int binary_interpreter(lua_State*& L, T const& x, U const& y) + { + return binary_interpreter(L, x, y, is_lua_proxy_type(), is_lua_proxy_type()); + } + + template + typename enable_binary::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)); + detail::stack_pop pop2(L, 1); + detail::push_to_lua(L, std::forward(rhs)); + return lua_compare(L, -1, -2, LUA_OPEQ) != 0; + } + + template + typename enable_binary::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)); + detail::stack_pop pop2(L, 1); + detail::push_to_lua(L, std::forward(rhs)); + return lua_compare(L, -1, -2, LUA_OPLT) != 0; + } + + template + std::ostream& operator<<(std::ostream& os, lua_proxy_interface const& v) + { + using namespace luabind; + lua_State* interpreter = lua_proxy_traits::interpreter( + static_cast(v)); + detail::stack_pop pop(interpreter, 1); + lua_proxy_traits::unwrap(interpreter, static_cast(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(os)); + return os; + } + + + template + typename enable_binary::type + operator>(LHS const& lhs, RHS const& rhs) + { + return !(lhs < rhs || lhs == rhs); + } + + template + typename enable_binary::type + operator<=(LHS const& lhs, RHS const& rhs) + { + return lhs < rhs || lhs == rhs; + } + + template + typename enable_binary::type + operator>=(LHS const& lhs, RHS const& rhs) + { + return !(lhs < rhs); + } + + template + typename enable_binary::type + operator!=(LHS const& lhs, RHS const& rhs) + { + return !(lhs == rhs); + } + + template + class lua_proxy_interface + { + public: + ~lua_proxy_interface() {} + + // defined in luabind/detail/object.hpp + template + object operator()(Args&&... args); + + // defined in luabind/detail/object.hpp + template + object call(Args&&... args); + + explicit operator bool() const + { + lua_State* L = lua_proxy_traits::interpreter(derived()); + if(!L) return 0; + lua_proxy_traits::unwrap(L, derived()); + detail::stack_pop pop(L, 1); + return lua_toboolean(L, -1) == 1; + } + + private: + Derived& derived() { return *static_cast(this); } + Derived const& derived() const { return *static_cast(this); } + }; + + } + + template + std::string to_string(adl::lua_proxy_interface const& v) + { + using namespace luabind; + lua_State* interpreter = lua_proxy_traits::interpreter(static_cast(v)); + detail::stack_pop pop(interpreter, 1); + lua_proxy_traits::unwrap(interpreter, static_cast(v)); + char const* p = lua_tostring(interpreter, -1); + std::size_t len = lua_rawlen(interpreter, -1); + return std::string(p, len); + } + + namespace detail + { + template + ReturnType object_cast_aux(ValueWrapper const& value_wrapper, T*, Policies*, ErrorPolicy error_policy, ReturnType*) + { + lua_State* interpreter = lua_proxy_traits::interpreter(value_wrapper); + +#ifndef LUABIND_NO_ERROR_CHECKING + if(!interpreter) + return error_policy.handle_error(interpreter, typeid(void)); +#endif + lua_proxy_traits::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(), -1) < 0) { + return error_policy.handle_error(interpreter, typeid(T)); + } + return cv.to_cpp(interpreter, decorate_type_t(), -1); + } + + template + 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::type*)0; //DEAD CODE! + } + }; + + template + 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 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*)0); + } + + template 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*)0); + } + + template 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(default_value), (ReturnValue*)0); + } + + template 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(default_value), (ReturnValue*)0); + } + + template + inline lua_CFunction tocfunction(ValueWrapper const& value) + { + lua_State* interpreter = lua_proxy_traits::interpreter(value); + lua_proxy_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 1); + return lua_tocfunction(interpreter, -1); + } + + template + inline T* touserdata(ValueWrapper const& value) + { + lua_State* interpreter = lua_proxy_traits::interpreter(value); + + lua_proxy_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 1); + return static_cast(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 + diff --git a/libs/luabind/luabind/get_pointer.hpp b/libs/luabind/luabind/lua_state_fwd.hpp similarity index 77% rename from libs/luabind/luabind/get_pointer.hpp rename to libs/luabind/luabind/lua_state_fwd.hpp index b9aae48a7..215574a13 100644 --- a/libs/luabind/luabind/get_pointer.hpp +++ b/libs/luabind/luabind/lua_state_fwd.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2005 Daniel Wallin +// 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"), @@ -20,20 +20,19 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef LUABIND_GET_POINTER_051023_HPP -# define LUABIND_GET_POINTER_051023_HPP +#ifndef LUABIND_LUA_STATE_FWD_HPP +#define LUABIND_LUA_STATE_FWD_HPP -// -// We need these overloads in the luabind namespace. -// +#ifndef LUABIND_CPLUSPLUS_LUA +extern "C" +{ +#endif -# include + struct lua_State; -namespace luabind { +#ifndef LUABIND_CPLUSPLUS_LUA +} +#endif -using boost::get_pointer; - -} // namespace luabind - -#endif // LUABIND_GET_POINTER_051023_HPP +#endif // LUABIND_BACK_REFERENCE_FWD_040510_HPP diff --git a/libs/luabind/luabind/luabind.hpp b/libs/luabind/luabind/luabind.hpp index 82298484c..9b47f01e2 100644 --- a/libs/luabind/luabind/luabind.hpp +++ b/libs/luabind/luabind/luabind.hpp @@ -28,5 +28,7 @@ #include #include #include +#include #endif // LUABIND_BIND_HPP_INCLUDED + diff --git a/libs/luabind/luabind/make_function.hpp b/libs/luabind/luabind/make_function.hpp index a1ac8716b..81bbe8f8f 100644 --- a/libs/luabind/luabind/make_function.hpp +++ b/libs/luabind/luabind/make_function.hpp @@ -3,119 +3,125 @@ // 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 -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include namespace luabind { -namespace detail -{ + namespace detail + { # ifndef LUABIND_NO_EXCEPTIONS - LUABIND_API void handle_exception_aux(lua_State* L); + 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 BOOST_MSVC + // 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 # pragma pack(push) # pragma pack(16) # endif - template - struct function_object_impl : function_object - { - function_object_impl(F f, Policies const& policies) - : function_object(&entry_point) - , f(f) - , policies(policies) - {} + template + struct function_object_impl : function_object + { + function_object_impl(F f) + : function_object(&entry_point), f(f) + {} - int call(lua_State* L, invoke_context& ctx) const - { - return invoke(L, *this, ctx, f, Signature(), policies); - } + 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(L, *this, ctx, f); +#endif + } - void format_signature(lua_State* L, char const* function) const - { - detail::format_signature(L, function, Signature()); - } + void format_signature(lua_State* L, char const* function) const + { + detail::format_signature(L, function, Signature()); + } - static int entry_point(lua_State* L) - { - function_object_impl const* impl = - *(function_object_impl const**)lua_touserdata(L, lua_upvalueindex(1)); + static bool invoke_defer(lua_State* L, function_object_impl* impl, invoke_context& ctx, int& results) + { + bool exception_caught = false; - invoke_context ctx; + try { +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + results = invoke(L, *impl, ctx, impl->f, Signature(), InjectorList()); +#else + results = invoke(L, *impl, ctx, impl->f); +#endif + } + catch(...) { + exception_caught = true; + handle_exception_aux(L); + } - int results = 0; + 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(impl_const); + invoke_context ctx; + int results = 0; # ifndef LUABIND_NO_EXCEPTIONS - bool exception_caught = false; - - try - { - results = invoke( - L, *impl, ctx, impl->f, Signature(), impl->policies); - } - catch (...) - { - exception_caught = true; - handle_exception_aux(L); - } - - if (exception_caught) - lua_error(L); + bool exception_caught = invoke_defer(L, impl, ctx, results); + if(exception_caught) lua_error(L); # else - results = invoke(L, *impl, ctx, impl->f, Signature(), impl->policies); +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + results = invoke(L, *impl, ctx, impl->f, Signature(), InjectorList()); +#else + results = invoke(L, *impl, ctx, impl->f); +#endif # endif + if(!ctx) { + ctx.format_error(L, impl); + lua_error(L); + } - if (!ctx) - { - ctx.format_error(L, impl); - lua_error(L); - } + return results; + } - return results; - } + F f; + }; - F f; - Policies policies; - }; - -# ifdef BOOST_MSVC +# ifdef _MSC_VER # 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&); - LUABIND_API void add_overload(object const&, char const*, object const&); + } // namespace detail -} // namespace detail + template + 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, meta::type_list< PolicyInjectors...> >(f)); + } -template -object make_function(lua_State* L, F f, Signature, Policies) -{ - return detail::make_function_aux( - L - , new detail::function_object_impl( - f, Policies() - ) - ); -} + template + object make_function(lua_State* L, F f, meta::type_list< PolicyInjectors... >) + { + return make_function(L, f, deduce_signature_t(), meta::type_list< PolicyInjectors... >()); + } -template -object make_function(lua_State* L, F f) -{ - return make_function(L, detail::deduce_signature(f), detail::null_type()); -} + template + object make_function(lua_State* L, F f) + { + return make_function(L, f, deduce_signature_t(), no_policies()); + } } // namespace luabind diff --git a/libs/luabind/luabind/nil.hpp b/libs/luabind/luabind/nil.hpp index 5f9ba4db1..9955cdb21 100644 --- a/libs/luabind/luabind/nil.hpp +++ b/libs/luabind/luabind/nil.hpp @@ -27,13 +27,12 @@ namespace luabind { - namespace detail - { - struct nil_type {}; - } + namespace detail + { + struct nil_type {}; + } - // defined in class.cpp - extern LUABIND_API detail::nil_type nil; + constexpr detail::nil_type nil; } #endif diff --git a/libs/luabind/luabind/no_dependency.hpp b/libs/luabind/luabind/no_dependency.hpp new file mode 100644 index 000000000..89f996bee --- /dev/null +++ b/libs/luabind/luabind/no_dependency.hpp @@ -0,0 +1,28 @@ +// Copyright Daniel Wallin 2010. 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_NO_DEPENDENCY_100324_HPP +# define LUABIND_NO_DEPENDENCY_100324_HPP + +# include + +namespace luabind { + + namespace detail + { + + struct no_dependency_policy + { + static void postcall(lua_State*, int /*results*/, meta::index_list_tag) + {} + }; + + } // namespace detail + + using no_dependency = policy_list>; + +} // namespace luabind + +#endif // LUABIND_NO_DEPENDENCY_100324_HPP + diff --git a/libs/luabind/luabind/object.hpp b/libs/luabind/luabind/object.hpp index 0feb7bd48..5659486e5 100644 --- a/libs/luabind/luabind/object.hpp +++ b/libs/luabind/luabind/object.hpp @@ -20,1393 +20,11 @@ // 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 +#ifndef LUABIND_OBJECT_HPP +#define LUABIND_OBJECT_HPP -#include // detail::push() -#include // detail::push() -#include // value_wrapper_traits specializations -#include -#include -#include +#include +#include -#include -#include -#include -#include -#include -#include -#include -#include // REFACTOR -#include - -#include // iterator - -#include -#include - -namespace luabind { - -namespace detail -{ - namespace mpl = boost::mpl; - - template - void push_aux(lua_State* interpreter, T& value, ConverterGenerator*) - { - typedef typename boost::mpl::if_< - boost::is_reference_wrapper - , BOOST_DEDUCED_TYPENAME boost::unwrap_reference::type& - , T - >::type unwrapped_type; - - typename mpl::apply_wrap2< - ConverterGenerator,unwrapped_type,cpp_to_lua - >::type cv; - - cv.apply( - interpreter - , boost::implicit_cast< - BOOST_DEDUCED_TYPENAME boost::unwrap_reference::type& - >(value) - ); - } - - template - void push(lua_State* interpreter, T& value, Policies const&) - { - typedef typename find_conversion_policy< - 0 - , Policies - >::type converter_policy; - - push_aux(interpreter, value, (converter_policy*)0); - } - - template - void push(lua_State* interpreter, T& value) - { - push(interpreter, value, null_type()); - } - -} // namespace detail - -namespace adl -{ - namespace mpl = boost::mpl; - - template - class object_interface; - - namespace is_object_interface_aux - { - typedef char (&yes)[1]; - typedef char (&no)[2]; - - template - yes check(object_interface*); - no check(void*); - - template - struct impl - { - BOOST_STATIC_CONSTANT(bool, value = - sizeof(is_object_interface_aux::check((T*)0)) == sizeof(yes) - ); - - typedef mpl::bool_ type; - }; - - } // namespace detail - - template - struct is_object_interface - : is_object_interface_aux::impl::type - {}; - - template - struct enable_binary -# ifndef BOOST_NO_SFINAE - : boost::enable_if< - mpl::or_< - is_object_interface - , is_object_interface - > - , R - > - {}; -# else - { - typedef R type; - }; -# endif - - template - int binary_interpreter(lua_State*& L, T const& lhs, U const& rhs - , boost::mpl::true_, boost::mpl::true_) - { - L = value_wrapper_traits::interpreter(lhs); - lua_State* L2 = value_wrapper_traits::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 - int binary_interpreter(lua_State*& L, T const& x, U const& - , boost::mpl::true_, boost::mpl::false_) - { - L = value_wrapper_traits::interpreter(x); - return 0; - } - - template - int binary_interpreter(lua_State*& L, T const&, U const& x, boost::mpl::false_, boost::mpl::true_) - { - L = value_wrapper_traits::interpreter(x); - return 0; - } - - template - int binary_interpreter(lua_State*& L, T const& x, U const& y) - { - return binary_interpreter( - L - , x - , y - , is_value_wrapper() - , is_value_wrapper() - ); - } - -#define LUABIND_BINARY_OP_DEF(op, fn) \ - template \ - typename enable_binary::type \ - operator op(LHS const& lhs, RHS const& 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(L, lhs); \ - detail::stack_pop pop2(L, 1); \ - detail::push(L, rhs); \ -\ - return fn(L, -1, -2) != 0; \ - } - -LUABIND_BINARY_OP_DEF(==, lua_equal) -LUABIND_BINARY_OP_DEF(<, lua_lessthan) - - template - std::ostream& operator<<(std::ostream& os - , object_interface const& v) - { - using namespace luabind; - lua_State* interpreter = value_wrapper_traits::interpreter( - static_cast(v)); - detail::stack_pop pop(interpreter, 1); - value_wrapper_traits::unwrap(interpreter - , static_cast(v)); - char const* p = lua_tostring(interpreter, -1); - std::size_t len = lua_strlen(interpreter, -1); - std::copy(p, p + len, std::ostream_iterator(os)); - return os; - } - -#undef LUABIND_BINARY_OP_DEF - - template - typename enable_binary::type - operator>(LHS const& lhs, RHS const& rhs) - { - return !(lhs < rhs || lhs == rhs); - } - - template - typename enable_binary::type - operator<=(LHS const& lhs, RHS const& rhs) - { - return lhs < rhs || lhs == rhs; - } - - template - typename enable_binary::type - operator>=(LHS const& lhs, RHS const& rhs) - { - return !(lhs < rhs); - } - - template - typename enable_binary::type - operator!=(LHS const& lhs, RHS const& rhs) - { - return !(lhs == rhs); - } - - template - struct call_proxy; - - template - class index_proxy; - - class object; - - template - class object_interface - { - struct safe_bool_type {}; - public: - ~object_interface() {} - - call_proxy > operator()(); - - template - call_proxy< - Derived - , boost::tuples::tuple - > operator()(A0 const& a0) - { - typedef boost::tuples::tuple arguments; - - return call_proxy( - derived() - , arguments(&a0) - ); - } - - template - call_proxy< - Derived - , boost::tuples::tuple - > operator()(A0 const& a0, A1 const& a1) - { - typedef boost::tuples::tuple arguments; - - return call_proxy( - derived() - , arguments(&a0, &a1) - ); - } - - // The rest of the overloads are PP-generated. - #define BOOST_PP_ITERATION_PARAMS_1 (3, \ - (3, LUABIND_MAX_ARITY, )) - #include BOOST_PP_ITERATE() - - operator safe_bool_type*() const - { - lua_State* L = value_wrapper_traits::interpreter(derived()); - - if (!L) - return 0; - - value_wrapper_traits::unwrap(L, derived()); - detail::stack_pop pop(L, 1); - - return lua_toboolean(L, -1) == 1 ? (safe_bool_type*)1 : 0; - } - - private: - Derived& derived() - { - return *static_cast(this); - } - - Derived const& derived() const - { - return *static_cast(this); - } - }; - -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG - struct iterator_proxy_tag; -#endif - - template - class iterator_proxy - : public object_interface > - { - public: -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG - typedef iterator_proxy_tag value_wrapper_tag; -#endif - - 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 - iterator_proxy& operator=(T const& value) - { - lua_pushvalue(m_interpreter, m_key_index); - detail::push(m_interpreter, value); - AccessPolicy::set(m_interpreter, m_table_index); - return *this; - } - - template - index_proxy > operator[](Key const& key) - { - return index_proxy >( - *this, m_interpreter, key - ); - } - - // This is non-const to prevent conversion on lvalues. - 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; - }; - -} // namespace adl - -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 basic_iterator - : public boost::iterator_facade< - basic_iterator - , adl::iterator_proxy - , boost::single_pass_traversal_tag - , adl::iterator_proxy - > - { - public: - basic_iterator() - : m_interpreter(0) - {} - - template - explicit basic_iterator(ValueWrapper const& value_wrapper) - : m_interpreter( - value_wrapper_traits::interpreter(value_wrapper) - ) - { - detail::stack_pop pop(m_interpreter, 1); - value_wrapper_traits::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); - } - - adl::object key() const; - - private: - friend class boost::iterator_core_access; - - 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_equal(m_interpreter, -2, -1) != 0; - } - - adl::iterator_proxy dereference() const - { - return adl::iterator_proxy(m_interpreter, m_table, m_key); - } - - lua_State* m_interpreter; - handle m_table; - handle m_key; - }; - -// Needed because of some strange ADL issues. -#if BOOST_VERSION < 105700 - -#define LUABIND_OPERATOR_ADL_WKND(op) \ - inline bool operator op( \ - basic_iterator const& x \ - , basic_iterator const& y) \ - { \ - return boost::operator op(x, y); \ - } \ - \ - inline bool operator op( \ - basic_iterator const& x \ - , basic_iterator const& y) \ - { \ - return boost::operator op(x, y); \ - } - - LUABIND_OPERATOR_ADL_WKND(==) - LUABIND_OPERATOR_ADL_WKND(!=) - -#undef LUABIND_OPERATOR_ADL_WKND -#endif - -} // namespace detail - -namespace adl -{ - -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG - struct index_proxy_tag; -#endif - - template - class index_proxy - : public object_interface > - { - public: -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG - typedef index_proxy_tag value_wrapper_tag; -#endif - - typedef index_proxy this_type; - - template - 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(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. - operator object(); - - // this will set the value to nil - this_type& operator=(luabind::detail::nil_type) - { - value_wrapper_traits::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 - this_type& operator=(T const& value) - { - value_wrapper_traits::unwrap(m_interpreter, m_next); - detail::stack_pop pop(m_interpreter, 1); - - lua_pushvalue(m_interpreter, m_key_index); - detail::push(m_interpreter, value); - lua_settable(m_interpreter, -3); - return *this; - } - - this_type& operator=(this_type const& value) - { - value_wrapper_traits::unwrap(m_interpreter, m_next); - detail::stack_pop pop(m_interpreter, 1); - - lua_pushvalue(m_interpreter, m_key_index); - detail::push(m_interpreter, value); - lua_settable(m_interpreter, -3); - return *this; - } - - template - index_proxy operator[](T const& key) - { - return index_proxy(*this, m_interpreter, key); - } - - void push(lua_State* interpreter); - - lua_State* interpreter() const - { - return m_interpreter; - } - - private: - struct hidden_type {}; - -// this_type& operator=(index_proxy const&); - - mutable lua_State* m_interpreter; - int m_key_index; - - Next const& m_next; - }; - -} // namespace adl - -typedef detail::basic_iterator iterator; -typedef detail::basic_iterator raw_iterator; - -#ifndef LUABIND_USE_VALUE_WRAPPER_TAG -template -struct value_wrapper_traits > -#else -template<> -struct value_wrapper_traits -#endif -{ - typedef boost::mpl::true_ is_specialized; - - template - static lua_State* interpreter(adl::index_proxy const& proxy) - { - return proxy.interpreter(); - } - - template - static void unwrap(lua_State* interpreter, adl::index_proxy const& proxy) - { - const_cast&>(proxy).push(interpreter); - } -}; - -#ifndef LUABIND_USE_VALUE_WRAPPER_TAG -template -struct value_wrapper_traits > -#else -template<> -struct value_wrapper_traits -#endif -{ - typedef boost::mpl::true_ is_specialized; - - template - static lua_State* interpreter(Proxy const& p) - { - return p.interpreter(); - } - - template - static void unwrap(lua_State* interpreter, Proxy const& p) - { - // TODO: Why const_cast? - const_cast(p).push(interpreter); - } -}; - -namespace adl -{ - - // An object holds a reference to a Lua value residing - // in the registry. - class object : public object_interface - { - 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 - object(lua_State* interpreter, T const& value) - { - detail::push(interpreter, value); - detail::stack_pop pop(interpreter, 1); - handle(interpreter, -1).swap(m_handle); - } - - template - object(lua_State* interpreter, T const& value, Policies const&) - { - detail::push(interpreter, value, Policies()); - 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 - index_proxy operator[](T const& key) const - { - return index_proxy( - *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; - } - - class argument : public object_interface - { - 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 - index_proxy operator[](T const& key) const - { - return index_proxy(*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; - }; - -} // namespace adl - -using adl::object; -using adl::argument; - -#ifndef LUABIND_USE_VALUE_WRAPPER_TAG -template -struct value_wrapper_traits > -#else -template<> -struct value_wrapper_traits -#endif -{ - typedef boost::mpl::true_ is_specialized; - - template - static lua_State* interpreter(adl::call_proxy const& proxy) - { - return value_wrapper_traits::interpreter(*proxy.value_wrapper); - } - - template - static void unwrap(lua_State*, adl::call_proxy const& proxy) - { - object result = const_cast&>(proxy); - result.push(result.interpreter()); - } -}; - -template<> -struct value_wrapper_traits -{ - typedef boost::mpl::true_ is_specialized; - - 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<> -struct value_wrapper_traits -{ - typedef boost::mpl::true_ is_specialized; - - 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; - } -}; - -template -inline void adl::index_proxy::push(lua_State* interpreter) -{ - assert(interpreter == m_interpreter); - - value_wrapper_traits::unwrap(m_interpreter, m_next); - - lua_pushvalue(m_interpreter, m_key_index); - lua_gettable(m_interpreter, -2); - lua_remove(m_interpreter, -2); -} - -template -inline adl::index_proxy::operator object() -{ - detail::stack_pop pop(m_interpreter, 1); - push(m_interpreter); - return object(from_stack(m_interpreter, -1)); -} - -template -adl::iterator_proxy::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)); -} - -template -object detail::basic_iterator::key() const -{ - return object(m_key); -} - -namespace detail -{ - - template< - class T - , class ValueWrapper - , class Policies - , class ErrorPolicy - , class ReturnType - > - ReturnType object_cast_aux( - ValueWrapper const& value_wrapper - , T* - , Policies* - , ErrorPolicy* - , ReturnType* - ) - { - lua_State* interpreter = value_wrapper_traits::interpreter( - value_wrapper - ); - -#ifndef LUABIND_NO_ERROR_CHECKING - if (!interpreter) - return ErrorPolicy::handle_error(interpreter, typeid(void)); -#endif - - value_wrapper_traits::unwrap(interpreter, value_wrapper); - - detail::stack_pop pop(interpreter, 1); - - typedef typename detail::find_conversion_policy< - 0 - , Policies - >::type converter_generator; - - typename mpl::apply_wrap2::type cv; - -#ifndef LUABIND_NO_ERROR_CHECKING - if (cv.match(interpreter, LUABIND_DECORATE_TYPE(T), -1) < 0) - { - return ErrorPolicy::handle_error(interpreter, typeid(T)); - } -#endif - - return cv.apply(interpreter, LUABIND_DECORATE_TYPE(T), -1); - } - -# ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable:4702) // unreachable code -# endif - - template - struct throw_error_policy - { - static 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 boost::remove_reference::type*)0; - } - }; - -# ifdef BOOST_MSVC -# pragma warning(pop) -# endif - - template - struct nothrow_error_policy - { - static boost::optional handle_error(lua_State*, type_id const&) - { - return boost::optional(); - } - }; - -} // namespace detail - -template -T object_cast(ValueWrapper const& value_wrapper) -{ - return detail::object_cast_aux( - value_wrapper - , (T*)0 - , (detail::null_type*)0 - , (detail::throw_error_policy*)0 - , (T*)0 - ); -} - -template -T object_cast(ValueWrapper const& value_wrapper, Policies const&) -{ - return detail::object_cast_aux( - value_wrapper - , (T*)0 - , (Policies*)0 - , (detail::throw_error_policy*)0 - , (T*)0 - ); -} - -template -boost::optional object_cast_nothrow(ValueWrapper const& value_wrapper) -{ - return detail::object_cast_aux( - value_wrapper - , (T*)0 - , (detail::null_type*)0 - , (detail::nothrow_error_policy*)0 - , (boost::optional*)0 - ); -} - -template -boost::optional object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&) -{ - return detail::object_cast_aux( - value_wrapper - , (T*)0 - , (Policies*)0 - , (detail::nothrow_error_policy*)0 - , (boost::optional*)0 - ); -} - -namespace detail -{ - - template - struct push_args_from_tuple - { - template - inline static void apply(lua_State* L, const boost::tuples::cons& x, const Policies& p) - { - convert_to_lua_p(L, *x.get_head(), p); - push_args_from_tuple::apply(L, x.get_tail(), p); - } - - template - inline static void apply(lua_State* L, const boost::tuples::cons& x) - { - convert_to_lua(L, *x.get_head()); - push_args_from_tuple::apply(L, x.get_tail()); - } - - template - inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {} - - inline static void apply(lua_State*, const boost::tuples::null_type&) {} - }; - -} // namespace detail - -namespace adl -{ - - template - struct call_proxy - { - call_proxy(ValueWrapper& value_wrapper, Arguments arguments) - : value_wrapper(&value_wrapper) - , arguments(arguments) - {} - - call_proxy(call_proxy const& other) - : value_wrapper(other.value_wrapper) - , arguments(other.arguments) - { - other.value_wrapper = 0; - } - - ~call_proxy() - { - if (value_wrapper) - call((detail::null_type*)0); - } - - operator object() - { - return call((detail::null_type*)0); - } - - template - object operator[](Policies const&) - { - return call((Policies*)0); - } - - template - object call(Policies*) - { - lua_State* interpreter = value_wrapper_traits::interpreter( - *value_wrapper - ); - - value_wrapper_traits::unwrap( - interpreter - , *value_wrapper - ); - - value_wrapper = 0; - - detail::push_args_from_tuple<1>::apply(interpreter, arguments, Policies()); - - if (detail::pcall(interpreter, boost::tuples::length::value, 1)) - { -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(interpreter); -#else - error_callback_fun e = get_error_callback(); - if (e) e(interpreter); - - 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 - } - - detail::stack_pop pop(interpreter, 1); - return object(from_stack(interpreter, -1)); - } - - mutable ValueWrapper* value_wrapper; - Arguments arguments; - }; - - template - call_proxy > - object_interface::operator()() - { - return call_proxy >( - derived() - , boost::tuples::tuple<>() - ); - } - - // 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 - struct table : Base - { - table(from_stack const& stack_reference) - : Base(stack_reference) - {} - }; - -} // namespace adl - -using adl::table; - -template -struct value_wrapper_traits > - : value_wrapper_traits -{ - static bool check(lua_State* L, int idx) - { - return value_wrapper_traits::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 -inline object gettable(ValueWrapper const& table, K const& key) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - table - ); - - value_wrapper_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 2); - detail::push(interpreter, key); - lua_gettable(interpreter, -2); - return object(from_stack(interpreter, -1)); -} - -template -inline void settable(ValueWrapper const& table, K const& key, T const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - table - ); - - // TODO: Exception safe? - - value_wrapper_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 1); - detail::push(interpreter, key); - detail::push(interpreter, value); - lua_settable(interpreter, -3); -} - -template -inline object rawget(ValueWrapper const& table, K const& key) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - table - ); - - value_wrapper_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 2); - detail::push(interpreter, key); - lua_rawget(interpreter, -2); - return object(from_stack(interpreter, -1)); -} - -template -inline void rawset(ValueWrapper const& table, K const& key, T const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - table - ); - - // TODO: Exception safe? - - value_wrapper_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 1); - detail::push(interpreter, key); - detail::push(interpreter, value); - lua_rawset(interpreter, -3); -} - -template -inline int type(ValueWrapper const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - value - ); - - value_wrapper_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 1); - return lua_type(interpreter, -1); -} - -template -inline object getmetatable(ValueWrapper const& obj) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - obj - ); - - value_wrapper_traits::unwrap(interpreter, obj); - detail::stack_pop pop(interpreter, 2); - lua_getmetatable(interpreter, -1); - return object(from_stack(interpreter, -1)); -} - -template -inline void setmetatable( - ValueWrapper1 const& obj, ValueWrapper2 const& metatable) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - obj - ); - - value_wrapper_traits::unwrap(interpreter, obj); - detail::stack_pop pop(interpreter, 1); - value_wrapper_traits::unwrap(interpreter, metatable); - lua_setmetatable(interpreter, -2); -} - -template -inline lua_CFunction tocfunction(ValueWrapper const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - value - ); - - value_wrapper_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 1); - return lua_tocfunction(interpreter, -1); -} - -template -inline T* touserdata(ValueWrapper const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - value - ); - - value_wrapper_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 1); - return static_cast(lua_touserdata(interpreter, -1)); -} - -template -inline object getupvalue(ValueWrapper const& value, int index) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - value - ); - - value_wrapper_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 2); - lua_getupvalue(interpreter, -1, index); - return object(from_stack(interpreter, -1)); -} - -template -inline void setupvalue( - ValueWrapper1 const& function, int index, ValueWrapper2 const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - function - ); - - value_wrapper_traits::unwrap(interpreter, function); - detail::stack_pop pop(interpreter, 1); - value_wrapper_traits::unwrap(interpreter, value); - lua_setupvalue(interpreter, -2, index); -} - -template -object property(GetValueWrapper const& get) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - get - ); - - value_wrapper_traits::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 -object property(GetValueWrapper const& get, SetValueWrapper const& set) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - get - ); - - value_wrapper_traits::unwrap(interpreter, get); - value_wrapper_traits::unwrap(interpreter, set); - - lua_pushcclosure(interpreter, &detail::property_tag, 2); - detail::stack_pop pop(interpreter, 1); - - return object(from_stack(interpreter, -1)); - -} - - -} // namespace luabind - -#endif // LUABIND_OBJECT_050419_HPP +#endif // LUABIND_OBJECT_HPP diff --git a/libs/luabind/luabind/open.hpp b/libs/luabind/luabind/open.hpp index cca4c7a52..5fe28f409 100644 --- a/libs/luabind/luabind/open.hpp +++ b/libs/luabind/luabind/open.hpp @@ -26,6 +26,8 @@ #include +#include + namespace luabind { LUABIND_API void open(lua_State* L); diff --git a/libs/luabind/luabind/operator.hpp b/libs/luabind/luabind/operator.hpp index aeb651c03..bde759290 100644 --- a/libs/luabind/luabind/operator.hpp +++ b/libs/luabind/luabind/operator.hpp @@ -23,15 +23,6 @@ #ifndef OPERATOR_040729_HPP #define OPERATOR_040729_HPP -#include -#include -#include -#include -#include -#include -#include -#include - #if defined(__GNUC__) && __GNUC__ < 3 # define LUABIND_NO_STRINGSTREAM #else @@ -46,154 +37,155 @@ #include #endif -namespace luabind { namespace detail { +#include +#include +#include +#include - template struct unwrap_parameter_type; - template struct operator_ {}; +namespace luabind { + namespace detail { - struct operator_void_return {}; + template struct unwrap_parameter_type; + template struct operator_ {}; -#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) - template - inline T const& operator,(T const& x, operator_void_return) - { - return x; - } -#endif - -}} // namespace luabind + struct operator_void_return {}; -namespace luabind { namespace operators { + template + inline T const& operator,(T const& x, operator_void_return) + { + return x; + } - #define BOOST_PP_ITERATION_PARAMS_1 (3, \ - (0, LUABIND_MAX_ARITY, )) - #include BOOST_PP_ITERATE() - -}} // namespace luabind::operators + template + inline void operator_result(lua_State*, operator_void_return, Policies*) + { + } -#include + template + inline void operator_result(lua_State* L, T const& x, Policies*) + { + specialized_converter_policy_n<0, Policies, T, cpp_to_lua >().to_lua(L, x); + } + + } +} // namespace luabind + + +namespace luabind { + namespace operators { + + template + struct call_operator + : detail::operator_ < call_operator< Self, Args... > > + { + call_operator(int) {} + + template + struct apply + { + static void execute( + lua_State* L + , typename detail::unwrap_parameter_type::type self + , typename detail::unwrap_parameter_type::type... args + ) + { + using namespace detail; + operator_result( + L + , (self(args...), detail::operator_void_return()) + , (Policies*)0 + ); + } + }; + + static char const* name() { return "__call"; } + }; + + } +} // namespace luabind::operators namespace luabind { - template - struct self_base - { - operators::call_operator0 operator()() const - { - return 0; - } - -#define BOOST_PP_LOCAL_MACRO(n) \ - template \ - BOOST_PP_CAT(operators::call_operator, n)< \ - Derived \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, A) \ - >\ - operator()( \ - BOOST_PP_ENUM_BINARY_PARAMS(n, A, const& BOOST_PP_INTERCEPT) \ - ) const \ - { \ - return 0; \ - } + template + struct self_base + { + template< typename... Args > + operators::call_operator operator()(const Args&...) const + { + return 0; + } + }; -#define BOOST_PP_LOCAL_LIMITS (1, LUABIND_MAX_ARITY) -#include BOOST_PP_LOCAL_ITERATE() + struct self_type : self_base + { + }; - }; + struct const_self_type : self_base + { + }; - struct self_type : self_base - { - }; + namespace detail { - struct const_self_type : self_base - { - }; + template + struct unwrap_parameter_type + { + using type = typename meta::select_ < + meta::case_< std::is_same, W& >, + meta::case_< std::is_same, W const& >, + meta::default_< typename unwrap_other::type > + > ::type; + }; -namespace detail { + template + struct binary_operator + : operator_ > + { + binary_operator(int) {} - template - struct unwrap_parameter_type - { - typedef typename boost::mpl::eval_if< - boost::is_same - , boost::mpl::identity - , boost::mpl::eval_if< - boost::is_same - , boost::mpl::identity - , unwrap_other - > - >::type type; - }; + template + struct apply + { + using arg0 = typename unwrap_parameter_type::type; + using arg1 = typename unwrap_parameter_type::type; - template - struct binary_operator - : operator_ > - { - binary_operator(int) {} + static void execute(lua_State* L, arg0 _0, arg1 _1) + { + Derived::template apply::execute( + L, _0, _1); + } + }; - template - struct apply - { - typedef typename unwrap_parameter_type::type arg0; - typedef typename unwrap_parameter_type::type arg1; + static char const* name() + { + return Derived::name(); + } + }; - static void execute(lua_State* L, arg0 _0, arg1 _1) - { - Derived::template apply::execute( - L, _0, _1); - } - }; + template + struct unary_operator + : operator_ > + { + unary_operator(int) {} - static char const* name() - { - return Derived::name(); - } - }; + template + struct apply + { + using arg0 = typename unwrap_parameter_type::type; - template - struct unary_operator - : operator_ > - { - unary_operator(int) {} - - template - struct apply - { - typedef typename unwrap_parameter_type::type arg0; + static void execute(lua_State* L, arg0 _0) + { + Derived::template apply::execute(L, _0); + } + }; - static void execute(lua_State* L, arg0 _0) - { - Derived::template apply::execute(L, _0); - } - }; + static char const* name() + { + return Derived::name(); + } + }; - static char const* name() - { - return Derived::name(); - } - }; - - template - inline void operator_result(lua_State* L, operator_void_return, Policies*) - { - } - - namespace mpl = boost::mpl; - - template - inline void operator_result(lua_State* L, T const& x, Policies*) - { - typedef typename find_conversion_policy< - 0 - , Policies - >::type cv_policy; - - typename mpl::apply_wrap2::type cv; - - cv.apply(L, x); - } - -}} // namespace detail::luabind + } +} // namespace detail::luabind namespace luabind { @@ -281,16 +273,17 @@ namespace luabind { return 0; \ } - LUABIND_BINARY_OPERATOR(add, +) - LUABIND_BINARY_OPERATOR(sub, -) - LUABIND_BINARY_OPERATOR(mul, *) - LUABIND_BINARY_OPERATOR(div, /) - LUABIND_BINARY_OPERATOR(pow, ^) - LUABIND_BINARY_OPERATOR(lt, <) - LUABIND_BINARY_OPERATOR(le, <=) - LUABIND_BINARY_OPERATOR(eq, ==) + LUABIND_BINARY_OPERATOR(add, +) + LUABIND_BINARY_OPERATOR(sub, -) + LUABIND_BINARY_OPERATOR(mul, *) + LUABIND_BINARY_OPERATOR(div, / ) + LUABIND_BINARY_OPERATOR(mod, %) + LUABIND_BINARY_OPERATOR(pow, ^) + LUABIND_BINARY_OPERATOR(lt, < ) + LUABIND_BINARY_OPERATOR(le, <= ) + LUABIND_BINARY_OPERATOR(eq, == ) -#undef LUABIND_UNARY_OPERATOR +#undef LUABIND_BINARY_OPERATOR #define LUABIND_UNARY_OPERATOR(name_, op, fn) \ namespace operators { \ @@ -324,31 +317,29 @@ namespace luabind { return 0; \ } - template - std::string tostring_operator(T const& x) - { + template + std::string tostring_operator(T const& x) + { #ifdef LUABIND_NO_STRINGSTREAM - std::strstream s; - s << x << std::ends; + std::strstream s; + s << x << std::ends; #else - std::stringstream s; - s << x; + std::stringstream s; + s << x; #endif - return s.str(); - } - - LUABIND_UNARY_OPERATOR(tostring, tostring_operator, tostring) - LUABIND_UNARY_OPERATOR(unm, -, operator-) + return s.str(); + } -#undef LUABIND_BINARY_OPERATOR + LUABIND_UNARY_OPERATOR(tostring, tostring_operator, tostring) + LUABIND_UNARY_OPERATOR(unm, -, operator-) - namespace { +#undef LUABIND_UNARY_OPERATOR + + + extern LUABIND_API self_type self; + extern LUABIND_API const_self_type const_self; - LUABIND_ANONYMOUS_FIX self_type self; - LUABIND_ANONYMOUS_FIX const_self_type const_self; - } // namespace unnamed - } // namespace luabind #endif // OPERATOR_040729_HPP diff --git a/libs/luabind/luabind/out_value_policy.hpp b/libs/luabind/luabind/out_value_policy.hpp index ca496b527..5fb5ada33 100644 --- a/libs/luabind/luabind/out_value_policy.hpp +++ b/libs/luabind/luabind/out_value_policy.hpp @@ -25,255 +25,247 @@ #define LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED #include -#include -#include +#include // for find_conversion_policy, etc +#include // for decorated_type +#include // for by_pointer, by_reference, etc +#include // for is_nonconst_pointer, is_nonconst_reference, etc +#include // for operator new -namespace luabind { namespace detail -{ - template - struct char_array - { - char storage[N]; - }; +namespace luabind { + namespace detail { -#if defined(__GNUC__) && ( __GNUC__ == 3 && __GNUC_MINOR__ == 1 ) - - template - char_array indirect_sizeof_test(by_reference); - - template - char_array indirect_sizeof_test(by_const_reference); - - template - char_array indirect_sizeof_test(by_pointer); - - template - char_array indirect_sizeof_test(by_const_pointer); - - template - char_array indirect_sizeof_test(by_value); - -#else - - template - char_array::type)> indirect_sizeof_test(by_reference); - - template - char_array::type)> indirect_sizeof_test(by_const_reference); - - template - char_array::type)> indirect_sizeof_test(by_pointer); - - template - char_array::type)> indirect_sizeof_test(by_const_pointer); - - template - char_array::type)> indirect_sizeof_test(by_value); - -#endif - - template - struct indirect_sizeof - { - BOOST_STATIC_CONSTANT(int, value = sizeof(indirect_sizeof_test(LUABIND_DECORATE_TYPE(T)))); - }; - - namespace mpl = boost::mpl; - - template - struct out_value_converter - { - int const consumed_args(...) - { - return 1; - } - - template - T& apply(lua_State* L, by_reference, int index) + template + struct char_array { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - new (m_storage) T(converter.apply(L, LUABIND_DECORATE_TYPE(T), index)); - return *reinterpret_cast(m_storage); - } - - template - static int match(lua_State* L, by_reference, int index) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typedef typename mpl::apply_wrap2::type converter; - return converter::match(L, LUABIND_DECORATE_TYPE(T), index); - } - - template - void converter_postcall(lua_State* L, by_reference, int) - { - typedef typename find_conversion_policy<2, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - converter.apply(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); - } - - template - T* apply(lua_State* L, by_pointer, int index) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - new (m_storage) T(converter.apply(L, LUABIND_DECORATE_TYPE(T), index)); - return reinterpret_cast(m_storage); - } - - template - static int match(lua_State* L, by_pointer, int index) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typedef typename mpl::apply_wrap2::type converter; - return converter::match(L, LUABIND_DECORATE_TYPE(T), index); - } - - template - void converter_postcall(lua_State* L, by_pointer, int) - { - typedef typename find_conversion_policy<2, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - converter.apply(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); - } - - char m_storage[Size]; - }; - - template - struct out_value_policy : conversion_policy - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - - struct only_accepts_nonconst_references_or_pointers {}; - struct can_only_convert_from_lua_to_cpp {}; - - template - struct apply - { - typedef typename boost::mpl::if_ - , typename boost::mpl::if_, is_nonconst_pointer > - , out_value_converter::value, Policies> - , only_accepts_nonconst_references_or_pointers - >::type - , can_only_convert_from_lua_to_cpp - >::type type; + char storage[N]; }; - }; - template - struct pure_out_value_converter - { - int const consumed_args(...) - { - return 0; - } + template + char_array::type)> indirect_sizeof_test(by_reference); - template - T& apply(lua_State*, by_reference, int) - { - new (m_storage) T(); - return *reinterpret_cast(m_storage); - } + template + char_array::type)> indirect_sizeof_test(by_const_reference); + + template + char_array::type)> indirect_sizeof_test(by_pointer); + + template + char_array::type)> indirect_sizeof_test(by_const_pointer); + + template + char_array::type)> indirect_sizeof_test(by_value); template - static int match(lua_State*, by_reference, int) + struct indirect_sizeof { - return 0; - } - - template - void converter_postcall(lua_State* L, by_reference, int) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - converter.apply(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); - } - - template - T* apply(lua_State*, by_pointer, int) - { - new (m_storage) T(); - return reinterpret_cast(m_storage); - } - - template - static int match(lua_State*, by_pointer, int) - { - return 0; - } - - template - void converter_postcall(lua_State* L, by_pointer, int) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - converter.apply(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); - } - - - char m_storage[Size]; - }; - - template - struct pure_out_value_policy : conversion_policy - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - - struct only_accepts_nonconst_references_or_pointers {}; - struct can_only_convert_from_lua_to_cpp {}; - - template - struct apply - { - typedef typename boost::mpl::if_ - , typename boost::mpl::if_, is_nonconst_pointer > - , pure_out_value_converter::value, Policies> - , only_accepts_nonconst_references_or_pointers - >::type - , can_only_convert_from_lua_to_cpp - >::type type; + static const int value = sizeof(indirect_sizeof_test(decorate_type_t())); }; - }; - -}} + + namespace out_value_detail { + + template< int Size > + struct temporary_storage_size { + + template< typename T, typename... Args > + void construct(Args&&... args) + { + new (&m_storage) T(std::forward(args)...); + } + + template + T& get() { + return *reinterpret_cast(&m_storage); + } + + template + const T& get() const { + return *reinterpret_cast(&m_storage); + } + + template + void destroy() + { + get().~T(); + } + + typename std::aligned_storage::type m_storage; + + }; + + template< typename T > + struct temporary_storage_type { + + template< typename... Args > + void construct(Args&&... args) + { + new (&m_storage) T(std::forward(args)...); + } + + T& get() { + return *reinterpret_cast(&m_storage); + } + + const T& get() const { + return *reinterpret_cast(&m_storage); + } + + void destroy() + { + get().~T(); + } + + typename std::aligned_storage::type m_storage; + + }; + + } + + // See note in out_value_policy about why we're not templating + // for the parameter type. + template + struct out_value_converter + { + enum { consumed_args = 1 }; + + T& to_cpp(lua_State* L, by_reference, int index) + { + //specialized_converter_policy_n<1, Policies, T, lua_to_cpp> converter; + storage_.construct(converter_.to_cpp(L, decorate_type_t(), index)); + return storage_.get(); + } + + int match(lua_State* L, by_reference, int index) + { + return converter_.match(L, decorate_type_t(), index); + } + + void converter_postcall(lua_State* L, by_reference, int) + { + //specialized_converter_policy_n<2,Policies,T,cpp_to_lua> converter; + converter_.to_lua(L, storage_.get()); + storage_.destroy(); + } + + T* to_cpp(lua_State* L, by_pointer, int index) + { + storage_.construct(converter_.to_cpp(L, decorate_type_t(), index)); + return &storage_.get(); + } + + int match(lua_State* L, by_pointer, int index) + { + return converter_.match(L, decorate_type_t(), index); + } + + void converter_postcall(lua_State* L, by_pointer, int) + { + //specialized_converter_policy_n<2, Policies, T, cpp_to_lua> converter; + converter_.to_lua(L, storage_.get()); + storage_.destroy(); + } + + private: + specialized_converter_policy_n<1, Policies, T, lua_to_cpp > converter_; + out_value_detail::temporary_storage_type storage_; + }; + + template + struct out_value_policy + { + struct only_accepts_nonconst_references_or_pointers {}; + struct can_only_convert_from_lua_to_cpp {}; + + template + struct specialize + { + static_assert(std::is_same< Direction, lua_to_cpp >::value, "Out value policy can only convert from lua to cpp"); + static_assert(meta::or_< is_nonconst_reference, is_nonconst_pointer >::value, "Out value policy only accepts non const references or pointers"); + + // Note to myself: + // Using the size and template members instead of a policy templated for the type seems + // to be done to tame template bloat. Need to check if this is worth is. + using base_type = typename std::remove_pointer< typename std::remove_reference< T >::type >::type; + using type = out_value_converter; + }; + }; + + template + struct pure_out_value_converter + { + enum { consumed_args = 0 }; + + template + T& to_cpp(lua_State*, by_reference, int) + { + storage_.decltype(storage_)::template construct(); + return storage_.template get(); + } + + template + static int match(lua_State*, by_reference, int) + { + return 0; + } + + template + void converter_postcall(lua_State* L, by_reference, int) + { + specialized_converter_policy_n<1, Policies, T, cpp_to_lua> converter; + converter.to_lua(L, storage_.template get()); + storage_.template destroy(); + } + + template + T* to_cpp(lua_State*, by_pointer, int) + { + storage_.decltype(storage_)::template construct(); + return &storage_.template get(); + } + + template + static int match(lua_State*, by_pointer, int) + { + return 0; + } + + template + void converter_postcall(lua_State* L, by_pointer, int) + { + specialized_converter_policy_n<1, Policies, T, cpp_to_lua> converter; + converter.to_lua(L, storage_.template get()); + storage_.template destroy(); + } + + private: + out_value_detail::temporary_storage_size storage_; + }; + + template + struct pure_out_value_policy + { + struct only_accepts_nonconst_references_or_pointers {}; + struct can_only_convert_from_lua_to_cpp {}; + + template + struct specialize + { + static_assert(std::is_same< Direction, lua_to_cpp >::value, "Pure out value policy can only convert from lua to cpp"); + static_assert(meta::or_< is_nonconst_reference, is_nonconst_pointer >::value, "Pure out value policy only accepts non const references or pointers"); + + using type = pure_out_value_converter::value, Policies>; + }; + }; + + } +} namespace luabind { - template - detail::policy_cons, detail::null_type> - out_value(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons, detail::null_type>(); - } + template + using out_value = meta::type_list>>; - template - detail::policy_cons, detail::null_type> - out_value(LUABIND_PLACEHOLDER_ARG(N), const Policies&) - { - return detail::policy_cons, detail::null_type>(); - } - - template - detail::policy_cons, detail::null_type> - pure_out_value(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons, detail::null_type>(); - } - - template - detail::policy_cons, detail::null_type> - pure_out_value(LUABIND_PLACEHOLDER_ARG(N), const Policies&) - { - return detail::policy_cons, detail::null_type>(); - } + template + using pure_out_value = meta::type_list>>; } #endif // LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/pointer_traits.hpp b/libs/luabind/luabind/pointer_traits.hpp new file mode 100644 index 000000000..899d40f74 --- /dev/null +++ b/libs/luabind/luabind/pointer_traits.hpp @@ -0,0 +1,148 @@ +// 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_GET_POINTER_051023_HPP +# define LUABIND_GET_POINTER_051023_HPP +#include +#include + +// TODO: Rename to pointer_traits + +namespace luabind { + + template + T* get_pointer(T* pointer) + { + return pointer; + } + + template + T* get_pointer(const std::unique_ptr& pointer) + { + return pointer.get(); + } + + template + T* get_pointer(const std::shared_ptr& pointer) + { + return pointer.get(); + } + + + namespace detail { + + template + struct pointer_traits { + enum { is_pointer = false }; + }; + + template + struct pointer_traits + { + enum { is_pointer = true }; + using value_type = T; + }; + + template + struct pointer_traits> + { + enum { is_pointer = true }; + using value_type = T; + }; + + template + struct pointer_traits> + { + enum { is_pointer = true }; + using value_type = T; + }; + + template + using is_pointer_to_const = std::is_const< typename pointer_traits::value_type >; + + template + void release_ownership(std::unique_ptr& p) + { + p.release(); + } + + template + void release_ownership(P const&) + { + throw std::runtime_error( + "luabind: smart pointer does not allow ownership transfer"); + } + + namespace has_get_pointer_ + { + + struct any + { + template any(T const&); + }; + + struct no_overload_tag + {}; + + typedef char(&yes)[1]; + typedef char(&no)[2]; + + no_overload_tag operator, (no_overload_tag, int); + + template + T* get_pointer(T const volatile*); + + template + T* get_pointer(std::unique_ptr const&); + + template + T* get_pointer(std::shared_ptr const&); + + detail::has_get_pointer_::no_overload_tag + get_pointer(detail::has_get_pointer_::any); + + ///@TODO: Rework + template + yes check(T const&); + no check(no_overload_tag); + + template + struct impl + { + static typename std::add_lvalue_reference::type x; + static const bool value = (sizeof(has_get_pointer_::check((get_pointer(x), 0))) == 1); + typedef std::integral_constant type; + }; + + } // namespace has_get_pointer_ + + template + struct has_get_pointer + : has_get_pointer_::impl::type + {}; + + } // namespace detail + +} // namespace luabind + +#endif // LUABIND_GET_POINTER_051023_HPP + diff --git a/libs/luabind/luabind/raw_policy.hpp b/libs/luabind/luabind/raw_policy.hpp index 6d22da246..ad3ecbfc1 100644 --- a/libs/luabind/luabind/raw_policy.hpp +++ b/libs/luabind/luabind/raw_policy.hpp @@ -27,58 +27,40 @@ #include #include -namespace luabind { namespace detail { - - struct raw_converter - { - int const consumed_args(...) - { - return 0; - } - - lua_State* apply(lua_State* L, by_pointer, int) - { - return L; - } - - static int match(...) - { - return 0; - } - - void converter_postcall(lua_State*, by_pointer, int) {} - }; - - template - struct raw_policy : conversion_policy - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - - template - struct apply - { - typedef raw_converter type; - }; - }; - -}} // namespace luabind::detail - namespace luabind { + namespace detail { + + struct raw_converter + { + enum { consumed_args = 0 }; + + lua_State* to_cpp(lua_State* L, by_pointer, int) + { + return L; + } + + static int match(...) + { + return 0; + } + + void converter_postcall(lua_State*, by_pointer, int) {} + }; + + struct raw_policy + { + template + struct specialize + { + using type = raw_converter; + }; + }; - template - detail::policy_cons< - detail::raw_policy - , detail::null_type - > - inline raw(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons< - detail::raw_policy - , detail::null_type - >(); } + template + using raw_policy = meta::type_list< converter_policy_injector< N, detail::raw_policy > >(); + } // namespace luabind #endif // LUABIND_RAW_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/return_reference_to_policy.hpp b/libs/luabind/luabind/return_reference_to_policy.hpp index 1432f79e0..e9e8846bf 100644 --- a/libs/luabind/luabind/return_reference_to_policy.hpp +++ b/libs/luabind/luabind/return_reference_to_policy.hpp @@ -23,50 +23,49 @@ #ifndef LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED #define LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED -namespace luabind { namespace detail -{ - template - struct return_reference_to_converter; +#include // for index_map, policy_cons, etc +#include // for lua_State, lua_pushnil, etc + +namespace luabind { + namespace detail { + + struct cpp_to_lua; - template<> - struct return_reference_to_converter - { template - void apply(lua_State* L, const T&) - { - lua_pushnil(L); - } - }; + struct return_reference_to_converter; - template - struct return_reference_to_policy : conversion_policy<0> - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State* L, const index_map& indices) + template<> + struct return_reference_to_converter { - int result_index = indices[0]; - int ref_to_index = indices[N]; - - lua_pushvalue(L, ref_to_index); - lua_replace(L, result_index); - } - - template - struct apply - { - typedef return_reference_to_converter type; + template + void to_lua(lua_State* L, const T&) + { + lua_pushnil(L); + } + }; + + template< unsigned int N > + struct return_reference_to_policy : detail::converter_policy_has_postcall_tag + { + template + static void postcall(lua_State* L, int results, StackIndexList) + { + lua_pushvalue(L, (meta::get::value)); + lua_replace(L, (meta::get::value + results)); + } + + template + struct specialize + { + using type = return_reference_to_converter; + }; }; - }; -}} -namespace luabind -{ - template - detail::policy_cons, detail::null_type> - return_reference_to(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons, detail::null_type>(); } + + template + using return_reference_to = meta::type_list>>; + } #endif // LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/scope.hpp b/libs/luabind/luabind/scope.hpp index 3b5f293bf..ff0237f4a 100644 --- a/libs/luabind/luabind/scope.hpp +++ b/libs/luabind/luabind/scope.hpp @@ -25,77 +25,79 @@ #include #include -#include +#include #include -namespace luabind { - - struct scope; - -} // namespace luabind - -namespace luabind { namespace detail { - - struct LUABIND_API registration - { - registration(); - virtual ~registration(); - - protected: - virtual void register_(lua_State*) const = 0; - - private: - friend struct ::luabind::scope; - registration* m_next; - }; - -}} // namespace luabind::detail - namespace luabind { - struct LUABIND_API scope - { - scope(); - explicit scope(std::auto_ptr reg); - scope(scope const& other_); - ~scope(); + struct scope; - scope& operator=(scope const& other_); +} // namespace luabind - scope& operator,(scope s); +namespace luabind { + namespace detail { - void register_(lua_State* L) const; + struct LUABIND_API registration + { + registration(); + virtual ~registration(); - private: - detail::registration* m_chain; - }; + protected: + virtual void register_(lua_State*) const = 0; - class LUABIND_API namespace_ : public scope - { - public: - explicit namespace_(char const* name); - namespace_& operator[](scope s); + private: + friend struct ::luabind::scope; + registration* m_next; + }; - private: - struct registration_; - registration_* m_registration; - }; + } +} // namespace luabind::detail - class LUABIND_API module_ - { - public: - module_(lua_State* L_, char const* name); - void operator[](scope s); +namespace luabind { - private: - lua_State* m_state; - char const* m_name; - }; + struct LUABIND_API scope + { + scope(); + explicit scope(std::unique_ptr reg); + scope(scope const& other_); + ~scope(); - inline module_ module(lua_State* L, char const* name = 0) - { - return module_(L, name); - } + scope& operator=(scope const& other_); + + scope& operator,(scope s); + + void register_(lua_State* L) const; + + private: + detail::registration* m_chain; + }; + + class LUABIND_API namespace_ : public scope + { + public: + explicit namespace_(char const* name); + namespace_& operator[](scope s); + + private: + struct registration_; + registration_* m_registration; + }; + + class LUABIND_API module_ + { + public: + module_(lua_State* L_, char const* name); + void operator[](scope s); + + private: + lua_State* m_state; + char const* m_name; + }; + + inline module_ module(lua_State* L, char const* name = 0) + { + return module_(L, name); + } } // namespace luabind diff --git a/libs/luabind/luabind/lua502.hpp b/libs/luabind/luabind/set_package_preload.hpp similarity index 56% rename from libs/luabind/luabind/lua502.hpp rename to libs/luabind/luabind/set_package_preload.hpp index 5006128ec..3ea227359 100644 --- a/libs/luabind/luabind/lua502.hpp +++ b/libs/luabind/luabind/set_package_preload.hpp @@ -1,5 +1,17 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg +/** @file + @brief Header + @date 2012 + + @author + Ryan Pavlik + and + 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 @@ -20,37 +32,23 @@ // 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 +#ifndef INCLUDED_set_package_preload_hpp_GUID_563c882e_86f7_4ea7_8603_4594ea41737e +#define INCLUDED_set_package_preload_hpp_GUID_563c882e_86f7_4ea7_8603_4594ea41737e -#if LUA_VERSION_NUM >= 502 +// Internal Includes +#include +#include -inline LUA_API int lua_equal(lua_State *L, int idx1, int idx2) -{ - return lua_compare(L, idx1, idx2, LUA_OPEQ); +// Library/third-party includes +// - none + +// Standard includes +// - none + + +namespace luabind { + + LUABIND_API void set_package_preload(lua_State * L, const char * modulename, int(*loader) (lua_State *)); } +#endif // INCLUDED_set_package_preload_hpp_GUID_563c882e_86f7_4ea7_8603_4594ea41737e -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 \ No newline at end of file diff --git a/libs/luabind/luabind/shared_ptr_converter.hpp b/libs/luabind/luabind/shared_ptr_converter.hpp index 2f61b5cff..d5c0d50e6 100644 --- a/libs/luabind/luabind/shared_ptr_converter.hpp +++ b/libs/luabind/luabind/shared_ptr_converter.hpp @@ -5,79 +5,79 @@ #ifndef LUABIND_SHARED_PTR_CONVERTER_090211_HPP # define LUABIND_SHARED_PTR_CONVERTER_090211_HPP -# include -# include -# include -# include +#include +#include // for default_converter, etc +#include // for get_main_thread +#include // for handle +#include // for decorated_type +#include namespace luabind { -namespace detail -{ + namespace detail + { - struct shared_ptr_deleter - { - shared_ptr_deleter(lua_State* L, int index) - : life_support(get_main_thread(L), L, index) - {} + struct shared_ptr_deleter + { + shared_ptr_deleter(lua_State* L, int index) + : life_support(get_main_thread(L), L, index) + {} - void operator()(void const*) - { - handle().swap(life_support); - } + void operator()(void const*) + { + handle().swap(life_support); + } - handle life_support; - }; + handle life_support; + }; -} // namespace detail + } // namespace detail -template -struct default_converter > - : default_converter -{ - typedef boost::mpl::false_ is_native; + template + struct default_converter > + : default_converter + { + using is_native = std::false_type; - template - int match(lua_State* L, U, int index) - { - return default_converter::match( - L, LUABIND_DECORATE_TYPE(T*), index); - } + template + int match(lua_State* L, U, int index) + { + return default_converter::match(L, decorate_type_t(), index); + } - template - boost::shared_ptr apply(lua_State* L, U, int index) - { - T* raw_ptr = default_converter::apply( - L, LUABIND_DECORATE_TYPE(T*), index); - if (!raw_ptr) - return boost::shared_ptr(); - return boost::shared_ptr( - raw_ptr, detail::shared_ptr_deleter(L, index)); - } + template + std::shared_ptr to_cpp(lua_State* L, U, int index) + { + T* raw_ptr = default_converter::to_cpp(L, decorate_type_t(), index); - void apply(lua_State* L, boost::shared_ptr const& p) - { - if (detail::shared_ptr_deleter* d = - boost::get_deleter(p)) - { - d->life_support.push(L); - } - else - { - detail::value_converter().apply(L, p); - } - } + if(!raw_ptr) { + return std::shared_ptr(); + } else { + return std::shared_ptr(raw_ptr, detail::shared_ptr_deleter(L, index)); + } + } - template - void converter_postcall(lua_State*, U const&, int) - {} -}; + void to_lua(lua_State* L, std::shared_ptr const& p) + { + if(detail::shared_ptr_deleter* d = std::get_deleter(p)) + { + d->life_support.push(L); + } else { + detail::value_converter().to_lua(L, p); + } + } -template -struct default_converter const&> - : default_converter > -{}; + template + void converter_postcall(lua_State*, U const&, int) + {} + }; + + template + struct default_converter const&> + : default_converter > + {}; } // namespace luabind #endif // LUABIND_SHARED_PTR_CONVERTER_090211_HPP + diff --git a/libs/luabind/luabind/tag_function.hpp b/libs/luabind/luabind/tag_function.hpp index 51fe97b75..ba8382ee5 100644 --- a/libs/luabind/luabind/tag_function.hpp +++ b/libs/luabind/luabind/tag_function.hpp @@ -2,87 +2,62 @@ // 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_TAG_FUNCTION_081129_HPP +#define LUABIND_TAG_FUNCTION_081129_HPP -# ifndef LUABIND_TAG_FUNCTION_081129_HPP -# define LUABIND_TAG_FUNCTION_081129_HPP - -# if LUABIND_MAX_ARITY <= 8 -# include -# else -# include -# endif -# include -# include -# include -# include +#include +#include +#include namespace luabind { -namespace detail -{ + template + struct tagged_function + { + tagged_function(F f) + : f(f) + {} - template - struct tagged_function - { - tagged_function(F f) - : f(f) - {} + F f; + }; - F f; - }; + namespace detail + { - template - Signature deduce_signature(tagged_function const&, ...) - { - return Signature(); - } + struct invoke_context; + struct function_object; - template - int invoke( - lua_State* L, function_object const& self, invoke_context& ctx - , tagged_function const& tagged - , Signature, Policies const& policies) - { - return invoke(L, self, ctx, tagged.f, Signature(), policies); - } +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + template + int invoke( + lua_State* L, function_object const& self, invoke_context& ctx + // std::bind operator() is nonconst... is that fixable? + , tagged_function /*const*/& tagged + , Signature, meta::type_list const& injectors) + { + return invoke(L, self, ctx, tagged.f, Signature(), injectors); + } +#else + //template< typename PolicyList, typename Signature, typename F> + //inline int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f) - template - struct signature_from_function; + template < typename PolicyList, typename Signature, typename F > + int invoke(lua_State* L, function_object const& self, invoke_context& ctx, tagged_function /*const*/& tagged) + { + return invoke(L, self, ctx, tagged.f); + } +#endif -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() + } // namespace detail -} // namespace detail - -template -detail::tagged_function< - typename detail::signature_from_function::type - , F -> -tag_function(F f) -{ - return f; -} + template + tagged_function, F > + tag_function(F f) + { + return f; + } } // namespace luabind # endif // LUABIND_TAG_FUNCTION_081129_HPP -#else // BOOST_PP_IS_ITERATING - -# define N BOOST_PP_ITERATION() -# define NPLUS1 BOOST_PP_INC(N) - -template -struct signature_from_function -{ - typedef BOOST_PP_CAT(mpl::vector, NPLUS1)< - R BOOST_PP_ENUM_TRAILING_PARAMS(N, A) - > type; -}; - -#endif // BOOST_PP_IS_ITERATING - - diff --git a/libs/luabind/luabind/typeid.hpp b/libs/luabind/luabind/typeid.hpp index d92d8fbac..9f8161bd3 100644 --- a/libs/luabind/luabind/typeid.hpp +++ b/libs/luabind/luabind/typeid.hpp @@ -5,59 +5,50 @@ #ifndef LUABIND_TYPEID_081227_HPP # define LUABIND_TYPEID_081227_HPP -# include # include -# include +# include namespace luabind { -# ifdef BOOST_MSVC -# pragma warning(push) -// std::type_info::before() returns int, rather than bool. -// At least on MSVC7.1, this is true for the comparison -// operators as well. -# pragma warning(disable:4800) -# endif + class type_id + { + public: + type_id() + : id(&typeid(null_type)) + {} -class type_id - : public boost::less_than_comparable -{ -public: - type_id() - : id(&typeid(detail::null_type)) - {} + type_id(std::type_info const& id) + : id(&id) + {} - type_id(std::type_info const& id) - : id(&id) - {} + bool operator!=(type_id const& other) const + { + return *id != *other.id; + } - bool operator!=(type_id const& other) const - { - return *id != *other.id; - } + bool operator==(type_id const& other) const + { + return *id == *other.id; + } - bool operator==(type_id const& other) const - { - return *id == *other.id; - } + bool operator<(type_id const& other) const + { + return id->before(*other.id); + } - bool operator<(type_id const& other) const - { - return id->before(*other.id); - } + size_t hash_code() const + { + return id->hash_code(); + } - char const* name() const - { - return id->name(); - } + char const* name() const + { + return id->name(); + } -private: - std::type_info const* id; -}; - -# ifdef BOOST_MSVC -# pragma warning(pop) -# endif + private: + std::type_info const* id; + }; } // namespace luabind diff --git a/libs/luabind/luabind/value_wrapper.hpp b/libs/luabind/luabind/value_wrapper.hpp deleted file mode 100644 index 8e09395d5..000000000 --- a/libs/luabind/luabind/value_wrapper.hpp +++ /dev/null @@ -1,168 +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_VALUE_WRAPPER_050419_HPP -#define LUABIND_VALUE_WRAPPER_050419_HPP - -#include -#include -#include - -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -# define LUABIND_USE_VALUE_WRAPPER_TAG -#else -#endif - -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -namespace luabind { - -// -// Concept ``ValueWrapper`` -// - -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG -template -struct value_wrapper_traits; - -namespace detail -{ - - BOOST_MPL_HAS_XXX_TRAIT_DEF(value_wrapper_tag); - - struct unspecialized_value_wrapper_traits - { - typedef boost::mpl::false_ is_specialized; - }; - - template - struct value_wrapper_traits_aux - { - typedef value_wrapper_traits type; - }; - -} // namespace detail -#endif - -template -struct value_wrapper_traits -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG - : boost::mpl::eval_if< - boost::mpl::and_< - boost::mpl::not_< - boost::mpl::or_< - boost::is_reference - , boost::is_pointer - , boost::is_array - > - > - , detail::has_value_wrapper_tag - > - , detail::value_wrapper_traits_aux - , boost::mpl::identity - >::type -{}; -#else -{ - typedef boost::mpl::false_ is_specialized; -}; -#endif - -template -struct is_value_wrapper - : boost::mpl::aux::msvc_eti_base< - typename value_wrapper_traits::is_specialized - >::type -{}; - -} // namespace luabind - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -# include -# include - -namespace luabind { - -template -struct is_value_wrapper_arg - : is_value_wrapper< - typename boost::remove_const< - typename boost::remove_reference::type - >::type - > -{}; - -} // namespace luabind - -#else - -# include -# include - -namespace luabind { - -namespace detail -{ - template - typename is_value_wrapper::type is_value_wrapper_arg_check(T const*); - - yes_t to_yesno(boost::mpl::true_); - no_t to_yesno(boost::mpl::false_); - - template - struct is_value_wrapper_arg_aux - { - static typename boost::add_reference::type x; - - BOOST_STATIC_CONSTANT(bool, value = - sizeof(to_yesno(is_value_wrapper_arg_check(&x))) - == sizeof(yes_t) - ); - - typedef boost::mpl::bool_ type; - }; - -} // namespace detail - -template -struct is_value_wrapper_arg - : detail::is_value_wrapper_arg_aux::type -{ -}; - -} // namespace luabind - -#endif - -#endif // LUABIND_VALUE_WRAPPER_050419_HPP - diff --git a/libs/luabind/luabind/version.hpp b/libs/luabind/luabind/version.hpp index 63acaf765..89625ac5b 100644 --- a/libs/luabind/luabind/version.hpp +++ b/libs/luabind/luabind/version.hpp @@ -14,3 +14,4 @@ // patch = LUABIND_VERSION % 100 #endif // LUABIND_VERSION_090216_HPP + diff --git a/libs/luabind/luabind/weak_ref.hpp b/libs/luabind/luabind/weak_ref.hpp index e08e250dc..c7a2a32ce 100644 --- a/libs/luabind/luabind/weak_ref.hpp +++ b/libs/luabind/luabind/weak_ref.hpp @@ -25,33 +25,33 @@ #include -struct lua_State; +#include namespace luabind { - class LUABIND_API weak_ref - { - public: - weak_ref(); - weak_ref(lua_State* main, lua_State* L, int index); - weak_ref(weak_ref const&); - ~weak_ref(); + class LUABIND_API weak_ref + { + public: + weak_ref(); + weak_ref(lua_State* main, lua_State* L, int index); + weak_ref(weak_ref const&); + ~weak_ref(); - weak_ref& operator=(weak_ref const&); + weak_ref& operator=(weak_ref const&); - void swap(weak_ref&); + void swap(weak_ref&); // returns a unique id that no // other weak ref will return int id() const; - lua_State* state() const; - void get(lua_State* L) const; + lua_State* state() const; + void get(lua_State* L) const; - private: - struct impl; - impl* m_impl; - }; + private: + struct impl; + impl* m_impl; + }; } // namespace luabind diff --git a/libs/luabind/luabind/wrapper_base.hpp b/libs/luabind/luabind/wrapper_base.hpp index 9adc05a35..7845e12d3 100644 --- a/libs/luabind/luabind/wrapper_base.hpp +++ b/libs/luabind/luabind/wrapper_base.hpp @@ -20,19 +20,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#if !BOOST_PP_IS_ITERATING - #ifndef LUABIND_WRAPPER_BASE_HPP_INCLUDED #define LUABIND_WRAPPER_BASE_HPP_INCLUDED #include #include #include -#include - -#include -#include - +#include +#include #include namespace luabind @@ -48,9 +43,15 @@ namespace luabind // on the top of the stack (the input self reference will // be popped) LUABIND_API void do_call_member_selection(lua_State* L, char const* name); + + template, unsigned int... Indices, typename... Args> + R call_member_impl(lua_State* L, std::true_type /*void*/, meta::index_list, Args&&... args); + + template, unsigned int... Indices, typename... Args> + R call_member_impl(lua_State* L, std::false_type /*void*/, meta::index_list, Args&&... args); } - struct wrapped_self_t: weak_ref + struct wrapped_self_t : weak_ref { detail::lua_reference m_strong_ref; }; @@ -60,16 +61,41 @@ namespace luabind friend struct detail::wrap_access; wrap_base() {} - #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) - #include BOOST_PP_ITERATE() + template + R call(char const* name, Args&&... args) const + { + // this will be cleaned up by the proxy object + // once the call has been made + + // TODO: what happens if this virtual function is + // dispatched from a lua thread where the state + // pointer is different? + + // get the function + lua_State* L = m_self.state(); + m_self.get(L); + assert(!lua_isnil(L, -1)); + detail::do_call_member_selection(L, name); + + if(lua_isnil(L, -1)) + { + lua_pop(L, 1); + throw std::runtime_error("Attempt to call nonexistent function"); + } + + // push the self reference as the first parameter + m_self.get(L); + + // now the function and self objects + // are on the stack. These will both + // be popped by pcall + return detail::call_member_impl(L, std::is_void(), meta::index_range<1, sizeof...(Args)+1>(), std::forward(args)...); + } private: wrapped_self_t m_self; }; -#define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 2)) -#include BOOST_PP_ITERATE() - namespace detail { struct wrap_access @@ -89,104 +115,3 @@ namespace luabind #endif // LUABIND_WRAPPER_BASE_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 - typename boost::mpl::if_ - , luabind::detail::proxy_member_void_caller > - , luabind::detail::proxy_member_caller > >::type - call(char const* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _), detail::type_* = 0) const - { - typedef boost::tuples::tuple 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_ - , luabind::detail::proxy_member_void_caller > - , luabind::detail::proxy_member_caller > >::type proxy_type; - - // this will be cleaned up by the proxy object - // once the call has been made - - // TODO: what happens if this virtual function is - // dispatched from a lua thread where the state - // pointer is different? - - // get the function - lua_State* L = m_self.state(); - m_self.get(L); - assert(!lua_isnil(L, -1)); - detail::do_call_member_selection(L, name); - - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - throw std::runtime_error("Attempt to call nonexistent function"); - } - - // push the self reference as the first parameter - m_self.get(L); - - // now the function and self objects - // are on the stack. These will both - // be popped by pcall - return proxy_type(L, args); - } - -#undef LUABIND_CALL_MEMBER_NAME -#undef LUABIND_OPERATOR_PARAMS -#undef LUABIND_TUPLE_PARAMS - -#else // free call_member forwardarding functions - -#define N BOOST_PP_ITERATION() - -#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_ENUM_TRAILING_PARAMS(N, class A) - > - typename boost::mpl::if_< - boost::is_void - , detail::proxy_member_void_caller< - boost::tuples::tuple< - BOOST_PP_ENUM(N, LUABIND_TUPLE_PARAMS, _) - > - > - , detail::proxy_member_caller< - R - , boost::tuples::tuple< - BOOST_PP_ENUM(N, LUABIND_TUPLE_PARAMS, _) - > - > - >::type - call_member( - wrap_base const* self - , char const* fn - BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, A, &a) - , detail::type_* = 0 - ) - { - return self->call( - fn - BOOST_PP_ENUM_TRAILING_PARAMS(N, a) - , (detail::type_*)0 - ); - } - -#undef LUABIND_OPERATOR_PARAMS -#undef LUABIND_TUPLE_PARAMS - -#undef N - -#endif -#endif \ No newline at end of file diff --git a/libs/luabind/luabind/yield_policy.hpp b/libs/luabind/luabind/yield_policy.hpp index 9dbbefa29..5622b62a3 100644 --- a/libs/luabind/luabind/yield_policy.hpp +++ b/libs/luabind/luabind/yield_policy.hpp @@ -27,40 +27,18 @@ #include #include -namespace luabind { namespace detail -{ - struct yield_policy - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - }; +namespace luabind { - template - struct has_yield - { - BOOST_STATIC_CONSTANT(bool, - value = (boost::is_same::value || - has_yield::value)); - }; + namespace detail { - template<> - struct has_yield - { - BOOST_STATIC_CONSTANT(bool, value = false); - }; -}} + struct yield_policy + { + static void postcall(lua_State*, int /*results*/, meta::index_list_tag) {} + }; -namespace luabind -{ - detail::policy_cons const yield = {}; + } - namespace detail - { - inline void ignore_unused_yield() - { - (void)yield; - } - } + using yield = policy_list>; } #endif // LUABIND_YIELD_POLICY_HPP_INCLUDED diff --git a/libs/luabind/src/CMakeLists.txt b/libs/luabind/src/CMakeLists.txt new file mode 100644 index 000000000..a839fb65a --- /dev/null +++ b/libs/luabind/src/CMakeLists.txt @@ -0,0 +1,182 @@ +# Build for LuaBind +# Ryan Pavlik +# http://academic.cleardefinition.com/ +# Iowa State University HCI Graduate Program/VRAC + +set(LUABIND_SRCS + class.cpp + class_info.cpp + class_registry.cpp + class_rep.cpp + create_class.cpp + error.cpp + exception_handler.cpp + function.cpp + function_introspection.cpp + inheritance.cpp + link_compatibility.cpp + object_rep.cpp + open.cpp + operator.cpp + pcall.cpp + scope.cpp + set_package_preload.cpp + stack_content_by_name.cpp + weak_ref.cpp + wrapper_base.cpp) + +set(LUABIND_API + ../luabind/back_reference_fwd.hpp + ../luabind/back_reference.hpp + ../luabind/class.hpp + ../luabind/class_info.hpp + ../luabind/config.hpp + ../luabind/error.hpp + ../luabind/error_callback_fun.hpp + ../luabind/exception_handler.hpp + ../luabind/from_stack.hpp + ../luabind/function.hpp + ../luabind/function_introspection.hpp + ../luabind/get_main_thread.hpp + ../luabind/pointer_traits.hpp + ../luabind/handle.hpp + ../luabind/luabind.hpp + ../luabind/lua_argument_proxy.hpp + ../luabind/lua_include.hpp + ../luabind/lua_index_proxy.hpp + ../luabind/lua_iterator_proxy.hpp + ../luabind/lua_proxy_interface.hpp + ../luabind/lua_state_fwd.hpp + ../luabind/make_function.hpp + ../luabind/nil.hpp + ../luabind/object.hpp + ../luabind/open.hpp + ../luabind/operator.hpp + ../luabind/prefix.hpp + ../luabind/scope.hpp + ../luabind/set_package_preload.hpp + ../luabind/shared_ptr_converter.hpp + ../luabind/tag_function.hpp + ../luabind/typeid.hpp + ../luabind/lua_proxy.hpp + ../luabind/version.hpp + ../luabind/weak_ref.hpp + ../luabind/wrapper_base.hpp +) +source_group(API FILES ${LUABIND_API}) + +set(LUABIND_DETAIL_API + ../luabind/detail/meta.hpp + ../luabind/detail/call_traits.hpp + ../luabind/detail/call_shared.hpp + ../luabind/detail/crtp_iterator.hpp + ../luabind/detail/call_function.hpp + ../luabind/detail/call.hpp + ../luabind/detail/call_member.hpp + ../luabind/detail/class_registry.hpp + ../luabind/detail/class_rep.hpp + ../luabind/detail/constructor.hpp + ../luabind/detail/conversion_storage.hpp + ../luabind/detail/push_to_lua.hpp + ../luabind/detail/debug.hpp + ../luabind/detail/decorate_type.hpp + ../luabind/detail/deduce_signature.hpp + ../luabind/detail/enum_maker.hpp + ../luabind/detail/format_signature.hpp + ../luabind/detail/garbage_collector.hpp + ../luabind/detail/inheritance.hpp + ../luabind/detail/instance_holder.hpp + ../luabind/detail/link_compatibility.hpp + ../luabind/detail/make_instance.hpp + ../luabind/detail/object.hpp + ../luabind/detail/object_rep.hpp + ../luabind/detail/open.hpp + ../luabind/detail/operator_id.hpp + ../luabind/detail/other.hpp + ../luabind/detail/pcall.hpp + ../luabind/detail/policy.hpp + ../luabind/detail/primitives.hpp + ../luabind/detail/property.hpp + ../luabind/detail/ref.hpp + ../luabind/detail/signature_match.hpp + ../luabind/detail/stack_utils.hpp + ../luabind/detail/type_traits.hpp +) +source_group(Internal FILES ${LUABIND_DETAIL_API}) + +set(LUABIND_DEFAULT_POLICIES + ../luabind/detail/conversion_policies/pointer_converter.hpp + ../luabind/detail/conversion_policies/reference_converter.hpp + ../luabind/detail/conversion_policies/value_converter.hpp + ../luabind/detail/conversion_policies/enum_converter.hpp + ../luabind/detail/conversion_policies/function_converter.hpp + ../luabind/detail/conversion_policies/conversion_base.hpp + ../luabind/detail/conversion_policies/conversion_policies.hpp + ../luabind/detail/conversion_policies/lua_proxy_converter.hpp + ../luabind/detail/conversion_policies/native_converter.hpp + ) +source_group("Default Policies" FILES ${LUABIND_DEFAULT_POLICIES} ) + +set(LUABIND_USER_POLICIES + ../luabind/yield_policy.hpp + ../luabind/no_dependency.hpp + ../luabind/iterator_policy.hpp + ../luabind/container_policy.hpp + ../luabind/copy_policy.hpp + ../luabind/dependency_policy.hpp + ../luabind/discard_result_policy.hpp + ../luabind/adopt_policy.hpp + ../luabind/out_value_policy.hpp + ../luabind/return_reference_to_policy.hpp + ../luabind/raw_policy.hpp +) +source_group("User Policies" FILES ${LUABIND_USER_POLICIES} ) + +set(LUABIND_EXTRA_LIBS) +if(MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251") +elseif(CMAKE_COMPILER_IS_GNUCXX) + list(APPEND LUABIND_EXTRA_LIBS m) +endif() + +add_library(luabind ${LUABIND_SRCS} ${LUABIND_API} ${LUABIND_DETAIL_API} ${LUABIND_DEFAULT_POLICIES} ${LUABIND_USER_POLICIES}) +target_link_libraries(luabind ${LUA_LIBRARIES} ${LUABIND_EXTRA_LIBS}) + +set_property(TARGET luabind PROPERTY COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_C_FLAGS}) +set_property(TARGET luabind PROPERTY PROJECT_LABEL "LuaBind Library") + +set(ALLHEADERS ${LUABIND_API} ${LUABIND_DETAIL_API} PARENT_SCOPE) +set(APIHEADERS ${LUABIND_API} PARENT_SCOPE) + +if(LUABIND_INSTALL) + if(NOT INCLUDE_DIR) + set(INCLUDE_DIR include) + endif() + if(NOT LIB_DIR) + set(LIB_DIR lib) + endif() + if(NOT ARCH_DIR) + set(ARCH_DIR lib) + endif() + if(NOT BIN_DIR) + set(BIN_DIR bin) + endif() + install(FILES ${LUABIND_API} + DESTINATION ${INCLUDE_DIR}/luabind + COMPONENT sdk) + install(FILES ${LUABIND_USER_POLICIES} + DESTINATION ${INCLUDE_DIR}/luabind + COMPONENT sdk) + install(FILES ${LUABIND_DETAIL_API} + DESTINATION ${INCLUDE_DIR}/luabind/detail + COMPONENT sdk) + install(FILES ${LUABIND_DEFAULT_POLICIES} + DESTINATION ${INCLUDE_DIR}/luabind/detail/conversion_policies + COMPONENT sdk) + install(TARGETS luabind + EXPORT luabind + RUNTIME DESTINATION ${BIN_DIR} COMPONENT runtime + LIBRARY DESTINATION ${LIB_DIR} COMPONENT runtime + ARCHIVE DESTINATION ${ARCH_DIR} COMPONENT sdk) +endif() + diff --git a/libs/luabind/src/class.cpp b/libs/luabind/src/class.cpp index 8a67cf6f3..ee772b643 100644 --- a/libs/luabind/src/class.cpp +++ b/libs/luabind/src/class.cpp @@ -22,316 +22,307 @@ #define LUABIND_BUILDING -#include - #include #include #include #include +#include #include #include -namespace luabind -{ - LUABIND_API detail::nil_type nil; -} +namespace luabind { + namespace detail { -namespace luabind { namespace detail { - - namespace - { - struct cast_entry - { - cast_entry(class_id src, class_id target, cast_function cast) - : src(src) - , target(target) - , cast(cast) - {} + namespace + { + struct cast_entry + { + cast_entry(class_id src, class_id target, cast_function cast) + : src(src) + , target(target) + , cast(cast) + {} - class_id src; - class_id target; - cast_function cast; - }; + class_id src; + class_id target; + cast_function cast; + }; - } // namespace unnamed + } // namespace unnamed - struct class_registration : registration - { - class_registration(char const* name); + struct class_registration : registration + { + class_registration(char const* name); - void register_(lua_State* L) const; + void register_(lua_State* L) const; - const char* m_name; + const char* m_name; - mutable std::map m_static_constants; + mutable std::map m_static_constants; - typedef std::pair base_desc; - mutable std::vector m_bases; + using base_desc = std::pair; + mutable std::vector m_bases; - type_id m_type; - class_id m_id; - class_id m_wrapper_id; - type_id m_wrapper_type; - std::vector m_casts; + type_id m_type; + class_id m_id; + class_id m_wrapper_id; + type_id m_wrapper_type; + std::vector m_casts; - scope m_scope; - scope m_members; - scope m_default_members; - }; - - class_registration::class_registration(char const* name) - { - m_name = name; - } - - void class_registration::register_(lua_State* L) const - { - LUABIND_CHECK_STACK(L); - - assert(lua_type(L, -1) == LUA_TTABLE); - - lua_pushstring(L, m_name); - - detail::class_rep* crep; - - detail::class_registry* r = detail::class_registry::get_registry(L); - // create a class_rep structure for this class. - // allocate it within lua to let lua collect it on - // lua_close(). This is better than allocating it - // as a static, since it will then be destructed - // when the program exits instead. - // warning: we assume that lua will not - // move the userdata memory. - lua_newuserdata(L, sizeof(detail::class_rep)); - crep = reinterpret_cast(lua_touserdata(L, -1)); - - new(crep) detail::class_rep( - m_type - , m_name - , L - ); - - // register this new type in the class registry - r->add_class(m_type, crep); - - lua_pushstring(L, "__luabind_class_map"); - lua_rawget(L, LUA_REGISTRYINDEX); - class_map& classes = *static_cast( - lua_touserdata(L, -1)); - lua_pop(L, 1); - - classes.put(m_id, crep); - - bool const has_wrapper = m_wrapper_id != registered_class::id; - - if (has_wrapper) - classes.put(m_wrapper_id, crep); - - crep->m_static_constants.swap(m_static_constants); - - detail::class_registry* registry = detail::class_registry::get_registry(L); - - crep->get_default_table(L); - m_scope.register_(L); - m_default_members.register_(L); - lua_pop(L, 1); - - crep->get_table(L); - m_members.register_(L); - lua_pop(L, 1); - - lua_pushstring(L, "__luabind_cast_graph"); - lua_gettable(L, LUA_REGISTRYINDEX); - cast_graph* const casts = static_cast( - lua_touserdata(L, -1)); - lua_pop(L, 1); - - lua_pushstring(L, "__luabind_class_id_map"); - lua_gettable(L, LUA_REGISTRYINDEX); - class_id_map* const class_ids = static_cast( - lua_touserdata(L, -1)); - lua_pop(L, 1); - - class_ids->put(m_id, m_type); - - if (has_wrapper) - class_ids->put(m_wrapper_id, m_wrapper_type); - - BOOST_FOREACH(cast_entry const& e, m_casts) - { - casts->insert(e.src, e.target, e.cast); - } - - for (std::vector::iterator i = m_bases.begin(); - i != m_bases.end(); ++i) - { - LUABIND_CHECK_STACK(L); - - // the baseclass' class_rep structure - detail::class_rep* bcrep = registry->find_class(i->first); - - detail::class_rep::base_info base; - base.pointer_offset = 0; - base.base = bcrep; - - crep->add_base_class(base); - - // copy base class table - crep->get_table(L); - bcrep->get_table(L); - lua_pushnil(L); - - while (lua_next(L, -2)) - { - lua_pushvalue(L, -2); // copy key - lua_gettable(L, -5); - - if (!lua_isnil(L, -1)) - { - lua_pop(L, 2); - continue; - } - - lua_pop(L, 1); - lua_pushvalue(L, -2); // copy key - lua_insert(L, -2); - - lua_settable(L, -5); - } - lua_pop(L, 2); - - // copy base class detaults table - crep->get_default_table(L); - bcrep->get_default_table(L); - lua_pushnil(L); - - while (lua_next(L, -2)) - { - lua_pushvalue(L, -2); // copy key - lua_gettable(L, -5); - - if (!lua_isnil(L, -1)) - { - lua_pop(L, 2); - continue; - } - - lua_pop(L, 1); - lua_pushvalue(L, -2); // copy key - lua_insert(L, -2); - - lua_settable(L, -5); - } - lua_pop(L, 2); + scope m_scope; + scope m_members; + scope m_default_members; + }; + class_registration::class_registration(char const* name) + { + m_name = name; } - lua_settable(L, -3); - } - - // -- interface --------------------------------------------------------- + void class_registration::register_(lua_State* L) const + { + LUABIND_CHECK_STACK(L); - class_base::class_base(char const* name) - : scope(std::auto_ptr( - m_registration = new class_registration(name)) - ) - { - } + assert(lua_type(L, -1) == LUA_TTABLE); - void class_base::init( - type_id const& type_id_, class_id id - , type_id const& wrapper_type, class_id wrapper_id) - { - m_registration->m_type = type_id_; - m_registration->m_id = id; - m_registration->m_wrapper_type = wrapper_type; - m_registration->m_wrapper_id = wrapper_id; - } + lua_pushstring(L, m_name); - void class_base::add_base(type_id const& base, cast_function cast) - { - m_registration->m_bases.push_back(std::make_pair(base, cast)); - } + detail::class_rep* crep; + + detail::class_registry* r = detail::class_registry::get_registry(L); + // create a class_rep structure for this class. + // allocate it within lua to let lua collect it on + // lua_close(). This is better than allocating it + // as a static, since it will then be destructed + // when the program exits instead. + // warning: we assume that lua will not + // move the userdata memory. + lua_newuserdata(L, sizeof(detail::class_rep)); + crep = reinterpret_cast(lua_touserdata(L, -1)); + + new(crep) detail::class_rep( + m_type + , m_name + , L + ); + + // register this new type in the class registry + r->add_class(m_type, crep); + + lua_pushstring(L, "__luabind_class_map"); + lua_rawget(L, LUA_REGISTRYINDEX); + class_map& classes = *static_cast( + lua_touserdata(L, -1)); + lua_pop(L, 1); + + classes.put(m_id, crep); + + bool const has_wrapper = m_wrapper_id != registered_class::id; + + if(has_wrapper) + classes.put(m_wrapper_id, crep); + + crep->m_static_constants.swap(m_static_constants); + + detail::class_registry* registry = detail::class_registry::get_registry(L); + + crep->get_default_table(L); + m_scope.register_(L); + m_default_members.register_(L); + lua_pop(L, 1); + + crep->get_table(L); + m_members.register_(L); + lua_pop(L, 1); + + lua_pushstring(L, "__luabind_cast_graph"); + lua_gettable(L, LUA_REGISTRYINDEX); + cast_graph* const casts = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); + + lua_pushstring(L, "__luabind_class_id_map"); + lua_gettable(L, LUA_REGISTRYINDEX); + class_id_map* const class_ids = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); + + class_ids->put(m_id, m_type); + + if(has_wrapper) { + class_ids->put(m_wrapper_id, m_wrapper_type); + } + + for(auto const& e : m_casts) { + casts->insert(e.src, e.target, e.cast); + } + + for(const auto& base_pair : m_bases) { + LUABIND_CHECK_STACK(L); + + // the baseclass' class_rep structure + detail::class_rep* bcrep = registry->find_class(base_pair.first); + + detail::class_rep::base_info base; + base.pointer_offset = 0; + base.base = bcrep; + + crep->add_base_class(base); + + // copy base class table + crep->get_table(L); + bcrep->get_table(L); + lua_pushnil(L); + + while(lua_next(L, -2)) + { + lua_pushvalue(L, -2); // copy key + lua_gettable(L, -5); + + if(!lua_isnil(L, -1)) + { + lua_pop(L, 2); + continue; + } + + lua_pop(L, 1); + lua_pushvalue(L, -2); // copy key + lua_insert(L, -2); + + lua_settable(L, -5); + } + lua_pop(L, 2); + + // copy base class detaults table + crep->get_default_table(L); + bcrep->get_default_table(L); + lua_pushnil(L); + + while(lua_next(L, -2)) + { + lua_pushvalue(L, -2); // copy key + lua_gettable(L, -5); + + if(!lua_isnil(L, -1)) + { + lua_pop(L, 2); + continue; + } + + lua_pop(L, 1); + lua_pushvalue(L, -2); // copy key + lua_insert(L, -2); + + lua_settable(L, -5); + } + lua_pop(L, 2); + + } + + lua_settable(L, -3); + } + + // -- interface --------------------------------------------------------- + + class_base::class_base(char const* name) + : scope(std::unique_ptr( + m_registration = new class_registration(name)) + ) + { + } + + void class_base::init( + type_id const& type_id_, class_id id + , type_id const& wrapper_type, class_id wrapper_id) + { + m_registration->m_type = type_id_; + m_registration->m_id = id; + m_registration->m_wrapper_type = wrapper_type; + m_registration->m_wrapper_id = wrapper_id; + } + + void class_base::add_base(type_id const& base, cast_function cast) + { + m_registration->m_bases.push_back(std::make_pair(base, cast)); + } + + void class_base::add_member(registration* member) + { + std::unique_ptr ptr(member); + m_registration->m_members.operator,(scope(std::move(ptr))); + } + + void class_base::add_default_member(registration* member) + { + std::unique_ptr ptr(member); + m_registration->m_default_members.operator,(scope(std::move(ptr))); + } + + const char* class_base::name() const + { + return m_registration->m_name; + } + + void class_base::add_static_constant(const char* name, int val) + { + m_registration->m_static_constants[name] = val; + } + + void class_base::add_inner_scope(scope& s) + { + m_registration->m_scope.operator,(s); + } + + void class_base::add_cast( + class_id src, class_id target, cast_function cast) + { + m_registration->m_casts.push_back(cast_entry(src, target, cast)); + } + + void add_custom_name(type_id const& i, std::string& s) + { + s += " ["; + s += i.name(); + s += "]"; + } + + std::string get_class_name(lua_State* L, type_id const& i) + { + std::string ret; + + assert(L); + + class_registry* r = class_registry::get_registry(L); + class_rep* crep = r->find_class(i); + + if(crep == 0) + { + ret = "custom"; + add_custom_name(i, ret); + } else + { + /* TODO reimplement this? + if (i == crep->holder_type()) + { + ret += "smart_ptr<"; + ret += crep->name(); + ret += ">"; + } + else if (i == crep->const_holder_type()) + { + ret += "smart_ptrname(); + ret += ">"; + } + else*/ + { + ret += crep->name(); + } + } + return ret; + } - void class_base::add_member(registration* member) - { - std::auto_ptr ptr(member); - m_registration->m_members.operator,(scope(ptr)); } - - void class_base::add_default_member(registration* member) - { - std::auto_ptr ptr(member); - m_registration->m_default_members.operator,(scope(ptr)); - } - - const char* class_base::name() const - { - return m_registration->m_name; - } - - void class_base::add_static_constant(const char* name, int val) - { - m_registration->m_static_constants[name] = val; - } - - void class_base::add_inner_scope(scope& s) - { - m_registration->m_scope.operator,(s); - } - - void class_base::add_cast( - class_id src, class_id target, cast_function cast) - { - m_registration->m_casts.push_back(cast_entry(src, target, cast)); - } - - void add_custom_name(type_id const& i, std::string& s) - { - s += " ["; - s += i.name(); - s += "]"; - } - - std::string get_class_name(lua_State* L, type_id const& i) - { - std::string ret; - - assert(L); - - class_registry* r = class_registry::get_registry(L); - class_rep* crep = r->find_class(i); - - if (crep == 0) - { - ret = "custom"; - add_custom_name(i, ret); - } - else - { - /* TODO reimplement this? - if (i == crep->holder_type()) - { - ret += "smart_ptr<"; - ret += crep->name(); - ret += ">"; - } - else if (i == crep->const_holder_type()) - { - ret += "smart_ptrname(); - ret += ">"; - } - else*/ - { - ret += crep->name(); - } - } - return ret; - } - -}} // namespace luabind::detail +} // namespace luabind::detail diff --git a/libs/luabind/src/class_info.cpp b/libs/luabind/src/class_info.cpp index 531f6e0cc..3f219e827 100644 --- a/libs/luabind/src/class_info.cpp +++ b/libs/luabind/src/class_info.cpp @@ -27,94 +27,111 @@ #include #include #include +#include +#include + +/* +#include +#define VERBOSE(X) std::cout << __FILE__ << ":" << __LINE__ << ": " << X << std::endl +*/ +#define VERBOSE(X) + +namespace luabind { -namespace luabind -{ LUABIND_API class_info get_class_info(argument const& o) { lua_State* L = o.interpreter(); - + detail::class_rep * crep = NULL; + o.push(L); - detail::object_rep* obj = detail::get_instance(L, -1); + if(detail::is_class_rep(L, -1)) { + VERBOSE("OK, got a class rep"); + // OK, o is a class rep, now at the top of the stack + crep = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); + } else { - if (!obj) - { - class_info result; - result.name = lua_typename(L, lua_type(L, -1)); - lua_pop(L, 1); - result.methods = newtable(L); - result.attributes = newtable(L); - return result; - } + VERBOSE("Not a class rep"); + detail::object_rep* obj = detail::get_instance(L, -1); - lua_pop(L, 1); + if(!obj) + { + VERBOSE("Not a obj rep"); + class_info result; + result.name = lua_typename(L, lua_type(L, -1)); + lua_pop(L, 1); + result.methods = newtable(L); + result.attributes = newtable(L); + return result; + } else { + lua_pop(L, 1); + // OK, we were given an object - gotta get the crep. + crep = obj->crep(); + } + } + crep->get_table(L); + object table(from_stack(L, -1)); + lua_pop(L, 1); - obj->crep()->get_table(L); - object table(from_stack(L, -1)); - lua_pop(L, 1); + class_info result; + result.name = crep->name(); + result.methods = newtable(L); + result.attributes = newtable(L); - class_info result; - result.name = obj->crep()->name(); - result.methods = newtable(L); - result.attributes = newtable(L); + std::size_t index = 1; - std::size_t index = 1; + for(iterator i(table), e; i != e; ++i) + { + if(type(*i) != LUA_TFUNCTION) + continue; - for (iterator i(table), e; i != e; ++i) - { - if (type(*i) != LUA_TFUNCTION) - continue; + // We have to create a temporary `object` here, otherwise the proxy + // returned by operator->() will mess up the stack. This is a known + // problem that probably doesn't show up in real code very often. + object member(*i); + member.push(L); + detail::stack_pop pop(L, 1); - // We have to create a temporary `object` here, otherwise the proxy - // returned by operator->() will mess up the stack. This is a known - // problem that probably doesn't show up in real code very often. - object member(*i); - member.push(L); - detail::stack_pop pop(L, 1); + if(lua_tocfunction(L, -1) == &detail::property_tag) + { + result.attributes[index++] = i.key(); + } else + { + result.methods[i.key()] = *i; + } + } - if (lua_tocfunction(L, -1) == &detail::property_tag) - { - result.attributes[index++] = i.key(); - } - else - { - result.methods[i.key()] = *i; - } - } - - return result; + return result; } - LUABIND_API object get_class_names(lua_State* L) - { - detail::class_registry* reg = detail::class_registry::get_registry(L); + LUABIND_API object get_class_names(lua_State* L) + { + detail::class_registry* reg = detail::class_registry::get_registry(L); - std::map const& classes = reg->get_classes(); + std::map const& classes = reg->get_classes(); - object result = newtable(L); - std::size_t index = 1; + object result = newtable(L); + std::size_t index = 1; - for (std::map::const_iterator iter = classes.begin(); - iter != classes.end(); ++iter) - { - result[index++] = iter->second->name(); - } + for(const auto& cl : classes) { + result[index++] = cl.second->name(); + } - return result; - } + return result; + } LUABIND_API void bind_class_info(lua_State* L) { module(L) - [ - class_("class_info_data") + [ + class_("class_info_data") .def_readonly("name", &class_info::name) - .def_readonly("methods", &class_info::methods) - .def_readonly("attributes", &class_info::attributes), - - def("class_info", &get_class_info), - def("class_names", &get_class_names) - ]; + .def_readonly("methods", &class_info::methods) + .def_readonly("attributes", &class_info::attributes), + + def("class_info", &get_class_info), + def("class_names", &get_class_names) + ]; } } diff --git a/libs/luabind/src/class_registry.cpp b/libs/luabind/src/class_registry.cpp index 79df30ade..046cb689b 100644 --- a/libs/luabind/src/class_registry.cpp +++ b/libs/luabind/src/class_registry.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2004 Daniel Wallin +// 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"), @@ -22,145 +22,121 @@ #define LUABIND_BUILDING -#include +#include // for lua_pushstring, lua_rawset, etc -#include -#include -#include -#include +#include // for LUABIND_API +#include // for type_id +#include // for class_registry +#include // for class_rep +#include // for garbage_collector -namespace luabind { namespace detail { - LUABIND_API void push_instance_metatable(lua_State* L); +#include // for assert +#include // for map, etc +#include // for pair - namespace { +namespace luabind { + namespace detail { - int create_cpp_class_metatable(lua_State* L) - { - lua_newtable(L); + LUABIND_API void push_instance_metatable(lua_State* L); - // mark the table with our (hopefully) unique tag - // that says that the user data that has this - // metatable is a class_rep - lua_pushstring(L, "__luabind_classrep"); - lua_pushboolean(L, 1); - lua_rawset(L, -3); + namespace { - lua_pushstring(L, "__gc"); - lua_pushcclosure( - L - , &garbage_collector_s< - detail::class_rep - >::apply - , 0); + /// @todo is this redundant with the following function? All that differs is the __gc closure + int create_cpp_class_metatable(lua_State* L) + { + lua_newtable(L); - lua_rawset(L, -3); + // mark the table with our (hopefully) unique tag + // that says that the user data that has this + // metatable is a class_rep + lua_pushstring(L, "__luabind_classrep"); + lua_pushboolean(L, 1); + lua_rawset(L, -3); - lua_pushstring(L, "__call"); - lua_pushcclosure(L, &class_rep::constructor_dispatcher, 0); - lua_rawset(L, -3); + lua_pushstring(L, "__gc"); + lua_pushcclosure(L, &garbage_collector, 0); - lua_pushstring(L, "__index"); - lua_pushcclosure(L, &class_rep::static_class_gettable, 0); - lua_rawset(L, -3); + lua_rawset(L, -3); - lua_pushstring(L, "__newindex"); - lua_pushcclosure(L, &class_rep::lua_settable_dispatcher, 0); - lua_rawset(L, -3); + lua_pushstring(L, "__call"); + lua_pushcclosure(L, &class_rep::constructor_dispatcher, 0); + lua_rawset(L, -3); - return luaL_ref(L, LUA_REGISTRYINDEX); - } + lua_pushstring(L, "__index"); + lua_pushcclosure(L, &class_rep::static_class_gettable, 0); + lua_rawset(L, -3); - int create_lua_class_metatable(lua_State* L) - { - lua_newtable(L); + lua_pushstring(L, "__newindex"); + lua_pushcclosure(L, &class_rep::lua_settable_dispatcher, 0); + lua_rawset(L, -3); - lua_pushstring(L, "__luabind_classrep"); - lua_pushboolean(L, 1); - lua_rawset(L, -3); + return luaL_ref(L, LUA_REGISTRYINDEX); + } - lua_pushstring(L, "__gc"); - lua_pushcclosure( - L - , &detail::garbage_collector_s< - detail::class_rep - >::apply - , 0); + int create_lua_class_metatable(lua_State* L) + { + return create_cpp_class_metatable(L); + } - lua_rawset(L, -3); + } // namespace unnamed - lua_pushstring(L, "__newindex"); - lua_pushcclosure(L, &class_rep::lua_settable_dispatcher, 0); - lua_rawset(L, -3); + class class_rep; - lua_pushstring(L, "__call"); - lua_pushcclosure(L, &class_rep::constructor_dispatcher, 0); - lua_rawset(L, -3); + class_registry::class_registry(lua_State* L) + : m_cpp_class_metatable(create_cpp_class_metatable(L)) + , m_lua_class_metatable(create_lua_class_metatable(L)) + { + push_instance_metatable(L); + m_instance_metatable = luaL_ref(L, LUA_REGISTRYINDEX); + } - lua_pushstring(L, "__index"); - lua_pushcclosure(L, &class_rep::static_class_gettable, 0); - lua_rawset(L, -3); - - return luaL_ref(L, LUA_REGISTRYINDEX); - } - - } // namespace unnamed - - class class_rep; - - class_registry::class_registry(lua_State* L) - : m_cpp_class_metatable(create_cpp_class_metatable(L)) - , m_lua_class_metatable(create_lua_class_metatable(L)) - { - push_instance_metatable(L); - m_instance_metatable = luaL_ref(L, LUA_REGISTRYINDEX); - } - - class_registry* class_registry::get_registry(lua_State* L) - { + class_registry* class_registry::get_registry(lua_State* L) + { #ifdef LUABIND_NOT_THREADSAFE - // if we don't have to be thread safe, we can keep a - // chache of the class_registry pointer without the - // need of a mutex - static lua_State* cache_key = 0; - static class_registry* registry_cache = 0; - if (cache_key == L) return registry_cache; + // if we don't have to be thread safe, we can keep a + // chache of the class_registry pointer without the + // need of a mutex + static lua_State* cache_key = 0; + static class_registry* registry_cache = 0; + if(cache_key == L) return registry_cache; #endif - lua_pushstring(L, "__luabind_classes"); - lua_gettable(L, LUA_REGISTRYINDEX); - class_registry* p = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); + lua_pushstring(L, "__luabind_classes"); + lua_gettable(L, LUA_REGISTRYINDEX); + class_registry* p = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); #ifdef LUABIND_NOT_THREADSAFE - cache_key = L; - registry_cache = p; + cache_key = L; + registry_cache = p; #endif - return p; - } + return p; + } - void class_registry::add_class(type_id const& info, class_rep* crep) - { - // class is already registered - assert((m_classes.find(info) == m_classes.end()) - && "you are trying to register a class twice"); - m_classes[info] = crep; - } + void class_registry::add_class(type_id const& info, class_rep* crep) + { + // class is already registered + assert((m_classes.find(info) == m_classes.end()) + && "you are trying to register a class twice"); + m_classes[info] = crep; + } - class_rep* class_registry::find_class(type_id const& info) const - { - std::map::const_iterator i( - m_classes.find(info)); + class_rep* class_registry::find_class(type_id const& info) const + { + std::map::const_iterator i( + m_classes.find(info)); - if (i == m_classes.end()) return 0; // the type is not registered - return i->second; - } + if(i == m_classes.end()) return 0; // the type is not registered + return i->second; + } -}} // namespace luabind::detail + } // namespace detail +} // namespace luabind diff --git a/libs/luabind/src/class_rep.cpp b/libs/luabind/src/class_rep.cpp index 5f03f3931..f6d7da015 100644 --- a/libs/luabind/src/class_rep.cpp +++ b/libs/luabind/src/class_rep.cpp @@ -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"), @@ -31,17 +31,23 @@ #include #include +#if LUA_VERSION_NUM < 502 +# define lua_rawlen lua_objlen +#endif + using namespace luabind::detail; -namespace luabind { namespace detail -{ - LUABIND_API int property_tag(lua_State* L) +namespace luabind { + namespace detail { - lua_pushstring(L, "luabind: property_tag function can't be called"); - lua_error(L); - return 0; + LUABIND_API int property_tag(lua_State* L) + { + lua_pushstring(L, "luabind: property_tag function can't be called"); + lua_error(L); + return 0; + } } -}} +} luabind::detail::class_rep::class_rep(type_id const& type , const char* name @@ -52,6 +58,11 @@ luabind::detail::class_rep::class_rep(type_id const& type , m_class_type(cpp_class) , m_operator_cache(0) { + shared_init(L); +} + + +void luabind::detail::class_rep::shared_init(lua_State * L) { lua_newtable(L); handle(L, -1).swap(m_table); lua_newtable(L); @@ -59,25 +70,27 @@ luabind::detail::class_rep::class_rep(type_id const& type lua_pop(L, 2); class_registry* r = class_registry::get_registry(L); + // the following line should be equivalent whether or not this is a cpp class assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()"); - lua_rawgeti(L, LUA_REGISTRYINDEX, r->cpp_class()); + lua_rawgeti(L, LUA_REGISTRYINDEX, (m_class_type == cpp_class) ? r->cpp_class() : r->lua_class()); lua_setmetatable(L, -2); lua_pushvalue(L, -1); // duplicate our user data m_self_ref.set(L); - m_instance_metatable = r->cpp_instance(); + m_instance_metatable = (m_class_type == cpp_class) ? r->cpp_instance() : r->lua_instance(); - lua_pushstring(L, "__luabind_cast_graph"); - lua_gettable(L, LUA_REGISTRYINDEX); - m_casts = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); + lua_pushstring(L, "__luabind_cast_graph"); + lua_gettable(L, LUA_REGISTRYINDEX); + m_casts = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); + + lua_pushstring(L, "__luabind_class_id_map"); + lua_gettable(L, LUA_REGISTRYINDEX); + m_classes = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); - lua_pushstring(L, "__luabind_class_id_map"); - lua_gettable(L, LUA_REGISTRYINDEX); - m_classes = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); } luabind::detail::class_rep::class_rep(lua_State* L, const char* name) @@ -86,31 +99,7 @@ luabind::detail::class_rep::class_rep(lua_State* L, const char* name) , m_class_type(lua_class) , m_operator_cache(0) { - lua_newtable(L); - handle(L, -1).swap(m_table); - lua_newtable(L); - handle(L, -1).swap(m_default_table); - lua_pop(L, 2); - - class_registry* r = class_registry::get_registry(L); - assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()"); - - lua_rawgeti(L, LUA_REGISTRYINDEX, r->lua_class()); - lua_setmetatable(L, -2); - lua_pushvalue(L, -1); // duplicate our user data - m_self_ref.set(L); - - m_instance_metatable = r->lua_instance(); - - lua_pushstring(L, "__luabind_cast_graph"); - lua_gettable(L, LUA_REGISTRYINDEX); - m_casts = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); - - lua_pushstring(L, "__luabind_class_id_map"); - lua_gettable(L, LUA_REGISTRYINDEX); - m_classes = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); + shared_init(L); } luabind::detail::class_rep::~class_rep() @@ -118,61 +107,61 @@ luabind::detail::class_rep::~class_rep() } // leaves object on lua stack -std::pair +std::pair luabind::detail::class_rep::allocate(lua_State* L) const { const int size = sizeof(object_rep); char* mem = static_cast(lua_newuserdata(L, size)); - return std::pair(mem, (void*)0); + return std::pair(mem, (void*)0); } namespace { - bool super_deprecation_disabled = false; + bool super_deprecation_disabled = false; } // namespace unnamed // this is called as metamethod __call on the class_rep. int luabind::detail::class_rep::constructor_dispatcher(lua_State* L) { - class_rep* cls = static_cast(lua_touserdata(L, 1)); + class_rep* cls = static_cast(lua_touserdata(L, 1)); - int args = lua_gettop(L); + int args = lua_gettop(L); - push_new_instance(L, cls); + push_new_instance(L, cls); - if (super_deprecation_disabled - && cls->get_class_type() == class_rep::lua_class - && !cls->bases().empty()) - { - lua_pushvalue(L, 1); - lua_pushvalue(L, -2); - lua_pushcclosure(L, super_callback, 2); - lua_setglobal(L, "super"); - } + if(super_deprecation_disabled + && cls->get_class_type() == class_rep::lua_class + && !cls->bases().empty()) + { + lua_pushvalue(L, 1); + lua_pushvalue(L, -2); + lua_pushcclosure(L, super_callback, 2); + lua_setglobal(L, "super"); + } - lua_pushvalue(L, -1); - lua_replace(L, 1); + lua_pushvalue(L, -1); + lua_replace(L, 1); - cls->get_table(L); - lua_pushliteral(L, "__init"); - lua_gettable(L, -2); + cls->get_table(L); + lua_pushliteral(L, "__init"); + lua_gettable(L, -2); - lua_insert(L, 1); + lua_insert(L, 1); - lua_pop(L, 1); - lua_insert(L, 1); + lua_pop(L, 1); + lua_insert(L, 1); - lua_call(L, args, 0); + lua_call(L, args, 0); - if (super_deprecation_disabled) - { - lua_pushnil(L); - lua_setglobal(L, "super"); - } + if(super_deprecation_disabled) + { + lua_pushnil(L); + lua_setglobal(L, "super"); + } - return 1; + return 1; } void luabind::detail::class_rep::add_base_class(const luabind::detail::class_rep::base_info& binfo) @@ -187,11 +176,9 @@ void luabind::detail::class_rep::add_base_class(const luabind::detail::class_rep class_rep* bcrep = binfo.base; // import all static constants - for (std::map::const_iterator i = bcrep->m_static_constants.begin(); - i != bcrep->m_static_constants.end(); ++i) - { - int& v = m_static_constants[i->first]; - v = i->second; + for(const auto& scon : bcrep->m_static_constants) { + int& v = m_static_constants[scon.first]; + v = scon.second; } // also, save the baseclass info to be used for typecasts @@ -200,17 +187,17 @@ void luabind::detail::class_rep::add_base_class(const luabind::detail::class_rep LUABIND_API void luabind::disable_super_deprecation() { - super_deprecation_disabled = true; + super_deprecation_disabled = true; } int luabind::detail::class_rep::super_callback(lua_State* L) { int args = lua_gettop(L); - + class_rep* crep = static_cast(lua_touserdata(L, lua_upvalueindex(1))); class_rep* base = crep->bases()[0].base; - if (base->bases().empty()) + if(base->bases().empty()) { lua_pushnil(L); lua_setglobal(L, "super"); @@ -265,7 +252,7 @@ int luabind::detail::class_rep::lua_settable_dispatcher(lua_State* L) lua_rawset(L, -3); crep->m_operator_cache = 0; // invalidate cache - + return 0; } @@ -282,12 +269,12 @@ int luabind::detail::class_rep::static_class_gettable(lua_State* L) crep->get_default_table(L); lua_pushvalue(L, 2); lua_gettable(L, -2); - if (!lua_isnil(L, -1)) return 1; + if(!lua_isnil(L, -1)) return 1; else lua_pop(L, 2); const char* key = lua_tostring(L, 2); - if (std::strlen(key) != lua_strlen(L, 2)) + if(std::strlen(key) != lua_rawlen(L, 2)) { lua_pushnil(L); return 1; @@ -295,7 +282,7 @@ int luabind::detail::class_rep::static_class_gettable(lua_State* L) std::map::const_iterator j = crep->m_static_constants.find(key); - if (j != crep->m_static_constants.end()) + if(j != crep->m_static_constants.end()) { lua_pushnumber(L, j->second); return 1; @@ -303,14 +290,7 @@ int luabind::detail::class_rep::static_class_gettable(lua_State* L) #ifndef LUABIND_NO_ERROR_CHECKING - { - std::string msg = "no static '"; - msg += key; - msg += "' in class '"; - msg += crep->name(); - msg += "'"; - lua_pushstring(L, msg.c_str()); - } + lua_pushfstring(L, "no static '%s' in class '%s'", key, crep->name()); lua_error(L); #endif @@ -320,13 +300,13 @@ int luabind::detail::class_rep::static_class_gettable(lua_State* L) return 1; } -bool luabind::detail::is_class_rep(lua_State* L, int index) +LUABIND_API bool luabind::detail::is_class_rep(lua_State* L, int index) { - if (lua_getmetatable(L, index) == 0) return false; + if(lua_getmetatable(L, index) == 0) return false; lua_pushstring(L, "__luabind_classrep"); lua_gettable(L, -2); - if (lua_toboolean(L, -1)) + if(lua_toboolean(L, -1)) { lua_pop(L, 2); return true; @@ -338,15 +318,15 @@ bool luabind::detail::is_class_rep(lua_State* L, int index) void luabind::detail::finalize(lua_State* L, class_rep* crep) { - if (crep->get_class_type() != class_rep::lua_class) return; + if(crep->get_class_type() != class_rep::lua_class) return; -// lua_pushvalue(L, -1); // copy the object ref + // lua_pushvalue(L, -1); // copy the object ref crep->get_table(L); - lua_pushliteral(L, "__finalize"); + lua_pushliteral(L, "__finalize"); lua_gettable(L, -2); lua_remove(L, -2); - if (lua_isnil(L, -1)) + if(lua_isnil(L, -1)) { lua_pop(L, 1); } @@ -356,10 +336,8 @@ void luabind::detail::finalize(lua_State* L, class_rep* crep) lua_call(L, 1, 0); } - for (std::vector::const_iterator - i = crep->bases().begin(); i != crep->bases().end(); ++i) - { - if (i->base) finalize(L, i->base); + for(const auto& baseinfo : crep->bases()) { + if(baseinfo.base) finalize(L, baseinfo.base); } } @@ -367,13 +345,13 @@ void luabind::detail::class_rep::cache_operators(lua_State* L) { m_operator_cache = 0x1; - for (int i = 0; i < number_of_operators; ++i) + for(int i = 0; i < number_of_operators; ++i) { get_table(L); lua_pushstring(L, get_operator_name(i)); lua_rawget(L, -2); - if (lua_isfunction(L, -1)) m_operator_cache |= 1 << (i + 1); + if(lua_isfunction(L, -1)) m_operator_cache |= 1 << (i + 1); lua_pop(L, 2); } @@ -381,10 +359,11 @@ void luabind::detail::class_rep::cache_operators(lua_State* L) bool luabind::detail::class_rep::has_operator_in_lua(lua_State* L, int id) { - if ((m_operator_cache & 0x1) == 0) + if((m_operator_cache & 0x1) == 0) cache_operators(L); const int mask = 1 << (id + 1); return (m_operator_cache & mask) != 0; } + diff --git a/libs/luabind/src/create_class.cpp b/libs/luabind/src/create_class.cpp index 47251ef23..4468374b7 100644 --- a/libs/luabind/src/create_class.cpp +++ b/libs/luabind/src/create_class.cpp @@ -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,114 +26,122 @@ #include -namespace luabind { namespace detail -{ - namespace - { - // expects two tables on the lua stack: - // 1: destination - // 2: source - void copy_member_table(lua_State* L) - { - lua_pushnil(L); +#if LUA_VERSION_NUM < 502 +# define lua_compare(L, index1, index2, fn) fn(L, index1, index2) +# define LUA_OPEQ lua_equal +# define lua_rawlen lua_objlen +#endif - while (lua_next(L, -2)) +namespace luabind { + namespace detail { + namespace { + + // expects two tables on the lua stack: + // 1: destination + // 2: source + void copy_member_table(lua_State* L) { - lua_pushstring(L, "__init"); - if (lua_equal(L, -1, -3)) - { - lua_pop(L, 2); - continue; - } - else lua_pop(L, 1); // __init string + lua_pushnil(L); - lua_pushstring(L, "__finalize"); - if (lua_equal(L, -1, -3)) + while(lua_next(L, -2)) { - lua_pop(L, 2); - continue; - } - else lua_pop(L, 1); // __finalize string + lua_pushstring(L, "__init"); + if(lua_compare(L, -1, -3, LUA_OPEQ)) + { + lua_pop(L, 2); + continue; + } + else lua_pop(L, 1); // __init string - lua_pushvalue(L, -2); // copy key - lua_insert(L, -2); - lua_settable(L, -5); + lua_pushstring(L, "__finalize"); + if(lua_compare(L, -1, -3, LUA_OPEQ)) + { + lua_pop(L, 2); + continue; + } + else lua_pop(L, 1); // __finalize string + + lua_pushvalue(L, -2); // copy key + lua_insert(L, -2); + lua_settable(L, -5); + } } - } - } + + } // namespace unnamed - int create_class::stage2(lua_State* L) - { - class_rep* crep = static_cast(lua_touserdata(L, lua_upvalueindex(1))); - assert((crep != 0) && "internal error, please report"); - assert((is_class_rep(L, lua_upvalueindex(1))) && "internal error, please report"); - - #ifndef LUABIND_NO_ERROR_CHECKING - - if (!is_class_rep(L, 1)) + int create_class::stage2(lua_State* L) { - lua_pushstring(L, "expected class to derive from or a newline"); - lua_error(L); + class_rep* crep = static_cast(lua_touserdata(L, lua_upvalueindex(1))); + assert((crep != 0) && "internal error, please report"); + assert((is_class_rep(L, lua_upvalueindex(1))) && "internal error, please report"); + +#ifndef LUABIND_NO_ERROR_CHECKING + + if(!is_class_rep(L, 1)) + { + lua_pushstring(L, "expected class to derive from or a newline"); + lua_error(L); + } + +#endif + + class_rep* base = static_cast(lua_touserdata(L, 1)); + class_rep::base_info binfo; + + binfo.pointer_offset = 0; + binfo.base = base; + crep->add_base_class(binfo); + + // copy base class members + + crep->get_table(L); + base->get_table(L); + copy_member_table(L); + + crep->get_default_table(L); + base->get_default_table(L); + copy_member_table(L); + + crep->set_type(base->type()); + + return 0; } - #endif - - class_rep* base = static_cast(lua_touserdata(L, 1)); - class_rep::base_info binfo; - - binfo.pointer_offset = 0; - binfo.base = base; - crep->add_base_class(binfo); - - // copy base class members - - crep->get_table(L); - base->get_table(L); - copy_member_table(L); - - crep->get_default_table(L); - base->get_default_table(L); - copy_member_table(L); - - crep->set_type(base->type()); - - return 0; - } - - int create_class::stage1(lua_State* L) - { - - #ifndef LUABIND_NO_ERROR_CHECKING - - if (lua_gettop(L) != 1 || lua_type(L, 1) != LUA_TSTRING || lua_isnumber(L, 1)) + int create_class::stage1(lua_State* L) { - lua_pushstring(L, "invalid construct, expected class name"); - lua_error(L); + +#ifndef LUABIND_NO_ERROR_CHECKING + + if(lua_gettop(L) != 1 || lua_type(L, 1) != LUA_TSTRING || lua_isnumber(L, 1)) + { + lua_pushstring(L, "invalid construct, expected class name"); + lua_error(L); + } + + if(std::strlen(lua_tostring(L, 1)) != lua_rawlen(L, 1)) + { + lua_pushstring(L, "luabind does not support class names with extra nulls"); + lua_error(L); + } + +#endif + + const char* name = lua_tostring(L, 1); + + void* c = lua_newuserdata(L, sizeof(class_rep)); + new(c) class_rep(L, name); + + // make the class globally available + lua_pushvalue(L, -1); + lua_setglobal(L, name); + + // also add it to the closure as return value + lua_pushcclosure(L, &stage2, 1); + + return 1; } - if (std::strlen(lua_tostring(L, 1)) != lua_strlen(L, 1)) - { - lua_pushstring(L, "luabind does not support class names with extra nulls"); - lua_error(L); - } - - #endif - - const char* name = lua_tostring(L, 1); - - void* c = lua_newuserdata(L, sizeof(class_rep)); - new(c) class_rep(L, name); - - // make the class globally available - lua_pushvalue(L, -1); - lua_setglobal(L, name); - - // also add it to the closure as return value - lua_pushcclosure(L, &stage2, 1); - - return 1; - } - -}} + } // namespace detail +} // namespace luabind diff --git a/libs/luabind/src/error.cpp b/libs/luabind/src/error.cpp index 73bbf5c62..07e352026 100644 --- a/libs/luabind/src/error.cpp +++ b/libs/luabind/src/error.cpp @@ -23,11 +23,32 @@ #define LUABIND_BUILDING #include +#ifndef LUA_INCLUDE_HPP_INCLUDED +#include +#endif -namespace luabind -{ +namespace luabind { +#ifndef LUABIND_NO_EXCEPTIONS + error::error(lua_State* L) + { + const char* message = lua_tostring(L, -1); + + if(message) + { + m_message = message; + } + + lua_pop(L, 1); + } + + + const char* error::what() const throw() + { + return m_message.c_str(); + } +#endif namespace { pcall_callback_fun pcall_callback = 0; @@ -40,9 +61,6 @@ namespace luabind #ifdef LUABIND_NO_EXCEPTIONS - typedef void(*error_callback_fun)(lua_State*); - typedef void(*cast_failed_callback_fun)(lua_State*, type_id const&); - void set_error_callback(error_callback_fun e) { error_callback = e; @@ -76,3 +94,4 @@ namespace luabind } } + diff --git a/libs/luabind/src/exception_handler.cpp b/libs/luabind/src/exception_handler.cpp index 555d3858c..d4ee7764a 100644 --- a/libs/luabind/src/exception_handler.cpp +++ b/libs/luabind/src/exception_handler.cpp @@ -4,84 +4,93 @@ #define LUABIND_BUILDING -#include -#include -#include -#include +#include + +#include // for LUABIND_API #ifndef LUABIND_NO_EXCEPTIONS +#include // for error +#include // for exception_handler_base -namespace luabind { namespace detail { +#include // for exception +#include // for logic_error, runtime_error -namespace -{ - exception_handler_base* handler_chain = 0; +namespace luabind { + namespace detail { - void push_exception_string(lua_State* L, char const* exception, char const* what) - { - lua_pushstring(L, exception); - lua_pushstring(L, ": '"); - lua_pushstring(L, what); - lua_pushstring(L, "'"); - lua_concat(L, 4); - } -} + namespace { -void exception_handler_base::try_next(lua_State* L) const -{ - if (next) - next->handle(L); - else - throw; -} + exception_handler_base* handler_chain = 0; -LUABIND_API void handle_exception_aux(lua_State* L) -{ - try - { - if (handler_chain) - handler_chain->handle(L); - else - throw; - } - catch (error const&) - {} - catch (std::logic_error const& e) - { - push_exception_string(L, "std::logic_error", e.what()); - } - catch (std::runtime_error const& e) - { - push_exception_string(L, "std::runtime_error", e.what()); - } - catch (std::exception const& e) - { - push_exception_string(L, "std::exception", e.what()); - } - catch (char const* str) - { - push_exception_string(L, "c-string", str); - } - catch (...) - { - lua_pushstring(L, "Unknown C++ exception"); - } -} + void push_exception_string(lua_State* L, char const* exception, char const* what) + { + lua_pushstring(L, exception); + lua_pushstring(L, ": '"); + lua_pushstring(L, what); + lua_pushstring(L, "'"); + lua_concat(L, 4); + } + } -LUABIND_API void register_exception_handler(exception_handler_base* handler) -{ - if (!handler_chain) handler_chain = handler; - else - { - exception_handler_base* p = handler_chain; + void exception_handler_base::try_next(lua_State* L) const + { + if(next) + next->handle(L); + else + throw; + } - for (; p->next; p = p->next); + LUABIND_API void handle_exception_aux(lua_State* L) + { + try + { + if(handler_chain) + handler_chain->handle(L); + else + throw; + } + catch(error const&) + { + // is always thrown in the context where an error message was already pushed to the lua stack. + } + catch(std::logic_error const& e) + { + push_exception_string(L, "std::logic_error", e.what()); + } + catch(std::runtime_error const& e) + { + push_exception_string(L, "std::runtime_error", e.what()); + } + catch(std::exception const& e) + { + push_exception_string(L, "std::exception", e.what()); + } + catch(char const* str) + { + push_exception_string(L, "c-string", str); + } + catch(...) + { + lua_pushstring(L, "Unknown C++ exception"); + } + } - handler->next = 0; - p->next = handler; - } -} + LUABIND_API void register_exception_handler(exception_handler_base* handler) + { + if(!handler_chain) handler_chain = handler; + else + { + exception_handler_base* p = handler_chain; -}} // namespace luabind::detail + for(; p->next; p = p->next); + + handler->next = 0; + p->next = handler; + } + } + + } // namespace detail +} // namespace luabind #endif // LUABIND_NO_EXCEPTIONS + diff --git a/libs/luabind/src/function.cpp b/libs/luabind/src/function.cpp index 20569b2bd..cacaf777c 100644 --- a/libs/luabind/src/function.cpp +++ b/libs/luabind/src/function.cpp @@ -4,133 +4,139 @@ #define LUABIND_BUILDING +#include #include +#include +#include -namespace luabind { namespace detail { +namespace luabind { + namespace detail { -namespace -{ + namespace { - int function_destroy(lua_State* L) - { - function_object* fn = *(function_object**)lua_touserdata(L, 1); - delete fn; - return 0; - } + int function_destroy(lua_State* L) + { + function_object* fn = *(function_object**)lua_touserdata(L, 1); + delete fn; + return 0; + } - void push_function_metatable(lua_State* L) - { - lua_pushstring(L, "luabind.function"); - lua_rawget(L, LUA_REGISTRYINDEX); + void push_function_metatable(lua_State* L) + { + lua_pushstring(L, "luabind.function"); + lua_rawget(L, LUA_REGISTRYINDEX); - if (lua_istable(L, -1)) - return; + if(lua_istable(L, -1)) + return; - lua_pop(L, 1); + lua_pop(L, 1); - lua_newtable(L); + lua_newtable(L); - lua_pushstring(L, "__gc"); - lua_pushcclosure(L, &function_destroy, 0); - lua_rawset(L, -3); + lua_pushstring(L, "__gc"); + lua_pushcclosure(L, &function_destroy, 0); + lua_rawset(L, -3); - lua_pushstring(L, "luabind.function"); - lua_pushvalue(L, -2); - lua_rawset(L, LUA_REGISTRYINDEX); - } + lua_pushstring(L, "luabind.function"); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + } - // A pointer to this is used as a tag value to identify functions exported - // by luabind. - int function_tag = 0; + // A pointer to this is used as a tag value to identify functions exported + // by luabind. + int function_tag = 0; -} // namespace unnamed + } // namespace unnamed -LUABIND_API bool is_luabind_function(lua_State* L, int index) -{ - if (!lua_getupvalue(L, index, 2)) - return false; - bool result = lua_touserdata(L, -1) == &function_tag; - lua_pop(L, 1); - return result; -} + LUABIND_API bool is_luabind_function(lua_State* L, int index) + { + if(!lua_getupvalue(L, index, 2)) + return false; + bool result = lua_touserdata(L, -1) == &function_tag; + lua_pop(L, 1); + return result; + } -namespace -{ + namespace + { - inline bool is_luabind_function(object const& obj) - { - obj.push(obj.interpreter()); - bool result = detail::is_luabind_function(obj.interpreter(), -1); - lua_pop(obj.interpreter(), 1); - return result; - } + inline bool is_luabind_function(object const& obj) + { + obj.push(obj.interpreter()); + bool result = detail::is_luabind_function(obj.interpreter(), -1); + lua_pop(obj.interpreter(), 1); + return result; + } -} // namespace unnamed + } // namespace unnamed -LUABIND_API void add_overload( - object const& context, char const* name, object const& fn) -{ - function_object* f = *touserdata(getupvalue(fn, 1)); - f->name = name; + LUABIND_API void add_overload( + object const& context, char const* name, object const& fn) + { + function_object* f = *touserdata(std::get<1>(getupvalue(fn, 1))); + f->name = name; - if (object overloads = context[name]) - { - if (is_luabind_function(overloads) && is_luabind_function(fn)) - { - f->next = *touserdata(getupvalue(overloads, 1)); - f->keepalive = overloads; - } - } + if(object overloads = context[name]) + { + if(is_luabind_function(overloads) && is_luabind_function(fn)) + { + f->next = *touserdata(std::get<1>(getupvalue(overloads, 1))); + f->keepalive = overloads; + } + } - context[name] = fn; -} + context[name] = fn; + } -LUABIND_API object make_function_aux(lua_State* L, function_object* impl) -{ - void* storage = lua_newuserdata(L, sizeof(function_object*)); - push_function_metatable(L); - *(function_object**)storage = impl; - lua_setmetatable(L, -2); + LUABIND_API object make_function_aux(lua_State* L, function_object* impl) + { + void* storage = lua_newuserdata(L, sizeof(function_object*)); + push_function_metatable(L); + *(function_object**)storage = impl; + lua_setmetatable(L, -2); - lua_pushlightuserdata(L, &function_tag); - lua_pushcclosure(L, impl->entry, 2); - stack_pop pop(L, 1); + lua_pushlightuserdata(L, &function_tag); + lua_pushcclosure(L, impl->entry, 2); + stack_pop pop(L, 1); - return object(from_stack(L, -1)); -} + return object(from_stack(L, -1)); + } -void invoke_context::format_error( - lua_State* L, function_object const* overloads) const -{ - char const* function_name = - overloads->name.empty() ? "" : overloads->name.c_str(); + void invoke_context::format_error( + lua_State* L, function_object const* overloads) const + { + char const* function_name = + overloads->name.empty() ? "" : overloads->name.c_str(); - if (candidate_index == 0) - { - lua_pushstring(L, "No matching overload found, candidates:\n"); - int count = 0; - for (function_object const* f = overloads; f != 0; f = f->next) - { - if (count != 0) - lua_pushstring(L, "\n"); - f->format_signature(L, function_name); - ++count; - } - lua_concat(L, count * 2); - } - else - { - // Ambiguous - lua_pushstring(L, "Ambiguous, candidates:\n"); - for (int i = 0; i < candidate_index; ++i) - { - if (i != 0) - lua_pushstring(L, "\n"); - candidates[i]->format_signature(L, function_name); - } - lua_concat(L, candidate_index * 2); - } -} + if(candidate_index == 0) + { + int stacksize = lua_gettop(L); + lua_pushstring(L, "No matching overload found, candidates:\n"); + int count = 0; + for(function_object const* f = overloads; f != 0; f = f->next) + { + if(count != 0) + lua_pushstring(L, "\n"); + f->format_signature(L, function_name); + ++count; + } + lua_concat(L, lua_gettop(L) - stacksize); + } + else + { + // Ambiguous + int stacksize = lua_gettop(L); + lua_pushstring(L, "Ambiguous, candidates:\n"); + for(int i = 0; i < candidate_index; ++i) + { + if(i != 0) + lua_pushstring(L, "\n"); + candidates[i]->format_signature(L, function_name); + } + lua_concat(L, lua_gettop(L) - stacksize); + } + } -}} // namespace luabind::detail + } // namespace detail +} // namespace luabind diff --git a/libs/luabind/src/function_introspection.cpp b/libs/luabind/src/function_introspection.cpp new file mode 100644 index 000000000..aed60e40e --- /dev/null +++ b/libs/luabind/src/function_introspection.cpp @@ -0,0 +1,117 @@ +/** + @file + @brief Implementation + + @date 2012 + + @author + Ryan Pavlik + and + 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. + +#define LUABIND_BUILDING + +// Internal Includes +#include +#include // for LUABIND_API + +#include +#include + +#include // for stack_pop +#include // for def, is_luabind_function +#include // for function_object +#include // for argument, object, etc +#include // for from_stack +#include // for module, module_, scope +#include +#include + +// Library/third-party includes +// - none + +// Standard includes +#include // for string +#include // for NULL + +namespace luabind { + + namespace { + detail::function_object* get_function_object(argument const& fn) { + lua_State * L = fn.interpreter(); + { + fn.push(L); + detail::stack_pop pop(L, 1); + if(!detail::is_luabind_function(L, -1)) { + return NULL; + } + } + return *touserdata(std::get<1>(getupvalue(fn, 1))); + } + + std::string get_function_name(argument const& fn) { + detail::function_object * f = get_function_object(fn); + if(!f) { + return ""; + } + return f->name; + } + + object get_function_overloads(argument const& fn) { + lua_State * L = fn.interpreter(); + detail::function_object * fobj = get_function_object(fn); + if(!fobj) { + return object(); + } + object overloadTable(newtable(L)); + int count = 1; + const char* function_name = fobj->name.c_str(); + for(detail::function_object const* f = fobj; f != 0; f = f->next) + { + f->format_signature(L, function_name); + detail::stack_pop pop(L, 1); + overloadTable[count] = object(from_stack(L, -1)); + + ++count; + } + /// @todo + + return overloadTable; + } + + } + + LUABIND_API int bind_function_introspection(lua_State * L) { + module(L, "function_info")[ + def("get_function_overloads", &get_function_overloads), + def("get_function_name", &get_function_name) + ]; + return 0; + } + +} // end of namespace luabind + diff --git a/libs/luabind/src/headertest.cpp b/libs/luabind/src/headertest.cpp new file mode 100644 index 000000000..2061691f6 --- /dev/null +++ b/libs/luabind/src/headertest.cpp @@ -0,0 +1 @@ +#include diff --git a/libs/luabind/src/inheritance.cpp b/libs/luabind/src/inheritance.cpp index 2e2ec902a..a3de45859 100644 --- a/libs/luabind/src/inheritance.cpp +++ b/libs/luabind/src/inheritance.cpp @@ -8,251 +8,224 @@ #include #include #include -#include -#include -#include -#include +#include #include #include -namespace luabind { namespace detail { +namespace luabind { + namespace detail { -class_id const class_id_map::local_id_base = - std::numeric_limits::max() / 2; + class_id const class_id_map::local_id_base = std::numeric_limits::max() / 2; -namespace -{ + namespace + { - struct edge - { - edge(class_id target, cast_function cast) - : target(target) - , cast(cast) - {} + struct edge + { + edge(class_id target, cast_function cast) + : target(target), cast(cast) + {} - class_id target; - cast_function cast; - }; + class_id target; + cast_function cast; + }; - bool operator<(edge const& x, edge const& y) - { - return x.target < y.target; - } + bool operator<(edge const& x, edge const& y) + { + return x.target < y.target; + } - struct vertex - { - vertex(class_id id) - : id(id) - {} + struct vertex + { + vertex(class_id id) + : id(id) + {} - class_id id; - std::vector edges; - }; + class_id id; + std::vector edges; + }; - typedef std::pair cache_entry; + using cache_entry = std::pair; - class cache - { - public: - static std::ptrdiff_t const unknown; - static std::ptrdiff_t const invalid; + class cache + { + public: + static constexpr std::ptrdiff_t unknown = std::numeric_limits::max(); + static constexpr std::ptrdiff_t invalid = unknown - 1; - cache_entry get( - class_id src, class_id target, class_id dynamic_id - , std::ptrdiff_t object_offset) const; + cache_entry get(class_id src, class_id target, class_id dynamic_id, std::ptrdiff_t object_offset) const; - void put( - class_id src, class_id target, class_id dynamic_id - , std::ptrdiff_t object_offset - , std::size_t distance, std::ptrdiff_t offset); + void put(class_id src, class_id target, class_id dynamic_id, std::ptrdiff_t object_offset, std::ptrdiff_t offset, int distance); + void invalidate(); - void invalidate(); + private: + using key_type = std::tuple; + using map_type = std::map; + map_type m_cache; + }; - private: - typedef boost::tuple< - class_id, class_id, class_id, std::ptrdiff_t> key_type; - typedef std::map map_type; - map_type m_cache; - }; + constexpr std::ptrdiff_t cache::unknown; + constexpr std::ptrdiff_t cache::invalid; - std::ptrdiff_t const cache::unknown = - std::numeric_limits::max(); - std::ptrdiff_t const cache::invalid = cache::unknown - 1; + cache_entry cache::get(class_id src, class_id target, class_id dynamic_id, std::ptrdiff_t object_offset) const + { + map_type::const_iterator i = m_cache.find( + key_type(src, target, dynamic_id, object_offset)); + return i != m_cache.end() ? i->second : cache_entry(unknown, -1); + } - cache_entry cache::get( - class_id src, class_id target, class_id dynamic_id - , std::ptrdiff_t object_offset) const - { - map_type::const_iterator i = m_cache.find( - key_type(src, target, dynamic_id, object_offset)); - return i != m_cache.end() ? i->second : cache_entry(unknown, -1); - } + void cache::put(class_id src, class_id target, class_id dynamic_id, std::ptrdiff_t object_offset, std::ptrdiff_t offset, int distance) + { + m_cache.insert(std::make_pair(key_type(src, target, dynamic_id, object_offset), cache_entry(offset, distance))); + } - void cache::put( - class_id src, class_id target, class_id dynamic_id - , std::ptrdiff_t object_offset, std::size_t distance, std::ptrdiff_t offset) - { - m_cache.insert(std::make_pair( - key_type(src, target, dynamic_id, object_offset) - , cache_entry(offset, distance) - )); - } + void cache::invalidate() + { + m_cache.clear(); + } - void cache::invalidate() - { - m_cache.clear(); - } + } // namespace anonymous -} // namespace unnamed + class cast_graph::impl + { + public: + std::pair 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); -class cast_graph::impl -{ -public: - std::pair 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: + std::vector m_vertices; + mutable cache m_cache; + }; -private: - std::vector m_vertices; - mutable cache m_cache; -}; + namespace + { -namespace -{ + struct queue_entry + { + queue_entry(void* p, class_id vertex_id, int distance) + : p(p) + , vertex_id(vertex_id) + , distance(distance) + {} - struct queue_entry - { - queue_entry(void* p, class_id vertex_id, int distance) - : p(p) - , vertex_id(vertex_id) - , distance(distance) - {} + void* p; + class_id vertex_id; + int distance; + }; - void* p; - class_id vertex_id; - int distance; - }; + } // namespace anonymous -} // namespace unnamed + std::pair cast_graph::impl::cast(void* const p, class_id src, class_id target, class_id dynamic_id, void const* dynamic_ptr) const + { + if(src == target) return std::make_pair(p, 0); + if(src >= m_vertices.size() || target >= m_vertices.size()) return std::pair((void*)0, -1); -std::pair cast_graph::impl::cast( - void* const p, class_id src, class_id target - , class_id dynamic_id, void const* dynamic_ptr) const -{ - if (src == target) - return std::make_pair(p, 0); + std::ptrdiff_t const object_offset = (char const*)dynamic_ptr - (char const*)p; + cache_entry cached = m_cache.get(src, target, dynamic_id, object_offset); - if (src >= m_vertices.size() || target >= m_vertices.size()) - return std::pair((void*)0, -1); + if(cached.first != cache::unknown) + { + if(cached.first == cache::invalid) + return std::pair((void*)0, -1); + return std::make_pair((char*)p + cached.first, cached.second); + } - std::ptrdiff_t const object_offset = - (char const*)dynamic_ptr - (char const*)p; + std::queue q; + q.push(queue_entry(p, src, 0)); - cache_entry cached = m_cache.get(src, target, dynamic_id, object_offset); + // Original source used boost::dynamic_bitset but didn't make use + // of its advanced capability of set operations, that's why I think + // it's safe to use a std::vector here. - if (cached.first != cache::unknown) - { - if (cached.first == cache::invalid) - return std::pair((void*)0, -1); - return std::make_pair((char*)p + cached.first, cached.second); - } + std::vector visited(m_vertices.size(), false); - std::queue q; - q.push(queue_entry(p, src, 0)); + while(!q.empty()) + { + queue_entry const qe = q.front(); + q.pop(); - boost::dynamic_bitset<> visited(m_vertices.size()); + visited[qe.vertex_id] = true; + vertex const& v = m_vertices[qe.vertex_id]; - while (!q.empty()) - { - queue_entry const qe = q.front(); - q.pop(); + if(v.id == target) + { + m_cache.put( + src, target, dynamic_id, object_offset + , (char*)qe.p - (char*)p, qe.distance + ); - visited[qe.vertex_id] = true; - vertex const& v = m_vertices[qe.vertex_id]; + return std::make_pair(qe.p, qe.distance); + } - if (v.id == target) - { - m_cache.put( - src, target, dynamic_id, object_offset - , qe.distance, (char*)qe.p - (char*)p - ); + for(auto const& e : v.edges) { + if(visited[e.target]) + continue; + if(void* casted = e.cast(qe.p)) + q.push(queue_entry(casted, e.target, qe.distance + 1)); + } + } - return std::make_pair(qe.p, qe.distance); - } + m_cache.put(src, target, dynamic_id, object_offset, cache::invalid, -1); - BOOST_FOREACH(edge const& e, v.edges) - { - if (visited[e.target]) - continue; - if (void* casted = e.cast(qe.p)) - q.push(queue_entry(casted, e.target, qe.distance + 1)); - } - } + return std::pair((void*)0, -1); + } - m_cache.put(src, target, dynamic_id, object_offset, cache::invalid, -1); + void cast_graph::impl::insert(class_id src, class_id target, cast_function cast) + { + class_id const max_id = std::max(src, target); - return std::pair((void*)0, -1); -} + if(max_id >= m_vertices.size()) + { + m_vertices.reserve(max_id + 1); + for(class_id i = m_vertices.size(); i < max_id + 1; ++i) + m_vertices.push_back(vertex(i)); + } -void cast_graph::impl::insert( - class_id src, class_id target, cast_function cast) -{ - class_id const max_id = std::max(src, target); + std::vector& edges = m_vertices[src].edges; - if (max_id >= m_vertices.size()) - { - m_vertices.reserve(max_id + 1); - for (class_id i = m_vertices.size(); i < max_id + 1; ++i) - m_vertices.push_back(vertex(i)); - } + std::vector::iterator i = std::lower_bound( + edges.begin(), edges.end(), edge(target, 0) + ); - std::vector& edges = m_vertices[src].edges; + if(i == edges.end() || i->target != target) + { + edges.insert(i, edge(target, cast)); + m_cache.invalidate(); + } + } - std::vector::iterator i = std::lower_bound( - edges.begin(), edges.end(), edge(target, 0) - ); + std::pair cast_graph::cast(void* p, class_id src, class_id target, class_id dynamic_id, void const* dynamic_ptr) const + { + return m_impl->cast(p, src, target, dynamic_id, dynamic_ptr); + } - if (i == edges.end() || i->target != target) - { - edges.insert(i, edge(target, cast)); - m_cache.invalidate(); - } -} + void cast_graph::insert(class_id src, class_id target, cast_function cast) + { + m_impl->insert(src, target, cast); + } -std::pair cast_graph::cast( - void* p, class_id src, class_id target - , class_id dynamic_id, void const* dynamic_ptr) const -{ - return m_impl->cast(p, src, target, dynamic_id, dynamic_ptr); -} + cast_graph::cast_graph() + : m_impl(new impl) + {} -void cast_graph::insert(class_id src, class_id target, cast_function cast) -{ - m_impl->insert(src, target, cast); -} + cast_graph::~cast_graph() + {} -cast_graph::cast_graph() - : m_impl(new impl) -{} + LUABIND_API class_id allocate_class_id(type_id const& cls) + { + using map_type = std::map; -cast_graph::~cast_graph() -{} + static map_type registered; + static class_id id = 0; -LUABIND_API class_id allocate_class_id(type_id const& cls) -{ - typedef std::map map_type; + std::pair inserted = registered.insert(std::make_pair(cls, id)); + if(inserted.second) ++id; - static map_type registered; - static class_id id = 0; + return inserted.first->second; + } - std::pair inserted = registered.insert( - std::make_pair(cls, id)); + } // namespace detail +} // namespace luabind - if (inserted.second) - ++id; - - return inserted.first->second; -} - -}} // namespace luabind::detail diff --git a/libs/luabind/src/link_compatibility.cpp b/libs/luabind/src/link_compatibility.cpp index 515e0e392..60a02f1c6 100644 --- a/libs/luabind/src/link_compatibility.cpp +++ b/libs/luabind/src/link_compatibility.cpp @@ -24,20 +24,21 @@ #include -namespace luabind { namespace detail -{ +namespace luabind { + namespace detail { #ifdef LUABIND_NOT_THREADSAFE - void not_threadsafe_defined_conflict() {} + void not_threadsafe_defined_conflict() {} #else - void not_threadsafe_not_defined_conflict() {} + void not_threadsafe_not_defined_conflict() {} #endif #ifdef LUABIND_NO_ERROR_CHECKING - void no_error_checking_defined_conflict() {} + void no_error_checking_defined_conflict() {} #else - void no_error_checking_not_defined_conflict() {} + void no_error_checking_not_defined_conflict() {} #endif -}} + } +} diff --git a/libs/luabind/src/object_rep.cpp b/libs/luabind/src/object_rep.cpp index afc6d9800..4d5f39bdf 100644 --- a/libs/luabind/src/object_rep.cpp +++ b/libs/luabind/src/object_rep.cpp @@ -24,250 +24,243 @@ #include #include -#include -namespace luabind { namespace detail -{ +#if LUA_VERSION_NUM < 502 +# define lua_getuservalue lua_getfenv +# define lua_setuservalue lua_setfenv +#endif - // dest is a function that is called to delete the c++ object this struct holds - object_rep::object_rep(instance_holder* instance, class_rep* crep) - : m_instance(instance) - , m_classrep(crep) - , m_dependency_cnt(0) - {} +namespace luabind { + namespace detail { + + // dest is a function that is called to delete the c++ object this struct holds + object_rep::object_rep(instance_holder* instance, class_rep* crep) + : m_instance(instance) + , m_classrep(crep) + { + } + + object_rep::~object_rep() + { + if(!m_instance) + return; + m_instance->~instance_holder(); + deallocate(m_instance); + } + + void object_rep::add_dependency(lua_State* L, int index) + { + if(!m_dependency_ref.is_valid()) + { + lua_newtable(L); + m_dependency_ref.set(L); + } + m_dependency_ref.get(L); + + lua_pushvalue(L, index); + lua_pushnumber(L, 0); + lua_rawset(L, -3); + lua_pop(L, 1); + } + + int destroy_instance(lua_State* L) + { + object_rep* instance = static_cast(lua_touserdata(L, 1)); + + lua_pushstring(L, "__finalize"); + lua_gettable(L, 1); + + if(lua_isnil(L, -1)) + { + lua_pop(L, 1); + } + else + { + lua_pushvalue(L, 1); + lua_call(L, 1, 0); + } + + instance->~object_rep(); + + lua_pushnil(L); + lua_setmetatable(L, 1); + return 0; + } + + namespace + { + + int set_instance_value(lua_State* L) + { + lua_getuservalue(L, 1); + lua_pushvalue(L, 2); + lua_rawget(L, -2); + + if(lua_isnil(L, -1) && lua_getmetatable(L, -2)) + { + lua_pushvalue(L, 2); + lua_rawget(L, -2); + lua_replace(L, -3); + lua_pop(L, 1); + } + + if(lua_tocfunction(L, -1) == &property_tag) + { + // this member is a property, extract the "set" function and call it. + lua_getupvalue(L, -1, 2); + + if(lua_isnil(L, -1)) + { + lua_pushfstring(L, "property '%s' is read only", lua_tostring(L, 2)); + lua_error(L); + } + + lua_pushvalue(L, 1); + lua_pushvalue(L, 3); + lua_call(L, 2, 0); + return 0; + } + + lua_pop(L, 1); + + if(!lua_getmetatable(L, 4)) + { + lua_newtable(L); + lua_pushvalue(L, -1); + lua_setuservalue(L, 1); + lua_pushvalue(L, 4); + lua_setmetatable(L, -2); + } + else + { + lua_pop(L, 1); + } + + lua_pushvalue(L, 2); + lua_pushvalue(L, 3); + lua_rawset(L, -3); + + return 0; + } + + int get_instance_value(lua_State* L) + { + lua_getuservalue(L, 1); + lua_pushvalue(L, 2); + lua_rawget(L, -2); + + if(lua_isnil(L, -1) && lua_getmetatable(L, -2)) + { + lua_pushvalue(L, 2); + lua_rawget(L, -2); + } + + if(lua_tocfunction(L, -1) == &property_tag) + { + // this member is a property, extract the "get" function and call it. + lua_getupvalue(L, -1, 1); + lua_pushvalue(L, 1); + lua_call(L, 1, 1); + } + + return 1; + } + + int dispatch_operator(lua_State* L) + { + for(int i = 0; i < 2; ++i) + { + if(get_instance(L, 1 + i)) + { + int nargs = lua_gettop(L); + + lua_pushvalue(L, lua_upvalueindex(1)); + lua_gettable(L, 1 + i); + + if(lua_isnil(L, -1)) + { + lua_pop(L, 1); + continue; + } + + lua_insert(L, 1); // move the function to the bottom + + nargs = lua_toboolean(L, lua_upvalueindex(2)) ? 1 : nargs; + + if(lua_toboolean(L, lua_upvalueindex(2))) // remove trailing nil + lua_remove(L, 3); + + lua_call(L, nargs, 1); + return 1; + } + } + + lua_pop(L, lua_gettop(L)); + lua_pushstring(L, "No such operator defined"); + lua_error(L); + + return 0; + } + + } // namespace unnamed + + LUABIND_API void push_instance_metatable(lua_State* L) + { + lua_newtable(L); + + // This is used as a tag to determine if a userdata is a luabind + // instance. We use a numeric key and a cclosure for fast comparison. + lua_pushnumber(L, 1); + lua_pushcclosure(L, get_instance_value, 0); + lua_rawset(L, -3); + + lua_pushcclosure(L, destroy_instance, 0); + lua_setfield(L, -2, "__gc"); + + lua_pushcclosure(L, get_instance_value, 0); + lua_setfield(L, -2, "__index"); + + lua_pushcclosure(L, set_instance_value, 0); + lua_setfield(L, -2, "__newindex"); + + for(int op = 0; op < number_of_operators; ++op) + { + lua_pushstring(L, get_operator_name(op)); + lua_pushvalue(L, -1); + lua_pushboolean(L, op == op_unm || op == op_len); + lua_pushcclosure(L, &dispatch_operator, 2); + lua_settable(L, -3); + } + } + + LUABIND_API object_rep* get_instance(lua_State* L, int index) + { + object_rep* result = static_cast(lua_touserdata(L, index)); + + if(!result || !lua_getmetatable(L, index)) + return 0; + + lua_rawgeti(L, -1, 1); + + if(lua_tocfunction(L, -1) != &get_instance_value) + result = 0; + + lua_pop(L, 2); + + return result; + } + + LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls) + { + void* storage = lua_newuserdata(L, sizeof(object_rep)); + object_rep* result = new (storage) object_rep(0, cls); + cls->get_table(L); + lua_setuservalue(L, -2); + lua_rawgeti(L, LUA_REGISTRYINDEX, cls->metatable_ref()); + lua_setmetatable(L, -2); + return result; + } - object_rep::~object_rep() - { - if (!m_instance) - return; - m_instance->~instance_holder(); - deallocate(m_instance); } - - void object_rep::add_dependency(lua_State* L, int index) - { - assert(m_dependency_cnt < sizeof(object_rep)); - - void* key = (char*)this + m_dependency_cnt; - - lua_pushlightuserdata(L, key); - lua_pushvalue(L, index); - lua_rawset(L, LUA_REGISTRYINDEX); - - ++m_dependency_cnt; - } - - void object_rep::release_dependency_refs(lua_State* L) - { - for (std::size_t i = 0; i < m_dependency_cnt; ++i) - { - void* key = (char*)this + i; - lua_pushlightuserdata(L, key); - lua_pushnil(L); - lua_rawset(L, LUA_REGISTRYINDEX); - } - } - - int destroy_instance(lua_State* L) - { - object_rep* instance = static_cast(lua_touserdata(L, 1)); - - lua_pushstring(L, "__finalize"); - lua_gettable(L, 1); - - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - } - else - { - lua_pushvalue(L, 1); - lua_call(L, 1, 0); - } - - instance->release_dependency_refs(L); - instance->~object_rep(); - return 0; - } - - namespace - { - - int set_instance_value(lua_State* L) - { - lua_getfenv(L, 1); - lua_pushvalue(L, 2); - lua_rawget(L, -2); - - if (lua_isnil(L, -1) && lua_getmetatable(L, -2)) - { - lua_pushvalue(L, 2); - lua_rawget(L, -2); - lua_replace(L, -3); - lua_pop(L, 1); - } - - if (lua_tocfunction(L, -1) == &property_tag) - { - // this member is a property, extract the "set" function and call it. - lua_getupvalue(L, -1, 2); - - if (lua_isnil(L, -1)) - { - lua_pushfstring(L, "property '%s' is read only", lua_tostring(L, 2)); - lua_error(L); - } - - lua_pushvalue(L, 1); - lua_pushvalue(L, 3); - lua_call(L, 2, 0); - return 0; - } - - lua_pop(L, 1); - - if (!lua_getmetatable(L, 4)) - { - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfenv(L, 1); - lua_pushvalue(L, 4); - lua_setmetatable(L, -2); - } - else - { - lua_pop(L, 1); - } - - lua_pushvalue(L, 2); - lua_pushvalue(L, 3); - lua_rawset(L, -3); - - return 0; - } - - int get_instance_value(lua_State* L) - { - lua_getfenv(L, 1); - lua_pushvalue(L, 2); - lua_rawget(L, -2); - - if (lua_isnil(L, -1) && lua_getmetatable(L, -2)) - { - lua_pushvalue(L, 2); - lua_rawget(L, -2); - } - - if (lua_tocfunction(L, -1) == &property_tag) - { - // this member is a property, extract the "get" function and call it. - lua_getupvalue(L, -1, 1); - lua_pushvalue(L, 1); - lua_call(L, 1, 1); - } - - return 1; - } - - int dispatch_operator(lua_State* L) - { - for (int i = 0; i < 2; ++i) - { - if (get_instance(L, 1 + i)) - { - int nargs = lua_gettop(L); - - lua_pushvalue(L, lua_upvalueindex(1)); - lua_gettable(L, 1 + i); - - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - continue; - } - - lua_insert(L, 1); // move the function to the bottom - - nargs = lua_toboolean(L, lua_upvalueindex(2)) ? 1 : nargs; - - if (lua_toboolean(L, lua_upvalueindex(2))) // remove trailing nil - lua_remove(L, 3); - - lua_call(L, nargs, 1); - return 1; - } - } - - lua_pop(L, lua_gettop(L)); - lua_pushstring(L, "No such operator defined"); - lua_error(L); - - return 0; - } - - } // namespace unnamed - - LUABIND_API void push_instance_metatable(lua_State* L) - { - lua_newtable(L); - - // just indicate that this really is a class and not just - // any user data - lua_pushboolean(L, 1); - lua_setfield(L, -2, "__luabind_class"); - - // This is used as a tag to determine if a userdata is a luabind - // instance. We use a numeric key and a cclosure for fast comparision. - lua_pushnumber(L, 1); - lua_pushcclosure(L, get_instance_value, 0); - lua_rawset(L, -3); - - lua_pushcclosure(L, destroy_instance, 0); - lua_setfield(L, -2, "__gc"); - - lua_pushcclosure(L, get_instance_value, 0); - lua_setfield(L, -2, "__index"); - - lua_pushcclosure(L, set_instance_value, 0); - lua_setfield(L, -2, "__newindex"); - - for (int op = 0; op < number_of_operators; ++op) - { - lua_pushstring(L, get_operator_name(op)); - lua_pushvalue(L, -1); - lua_pushboolean(L, op == op_unm || op == op_len); - lua_pushcclosure(L, &dispatch_operator, 2); - lua_settable(L, -3); - } - } - - LUABIND_API object_rep* get_instance(lua_State* L, int index) - { - object_rep* result = static_cast(lua_touserdata(L, index)); - - if (!result || !lua_getmetatable(L, index)) - return 0; - - lua_rawgeti(L, -1, 1); - - if (lua_tocfunction(L, -1) != &get_instance_value) - result = 0; - - lua_pop(L, 2); - - return result; - } - - LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls) - { - void* storage = lua_newuserdata(L, sizeof(object_rep)); - object_rep* result = new (storage) object_rep(0, cls); - cls->get_table(L); - lua_setfenv(L, -2); - lua_rawgeti(L, LUA_REGISTRYINDEX, cls->metatable_ref()); - lua_setmetatable(L, -2); - return result; - } - -}} +} diff --git a/libs/luabind/src/open.cpp b/libs/luabind/src/open.cpp index ec8e4ff64..bfdcbb8ec 100644 --- a/libs/luabind/src/open.cpp +++ b/libs/luabind/src/open.cpp @@ -24,173 +24,129 @@ #include -#include -#include +#include #include +#include +#include +#include namespace luabind { -namespace -{ + namespace + { - int make_property(lua_State* L) - { - int args = lua_gettop(L); + int make_property(lua_State* L) + { + int args = lua_gettop(L); - if (args == 0 || args > 2) - { - lua_pushstring(L, "make_property() called with wrong number of arguments."); - lua_error(L); - } + if(args == 0 || args > 2) + { + lua_pushstring(L, "make_property() called with wrong number of arguments."); + lua_error(L); + } - if (args == 1) - lua_pushnil(L); + if(args == 1) + lua_pushnil(L); - lua_pushcclosure(L, &detail::property_tag, 2); - return 1; - } + lua_pushcclosure(L, &detail::property_tag, 2); + return 1; + } - int main_thread_tag; + int main_thread_tag; - int deprecated_super(lua_State* L) - { - lua_pushstring(L, - "DEPRECATION: 'super' has been deprecated in favor of " - "directly calling the base class __init() function. " - "This error can be disabled by calling 'luabind::disable_super_deprecation()'." - ); - lua_error(L); + int deprecated_super(lua_State* L) + { + lua_pushstring(L, + "DEPRECATION: 'super' has been deprecated in favor of " + "directly calling the base class __init() function. " + "This error can be disabled by calling 'luabind::disable_super_deprecation()'." + ); + lua_error(L); - return 0; - } + return 0; + } - int destroy_class_id_map(lua_State* L) - { - detail::class_id_map* m = - (detail::class_id_map*)lua_touserdata(L, 1); - m->~class_id_map(); - return 0; - } + } // namespace unnamed - int destroy_cast_graph(lua_State* L) - { - detail::cast_graph* g = - (detail::cast_graph*)lua_touserdata(L, 1); - g->~cast_graph(); - return 0; - } + LUABIND_API lua_State* get_main_thread(lua_State* L) + { + lua_pushlightuserdata(L, &main_thread_tag); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_State* result = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); - int destroy_class_map(lua_State* L) - { - detail::class_map* m = - (detail::class_map*)lua_touserdata(L, 1); - m->~class_map(); - return 0; - } + if(!result) + throw std::runtime_error("Unable to get main thread, luabind::open() not called?"); -} // namespace unnamed + return result; + } - LUABIND_API lua_State* get_main_thread(lua_State* L) - { - lua_pushlightuserdata(L, &main_thread_tag); - lua_rawget(L, LUA_REGISTRYINDEX); - lua_State* result = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); + namespace { - if (!result) - throw std::runtime_error("Unable to get main thread, luabind::open() not called?"); + template + inline void * shared_create_userdata(lua_State* L, const char * name) { + lua_pushstring(L, name); + void* storage = lua_newuserdata(L, sizeof(T)); - return result; - } + // set gc metatable + lua_newtable(L); + lua_pushcclosure(L, &detail::garbage_collector, 0); + lua_setfield(L, -2, "__gc"); + lua_setmetatable(L, -2); - LUABIND_API void open(lua_State* L) - { - bool is_main_thread = lua_pushthread(L) == 1; - lua_pop(L, 1); + lua_settable(L, LUA_REGISTRYINDEX); + return storage; + } - if (!is_main_thread) - { - throw std::runtime_error( - "luabind::open() must be called with the main thread " - "lua_State*" - ); - } + template + inline void createGarbageCollectedRegistryUserdata(lua_State* L, const char * name) { + void * storage = shared_create_userdata(L, name); + // placement "new" + new (storage) T; + } - if (detail::class_registry::get_registry(L)) - return; + template + inline void createGarbageCollectedRegistryUserdata(lua_State* L, const char * name, A1 constructorArg) { + void * storage = shared_create_userdata(L, name); - lua_pushstring(L, "__luabind_classes"); - detail::class_registry* r = static_cast( - lua_newuserdata(L, sizeof(detail::class_registry))); + // placement "new" + new (storage) T(constructorArg); + } - // set gc metatable - lua_newtable(L); - lua_pushstring(L, "__gc"); - lua_pushcclosure( - L - , detail::garbage_collector_s< - detail::class_registry - >::apply - , 0); + } // namespace anonymous - lua_settable(L, -3); - lua_setmetatable(L, -2); + LUABIND_API void open(lua_State* L) + { + bool is_main_thread = lua_pushthread(L) == 1; + lua_pop(L, 1); - new(r) detail::class_registry(L); - lua_settable(L, LUA_REGISTRYINDEX); + if(!is_main_thread) + { + throw std::runtime_error( + "luabind::open() must be called with the main thread " + "lua_State*" + ); + } - lua_pushstring(L, "__luabind_class_id_map"); - void* classes_storage = lua_newuserdata(L, sizeof(detail::class_id_map)); - detail::class_id_map* class_ids = new (classes_storage) detail::class_id_map; - (void)class_ids; + createGarbageCollectedRegistryUserdata(L, "__luabind_classes", L); + createGarbageCollectedRegistryUserdata(L, "__luabind_class_id_map"); + createGarbageCollectedRegistryUserdata(L, "__luabind_cast_graph"); + createGarbageCollectedRegistryUserdata(L, "__luabind_class_map"); - lua_newtable(L); - lua_pushcclosure(L, &destroy_class_id_map, 0); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L, -2); + // add functions (class, cast etc...) + lua_pushcclosure(L, detail::create_class::stage1, 0); + lua_setglobal(L, "class"); - lua_settable(L, LUA_REGISTRYINDEX); + lua_pushcclosure(L, &make_property, 0); + lua_setglobal(L, "property"); - lua_pushstring(L, "__luabind_cast_graph"); - void* cast_graph_storage = lua_newuserdata( - L, sizeof(detail::cast_graph)); - detail::cast_graph* graph = new (cast_graph_storage) detail::cast_graph; - (void)graph; + lua_pushlightuserdata(L, &main_thread_tag); + lua_pushlightuserdata(L, L); + lua_rawset(L, LUA_REGISTRYINDEX); - lua_newtable(L); - lua_pushcclosure(L, &destroy_cast_graph, 0); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L, -2); - - lua_settable(L, LUA_REGISTRYINDEX); - - lua_pushstring(L, "__luabind_class_map"); - void* class_map_storage = lua_newuserdata( - L, sizeof(detail::class_map)); - detail::class_map* classes = new (class_map_storage) detail::class_map; - (void)classes; - - lua_newtable(L); - lua_pushcclosure(L, &destroy_class_map, 0); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L, -2); - - lua_settable(L, LUA_REGISTRYINDEX); - - // add functions (class, cast etc...) - lua_pushcclosure(L, detail::create_class::stage1, 0); - lua_setglobal(L, "class"); - - lua_pushcclosure(L, &make_property, 0); - lua_setglobal(L, "property"); - - lua_pushlightuserdata(L, &main_thread_tag); - lua_pushlightuserdata(L, L); - lua_rawset(L, LUA_REGISTRYINDEX); - - lua_pushcclosure(L, &deprecated_super, 0); - lua_setglobal(L, "super"); - } + lua_pushcclosure(L, &deprecated_super, 0); + lua_setglobal(L, "super"); + } } // namespace luabind diff --git a/libs/luabind/luabind/detail/yes_no.hpp b/libs/luabind/src/operator.cpp similarity index 81% rename from libs/luabind/luabind/detail/yes_no.hpp rename to libs/luabind/src/operator.cpp index 931847c60..db64ce862 100644 --- a/libs/luabind/luabind/detail/yes_no.hpp +++ b/libs/luabind/src/operator.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2004 Daniel Wallin +// 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"), @@ -20,15 +20,13 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef YES_NO_040211_HPP -#define YES_NO_040211_HPP +#define LUABIND_BUILDING -namespace luabind { namespace detail { +#include - typedef char(&yes_t)[1]; - typedef char(&no_t)[2]; - -}} // namespace luabind::detail - -#endif // YES_NO_040211_HPP +namespace luabind +{ + LUABIND_API self_type self; + LUABIND_API const_self_type const_self; +} diff --git a/libs/luabind/src/pcall.cpp b/libs/luabind/src/pcall.cpp index 1bf642531..07b3d9241 100644 --- a/libs/luabind/src/pcall.cpp +++ b/libs/luabind/src/pcall.cpp @@ -26,40 +26,38 @@ #include #include -namespace luabind { namespace detail -{ - int pcall(lua_State *L, int nargs, int nresults) - { - pcall_callback_fun e = get_pcall_callback(); - int en = 0; - if ( e ) +namespace luabind { + namespace detail { + + int pcall(lua_State *L, int nargs, int nresults) { - int base = lua_gettop(L) - nargs; - lua_pushcfunction(L, e); - lua_insert(L, base); // push pcall_callback under chunk and args - en = base; - } - int result = lua_pcall(L, nargs, nresults, en); - if ( en ) - lua_remove(L, en); // remove pcall_callback - return result; - } + pcall_callback_fun e = get_pcall_callback(); + int en = 0; + if(e) + { + int base = lua_gettop(L) - nargs; + e(L); + lua_insert(L, base); // push pcall_callback under chunk and args + en = base; + } + int result = lua_pcall(L, nargs, nresults, en); + if(en) + lua_remove(L, en); // remove pcall_callback + return result; + } - int resume_impl(lua_State *L, int nargs, int) - { + int resume_impl(lua_State *L, int nargs, int) + { #if LUA_VERSION_NUM >= 502 - int res = lua_resume(L, NULL, nargs); + int res = lua_resume(L, NULL, nargs); #else - int res = lua_resume(L, nargs); + int res = lua_resume(L, nargs); #endif + // Lua 5.1 added LUA_YIELD as a possible return value, + // this was causing crashes, because the caller expects 0 on success. + return (res == LUA_YIELD) ? 0 : res; + } -#if LUA_VERSION_NUM >= 501 - // Lua 5.1 added LUA_YIELD as a possible return value, - // this was causing crashes, because the caller expects 0 on success. - return (res == LUA_YIELD) ? 0 : res; -#else - return res; -#endif } +} -}} diff --git a/libs/luabind/src/scope.cpp b/libs/luabind/src/scope.cpp index 52bd132f9..0137af674 100644 --- a/libs/luabind/src/scope.cpp +++ b/libs/luabind/src/scope.cpp @@ -27,182 +27,182 @@ #include #include #include -#include #include -namespace luabind { namespace detail { - - registration::registration() - : m_next(0) - { - } - - registration::~registration() - { - delete m_next; - } - - } // namespace detail - - scope::scope() - : m_chain(0) - { - } - - scope::scope(std::auto_ptr reg) - : m_chain(reg.release()) - { - } - - scope::scope(scope const& other) - : m_chain(other.m_chain) - { - const_cast(other).m_chain = 0; - } - - scope& scope::operator=(scope const& other_) - { - delete m_chain; - m_chain = other_.m_chain; - const_cast(other_).m_chain = 0; - return *this; - } - - scope::~scope() - { - delete m_chain; - } - - scope& scope::operator,(scope s) - { - if (!m_chain) - { - m_chain = s.m_chain; - s.m_chain = 0; - return *this; - } - - for (detail::registration* c = m_chain;; c = c->m_next) - { - if (!c->m_next) - { - c->m_next = s.m_chain; - s.m_chain = 0; - break; - } - } - - return *this; - } - - void scope::register_(lua_State* L) const - { - for (detail::registration* r = m_chain; r != 0; r = r->m_next) - { - LUABIND_CHECK_STACK(L); - r->register_(L); - } - } - -} // namespace luabind +#if LUA_VERSION_NUM < 502 +# define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX) +#endif namespace luabind { + namespace detail { - namespace { + registration::registration() + : m_next(0) + { + } - struct lua_pop_stack - { - lua_pop_stack(lua_State* L) - : m_state(L) - { - } + registration::~registration() + { + delete m_next; + } - ~lua_pop_stack() - { - lua_pop(m_state, 1); - } + } // namespace detail - lua_State* m_state; - }; + scope::scope() + : m_chain(0) + { + } - } // namespace unnamed - - module_::module_(lua_State* L, char const* name = 0) - : m_state(L) - , m_name(name) - { - } + scope::scope(std::unique_ptr reg) + : m_chain(reg.release()) + { + } - void module_::operator[](scope s) - { - if (m_name) - { - lua_getglobal(m_state, m_name); + scope::scope(scope const& other) + : m_chain(other.m_chain) + { + const_cast(other).m_chain = 0; + } - if (!lua_istable(m_state, -1)) - { - lua_pop(m_state, 1); + scope& scope::operator=(scope const& other_) + { + delete m_chain; + m_chain = other_.m_chain; + const_cast(other_).m_chain = 0; + return *this; + } - lua_newtable(m_state); - lua_pushvalue(m_state, -1); - lua_setglobal(m_state, m_name); - } - } - else - { - lua_pushglobaltable(m_state); - } + scope::~scope() + { + delete m_chain; + } - lua_pop_stack guard(m_state); + scope& scope::operator,(scope s) + { + if(!m_chain) + { + m_chain = s.m_chain; + s.m_chain = 0; + return *this; + } - s.register_(m_state); - } + for(detail::registration* c = m_chain;; c = c->m_next) + { + if(!c->m_next) + { + c->m_next = s.m_chain; + s.m_chain = 0; + break; + } + } - struct namespace_::registration_ : detail::registration - { - registration_(char const* name) - : m_name(name) - { - } + return *this; + } - void register_(lua_State* L) const - { + void scope::register_(lua_State* L) const + { + for(detail::registration* r = m_chain; r != 0; r = r->m_next) + { LUABIND_CHECK_STACK(L); - assert(lua_gettop(L) >= 1); + r->register_(L); + } + } - lua_pushstring(L, m_name); - lua_gettable(L, -2); + namespace { + + struct lua_pop_stack + { + lua_pop_stack(lua_State* L) + : m_state(L) + { + } + + ~lua_pop_stack() + { + lua_pop(m_state, 1); + } + + lua_State* m_state; + }; + + } // namespace unnamed + + module_::module_(lua_State* L, char const* name = 0) + : m_state(L) + , m_name(name) + { + } + + void module_::operator[](scope s) + { + if(m_name) + { + lua_getglobal(m_state, m_name); + + if(!lua_istable(m_state, -1)) + { + lua_pop(m_state, 1); + + lua_newtable(m_state); + lua_pushvalue(m_state, -1); + lua_setglobal(m_state, m_name); + } + } + else + { + lua_pushglobaltable(m_state); + } + + lua_pop_stack guard(m_state); + + s.register_(m_state); + } + + struct namespace_::registration_ : detail::registration + { + registration_(char const* name) + : m_name(name) + { + } + + void register_(lua_State* L) const + { + LUABIND_CHECK_STACK(L); + assert(lua_gettop(L) >= 1); + + lua_pushstring(L, m_name); + lua_gettable(L, -2); detail::stack_pop p(L, 1); // pops the table on exit - if (!lua_istable(L, -1)) - { - lua_pop(L, 1); + if(!lua_istable(L, -1)) + { + lua_pop(L, 1); - lua_newtable(L); - lua_pushstring(L, m_name); - lua_pushvalue(L, -2); - lua_settable(L, -4); - } + lua_newtable(L); + lua_pushstring(L, m_name); + lua_pushvalue(L, -2); + lua_settable(L, -4); + } - m_scope.register_(L); - } + m_scope.register_(L); + } - char const* m_name; - scope m_scope; - }; + char const* m_name; + scope m_scope; + }; - namespace_::namespace_(char const* name) - : scope(std::auto_ptr( - m_registration = new registration_(name))) - { - } + namespace_::namespace_(char const* name) + : scope(std::unique_ptr( + m_registration = new registration_(name))) + { + } - namespace_& namespace_::operator[](scope s) - { - m_registration->m_scope.operator,(s); - return *this; - } + namespace_& namespace_::operator[](scope s) + { + m_registration->m_scope.operator,(s); + return *this; + } } // namespace luabind diff --git a/libs/luabind/src/set_package_preload.cpp b/libs/luabind/src/set_package_preload.cpp new file mode 100644 index 000000000..166835c66 --- /dev/null +++ b/libs/luabind/src/set_package_preload.cpp @@ -0,0 +1,60 @@ +/** + @file + @brief Implementation + + @date 2012 + + @author + Ryan Pavlik + and + 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. + +#define LUABIND_BUILDING + +// Internal Includes +#include +#include // for LUABIND_API +#include // for object, rawget, globals +#include + +// Library/third-party includes +#include // for lua_pushstring, lua_rawset, etc + +// Standard includes +// - none + + +namespace luabind { + LUABIND_API void set_package_preload(lua_State * L, const char * modulename, int(*loader) (lua_State *)) { + rawget(rawget(globals(L), "package"), "preload").push(L); + lua_pushcclosure(L, loader, 0); + lua_setfield(L, -2, modulename); + lua_pop(L, 1); + } + +} // namespace luabind + diff --git a/libs/luabind/src/stack_content_by_name.cpp b/libs/luabind/src/stack_content_by_name.cpp index 38b5c691d..e141c4054 100644 --- a/libs/luabind/src/stack_content_by_name.cpp +++ b/libs/luabind/src/stack_content_by_name.cpp @@ -22,9 +22,12 @@ #define LUABIND_BUILDING -#include +#include // for lua_gettop, lua_touserdata, etc -#include +#include // for class_rep, is_class_rep +#include // for get_instance, object_rep + +#include // for string using namespace luabind::detail; @@ -32,27 +35,27 @@ std::string luabind::detail::stack_content_by_name(lua_State* L, int start_index { std::string ret; int top = lua_gettop(L); - for (int i = start_index; i <= top; ++i) + for(int i = start_index; i <= top; ++i) { object_rep* obj = get_instance(L, i); - class_rep* crep = is_class_rep(L, i)?(class_rep*)lua_touserdata(L, i):0; - if (obj == 0 && crep == 0) + class_rep* crep = is_class_rep(L, i) ? (class_rep*)lua_touserdata(L, i) : 0; + if(obj == 0 && crep == 0) { int type = lua_type(L, i); ret += lua_typename(L, type); } - else if (obj) + else if(obj) { - if (obj->is_const()) ret += "const "; + if(obj->is_const()) ret += "const "; ret += obj->crep()->name(); } - else if (crep) + else if(crep) { ret += "<"; ret += crep->name(); ret += ">"; } - if (i < top) ret += ", "; + if(i < top) ret += ", "; } return ret; } diff --git a/libs/luabind/src/weak_ref.cpp b/libs/luabind/src/weak_ref.cpp index 245b26c2e..b73ba3876 100644 --- a/libs/luabind/src/weak_ref.cpp +++ b/libs/luabind/src/weak_ref.cpp @@ -32,126 +32,155 @@ namespace luabind { -namespace -{ + namespace + { - int weak_table_tag; + int weak_table_tag; + int impl_table_tag; -} // namespace unnamed + } // namespace unnamed -LUABIND_API void get_weak_table(lua_State* L) -{ - lua_pushlightuserdata(L, &weak_table_tag); - lua_rawget(L, LUA_REGISTRYINDEX); + LUABIND_API void get_weak_table(lua_State* L) + { + lua_pushlightuserdata(L, &weak_table_tag); + lua_rawget(L, LUA_REGISTRYINDEX); - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - lua_newtable(L); - // metatable - lua_newtable(L); - lua_pushliteral(L, "__mode"); - lua_pushliteral(L, "v"); - lua_rawset(L, -3); - // set metatable - lua_setmetatable(L, -2); + if(lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_newtable(L); + // metatable + lua_createtable(L, 0, 1); // One non-sequence entry for __mode. + lua_pushliteral(L, "__mode"); + lua_pushliteral(L, "v"); + lua_rawset(L, -3); + // set metatable + lua_setmetatable(L, -2); - lua_pushlightuserdata(L, &weak_table_tag); - lua_pushvalue(L, -2); - lua_rawset(L, LUA_REGISTRYINDEX); - } -} + lua_pushlightuserdata(L, &weak_table_tag); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + + } + + } + + LUABIND_API void get_impl_table(lua_State* L) + { + + lua_pushlightuserdata(L, &impl_table_tag); + lua_rawget(L, LUA_REGISTRYINDEX); + + if(lua_isnil(L, -1)) + { + lua_pop(L, 1); + + lua_newtable(L); + lua_pushlightuserdata(L, &impl_table_tag); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + + } + + } } // namespace luabind namespace luabind { - struct weak_ref::impl - { - impl(lua_State* main, lua_State* s, int index) - : count(0) - , state(main) - , ref(0) - { - get_weak_table(s); - lua_pushvalue(s, index); - ref = luaL_ref(s, -2); - lua_pop(s, 1); - } + struct weak_ref::impl + { + impl(lua_State* main, lua_State* s, int index) + : count(0) + , state(main) + , ref(0) + { - ~impl() - { - get_weak_table(state); - luaL_unref(state, -1, ref); - lua_pop(state, 1); - } + get_impl_table(s); + lua_pushlightuserdata(s, this); + ref = luaL_ref(s, -2); + lua_pop(s, 1); - int count; - lua_State* state; - int ref; - }; + get_weak_table(s); + lua_pushvalue(s, index); + lua_rawseti(s, -2, ref); + lua_pop(s, 1); - weak_ref::weak_ref() - : m_impl(0) - { - } - - weak_ref::weak_ref(lua_State* main, lua_State* L, int index) - : m_impl(new impl(main, L, index)) - { - m_impl->count = 1; - } + } - weak_ref::weak_ref(weak_ref const& other) - : m_impl(other.m_impl) - { - if (m_impl) ++m_impl->count; - } + ~impl() + { + get_impl_table(state); + luaL_unref(state, -1, ref); + lua_pop(state, 1); + } - weak_ref::~weak_ref() - { - if (m_impl && --m_impl->count == 0) - { - delete m_impl; - } - } + int count; + lua_State* state; + int ref; + }; - weak_ref& weak_ref::operator=(weak_ref const& other) - { - weak_ref(other).swap(*this); - return *this; - } + weak_ref::weak_ref() + : m_impl(0) + { + } - void weak_ref::swap(weak_ref& other) - { - std::swap(m_impl, other.m_impl); - } + weak_ref::weak_ref(lua_State* main, lua_State* L, int index) + : m_impl(new impl(main, L, index)) + { + m_impl->count = 1; + } - int weak_ref::id() const - { - assert(m_impl); + weak_ref::weak_ref(weak_ref const& other) + : m_impl(other.m_impl) + { + if(m_impl) ++m_impl->count; + } + + weak_ref::~weak_ref() + { + if(m_impl && --m_impl->count == 0) + { + delete m_impl; + } + } + + weak_ref& weak_ref::operator=(weak_ref const& other) + { + weak_ref(other).swap(*this); + return *this; + } + + void weak_ref::swap(weak_ref& other) + { + std::swap(m_impl, other.m_impl); + } + + int weak_ref::id() const + { + assert(m_impl); return m_impl->ref; - } + } // L may not be the same pointer as // was used when creating this reference // since it may be a thread that shares // the same globals table. - void weak_ref::get(lua_State* L) const - { - assert(m_impl); + void weak_ref::get(lua_State* L) const + { + assert(m_impl); assert(L); - get_weak_table(L); - lua_rawgeti(L, -1, m_impl->ref); - lua_remove(L, -2); - } + get_weak_table(L); + lua_rawgeti(L, -1, m_impl->ref); + lua_remove(L, -2); + } + + lua_State* weak_ref::state() const + { + assert(m_impl); + return m_impl->state; + } - lua_State* weak_ref::state() const - { - assert(m_impl); - return m_impl->state; - } - } // namespace luabind diff --git a/libs/luabind/src/wrapper_base.cpp b/libs/luabind/src/wrapper_base.cpp index 9fb54a5db..d09dfe983 100644 --- a/libs/luabind/src/wrapper_base.cpp +++ b/libs/luabind/src/wrapper_base.cpp @@ -29,27 +29,29 @@ #include #include -namespace luabind { namespace detail -{ - LUABIND_API void do_call_member_selection(lua_State* L, char const* name) - { - object_rep* obj = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); // pop self +namespace luabind { + namespace detail { - obj->crep()->get_table(L); // push the crep table - lua_pushstring(L, name); - lua_gettable(L, -2); - lua_remove(L, -2); // remove the crep table + LUABIND_API void do_call_member_selection(lua_State* L, char const* name) + { + object_rep* obj = static_cast(lua_touserdata(L, -1)); + assert(obj); - if (!is_luabind_function(L, -1)) - return; + lua_pushstring(L, name); + lua_gettable(L, -2); + lua_replace(L, -2); - // this (usually) means the function has not been - // overridden by lua, call the default implementation - lua_pop(L, 1); - obj->crep()->get_default_table(L); // push the crep table - lua_pushstring(L, name); - lua_gettable(L, -2); - lua_remove(L, -2); // remove the crep table + if(!is_luabind_function(L, -1)) + return; + + // this (usually) means the function has not been + // overridden by lua, call the default implementation + lua_pop(L, 1); + obj->crep()->get_default_table(L); // push the crep table + lua_pushstring(L, name); + lua_gettable(L, -2); + lua_remove(L, -2); // remove the crep table + } } -}} +} + From 5f23a72a16c4a932a2227471b0044878a49e81cd Mon Sep 17 00:00:00 2001 From: Adam Martin Date: Sat, 2 Feb 2019 00:08:39 -0600 Subject: [PATCH 2/3] Removed unused boost header, fixed compiling with new luabind Fixed TryFinishingBlow attempting to return by parameter reference. The new luabind fails with a by_reference to by_value check. Using a pointer accomplishes the same goal, but bypasses this issue. --- zone/attack.cpp | 1 - zone/lua_entity_list.cpp | 14 +++++++------- zone/lua_hate_list.cpp | 2 +- zone/lua_mob.cpp | 6 +++--- zone/lua_mob.h | 2 +- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/zone/attack.cpp b/zone/attack.cpp index 483cce368..f5fc34a2c 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -39,7 +39,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include #include #include -#include #ifdef BOTS #include "bot.h" diff --git a/zone/lua_entity_list.cpp b/zone/lua_entity_list.cpp index abfc020d6..3d53b6166 100644 --- a/zone/lua_entity_list.cpp +++ b/zone/lua_entity_list.cpp @@ -508,37 +508,37 @@ luabind::scope lua_register_entity_list() { luabind::scope lua_register_mob_list() { return luabind::class_("MobList") - .def_readwrite("entries", &Lua_Mob_List::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_Mob_List::entries, luabind::return_stl_iterator()); } luabind::scope lua_register_client_list() { return luabind::class_("ClientList") - .def_readwrite("entries", &Lua_Client_List::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_Client_List::entries, luabind::return_stl_iterator()); } luabind::scope lua_register_npc_list() { return luabind::class_("NPCList") - .def_readwrite("entries", &Lua_NPC_List::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_NPC_List::entries, luabind::return_stl_iterator()); } luabind::scope lua_register_corpse_list() { return luabind::class_("CorpseList") - .def_readwrite("entries", &Lua_Corpse_List::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_Corpse_List::entries, luabind::return_stl_iterator()); } luabind::scope lua_register_object_list() { return luabind::class_("ObjectList") - .def_readwrite("entries", &Lua_Object_List::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_Object_List::entries, luabind::return_stl_iterator()); } luabind::scope lua_register_door_list() { return luabind::class_("DoorList") - .def_readwrite("entries", &Lua_Doors_List::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_Doors_List::entries, luabind::return_stl_iterator()); } luabind::scope lua_register_spawn_list() { return luabind::class_("SpawnList") - .def_readwrite("entries", &Lua_Spawn_List::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_Spawn_List::entries, luabind::return_stl_iterator()); } #endif diff --git a/zone/lua_hate_list.cpp b/zone/lua_hate_list.cpp index e8c6a52df..82d79f977 100644 --- a/zone/lua_hate_list.cpp +++ b/zone/lua_hate_list.cpp @@ -63,7 +63,7 @@ luabind::scope lua_register_hate_entry() { luabind::scope lua_register_hate_list() { return luabind::class_("HateList") - .def_readwrite("entries", &Lua_HateList::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_HateList::entries, luabind::return_stl_iterator()); } #endif diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 59d50508e..c09cc8b0d 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -2141,9 +2141,9 @@ bool Lua_Mob::IsBerserk() { return self->IsBerserk(); } -bool Lua_Mob::TryFinishingBlow(Lua_Mob defender, int &damage) { +bool Lua_Mob::TryFinishingBlow(Lua_Mob defender, int *damage) { Lua_Safe_Call_Bool(); - return self->TryFinishingBlow(defender, damage); + return self->TryFinishingBlow(defender, *damage); } int Lua_Mob::GetBodyType() @@ -2540,7 +2540,7 @@ luabind::scope lua_register_mob() { .def("AttackAnimation", &Lua_Mob::AttackAnimation) .def("GetWeaponDamage", &Lua_Mob::GetWeaponDamage) .def("IsBerserk", &Lua_Mob::IsBerserk) - .def("TryFinishingBlow", &Lua_Mob::TryFinishingBlow) + .def("TryFinishingBlow", (bool(Lua_Mob::*)(int*))&Lua_Mob::TryFinishingBlow) .def("GetBodyType", &Lua_Mob::GetBodyType) .def("GetOrigBodyType", &Lua_Mob::GetOrigBodyType) .def("CheckNumHitsRemaining", &Lua_Mob::CheckNumHitsRemaining); diff --git a/zone/lua_mob.h b/zone/lua_mob.h index fc58af6d5..993556ae3 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -411,7 +411,7 @@ public: int AttackAnimation(int Hand, Lua_ItemInst weapon); int GetWeaponDamage(Lua_Mob against, Lua_ItemInst weapon); bool IsBerserk(); - bool TryFinishingBlow(Lua_Mob defender, int &damage); + bool TryFinishingBlow(Lua_Mob defender, int *damage); int GetBodyType(); int GetOrigBodyType(); void CheckNumHitsRemaining(int type, int32 buff_slot, uint16 spell_id); From f6c8d9532e9116d88c904a0b014b49d4b291674a Mon Sep 17 00:00:00 2001 From: Adam Martin Date: Sat, 2 Feb 2019 00:32:41 -0600 Subject: [PATCH 3/3] Applied changes proposed in https://github.com/decimad/luabind-deboostified/pull/38/ These changes claim to fix GCC 7 compilation. --- .../conversion_policies/function_converter.hpp | 12 +++++------- libs/luabind/luabind/detail/push_to_lua.hpp | 1 + libs/luabind/luabind/lua_index_proxy.hpp | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp index 13c27da09..905784730 100644 --- a/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp +++ b/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp @@ -39,15 +39,13 @@ namespace luabind { template< typename T > struct is_function< std::function< T > > : public std::true_type {}; - - template< typename R, typename... Args, typename WrappedType > - struct deduce_signature , WrappedType > - { - using type = meta::type_list< R, Args... >; - }; - } + template< typename R, typename... Args, typename WrappedType > + struct deduce_signature , WrappedType > + { + using type = meta::type_list< R, Args... >; + }; template struct default_converter>::value>::type> diff --git a/libs/luabind/luabind/detail/push_to_lua.hpp b/libs/luabind/luabind/detail/push_to_lua.hpp index 22ad8534f..8bb2e646a 100644 --- a/libs/luabind/luabind/detail/push_to_lua.hpp +++ b/libs/luabind/luabind/detail/push_to_lua.hpp @@ -26,6 +26,7 @@ #include #include +#include namespace luabind { diff --git a/libs/luabind/luabind/lua_index_proxy.hpp b/libs/luabind/luabind/lua_index_proxy.hpp index f8c726de1..c62314f91 100644 --- a/libs/luabind/luabind/lua_index_proxy.hpp +++ b/libs/luabind/luabind/lua_index_proxy.hpp @@ -72,7 +72,7 @@ namespace luabind { detail::stack_pop pop(m_interpreter, 1); lua_pushvalue(m_interpreter, m_key_index); - detail::push(m_interpreter, value); + detail::push_to_lua(m_interpreter, value); lua_settable(m_interpreter, -3); return *this; }