diff options
Diffstat (limited to 'boost/container/detail')
-rw-r--r-- | boost/container/detail/advanced_insert_int.hpp | 14 | ||||
-rw-r--r-- | boost/container/detail/container_rebind.hpp | 137 | ||||
-rw-r--r-- | boost/container/detail/copy_move_algo.hpp | 7 | ||||
-rw-r--r-- | boost/container/detail/flat_tree.hpp | 40 | ||||
-rw-r--r-- | boost/container/detail/mpl.hpp | 4 | ||||
-rw-r--r-- | boost/container/detail/thread_mutex.hpp | 10 | ||||
-rw-r--r-- | boost/container/detail/tree.hpp | 74 | ||||
-rw-r--r-- | boost/container/detail/version_type.hpp | 7 |
8 files changed, 102 insertions, 191 deletions
diff --git a/boost/container/detail/advanced_insert_int.hpp b/boost/container/detail/advanced_insert_int.hpp index 17ceb013fd..28e7ae953f 100644 --- a/boost/container/detail/advanced_insert_int.hpp +++ b/boost/container/detail/advanced_insert_int.hpp @@ -128,7 +128,7 @@ struct insert_value_initialized_n_proxy void copy_n_and_update(Allocator &a, Iterator p, size_type n) const { for (; 0 < n; --n, ++p){ - typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v; + typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v; value_type *vp = reinterpret_cast<value_type *>(v.data); alloc_traits::construct(a, vp); value_destructor<Allocator> on_exit(a, *vp); (void)on_exit; @@ -151,7 +151,7 @@ struct insert_default_initialized_n_proxy { if(!is_pod<value_type>::value){ for (; 0 < n; --n, ++p){ - typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v; + typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v; value_type *vp = reinterpret_cast<value_type *>(v.data); alloc_traits::construct(a, vp, default_init); value_destructor<Allocator> on_exit(a, *vp); (void)on_exit; @@ -195,17 +195,17 @@ struct insert_move_proxy typedef typename alloc_traits::size_type size_type; typedef typename alloc_traits::value_type value_type; - explicit insert_move_proxy(value_type &v) + BOOST_CONTAINER_FORCEINLINE explicit insert_move_proxy(value_type &v) : v_(v) {} - void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const { BOOST_ASSERT(n == 1); (void)n; alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::move(v_) ); } - void copy_n_and_update(Allocator &, Iterator p, size_type n) const + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n) const { BOOST_ASSERT(n == 1); (void)n; *p = ::boost::move(v_); @@ -288,7 +288,7 @@ struct insert_emplace_proxy void priv_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n) { BOOST_ASSERT(n ==1); (void)n; - typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v; + typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v; value_type *vp = reinterpret_cast<value_type *>(v.data); alloc_traits::construct(a, vp, ::boost::forward<Args>(get<IdxPack>(this->args_))...); @@ -398,7 +398,7 @@ struct insert_emplace_proxy_arg##N\ void copy_n_and_update(Allocator &a, Iterator p, size_type n)\ {\ BOOST_ASSERT(n == 1); (void)n;\ - typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\ + typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;\ BOOST_ASSERT((((size_type)(&v)) % alignment_of<value_type>::value) == 0);\ value_type *vp = reinterpret_cast<value_type *>(v.data);\ alloc_traits::construct(a, vp BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ diff --git a/boost/container/detail/container_rebind.hpp b/boost/container/detail/container_rebind.hpp index 0ebb4789e4..0af9b9e9f4 100644 --- a/boost/container/detail/container_rebind.hpp +++ b/boost/container/detail/container_rebind.hpp @@ -19,6 +19,7 @@ #endif #include <boost/container/allocator_traits.hpp> +#include <boost/container/container_fwd.hpp> namespace boost { @@ -33,14 +34,14 @@ namespace dtl { template <template <class, class, class...> class Cont, typename V, typename A, class... An, class U> struct container_rebind<Cont<V, A, An...>, U> { - typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, An...> type; + typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, An...> type; }; //Needed for non-conforming compilers like GCC 4.3 template <template <class, class> class Cont, typename V, typename A, class U> struct container_rebind<Cont<V, A>, U> { - typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type; + typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type> type; }; template <template <class> class Cont, typename V, class U> @@ -49,27 +50,6 @@ namespace dtl { typedef Cont<U> type; }; - //for small_vector,static_vector - - template <template <class, std::size_t, class, class...> class Cont, typename V, std::size_t N, typename A, class... An, class U> - struct container_rebind<Cont<V, N, A, An...>, U> - { - typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, An...> type; - }; - - //Needed for non-conforming compilers like GCC 4.3 - template <template <class, std::size_t, class> class Cont, typename V, std::size_t N, typename A, class U> - struct container_rebind<Cont<V, N, A>, U> - { - typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type; - }; - - template <template <class, std::size_t> class Cont, typename V, std::size_t N, class U> - struct container_rebind<Cont<V, N>, U> - { - typedef Cont<U, N> type; - }; - #else //C++03 compilers template <template <class> class Cont //0arg @@ -85,7 +65,7 @@ namespace dtl { , class U> struct container_rebind<Cont<V, A>, U> { - typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type; + typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type> type; }; template <template <class, class, class> class Cont //1arg @@ -93,7 +73,7 @@ namespace dtl { , class U> struct container_rebind<Cont<V, A, P0>, U> { - typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0> type; + typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0> type; }; template <template <class, class, class, class> class Cont //2arg @@ -101,7 +81,7 @@ namespace dtl { , class U> struct container_rebind<Cont<V, A, P0, P1>, U> { - typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1> type; + typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1> type; }; template <template <class, class, class, class, class> class Cont //3arg @@ -109,7 +89,7 @@ namespace dtl { , class U> struct container_rebind<Cont<V, A, P0, P1, P2>, U> { - typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2> type; + typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2> type; }; template <template <class, class, class, class, class, class> class Cont //4arg @@ -117,7 +97,7 @@ namespace dtl { , class U> struct container_rebind<Cont<V, A, P0, P1, P2, P3>, U> { - typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3> type; + typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3> type; }; template <template <class, class, class, class, class, class, class> class Cont //5arg @@ -125,7 +105,7 @@ namespace dtl { , class U> struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4>, U> { - typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4> type; + typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4> type; }; template <template <class, class, class, class, class, class, class, class> class Cont //6arg @@ -133,7 +113,7 @@ namespace dtl { , class U> struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5>, U> { - typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5> type; + typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5> type; }; template <template <class, class, class, class, class, class, class, class, class> class Cont //7arg @@ -141,7 +121,7 @@ namespace dtl { , class U> struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6>, U> { - typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6> type; + typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6> type; }; template <template <class, class, class, class, class, class, class, class, class, class> class Cont //8arg @@ -149,7 +129,7 @@ namespace dtl { , class U> struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6, P7>, U> { - typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7> type; + typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7> type; }; template <template <class, class, class, class, class, class, class, class, class, class, class> class Cont //9arg @@ -157,100 +137,25 @@ namespace dtl { , class U> struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6, P7, P8>, U> { - typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7, P8> type; - }; - - //For small_vector/static_vector - template <template <class, std::size_t> class Cont //0arg - , typename V, std::size_t N - , class U> - struct container_rebind<Cont<V, N>, U> - { - typedef Cont<U, N> type; - }; - - template <template <class, std::size_t, class> class Cont //0arg - , typename V, std::size_t N, typename A - , class U> - struct container_rebind<Cont<V, N, A>, U> - { - typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type; - }; - - template <template <class, std::size_t, class, class> class Cont //1arg - , typename V, std::size_t N, typename A, class P0 - , class U> - struct container_rebind<Cont<V, N, A, P0>, U> - { - typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0> type; - }; - - template <template <class, std::size_t, class, class, class> class Cont //2arg - , typename V, std::size_t N, typename A, class P0, class P1 - , class U> - struct container_rebind<Cont<V, N, A, P0, P1>, U> - { - typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1> type; - }; - - template <template <class, std::size_t, class, class, class, class> class Cont //3arg - , typename V, std::size_t N, typename A, class P0, class P1, class P2 - , class U> - struct container_rebind<Cont<V, N, A, P0, P1, P2>, U> - { - typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2> type; - }; - - template <template <class, std::size_t, class, class, class, class, class> class Cont //4arg - , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3 - , class U> - struct container_rebind<Cont<V, N, A, P0, P1, P2, P3>, U> - { - typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3> type; - }; - - template <template <class, std::size_t, class, class, class, class, class, class> class Cont //5arg - , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4 - , class U> - struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4>, U> - { - typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4> type; + typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7, P8> type; }; - template <template <class, std::size_t, class, class, class, class, class, class, class> class Cont //6arg - , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5 - , class U> - struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5>, U> - { - typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5> type; - }; +#endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template <template <class, std::size_t, class, class, class, class, class, class, class, class> class Cont //7arg - , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6 - , class U> - struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5, P6>, U> - { - typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6> type; - }; + //for small_vector,static_vector - template <template <class, std::size_t, class, class, class, class, class, class, class, class, class> class Cont //8arg - , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7 - , class U> - struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5, P6, P7>, U> + template <typename V, std::size_t N, typename A, class U> + struct container_rebind<small_vector<V, N, A>, U> { - typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7> type; + typedef small_vector<U, N, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type> type; }; - template <template <class, std::size_t, class, class, class, class, class, class, class, class, class, class> class Cont //9arg - , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8 - , class U> - struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5, P6, P7, P8>, U> + template <typename V, std::size_t N, typename O, class U> + struct container_rebind<static_vector<V, N, O>, U> { - typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7, P8> type; + typedef static_vector<U, N, O> type; }; -#endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - } //namespace dtl { } //namespace container { } //namespace boost { diff --git a/boost/container/detail/copy_move_algo.hpp b/boost/container/detail/copy_move_algo.hpp index 29d47ccbda..b71560d9e5 100644 --- a/boost/container/detail/copy_move_algo.hpp +++ b/boost/container/detail/copy_move_algo.hpp @@ -177,8 +177,7 @@ inline F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW value_type *const dest_raw = boost::movelib::iterator_to_raw_pointer(r); const value_type *const beg_raw = boost::movelib::iterator_to_raw_pointer(f); const value_type *const end_raw = boost::movelib::iterator_to_raw_pointer(l); - if(BOOST_LIKELY(beg_raw != end_raw)){ - BOOST_ASSERT(beg_raw != 0); + if(BOOST_LIKELY(beg_raw != end_raw && dest_raw && beg_raw)){ const typename boost::container::iterator_traits<I>::difference_type n = end_raw - beg_raw; std::memmove(dest_raw, beg_raw, sizeof(value_type)*n); boost::container::iterator_advance(r, n); @@ -522,9 +521,9 @@ inline typename dtl::disable_if_memtransfer_copy_constructible<I, F, I>::type { F back = r; BOOST_TRY{ - while (n--) { + while (n) { boost::container::construct_in_place(a, boost::movelib::iterator_to_raw_pointer(r), f); - ++f; ++r; + ++f; ++r; --n; } } BOOST_CATCH(...){ diff --git a/boost/container/detail/flat_tree.hpp b/boost/container/detail/flat_tree.hpp index 476a63aca0..c346360b46 100644 --- a/boost/container/detail/flat_tree.hpp +++ b/boost/container/detail/flat_tree.hpp @@ -205,7 +205,7 @@ BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_unique //has_merge_unique == f size_type const old_sz = dest.size(); iterator const first_new = dest.insert(dest.cend(), first, last ); - iterator e = boost::movelib::inplace_set_difference(first_new, dest.end(), dest.begin(), first_new, comp); + iterator e = boost::movelib::inplace_set_unique_difference(first_new, dest.end(), dest.begin(), first_new, comp); dest.erase(e, dest.end()); dtl::bool_<is_contiguous_container<SequenceContainer>::value> contiguous_tag; (flat_tree_container_inplace_merge)(dest, dest.begin()+old_sz, comp, contiguous_tag); @@ -883,10 +883,14 @@ class flat_tree //Step 3: only left unique values from the back not already present in the original range typename container_type::iterator const e = boost::movelib::inplace_set_unique_difference (it, seq.end(), seq.begin(), it, val_cmp); - seq.erase(e, seq.cend()); - //Step 4: merge both ranges - (flat_tree_container_inplace_merge)(seq, it, this->priv_value_comp(), contiguous_tag); + seq.erase(e, seq.cend()); + //it might be invalidated by erasing [e, seq.end) if e == it + if (it != e) + { + //Step 4: merge both ranges + (flat_tree_container_inplace_merge)(seq, it, this->priv_value_comp(), contiguous_tag); + } } template <class InIt> @@ -922,7 +926,7 @@ class flat_tree template <class... Args> std::pair<iterator, bool> emplace_unique(BOOST_FWD_REF(Args)... args) { - typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v; + typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v; value_type *pval = reinterpret_cast<value_type *>(v.data); get_stored_allocator_noconst_return_t a = this->get_stored_allocator(); stored_allocator_traits::construct(a, pval, ::boost::forward<Args>(args)... ); @@ -934,7 +938,7 @@ class flat_tree iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... args) { //hint checked in insert_unique - typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v; + typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v; value_type *pval = reinterpret_cast<value_type *>(v.data); get_stored_allocator_noconst_return_t a = this->get_stored_allocator(); stored_allocator_traits::construct(a, pval, ::boost::forward<Args>(args)... ); @@ -945,7 +949,7 @@ class flat_tree template <class... Args> iterator emplace_equal(BOOST_FWD_REF(Args)... args) { - typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v; + typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v; value_type *pval = reinterpret_cast<value_type *>(v.data); get_stored_allocator_noconst_return_t a = this->get_stored_allocator(); stored_allocator_traits::construct(a, pval, ::boost::forward<Args>(args)... ); @@ -957,7 +961,7 @@ class flat_tree iterator emplace_hint_equal(const_iterator hint, BOOST_FWD_REF(Args)... args) { //hint checked in insert_equal - typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v; + typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v; value_type *pval = reinterpret_cast<value_type *>(v.data); get_stored_allocator_noconst_return_t a = this->get_stored_allocator(); stored_allocator_traits::construct(a, pval, ::boost::forward<Args>(args)... ); @@ -994,7 +998,7 @@ class flat_tree BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ std::pair<iterator, bool> emplace_unique(BOOST_MOVE_UREF##N)\ {\ - typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\ + typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;\ value_type *pval = reinterpret_cast<value_type *>(v.data);\ get_stored_allocator_noconst_return_t a = this->get_stored_allocator();\ stored_allocator_traits::construct(a, pval BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ @@ -1005,7 +1009,7 @@ class flat_tree BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ iterator emplace_hint_unique(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ {\ - typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\ + typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;\ value_type *pval = reinterpret_cast<value_type *>(v.data);\ get_stored_allocator_noconst_return_t a = this->get_stored_allocator();\ stored_allocator_traits::construct(a, pval BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ @@ -1016,7 +1020,7 @@ class flat_tree BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ iterator emplace_equal(BOOST_MOVE_UREF##N)\ {\ - typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\ + typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;\ value_type *pval = reinterpret_cast<value_type *>(v.data);\ get_stored_allocator_noconst_return_t a = this->get_stored_allocator();\ stored_allocator_traits::construct(a, pval BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ @@ -1027,7 +1031,7 @@ class flat_tree BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ iterator emplace_hint_equal(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ {\ - typename aligned_storage <sizeof(value_type), alignment_of<value_type>::value>::type v;\ + typename dtl::aligned_storage <sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;\ value_type *pval = reinterpret_cast<value_type *>(v.data);\ get_stored_allocator_noconst_return_t a = this->get_stored_allocator();\ stored_allocator_traits::construct(a, pval BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ @@ -1601,7 +1605,7 @@ class flat_tree const Compare &key_cmp = this->m_data.get_comp(); KeyOfValue key_extract; RanIt lb(this->priv_lower_bound(first, last, k)), ub(lb); - if(lb != last && static_cast<difference_type>(!key_cmp(k, key_extract(*lb)))){ + if(lb != last && !key_cmp(k, key_extract(*lb))){ ++ub; } return std::pair<RanIt, RanIt>(lb, ub); @@ -1618,11 +1622,11 @@ template <class T, class KeyOfValue, class Compare, class AllocatorOrContainer> struct has_trivial_destructor_after_move<boost::container::dtl::flat_tree<T, KeyOfValue, Compare, AllocatorOrContainer> > { - typedef typename boost::container::dtl::select_container_type<T, AllocatorOrContainer>::type container_type; - typedef typename container_type::allocator_type allocator_t; - typedef typename ::boost::container::allocator_traits<allocator_t>::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move<allocator_t>::value && - ::boost::has_trivial_destructor_after_move<pointer>::value; + typedef boost::container::dtl::flat_tree<T, KeyOfValue, Compare, AllocatorOrContainer> flat_tree; + typedef typename flat_tree::container_type container_type; + typedef typename flat_tree::key_compare key_compare; + static const bool value = ::boost::has_trivial_destructor_after_move<container_type>::value && + ::boost::has_trivial_destructor_after_move<key_compare>::value; }; } //namespace boost { diff --git a/boost/container/detail/mpl.hpp b/boost/container/detail/mpl.hpp index 4706c58022..ffae180c85 100644 --- a/boost/container/detail/mpl.hpp +++ b/boost/container/detail/mpl.hpp @@ -69,11 +69,11 @@ struct select1st typedef FirstType type; template<class T> - const type& operator()(const T& x) const + BOOST_CONTAINER_FORCEINLINE const type& operator()(const T& x) const { return x.first; } template<class T> - type& operator()(T& x) + BOOST_CONTAINER_FORCEINLINE type& operator()(T& x) { return const_cast<type&>(x.first); } }; diff --git a/boost/container/detail/thread_mutex.hpp b/boost/container/detail/thread_mutex.hpp index 66d64b9c5e..4027ff2e01 100644 --- a/boost/container/detail/thread_mutex.hpp +++ b/boost/container/detail/thread_mutex.hpp @@ -142,25 +142,25 @@ class thread_mutex thread_mutex() { #ifdef BOOST_PLAT_WINDOWS_UWP - InitializeCriticalSectionEx(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect), 4000, 0); + (InitializeCriticalSectionEx)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect), 4000, 0); #else - InitializeCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); + (InitializeCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); #endif } void lock() { - EnterCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); + (EnterCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); } void unlock() { - LeaveCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); + (LeaveCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); } ~thread_mutex() { - DeleteCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); + (DeleteCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); } private: diff --git a/boost/container/detail/tree.hpp b/boost/container/detail/tree.hpp index 08965e5a6d..23fbfded5d 100644 --- a/boost/container/detail/tree.hpp +++ b/boost/container/detail/tree.hpp @@ -788,7 +788,7 @@ class tree tree& operator=(BOOST_COPY_ASSIGN_REF(tree) x) { - if (&x != this){ + if (BOOST_LIKELY(this != &x)) { NodeAlloc &this_alloc = this->get_stored_allocator(); const NodeAlloc &x_alloc = x.get_stored_allocator(); dtl::bool_<allocator_traits<NodeAlloc>:: @@ -822,39 +822,40 @@ class tree allocator_traits_type::is_always_equal::value) && boost::container::dtl::is_nothrow_move_assignable<Compare>::value) { - BOOST_ASSERT(this != &x); - NodeAlloc &this_alloc = this->node_alloc(); - NodeAlloc &x_alloc = x.node_alloc(); - const bool propagate_alloc = allocator_traits<NodeAlloc>:: - propagate_on_container_move_assignment::value; - const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal; - //Resources can be transferred if both allocators are - //going to be equal after this function (either propagated or already equal) - if(propagate_alloc || allocators_equal){ - //Destroy - this->clear(); - //Move allocator if needed - this->AllocHolder::move_assign_alloc(x); - //Obtain resources - this->icont() = boost::move(x.icont()); - } - //Else do a one by one move - else{ - //Transfer all the nodes to a temporary tree - //If anything goes wrong, all the nodes will be destroyed - //automatically - Icont other_tree(::boost::move(this->icont())); - - //Now recreate the source tree reusing nodes stored by other_tree - this->icont().clone_from - (::boost::move(x.icont()) - , RecyclingCloner<AllocHolder, true>(*this, other_tree) - , Destroyer(this->node_alloc())); - - //If there are remaining nodes, destroy them - NodePtr p; - while((p = other_tree.unlink_leftmost_without_rebalance())){ - AllocHolder::destroy_node(p); + if (BOOST_LIKELY(this != &x)) { + NodeAlloc &this_alloc = this->node_alloc(); + NodeAlloc &x_alloc = x.node_alloc(); + const bool propagate_alloc = allocator_traits<NodeAlloc>:: + propagate_on_container_move_assignment::value; + const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal; + //Resources can be transferred if both allocators are + //going to be equal after this function (either propagated or already equal) + if(propagate_alloc || allocators_equal){ + //Destroy + this->clear(); + //Move allocator if needed + this->AllocHolder::move_assign_alloc(x); + //Obtain resources + this->icont() = boost::move(x.icont()); + } + //Else do a one by one move + else{ + //Transfer all the nodes to a temporary tree + //If anything goes wrong, all the nodes will be destroyed + //automatically + Icont other_tree(::boost::move(this->icont())); + + //Now recreate the source tree reusing nodes stored by other_tree + this->icont().clone_from + (::boost::move(x.icont()) + , RecyclingCloner<AllocHolder, true>(*this, other_tree) + , Destroyer(this->node_alloc())); + + //If there are remaining nodes, destroy them + NodePtr p; + while((p = other_tree.unlink_leftmost_without_rebalance())){ + AllocHolder::destroy_node(p); + } } } return *this; @@ -1515,8 +1516,9 @@ struct has_trivial_destructor_after_move <T, KeyOfValue, Compare, Allocator, Options> > { - typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value && + typedef typename ::boost::container::dtl::tree<T, KeyOfValue, Compare, Allocator, Options>::allocator_type allocator_type; + typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value && ::boost::has_trivial_destructor_after_move<pointer>::value && ::boost::has_trivial_destructor_after_move<Compare>::value; }; diff --git a/boost/container/detail/version_type.hpp b/boost/container/detail/version_type.hpp index 58e9da6aae..389606a567 100644 --- a/boost/container/detail/version_type.hpp +++ b/boost/container/detail/version_type.hpp @@ -45,8 +45,9 @@ namespace impl{ template <class T> struct extract_version - : T::version -{}; +{ + typedef typename T::version type; +}; template <class T> struct has_version @@ -69,7 +70,7 @@ struct version template <class T> struct version<T, true> { - static const unsigned value = extract_version<T>::value; + static const unsigned value = extract_version<T>::type::value; }; } //namespace impl |