Revert "Remove boost"

This commit is contained in:
Alex 2019-10-13 00:53:31 -07:00 committed by GitHub
parent 04e7238a6e
commit 47ee5b5afb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
131 changed files with 10198 additions and 9498 deletions

View File

@ -49,6 +49,7 @@ IF(MSVC)
ENDIF() ENDIF()
#Find everything we need #Find everything we need
FIND_PACKAGE(Boost REQUIRED)
FIND_PACKAGE(MySQL) FIND_PACKAGE(MySQL)
FIND_PACKAGE(MariaDB) FIND_PACKAGE(MariaDB)
FIND_PACKAGE(ZLIB) FIND_PACKAGE(ZLIB)
@ -262,10 +263,11 @@ MESSAGE(STATUS "* zlib: ${ZLIB_LIBRARY_TYPE} *"
MESSAGE(STATUS "**************************************************") MESSAGE(STATUS "**************************************************")
#setup server libs and headers #setup server libs and headers
SET(SERVER_LIBS common ${DATABASE_LIBRARY_LIBS} ${ZLIB_LIBRARY_LIBS} uv_a fmt RecastNavigation::Detour) SET(SERVER_LIBS common ${DATABASE_LIBRARY_LIBS} ${ZLIB_LIBRARY_LIBS} ${Boost_LIBRARIES} uv_a fmt RecastNavigation::Detour)
INCLUDE_DIRECTORIES(SYSTEM "${DATABASE_LIBRARY_INCLUDE}") INCLUDE_DIRECTORIES(SYSTEM "${DATABASE_LIBRARY_INCLUDE}")
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_LIBRARY_INCLUDE}") INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_LIBRARY_INCLUDE}")
INCLUDE_DIRECTORIES(SYSTEM "${Boost_INCLUDE_DIRS}")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/glm") INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/glm")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/cereal/include") INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/cereal/include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/fmt/include") INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/fmt/include")

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,89 @@
// Copyright (c) 2004 Daniel Wallin
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef CLASS_CACHE_040218_HPP
#define CLASS_CACHE_040218_HPP
#include <luabind/prefix.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/add_const.hpp>
namespace luabind { namespace detail {
#ifdef LUABIND_NOT_THREADSAFE
class class_rep;
template<class T>
struct class_cache_impl
{
static lua_State* state;
static class_rep* class_;
};
template<class T>
lua_State* class_cache_impl<T>::state = 0;
template<class T>
class_rep* class_cache_impl<T>::class_ = 0;
template<class T>
struct class_cache
: class_cache_impl<
typename boost::add_reference<
typename boost::add_const<
T
>::type
>::type
>
{
};
template<class T>
class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0)
{
if (class_cache<T>::state != L)
{
class_cache<T>::state = L;
class_registry* registry = class_registry::get_registry(L);
class_cache<T>::class_ = registry->find_class(typeid(T));
}
return class_cache<T>::class_;
}
#else
template<class T>
class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0)
{
class_registry* registry = class_registry::get_registry(L);
return registry->find_class(typeid(T));
}
#endif
}} // namespace luabind::detail
#endif // CLASS_CACHE_040218_HPP

View File

@ -30,9 +30,8 @@
#include <luabind/open.hpp> #include <luabind/open.hpp>
#include <luabind/typeid.hpp> #include <luabind/typeid.hpp>
namespace luabind { namespace luabind { namespace detail
namespace detail { {
class class_rep; class class_rep;
struct LUABIND_API class_registry struct LUABIND_API class_registry
@ -80,8 +79,7 @@ namespace luabind {
}; };
} }}
}
#endif // LUABIND_CLASS_REGISTRY_HPP_INCLUDED #endif // LUABIND_CLASS_REGISTRY_HPP_INCLUDED

View File

