diff --git a/CMakeLists.txt b/CMakeLists.txt index 4003d529..c1d05305 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ include_directories( ${LUA_INCLUDE_DIRS}) add_subdirectory(src) +add_subdirectory(test) if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) if(LUABIND_BUILD_TESTING) diff --git a/luabind/config.hpp b/luabind/config.hpp index 167a1217..6a412e01 100644 --- a/luabind/config.hpp +++ b/luabind/config.hpp @@ -70,7 +70,7 @@ // C code has undefined behavior, lua is written in C). #ifdef LUABIND_DYNAMIC_LINK -# if defined (BOOST_WINDOWS) +# if defined (_WIN32) # ifdef LUABIND_BUILDING # define LUABIND_API __declspec(dllexport) # else diff --git a/luabind/detail/call_function.hpp b/luabind/detail/call_function.hpp index 64d8a2ce..53fd24aa 100644 --- a/luabind/detail/call_function.hpp +++ b/luabind/detail/call_function.hpp @@ -103,7 +103,7 @@ namespace luabind push_arguments(L, std::forward(args)...); if(Function(L, sizeof...(Args), 0)) { - assert(lua_gettop(L)==top-NumParams+1); + assert(lua_gettop(L)==int(top-NumParams+1)); call_error(L); } // pops the return values from the function call diff --git a/luabind/detail/call_shared.hpp b/luabind/detail/call_shared.hpp index 3b644e30..cae5786c 100644 --- a/luabind/detail/call_shared.hpp +++ b/luabind/detail/call_shared.hpp @@ -47,10 +47,10 @@ namespace luabind { throw cast_failed(L, typeid(T)); #else cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(L, typeid(Ret)); + 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_error_callback()"); + " If you want to handle the error you can use luabind::set_cast_failed_callback()"); std::terminate(); #endif } diff --git a/luabind/detail/class_rep.hpp b/luabind/detail/class_rep.hpp index 34324a06..29dee666 100644 --- a/luabind/detail/class_rep.hpp +++ b/luabind/detail/class_rep.hpp @@ -203,7 +203,7 @@ namespace luabind { namespace detail class_id_map* m_classes; }; - bool is_class_rep(lua_State* L, int index); + LUABIND_API bool is_class_rep(lua_State* L, int index); }} diff --git a/luabind/detail/conversion_policies/conversion_policies.hpp b/luabind/detail/conversion_policies/conversion_policies.hpp index ab683dfe..946fe2ae 100644 --- a/luabind/detail/conversion_policies/conversion_policies.hpp +++ b/luabind/detail/conversion_policies/conversion_policies.hpp @@ -34,6 +34,7 @@ #include #include #include +#include namespace luabind { diff --git a/luabind/detail/conversion_policies/native_converter.hpp b/luabind/detail/conversion_policies/native_converter.hpp index 1e8ffda0..0826b758 100644 --- a/luabind/detail/conversion_policies/native_converter.hpp +++ b/luabind/detail/conversion_policies/native_converter.hpp @@ -268,6 +268,11 @@ namespace luabind { : default_converter {}; + template + struct default_converter + : default_converter + {}; + template struct default_converter : default_converter diff --git a/luabind/detail/crtp_iterator.hpp b/luabind/detail/crtp_iterator.hpp index 9193ba6b..22a10fe7 100644 --- a/luabind/detail/crtp_iterator.hpp +++ b/luabind/detail/crtp_iterator.hpp @@ -21,7 +21,7 @@ namespace luabind { CRTP operator++(int) { - CRTP tmp(*this); + CRTP tmp(upcast()); upcast().increment(); return tmp; } diff --git a/luabind/detail/format_signature.hpp b/luabind/detail/format_signature.hpp index 40f31742..a3ddb90b 100644 --- a/luabind/detail/format_signature.hpp +++ b/luabind/detail/format_signature.hpp @@ -138,9 +138,12 @@ LUABIND_TYPE_TO_STRING(luabind::argument) , true , typename meta::pop_front::type() ); - lua_pushstring(L, ")"); - - lua_concat(L, static_cast(meta::size::value) * 2 + 2); + lua_pushstring(L, ")"); + size_t sz = meta::size::value; + size_t ncat = sz * 2 + 2; + if (sz == 1) + ++ncat; + lua_concat(L, ncat); } } // namespace detail diff --git a/luabind/detail/meta.hpp b/luabind/detail/meta.hpp index 18e36438..249c6662 100644 --- a/luabind/detail/meta.hpp +++ b/luabind/detail/meta.hpp @@ -85,12 +85,35 @@ namespace luabind { namespace meta template< typename List, unsigned int Index, template< typename > class T > struct transform; - template< typename List, template< typename > class T > + template< typename List, unsigned int Index, template< typename > class Function > + using transform_t = typename transform< List, Index, Function >::type; + + template< typename List, template< typename > class Function > struct transform_all; + template< typename List, template< typename > class Function > + using transform_all_t = typename transform_all< List, Function >::type; + + template< typename T, unsigned int start, unsigned int end > struct sub_range; + /* + aliases + */ + template< typename T > + using pop_front_t = typename pop_front::type; + + template< typename T1, typename... Types > + using join_t = typename join< T1, Types... >::type; + + template< typename T, unsigned int start, unsigned int end > + using sub_range_t = typename sub_range< T, start, end >::type; + + template< typename T, unsigned int index > + using get_t = typename get< T, index >::type; + + // Used as terminator on type and index lists struct null_type {}; @@ -183,8 +206,6 @@ namespace luabind { namespace meta /* Index access to type list */ - - template< typename Element0, typename... Elements, unsigned int Index > struct get< type_list, Index > { using type = typename get< type_list, Index - 1 >::type; @@ -202,17 +223,15 @@ namespace luabind { namespace meta 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... >; }; - /* - template< typename List, unsigned int Index, typename T > - struct replace; - */ - namespace detail { template< typename HeadList, typename TailList, typename Type, unsigned int Index > struct replace_helper; @@ -233,30 +252,23 @@ namespace luabind { namespace meta { using TypeList = type_list< Types... >; - using type = typename meta::join< - typename meta::sub_range< TypeList, 0, Index >::type, meta::type_list, - typename meta::sub_range< TypeList, Index + 1, sizeof...(Types) >::type - >::type; + using type = join_t< + sub_range_t< TypeList, 0, Index >, + meta::type_list, + sub_range_t< TypeList, Index + 1, sizeof...(Types) > + >; }; - namespace detail { - template< typename HeadList, typename TailList, template< typename > class Type, unsigned int Index > - struct enwrap_helper; - - template< typename... HeadTypes, typename CurrentType, typename... TailTypes, template< typename > class Type, unsigned int Index > - struct enwrap_helper< type_list< HeadTypes... >, type_list< CurrentType, TailTypes... >, Type, Index> { - using type = typename enwrap_helper< type_list< HeadTypes..., CurrentType >, type_list, Type, Index - 1 >::type; - }; - - template< typename... HeadTypes, typename CurrentType, typename... TailTypes, template< typename > class Type > - struct enwrap_helper< type_list< HeadTypes... >, type_list< CurrentType, TailTypes... >, Type, 0> { - using type = type_list< HeadTypes..., Type, TailTypes... >; - }; - } - - template< typename... Types, unsigned int Index, template< typename > class Type > - struct enwrap< type_list< Types... >, Index, Type > { - using type = typename detail::enwrap_helper< type_list< >, type_list< Types... >, Type, Index >::type; + /* + Enwrap all elements of a type list in an template + */ + template< typename... Types, unsigned int Index, template< typename > class Enwrapper > + struct enwrap< type_list< Types... >, Index, Enwrapper > { + using type = join_t< + sub_range_t< type_list, 0, Index >, + Enwrapper< get_t< type_list, Index> >, + sub_range_t< type_list, Index+1, sizeof...(Types) > + >; }; template< typename... Types, template< typename > class Enwrapper > @@ -265,38 +277,29 @@ namespace luabind { namespace meta using type = type_list< Enwrapper< Types >... >; }; - namespace detail { - template< typename HeadList, typename TailList, template< typename > class Type, unsigned int Index > - struct transform_helper; - - template< typename... HeadTypes, typename CurrentType, typename... TailTypes, template< typename > class Type, unsigned int Index > - struct transform_helper< type_list< HeadTypes... >, type_list< CurrentType, TailTypes... >, Type, Index> { - using type = typename transform_helper< type_list< HeadTypes..., CurrentType >, type_list, Type, Index - 1 >::type; - }; - - template< typename... HeadTypes, typename CurrentType, typename... TailTypes, template< typename > class Type > - struct transform_helper< type_list< HeadTypes... >, type_list< CurrentType, TailTypes... >, Type, 0> { - using type = type_list< HeadTypes..., typename Type::type, TailTypes... >; - }; - } - - template< typename... Types, unsigned int Index, template< typename > class Type > - struct transform< type_list< Types... >, Index, Type > { - using type = typename detail::transform_helper< type_list< >, type_list< Types... >, Type, Index >::type; - }; - + /* + Transform a certain element of a type list + */ + template< typename T, unsigned int Index, template< typename > class Function > + struct transform; - template< typename Type0, typename... Types, template< typename > class Type > - struct transform_all< type_list< Type0, Types... >, Type > { - using type = typename push_front< typename transform_all< type_list, Type >::type, typename Type::type >::type; + template< typename... Types, unsigned int Index, template< typename > class Function > + struct transform< type_list< Types... >, Index, Function > { + using type = join_t< + sub_range_t< type_list, 0, Index >, + typename Function< get_t< type_list, Index> >::type, + sub_range_t< type_list, Index + 1, sizeof...(Types) > + >; }; - - template< template< typename > class Type > - struct transform_all< type_list< >, Type > { - using type = type_list< >; + + /* + Transform all elements of a type list + */ + template< typename... Types, template< typename > class Function > + struct transform_all< type_list< Types... >, Function > { + using type = type_list< typename Function::type... >; }; - /* Tuple from type list */ @@ -363,48 +366,49 @@ namespace luabind { namespace meta Index index list */ - template< unsigned int Index0, unsigned int... Indices, unsigned int Index > - struct get< index_list, Index > { - enum { value = get< index_list, Index - 1 >::value }; - }; + namespace detail { - template< unsigned int Index0, unsigned int... Indices > - struct get< index_list, 0 > - { - enum { value = Index0 }; - }; + 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 Index > - struct get< index_list< >, Index > - { - static_assert(size< index_list< Index > >::value == 1, "Bad Index"); - }; + template< unsigned int Value0, unsigned int... Values > + struct get_iterate< 0, Value0, Values... > { + static const unsigned int value = Value0; + }; - template< > - struct get< index_list< >, 0 > + } + + 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< > - struct size< index_list< > > { - enum { value = 0 }; + template< unsigned int... Values > + struct size< index_list< Values... > > { + static const unsigned int value = sizeof...(Values); }; - template< unsigned int Index0, unsigned int... Indices > - struct size< index_list< Index0, Indices... > > { - enum { value = 1 + size< index_list< Indices... > >::value }; - }; + /* + Index list push front + */ template< unsigned int... Indices, unsigned int Index > struct push_front< index_list< Indices... >, index > { using type = index_list< Index, Indices... >; }; + /* + Index list push back + */ template< unsigned int... Indices, unsigned int Index > struct push_back< index_list< Indices... >, index > { @@ -412,9 +416,8 @@ namespace luabind { namespace meta }; /* - pop_front + Index list pop_front */ - template< unsigned int Index0, unsigned int... Indices > struct pop_front< index_list< Index0, Indices... > > { using type = index_list< Indices... >; @@ -425,14 +428,15 @@ namespace luabind { namespace meta 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 > { - static_assert(end >= curr, "end must be greater or equal to start"); }; template< unsigned int end, unsigned int... Indices > @@ -443,6 +447,10 @@ namespace luabind { namespace meta } + /* + 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"); @@ -452,12 +460,8 @@ namespace luabind { namespace meta template< unsigned int start, unsigned int end > using index_range = typename make_index_range::type; - /* - Exracts the first N elements of an index list and creates a new index list from them - */ - namespace detail { - + // These implementation are not really efficient... template< typename SourceList, typename IndexList > struct sub_range_index; @@ -465,7 +469,7 @@ namespace luabind { namespace meta 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; @@ -476,6 +480,9 @@ namespace luabind { namespace meta } + /* + Index list sub_range [start, end) + */ template< unsigned int start, unsigned int end, unsigned int... Indices > struct sub_range< index_list, start, end > { @@ -483,6 +490,9 @@ namespace luabind { namespace meta using type = typename detail::sub_range_index< index_list, typename make_index_range::type >::type; }; + /* + Type list sub_range [start, end) + */ template< unsigned int start, unsigned int end, typename... Types > struct sub_range< type_list, start, end > { @@ -490,28 +500,35 @@ namespace luabind { namespace meta using type = typename detail::sub_range_type< type_list, typename make_index_range::type >::type; }; - template< typename IndexList, unsigned int Index > - struct push_back_index; + /* + Index list sum + */ - template< unsigned int... Indices, unsigned int Index > - struct push_back_index< index_list< Indices... >, Index > - { - using type = index_list< Indices..., Index >; - }; + 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 Arg0, unsigned int... Args > - struct sum< index_list > + template< unsigned int... Args > + struct sum< index_list > { - enum{ value = Arg0 + sum>::value }; - }; - - template< > - struct sum< index_list< > > { - enum {value = 0}; + static const unsigned int value = detail::sum_values::value; }; /* diff --git a/luabind/detail/object.hpp b/luabind/detail/object.hpp index 5f90ff99..3ec3a698 100644 --- a/luabind/detail/object.hpp +++ b/luabind/detail/object.hpp @@ -333,13 +333,13 @@ namespace luabind { } template - inline object getupvalue(ValueWrapper const& value, int index) + inline std::tuple getupvalue(ValueWrapper const& value, int index) { lua_State* interpreter = lua_proxy_traits::interpreter(value); lua_proxy_traits::unwrap(interpreter, value); detail::stack_pop pop(interpreter, 2); - lua_getupvalue(interpreter, -1, index); - return object(from_stack(interpreter, -1)); + const char* name = lua_getupvalue(interpreter, -1, index); + return std::make_tuple(name, object(from_stack(interpreter, -1))); } template diff --git a/luabind/detail/typetraits.hpp b/luabind/detail/typetraits.hpp index c7a189fe..99c195e9 100644 --- a/luabind/detail/typetraits.hpp +++ b/luabind/detail/typetraits.hpp @@ -24,7 +24,7 @@ #ifndef LUABIND_TYPETRAITS_HPP_INCLUDED #define LUABIND_TYPETRAITS_HPP_INCLUDED -#include +#include namespace luabind { namespace detail { @@ -32,28 +32,24 @@ namespace luabind { namespace detail struct is_const_reference : public std::conditional< std::is_reference::value && std::is_const::type>::value, std::true_type, std::false_type >::type { - enum { value = std::is_reference::value && std::is_const::value }; }; template struct is_nonconst_reference : public std::conditional< std::is_reference::value && !std::is_const::type>::value, std::true_type, std::false_type >::type { - static const bool value = std::is_reference::value && !std::is_const::value; }; template struct is_const_pointer : public std::conditional< std::is_const::type>::value && std::is_pointer::value, std::true_type, std::false_type >::type { - static const bool value = std::is_const::type>::value && std::is_pointer::value; }; template struct is_nonconst_pointer : public std::conditional < std::is_pointer::value && !std::is_const::type>::value, std::true_type, std::false_type >::type { - static const bool value = std::is_pointer::value && !std::is_const::type>::value; }; template diff --git a/luabind/make_function.hpp b/luabind/make_function.hpp index 6a6b6dc9..d60520dd 100644 --- a/luabind/make_function.hpp +++ b/luabind/make_function.hpp @@ -79,7 +79,11 @@ namespace luabind { bool exception_caught = invoke_defer(L, impl, ctx, results); if(exception_caught) lua_error(L); # else - results = invoke(L, *impl, ctx, impl->f, Signature(), impl->policies); + #ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + results = invoke(L, *impl, ctx, impl->f, Signature(), InjectorList()); + #else + results = invoke(L, *impl, ctx, impl->f); + #endif # endif if(!ctx) { ctx.format_error(L, impl); diff --git a/luabind/out_value_policy.hpp b/luabind/out_value_policy.hpp index 86f8fdf4..24202850 100644 --- a/luabind/out_value_policy.hpp +++ b/luabind/out_value_policy.hpp @@ -60,7 +60,68 @@ namespace luabind { namespace detail static const int value = sizeof(indirect_sizeof_test(decorated_type())); }; - template + namespace out_value_detail { + + template< int Size > + struct temporary_storage_size { + + template< typename T, typename... Args > + void construct(Args&&... args) + { + new (&m_storage) T(std::forward(args)...); + } + + template + T& get() { + return *reinterpret_cast(&m_storage); + } + + template + const T& get() const { + return *reinterpret_cast(&m_storage); + } + + template + void destroy() + { + get().~T(); + } + + typename std::aligned_storage::type m_storage; + + }; + + template< typename T > + struct temporary_storage_type { + + template< typename... Args > + void construct(Args&&... args) + { + new (&m_storage) T(std::forward(args)...); + } + + T& get() { + return *reinterpret_cast(&m_storage); + } + + const T& get() const { + return *reinterpret_cast(&m_storage); + } + + void destroy() + { + get().~T(); + } + + typename std::aligned_storage::type m_storage; + + }; + + } + + // See note in out_value_policy about why we're not templating + // for the parameter type. + template struct out_value_converter { enum { consumed_args = 1 }; @@ -68,73 +129,45 @@ namespace luabind { namespace detail template T& to_cpp(lua_State* L, by_reference, int index) { - specialized_converter_policy_n<1, Policies, T, lua_to_cpp> converter; - -#if defined(__GNUC__) && __GNUC__ >= 4 - T* storage = reinterpret_cast(m_storage); - new (storage) T(converter.to_cpp(L, decorated_type(), index)); - return *storage; -#else - new (m_storage) T(converter.to_cpp(L, decorated_type(), index)); - return *reinterpret_cast(m_storage); -#endif + //specialized_converter_policy_n<1, Policies, T, lua_to_cpp> converter; + storage_.construct(converter_.to_cpp(L, decorated_type(), index)); + return storage_.get(); } - template - static int match(lua_State* L, by_reference, int index) + int match(lua_State* L, by_reference, int index) { - return specialized_converter_policy_n<1, Policies, T, lua_to_cpp >::match(L, decorated_type(), index); + return converter_.match(L, decorated_type(), index); } - template void converter_postcall(lua_State* L, by_reference, int) { - specialized_converter_policy_n<2,Policies,T,cpp_to_lua> converter; -#if defined(__GNUC__) && __GNUC__ >= 4 - T* storage = reinterpret_cast(m_storage); - converter.to_lua(L, *storage); - storage->~T(); -#else - converter.to_lua(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); -#endif + //specialized_converter_policy_n<2,Policies,T,cpp_to_lua> converter; + converter_.to_lua(L, storage_.get()); + storage_.destroy(); } - template T* to_cpp(lua_State* L, by_pointer, int index) { - specialized_converter_policy_n<1, Policies, T, lua_to_cpp > converter; -#if defined(__GNUC__) && __GNUC__ >= 4 - T* storage = reinterpret_cast(m_storage); - new (storage) T(converter.to_cpp(L, decorated_type(), index)); - return storage; -#else - new (m_storage) T(converter.to_cpp(L, decorated_type(), index)); - return reinterpret_cast(m_storage); -#endif + storage_.construct(converter_.to_cpp(L, decorated_type(), index)); + return &storage_.get(); } - template - static int match(lua_State* L, by_pointer, int index) + int match(lua_State* L, by_pointer, int index) { - return specialized_converter_policy_n<1, Policies, T, lua_to_cpp>::match(L, decorated_type(), index); + return converter_.match(L, decorated_type(), index); } template void converter_postcall(lua_State* L, by_pointer, int) { - specialized_converter_policy_n<2, Policies, T, cpp_to_lua> converter; -#if defined(__GNUC__) && __GNUC__ >= 4 - T* storage = reinterpret_cast(m_storage); - converter.to_lua(L, *storage); - storage->~T(); -#else - converter.to_lua(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); -#endif + //specialized_converter_policy_n<2, Policies, T, cpp_to_lua> converter; + converter_.to_lua(L, storage_.get()); + storage_.destroy(); } - char m_storage[Size]; + private: + specialized_converter_policy_n<1, Policies, T, lua_to_cpp > converter_; + out_value_detail::temporary_storage_type storage_; }; template @@ -149,7 +182,11 @@ namespace luabind { namespace detail static_assert(std::is_same< Direction, lua_to_cpp >::value, "Out value policy can only convert from lua to cpp"); static_assert(meta::or_< is_nonconst_reference, is_nonconst_pointer >::value, "Out value policy only accepts non const references or pointers"); - typedef out_value_converter::value, Policies> type; + // Note to myself: + // Using the size and template members instead of a policy templated for the type seems + // to be done to tame template bloat. Need to check if this is worth is. + using base_type = typename std::remove_pointer< typename std::remove_reference< T >::type >::type; + typedef out_value_converter type; }; }; @@ -161,14 +198,8 @@ namespace luabind { namespace detail template T& to_cpp(lua_State*, by_reference, int) { -#if defined(__GNUC__) && __GNUC__ >= 4 - T* storage = reinterpret_cast(m_storage); - new (storage) T(); - return *storage; -#else - new (m_storage) T(); - return *reinterpret_cast(m_storage); -#endif + storage_.construct(); + return storage_.get(); } template @@ -181,28 +212,15 @@ namespace luabind { namespace detail void converter_postcall(lua_State* L, by_reference, int) { specialized_converter_policy_n<1, Policies, T, cpp_to_lua> converter; - -#if defined(__GNUC__) && __GNUC__ >= 4 - T* storage = reinterpret_cast(m_storage); - converter.to_lua(L, *storage); - storage->~T(); -#else - converter.to_lua(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); -#endif + converter.to_lua(L, storage_.get()); + storage_.destroy(); } template T* to_cpp(lua_State*, by_pointer, int) { -#if defined(__GNUC__) && __GNUC__ >= 4 - T* storage = reinterpret_cast(m_storage); - new (storage) T(); - return storage; -#else - new (m_storage) T(); - return reinterpret_cast(m_storage); -#endif + storage_.construct(); + return &storage_.get(); } template @@ -215,18 +233,12 @@ namespace luabind { namespace detail void converter_postcall(lua_State* L, by_pointer, int) { specialized_converter_policy_n<1, Policies, T, cpp_to_lua> converter; -#if defined(__GNUC__) && __GNUC__ >= 4 - T* storage = reinterpret_cast(m_storage); - converter.to_lua(L, *storage); - storage->~T(); -#else - converter.to_lua(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); -#endif + converter.to_lua(L, storage_.get()); + storage_.destroy(); } - //std::aligned_storage< Size, Size > m_storage; - char m_storage[Size]; + private: + out_value_detail::temporary_storage_size storage_; }; template diff --git a/src/class_rep.cpp b/src/class_rep.cpp index 6e4b29d7..45667386 100644 --- a/src/class_rep.cpp +++ b/src/class_rep.cpp @@ -300,7 +300,7 @@ int luabind::detail::class_rep::static_class_gettable(lua_State* L) return 1; } -bool luabind::detail::is_class_rep(lua_State* L, int index) +LUABIND_API bool luabind::detail::is_class_rep(lua_State* L, int index) { if (lua_getmetatable(L, index) == 0) return false; diff --git a/src/error.cpp b/src/error.cpp index 944296d3..5cacada2 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -30,6 +30,7 @@ namespace luabind { +#ifndef LUABIND_NO_EXCEPTIONS error::error(lua_State* L) { const char* message=lua_tostring(L, -1); @@ -47,7 +48,7 @@ namespace luabind { return m_message.c_str(); } - +#endif namespace { pcall_callback_fun pcall_callback = 0; diff --git a/src/function.cpp b/src/function.cpp index 9ec91ee9..5b40918a 100644 --- a/src/function.cpp +++ b/src/function.cpp @@ -73,14 +73,14 @@ namespace LUABIND_API void add_overload( object const& context, char const* name, object const& fn) { - function_object* f = *touserdata(getupvalue(fn, 1)); + function_object* f = *touserdata(std::get<1>(getupvalue(fn, 1))); f->name = name; if (object overloads = context[name]) { if (is_luabind_function(overloads) && is_luabind_function(fn)) { - f->next = *touserdata(getupvalue(overloads, 1)); + f->next = *touserdata(std::get<1>(getupvalue(overloads, 1))); f->keepalive = overloads; } } diff --git a/src/function_introspection.cpp b/src/function_introspection.cpp index c9240310..06a1d743 100644 --- a/src/function_introspection.cpp +++ b/src/function_introspection.cpp @@ -70,7 +70,7 @@ namespace { return NULL; } } - return *touserdata(getupvalue(fn, 1)); + return *touserdata(std::get<1>(getupvalue(fn, 1))); } std::string get_function_name(argument const& fn) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 13661a1e..336b2bbb 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,7 +4,7 @@ # Iowa State University HCI Graduate Program/VRAC # ls test_*.cpp | sort | sed s/test_// | sed s/.cpp// -# remove typetraits value_wrapper and has_get_pointer because they are +# remove typetraits lua_proxy and has_get_pointer because they are # compile-only tests set(TESTS abstract_base diff --git a/test/benchmark.cpp b/test/benchmark.cpp index 124c6193..aee4f5f2 100644 --- a/test/benchmark.cpp +++ b/test/benchmark.cpp @@ -44,10 +44,12 @@ int main() lua_State* L = luaL_newstate(); open(L); - class_(L, "A") - .def(constructor<>()); - - function(L, "test1", &f1); + module(L) + [ + class_("A") + .def(constructor<>()), + def("test1", &f1) + ]; lua_pushcclosure(L, &f2, 0); lua_setglobal(L, "test2"); @@ -59,7 +61,7 @@ int main() { // benchmark luabind std::clock_t start1 = std::clock(); - lua_dostring(L, "a = A()\n" + luaL_dostring(L, "a = A()\n" "for i = 1, 100000 do\n" "test1(5, 4.6, 'foo', a)\n" "end"); @@ -69,7 +71,7 @@ int main() // benchmark empty binding std::clock_t start2 = std::clock(); - lua_dostring(L, "a = A()\n" + luaL_dostring(L, "a = A()\n" "for i = 1, 100000 do\n" "test2(5, 4.6, 'foo', a)\n" "end"); diff --git a/test/test_free_functions.cpp b/test/test_free_functions.cpp index 9ae5f3e1..c28cdc6c 100644 --- a/test/test_free_functions.cpp +++ b/test/test_free_functions.cpp @@ -152,6 +152,7 @@ void test_main(lua_State* L) } catch(luabind::error const& e) { + if (std::string("[string \"function failing_fun() error('expected error ...\"]:1: expected error message") != e.what()) if (std::string("[string \"function failing_fun() error('expected " #if LUA_VERSION_NUM >= 502 "error ..." diff --git a/test/test_has_get_pointer.cpp b/test/test_has_get_pointer.cpp deleted file mode 100644 index 7cc5ea9d..00000000 --- a/test/test_has_get_pointer.cpp +++ /dev/null @@ -1,62 +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. - -#include -#include -#include -#include -#include - -namespace lb = luabind::detail; - -namespace test -{ - - struct X - { - }; - - struct Y - { - }; - - Y* get_pointer(Y const&); - - struct Z : boost::enable_shared_from_this {}; - -} // namespace test - -#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP -namespace luabind -{ - using test::get_pointer; - using boost::get_pointer; -} // namespace luabind -#endif - -BOOST_MPL_ASSERT(( lb::has_get_pointer > )); -BOOST_MPL_ASSERT(( lb::has_get_pointer )); -BOOST_MPL_ASSERT(( lb::has_get_pointer )); -BOOST_MPL_ASSERT_NOT(( lb::has_get_pointer )); -BOOST_MPL_ASSERT_NOT(( lb::has_get_pointer )); -BOOST_MPL_ASSERT(( lb::has_get_pointer )); - diff --git a/test/test_implicit_cast.cpp b/test/test_implicit_cast.cpp index 93276fd7..56e7bfa5 100644 --- a/test/test_implicit_cast.cpp +++ b/test/test_implicit_cast.cpp @@ -124,6 +124,7 @@ void test_main(lua_State* L) DOSTRING(L, "assert(enum_by_const_ref(LBENUM.VAL1) == LBENUM.VAL1)"); DOSTRING(L, "assert(enum_by_const_ref(LBENUM.VAL2) == LBENUM.VAL2)"); + // This test fails because shared_ptr-converter is broken. DOSTRING_EXPECTED(L, "a = A()\n" "no_convert(a)", diff --git a/test/test_value_wrapper.cpp b/test/test_lua_proxy.cpp similarity index 52% rename from test/test_value_wrapper.cpp rename to test/test_lua_proxy.cpp index 2b8837ac..b763f920 100644 --- a/test/test_value_wrapper.cpp +++ b/test/test_lua_proxy.cpp @@ -20,50 +20,41 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#include +#include #include -#include struct X_tag; struct X { - typedef X_tag value_wrapper_tag; + typedef X_tag lua_proxy_tag; }; namespace luabind { -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG template<> - struct value_wrapper_traits + struct lua_proxy_traits { - typedef boost::mpl::true_ is_specialized; + typedef std::true_type is_specialized; }; -#else - // used on compilers supporting partial template specialization - template<> - struct value_wrapper_traits - { - typedef boost::mpl::true_ is_specialized; - }; -#endif - } // namespace luabind -BOOST_MPL_ASSERT(( luabind::is_value_wrapper )); -BOOST_MPL_ASSERT_NOT(( luabind::is_value_wrapper )); -BOOST_MPL_ASSERT_NOT(( luabind::is_value_wrapper )); +#define LUABIND_STATIC_ASSERT(expr) static_assert(expr, #expr) + +LUABIND_STATIC_ASSERT(luabind::is_lua_proxy_type::value); +LUABIND_STATIC_ASSERT(!luabind::is_lua_proxy_type::value); +LUABIND_STATIC_ASSERT(!luabind::is_lua_proxy_type::value); -BOOST_MPL_ASSERT(( luabind::is_value_wrapper_arg )); -BOOST_MPL_ASSERT(( luabind::is_value_wrapper_arg )); -BOOST_MPL_ASSERT(( luabind::is_value_wrapper_arg )); -BOOST_MPL_ASSERT(( luabind::is_value_wrapper_arg )); -BOOST_MPL_ASSERT_NOT(( luabind::is_value_wrapper_arg )); -BOOST_MPL_ASSERT_NOT(( luabind::is_value_wrapper_arg )); +LUABIND_STATIC_ASSERT(luabind::is_lua_proxy_arg::value); +LUABIND_STATIC_ASSERT(luabind::is_lua_proxy_arg::value); +LUABIND_STATIC_ASSERT(luabind::is_lua_proxy_arg::value); +LUABIND_STATIC_ASSERT(luabind::is_lua_proxy_arg::value); +LUABIND_STATIC_ASSERT(!luabind::is_lua_proxy_arg::value); +LUABIND_STATIC_ASSERT(!luabind::is_lua_proxy_arg::value); -BOOST_MPL_ASSERT(( luabind::is_value_wrapper_arg )); -BOOST_MPL_ASSERT(( luabind::is_value_wrapper_arg )); -BOOST_MPL_ASSERT(( luabind::is_value_wrapper_arg )); +LUABIND_STATIC_ASSERT(luabind::is_lua_proxy_arg::value); +LUABIND_STATIC_ASSERT(luabind::is_lua_proxy_arg::value); +LUABIND_STATIC_ASSERT(luabind::is_lua_proxy_arg::value); int main() { diff --git a/test/test_policies.cpp b/test/test_policies.cpp index 2397cf05..ccbc4061 100644 --- a/test/test_policies.cpp +++ b/test/test_policies.cpp @@ -58,17 +58,33 @@ struct policies_test_class { delete p; } - const policies_test_class* internal_ref() { return this; } + + const policies_test_class* internal_ref() { + return this; + } + policies_test_class* self_ref() - { return this; } + { + return this; + } static int count; // private: - policies_test_class(policies_test_class const& c): name_(c.name_) - { ++count; } + policies_test_class(policies_test_class const& c) + : name_(c.name_) + { + ++count; + } + + void member_pure_out_val(int a, int* v) { + *v = a * 2; + } + + void member_out_val(int a, int* v) { + *v *= a; + } - void member_out_val(int a, int* v) { *v = a * 2; } secret_type* member_secret() { return &sec_; } }; @@ -135,7 +151,8 @@ void test_main(lua_State* L) [ class_("test") .def(constructor<>()) - .def("member_out_val", &policies_test_class::member_out_val, pure_out_value<3>()) + .def("member_pure_out_val", &policies_test_class::member_pure_out_val, pure_out_value<3>()) + .def("member_out_val", &policies_test_class::member_out_val, out_value<3>()) .def("member_secret", &policies_test_class::member_secret, discard_result()) .def("f", &policies_test_class::f, adopt_policy<2>()) .def("make", &policies_test_class::make, adopt_policy<0>()) @@ -226,7 +243,8 @@ void test_main(lua_State* L) TEST_CHECK(policies_test_class::count == 2); DOSTRING(L, "b = a:make('tjosan')"); - DOSTRING(L, "assert(a:member_out_val(3) == 6)"); + DOSTRING(L, "assert(a:member_pure_out_val(3) == 6)"); + DOSTRING(L, "assert(a:member_out_val(3,2) == 6)"); DOSTRING(L, "a:member_secret()"); // make instantiated a new policies_test_class diff --git a/test/test_typetraits.cpp b/test/test_typetraits.cpp index a8808bb9..8b9a7518 100644 --- a/test/test_typetraits.cpp +++ b/test/test_typetraits.cpp @@ -22,7 +22,6 @@ #include #include -#include using namespace luabind; using namespace luabind::detail; @@ -30,29 +29,31 @@ using namespace luabind::detail; struct tester {}; struct lua_State; +#define LUABIND_STATIC_ASSERT(expr) static_assert(expr, #expr) + int test_main(lua_State*) { - BOOST_STATIC_ASSERT(is_nonconst_reference::value); - BOOST_STATIC_ASSERT(!is_nonconst_reference::value); - BOOST_STATIC_ASSERT(is_nonconst_reference::value); - BOOST_STATIC_ASSERT(!is_nonconst_reference::value); - - BOOST_STATIC_ASSERT(!is_const_reference::value); - BOOST_STATIC_ASSERT(is_const_reference::value); - BOOST_STATIC_ASSERT(!is_const_reference::value); - BOOST_STATIC_ASSERT(is_const_reference::value); - - BOOST_STATIC_ASSERT(!is_const_pointer::value); - BOOST_STATIC_ASSERT(is_const_pointer::value); - BOOST_STATIC_ASSERT(!is_const_pointer::value); - BOOST_STATIC_ASSERT(is_const_pointer::value); - - BOOST_STATIC_ASSERT(is_nonconst_pointer::value); - BOOST_STATIC_ASSERT(!is_nonconst_pointer::value); - BOOST_STATIC_ASSERT(is_nonconst_pointer::value); - BOOST_STATIC_ASSERT(!is_nonconst_pointer::value); - - BOOST_STATIC_ASSERT(!is_const_reference::value); + LUABIND_STATIC_ASSERT(is_nonconst_reference::value); + LUABIND_STATIC_ASSERT(!is_nonconst_reference::value); + LUABIND_STATIC_ASSERT(is_nonconst_reference::value); + LUABIND_STATIC_ASSERT(!is_nonconst_reference::value); + + LUABIND_STATIC_ASSERT(!is_const_reference::value); + LUABIND_STATIC_ASSERT(is_const_reference::value); + LUABIND_STATIC_ASSERT(!is_const_reference::value); + LUABIND_STATIC_ASSERT(is_const_reference::value); + + LUABIND_STATIC_ASSERT(!is_const_pointer::value); + LUABIND_STATIC_ASSERT(is_const_pointer::value); + LUABIND_STATIC_ASSERT(!is_const_pointer::value); + LUABIND_STATIC_ASSERT(is_const_pointer::value); + + LUABIND_STATIC_ASSERT(is_nonconst_pointer::value); + LUABIND_STATIC_ASSERT(!is_nonconst_pointer::value); + LUABIND_STATIC_ASSERT(is_nonconst_pointer::value); + LUABIND_STATIC_ASSERT(!is_nonconst_pointer::value); + + LUABIND_STATIC_ASSERT(!is_const_reference::value); return 0; }