From 6477543f3b5f395ed2375e8881be34609b5f42d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Tue, 14 Apr 2015 15:21:46 +0200 Subject: [PATCH] Updated to new meta-functions reused from Intrusive/Move --- include/boost/container/adaptive_pool.hpp | 6 +- include/boost/container/allocator_traits.hpp | 75 +++----- include/boost/container/deque.hpp | 28 +-- .../boost/container/detail/copy_move_algo.hpp | 43 ++--- include/boost/container/detail/iterator.hpp | 1 + include/boost/container/detail/iterators.hpp | 12 +- include/boost/container/detail/mpl.hpp | 175 ++++-------------- .../container/detail/node_alloc_holder.hpp | 6 +- include/boost/container/detail/pair.hpp | 79 +++++++- include/boost/container/detail/tree.hpp | 38 ++-- .../boost/container/detail/type_traits.hpp | 1 + include/boost/container/list.hpp | 4 +- include/boost/container/node_allocator.hpp | 6 +- include/boost/container/scoped_allocator.hpp | 52 ++++-- include/boost/container/slist.hpp | 4 +- include/boost/container/small_vector.hpp | 4 + include/boost/container/stable_vector.hpp | 47 ++--- include/boost/container/string.hpp | 35 ++-- test/allocator_traits_test.cpp | 8 +- test/dummy_test_allocator.hpp | 8 +- 20 files changed, 306 insertions(+), 326 deletions(-) diff --git a/include/boost/container/adaptive_pool.hpp b/include/boost/container/adaptive_pool.hpp index 1f6b666..59ba37b 100644 --- a/include/boost/container/adaptive_pool.hpp +++ b/include/boost/container/adaptive_pool.hpp @@ -83,9 +83,9 @@ class adaptive_pool typedef T * pointer; typedef const T * const_pointer; typedef typename ::boost::container:: - container_detail::unvoid::type & reference; - typedef const typename ::boost::container:: - container_detail::unvoid::type & const_reference; + container_detail::unvoid_ref::type reference; + typedef typename ::boost::container:: + container_detail::unvoid_ref::type const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; diff --git a/include/boost/container/allocator_traits.hpp b/include/boost/container/allocator_traits.hpp index cdaf2ea..2c7900e 100644 --- a/include/boost/container/allocator_traits.hpp +++ b/include/boost/container/allocator_traits.hpp @@ -96,6 +96,10 @@ template struct is_std_allocator< std::allocator > { static const bool value = true; }; +template +struct is_not_std_allocator +{ static const bool value = !is_std_allocator::value; }; + BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer) BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_pointer) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference) @@ -195,11 +199,11 @@ struct allocator_traits const_pointer; //reference typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, - reference, typename container_detail::unvoid::type&) + reference, typename container_detail::unvoid_ref::type) reference; //const_reference typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator, - const_reference, const typename container_detail::unvoid::type&) + const_reference, typename container_detail::unvoid_ref::type) const_reference; //void_pointer typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator, @@ -340,7 +344,12 @@ struct allocator_traits template static void construct(Allocator & a, T* p, BOOST_FWD_REF(Args)... args) { - container_detail::bool_::value> flag; + static const bool value = ::boost::move_detail::and_ + < container_detail::is_not_std_allocator + , boost::container::container_detail::has_member_function_callable_with_construct + < Allocator, T*, Args... > + >::value; + container_detail::bool_ flag; allocator_traits::priv_construct(flag, a, p, ::boost::forward(args)...); } #endif @@ -390,26 +399,12 @@ struct allocator_traits { return a; } #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template - static void priv_construct(container_detail::false_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args) - { - const bool value = boost::container::container_detail:: - has_member_function_callable_with_construct - < Allocator, T*, Args... >::value; - container_detail::bool_ flag; - (priv_construct_dispatch_next)(flag, a, p, ::boost::forward(args)...); - } - template static void priv_construct(container_detail::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args) - { (priv_construct_dispatch_next)(container_detail::false_type(), a, p, ::boost::forward(args)...); } - - template - static void priv_construct_dispatch_next(container_detail::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args) { a.construct( p, ::boost::forward(args)...); } template - static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p, BOOST_FWD_REF(Args) ...args) + static void priv_construct(container_detail::false_type, Allocator &, T *p, BOOST_FWD_REF(Args) ...args) { ::new((void*)p, boost_container_new_t()) T(::boost::forward(args)...); } #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) public: @@ -418,54 +413,38 @@ struct allocator_traits template\ static void construct(Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ {\ - container_detail::bool_::value> flag;\ + static const bool value = ::boost::move_detail::and_ \ + < container_detail::is_not_std_allocator \ + , boost::container::container_detail::has_member_function_callable_with_construct \ + < Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_FWD_T##N > \ + >::value; \ + container_detail::bool_ flag;\ (priv_construct)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ }\ // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL) + BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL) #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL private: - - ////////////////// + ///////////////////////////////// // priv_construct - ////////////////// + ///////////////////////////////// #define BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL(N) \ template\ - static void priv_construct(container_detail::false_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - {\ - const bool value = boost::container::container_detail::has_member_function_callable_with_construct\ - < Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_FWD_T##N>::value;\ - container_detail::bool_ flag;\ - (priv_construct_dispatch_next)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - }\ + static void priv_construct(container_detail::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { a.construct( p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); }\ \ template\ - static void priv_construct(container_detail::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - { (priv_construct_dispatch_next)(container_detail::false_type(), a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\ + static void priv_construct(container_detail::false_type, Allocator &, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { ::new((void*)p, boost_container_new_t()) T(BOOST_MOVE_FWD##N); }\ // BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL) #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL - ///////////////////////////////// - // priv_construct_dispatch_next - ///////////////////////////////// - #define BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_DISPATCH_NEXT_IMPL(N) \ - template\ - static void priv_construct_dispatch_next(container_detail::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - { a.construct( p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); }\ - \ - template\ - static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - { ::new((void*)p, boost_container_new_t()) T(BOOST_MOVE_FWD##N); }\ - // - BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_DISPATCH_NEXT_IMPL) - #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_DISPATCH_NEXT_IMPL - #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template - static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p, const ::boost::container::default_init_t&) + static void priv_construct(container_detail::false_type, Allocator &, T *p, const ::boost::container::default_init_t&) { ::new((void*)p) T; } static bool priv_storage_is_unpropagable(container_detail::true_type, const Allocator &a, pointer p) diff --git a/include/boost/container/deque.hpp b/include/boost/container/deque.hpp index eb372a4..bdfecc1 100644 --- a/include/boost/container/deque.hpp +++ b/include/boost/container/deque.hpp @@ -835,9 +835,10 @@ class deque : protected deque_base template void assign(InIt first, InIt last #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename container_detail::enable_if_c - < !container_detail::is_convertible::value - && container_detail::is_input_iterator::value + , typename container_detail::disable_if_or + < void + , container_detail::is_convertible + , container_detail::is_not_input_iterator >::type * = 0 #endif ) @@ -857,9 +858,10 @@ class deque : protected deque_base #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) template void assign(FwdIt first, FwdIt last - , typename container_detail::enable_if_c - < !container_detail::is_convertible::value - && !container_detail::is_input_iterator::value + , typename container_detail::disable_if_or + < void + , container_detail::is_convertible + , container_detail::is_input_iterator >::type * = 0 ) { @@ -1509,9 +1511,10 @@ class deque : protected deque_base template iterator insert(const_iterator pos, InIt first, InIt last #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename container_detail::enable_if_c - < !container_detail::is_convertible::value - && container_detail::is_input_iterator::value + , typename container_detail::disable_if_or + < void + , container_detail::is_convertible + , container_detail::is_not_input_iterator >::type * = 0 #endif ) @@ -1545,9 +1548,10 @@ class deque : protected deque_base template iterator insert(const_iterator p, FwdIt first, FwdIt last #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename container_detail::enable_if_c - < !container_detail::is_convertible::value - && !container_detail::is_input_iterator::value + , typename container_detail::disable_if_or + < void + , container_detail::is_convertible + , container_detail::is_input_iterator >::type * = 0 #endif ) diff --git a/include/boost/container/detail/copy_move_algo.hpp b/include/boost/container/detail/copy_move_algo.hpp index 79cbde8..5ae5a04 100644 --- a/include/boost/container/detail/copy_move_algo.hpp +++ b/include/boost/container/detail/copy_move_algo.hpp @@ -123,48 +123,49 @@ struct are_elements_contiguous< ::boost::interprocess::offset_ptr struct are_contiguous_and_same -{ - static const bool is_same_io = - is_same< typename remove_const< typename ::boost::container::iterator_traits::value_type >::type - , typename ::boost::container::iterator_traits::value_type - >::value; - static const bool value = is_same_io && - are_elements_contiguous::value && - are_elements_contiguous::value; -}; + : boost::move_detail::and_ + < are_elements_contiguous + , are_elements_contiguous + , is_same< typename remove_const< typename ::boost::container::iterator_traits::value_type >::type + , typename ::boost::container::iterator_traits::value_type + > + > +{}; template struct is_memtransfer_copy_assignable -{ - static const bool value = are_contiguous_and_same::value && - container_detail::is_trivially_copy_assignable< typename ::boost::container::iterator_traits::value_type >::value; -}; + : boost::move_detail::and_ + < are_contiguous_and_same + , container_detail::is_trivially_copy_assignable< typename ::boost::container::iterator_traits::value_type > + > +{}; template struct is_memtransfer_copy_constructible -{ - static const bool value = are_contiguous_and_same::value && - container_detail::is_trivially_copy_constructible< typename ::boost::container::iterator_traits::value_type >::value; -}; + : boost::move_detail::and_ + < are_contiguous_and_same + , container_detail::is_trivially_copy_constructible< typename ::boost::container::iterator_traits::value_type > + > +{}; template struct enable_if_memtransfer_copy_constructible - : enable_if_c::value, R> + : enable_if, R> {}; template struct disable_if_memtransfer_copy_constructible - : enable_if_c::value, R> + : disable_if, R> {}; template struct enable_if_memtransfer_copy_assignable - : enable_if_c::value, R> + : enable_if, R> {}; template struct disable_if_memtransfer_copy_assignable - : enable_if_c::value, R> + : disable_if, R> {}; template diff --git a/include/boost/container/detail/iterator.hpp b/include/boost/container/detail/iterator.hpp index ceb224f..8538acc 100644 --- a/include/boost/container/detail/iterator.hpp +++ b/include/boost/container/detail/iterator.hpp @@ -32,6 +32,7 @@ using ::boost::intrusive::iterator_advance; using ::boost::intrusive::iterator; using ::boost::intrusive::iterator_enable_if_tag; using ::boost::intrusive::iterator_disable_if_tag; +using ::boost::intrusive::iterator_arrow_result; } //namespace container { } //namespace boost { diff --git a/include/boost/container/detail/iterators.hpp b/include/boost/container/detail/iterators.hpp index 1f80d3e..e8cfcf9 100644 --- a/include/boost/container/detail/iterators.hpp +++ b/include/boost/container/detail/iterators.hpp @@ -651,11 +651,13 @@ namespace container_detail { template struct has_iterator_category { + struct two { char _[2]; }; + template static char test(int, typename X::iterator_category*); template - static int test(int, ...); + static two test(int, ...); static const bool value = (1 == sizeof(test(0, 0))); }; @@ -673,6 +675,12 @@ struct is_input_iterator static const bool value = false; }; +template +struct is_not_input_iterator +{ + static const bool value = !is_input_iterator::value; +}; + template::value > struct is_forward_iterator { @@ -796,7 +804,7 @@ class iterator_from_iiterator { return !(l == r); } reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW - { return (*this->m_iit).get_data(); } + { return this->m_iit->get_data(); } pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW { return ::boost::intrusive::pointer_traits::pointer_to(this->operator*()); } diff --git a/include/boost/container/detail/mpl.hpp b/include/boost/container/detail/mpl.hpp index 74b618f..e1684ea 100644 --- a/include/boost/container/detail/mpl.hpp +++ b/include/boost/container/detail/mpl.hpp @@ -23,6 +23,8 @@ #include #include +#include +#include #include @@ -30,110 +32,35 @@ namespace boost { namespace container { namespace container_detail { -template -struct integral_constant -{ - static const T value = val; - typedef integral_constant type; -}; - -template< bool C_ > -struct bool_ : integral_constant -{ - static const bool value = C_; - operator bool() const { return bool_::value; } -}; - -template< unsigned V_ > -struct unsigned_ : integral_constant -{ - static const unsigned value = V_; - operator unsigned() const { return unsigned_::value; } -}; - -typedef bool_ true_; -typedef bool_ false_; - -typedef true_ true_type; -typedef false_ false_type; - -typedef char yes_type; -struct no_type -{ - char padding[8]; -}; - -template -struct enable_if_c { - typedef T type; -}; - -template -struct enable_if_c {}; - -template -struct enable_if : public enable_if_c {}; - -template -struct disable_if : public enable_if_c {}; - -template -struct disable_if_c : public enable_if_c {}; - -#if defined(_MSC_VER) && (_MSC_VER >= 1400) - -template -struct is_convertible -{ - static const bool value = __is_convertible_to(T, U); -}; - -#else - -template -class is_convertible -{ - typedef char true_t; - class false_t { char dummy[2]; }; - //use any_conversion as first parameter since in MSVC - //overaligned types can't go through ellipsis - static false_t dispatch(...); - static true_t dispatch(U); - static T &trigger(); - public: - static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t); -}; - -#endif - -template< - bool C - , typename T1 - , typename T2 - > -struct if_c -{ - typedef T1 type; -}; - -template< - typename T1 - , typename T2 - > -struct if_c -{ - typedef T2 type; -}; - -template< - typename T1 - , typename T2 - , typename T3 - > -struct if_ -{ - typedef typename if_c<0 != T1::value, T2, T3>::type type; -}; +using boost::move_detail::integral_constant; +using boost::move_detail::true_type; +using boost::move_detail::false_type; +using boost::move_detail::enable_if_c; +using boost::move_detail::enable_if; +using boost::move_detail::enable_if_convertible; +using boost::move_detail::disable_if_c; +using boost::move_detail::disable_if; +using boost::move_detail::disable_if_convertible; +using boost::move_detail::is_convertible; +using boost::move_detail::if_c; +using boost::move_detail::if_; +using boost::move_detail::identity; +using boost::move_detail::bool_; +using boost::move_detail::true_; +using boost::move_detail::false_; +using boost::move_detail::yes_type; +using boost::move_detail::no_type; +using boost::move_detail::bool_; +using boost::move_detail::true_; +using boost::move_detail::false_; +using boost::move_detail::unvoid_ref; +using boost::move_detail::and_; +using boost::move_detail::or_; +using boost::move_detail::not_; +using boost::move_detail::enable_if_and; +using boost::move_detail::disable_if_and; +using boost::move_detail::enable_if_or; +using boost::move_detail::disable_if_or; template @@ -150,46 +77,6 @@ struct select1st { return x; } }; -// identity is an extension: it is not part of the standard. -template -struct identity -{ - typedef T argument_type; - typedef T result_type; - - typedef T type; - const T& operator()(const T& x) const - { return x; } -}; - -template -struct ls_zeros -{ - static const std::size_t value = (S & std::size_t(1)) ? 0 : (1u + ls_zeros<(S >> 1u)>::value); -}; - -template<> -struct ls_zeros<0> -{ - static const std::size_t value = 0; -}; - -template<> -struct ls_zeros<1> -{ - static const std::size_t value = 0; -}; - -template -struct ct_rounded_size -{ - static const std::size_t value = ((OrigSize-1)/RoundTo+1)*RoundTo; -}; - -template struct unvoid { typedef T type; }; -template <> struct unvoid { struct type { }; }; -template <> struct unvoid { struct type { }; }; - } //namespace container_detail { } //namespace container { } //namespace boost { diff --git a/include/boost/container/detail/node_alloc_holder.hpp b/include/boost/container/detail/node_alloc_holder.hpp index 98c8e62..a95184c 100644 --- a/include/boost/container/detail/node_alloc_holder.hpp +++ b/include/boost/container/detail/node_alloc_holder.hpp @@ -375,7 +375,7 @@ struct node_alloc_holder {} NodePtr operator()(const Node &other) const - { return m_holder.create_node(other.get_data()); } + { return m_holder.create_node(other.m_data); } node_alloc_holder &m_holder; }; @@ -387,7 +387,9 @@ struct node_alloc_holder {} NodePtr operator()(Node &other) - { return m_holder.create_node(::boost::move(other.get_data())); } + { //Use m_data instead of get_data to allow moving const key in [multi]map + return m_holder.create_node(::boost::move(other.m_data)); + } node_alloc_holder &m_holder; }; diff --git a/include/boost/container/detail/pair.hpp b/include/boost/container/detail/pair.hpp index 6d31d3b..35e8846 100644 --- a/include/boost/container/detail/pair.hpp +++ b/include/boost/container/detail/pair.hpp @@ -33,6 +33,46 @@ #include //pair #include +/* +namespace boost{ + +template +inline rv< std::pair > &move(std::pair &r) +{ + return reinterpret_cast< rv< std::pair > &>(r); +} + +template +inline rv< std::pair > &move(rv< std::pair > &r) +{ + return r; +} + +template +inline typename ::boost::move_detail::enable_if_and + < T & + , boost::container::container_detail::is_std_pair + , ::boost::move_detail::is_rv + >::type + forward(const typename ::boost::move_detail::identity::type &x) BOOST_NOEXCEPT +{ + return const_cast(x); +} + +template +inline typename ::boost::move_detail::enable_if_and + < const T & + , boost::container::container_detail::is_std_pair + , ::boost::move_detail::is_not_rv + >::type + forward(const typename ::boost::move_detail::identity::type &x) BOOST_NOEXCEPT +{ + return x; +} + +} //namespace boost { +*/ + namespace boost { namespace container { namespace container_detail { @@ -58,6 +98,24 @@ struct is_pair< std::pair > static const bool value = true; }; +template +struct is_not_pair +{ + static const bool value = !is_pair::value; +}; + +template +struct is_std_pair +{ + static const bool value = false; +}; + +template +struct is_std_pair< std::pair > +{ + static const bool value = true; +}; + struct pair_nat; struct piecewise_construct_t { }; @@ -182,10 +240,11 @@ struct pair } template - typename ::boost::container::container_detail::enable_if_c - < !(::boost::container::container_detail::is_same::value && - ::boost::container::container_detail::is_same::value) - , pair &>::type + typename ::boost::container::container_detail::disable_if_or + < pair & + , ::boost::container::container_detail::is_same + , ::boost::container::container_detail::is_same + >::type operator=(const pair&p) { first = p.first; @@ -194,18 +253,18 @@ struct pair } template - typename ::boost::container::container_detail::enable_if_c - < !(::boost::container::container_detail::is_same::value && - ::boost::container::container_detail::is_same::value) - , pair &>::type + typename ::boost::container::container_detail::disable_if_or + < pair & + , ::boost::container::container_detail::is_same + , ::boost::container::container_detail::is_same + >::type operator=(BOOST_RV_REF_BEG pair BOOST_RV_REF_END p) { first = ::boost::move(p.first); second = ::boost::move(p.second); return *this; } - - //std::pair copy assignment +//std::pair copy assignment pair& operator=(const std::pair &p) { first = p.first; diff --git a/include/boost/container/detail/tree.hpp b/include/boost/container/detail/tree.hpp index 0f90b5a..365e85a 100644 --- a/include/boost/container/detail/tree.hpp +++ b/include/boost/container/detail/tree.hpp @@ -52,6 +52,10 @@ // other #include + + +#include + namespace boost { namespace container { namespace container_detail { @@ -156,7 +160,7 @@ struct tree_internal_data_type template struct tree_internal_data_type< std::pair > { - typedef pair type; + typedef pair::type, T2> type; }; //The node to be store in the tree @@ -549,9 +553,10 @@ class tree tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp, const allocator_type& a #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename container_detail::enable_if_c - < container_detail::is_input_iterator::value - || container_detail::is_same::value + , typename container_detail::enable_if_or + < void + , container_detail::is_same + , container_detail::is_input_iterator >::type * = 0 #endif ) @@ -577,9 +582,10 @@ class tree tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp, const allocator_type& a #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename container_detail::enable_if_c - < !(container_detail::is_input_iterator::value - || container_detail::is_same::value) + , typename container_detail::disable_if_or + < void + , container_detail::is_same + , container_detail::is_input_iterator >::type * = 0 #endif ) @@ -606,10 +612,11 @@ class tree tree( ordered_range_t, InputIterator first, InputIterator last , const key_compare& comp = key_compare(), const allocator_type& a = allocator_type() #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename container_detail::enable_if_c - < container_detail::is_input_iterator::value - || container_detail::is_same::value - >::type * = 0 + , typename container_detail::enable_if_or + < void + , container_detail::is_same + , container_detail::is_input_iterator + >::type * = 0 #endif ) : AllocHolder(value_compare(comp), a) @@ -623,10 +630,11 @@ class tree tree( ordered_range_t, InputIterator first, InputIterator last , const key_compare& comp = key_compare(), const allocator_type& a = allocator_type() #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename container_detail::enable_if_c - < !(container_detail::is_input_iterator::value - || container_detail::is_same::value) - >::type * = 0 + , typename container_detail::disable_if_or + < void + , container_detail::is_same + , container_detail::is_input_iterator + >::type * = 0 #endif ) : AllocHolder(value_compare(comp), a) diff --git a/include/boost/container/detail/type_traits.hpp b/include/boost/container/detail/type_traits.hpp index 1ae2426..e02709a 100644 --- a/include/boost/container/detail/type_traits.hpp +++ b/include/boost/container/detail/type_traits.hpp @@ -31,6 +31,7 @@ namespace container { namespace container_detail { using ::boost::move_detail::is_same; +using ::boost::move_detail::is_different; using ::boost::move_detail::is_pointer; using ::boost::move_detail::add_reference; using ::boost::move_detail::add_const; diff --git a/include/boost/container/list.hpp b/include/boost/container/list.hpp index 54da6df..5135eae 100644 --- a/include/boost/container/list.hpp +++ b/include/boost/container/list.hpp @@ -417,9 +417,7 @@ class list template void assign(InpIt first, InpIt last #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename container_detail::enable_if_c - < !container_detail::is_convertible::value - >::type * = 0 + , typename container_detail::disable_if_convertible::type * = 0 #endif ) { diff --git a/include/boost/container/node_allocator.hpp b/include/boost/container/node_allocator.hpp index afd6f98..c3d8090 100644 --- a/include/boost/container/node_allocator.hpp +++ b/include/boost/container/node_allocator.hpp @@ -74,9 +74,9 @@ class node_allocator typedef T * pointer; typedef const T * const_pointer; typedef typename ::boost::container:: - container_detail::unvoid::type & reference; - typedef const typename ::boost::container:: - container_detail::unvoid::type & const_reference; + container_detail::unvoid_ref::type reference; + typedef typename ::boost::container:: + container_detail::unvoid_ref::type const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; diff --git a/include/boost/container/scoped_allocator.hpp b/include/boost/container/scoped_allocator.hpp index 55514aa..0724f94 100644 --- a/include/boost/container/scoped_allocator.hpp +++ b/include/boost/container/scoped_allocator.hpp @@ -1129,7 +1129,7 @@ class scoped_allocator_adaptor #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) void #else - typename container_detail::enable_if_c::value, void>::type + typename container_detail::enable_if >::type #endif construct(T* p, BOOST_FWD_REF(Args)...args) { @@ -1146,7 +1146,7 @@ class scoped_allocator_adaptor //overload selection problems when the first parameter is a pair. #define BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE(N) \ template < typename T BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\ - typename container_detail::enable_if_c::value, void>::type\ + typename container_detail::enable_if< container_detail::is_not_pair >::type\ construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\ {\ container_detail::dispatch_uses_allocator\ @@ -1188,12 +1188,12 @@ class scoped_allocator_adaptor template void construct( std::pair* p , BOOST_RV_REF_BEG std::pair BOOST_RV_REF_END x) - { this->construct_pair(p, x); } + { this->construct_pair(p, ::boost::move(x)); } template void construct( container_detail::pair* p , BOOST_RV_REF_BEG container_detail::pair BOOST_RV_REF_END x) - { this->construct_pair(p, x); } + { this->construct_pair(p, ::boost::move(x)); } #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: @@ -1246,6 +1246,39 @@ class scoped_allocator_adaptor #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; +template +struct scoped_allocator_operator_equal +{ + //Optimize equal outer allocator types with + //allocator_traits::equal which uses is_always_equal + template + static bool equal_outer(const IA &l, const IA &r) + { return allocator_traits::equal(l, r); } + + //Otherwise compare it normally + template + static bool equal_outer(const IA1 &l, const IA2 &r) + { return l == r; } + + //Otherwise compare it normally + template + static bool equal_inner(const IA &l, const IA &r) + { return allocator_traits::equal(l, r); } +}; + +template<> +struct scoped_allocator_operator_equal + : scoped_allocator_operator_equal +{ + //when inner allocator count is zero, + //inner_allocator_type is the same as outer_allocator_type + //so both types can be different in operator== + template + static bool equal_inner(const IA1 &, const IA2 &) + { return true; } +}; + + template inline bool operator==(const scoped_allocator_adaptor& a ,const scoped_allocator_adaptor& b) @@ -1255,14 +1288,9 @@ inline bool operator==(const scoped_allocator_adaptor::value; #endif - typedef typename scoped_allocator_adaptor - ::outer_allocator_type outer_allocator_type; - typedef typename scoped_allocator_adaptor - ::inner_allocator_type inner_allocator_type; - - return allocator_traits::equal(a.outer_allocator(), b.outer_allocator()) - && (has_zero_inner || - allocator_traits::equal(a.inner_allocator(), b.inner_allocator())); + typedef scoped_allocator_operator_equal equal_t; + return equal_t::equal_outer(a.outer_allocator(), b.outer_allocator()) && + equal_t::equal_inner(a.inner_allocator(), b.inner_allocator()); } template diff --git a/include/boost/container/slist.hpp b/include/boost/container/slist.hpp index b0901ef..2b53df1 100644 --- a/include/boost/container/slist.hpp +++ b/include/boost/container/slist.hpp @@ -442,9 +442,7 @@ class slist template void assign(InpIt first, InpIt last #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename container_detail::enable_if_c - < !container_detail::is_convertible::value - >::type * = 0 + , typename container_detail::disable_if_convertible::type * = 0 #endif ) { diff --git a/include/boost/container/small_vector.hpp b/include/boost/container/small_vector.hpp index 7ef0c23..4c5a59c 100644 --- a/include/boost/container/small_vector.hpp +++ b/include/boost/container/small_vector.hpp @@ -311,8 +311,12 @@ class small_vector_base : public vector > { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + public: + //Make it public as it will be inherited by small_vector and container + //must have this public member typedef typename allocator_traits::pointer pointer; + private: BOOST_COPYABLE_AND_MOVABLE(small_vector_base) friend class small_vector_allocator; diff --git a/include/boost/container/stable_vector.hpp b/include/boost/container/stable_vector.hpp index 76c9e9f..c801ba1 100644 --- a/include/boost/container/stable_vector.hpp +++ b/include/boost/container/stable_vector.hpp @@ -349,7 +349,7 @@ class stable_vector_iterator return tmp; } - friend difference_type operator-(const stable_vector_iterator& left, const stable_vector_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW + friend difference_type operator-(const stable_vector_iterator &left, const stable_vector_iterator &right) BOOST_NOEXCEPT_OR_NOTHROW { return left.m_pn->up - right.m_pn->up; } //Comparison operators @@ -493,7 +493,7 @@ class stable_vector , false> iterator_impl; typedef stable_vector_iterator < typename allocator_traits::pointer - , false> const_iterator_impl; + , true> const_iterator_impl; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -850,13 +850,12 @@ class stable_vector //! //! Complexity: Linear to n. template - void assign(InputIterator first,InputIterator last - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename container_detail::enable_if_c - < !container_detail::is_convertible::value - >::type * = 0 - #endif - ) + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + typename container_detail::disable_if_convertible::type + #else + void + #endif + assign(InputIterator first,InputIterator last) { STABLE_VECTOR_CHECK_INVARIANT; iterator first1 = this->begin(); @@ -1517,14 +1516,16 @@ class stable_vector //! //! Complexity: Linear to distance [first, last). template - iterator insert(const_iterator p, InputIterator first, InputIterator last - #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename container_detail::enable_if_c - < !container_detail::is_convertible::value - && container_detail::is_input_iterator::value - >::type * = 0 - #endif - ) + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + typename container_detail::disable_if_or + < iterator + , container_detail::is_convertible + , container_detail::is_not_input_iterator + >::type + #else + iterator + #endif + insert(const_iterator p, InputIterator first, InputIterator last) { STABLE_VECTOR_CHECK_INVARIANT; const size_type pos_n = p - this->cbegin(); @@ -1536,12 +1537,12 @@ class stable_vector #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) template - iterator insert(const_iterator p, FwdIt first, FwdIt last - , typename container_detail::enable_if_c - < !container_detail::is_convertible::value - && !container_detail::is_input_iterator::value - >::type * = 0 - ) + typename container_detail::disable_if_or + < iterator + , container_detail::is_convertible + , container_detail::is_input_iterator + >::type + insert(const_iterator p, FwdIt first, FwdIt last) { const size_type num_new = static_cast(boost::container::iterator_distance(first, last)); const size_type idx = static_cast(p - this->cbegin()); diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp index e5ec287..463c187 100644 --- a/include/boost/container/string.hpp +++ b/include/boost/container/string.hpp @@ -165,8 +165,7 @@ class basic_string_base static const size_type MinInternalBufferChars = 8; static const size_type AlignmentOfValueType = alignment_of::value; - static const size_type ShortDataOffset = - container_detail::ct_rounded_size::value; + static const size_type ShortDataOffset = ((sizeof(short_header)-1)/AlignmentOfValueType+1)*AlignmentOfValueType; static const size_type ZeroCostInternalBufferChars = (sizeof(long_t) - ShortDataOffset)/sizeof(value_type); static const size_type UnalignedFinalInternalBufferChars = @@ -1289,9 +1288,7 @@ class basic_string template basic_string& assign(InputIter first, InputIter last #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename container_detail::enable_if_c - < !container_detail::is_convertible::value - >::type * = 0 + , typename container_detail::disable_if_convertible::type * = 0 #endif ) { @@ -1438,9 +1435,10 @@ class basic_string template iterator insert(const_iterator p, InputIter first, InputIter last #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename container_detail::enable_if_c - < !container_detail::is_convertible::value - && container_detail::is_input_iterator::value + , typename container_detail::disable_if_or + < void + , container_detail::is_convertible + , container_detail::is_not_input_iterator >::type * = 0 #endif ) @@ -1455,9 +1453,10 @@ class basic_string #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) template iterator insert(const_iterator p, ForwardIter first, ForwardIter last - , typename container_detail::enable_if_c - < !container_detail::is_convertible::value - && !container_detail::is_input_iterator::value + , typename container_detail::disable_if_or + < void + , container_detail::is_convertible + , container_detail::is_input_iterator >::type * = 0 ) { @@ -1829,9 +1828,10 @@ class basic_string template basic_string& replace(const_iterator i1, const_iterator i2, InputIter j1, InputIter j2 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename container_detail::enable_if_c - < !container_detail::is_convertible::value - && container_detail::is_input_iterator::value + , typename container_detail::disable_if_or + < void + , container_detail::is_convertible + , container_detail::is_input_iterator >::type * = 0 #endif ) @@ -1850,9 +1850,10 @@ class basic_string #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) template basic_string& replace(const_iterator i1, const_iterator i2, ForwardIter j1, ForwardIter j2 - , typename container_detail::enable_if_c - < !container_detail::is_convertible::value - && !container_detail::is_input_iterator::value + , typename container_detail::disable_if_or + < void + , container_detail::is_convertible + , container_detail::is_not_input_iterator >::type * = 0 ) { diff --git a/test/allocator_traits_test.cpp b/test/allocator_traits_test.cpp index 3f4dff0..0885f0b 100644 --- a/test/allocator_traits_test.cpp +++ b/test/allocator_traits_test.cpp @@ -105,10 +105,10 @@ class ComplexAllocator typedef T value_type; typedef SimpleSmartPtr pointer; typedef SimpleSmartPtr const_pointer; - typedef typename boost::container:: - container_detail::unvoid::type & reference; - typedef const typename boost::container:: - container_detail::unvoid::type & const_reference; + typedef typename ::boost::container:: + container_detail::unvoid_ref::type reference; + typedef typename ::boost::container:: + container_detail::unvoid_ref::type const_reference; typedef SimpleSmartPtr void_pointer; typedef SimpleSmartPtr const_void_pointer; typedef signed short difference_type; diff --git a/test/dummy_test_allocator.hpp b/test/dummy_test_allocator.hpp index a9f0b82..5b6e99a 100644 --- a/test/dummy_test_allocator.hpp +++ b/test/dummy_test_allocator.hpp @@ -86,10 +86,10 @@ class dummy_test_allocator typedef T value_type; typedef T * pointer; typedef const T * const_pointer; - typedef typename container_detail::add_reference - ::type reference; - typedef typename container_detail::add_reference - ::type const_reference; + typedef typename container_detail:: + unvoid_ref::type reference; + typedef typename container_detail:: + unvoid_ref::type const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type;