@ -1,4 +1,4 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"), // copy of this software and associated documentation files (the "Software"),
@ -24,12 +24,16 @@
#ifndef LUABIND_CLASS_REP_HPP_INCLUDED #ifndef LUABIND_CLASS_REP_HPP_INCLUDED
#define LUABIND_CLASS_REP_HPP_INCLUDED #define LUABIND_CLASS_REP_HPP_INCLUDED
#include <boost/limits.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/lua_include.hpp> #include <luabind/lua_include.hpp>
#include <luabind/detail/object_rep.hpp>
#include <luabind/detail/garbage_collector.hpp> #include <luabind/detail/garbage_collector.hpp>
#include <luabind/detail/operator_id.hpp> #include <luabind/detail/operator_id.hpp>
#include <luabind/detail/class_registry.hpp> #include <luabind/detail/class_registry.hpp>
@ -39,8 +43,8 @@
#include <luabind/typeid.hpp> #include <luabind/typeid.hpp>
#include <luabind/detail/ref.hpp> #include <luabind/detail/ref.hpp>
namespace luabind { namespace luabind { namespace detail
namespace detail { {
LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
@ -67,7 +71,7 @@ namespace luabind {
{ {
friend struct class_registration; friend struct class_registration;
friend int super_callback(lua_State*); friend int super_callback(lua_State*);
//TODO: avoid the lua-prefix //TODO: avoid the lua-prefix
friend int lua_class_gettable(lua_State*); friend int lua_class_gettable(lua_State*);
friend int lua_class_settable(lua_State*); friend int lua_class_settable(lua_State*);
friend int static_class_gettable(lua_State*); friend int static_class_gettable(lua_State*);
@ -95,7 +99,7 @@ namespace luabind {
~class_rep(); ~class_rep();
std::pair<void*, void*> allocate(lua_State* L) const; std::pair<void*,void*> allocate(lua_State* L) const;
// this is called as metamethod __call on the class_rep. // this is called as metamethod __call on the class_rep.
static int constructor_dispatcher(lua_State* L); static int constructor_dispatcher(lua_State* L);
@ -147,9 +151,6 @@ namespace luabind {
private: private:
// Code common to both constructors
void shared_init(lua_State * L);
void cache_operators(lua_State*); void cache_operators(lua_State*);
// this is a pointer to the type_info structure for // this is a pointer to the type_info structure for
@ -203,10 +204,10 @@ namespace luabind {
class_id_map* m_classes; class_id_map* m_classes;
}; };
LUABIND_API bool is_class_rep(lua_State* L, int index); bool is_class_rep(lua_State* L, int index);
} }}
}
//#include <luabind/detail/overload_rep_impl.hpp>
#endif // LUABIND_CLASS_REP_HPP_INCLUDED #endif // LUABIND_CLASS_REP_HPP_INCLUDED

View File

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

View File

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

View File

@ -1,81 +0,0 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_CONVERSION_BASE_HPP_INCLUDED
#define LUABIND_CONVERSION_BASE_HPP_INCLUDED
#include <type_traits>
#include <luabind/lua_include.hpp>
#include <luabind/detail/decorate_type.hpp>
#include <luabind/detail/make_instance.hpp>
#include <luabind/pointer_traits.hpp>
#include <luabind/from_stack.hpp>
namespace luabind {
namespace detail {
// Something's strange with the references here... need to know when to copy :(
template <class T, class Clone>
void make_pointee_instance(lua_State* L, T&& x, std::true_type, Clone)
{
if(get_pointer(x))
{
make_pointer_instance(L, std::forward<T>(x));
}
else
{
lua_pushnil(L);
}
}
template <class T>
void make_pointee_instance(lua_State* L, T&& x, std::false_type, std::true_type)
{
using value_type = typename std::remove_reference<T>::type;
std::unique_ptr<value_type> ptr(new value_type(std::move(x)));
make_pointer_instance(L, std::move(ptr));
}
template <class T>
void make_pointee_instance(lua_State* L, T&& x, std::false_type, std::false_type)
{
// need a second make_instance that moves x into place
make_pointer_instance(L, &x);
}
template <class T, class Clone>
void make_pointee_instance(lua_State* L, T&& x, Clone)
{
make_pointee_instance(L, std::forward<T>(x), has_get_pointer<T>(), Clone());
}
}
template <class T, class Enable>
struct default_converter;
}
#endif

View File

@ -1,89 +0,0 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_CONVERSION_POLICIES_HPP_INCLUDED
#define LUABIND_CONVERSION_POLICIES_HPP_INCLUDED
#include <luabind/detail/type_traits.hpp>
#include <luabind/detail/meta.hpp>
#include <luabind/detail/policy.hpp>
#include <luabind/detail/conversion_policies/conversion_base.hpp>
#include <luabind/detail/conversion_policies/enum_converter.hpp>
#include <luabind/detail/conversion_policies/pointer_converter.hpp>
#include <luabind/detail/conversion_policies/reference_converter.hpp>
#include <luabind/detail/conversion_policies/value_converter.hpp>
#include <luabind/detail/conversion_policies/lua_proxy_converter.hpp>
#include <luabind/detail/conversion_policies/native_converter.hpp>
#include <luabind/detail/conversion_policies/function_converter.hpp>
#include <luabind/shared_ptr_converter.hpp>
namespace luabind {
template <>
struct default_converter<lua_State*>
{
enum { consumed_args = 0 };
template <class U>
lua_State* to_cpp(lua_State* L, U, int /*index*/)
{
return L;
}
template <class U>
static int match(lua_State*, U, int /*index*/)
{
return 0;
}
template <class U>
void converter_postcall(lua_State*, U, int) {}
};
namespace detail {
// This is the one that gets hit, if default_policy doesn't hit one of the specializations defined all over the place
template< class T >
struct default_converter_generator
: public meta::select_ <
meta::case_< is_lua_proxy_arg<T>, lua_proxy_converter<T> >,
meta::case_< std::is_enum<typename std::remove_reference<T>::type>, enum_converter >,
meta::case_< is_nonconst_pointer<T>, pointer_converter >,
meta::case_< is_const_pointer<T>, const_pointer_converter >,
meta::case_< is_nonconst_reference<T>, ref_converter >,
meta::case_< is_const_reference<T>, const_ref_converter >,
meta::default_< value_converter >
> ::type
{
};
}
template <class T, class Enable>
struct default_converter
: detail::default_converter_generator<T>::type
{};
}
#endif

View File

@ -1,82 +0,0 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_ENUM_CONVERTER_HPP_INCLUDED
#define LUABIND_ENUM_CONVERTER_HPP_INCLUDED
#include <type_traits>
#include <luabind/detail/type_traits.hpp>
#include <luabind/detail/conversion_policies/conversion_base.hpp>
namespace luabind {
namespace detail {
struct enum_converter
{
using type = enum_converter;
using is_native = std::false_type;
enum { consumed_args = 1 };
void to_lua(lua_State* L, int val)
{
lua_pushnumber(L, val);
}
template<class T>
T to_cpp(lua_State* L, by_value<T>, int index)
{
return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
}
template<class T>
static int match(lua_State* L, by_value<T>, int index)
{
if(lua_isnumber(L, index)) {
return 0;
} else {
return no_match;
}
}
template<class T>
T to_cpp(lua_State* L, by_const_reference<T>, int index)
{
return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
}
template<class T>
static int match(lua_State* L, by_const_reference<T>, int index)
{
if(lua_isnumber(L, index)) return 0; else return no_match;
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
}
}
#endif

View File

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

View File

@ -1,73 +0,0 @@
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_VALUE_WRAPPER_CONVERTER_HPP_INCLUDED
#define LUABIND_VALUE_WRAPPER_CONVERTER_HPP_INCLUDED
#include <luabind/lua_proxy.hpp>
#include <type_traits>
namespace luabind {
namespace detail {
template <class U>
struct lua_proxy_converter
{
using type = lua_proxy_converter<U>;
using is_native = std::true_type;
enum { consumed_args = 1 };
template<class T>
T to_cpp(lua_State* L, by_const_reference<T>, int index)
{
return T(from_stack(L, index));
}
template<class T>
T to_cpp(lua_State* L, by_value<T>, int index)
{
return to_cpp(L, by_const_reference<T>(), index);
}
template<class T>
static int match(lua_State* L, by_const_reference<T>, int index)
{
return lua_proxy_traits<T>::check(L, index)
? max_hierarchy_depth
: no_match;
}
template<class T>
static int match(lua_State* L, by_value<T>, int index)
{
return match(L, by_const_reference<T>(), index);
}
void converter_postcall(...) {}
template<class T>
void to_lua(lua_State* interpreter, T const& value_wrapper)
{
lua_proxy_traits<T>::unwrap(interpreter, value_wrapper);
}
};
}
}
#endif

View File

@ -1,302 +0,0 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_NATIVE_CONVERTER_HPP_INCLUDED
#define LUABIND_NATIVE_CONVERTER_HPP_INCLUDED
#include <type_traits>
#include <string>
#include <luabind/detail/policy.hpp>
#include <luabind/detail/conversion_policies/conversion_base.hpp>
#include <luabind/detail/type_traits.hpp>
#include <luabind/detail/call_traits.hpp>
#include <luabind/lua_include.hpp>
#if LUA_VERSION_NUM < 502
# define lua_rawlen lua_objlen
#endif
namespace luabind {
template <class T, class Derived = default_converter<T> >
struct native_converter_base
{
using is_native = std::true_type;
using value_type = typename detail::call_traits<T>::value_type;
using param_type = typename detail::call_traits<T>::param_type;
enum { consumed_args = 1 };
template <class U>
void converter_postcall(lua_State*, U const&, int)
{}
int match(lua_State* L, by_value<T>, int index)
{
return Derived::compute_score(L, index);
}
int match(lua_State* L, by_value<T const>, int index)
{
return Derived::compute_score(L, index);
}
int match(lua_State* L, by_const_reference<T>, int index)
{
return Derived::compute_score(L, index);
}
value_type to_cpp(lua_State* L, by_value<T>, int index)
{
return derived().to_cpp_deferred(L, index);
}
value_type to_cpp(lua_State* L, by_const_reference<T>, int index)
{
return derived().to_cpp_deferred(L, index);
}
void to_lua(lua_State* L, param_type value)
{
derived().to_lua_deferred(L, value);
}
Derived& derived()
{
return static_cast<Derived&>(*this);
}
};
template <typename QualifiedT>
struct integer_converter
: native_converter_base<remove_const_reference_t<QualifiedT>>
{
using T = remove_const_reference_t<QualifiedT>;
using value_type = typename native_converter_base<T>::value_type;
using param_type = typename native_converter_base<T>::param_type;
static int compute_score(lua_State* L, int index)
{
return lua_type(L, index) == LUA_TNUMBER ? 0 : no_match;
}
static value_type to_cpp_deferred(lua_State* L, int index)
{
if((std::is_unsigned<value_type>::value && sizeof(value_type) >= sizeof(lua_Integer)) || (sizeof(value_type) > sizeof(lua_Integer))) {
return static_cast<T>(lua_tonumber(L, index));
} else {
return static_cast<T>(lua_tointeger(L, index));
}
}
void to_lua_deferred(lua_State* L, param_type value)
{
if((std::is_unsigned<value_type>::value && sizeof(value_type) >= sizeof(lua_Integer)) || (sizeof(value_type) > sizeof(lua_Integer)))
{
lua_pushnumber(L, (lua_Number)value);
} else {
lua_pushinteger(L, static_cast<lua_Integer>(value));
}
}
};
template <typename QualifiedT>
struct number_converter
: native_converter_base<remove_const_reference_t<QualifiedT>>
{
using T = remove_const_reference_t<QualifiedT>;
using value_type = typename native_converter_base<T>::value_type;
using param_type = typename native_converter_base<T>::param_type;
static int compute_score(lua_State* L, int index)
{
return lua_type(L, index) == LUA_TNUMBER ? 0 : no_match;
}
static value_type to_cpp_deferred(lua_State* L, int index)
{
return static_cast<T>(lua_tonumber(L, index));
}
static void to_lua_deferred(lua_State* L, param_type value)
{
lua_pushnumber(L, static_cast<lua_Number>(value));
}
};
template <>
struct default_converter<bool>
: native_converter_base<bool>
{
static int compute_score(lua_State* L, int index)
{
return lua_type(L, index) == LUA_TBOOLEAN ? 0 : no_match;
}
static bool to_cpp_deferred(lua_State* L, int index)
{
return lua_toboolean(L, index) == 1;
}
static void to_lua_deferred(lua_State* L, bool value)
{
lua_pushboolean(L, value);
}
};
template <>
struct default_converter<bool const>
: default_converter<bool>
{};
template <>
struct default_converter<bool const&>
: default_converter<bool>
{};
template <>
struct default_converter<std::string>
: native_converter_base<std::string>
{
static int compute_score(lua_State* L, int index)
{
return lua_type(L, index) == LUA_TSTRING ? 0 : no_match;
}
static std::string to_cpp_deferred(lua_State* L, int index)
{
return std::string(lua_tostring(L, index), lua_rawlen(L, index));
}
static void to_lua_deferred(lua_State* L, std::string const& value)
{
lua_pushlstring(L, value.data(), value.size());
}
};
template <>
struct default_converter<std::string&>
: default_converter<std::string>
{};
template <>
struct default_converter<std::string const>
: default_converter<std::string>
{};
template <>
struct default_converter<std::string const&>
: default_converter<std::string>
{};
template <>
struct default_converter<char const*>
{
using is_native = std::true_type;
enum { consumed_args = 1 };
template <class U>
static int match(lua_State* L, U, int index)
{
int type = lua_type(L, index);
return (type == LUA_TSTRING || type == LUA_TNIL) ? 0 : no_match;
}
template <class U>
static char const* to_cpp(lua_State* L, U, int index)
{
return lua_tostring(L, index);
}
static void to_lua(lua_State* L, char const* str)
{
lua_pushstring(L, str);
}
template <class U>
void converter_postcall(lua_State*, U, int)
{}
};
template <>
struct default_converter<const char* const>
: default_converter<char const*>
{};
template <>
struct default_converter<const char* const&>
: default_converter<char const*>
{};
template <>
struct default_converter<const char*&>
: default_converter<char const*>
{};
template <>
struct default_converter<char*>
: default_converter<char const*>
{};
template <std::size_t N>
struct default_converter<char const[N]>
: default_converter<char const*>
{};
template <std::size_t N>
struct default_converter<char[N]>
: default_converter<char const*>
{};
template <std::size_t N>
struct default_converter <char(&)[N]>
: default_converter<char const*>
{};
template <std::size_t N>
struct default_converter <const char(&)[N]>
: default_converter<char const*>
{};
template <typename T>
struct default_converter < T, typename std::enable_if< std::is_integral<remove_const_reference_t<T>>::value >::type >
: integer_converter<T>
{
};
template <typename T>
struct default_converter < T, typename std::enable_if< std::is_floating_point<remove_const_reference_t<T>>::value >::type >
: number_converter<T>
{
};
}
#if LUA_VERSION_NUM < 502
# undef lua_rawlen
#endif
#endif

View File

@ -1,143 +0,0 @@
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_POINTER_CONVERTER_HPP_INCLUDED
#define LUABIND_POINTER_CONVERTER_HPP_INCLUDED
#include <type_traits>
#include <luabind/lua_include.hpp>
#include <luabind/detail/make_instance.hpp>
#include <luabind/back_reference.hpp>
namespace luabind {
/*
Todo: Remove code duplication
*/
namespace detail {
struct pointer_converter
{
using type = pointer_converter;
using is_native = std::false_type;
pointer_converter()
: result(0)
{}
void* result;
enum { consumed_args = 1 };
template<class T>
static void to_lua(lua_State* L, T* ptr)
{
if(ptr == 0)
{
lua_pushnil(L);
return;
}
if(luabind::get_back_reference(L, ptr))
return;
make_pointer_instance(L, ptr);
}
template<class T>
T* to_cpp(lua_State*, by_pointer<T>, int /*index*/)
{
return static_cast<T*>(result);
}
template<class T>
int match(lua_State* L, by_pointer<T>, int index)
{
if(lua_isnil(L, index)) return 0;
object_rep* obj = get_instance(L, index);
if(obj == 0) return no_match;
if(obj->is_const())
return no_match;
std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
result = s.first;
return s.second;
}
template<class T>
void converter_postcall(lua_State*, by_pointer<T>, int /*index*/)
{}
};
struct const_pointer_converter
{
using type = const_pointer_converter;
using is_native = std::false_type;
enum { consumed_args = 1 };
const_pointer_converter()
: result(0)
{}
void* result;
template<class T>
void to_lua(lua_State* L, const T* ptr)
{
if(ptr == 0)
{
lua_pushnil(L);
return;
}
if(luabind::get_back_reference(L, ptr))
return;
make_pointer_instance(L, ptr);
}
template<class T>
T const* to_cpp(lua_State*, by_const_pointer<T>, int)
{
return static_cast<T const*>(result);
}
template<class T>
int match(lua_State* L, by_const_pointer<T>, int index)
{
if(lua_isnil(L, index)) return 0;
object_rep* obj = get_instance(L, index);
if(obj == 0) return no_match; // if the type is not one of our own registered types, classify it as a non-match
std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
if(s.second >= 0 && !obj->is_const())
s.second += 10;
result = s.first;
return s.second;
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
}
}
#endif

View File

@ -1,124 +0,0 @@
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_REFERENCE_CONVERTER_HPP_INCLUDED
#define LUABIND_REFERENCE_CONVERTER_HPP_INCLUDED
#include <type_traits>
#include <luabind/detail/conversion_policies/conversion_base.hpp>
#include <luabind/detail/conversion_policies/pointer_converter.hpp>
#include <luabind/back_reference.hpp>
namespace luabind {
/*
TODO: Remove code duplication
*/
namespace detail {
struct ref_converter : pointer_converter
{
using type = ref_converter;
using is_native = std::false_type;
enum { consumed_args = 1 };
template<class T>
void to_lua(lua_State* L, T& ref)
{
if(luabind::get_back_reference(L, ref))
return;
make_pointee_instance(L, ref, std::false_type());
}
template<class T>
T& to_cpp(lua_State* L, by_reference<T>, int index)
{
assert(!lua_isnil(L, index));
return *pointer_converter::to_cpp(L, by_pointer<T>(), index);
}
template<class T>
int match(lua_State* L, by_reference<T>, int index)
{
object_rep* obj = get_instance(L, index);
if(obj == 0) return no_match;
if(obj->is_const())
return no_match;
std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
result = s.first;
return s.second;
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
struct const_ref_converter
{
using type = const_ref_converter;
using is_native = std::false_type;
enum { consumed_args = 1 };
const_ref_converter()
: result(0)
{}
void* result;
template<class T>
void to_lua(lua_State* L, T const& ref)
{
if(luabind::get_back_reference(L, ref))
return;
make_pointee_instance(L, ref, std::false_type());
}
template<class T>
T const& to_cpp(lua_State*, by_const_reference<T>, int)
{
return *static_cast<T*>(result);
}
template<class T>
int match(lua_State* L, by_const_reference<T>, int index)
{
object_rep* obj = get_instance(L, index);
if(obj == 0) return no_match; // if the type is not one of our own registered types, classify it as a non-match
std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
if(s.second >= 0 && !obj->is_const())
s.second += 10;
result = s.first;
return s.second;
}
template<class T>
void converter_postcall(lua_State*, by_const_reference<T>, int)
{
}
};
}
}
#endif

View File

@ -1,79 +0,0 @@
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_VALUE_CONVERTER_HPP_INCLUDED
#define LUABIND_VALUE_CONVERTER_HPP_INCLUDED
#include <type_traits>
#include <luabind/lua_include.hpp>
#include <luabind/back_reference.hpp>
#include <luabind/detail/object_rep.hpp>
namespace luabind {
namespace detail {
struct value_converter
{
using type = value_converter;
using is_native = std::false_type;
enum { consumed_args = 1 };
value_converter()
: result(0)
{}
void* result;
template<class T>
void to_lua(lua_State* L, T&& x)
{
if(luabind::get_back_reference(L, x))
return;
make_value_instance(L, std::forward<T>(x));
}
template<class T>
T to_cpp(lua_State*, by_value<T>, int)
{
return *static_cast<T*>(result);
}
template<class T>
int match(lua_State* L, by_value<T>, int index)
{
// special case if we get nil in, try to match the holder type
if(lua_isnil(L, index))
return no_match;
object_rep* obj = get_instance(L, index);
if(obj == 0) return no_match;
std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
result = s.first;
return s.second;
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
}
}
#endif

View File

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

View File

@ -0,0 +1,92 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_CONVERT_TO_LUA_HPP_INCLUDED
#define LUABIND_CONVERT_TO_LUA_HPP_INCLUDED
#include <luabind/config.hpp>
#include <luabind/detail/policy.hpp>
#include <boost/ref.hpp>
#include <boost/mpl/apply_wrap.hpp>
namespace luabind { namespace detail
{
template<bool IsReferenceWrapper = false>
struct unwrap_ref
{
template<class T>
static const T& get(const T& r) { return r; }
template<class T>
struct apply
{
typedef T type;
};
};
template<>
struct unwrap_ref<true>
{
template<class T>
static T& get(const boost::reference_wrapper<T>& r) { return r.get(); }
template<class T>
struct apply
{
typedef typename T::type& type;
};
};
namespace mpl = boost::mpl;
template<class T>
void convert_to_lua(lua_State* L, const T& v)
{
typedef typename mpl::apply_wrap1<
unwrap_ref<boost::is_reference_wrapper<T>::value>
, T
>::type value_type;
typename mpl::apply_wrap2<default_policy,value_type,cpp_to_lua>::type converter;
converter.apply(L, unwrap_ref<boost::is_reference_wrapper<T>::value>::get(v));
}
template<int Index, class T, class Policies>
void convert_to_lua_p(lua_State* L, const T& v, const Policies&)
{
typedef typename mpl::apply_wrap1<
unwrap_ref<boost::is_reference_wrapper<T>::value>
, T
>::type value_type;
typedef typename find_conversion_policy<Index, Policies>::type converter_policy;
typename mpl::apply_wrap2<converter_policy,value_type,cpp_to_lua>::type converter;
converter.apply(L, unwrap_ref<boost::is_reference_wrapper<T>::value>::get(v));
}
}}
#endif

View File

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

View File

@ -28,9 +28,8 @@
#include <luabind/lua_include.hpp> #include <luabind/lua_include.hpp>
#include <cassert> #include <cassert>
namespace luabind { namespace luabind { namespace detail
namespace detail { {
struct stack_checker_type struct stack_checker_type
{ {
stack_checker_type(lua_State* L) stack_checker_type(lua_State* L)
@ -47,13 +46,10 @@ namespace luabind {
int m_stack; int m_stack;
}; };
} }}
}
#define LUABIND_CHECK_STACK(L) luabind::detail::stack_checker_type stack_checker_object(L) #define LUABIND_CHECK_STACK(L) luabind::detail::stack_checker_type stack_checker_object(L)
#else #else
#define LUABIND_CHECK_STACK(L) do {} while (0) #define LUABIND_CHECK_STACK(L) do {} while (0)
#endif #endif
#endif // LUABIND_DEBUG_HPP_INCLUDED #endif // LUABIND_DEBUG_HPP_INCLUDED

View File

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

View File

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

View File

@ -30,8 +30,8 @@
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/detail/class_rep.hpp> #include <luabind/detail/class_rep.hpp>
namespace luabind { namespace luabind
{
struct value; struct value;
struct value_vector : public std::vector<value> struct value_vector : public std::vector<value>
@ -93,7 +93,7 @@ namespace luabind {
template<class From> template<class From>
struct enum_maker struct enum_maker
{ {
explicit enum_maker(From& from) : from_(from) {} explicit enum_maker(From& from): from_(from) {}
From& operator[](const value& val) From& operator[](const value& val)
{ {
@ -103,8 +103,9 @@ namespace luabind {
From& operator[](const value_vector& values) From& operator[](const value_vector& values)
{ {
for(const auto& val : values) { for (value_vector::const_iterator i = values.begin(); i != values.end(); ++i)
from_.add_static_constant(val.name_, val.val_); {
from_.add_static_constant(i->name_, i->val_);
} }
return from_; return from_;
@ -120,4 +121,3 @@ namespace luabind {
} }
#endif // LUABIND_ENUM_MAKER_HPP_INCLUDED #endif // LUABIND_ENUM_MAKER_HPP_INCLUDED

View File

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

View File

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

View File

@ -0,0 +1,107 @@
// Copyright (c) 2005 Daniel Wallin
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_HAS_GET_POINTER_051022_HPP
# define LUABIND_HAS_GET_POINTER_051022_HPP
# include <boost/type_traits/add_reference.hpp>
# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
# include <memory>
# endif
namespace luabind { namespace detail {
namespace has_get_pointer_
{
struct any
{
template<class T> any(T const&);
};
struct no_overload_tag
{};
typedef char (&yes)[1];
typedef char (&no)[2];
no_overload_tag operator,(no_overload_tag, int);
//
// On compilers with ADL, we need these generic overloads in this
// namespace as well as in luabind::. Otherwise get_pointer(any)
// will be found before them.
//
# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
template<class T>
T* get_pointer(T const volatile*);
template<class T>
T* get_pointer(std::auto_ptr<T> const&);
# endif
//
// On compilers that doesn't support ADL, the overload below has to
// live in luabind::.
//
# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
}} // namespace detail::has_get_pointer_
# endif
detail::has_get_pointer_::no_overload_tag
get_pointer(detail::has_get_pointer_::any);
# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
namespace detail { namespace has_get_pointer_
{
# endif
template<class T>
yes check(T const&);
no check(no_overload_tag);
template<class T>
struct impl
{
static typename boost::add_reference<T>::type x;
BOOST_STATIC_CONSTANT(bool,
value = sizeof(has_get_pointer_::check( (get_pointer(x),0) )) == 1
);
typedef boost::mpl::bool_<value> type;
};
} // namespace has_get_pointer_
template<class T>
struct has_get_pointer
: has_get_pointer_::impl<T>::type
{};
}} // namespace luabind::detail
#endif // LUABIND_HAS_GET_POINTER_051022_HPP

View File

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

View File

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

View File

@ -0,0 +1,70 @@
// Copyright (c) 2004 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef IS_INDIRECT_CONST_040211_HPP
#define IS_INDIRECT_CONST_040211_HPP
#include <luabind/detail/yes_no.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/mpl/bool.hpp>
namespace luabind {
namespace detail {
template<class T>
typename boost::is_const<T>::type
is_indirect_const_check(T(*)(), int);
template<class T>
typename boost::is_const<T>::type
is_indirect_const_check(T*(*)(), long);
template<class T>
typename boost::is_const<T>::type
is_indirect_const_check(T&(*)(), long);
yes_t to_yes_no(boost::mpl::true_);
no_t to_yes_no(boost::mpl::false_);
} // namespace detail
// returns true for:
// T = U* is_const<U>
// T = U& is_const<U>
// T = U is_const<U>
template<class T>
struct is_indirect_const
{
BOOST_STATIC_CONSTANT(int, value = (
sizeof(
detail::to_yes_no(
detail::is_indirect_const_check((T(*)())0, 0L)
))
== sizeof(detail::yes_t)
));
};
} // namespace luabind
#endif // IS_INDIRECT_CONST_040211_HPP

View File

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

View File

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

View File

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

View File

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

View File

@ -1,386 +0,0 @@
// Copyright (c) 2005 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_OBJECT_050419_HPP
#define LUABIND_OBJECT_050419_HPP
#include <tuple>
#include <luabind/nil.hpp>
#include <luabind/handle.hpp>
#include <luabind/from_stack.hpp>
#include <luabind/detail/stack_utils.hpp>
#include <luabind/detail/push_to_lua.hpp>
#include <luabind/typeid.hpp>
#include <luabind/detail/crtp_iterator.hpp>
#include <luabind/lua_proxy_interface.hpp>
#include <luabind/lua_index_proxy.hpp>
#include <luabind/lua_iterator_proxy.hpp>
#include <luabind/detail/class_rep.hpp>
#if LUA_VERSION_NUM < 502
# define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX)
#endif
namespace luabind {
namespace adl {
// An object holds a reference to a Lua value residing
// in the registry.
class object :
public lua_proxy_interface<object>
{
public:
object()
{}
explicit object(handle const& other)
: m_handle(other)
{}
explicit object(from_stack const& stack_reference)
: m_handle(stack_reference.interpreter, stack_reference.index)
{
}
template<class T>
object(lua_State* interpreter, T&& value)
{
detail::push_to_lua(interpreter, std::forward<T>(value));
detail::stack_pop pop(interpreter, 1);
handle(interpreter, -1).swap(m_handle);
}
template<class T, class Policies>
object(lua_State* interpreter, T&& value, Policies const&)
{
detail::push_to_lua<1, Policies>(interpreter, std::forward<T>(value));
detail::stack_pop pop(interpreter, 1);
handle(interpreter, -1).swap(m_handle);
}
void push(lua_State* interpreter) const;
lua_State* interpreter() const;
bool is_valid() const;
template<class T>
index_proxy<object> operator[](T const& key) const
{
return index_proxy<object>(
*this, m_handle.interpreter(), key
);
}
void swap(object& other)
{
m_handle.swap(other.m_handle);
}
private:
handle m_handle;
};
inline void object::push(lua_State* interpreter) const
{
m_handle.push(interpreter);
}
inline lua_State* object::interpreter() const
{
return m_handle.interpreter();
}
inline bool object::is_valid() const
{
return m_handle.interpreter() != 0;
}
} // namespace adl
using adl::object;
template<>
struct lua_proxy_traits<object>
{
using is_specialized = std::true_type;
static lua_State* interpreter(object const& value)
{
return value.interpreter();
}
static void unwrap(lua_State* interpreter, object const& value)
{
value.push(interpreter);
}
static bool check(...)
{
return true;
}
};
template<class R, typename PolicyList = no_policies, typename... Args>
R call_function(luabind::object const& obj, Args&&... args)
{
obj.push(obj.interpreter());
return call_pushed_function<R, PolicyList>(obj.interpreter(), std::forward<Args>(args)...);
}
template<class R, typename PolicyList = no_policies, typename... Args>
R resume_function(luabind::object const& obj, Args&&... args)
{
obj.push(obj.interpreter());
return resume_pushed_function<R, PolicyList>(obj.interpreter(), std::forward<Args>(args)...);
}
// declared in luabind/lua_index_proxy.hpp
template<typename Next>
adl::index_proxy<Next>::operator object()
{
detail::stack_pop pop(m_interpreter, 1);
push(m_interpreter);
return object(from_stack(m_interpreter, -1));
}
// declared in luabind/lua_proxy_interface.hpp
template<typename ProxyType>
template<typename PolicyList, typename... Args>
object adl::lua_proxy_interface<ProxyType>::call(Args&&... args)
{
return call_function<object, PolicyList>(derived(), std::forward<Args>(args)...);
}
// declared in luabind/lua_proxy_interface.hpp
template<typename ProxyType>
template<typename... Args>
object adl::lua_proxy_interface<ProxyType>::operator()(Args&&... args)
{
return call<no_policies>(std::forward<Args>(args)...);
}
// declared in luabind/lua_iterator_proxy.hpp
template<class AccessPolicy>
adl::iterator_proxy<AccessPolicy>::operator object()
{
lua_pushvalue(m_interpreter, m_key_index);
AccessPolicy::get(m_interpreter, m_table_index);
detail::stack_pop pop(m_interpreter, 1);
return object(from_stack(m_interpreter, -1));
}
// declared in luabind/lua_iterator_proxy.hpp
template<class AccessPolicy>
object detail::basic_iterator<AccessPolicy>::key() const
{
return object(m_key);
}
namespace adl {
// Simple value_wrapper adaptor with the sole purpose of helping with
// overload resolution. Use this as a function parameter type instead
// of "object" or "argument" to restrict the parameter to Lua tables.
template <class Base = object>
struct table : Base
{
table(from_stack const& stack_reference)
: Base(stack_reference)
{}
};
} // namespace adl
using adl::table;
template <class Base>
struct lua_proxy_traits<adl::table<Base> >
: lua_proxy_traits<Base>
{
static bool check(lua_State* L, int idx)
{
return lua_proxy_traits<Base>::check(L, idx) &&
lua_istable(L, idx);
}
};
inline object newtable(lua_State* interpreter)
{
lua_newtable(interpreter);
detail::stack_pop pop(interpreter, 1);
return object(from_stack(interpreter, -1));
}
// this could be optimized by returning a proxy
inline object globals(lua_State* interpreter)
{
lua_pushglobaltable(interpreter);
detail::stack_pop pop(interpreter, 1);
return object(from_stack(interpreter, -1));
}
// this could be optimized by returning a proxy
inline object registry(lua_State* interpreter)
{
lua_pushvalue(interpreter, LUA_REGISTRYINDEX);
detail::stack_pop pop(interpreter, 1);
return object(from_stack(interpreter, -1));
}
template<class ValueWrapper, class K>
inline object gettable(ValueWrapper const& table, K&& key)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(table);
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, table);
detail::stack_pop pop(interpreter, 2);
detail::push_to_lua(interpreter, std::forward<K>(key));
lua_gettable(interpreter, -2);
return object(from_stack(interpreter, -1));
}
template<class ValueWrapper, class K, class T>
inline void settable(ValueWrapper const& table, K&& key, T&& value)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(table);
// TODO: Exception safe?
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, table);
detail::stack_pop pop(interpreter, 1);
detail::push_to_lua(interpreter, std::forward<K>(key));
detail::push_to_lua(interpreter, std::forward<T>(value));
lua_settable(interpreter, -3);
}
template<class ValueWrapper, class K>
inline object rawget(ValueWrapper const& table, K&& key)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(
table
);
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, table);
detail::stack_pop pop(interpreter, 2);
detail::push_to_lua(interpreter, std::forward<K>(key));
lua_rawget(interpreter, -2);
return object(from_stack(interpreter, -1));
}
template<class ValueWrapper, class K, class T>
inline void rawset(ValueWrapper const& table, K&& key, T&& value)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(
table
);
// TODO: Exception safe?
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, table);
detail::stack_pop pop(interpreter, 1);
detail::push_to_lua(interpreter, std::forward<K>(key));
detail::push_to_lua(interpreter, std::forward<T>(value));
lua_rawset(interpreter, -3);
}
template<class ValueWrapper>
inline int type(ValueWrapper const& value)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(value);
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, value);
detail::stack_pop pop(interpreter, 1);
return lua_type(interpreter, -1);
}
template <class ValueWrapper>
inline object getmetatable(ValueWrapper const& obj)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(obj);
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, obj);
detail::stack_pop pop(interpreter, 2);
lua_getmetatable(interpreter, -1);
return object(from_stack(interpreter, -1));
}
template <class ValueWrapper1, class ValueWrapper2>
inline void setmetatable(ValueWrapper1 const& obj, ValueWrapper2 const& metatable)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper1>::interpreter(obj);
lua_proxy_traits<ValueWrapper1>::unwrap(interpreter, obj);
detail::stack_pop pop(interpreter, 1);
lua_proxy_traits<ValueWrapper2>::unwrap(interpreter, metatable);
lua_setmetatable(interpreter, -2);
}
template <class ValueWrapper>
inline std::tuple<const char*, object> getupvalue(ValueWrapper const& value, int index)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper>::interpreter(value);
lua_proxy_traits<ValueWrapper>::unwrap(interpreter, value);
detail::stack_pop pop(interpreter, 2);
const char* name = lua_getupvalue(interpreter, -1, index);
return std::make_tuple(name, object(from_stack(interpreter, -1)));
}
template <class ValueWrapper1, class ValueWrapper2>
inline void setupvalue(ValueWrapper1 const& function, int index, ValueWrapper2 const& value)
{
lua_State* interpreter = lua_proxy_traits<ValueWrapper1>::interpreter(function);
lua_proxy_traits<ValueWrapper1>::unwrap(interpreter, function);
detail::stack_pop pop(interpreter, 1);
lua_proxy_traits<ValueWrapper2>::unwrap(interpreter, value);
lua_setupvalue(interpreter, -2, index);
}
template <class GetValueWrapper>
object property(GetValueWrapper const& get)
{
lua_State* interpreter = lua_proxy_traits<GetValueWrapper>::interpreter(get);
lua_proxy_traits<GetValueWrapper>::unwrap(interpreter, get);
lua_pushnil(interpreter);
lua_pushcclosure(interpreter, &detail::property_tag, 2);
detail::stack_pop pop(interpreter, 1);
return object(from_stack(interpreter, -1));
}
template <class GetValueWrapper, class SetValueWrapper>
object property(GetValueWrapper const& get, SetValueWrapper const& set)
{
lua_State* interpreter = lua_proxy_traits<GetValueWrapper>::interpreter(get);
lua_proxy_traits<GetValueWrapper>::unwrap(interpreter, get);
lua_proxy_traits<SetValueWrapper>::unwrap(interpreter, set);
lua_pushcclosure(interpreter, &detail::property_tag, 2);
detail::stack_pop pop(interpreter, 1);
return object(from_stack(interpreter, -1));
}
} // namespace luabind
#if LUA_VERSION_NUM < 502
#undef lua_pushglobaltable
#endif
#include <luabind/detail/conversion_policies/conversion_policies.hpp>
#endif // LUABIND_OBJECT_050419_HPP

View File

@ -0,0 +1,52 @@
// Copyright (c) 2005 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#if !BOOST_PP_IS_ITERATING
# error Do not include object_call.hpp directly!
#endif
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#define N BOOST_PP_ITERATION()
template<BOOST_PP_ENUM_PARAMS(N, class A)>
call_proxy<
Derived
, boost::tuples::tuple<
BOOST_PP_ENUM_BINARY_PARAMS(N, A, const* BOOST_PP_INTERCEPT)
>
> operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a))
{
typedef boost::tuples::tuple<
BOOST_PP_ENUM_BINARY_PARAMS(N, A, const* BOOST_PP_INTERCEPT)
> arguments;
return call_proxy<Derived, arguments>(
derived()
, arguments(BOOST_PP_ENUM_PARAMS(N, &a))
);
}
#undef N

View File

@ -0,0 +1,224 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_OBJECT_PROXY_HPP_INCLUDED
#define LUABIND_OBJECT_PROXY_HPP_INCLUDED
#include <boost/optional.hpp>
#include <luabind/config.hpp>
#include <luabind/detail/policy.hpp>
#include <luabind/error.hpp>
#include <luabind/detail/convert_to_lua.hpp>
#include <luabind/detail/debug.hpp>
#include <luabind/detail/stack_utils.hpp>
#include <boost/mpl/apply_wrap.hpp>
namespace luabind
{
namespace detail
{
namespace mpl = boost::mpl;
template<class T, class Obj, class Policies>
inline T object_cast_impl(const Obj& obj, const Policies&)
{
if (obj.lua_state() == 0)
{
#ifndef LUABIND_NO_EXCEPTIONS
throw cast_failed(0, typeid(T));
#else
lua_State* L = obj.lua_state();
cast_failed_callback_fun e = get_cast_failed_callback();
if (e) e(L, typeid(T));
assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()");
std::terminate();
#endif
}
LUABIND_CHECK_STACK(obj.lua_state());
typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy;
typename mpl::apply_wrap2<converter_policy,T,lua_to_cpp>::type converter;
obj.pushvalue();
lua_State* L = obj.lua_state();
detail::stack_pop p(L, 1);
#ifndef LUABIND_NO_ERROR_CHECKING
if (converter.match(L, LUABIND_DECORATE_TYPE(T), -1) < 0)
{
#ifndef LUABIND_NO_EXCEPTIONS
throw cast_failed(L, typeid(T));
#else
cast_failed_callback_fun e = get_cast_failed_callback();
if (e) e(L, typeid(T));
assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()");
std::terminate();
#endif
}
#endif
return converter.apply(L, LUABIND_DECORATE_TYPE(T), -1);
}
template<class T, class Obj, class Policies>
boost::optional<T> object_cast_nothrow_impl(const Obj& obj, const Policies&)
{
typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy;
typename mpl::apply_wrap2<converter_policy,T,lua_to_cpp>::type converter;
if (obj.lua_state() == 0) return boost::optional<T>();
LUABIND_CHECK_STACK(obj.lua_state());
obj.pushvalue();
lua_State* L = obj.lua_state();
detail::stack_pop p(L, 1);
#ifndef LUABIND_NO_ERROR_CHECKING
if (converter.match(L, LUABIND_DECORATE_TYPE(T), -1) < 0)
return boost::optional<T>();
#endif
return boost::optional<T>(converter.apply(L, LUABIND_DECORATE_TYPE(T), -1));
}
}
template<class T>
T object_cast(const object& obj)
{ return detail::object_cast_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
T object_cast(const object& obj, const Policies& p)
{ return detail::object_cast_impl<T>(obj, p); }
template<class T>
boost::optional<T> object_cast_nothrow(const object& obj)
{ return detail::object_cast_nothrow_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
boost::optional<T> object_cast_nothrow(const object& obj, const Policies& p)
{ return detail::object_cast_nothrow_impl<T>(obj, p); }
template<class T>
T object_cast(const detail::proxy_object& obj)
{ return detail::object_cast_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
T object_cast(const detail::proxy_object& obj, const Policies& p)
{ return detail::object_cast_impl<T>(obj, p); }
template<class T>
boost::optional<T> object_cast_nothrow(const detail::proxy_object& obj)
{ return detail::object_cast_nothrow_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
boost::optional<T> object_cast_nothrow(const detail::proxy_object& obj, const Policies& p)
{ return detail::object_cast_nothrow_impl<T>(obj, p); }
template<class T>
T object_cast(const detail::proxy_raw_object& obj)
{ return detail::object_cast_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
T object_cast(const detail::proxy_raw_object& obj, const Policies& p)
{ return detail::object_cast_impl<T>(obj, p); }
template<class T>
boost::optional<T> object_cast_nothrow(const detail::proxy_raw_object& obj)
{ return detail::object_cast_nothrow_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
boost::optional<T> object_cast_nothrow(const detail::proxy_raw_object& obj, const Policies& p)
{ return detail::object_cast_nothrow_impl<T>(obj, p); }
template<class T>
T object_cast(const detail::proxy_array_object& obj)
{ return detail::object_cast_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
T object_cast(const detail::proxy_array_object& obj, const Policies& p)
{ return detail::object_cast_impl<T>(obj, p); }
template<class T>
boost::optional<T> object_cast_nothrow(const detail::proxy_array_object& obj)
{ return detail::object_cast_nothrow_impl<T>(obj, detail::null_type()); }
template<class T, class Policies>
boost::optional<T> object_cast_nothrow(const detail::proxy_array_object& obj, const Policies& p)
{ return detail::object_cast_nothrow_impl<T>(obj, p); }
inline object get_globals(lua_State* L)
{
lua_pushvalue(L, LUA_GLOBALSINDEX);
detail::lua_reference ref;
ref.set(L);
return object(L, ref, true/*object::reference()*/);
}
inline object get_registry(lua_State* L)
{
lua_pushvalue(L, LUA_REGISTRYINDEX);
detail::lua_reference ref;
ref.set(L);
return object(L, ref, true/*object::reference()*/);
}
inline object newtable(lua_State* L)
{
lua_newtable(L);
detail::lua_reference ref;
ref.set(L);
return object(L, ref, true/*object::reference()*/);
}
}
/*
struct A
{
};
object f = class_<A>();
A* ptr = object_cast<A*>(f(), adopt(_1));
delete ptr;
*/
#endif // LUABIND_OBJECT_PROXY_HPP_INCLUDED

View File

@ -24,15 +24,15 @@
#ifndef LUABIND_OBJECT_REP_HPP_INCLUDED #ifndef LUABIND_OBJECT_REP_HPP_INCLUDED
#define LUABIND_OBJECT_REP_HPP_INCLUDED #define LUABIND_OBJECT_REP_HPP_INCLUDED
#include <boost/aligned_storage.hpp>
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/detail/class_rep.hpp>
#include <luabind/detail/instance_holder.hpp> #include <luabind/detail/instance_holder.hpp>
#include <luabind/detail/ref.hpp> #include <luabind/detail/ref.hpp>
#include <type_traits> // std::aligned_storage
#include <cstdlib> #include <cstdlib>
namespace luabind { namespace luabind { namespace detail
namespace detail { {
class class_rep;
void finalize(lua_State* L, class_rep* crep); void finalize(lua_State* L, class_rep* crep);
@ -51,12 +51,13 @@ namespace luabind {
void set_instance(instance_holder* instance) { m_instance = instance; } void set_instance(instance_holder* instance) { m_instance = instance; }
void add_dependency(lua_State* L, int index); void add_dependency(lua_State* L, int index);
void release_dependency_refs(lua_State* L);
std::pair<void*, int> get_instance(class_id target) const std::pair<void*, int> get_instance(class_id target) const
{ {
if(m_instance == 0) if (m_instance == 0)
return std::pair<void*, int>(nullptr, -1); return std::pair<void*, int>((void*)0, -1);
return m_instance->get(m_classrep->casts(), target); return m_instance->get(target);
} }
bool is_const() const bool is_const() const
@ -66,39 +67,36 @@ namespace luabind {
void release() void release()
{ {
if(m_instance) if (m_instance)
m_instance->release(); m_instance->release();
} }
void* allocate(std::size_t size) void* allocate(std::size_t size)
{ {
if(size <= 32) { if (size <= 32)
return &m_instance_buffer; return &m_instance_buffer;
}
else {
return std::malloc(size); return std::malloc(size);
} }
}
void deallocate(void* storage) void deallocate(void* storage)
{ {
if(storage == &m_instance_buffer) { if (storage == &m_instance_buffer)
return; return;
}
else {
std::free(storage); std::free(storage);
} }
}
private: private:
object_rep(object_rep const&) = delete;
void operator=(object_rep const&) = delete; object_rep(object_rep const&)
{}
void operator=(object_rep const&)
{}
instance_holder* m_instance; instance_holder* m_instance;
std::aligned_storage<32>::type m_instance_buffer; boost::aligned_storage<32> m_instance_buffer;
class_rep* m_classrep; // the class information about this object's type class_rep* m_classrep; // the class information about this object's type
detail::lua_reference m_dependency_ref; // reference to lua table holding dependency references std::size_t m_dependency_cnt; // counts dependencies
}; };
template<class T> template<class T>
@ -129,9 +127,7 @@ namespace luabind {
LUABIND_API void push_instance_metatable(lua_State* L); LUABIND_API void push_instance_metatable(lua_State* L);
LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls); LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls);
} // namespace detail }}
} // namespace luabind
#endif // LUABIND_OBJECT_REP_HPP_INCLUDED #endif // LUABIND_OBJECT_REP_HPP_INCLUDED

View File

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

View File

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

View File

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

View File

@ -0,0 +1,54 @@
// Copyright (c) 2004 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef POINTEE_SIZEOF_040211_HPP
#define POINTEE_SIZEOF_040211_HPP
#include <boost/mpl/int.hpp>
namespace luabind {
namespace detail {
template<class T> T& deref_type(T(*)(), int);
template<class T> T& deref_type(T*(*)(), long);
} // namespace detail
// returns the indirect sizeof U, as in
// sizeof(T*) = sizeof(T)
// sizeof(T&) = sizeof(T)
// sizeof(T) = sizeof(T)
template<class T>
struct pointee_sizeof
{
BOOST_STATIC_CONSTANT(int, value = (
sizeof(detail::deref_type((T(*)())0), 0L)
));
typedef boost::mpl::int_<value> type;
};
} // namespace luabind
#endif // POINTEE_SIZEOF_040211_HPP

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -5,12 +5,11 @@
#ifndef LUABIND_PROPERTY_081020_HPP #ifndef LUABIND_PROPERTY_081020_HPP
# define LUABIND_PROPERTY_081020_HPP # define LUABIND_PROPERTY_081020_HPP
namespace luabind { namespace luabind { namespace detail {
namespace detail {
template <class Class, class T, class Result = T> template <class Class, class T, class Result = T>
struct access_member_ptr struct access_member_ptr
{ {
access_member_ptr(T Class::* mem_ptr) access_member_ptr(T Class::* mem_ptr)
: mem_ptr(mem_ptr) : mem_ptr(mem_ptr)
{} {}
@ -26,10 +25,9 @@ namespace luabind {
} }
T Class::* mem_ptr; T Class::* mem_ptr;
}; };
} // namespace detail }} // namespace luabind::detail
} // namespace luabind
#endif // LUABIND_PROPERTY_081020_HPP #endif // LUABIND_PROPERTY_081020_HPP

View File

@ -1,74 +0,0 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_CONVERT_TO_LUA_HPP_INCLUDED
#define LUABIND_CONVERT_TO_LUA_HPP_INCLUDED
#include <luabind/config.hpp>
#include <luabind/detail/policy.hpp>
#include <luabind/detail/type_traits.hpp>
namespace luabind {
namespace detail {
template< typename T >
struct unwrapped {
static const bool is_wrapped_ref = false;
using type = T;
static const T& get(const T& t) {
return t;
}
};
template< typename T >
struct unwrapped< std::reference_wrapper< T > >
{
static const bool is_wrapped_ref = true;
using type = T&;
static T& get(const std::reference_wrapper<T>& refwrap)
{
return refwrap.get();
}
};
template<typename T>
using unwrapped_t = typename unwrapped< T >::type;
template<unsigned int PolicyIndex = 1, typename Policies = no_policies, typename T>
void push_to_lua(lua_State* L, T&& v)
{
using value_type = unwrapped_t<remove_const_reference_t<T>>;
specialized_converter_policy_n<PolicyIndex, Policies, value_type, cpp_to_lua>()
.to_lua(L, unwrapped<T>::get(v));
}
}
}
#endif

View File

@ -33,8 +33,8 @@
namespace luabind namespace luabind
{ {
namespace detail namespace detail
{ {
struct lua_reference struct lua_reference
{ {
@ -46,7 +46,7 @@ namespace luabind
: L(r.L) : L(r.L)
, m_ref(LUA_NOREF) , m_ref(LUA_NOREF)
{ {
if(!r.is_valid()) return; if (!r.is_valid()) return;
r.get(L); r.get(L);
set(L); set(L);
} }
@ -58,15 +58,13 @@ namespace luabind
{ {
// TODO: self assignment problems // TODO: self assignment problems
reset(); reset();
if(!r.is_valid()) return; if (!r.is_valid()) return;
r.get(r.state()); r.get(r.state());
set(r.state()); set(r.state());
} }
bool is_valid() const bool is_valid() const
{ { return m_ref != LUA_NOREF; }
return m_ref != LUA_NOREF;
}
void set(lua_State* L_) void set(lua_State* L_)
{ {
@ -93,7 +91,7 @@ namespace luabind
void reset() void reset()
{ {
if(L && m_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, m_ref); if (L && m_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, m_ref);
m_ref = LUA_NOREF; m_ref = LUA_NOREF;
} }
@ -108,8 +106,7 @@ namespace luabind
int m_ref; int m_ref;
}; };
} }}
}
#endif // LUABIND_REF_HPP_INCLUDED #endif // LUABIND_REF_HPP_INCLUDED

View File

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

View File

@ -23,14 +23,10 @@
#ifndef LUABIND_STACK_UTILS_HPP_INCLUDED #ifndef LUABIND_STACK_UTILS_HPP_INCLUDED
#define LUABIND_STACK_UTILS_HPP_INCLUDED #define LUABIND_STACK_UTILS_HPP_INCLUDED
#ifndef LUA_INCLUDE_HPP_INCLUDED
#include <luabind/lua_include.hpp>
#endif
#include <cassert> #include <cassert>
namespace luabind { namespace luabind { namespace detail
namespace detail { {
struct stack_pop struct stack_pop
{ {
@ -50,9 +46,7 @@ namespace luabind {
lua_State* m_state; lua_State* m_state;
int m_n; int m_n;
}; };
}}
} // namespace detail
} // namespace luabind
#endif // LUABIND_STACK_UTILS_HPP_INCLUDED #endif // LUABIND_STACK_UTILS_HPP_INCLUDED

View File

@ -1,189 +0,0 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_TYPETRAITS_HPP_INCLUDED
#define LUABIND_TYPETRAITS_HPP_INCLUDED
#include <type_traits>
#include <functional> // reference_wrapper
#include <luabind/detail/meta.hpp>
namespace luabind {
namespace detail {
template< typename T >
struct is_const_reference
: public std::conditional< std::is_reference<T>::value && std::is_const<typename std::remove_reference<T>::type>::value, std::true_type, std::false_type >::type
{
};
template<class T>
struct is_nonconst_reference
: public std::conditional< std::is_reference<T>::value && !std::is_const<typename std::remove_reference<T>::type>::value, std::true_type, std::false_type >::type
{
};
template<class T>
struct is_const_pointer
: public std::conditional< std::is_const<typename std::remove_pointer<T>::type>::value && std::is_pointer<T>::value, std::true_type, std::false_type >::type
{
};
template<class T>
struct is_nonconst_pointer :
public std::conditional < std::is_pointer<T>::value && !std::is_const<typename std::remove_pointer<T>::type>::value, std::true_type, std::false_type >::type
{
};
template<int v1, int v2>
struct max_c
{
enum { value = (v1 > v2) ? v1 : v2 };
};
} // namespace detail
template< typename T >
struct remove_const_reference {
using type = typename std::remove_const<typename std::remove_reference<T>::type>::type;
};
template< typename T >
using remove_const_reference_t = typename remove_const_reference<T>::type;
//
// most_derived
//
template<class A, class B>
struct most_derived
{
using type = typename std::conditional<
std::is_base_of<A, B>::value
, B
, A
>::type;
};
template< typename A, typename B >
using most_derived_t = typename most_derived<A, B>::type;
//
// null_type
//
struct null_type {};
template< typename T >
struct is_null_type : public std::false_type {};
template< >
struct is_null_type< null_type > : public std::true_type {};
//
// deduce_signature
//
template< typename, typename > struct tagged_function;
template< typename T, typename WrappedType = null_type >
struct deduce_signature;
template< typename R, typename... Args, typename WrappedType >
struct deduce_signature < R(Args...), WrappedType >
{
using type = meta::type_list< R, Args... >;
};
template< typename R, typename... Args, typename WrappedType >
struct deduce_signature < R(*)(Args...), WrappedType >
{
using type = meta::type_list< R, Args... >;
};
template< typename R, typename Class, typename... Args >
struct deduce_signature < R(Class::*)(Args...), null_type >
{
using type = meta::type_list< R, Class&, Args... >;
};
template< typename R, typename Class, typename... Args >
struct deduce_signature < R(Class::*)(Args...) const, null_type >
{
using type = meta::type_list< R, Class const&, Args... >;
};
template< typename R, typename Class, typename... Args, class WrappedType >
struct deduce_signature < R(Class::*)(Args...), WrappedType >
{
using type = meta::type_list< R, typename most_derived<Class, WrappedType>::type&, Args... >;
};
template< typename R, typename Class, typename... Args, class WrappedType >
struct deduce_signature < R(Class::*)(Args...) const, WrappedType >
{
using type = meta::type_list< R, typename most_derived<Class, WrappedType>::type const&, Args... >;
};
template< typename Signature, typename F, class WrappedType >
struct deduce_signature< tagged_function< Signature, F >, WrappedType >
{
using type = Signature;
};
template< typename T, typename WrappedType = null_type >
using deduce_signature_t = typename deduce_signature<T, WrappedType>::type;
//
// is_reference_wrapper
//
template< typename T > struct is_reference_wrapper : public std::false_type { };
template< typename T > struct is_reference_wrapper< std::reference_wrapper<T> > : public std::true_type { };
//
// apply_reference_wrapper
//
template< typename T > struct apply_reference_wrapper { using type = T; };
template< typename T > struct apply_reference_wrapper< std::reference_wrapper<T> > { using type = T&; };
template< typename T >
using apply_reference_wrapper_t = typename apply_reference_wrapper<T>::type;
//
// identity
//
template< typename T > struct identity { using type = T; };
template< typename T >
using identity_t = typename identity<T>::type;
template< typename Dst > Dst implicit_cast(typename identity<Dst>::type t) { return t; }
} // namespace luabind
#endif // LUABIND_TYPETRAITS_HPP_INCLUDED

View File

@ -0,0 +1,190 @@
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUABIND_TYPETRAITS_HPP_INCLUDED
#define LUABIND_TYPETRAITS_HPP_INCLUDED
#include <luabind/config.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_const.hpp>
#include <luabind/detail/primitives.hpp>
namespace luabind { namespace detail
{
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<class T>
struct is_const_type
{
typedef typename boost::mpl::if_<boost::is_const<T>
, yes_t
, no_t
>::type type;
};
template<bool is_Reference = false>
struct is_const_reference_helper
{
template<class>
struct apply
{
enum
{
value = false
};
};
};
template<class T>
typename is_const_type<T>::type is_const_reference_tester(T&);
no_t is_const_reference_tester(...);
template<>
struct is_const_reference_helper<true>
{
template<class T>
struct apply
{
static T getT();
enum
{
value = sizeof(is_const_reference_tester(getT())) == sizeof(yes_t)
};
};
};
template<class T>
struct is_const_reference
: is_const_reference_helper<boost::is_reference<T>::value>::template apply<T>
{
typedef boost::mpl::bool_<value> type;
};
#else
template<class T>
struct is_const_reference
{
enum { value = false };
typedef boost::mpl::bool_<value> type;
};
template<class T>
struct is_const_reference<const T&>
{
enum { value = true };
typedef boost::mpl::bool_<value> type;
};
#endif
template<class T>
struct is_nonconst_reference
{
enum
{
value = boost::is_reference<T>::value && !is_const_reference<T>::value
};
typedef boost::mpl::bool_<value> type;
};
template<class A>
yes_t is_const_pointer_helper(void(*)(const A*));
no_t is_const_pointer_helper(...);
template<class T>
struct is_const_pointer
{
enum { value = sizeof(is_const_pointer_helper((void(*)(T))0)) == sizeof(yes_t) };
typedef boost::mpl::bool_<value> type;
};
template<class A>
yes_t is_nonconst_pointer_helper(void(*)(A*));
no_t is_nonconst_pointer_helper(...);
template<class T>
struct is_nonconst_pointer
{
enum { value = sizeof(is_nonconst_pointer_helper((void(*)(T))0)) == sizeof(yes_t) && !is_const_pointer<T>::value };
typedef boost::mpl::bool_<value> type;
};
/*
template<class T>
struct is_constructable_from_helper
{
static yes_t check(const T&);
static no_t check(...);
};
template<class T, class From>
struct is_constructable_from
{
static From getFrom();
enum
{
value = sizeof(is_constructable_from_helper<T>::check(getFrom())) == sizeof(yes_t)
};
};
template<class T>
struct is_const_member_function_helper
{
static no_t test(...);
template<class R>
static yes_t test(R(T::*)() const);
template<class R, class A1>
static yes_t test(R(T::*)(A1) const);
template<class R, class A1, class A2>
static yes_t test(R(T::*)(A1,A2) const);
template<class R, class A1, class A2, class A3>
static yes_t test(R(T::*)(A1,A2,A3) const);
};
template<class T, class U>
struct is_const_member_function
{
static U getU();
enum
{
value = sizeof(is_const_member_function_helper<T>::test(getU())) == sizeof(yes_t)
};
};
*/
template<int v1, int v2>
struct max_c
{
enum { value = (v1>v2)?v1:v2 };
};
}}
#endif // LUABIND_TYPETRAITS_HPP_INCLUDED

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,56 +0,0 @@
/** @file
@brief Header
@date 2012
@author
Ryan Pavlik
<rpavlik@iastate.edu> and <abiryan@ryand.net>
http://academic.cleardefinition.com/
Iowa State University Virtual Reality Applications Center
Human-Computer Interaction Graduate Program
*/
// Copyright Iowa State University 2012.
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef INCLUDED_function_introspection_hpp_GUID_b55783e7_e6da_4816_925e_9256245c1065
#define INCLUDED_function_introspection_hpp_GUID_b55783e7_e6da_4816_925e_9256245c1065
// Internal Includes
#include <luabind/config.hpp>
#include <luabind/lua_state_fwd.hpp>
// Library/third-party includes
// - none
// Standard includes
// - none
namespace luabind {
LUABIND_API int bind_function_introspection(lua_State * L);
} // end of namespace luabind
#endif // INCLUDED_function_introspection_hpp_GUID_b55783e7_e6da_4816_925e_9256245c1065

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,56 @@
// Copyright (c) 2004 Daniel Wallin and Arvid Norberg
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef LUA_502_HPP
#define LUA_502_HPP
#if LUA_VERSION_NUM >= 502
inline LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
{
return lua_compare(L, idx1, idx2, LUA_OPEQ);
}
inline LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2)
{
return lua_compare(L, idx1, idx2, LUA_OPLT);
}
#undef lua_strlen
#define lua_strlen lua_rawlen
#undef lua_getfenv
#define lua_getfenv lua_getuservalue
#undef lua_setfenv
#define lua_setfenv lua_setuservalue
#undef lua_open
#define lua_open luaL_newstate
#else // LUA_VERSION_NUM >= 502
#define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX)
#endif // LUA_VERSION_NUM >= 502
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -32,7 +32,8 @@ namespace luabind
struct nil_type {}; struct nil_type {};
} }
constexpr detail::nil_type nil; // defined in class.cpp
extern LUABIND_API detail::nil_type nil;
} }
#endif #endif

View File

@ -1,28 +0,0 @@
// 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 <luabind/detail/policy.hpp>
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<call_policy_injector<detail::no_dependency_policy>>;
} // namespace luabind
#endif // LUABIND_NO_DEPENDENCY_100324_HPP

File diff suppressed because it is too large Load Diff

View File

@ -26,8 +26,6 @@
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/lua_state_fwd.hpp>
namespace luabind { namespace luabind {
LUABIND_API void open(lua_State* L); LUABIND_API void open(lua_State* L);

View File

@ -23,6 +23,15 @@
#ifndef OPERATOR_040729_HPP #ifndef OPERATOR_040729_HPP
#define OPERATOR_040729_HPP #define OPERATOR_040729_HPP
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/apply_wrap.hpp>
#include <boost/preprocessor/repetition/enum_trailing.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/type_traits/is_same.hpp>
#include <luabind/detail/other.hpp>
#include <luabind/raw_policy.hpp>
#if defined(__GNUC__) && __GNUC__ < 3 #if defined(__GNUC__) && __GNUC__ < 3
# define LUABIND_NO_STRINGSTREAM # define LUABIND_NO_STRINGSTREAM
#else #else
@ -37,83 +46,59 @@
#include <sstream> #include <sstream>
#endif #endif
#include <luabind/detail/meta.hpp> namespace luabind { namespace detail {
#include <luabind/lua_include.hpp>
#include <luabind/detail/other.hpp>
#include <luabind/detail/policy.hpp>
namespace luabind {
namespace detail {
template<class W, class T> struct unwrap_parameter_type; template<class W, class T> struct unwrap_parameter_type;
template<class Derived> struct operator_ {}; template<class Derived> struct operator_ {};
struct operator_void_return {}; struct operator_void_return {};
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
template<class T> template<class T>
inline T const& operator,(T const& x, operator_void_return) inline T const& operator,(T const& x, operator_void_return)
{ {
return x; return x;
} }
#endif
template<class Policies> }} // namespace luabind
inline void operator_result(lua_State*, operator_void_return, Policies*)
{
}
template<class T, class Policies> namespace luabind { namespace operators {
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);
}
} #define BOOST_PP_ITERATION_PARAMS_1 (3, \
} // namespace luabind (0, LUABIND_MAX_ARITY, <luabind/detail/call_operator_iterate.hpp>))
#include BOOST_PP_ITERATE()
}} // namespace luabind::operators
namespace luabind { #include <boost/preprocessor/iteration/local.hpp>
namespace operators {
template<class Self, typename... Args>
struct call_operator
: detail::operator_ < call_operator< Self, Args... > >
{
call_operator(int) {}
template<class T, class Policies>
struct apply
{
static void execute(
lua_State* L
, typename detail::unwrap_parameter_type<T, Self>::type self
, typename detail::unwrap_parameter_type<T, Args>::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 { namespace luabind {
template<class Derived> template<class Derived>
struct self_base struct self_base
{ {
template< typename... Args > operators::call_operator0<Derived> operator()() const
operators::call_operator<Derived, Args...> operator()(const Args&...) const
{ {
return 0; return 0;
} }
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class A)> \
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; \
}
#define BOOST_PP_LOCAL_LIMITS (1, LUABIND_MAX_ARITY)
#include BOOST_PP_LOCAL_ITERATE()
}; };
struct self_type : self_base<self_type> struct self_type : self_base<self_type>
@ -124,16 +109,20 @@ namespace luabind {
{ {
}; };
namespace detail { namespace detail {
template<class W, class T> template<class W, class T>
struct unwrap_parameter_type struct unwrap_parameter_type
{ {
using type = typename meta::select_ < typedef typename boost::mpl::eval_if<
meta::case_< std::is_same<T, self_type>, W& >, boost::is_same<T, self_type>
meta::case_< std::is_same<T, const_self_type >, W const& >, , boost::mpl::identity<W&>
meta::default_< typename unwrap_other<T>::type > , boost::mpl::eval_if<
> ::type; boost::is_same<T, const_self_type>
, boost::mpl::identity<W const&>
, unwrap_other<T>
>
>::type type;
}; };
template<class Derived, class A, class B> template<class Derived, class A, class B>
@ -145,8 +134,8 @@ namespace luabind {
template<class T, class Policies> template<class T, class Policies>
struct apply struct apply
{ {
using arg0 = typename unwrap_parameter_type<T, A>::type; typedef typename unwrap_parameter_type<T, A>::type arg0;
using arg1 = typename unwrap_parameter_type<T, B>::type; typedef typename unwrap_parameter_type<T, B>::type arg1;
static void execute(lua_State* L, arg0 _0, arg1 _1) static void execute(lua_State* L, arg0 _0, arg1 _1)
{ {
@ -170,7 +159,7 @@ namespace luabind {
template<class T, class Policies> template<class T, class Policies>
struct apply struct apply
{ {
using arg0 = typename unwrap_parameter_type<T, A>::type; typedef typename unwrap_parameter_type<T, A>::type arg0;
static void execute(lua_State* L, arg0 _0) static void execute(lua_State* L, arg0 _0)
{ {
@ -184,8 +173,27 @@ namespace luabind {
} }
}; };
template<class Policies>
inline void operator_result(lua_State* L, operator_void_return, Policies*)
{
} }
} // namespace detail::luabind
namespace mpl = boost::mpl;
template<class T, class Policies>
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<cv_policy,T,cpp_to_lua>::type cv;
cv.apply(L, x);
}
}} // namespace detail::luabind
namespace luabind { namespace luabind {
@ -276,14 +284,13 @@ namespace luabind {
LUABIND_BINARY_OPERATOR(add, +) LUABIND_BINARY_OPERATOR(add, +)
LUABIND_BINARY_OPERATOR(sub, -) LUABIND_BINARY_OPERATOR(sub, -)
LUABIND_BINARY_OPERATOR(mul, *) LUABIND_BINARY_OPERATOR(mul, *)
LUABIND_BINARY_OPERATOR(div, / ) LUABIND_BINARY_OPERATOR(div, /)
LUABIND_BINARY_OPERATOR(mod, %)
LUABIND_BINARY_OPERATOR(pow, ^) LUABIND_BINARY_OPERATOR(pow, ^)
LUABIND_BINARY_OPERATOR(lt, < ) LUABIND_BINARY_OPERATOR(lt, <)
LUABIND_BINARY_OPERATOR(le, <= ) LUABIND_BINARY_OPERATOR(le, <=)
LUABIND_BINARY_OPERATOR(eq, == ) LUABIND_BINARY_OPERATOR(eq, ==)
#undef LUABIND_BINARY_OPERATOR #undef LUABIND_UNARY_OPERATOR
#define LUABIND_UNARY_OPERATOR(name_, op, fn) \ #define LUABIND_UNARY_OPERATOR(name_, op, fn) \
namespace operators { \ namespace operators { \
@ -333,12 +340,14 @@ namespace luabind {
LUABIND_UNARY_OPERATOR(tostring, tostring_operator, tostring) LUABIND_UNARY_OPERATOR(tostring, tostring_operator, tostring)
LUABIND_UNARY_OPERATOR(unm, -, operator-) LUABIND_UNARY_OPERATOR(unm, -, operator-)
#undef LUABIND_UNARY_OPERATOR #undef LUABIND_BINARY_OPERATOR
namespace {
extern LUABIND_API self_type self; LUABIND_ANONYMOUS_FIX self_type self;
extern LUABIND_API const_self_type const_self; LUABIND_ANONYMOUS_FIX const_self_type const_self;
} // namespace unnamed
} // namespace luabind } // namespace luabind

View File

@ -25,21 +25,36 @@
#define LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED #define LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/detail/policy.hpp> // for find_conversion_policy, etc #include <luabind/detail/policy.hpp>
#include <luabind/detail/decorate_type.hpp> // for decorated_type #include <boost/mpl/apply_wrap.hpp>
#include <luabind/detail/primitives.hpp> // for by_pointer, by_reference, etc
#include <luabind/detail/type_traits.hpp> // for is_nonconst_pointer, is_nonconst_reference, etc
#include <new> // for operator new
namespace luabind {
namespace detail {
namespace luabind { namespace detail
{
template<int N> template<int N>
struct char_array struct char_array
{ {
char storage[N]; char storage[N];
}; };
#if defined(__GNUC__) && ( __GNUC__ == 3 && __GNUC_MINOR__ == 1 )
template<class U>
char_array<sizeof(U)> indirect_sizeof_test(by_reference<U>);
template<class U>
char_array<sizeof(U)> indirect_sizeof_test(by_const_reference<U>);
template<class U>
char_array<sizeof(U)> indirect_sizeof_test(by_pointer<U>);
template<class U>
char_array<sizeof(U)> indirect_sizeof_test(by_const_pointer<U>);
template<class U>
char_array<sizeof(U)> indirect_sizeof_test(by_value<U>);
#else
template<class U> template<class U>
char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_reference<U>); char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_reference<U>);
@ -55,150 +70,114 @@ namespace luabind {
template<class U> template<class U>
char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_value<U>); char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_value<U>);
#endif
template<class T> template<class T>
struct indirect_sizeof struct indirect_sizeof
{ {
static const int value = sizeof(indirect_sizeof_test(decorate_type_t<T>())); BOOST_STATIC_CONSTANT(int, value = sizeof(indirect_sizeof_test(LUABIND_DECORATE_TYPE(T))));
}; };
namespace out_value_detail { namespace mpl = boost::mpl;
template< int Size > template<int Size, class Policies = detail::null_type>
struct temporary_storage_size {
template< typename T, typename... Args >
void construct(Args&&... args)
{
new (&m_storage) T(std::forward<Args>(args)...);
}
template<typename T>
T& get() {
return *reinterpret_cast<T*>(&m_storage);
}
template<typename T>
const T& get() const {
return *reinterpret_cast<T*>(&m_storage);
}
template<typename T>
void destroy()
{
get<T>().~T();
}
typename std::aligned_storage<Size>::type m_storage;
};
template< typename T >
struct temporary_storage_type {
template< typename... Args >
void construct(Args&&... args)
{
new (&m_storage) T(std::forward<Args>(args)...);
}
T& get() {
return *reinterpret_cast<T*>(&m_storage);
}
const T& get() const {
return *reinterpret_cast<T*>(&m_storage);
}
void destroy()
{
get().~T();
}
typename std::aligned_storage<sizeof(T), alignof(T)>::type m_storage;
};
}
// See note in out_value_policy about why we're not templating
// for the parameter type.
template<typename T, class Policies = no_policies>
struct out_value_converter struct out_value_converter
{ {
enum { consumed_args = 1 }; int const consumed_args(...)
T& to_cpp(lua_State* L, by_reference<T>, int index)
{ {
//specialized_converter_policy_n<1, Policies, T, lua_to_cpp> converter; return 1;
storage_.construct(converter_.to_cpp(L, decorate_type_t<T>(), index));
return storage_.get();
} }
int match(lua_State* L, by_reference<T>, int index) template<class T>
T& apply(lua_State* L, by_reference<T>, int index)
{ {
return converter_.match(L, decorate_type_t<T>(), index); typedef typename find_conversion_policy<1, Policies>::type converter_policy;
typename mpl::apply_wrap2<converter_policy,T,lua_to_cpp>::type converter;
new (m_storage) T(converter.apply(L, LUABIND_DECORATE_TYPE(T), index));
return *reinterpret_cast<T*>(m_storage);
} }
template<class T>
static int match(lua_State* L, by_reference<T>, int index)
{
typedef typename find_conversion_policy<1, Policies>::type converter_policy;
typedef typename mpl::apply_wrap2<converter_policy,T,lua_to_cpp>::type converter;
return converter::match(L, LUABIND_DECORATE_TYPE(T), index);
}
template<class T>
void converter_postcall(lua_State* L, by_reference<T>, int) void converter_postcall(lua_State* L, by_reference<T>, int)
{ {
//specialized_converter_policy_n<2,Policies,T,cpp_to_lua> converter; typedef typename find_conversion_policy<2, Policies>::type converter_policy;
converter_.to_lua(L, storage_.get()); typename mpl::apply_wrap2<converter_policy,T,cpp_to_lua>::type converter;
storage_.destroy(); converter.apply(L, *reinterpret_cast<T*>(m_storage));
reinterpret_cast<T*>(m_storage)->~T();
} }
T* to_cpp(lua_State* L, by_pointer<T>, int index) template<class T>
T* apply(lua_State* L, by_pointer<T>, int index)
{ {
storage_.construct(converter_.to_cpp(L, decorate_type_t<T>(), index)); typedef typename find_conversion_policy<1, Policies>::type converter_policy;
return &storage_.get(); typename mpl::apply_wrap2<converter_policy,T,lua_to_cpp>::type converter;
new (m_storage) T(converter.apply(L, LUABIND_DECORATE_TYPE(T), index));
return reinterpret_cast<T*>(m_storage);
} }
int match(lua_State* L, by_pointer<T>, int index) template<class T>
static int match(lua_State* L, by_pointer<T>, int index)
{ {
return converter_.match(L, decorate_type_t<T>(), index); typedef typename find_conversion_policy<1, Policies>::type converter_policy;
typedef typename mpl::apply_wrap2<converter_policy,T,lua_to_cpp>::type converter;
return converter::match(L, LUABIND_DECORATE_TYPE(T), index);
} }
template<class T>
void converter_postcall(lua_State* L, by_pointer<T>, int) void converter_postcall(lua_State* L, by_pointer<T>, int)
{ {
//specialized_converter_policy_n<2, Policies, T, cpp_to_lua> converter; typedef typename find_conversion_policy<2, Policies>::type converter_policy;
converter_.to_lua(L, storage_.get()); typename mpl::apply_wrap2<converter_policy,T,cpp_to_lua>::type converter;
storage_.destroy(); converter.apply(L, *reinterpret_cast<T*>(m_storage));
reinterpret_cast<T*>(m_storage)->~T();
} }
private: char m_storage[Size];
specialized_converter_policy_n<1, Policies, T, lua_to_cpp > converter_;
out_value_detail::temporary_storage_type<T> storage_;
}; };
template<class Policies = no_policies> template<int N, class Policies = detail::null_type>
struct out_value_policy struct out_value_policy : conversion_policy<N>
{ {
static void precall(lua_State*, const index_map&) {}
static void postcall(lua_State*, const index_map&) {}
struct only_accepts_nonconst_references_or_pointers {}; struct only_accepts_nonconst_references_or_pointers {};
struct can_only_convert_from_lua_to_cpp {}; struct can_only_convert_from_lua_to_cpp {};
template<class T, class Direction> template<class T, class Direction>
struct specialize struct apply
{ {
static_assert(std::is_same< Direction, lua_to_cpp >::value, "Out value policy can only convert from lua to cpp"); typedef typename boost::mpl::if_<boost::is_same<lua_to_cpp, Direction>
static_assert(meta::or_< is_nonconst_reference<T>, is_nonconst_pointer<T> >::value, "Out value policy only accepts non const references or pointers"); , typename boost::mpl::if_<boost::mpl::or_<is_nonconst_reference<T>, is_nonconst_pointer<T> >
, out_value_converter<indirect_sizeof<T>::value, Policies>
// Note to myself: , only_accepts_nonconst_references_or_pointers
// Using the size and template members instead of a policy templated for the type seems >::type
// to be done to tame template bloat. Need to check if this is worth is. , can_only_convert_from_lua_to_cpp
using base_type = typename std::remove_pointer< typename std::remove_reference< T >::type >::type; >::type type;
using type = out_value_converter<base_type, Policies>;
}; };
}; };
template<int Size, class Policies = no_policies> template<int Size, class Policies = detail::null_type>
struct pure_out_value_converter struct pure_out_value_converter
{ {
enum { consumed_args = 0 }; int const consumed_args(...)
{
return 0;
}
template<class T> template<class T>
T& to_cpp(lua_State*, by_reference<T>, int) T& apply(lua_State*, by_reference<T>, int)
{ {
storage_.decltype(storage_)::template construct<T>(); new (m_storage) T();
return storage_.template get<T>(); return *reinterpret_cast<T*>(m_storage);
} }
template<class T> template<class T>
@ -210,16 +189,17 @@ namespace luabind {
template<class T> template<class T>
void converter_postcall(lua_State* L, by_reference<T>, int) void converter_postcall(lua_State* L, by_reference<T>, int)
{ {
specialized_converter_policy_n<1, Policies, T, cpp_to_lua> converter; typedef typename find_conversion_policy<1, Policies>::type converter_policy;
converter.to_lua(L, storage_.template get<T>()); typename mpl::apply_wrap2<converter_policy,T,cpp_to_lua>::type converter;
storage_.template destroy<T>(); converter.apply(L, *reinterpret_cast<T*>(m_storage));
reinterpret_cast<T*>(m_storage)->~T();
} }
template<class T> template<class T>
T* to_cpp(lua_State*, by_pointer<T>, int) T* apply(lua_State*, by_pointer<T>, int)
{ {
storage_.decltype(storage_)::template construct<T>(); new (m_storage) T();
return &storage_.template get<T>(); return reinterpret_cast<T*>(m_storage);
} }
template<class T> template<class T>
@ -231,41 +211,69 @@ namespace luabind {
template<class T> template<class T>
void converter_postcall(lua_State* L, by_pointer<T>, int) void converter_postcall(lua_State* L, by_pointer<T>, int)
{ {
specialized_converter_policy_n<1, Policies, T, cpp_to_lua> converter; typedef typename find_conversion_policy<1, Policies>::type converter_policy;
converter.to_lua(L, storage_.template get<T>()); typename mpl::apply_wrap2<converter_policy,T,cpp_to_lua>::type converter;
storage_.template destroy<T>(); converter.apply(L, *reinterpret_cast<T*>(m_storage));
reinterpret_cast<T*>(m_storage)->~T();
} }
private:
out_value_detail::temporary_storage_size<Size> storage_; char m_storage[Size];
}; };
template<class Policies = no_policies> template<int N, class Policies = detail::null_type>
struct pure_out_value_policy struct pure_out_value_policy : conversion_policy<N, false>
{ {
static void precall(lua_State*, const index_map&) {}
static void postcall(lua_State*, const index_map&) {}
struct only_accepts_nonconst_references_or_pointers {}; struct only_accepts_nonconst_references_or_pointers {};
struct can_only_convert_from_lua_to_cpp {}; struct can_only_convert_from_lua_to_cpp {};
template<class T, class Direction> template<class T, class Direction>
struct specialize struct apply
{ {
static_assert(std::is_same< Direction, lua_to_cpp >::value, "Pure out value policy can only convert from lua to cpp"); typedef typename boost::mpl::if_<boost::is_same<lua_to_cpp, Direction>
static_assert(meta::or_< is_nonconst_reference<T>, is_nonconst_pointer<T> >::value, "Pure out value policy only accepts non const references or pointers"); , typename boost::mpl::if_<boost::mpl::or_<is_nonconst_reference<T>, is_nonconst_pointer<T> >
, pure_out_value_converter<indirect_sizeof<T>::value, Policies>
using type = pure_out_value_converter<indirect_sizeof<T>::value, Policies>; , only_accepts_nonconst_references_or_pointers
>::type
, can_only_convert_from_lua_to_cpp
>::type type;
}; };
}; };
} }}
}
namespace luabind namespace luabind
{ {
template<unsigned int N, class Policies = no_policies > template<int N>
using out_value = meta::type_list<converter_policy_injector<N, detail::out_value_policy<Policies>>>; detail::policy_cons<detail::out_value_policy<N>, detail::null_type>
out_value(LUABIND_PLACEHOLDER_ARG(N))
{
return detail::policy_cons<detail::out_value_policy<N>, detail::null_type>();
}
template<unsigned int N, class Policies = no_policies > template<int N, class Policies>
using pure_out_value = meta::type_list<converter_policy_injector<N, detail::pure_out_value_policy<Policies>>>; detail::policy_cons<detail::out_value_policy<N, Policies>, detail::null_type>
out_value(LUABIND_PLACEHOLDER_ARG(N), const Policies&)
{
return detail::policy_cons<detail::out_value_policy<N, Policies>, detail::null_type>();
}
template<int N>
detail::policy_cons<detail::pure_out_value_policy<N>, detail::null_type>
pure_out_value(LUABIND_PLACEHOLDER_ARG(N))
{
return detail::policy_cons<detail::pure_out_value_policy<N>, detail::null_type>();
}
template<int N, class Policies>
detail::policy_cons<detail::pure_out_value_policy<N, Policies>, detail::null_type>
pure_out_value(LUABIND_PLACEHOLDER_ARG(N), const Policies&)
{
return detail::policy_cons<detail::pure_out_value_policy<N, Policies>, detail::null_type>();
}
} }
#endif // LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED #endif // LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED

View File

@ -1,148 +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_GET_POINTER_051023_HPP
# define LUABIND_GET_POINTER_051023_HPP
#include <memory>
#include <stdexcept>
// TODO: Rename to pointer_traits
namespace luabind {
template<typename T>
T* get_pointer(T* pointer)
{
return pointer;
}
template<typename T>
T* get_pointer(const std::unique_ptr<T>& pointer)
{
return pointer.get();
}
template<typename T>
T* get_pointer(const std::shared_ptr<T>& pointer)
{
return pointer.get();
}
namespace detail {
template<typename T>
struct pointer_traits {
enum { is_pointer = false };
};
template<typename T>
struct pointer_traits<T*>
{
enum { is_pointer = true };
using value_type = T;
};
template<typename T>
struct pointer_traits<std::unique_ptr<T>>
{
enum { is_pointer = true };
using value_type = T;
};
template<typename T>
struct pointer_traits<std::shared_ptr<T>>
{
enum { is_pointer = true };
using value_type = T;
};
template<typename T>
using is_pointer_to_const = std::is_const< typename pointer_traits<T>::value_type >;
template<typename T>
void release_ownership(std::unique_ptr<T>& p)
{
p.release();
}
template <class P>
void release_ownership(P const&)
{
throw std::runtime_error(
"luabind: smart pointer does not allow ownership transfer");
}
namespace has_get_pointer_
{
struct any
{
template<class T> any(T const&);
};
struct no_overload_tag
{};
typedef char(&yes)[1];
typedef char(&no)[2];
no_overload_tag operator, (no_overload_tag, int);
template<class T>
T* get_pointer(T const volatile*);
template<class T>
T* get_pointer(std::unique_ptr<T> const&);
template<class T>
T* get_pointer(std::shared_ptr<T> const&);
detail::has_get_pointer_::no_overload_tag
get_pointer(detail::has_get_pointer_::any);
///@TODO: Rework
template<class T>
yes check(T const&);
no check(no_overload_tag);
template<class T>
struct impl
{
static typename std::add_lvalue_reference<T>::type x;
static const bool value = (sizeof(has_get_pointer_::check((get_pointer(x), 0))) == 1);
typedef std::integral_constant<bool, value> type;
};
} // namespace has_get_pointer_
template<class T>
struct has_get_pointer
: has_get_pointer_::impl<T>::type
{};
} // namespace detail
} // namespace luabind
#endif // LUABIND_GET_POINTER_051023_HPP

View File

@ -27,14 +27,16 @@
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/detail/policy.hpp> #include <luabind/detail/policy.hpp>
namespace luabind { namespace luabind { namespace detail {
namespace detail {
struct raw_converter struct raw_converter
{ {
enum { consumed_args = 0 }; int const consumed_args(...)
{
return 0;
}
lua_State* to_cpp(lua_State* L, by_pointer<lua_State>, int) lua_State* apply(lua_State* L, by_pointer<lua_State>, int)
{ {
return L; return L;
} }
@ -47,20 +49,36 @@ namespace luabind {
void converter_postcall(lua_State*, by_pointer<lua_State>, int) {} void converter_postcall(lua_State*, by_pointer<lua_State>, int) {}
}; };
struct raw_policy template<int N>
struct raw_policy : conversion_policy<N, false>
{ {
static void precall(lua_State*, const index_map&) {}
static void postcall(lua_State*, const index_map&) {}
template<class T, class Direction> template<class T, class Direction>
struct specialize struct apply
{ {
using type = raw_converter; typedef raw_converter type;
}; };
}; };
}} // namespace luabind::detail
namespace luabind {
template<int N>
detail::policy_cons<
detail::raw_policy<N>
, detail::null_type
>
inline raw(LUABIND_PLACEHOLDER_ARG(N))
{
return detail::policy_cons<
detail::raw_policy<N>
, detail::null_type
>();
} }
template<unsigned int N>
using raw_policy = meta::type_list< converter_policy_injector< N, detail::raw_policy > >();
} // namespace luabind } // namespace luabind
#endif // LUABIND_RAW_POLICY_HPP_INCLUDED #endif // LUABIND_RAW_POLICY_HPP_INCLUDED

View File

@ -23,14 +23,8 @@
#ifndef LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED #ifndef LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED
#define LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED #define LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED
#include <luabind/detail/policy.hpp> // for index_map, policy_cons, etc namespace luabind { namespace detail
#include <luabind/lua_include.hpp> // for lua_State, lua_pushnil, etc {
namespace luabind {
namespace detail {
struct cpp_to_lua;
template<class T> template<class T>
struct return_reference_to_converter; struct return_reference_to_converter;
@ -38,34 +32,41 @@ namespace luabind {
struct return_reference_to_converter<cpp_to_lua> struct return_reference_to_converter<cpp_to_lua>
{ {
template<class T> template<class T>
void to_lua(lua_State* L, const T&) void apply(lua_State* L, const T&)
{ {
lua_pushnil(L); lua_pushnil(L);
} }
}; };
template< unsigned int N > template<int N>
struct return_reference_to_policy : detail::converter_policy_has_postcall_tag struct return_reference_to_policy : conversion_policy<0>
{ {
template<typename StackIndexList> static void precall(lua_State*, const index_map&) {}
static void postcall(lua_State* L, int results, StackIndexList) static void postcall(lua_State* L, const index_map& indices)
{ {
lua_pushvalue(L, (meta::get<StackIndexList, N>::value)); int result_index = indices[0];
lua_replace(L, (meta::get<StackIndexList, 0>::value + results)); int ref_to_index = indices[N];
lua_pushvalue(L, ref_to_index);
lua_replace(L, result_index);
} }
template<class T, class Direction> template<class T, class Direction>
struct specialize struct apply
{ {
using type = return_reference_to_converter<Direction>; typedef return_reference_to_converter<Direction> type;
}; };
}; };
}}
namespace luabind
{
template<int N>
detail::policy_cons<detail::return_reference_to_policy<N>, detail::null_type>
return_reference_to(LUABIND_PLACEHOLDER_ARG(N))
{
return detail::policy_cons<detail::return_reference_to_policy<N>, detail::null_type>();
} }
template<unsigned int N>
using return_reference_to = meta::type_list<converter_policy_injector<0, detail::return_reference_to_policy<N>>>;
} }
#endif // LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED #endif // LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED

View File

@ -25,7 +25,7 @@
#include <luabind/prefix.hpp> #include <luabind/prefix.hpp>
#include <luabind/config.hpp> #include <luabind/config.hpp>
#include <luabind/lua_state_fwd.hpp> #include <luabind/lua_include.hpp>
#include <memory> #include <memory>
namespace luabind { namespace luabind {
@ -34,8 +34,7 @@ namespace luabind {
} // namespace luabind } // namespace luabind
namespace luabind { namespace luabind { namespace detail {
namespace detail {
struct LUABIND_API registration struct LUABIND_API registration
{ {
@ -50,15 +49,14 @@ namespace luabind {
registration* m_next; registration* m_next;
}; };
} }} // namespace luabind::detail
} // namespace luabind::detail
namespace luabind { namespace luabind {
struct LUABIND_API scope struct LUABIND_API scope
{ {
scope(); scope();
explicit scope(std::unique_ptr<detail::registration> reg); explicit scope(std::auto_ptr<detail::registration> reg);
scope(scope const& other_); scope(scope const& other_);
~scope(); ~scope();

View File

@ -1,54 +0,0 @@
/** @file
@brief Header
@date 2012
@author
Ryan Pavlik
<rpavlik@iastate.edu> and <abiryan@ryand.net>
http://academic.cleardefinition.com/
Iowa State University Virtual Reality Applications Center
Human-Computer Interaction Graduate Program
*/
// Copyright Iowa State University 2012.
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef INCLUDED_set_package_preload_hpp_GUID_563c882e_86f7_4ea7_8603_4594ea41737e
#define INCLUDED_set_package_preload_hpp_GUID_563c882e_86f7_4ea7_8603_4594ea41737e
// Internal Includes
#include <luabind/config.hpp>
#include <luabind/lua_state_fwd.hpp>
// 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

View File

@ -5,17 +5,15 @@
#ifndef LUABIND_SHARED_PTR_CONVERTER_090211_HPP #ifndef LUABIND_SHARED_PTR_CONVERTER_090211_HPP
# define LUABIND_SHARED_PTR_CONVERTER_090211_HPP # define LUABIND_SHARED_PTR_CONVERTER_090211_HPP
#include <luabind/detail/policy.hpp> # include <luabind/get_main_thread.hpp>
#include <luabind/detail/conversion_policies/value_converter.hpp> // for default_converter, etc # include <luabind/handle.hpp>
#include <luabind/get_main_thread.hpp> // for get_main_thread # include <luabind/detail/policy.hpp>
#include <luabind/handle.hpp> // for handle # include <boost/shared_ptr.hpp>
#include <luabind/detail/decorate_type.hpp> // for decorated_type
#include <memory>
namespace luabind { namespace luabind {
namespace detail namespace detail
{ {
struct shared_ptr_deleter struct shared_ptr_deleter
{ {
@ -31,53 +29,55 @@ namespace luabind {
handle life_support; handle life_support;
}; };
} // namespace detail } // namespace detail
template <class T> template <class T>
struct default_converter<std::shared_ptr<T> > struct default_converter<boost::shared_ptr<T> >
: default_converter<T*> : default_converter<T*>
{ {
using is_native = std::false_type; typedef boost::mpl::false_ is_native;
template <class U> template <class U>
int match(lua_State* L, U, int index) int match(lua_State* L, U, int index)
{ {
return default_converter<T*>::match(L, decorate_type_t<T*>(), index); return default_converter<T*>::match(
L, LUABIND_DECORATE_TYPE(T*), index);
} }
template <class U> template <class U>
std::shared_ptr<T> to_cpp(lua_State* L, U, int index) boost::shared_ptr<T> apply(lua_State* L, U, int index)
{ {
T* raw_ptr = default_converter<T*>::to_cpp(L, decorate_type_t<T*>(), index); T* raw_ptr = default_converter<T*>::apply(
L, LUABIND_DECORATE_TYPE(T*), index);
if(!raw_ptr) { if (!raw_ptr)
return std::shared_ptr<T>(); return boost::shared_ptr<T>();
} else { return boost::shared_ptr<T>(
return std::shared_ptr<T>(raw_ptr, detail::shared_ptr_deleter(L, index)); raw_ptr, detail::shared_ptr_deleter(L, index));
}
} }
void to_lua(lua_State* L, std::shared_ptr<T> const& p) void apply(lua_State* L, boost::shared_ptr<T> const& p)
{ {
if(detail::shared_ptr_deleter* d = std::get_deleter<detail::shared_ptr_deleter>(p)) if (detail::shared_ptr_deleter* d =
boost::get_deleter<detail::shared_ptr_deleter>(p))
{ {
d->life_support.push(L); d->life_support.push(L);
} else { }
detail::value_converter().to_lua(L, p); else
{
detail::value_converter().apply(L, p);
} }
} }
template <class U> template <class U>
void converter_postcall(lua_State*, U const&, int) void converter_postcall(lua_State*, U const&, int)
{} {}
}; };
template <class T> template <class T>
struct default_converter<std::shared_ptr<T> const&> struct default_converter<boost::shared_ptr<T> const&>
: default_converter<std::shared_ptr<T> > : default_converter<boost::shared_ptr<T> >
{}; {};
} // namespace luabind } // namespace luabind
#endif // LUABIND_SHARED_PTR_CONVERTER_090211_HPP #endif // LUABIND_SHARED_PTR_CONVERTER_090211_HPP

View File

@ -2,15 +2,26 @@
// subject to the Boost Software License, Version 1.0. (See accompanying // subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef LUABIND_TAG_FUNCTION_081129_HPP #if !BOOST_PP_IS_ITERATING
#define LUABIND_TAG_FUNCTION_081129_HPP
#include <luabind/config.hpp> # ifndef LUABIND_TAG_FUNCTION_081129_HPP
#include <luabind/detail/type_traits.hpp> # define LUABIND_TAG_FUNCTION_081129_HPP
#include <luabind/lua_state_fwd.hpp>
# if LUABIND_MAX_ARITY <= 8
# include <boost/mpl/vector/vector10.hpp>
# else
# include <boost/mpl/vector/vector50.hpp>
# endif
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/iterate.hpp>
# include <boost/preprocessor/repetition/enum_params.hpp>
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
namespace luabind { namespace luabind {
namespace detail
{
template <class Signature, class F> template <class Signature, class F>
struct tagged_function struct tagged_function
{ {
@ -21,43 +32,57 @@ namespace luabind {
F f; F f;
}; };
namespace detail template <class Signature, class F>
Signature deduce_signature(tagged_function<Signature, F> const&, ...)
{ {
return Signature();
}
struct invoke_context; template <class Signature, class F, class Policies>
struct function_object;
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
template <class Signature, class F, typename... PolicyInjectors>
int invoke( int invoke(
lua_State* L, function_object const& self, invoke_context& ctx lua_State* L, function_object const& self, invoke_context& ctx
// std::bind operator() is nonconst... is that fixable? , tagged_function<Signature, F> const& tagged
, tagged_function<Signature, F> /*const*/& tagged , Signature, Policies const& policies)
, Signature, meta::type_list<PolicyInjectors...> const& injectors)
{ {
return invoke(L, self, ctx, tagged.f, Signature(), injectors); return invoke(L, self, ctx, tagged.f, Signature(), policies);
} }
#else
//template< typename PolicyList, typename Signature, typename F>
//inline int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f)
template < typename PolicyList, typename Signature, typename F > template <class Function>
int invoke(lua_State* L, function_object const& self, invoke_context& ctx, tagged_function<Signature, F> /*const*/& tagged) struct signature_from_function;
{
return invoke<PolicyList, Signature>(L, self, ctx, tagged.f);
}
#endif
} // namespace detail # define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, LUABIND_MAX_ARITY, <luabind/tag_function.hpp>))
# include BOOST_PP_ITERATE()
template <class Signature, class F> } // namespace detail
tagged_function<deduce_signature_t<Signature>, F >
tag_function(F f) template <class Signature, class F>
{ detail::tagged_function<
typename detail::signature_from_function<Signature>::type
, F
>
tag_function(F f)
{
return f; return f;
} }
} // namespace luabind } // namespace luabind
# endif // LUABIND_TAG_FUNCTION_081129_HPP # endif // LUABIND_TAG_FUNCTION_081129_HPP
#else // BOOST_PP_IS_ITERATING
# define N BOOST_PP_ITERATION()
# define NPLUS1 BOOST_PP_INC(N)
template <class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class A)>
struct signature_from_function<R(BOOST_PP_ENUM_PARAMS(N, A))>
{
typedef BOOST_PP_CAT(mpl::vector, NPLUS1)<
R BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
> type;
};
#endif // BOOST_PP_IS_ITERATING

View File

@ -5,16 +5,26 @@
#ifndef LUABIND_TYPEID_081227_HPP #ifndef LUABIND_TYPEID_081227_HPP
# define LUABIND_TYPEID_081227_HPP # define LUABIND_TYPEID_081227_HPP
# include <boost/operators.hpp>
# include <typeinfo> # include <typeinfo>
# include <luabind/detail/type_traits.hpp> # include <luabind/detail/primitives.hpp>
namespace luabind { namespace luabind {
class type_id # ifdef BOOST_MSVC
{ # pragma warning(push)
public: // 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 boost::less_than_comparable<type_id>
{
public:
type_id() type_id()
: id(&typeid(null_type)) : id(&typeid(detail::null_type))
{} {}
type_id(std::type_info const& id) type_id(std::type_info const& id)
@ -36,19 +46,18 @@ namespace luabind {
return id->before(*other.id); return id->before(*other.id);
} }
size_t hash_code() const
{
return id->hash_code();
}
char const* name() const char const* name() const
{ {
return id->name(); return id->name();
} }
private: private:
std::type_info const* id; std::type_info const* id;
}; };
# ifdef BOOST_MSVC
# pragma warning(pop)
# endif
} // namespace luabind } // namespace luabind

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