Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // (C) Copyright Pablo Halpern 2009. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@101: // (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // See http://www.boost.org/libs/container for documentation. Chris@16: // Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: #ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP Chris@16: #define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP Chris@16: Chris@101: #ifndef BOOST_CONFIG_HPP Chris@101: # include Chris@101: #endif Chris@101: Chris@101: #if defined(BOOST_HAS_PRAGMA_ONCE) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@101: Chris@101: // container Chris@16: #include Chris@101: #include Chris@101: #include //is_empty Chris@101: #include Chris@101: #ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP Chris@101: #include Chris@101: #endif Chris@101: // intrusive Chris@16: #include Chris@101: #include Chris@101: // move Chris@101: #include Chris@101: // move/detail Chris@101: #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) Chris@101: #include Chris@101: #endif Chris@101: // other boost Chris@101: #include Chris@16: Chris@101: #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED Chris@16: Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail { Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 2 Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 2 Chris@101: #include Chris@101: Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME destroy Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail { Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1 Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1 Chris@101: #include Chris@101: Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME construct Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail { Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1 Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 9 Chris@101: #include Chris@101: Chris@101: #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED Chris@16: Chris@16: namespace boost { Chris@16: namespace container { Chris@101: Chris@101: #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED Chris@101: Chris@101: namespace allocator_traits_detail { Chris@101: Chris@101: BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_max_size, max_size) Chris@101: BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_select_on_container_copy_construction, select_on_container_copy_construction) Chris@101: Chris@101: } //namespace allocator_traits_detail { Chris@101: Chris@16: namespace container_detail { Chris@16: Chris@16: //workaround needed for C++03 compilers with no construct() Chris@16: //supporting rvalue references Chris@101: template Chris@16: struct is_std_allocator Chris@16: { static const bool value = false; }; Chris@16: Chris@16: template Chris@16: struct is_std_allocator< std::allocator > Chris@16: { static const bool value = true; }; Chris@16: Chris@101: BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer) Chris@101: BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_pointer) Chris@101: BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference) Chris@101: BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reference) Chris@101: BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(void_pointer) Chris@101: BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_void_pointer) Chris@101: BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(size_type) Chris@101: BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment) Chris@101: BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment) Chris@101: BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_swap) Chris@101: BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(is_always_equal) Chris@101: BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type) Chris@101: BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(is_partially_propagable) Chris@101: Chris@16: } //namespace container_detail { Chris@16: Chris@101: #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED Chris@16: Chris@16: //! The class template allocator_traits supplies a uniform interface to all allocator types. Chris@16: //! This class is a C++03-compatible implementation of std::allocator_traits Chris@101: template Chris@16: struct allocator_traits Chris@16: { Chris@16: //allocator_type Chris@101: typedef Allocator allocator_type; Chris@16: //value_type Chris@101: typedef typename allocator_type::value_type value_type; Chris@16: Chris@16: #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) Chris@101: //! Allocator::pointer if such a type exists; otherwise, value_type* Chris@16: //! Chris@16: typedef unspecified pointer; Chris@101: //! Allocator::const_pointer if such a type exists ; otherwise, pointer_traits::rebind::rebind. Chris@16: //! Chris@16: typedef see_documentation void_pointer; Chris@101: //! Allocator::const_void_pointer if such a type exists ; otherwis e, pointer_traits::rebind::difference_type. Chris@16: //! Chris@16: typedef see_documentation difference_type; Chris@101: //! Allocator::size_type if such a type exists ; otherwise, make_unsigned::type Chris@16: //! Chris@16: typedef see_documentation size_type; Chris@101: //! Allocator::propagate_on_container_copy_assignment if such a type exists, otherwise a type Chris@101: //! with an internal constant static boolean member value == false. Chris@16: typedef see_documentation propagate_on_container_copy_assignment; Chris@101: //! Allocator::propagate_on_container_move_assignment if such a type exists, otherwise a type Chris@101: //! with an internal constant static boolean member value == false. Chris@16: typedef see_documentation propagate_on_container_move_assignment; Chris@101: //! Allocator::propagate_on_container_swap if such a type exists, otherwise a type Chris@101: //! with an internal constant static boolean member value == false. Chris@16: typedef see_documentation propagate_on_container_swap; Chris@101: //! Allocator::is_always_equal if such a type exists, otherwise a type Chris@101: //! with an internal constant static boolean member value == is_empty::value Chris@101: typedef see_documentation is_always_equal; Chris@101: //! Allocator::is_partially_propagable if such a type exists, otherwise a type Chris@101: //! with an internal constant static boolean member value == false Chris@101: //! Note: Non-standard extension used to implement `small_vector_allocator`. Chris@101: typedef see_documentation is_partially_propagable; Chris@101: //! Defines an allocator: Allocator::rebind::other if such a type exists; otherwise, Allocator Chris@101: //! if Allocator is a class template instantiation of the form Allocator, where Args is zero or Chris@16: //! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed. Chris@16: //! Chris@101: //! In C++03 compilers rebind_alloc is a struct derived from an allocator Chris@16: //! deduced by previously detailed rules. Chris@16: template using rebind_alloc = see_documentation; Chris@16: Chris@101: //! In C++03 compilers rebind_traits is a struct derived from Chris@101: //! allocator_traits, where OtherAlloc is Chris@101: //! the allocator deduced by rules explained in rebind_alloc. Chris@16: template using rebind_traits = allocator_traits >; Chris@16: Chris@16: //! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers. Chris@101: //! type is an allocator related to Allocator deduced deduced by rules explained in rebind_alloc. Chris@16: template Chris@16: struct portable_rebind_alloc Chris@16: { typedef see_documentation type; }; Chris@16: #else Chris@16: //pointer Chris@101: typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, Chris@16: pointer, value_type*) Chris@16: pointer; Chris@16: //const_pointer Chris@101: typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator, Chris@16: const_pointer, typename boost::intrusive::pointer_traits::template Chris@16: rebind_pointer) Chris@16: const_pointer; Chris@16: //reference Chris@101: typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, Chris@16: reference, typename container_detail::unvoid::type&) Chris@16: reference; Chris@16: //const_reference Chris@101: typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, Chris@16: const_reference, const typename container_detail::unvoid::type&) Chris@16: const_reference; Chris@16: //void_pointer Chris@101: typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator, Chris@16: void_pointer, typename boost::intrusive::pointer_traits::template Chris@16: rebind_pointer) Chris@16: void_pointer; Chris@16: //const_void_pointer Chris@101: typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator, Chris@16: const_void_pointer, typename boost::intrusive::pointer_traits::template Chris@16: rebind_pointer) Chris@16: const_void_pointer; Chris@16: //difference_type Chris@101: typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, Chris@16: difference_type, std::ptrdiff_t) Chris@16: difference_type; Chris@16: //size_type Chris@101: typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, Chris@16: size_type, std::size_t) Chris@16: size_type; Chris@16: //propagate_on_container_copy_assignment Chris@101: typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, Chris@101: propagate_on_container_copy_assignment, container_detail::false_type) Chris@16: propagate_on_container_copy_assignment; Chris@16: //propagate_on_container_move_assignment Chris@101: typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, Chris@101: propagate_on_container_move_assignment, container_detail::false_type) Chris@16: propagate_on_container_move_assignment; Chris@16: //propagate_on_container_swap Chris@101: typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, Chris@101: propagate_on_container_swap, container_detail::false_type) Chris@16: propagate_on_container_swap; Chris@101: //is_always_equal Chris@101: typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, Chris@101: is_always_equal, container_detail::is_empty) Chris@101: is_always_equal; Chris@101: //is_partially_propagable Chris@101: typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, Chris@101: is_partially_propagable, container_detail::false_type) Chris@101: is_partially_propagable; Chris@16: Chris@101: //rebind_alloc & rebind_traits Chris@16: #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) Chris@16: //C++11 Chris@101: template using rebind_alloc = typename boost::intrusive::pointer_rebind::type; Chris@16: template using rebind_traits = allocator_traits< rebind_alloc >; Chris@16: #else // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) Chris@16: //Some workaround for C++03 or C++11 compilers with no template aliases Chris@16: template Chris@101: struct rebind_alloc : boost::intrusive::pointer_rebind::type Chris@16: { Chris@101: typedef typename boost::intrusive::pointer_rebind::type Base; Chris@16: #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) Chris@101: template Chris@101: rebind_alloc(BOOST_FWD_REF(Args)... args) : Base(boost::forward(args)...) {} Chris@16: #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) Chris@101: #define BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC(N) \ Chris@101: BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\ Chris@101: explicit rebind_alloc(BOOST_MOVE_UREF##N) : Base(BOOST_MOVE_FWD##N){}\ Chris@101: // Chris@101: BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC) Chris@101: #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC Chris@16: #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) Chris@16: }; Chris@16: Chris@16: template Chris@16: struct rebind_traits Chris@101: : allocator_traits::type> Chris@16: {}; Chris@16: #endif // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) Chris@101: Chris@101: //portable_rebind_alloc Chris@16: template Chris@16: struct portable_rebind_alloc Chris@101: { typedef typename boost::intrusive::pointer_rebind::type type; }; Chris@16: #endif //BOOST_CONTAINER_DOXYGEN_INVOKED Chris@16: Chris@101: //! Returns: a.allocate(n) Chris@16: //! Chris@101: static pointer allocate(Allocator &a, size_type n) Chris@16: { return a.allocate(n); } Chris@16: Chris@101: //! Returns: a.deallocate(p, n) Chris@16: //! Chris@16: //! Throws: Nothing Chris@101: static void deallocate(Allocator &a, pointer p, size_type n) Chris@16: { a.deallocate(p, n); } Chris@16: Chris@101: //! Effects: calls a.allocate(n, p) if that call is well-formed; Chris@101: //! otherwise, invokes a.allocate(n) Chris@101: static pointer allocate(Allocator &a, size_type n, const_void_pointer p) Chris@16: { Chris@16: const bool value = boost::container::container_detail:: Chris@16: has_member_function_callable_with_allocate Chris@101: ::value; Chris@101: container_detail::bool_ flag; Chris@16: return allocator_traits::priv_allocate(flag, a, n, p); Chris@16: } Chris@16: Chris@101: //! Effects: calls a.destroy(p) if that call is well-formed; Chris@101: //! otherwise, invokes p->~T(). Chris@16: template Chris@101: static void destroy(Allocator &a, T*p) BOOST_NOEXCEPT_OR_NOTHROW Chris@16: { Chris@16: typedef T* destroy_pointer; Chris@16: const bool value = boost::container::container_detail:: Chris@16: has_member_function_callable_with_destroy Chris@101: ::value; Chris@101: container_detail::bool_ flag; Chris@16: allocator_traits::priv_destroy(flag, a, p); Chris@16: } Chris@16: Chris@101: //! Returns: a.max_size() if that expression is well-formed; otherwise, Chris@101: //! numeric_limits::max(). Chris@101: static size_type max_size(const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW Chris@16: { Chris@101: const bool value = allocator_traits_detail::has_max_size::value; Chris@101: container_detail::bool_ flag; Chris@16: return allocator_traits::priv_max_size(flag, a); Chris@16: } Chris@16: Chris@101: //! Returns: a.select_on_container_copy_construction() if that expression is well-formed; Chris@16: //! otherwise, a. Chris@101: static BOOST_CONTAINER_DOC1ST(Allocator, Chris@101: typename container_detail::if_c Chris@101: < allocator_traits_detail::has_select_on_container_copy_construction::value Chris@101: BOOST_MOVE_I Allocator BOOST_MOVE_I const Allocator & >::type) Chris@101: select_on_container_copy_construction(const Allocator &a) Chris@16: { Chris@101: const bool value = allocator_traits_detail::has_select_on_container_copy_construction Chris@101: ::value; Chris@101: container_detail::bool_ flag; Chris@16: return allocator_traits::priv_select_on_container_copy_construction(flag, a); Chris@16: } Chris@16: Chris@16: #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) Chris@101: //! Effects: calls a.construct(p, std::forward(args)...) if that call is well-formed; Chris@101: //! otherwise, invokes ::new (static_cast(p)) T(std::forward(args)...) Chris@16: template Chris@101: static void construct(Allocator & a, T* p, BOOST_FWD_REF(Args)... args) Chris@16: { Chris@101: container_detail::bool_::value> flag; Chris@16: allocator_traits::priv_construct(flag, a, p, ::boost::forward(args)...); Chris@16: } Chris@16: #endif Chris@101: Chris@101: //! Returns: a.storage_is_unpropagable(p) if is_partially_propagable::value is true; otherwise, Chris@101: //! false. Chris@101: static bool storage_is_unpropagable(const Allocator &a, pointer p) BOOST_NOEXCEPT_OR_NOTHROW Chris@101: { Chris@101: container_detail::bool_ flag; Chris@101: return allocator_traits::priv_storage_is_unpropagable(flag, a, p); Chris@101: } Chris@101: Chris@101: //! Returns: true if is_always_equal::value == true, otherwise, Chris@101: //! a == b. Chris@101: static bool equal(const Allocator &a, const Allocator &b) BOOST_NOEXCEPT_OR_NOTHROW Chris@101: { Chris@101: container_detail::bool_ flag; Chris@101: return allocator_traits::priv_equal(flag, a, b); Chris@101: } Chris@101: Chris@16: #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) Chris@101: private: Chris@101: static pointer priv_allocate(container_detail::true_type, Allocator &a, size_type n, const_void_pointer p) Chris@101: { return a.allocate(n, p); } Chris@101: Chris@101: static pointer priv_allocate(container_detail::false_type, Allocator &a, size_type n, const_void_pointer) Chris@101: { return a.allocate(n); } Chris@101: Chris@101: template Chris@101: static void priv_destroy(container_detail::true_type, Allocator &a, T* p) BOOST_NOEXCEPT_OR_NOTHROW Chris@101: { a.destroy(p); } Chris@101: Chris@101: template Chris@101: static void priv_destroy(container_detail::false_type, Allocator &, T* p) BOOST_NOEXCEPT_OR_NOTHROW Chris@101: { p->~T(); (void)p; } Chris@101: Chris@101: static size_type priv_max_size(container_detail::true_type, const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW Chris@101: { return a.max_size(); } Chris@101: Chris@101: static size_type priv_max_size(container_detail::false_type, const Allocator &) BOOST_NOEXCEPT_OR_NOTHROW Chris@101: { return size_type(-1)/sizeof(value_type); } Chris@101: Chris@101: static Allocator priv_select_on_container_copy_construction(container_detail::true_type, const Allocator &a) Chris@101: { return a.select_on_container_copy_construction(); } Chris@101: Chris@101: static const Allocator &priv_select_on_container_copy_construction(container_detail::false_type, const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW Chris@101: { return a; } Chris@101: Chris@101: #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) Chris@101: template Chris@101: static void priv_construct(container_detail::false_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args) Chris@101: { Chris@101: const bool value = boost::container::container_detail:: Chris@101: has_member_function_callable_with_construct Chris@101: < Allocator, T*, Args... >::value; Chris@101: container_detail::bool_ flag; Chris@101: (priv_construct_dispatch_next)(flag, a, p, ::boost::forward(args)...); Chris@101: } Chris@101: Chris@101: template Chris@101: static void priv_construct(container_detail::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args) Chris@101: { (priv_construct_dispatch_next)(container_detail::false_type(), a, p, ::boost::forward(args)...); } Chris@101: Chris@101: template Chris@101: static void priv_construct_dispatch_next(container_detail::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args) Chris@101: { a.construct( p, ::boost::forward(args)...); } Chris@101: Chris@101: template Chris@101: static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p, BOOST_FWD_REF(Args) ...args) Chris@101: { ::new((void*)p, boost_container_new_t()) T(::boost::forward(args)...); } Chris@101: #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) Chris@101: public: Chris@101: Chris@101: #define BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL(N) \ Chris@101: template\ Chris@101: static void construct(Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ Chris@101: {\ Chris@101: container_detail::bool_::value> flag;\ Chris@101: (priv_construct)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ Chris@101: }\ Chris@101: // Chris@101: BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL) Chris@101: #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL Chris@101: Chris@16: private: Chris@16: Chris@101: ////////////////// Chris@101: // priv_construct Chris@101: ////////////////// Chris@101: #define BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL(N) \ Chris@101: template\ Chris@101: static void priv_construct(container_detail::false_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ Chris@101: {\ Chris@101: const bool value = boost::container::container_detail::has_member_function_callable_with_construct\ Chris@101: < Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_FWD_T##N>::value;\ Chris@101: container_detail::bool_ flag;\ Chris@101: (priv_construct_dispatch_next)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ Chris@101: }\ Chris@101: \ Chris@101: template\ Chris@101: static void priv_construct(container_detail::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ Chris@101: { (priv_construct_dispatch_next)(container_detail::false_type(), a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ Chris@101: // Chris@101: BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL) Chris@101: #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL Chris@16: Chris@101: ///////////////////////////////// Chris@101: // priv_construct_dispatch_next Chris@101: ///////////////////////////////// Chris@101: #define BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_DISPATCH_NEXT_IMPL(N) \ Chris@101: template\ Chris@101: static void priv_construct_dispatch_next(container_detail::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ Chris@101: { a.construct( p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); }\ Chris@101: \ Chris@101: template\ Chris@101: static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ Chris@101: { ::new((void*)p, boost_container_new_t()) T(BOOST_MOVE_FWD##N); }\ Chris@101: // Chris@101: BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_DISPATCH_NEXT_IMPL) Chris@101: #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_DISPATCH_NEXT_IMPL Chris@16: Chris@101: #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) Chris@16: Chris@101: template Chris@101: static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p, const ::boost::container::default_init_t&) Chris@101: { ::new((void*)p) T; } Chris@16: Chris@101: static bool priv_storage_is_unpropagable(container_detail::true_type, const Allocator &a, pointer p) Chris@101: { return a.storage_is_unpropagable(p); } Chris@16: Chris@101: static bool priv_storage_is_unpropagable(container_detail::false_type, const Allocator &, pointer) Chris@101: { return false; } Chris@16: Chris@101: static bool priv_equal(container_detail::true_type, const Allocator &, const Allocator &) Chris@101: { return true; } Chris@16: Chris@101: static bool priv_equal(container_detail::false_type, const Allocator &a, const Allocator &b) Chris@101: { return a == b; } Chris@16: Chris@16: #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) Chris@16: }; Chris@16: Chris@16: } //namespace container { Chris@16: } //namespace boost { Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // ! defined(BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP)