diff --git a/doc/container.qbk b/doc/container.qbk index 1bf1598..0749045 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -1213,6 +1213,11 @@ use [*Boost.Container]? There are several reasons for that: [section:release_notes Release Notes] +[section:release_notes_boost_1_65_00 Boost 1.65 Release] + +* Implemented `extract_sequence`, `adopt_sequence` functions for flat_[multi]map/set associative containers. + +[endsect] [section:release_notes_boost_1_64_00 Boost 1.64 Release] diff --git a/include/boost/container/allocator_traits.hpp b/include/boost/container/allocator_traits.hpp index d6621f6..b08f601 100644 --- a/include/boost/container/allocator_traits.hpp +++ b/include/boost/container/allocator_traits.hpp @@ -347,7 +347,7 @@ struct allocator_traits #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: calls a.construct(p, std::forward(args)...) if that call is well-formed; - //! otherwise, invokes ::new (static_cast(p)) T(std::forward(args)...) + //! otherwise, invokes `placement new` (static_cast(p)) T(std::forward(args)...) template BOOST_CONTAINER_FORCEINLINE static void construct(Allocator & a, T* p, BOOST_FWD_REF(Args)... args) { diff --git a/include/boost/container/deque.hpp b/include/boost/container/deque.hpp index 255cd93..b838f6e 100644 --- a/include/boost/container/deque.hpp +++ b/include/boost/container/deque.hpp @@ -31,11 +31,11 @@ #include #include #include -#include +#include #include #include #include -#include +#include #include // move #include @@ -1649,7 +1649,7 @@ class deque : protected deque_base if (this->members_.m_start.m_cur != this->members_.m_start.m_last - 1) { allocator_traits_type::destroy ( this->alloc() - , container_detail::to_raw_pointer(this->members_.m_start.m_cur) + , boost::movelib::to_raw_pointer(this->members_.m_start.m_cur) ); ++this->members_.m_start.m_cur; } @@ -1669,7 +1669,7 @@ class deque : protected deque_base --this->members_.m_finish.m_cur; allocator_traits_type::destroy ( this->alloc() - , container_detail::to_raw_pointer(this->members_.m_finish.m_cur) + , boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur) ); } else @@ -1916,7 +1916,7 @@ class deque : protected deque_base T *priv_push_back_simple_pos() const { - return container_detail::to_raw_pointer(this->members_.m_finish.m_cur); + return boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur); } void priv_push_back_simple_commit() @@ -1931,7 +1931,7 @@ class deque : protected deque_base } T *priv_push_front_simple_pos() const - { return container_detail::to_raw_pointer(this->members_.m_start.m_cur) - 1; } + { return boost::movelib::to_raw_pointer(this->members_.m_start.m_cur) - 1; } void priv_push_front_simple_commit() { --this->members_.m_start.m_cur; } @@ -1940,7 +1940,7 @@ class deque : protected deque_base { if(!Base::traits_t::trivial_dctr){ for(;p != p2; ++p){ - allocator_traits_type::destroy(this->alloc(), container_detail::iterator_to_raw_pointer(p)); + allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p)); } } } @@ -1949,7 +1949,7 @@ class deque : protected deque_base { if(!Base::traits_t::trivial_dctr){ for(;p != p2; ++p){ - allocator_traits_type::destroy(this->alloc(), container_detail::iterator_to_raw_pointer(p)); + allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p)); } } } @@ -2133,7 +2133,7 @@ class deque : protected deque_base this->members_.m_finish.m_cur = this->members_.m_finish.m_last - 1; allocator_traits_type::destroy ( this->alloc() - , container_detail::to_raw_pointer(this->members_.m_finish.m_cur) + , boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur) ); } @@ -2145,7 +2145,7 @@ class deque : protected deque_base { allocator_traits_type::destroy ( this->alloc() - , container_detail::to_raw_pointer(this->members_.m_start.m_cur) + , boost::movelib::to_raw_pointer(this->members_.m_start.m_cur) ); this->priv_deallocate_node(this->members_.m_start.m_first); this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1); diff --git a/include/boost/container/detail/adaptive_node_pool_impl.hpp b/include/boost/container/detail/adaptive_node_pool_impl.hpp index 24c81dd..54db19d 100644 --- a/include/boost/container/detail/adaptive_node_pool_impl.hpp +++ b/include/boost/container/detail/adaptive_node_pool_impl.hpp @@ -28,10 +28,10 @@ // container/detail #include #include -#include +#include #include #include -#include +#include #include // intrusive #include @@ -378,7 +378,7 @@ class private_adaptive_node_pool_impl //!Returns the segment manager. Never throws segment_manager_base_type* get_segment_manager_base()const - { return container_detail::to_raw_pointer(mp_segment_mngr_base); } + { return boost::movelib::to_raw_pointer(mp_segment_mngr_base); } //!Allocates array of count elements. Can throw void *allocate_node() @@ -390,7 +390,7 @@ class private_adaptive_node_pool_impl free_nodes_t &free_nodes = m_block_container.begin()->free_nodes; BOOST_ASSERT(!free_nodes.empty()); const size_type free_nodes_count = free_nodes.size(); - void *first_node = container_detail::to_raw_pointer(free_nodes.pop_front()); + void *first_node = boost::movelib::to_raw_pointer(free_nodes.pop_front()); if(free_nodes.empty()){ block_container_traits_t::erase_first(m_block_container); } @@ -401,7 +401,7 @@ class private_adaptive_node_pool_impl else{ multiallocation_chain chain; this->priv_append_from_new_blocks(1, chain, IsAlignOnly()); - return container_detail::to_raw_pointer(chain.pop_front()); + return boost::movelib::to_raw_pointer(chain.pop_front()); } } @@ -492,7 +492,7 @@ class private_adaptive_node_pool_impl free_nodes_iterator itf(nodes.begin()), itbf(itbb); size_type splice_node_count = size_type(-1); while(itf != ite){ - void *pElem = container_detail::to_raw_pointer(container_detail::iterator_to_raw_pointer(itf)); + void *pElem = boost::movelib::to_raw_pointer(boost::movelib::iterator_to_raw_pointer(itf)); block_info_t &block_info = *this->priv_block_from_node(pElem); BOOST_ASSERT(block_info.free_nodes.size() < m_real_num_node); ++splice_node_count; @@ -631,7 +631,7 @@ class private_adaptive_node_pool_impl BOOST_ASSERT(to_deallocate->free_nodes.size() == mp_impl->m_real_num_node); BOOST_ASSERT(0 == to_deallocate->hdr_offset); hdr_offset_holder *hdr_off_holder = - mp_impl->priv_first_subblock_from_block(container_detail::to_raw_pointer(to_deallocate)); + mp_impl->priv_first_subblock_from_block(boost::movelib::to_raw_pointer(to_deallocate)); m_chain.push_back(hdr_off_holder); } @@ -763,7 +763,7 @@ class private_adaptive_node_pool_impl //First add all possible nodes to the chain const size_type left = total_elements - chain.size(); const size_type max_chain = (num_node < left) ? num_node : left; - mem_address = static_cast(container_detail::to_raw_pointer + mem_address = static_cast(boost::movelib::to_raw_pointer (chain.incorporate_after(chain.last(), void_pointer(mem_address), m_real_node_size, max_chain))); //Now store remaining nodes in the free list if(const size_type max_free = num_node - max_chain){ diff --git a/include/boost/container/detail/advanced_insert_int.hpp b/include/boost/container/detail/advanced_insert_int.hpp index 1050857..20adb52 100644 --- a/include/boost/container/detail/advanced_insert_int.hpp +++ b/include/boost/container/detail/advanced_insert_int.hpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #include #endif @@ -157,7 +157,7 @@ struct insert_copy_proxy void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const { BOOST_ASSERT(n == 1); (void)n; - alloc_traits::construct( a, iterator_to_raw_pointer(p), v_); + alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), v_); } void copy_n_and_update(Allocator &, Iterator p, size_type n) const @@ -184,7 +184,7 @@ struct insert_move_proxy void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const { BOOST_ASSERT(n == 1); (void)n; - alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::move(v_) ); + 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 @@ -240,7 +240,7 @@ struct insert_nonmovable_emplace_proxy void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple&, Iterator p, size_type n) { BOOST_ASSERT(n == 1); (void)n; - alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::forward(get(this->args_))... ); + alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::forward(get(this->args_))... ); } protected: @@ -354,7 +354,7 @@ struct insert_nonmovable_emplace_proxy##N\ void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)\ {\ BOOST_ASSERT(n == 1); (void)n;\ - alloc_traits::construct(a, iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ + alloc_traits::construct(a, boost::movelib::iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ }\ \ void copy_n_and_update(Allocator &, Iterator, size_type)\ diff --git a/include/boost/container/detail/copy_move_algo.hpp b/include/boost/container/detail/copy_move_algo.hpp index dda311a..968f4ac 100644 --- a/include/boost/container/detail/copy_move_algo.hpp +++ b/include/boost/container/detail/copy_move_algo.hpp @@ -22,7 +22,7 @@ #include // container/detail #include -#include +#include #include #include #include @@ -178,7 +178,7 @@ inline F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW typedef typename boost::container::iterator_traits::value_type value_type; typename boost::container::iterator_traits::difference_type n = boost::container::iterator_distance(f, l); if(n){ - std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n); + std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n); boost::container::iterator_advance(r, n); } return r; @@ -192,7 +192,7 @@ F memmove_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW { typedef typename boost::container::iterator_traits::value_type value_type; if(n){ - std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n); + std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n); boost::container::iterator_advance(r, n); } return r; @@ -206,7 +206,7 @@ I memmove_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW { if(n){ typedef typename boost::container::iterator_traits::value_type value_type; - std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n); + std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n); boost::container::iterator_advance(f, n); } return f; @@ -220,7 +220,7 @@ I memmove_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW { typedef typename boost::container::iterator_traits::value_type value_type; if(n){ - std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n); + std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n); boost::container::iterator_advance(f, n); boost::container::iterator_advance(r, n); } @@ -295,13 +295,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f)); + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f)); ++f; ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -340,13 +340,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f)); + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f)); ++f; ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -385,13 +385,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f)); + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f)); ++f; ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -430,13 +430,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible::construct(a, container_detail::iterator_to_raw_pointer(r), *f); + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f); ++f; ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -475,13 +475,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible::construct(a, container_detail::iterator_to_raw_pointer(r), *f); + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f); ++f; ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -520,13 +520,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -564,13 +564,13 @@ inline typename container_detail::disable_if_memzero_initializable::type F back = r; BOOST_TRY{ while (n--) { - allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r)); + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r)); ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -585,7 +585,7 @@ inline typename container_detail::enable_if_memzero_initializable::type uninitialized_value_init_alloc_n(Allocator &, typename boost::container::allocator_traits::size_type n, F r) { typedef typename boost::container::iterator_traits::value_type value_type; - std::memset((void*)container_detail::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n); + std::memset((void*)boost::movelib::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n); boost::container::iterator_advance(r, n); return r; } @@ -611,13 +611,13 @@ inline F uninitialized_default_init_alloc_n(Allocator &a, typename boost::contai F back = r; BOOST_TRY{ while (n--) { - allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), default_init); + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), default_init); ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -647,13 +647,13 @@ inline void uninitialized_fill_alloc(Allocator &a, F f, F l, const T &t) F back = f; BOOST_TRY{ while (f != l) { - allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(f), t); + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(f), t); ++f; } } BOOST_CATCH(...){ for (; back != l; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -683,13 +683,13 @@ inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, typename boost::co F back = r; BOOST_TRY{ while (n--) { - allocator_traits::construct(a, container_detail::iterator_to_raw_pointer(r), v); + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), v); ++r; } } BOOST_CATCH(...){ for (; back != r; ++back){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(back)); + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); } BOOST_RETHROW; } @@ -890,7 +890,7 @@ inline typename container_detail::enable_if_memtransfer_copy_assignable typedef typename boost::container::iterator_traits::value_type value_type; const typename boost::container::iterator_traits::difference_type n = boost::container::iterator_distance(f, l); r -= n; - std::memmove((container_detail::iterator_to_raw_pointer)(r), (container_detail::iterator_to_raw_pointer)(f), sizeof(value_type)*n); + std::memmove((boost::movelib::iterator_to_raw_pointer)(r), (boost::movelib::iterator_to_raw_pointer)(f), sizeof(value_type)*n); return r; } @@ -964,7 +964,7 @@ inline typename container_detail::disable_if_trivially_destructible::ty destroy_alloc_n(Allocator &a, I f, U n) { while(n--){ - allocator_traits::destroy(a, container_detail::iterator_to_raw_pointer(f)); + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(f)); ++f; } } @@ -1021,9 +1021,9 @@ inline typename container_detail::enable_if_c storage_type storage; const std::size_t n_i_bytes = sizeof(value_type)*n_i; - void *const large_ptr = static_cast(container_detail::iterator_to_raw_pointer(large_range_f)); - void *const short_ptr = static_cast(container_detail::iterator_to_raw_pointer(short_range_f)); - void *const stora_ptr = static_cast(container_detail::iterator_to_raw_pointer(storage)); + void *const large_ptr = static_cast(boost::movelib::iterator_to_raw_pointer(large_range_f)); + void *const short_ptr = static_cast(boost::movelib::iterator_to_raw_pointer(short_range_f)); + void *const stora_ptr = static_cast(boost::movelib::iterator_to_raw_pointer(storage)); std::memcpy(stora_ptr, large_ptr, n_i_bytes); std::memcpy(large_ptr, short_ptr, n_i_bytes); std::memcpy(short_ptr, stora_ptr, n_i_bytes); @@ -1052,8 +1052,8 @@ inline typename container_detail::enable_if_c const std::size_t sizeof_storage = sizeof(storage); std::size_t n_i_bytes = sizeof(value_type)*n_i; - char *large_ptr = static_cast(static_cast(container_detail::iterator_to_raw_pointer(large_range_f))); - char *short_ptr = static_cast(static_cast(container_detail::iterator_to_raw_pointer(short_range_f))); + char *large_ptr = static_cast(static_cast(boost::movelib::iterator_to_raw_pointer(large_range_f))); + char *short_ptr = static_cast(static_cast(boost::movelib::iterator_to_raw_pointer(short_range_f))); char *stora_ptr = static_cast(static_cast(&storage)); std::size_t szt_times = n_i_bytes/sizeof_storage; diff --git a/include/boost/container/detail/destroyers.hpp b/include/boost/container/detail/destroyers.hpp index 52b44c0..b110561 100644 --- a/include/boost/container/detail/destroyers.hpp +++ b/include/boost/container/detail/destroyers.hpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include namespace boost { @@ -152,7 +152,7 @@ struct scoped_destroy_deallocator ~scoped_destroy_deallocator() { if(m_ptr){ - AllocTraits::destroy(m_alloc, container_detail::to_raw_pointer(m_ptr)); + AllocTraits::destroy(m_alloc, boost::movelib::to_raw_pointer(m_ptr)); priv_deallocate(m_ptr, alloc_version()); } } @@ -202,7 +202,7 @@ struct scoped_destructor_n ~scoped_destructor_n() { if(!m_p) return; - value_type *raw_ptr = container_detail::to_raw_pointer(m_p); + value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p); while(m_n--){ AllocTraits::destroy(m_a, raw_ptr++); } @@ -317,7 +317,7 @@ class allocator_destroyer void operator()(const pointer &p) { - AllocTraits::destroy(a_, container_detail::to_raw_pointer(p)); + AllocTraits::destroy(a_, boost::movelib::to_raw_pointer(p)); this->priv_deallocate(p, alloc_version()); } }; @@ -339,7 +339,7 @@ class allocator_destroyer_and_chain_builder void operator()(const typename Allocator::pointer &p) { - allocator_traits::destroy(a_, container_detail::to_raw_pointer(p)); + allocator_traits::destroy(a_, boost::movelib::to_raw_pointer(p)); c_.push_back(p); } }; diff --git a/include/boost/container/detail/flat_tree.hpp b/include/boost/container/detail/flat_tree.hpp index 93984d1..89ff735 100644 --- a/include/boost/container/detail/flat_tree.hpp +++ b/include/boost/container/detail/flat_tree.hpp @@ -28,25 +28,30 @@ #include #include +#include + #include #include #include //algo_equal(), algo_lexicographical_compare #include #include -#include +#include +#include + #ifdef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER #include #endif -#include -#include +#include //pair + #include +#include #include +#include + #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #include #endif -#include //pair -#include namespace boost { namespace container { @@ -105,14 +110,17 @@ template class flat_tree { - typedef boost::container::vector vector_t; + public: + typedef boost::container::vector sequence_type; + + private: typedef Allocator allocator_t; typedef allocator_traits allocator_traits_type; public: typedef flat_tree_value_compare value_compare; - private: + private: struct Data //Inherit from value_compare to do EBO : public value_compare @@ -121,48 +129,48 @@ class flat_tree public: Data() - : value_compare(), m_vect() + : value_compare(), m_seq() {} explicit Data(const Data &d) - : value_compare(static_cast(d)), m_vect(d.m_vect) + : value_compare(static_cast(d)), m_seq(d.m_seq) {} Data(BOOST_RV_REF(Data) d) - : value_compare(boost::move(static_cast(d))), m_vect(boost::move(d.m_vect)) + : value_compare(boost::move(static_cast(d))), m_seq(boost::move(d.m_seq)) {} Data(const Data &d, const Allocator &a) - : value_compare(static_cast(d)), m_vect(d.m_vect, a) + : value_compare(static_cast(d)), m_seq(d.m_seq, a) {} Data(BOOST_RV_REF(Data) d, const Allocator &a) - : value_compare(boost::move(static_cast(d))), m_vect(boost::move(d.m_vect), a) + : value_compare(boost::move(static_cast(d))), m_seq(boost::move(d.m_seq), a) {} explicit Data(const Compare &comp) - : value_compare(comp), m_vect() + : value_compare(comp), m_seq() {} Data(const Compare &comp, const allocator_t &alloc) - : value_compare(comp), m_vect(alloc) + : value_compare(comp), m_seq(alloc) {} explicit Data(const allocator_t &alloc) - : value_compare(), m_vect(alloc) + : value_compare(), m_seq(alloc) {} Data& operator=(BOOST_COPY_ASSIGN_REF(Data) d) { this->value_compare::operator=(d); - m_vect = d.m_vect; + m_seq = d.m_seq; return *this; } Data& operator=(BOOST_RV_REF(Data) d) { this->value_compare::operator=(boost::move(static_cast(d))); - m_vect = boost::move(d.m_vect); + m_seq = boost::move(d.m_seq); return *this; } @@ -170,10 +178,10 @@ class flat_tree { value_compare& mycomp = *this, & othercomp = d; boost::adl_move_swap(mycomp, othercomp); - this->m_vect.swap(d.m_vect); + this->m_seq.swap(d.m_seq); } - vector_t m_vect; + sequence_type m_seq; }; Data m_data; @@ -181,23 +189,23 @@ class flat_tree public: - typedef typename vector_t::value_type value_type; - typedef typename vector_t::pointer pointer; - typedef typename vector_t::const_pointer const_pointer; - typedef typename vector_t::reference reference; - typedef typename vector_t::const_reference const_reference; - typedef typename KeyOfValue::type key_type; - typedef Compare key_compare; - typedef typename vector_t::allocator_type allocator_type; - typedef typename vector_t::size_type size_type; - typedef typename vector_t::difference_type difference_type; - typedef typename vector_t::iterator iterator; - typedef typename vector_t::const_iterator const_iterator; - typedef typename vector_t::reverse_iterator reverse_iterator; - typedef typename vector_t::const_reverse_iterator const_reverse_iterator; + typedef typename sequence_type::value_type value_type; + typedef typename sequence_type::pointer pointer; + typedef typename sequence_type::const_pointer const_pointer; + typedef typename sequence_type::reference reference; + typedef typename sequence_type::const_reference const_reference; + typedef typename KeyOfValue::type key_type; + typedef Compare key_compare; + typedef typename sequence_type::allocator_type allocator_type; + typedef typename sequence_type::size_type size_type; + typedef typename sequence_type::difference_type difference_type; + typedef typename sequence_type::iterator iterator; + typedef typename sequence_type::const_iterator const_iterator; + typedef typename sequence_type::reverse_iterator reverse_iterator; + typedef typename sequence_type::const_reverse_iterator const_reverse_iterator; //!Standard extension - typedef allocator_type stored_allocator_type; + typedef allocator_type stored_allocator_type; private: typedef allocator_traits stored_allocator_traits; @@ -242,8 +250,8 @@ class flat_tree , const allocator_type& a = allocator_type()) : m_data(comp, a) { - this->m_data.m_vect.insert(this->m_data.m_vect.end(), first, last); - BOOST_ASSERT((is_sorted)(this->m_data.m_vect.cbegin(), this->m_data.m_vect.cend(), this->priv_value_comp())); + this->m_data.m_seq.insert(this->m_data.m_seq.end(), first, last); + BOOST_ASSERT((is_sorted)(this->m_data.m_seq.cbegin(), this->m_data.m_seq.cend(), this->priv_value_comp())); } template @@ -252,8 +260,8 @@ class flat_tree , const allocator_type& a = allocator_type()) : m_data(comp, a) { - this->m_data.m_vect.insert(this->m_data.m_vect.end(), first, last); - BOOST_ASSERT((is_sorted_and_unique)(this->m_data.m_vect.cbegin(), this->m_data.m_vect.cend(), this->priv_value_comp())); + this->m_data.m_seq.insert(this->m_data.m_seq.end(), first, last); + BOOST_ASSERT((is_sorted_and_unique)(this->m_data.m_seq.cbegin(), this->m_data.m_seq.cend(), this->priv_value_comp())); } template @@ -312,31 +320,31 @@ class flat_tree { return this->m_data; } BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const - { return this->m_data.m_vect.get_allocator(); } + { return this->m_data.m_seq.get_allocator(); } BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const - { return this->m_data.m_vect.get_stored_allocator(); } + { return this->m_data.m_seq.get_stored_allocator(); } BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator() - { return this->m_data.m_vect.get_stored_allocator(); } + { return this->m_data.m_seq.get_stored_allocator(); } BOOST_CONTAINER_FORCEINLINE iterator begin() - { return this->m_data.m_vect.begin(); } + { return this->m_data.m_seq.begin(); } BOOST_CONTAINER_FORCEINLINE const_iterator begin() const { return this->cbegin(); } BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const - { return this->m_data.m_vect.begin(); } + { return this->m_data.m_seq.begin(); } BOOST_CONTAINER_FORCEINLINE iterator end() - { return this->m_data.m_vect.end(); } + { return this->m_data.m_seq.end(); } BOOST_CONTAINER_FORCEINLINE const_iterator end() const { return this->cend(); } BOOST_CONTAINER_FORCEINLINE const_iterator cend() const - { return this->m_data.m_vect.end(); } + { return this->m_data.m_seq.end(); } BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin() { return reverse_iterator(this->end()); } @@ -357,13 +365,13 @@ class flat_tree { return const_reverse_iterator(this->cbegin()); } BOOST_CONTAINER_FORCEINLINE bool empty() const - { return this->m_data.m_vect.empty(); } + { return this->m_data.m_seq.empty(); } BOOST_CONTAINER_FORCEINLINE size_type size() const - { return this->m_data.m_vect.size(); } + { return this->m_data.m_seq.size(); } BOOST_CONTAINER_FORCEINLINE size_type max_size() const - { return this->m_data.m_vect.max_size(); } + { return this->m_data.m_seq.max_size(); } BOOST_CONTAINER_FORCEINLINE void swap(flat_tree& other) BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value @@ -395,14 +403,14 @@ class flat_tree iterator insert_equal(const value_type& val) { iterator i = this->upper_bound(KeyOfValue()(val)); - i = this->m_data.m_vect.insert(i, val); + i = this->m_data.m_seq.insert(i, val); return i; } iterator insert_equal(BOOST_RV_REF(value_type) mval) { iterator i = this->upper_bound(KeyOfValue()(mval)); - i = this->m_data.m_vect.insert(i, boost::move(mval)); + i = this->m_data.m_seq.insert(i, boost::move(mval)); return i; } @@ -509,7 +517,7 @@ class flat_tree >::type * = 0 #endif ) - { this->m_data.m_vect.merge(first, last, static_cast(this->m_data)); } + { this->m_data.m_seq.merge(first, last, static_cast(this->m_data)); } template void insert_unique(ordered_unique_range_t, InIt first, InIt last @@ -538,7 +546,7 @@ class flat_tree >::type * = 0 #endif ) - { this->m_data.m_vect.merge_unique(first, last, static_cast(this->m_data)); } + { this->m_data.m_seq.merge_unique(first, last, static_cast(this->m_data)); } #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) @@ -606,7 +614,7 @@ class flat_tree typedef typename emplace_functor_type::type func_t; typedef emplace_iterator it_t; func_t func(try_emplace_t(), ::boost::forward(key), ::boost::forward(args)...); - ret.first = this->m_data.m_vect.insert(data.position, it_t(func), it_t()); + ret.first = this->m_data.m_seq.insert(data.position, it_t(func), it_t()); } return ret; } @@ -675,7 +683,7 @@ class flat_tree typedef typename emplace_functor_type::type func_t;\ typedef emplace_iterator it_t;\ func_t func(try_emplace_t(), ::boost::forward(key) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ - ret.first = this->m_data.m_vect.insert(data.position, it_t(func), it_t());\ + ret.first = this->m_data.m_seq.insert(data.position, it_t(func), it_t());\ }\ return ret;\ }\ @@ -702,29 +710,29 @@ class flat_tree typedef typename emplace_functor_type::type func_t; typedef emplace_iterator it_t; func_t func(boost::forward(key), boost::forward(obj)); - ret.first = this->m_data.m_vect.insert(data.position, it_t(func), it_t()); + ret.first = this->m_data.m_seq.insert(data.position, it_t(func), it_t()); } return ret; } BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator position) - { return this->m_data.m_vect.erase(position); } + { return this->m_data.m_seq.erase(position); } size_type erase(const key_type& k) { std::pair itp = this->equal_range(k); size_type ret = static_cast(itp.second-itp.first); if (ret){ - this->m_data.m_vect.erase(itp.first, itp.second); + this->m_data.m_seq.erase(itp.first, itp.second); } return ret; } BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last) - { return this->m_data.m_vect.erase(first, last); } + { return this->m_data.m_seq.erase(first, last); } BOOST_CONTAINER_FORCEINLINE void clear() - { this->m_data.m_vect.clear(); } + { this->m_data.m_seq.clear(); } //! Effects: Tries to deallocate the excess of memory created // with previous allocations. The size of the vector is unchanged @@ -733,19 +741,19 @@ class flat_tree //! //! Complexity: Linear to size(). BOOST_CONTAINER_FORCEINLINE void shrink_to_fit() - { this->m_data.m_vect.shrink_to_fit(); } + { this->m_data.m_seq.shrink_to_fit(); } BOOST_CONTAINER_FORCEINLINE iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW - { return this->m_data.m_vect.nth(n); } + { return this->m_data.m_seq.nth(n); } BOOST_CONTAINER_FORCEINLINE const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW - { return this->m_data.m_vect.nth(n); } + { return this->m_data.m_seq.nth(n); } BOOST_CONTAINER_FORCEINLINE size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW - { return this->m_data.m_vect.index_of(p); } + { return this->m_data.m_seq.index_of(p); } BOOST_CONTAINER_FORCEINLINE size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW - { return this->m_data.m_vect.index_of(p); } + { return this->m_data.m_seq.index_of(p); } // set operations: iterator find(const key_type& k) @@ -793,7 +801,7 @@ class flat_tree void merge_unique(flat_tree& source) { - this->m_data.m_vect.merge_unique + this->m_data.m_seq.merge_unique ( boost::make_move_iterator(source.begin()) , boost::make_move_iterator(source.end()) , static_cast(this->m_data)); @@ -801,7 +809,7 @@ class flat_tree void merge_equal(flat_tree& source) { - this->m_data.m_vect.merge + this->m_data.m_seq.merge ( boost::make_move_iterator(source.begin()) , boost::make_move_iterator(source.end()) , static_cast(this->m_data)); @@ -832,10 +840,61 @@ class flat_tree { return this->priv_lower_bound_range(this->cbegin(), this->cend(), k); } BOOST_CONTAINER_FORCEINLINE size_type capacity() const - { return this->m_data.m_vect.capacity(); } + { return this->m_data.m_seq.capacity(); } BOOST_CONTAINER_FORCEINLINE void reserve(size_type cnt) - { this->m_data.m_vect.reserve(cnt); } + { this->m_data.m_seq.reserve(cnt); } + + BOOST_CONTAINER_FORCEINLINE sequence_type extract_sequence() + { + return boost::move(m_data.m_seq); + } + + BOOST_CONTAINER_FORCEINLINE sequence_type &get_sequence_ref() + { + return m_data.m_seq; + } + + void adopt_sequence_equal(BOOST_RV_REF(sequence_type) seq) + { + sequence_type &tseq = m_data.m_seq; + boost::movelib::adaptive_sort + ( boost::movelib::iterator_to_raw_pointer(seq.begin()) + , boost::movelib::iterator_to_raw_pointer(seq.end()) + , this->priv_value_comp() + , boost::movelib::iterator_to_raw_pointer(tseq.begin() + tseq.size()) + , tseq.capacity() - tseq.size()); + tseq = boost::move(seq); + } + + void adopt_sequence_equal(ordered_range_t, BOOST_RV_REF(sequence_type) seq) + { + BOOST_ASSERT((is_sorted)(seq.cbegin(), seq.cend(), this->priv_value_comp())); + sequence_type &tseq = m_data.m_seq; + tseq = boost::move(seq); + } + + void adopt_sequence_unique(BOOST_RV_REF(sequence_type) seq) + { + sequence_type &tseq = m_data.m_seq; + boost::movelib::adaptive_sort + ( boost::movelib::iterator_to_raw_pointer(seq.begin()) + , boost::movelib::iterator_to_raw_pointer(seq.end()) + , this->priv_value_comp() + , boost::movelib::iterator_to_raw_pointer(tseq.begin() + tseq.size()) + , tseq.capacity() - tseq.size()); + seq.erase( boost::movelib::unique + (seq.begin(), seq.end(), boost::movelib::negate(this->m_data.get_comp())) + , seq.cend()); + tseq = boost::move(seq); + } + + void adopt_sequence_unique(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq) + { + BOOST_ASSERT((is_sorted_and_unique)(seq.cbegin(), seq.cend(), this->priv_value_comp())); + sequence_type &tseq = m_data.m_seq; + tseq = boost::move(seq); + } BOOST_CONTAINER_FORCEINLINE friend bool operator==(const flat_tree& x, const flat_tree& y) { @@ -963,7 +1022,7 @@ class flat_tree BOOST_CONTAINER_FORCEINLINE iterator priv_insert_commit (insert_commit_data &commit_data, BOOST_FWD_REF(Convertible) convertible) { - return this->m_data.m_vect.insert + return this->m_data.m_seq.insert ( commit_data.position , boost::forward(convertible)); } diff --git a/include/boost/container/detail/iterator_to_raw_pointer.hpp b/include/boost/container/detail/iterator_to_raw_pointer.hpp index 83736d8..8c7c880 100644 --- a/include/boost/container/detail/iterator_to_raw_pointer.hpp +++ b/include/boost/container/detail/iterator_to_raw_pointer.hpp @@ -18,38 +18,13 @@ # pragma once #endif -#include -#include -#include +#include namespace boost { namespace container { namespace container_detail { -template -inline T* iterator_to_pointer(T* i) -{ return i; } - -template -inline typename boost::container::iterator_traits::pointer - iterator_to_pointer(const Iterator &i) -{ return i.operator->(); } - -template -struct iterator_to_element_ptr -{ - typedef typename boost::container::iterator_traits::pointer pointer; - typedef typename boost::intrusive::pointer_traits::element_type element_type; - typedef element_type* type; -}; - -template -inline typename iterator_to_element_ptr::type - iterator_to_raw_pointer(const Iterator &i) -{ - return ::boost::intrusive::detail::to_raw_pointer - ( ::boost::container::container_detail::iterator_to_pointer(i) ); -} +using ::boost::movelib::iterator_to_raw_pointer; } //namespace container_detail { } //namespace container { diff --git a/include/boost/container/detail/multiallocation_chain.hpp b/include/boost/container/detail/multiallocation_chain.hpp index 32f87c8..bce1b86 100644 --- a/include/boost/container/detail/multiallocation_chain.hpp +++ b/include/boost/container/detail/multiallocation_chain.hpp @@ -24,7 +24,7 @@ // container #include // container/detail -#include +#include #include #include // intrusive @@ -63,7 +63,7 @@ class basic_multiallocation_chain pointer_traits node_ptr_traits; static node & to_node(const VoidPointer &p) - { return *static_cast(static_cast(container_detail::to_raw_pointer(p))); } + { return *static_cast(static_cast(boost::movelib::to_raw_pointer(p))); } static VoidPointer from_node(node &n) { return node_ptr_traits::pointer_to(n); } @@ -152,7 +152,7 @@ class basic_multiallocation_chain char_ptr prev_elem = elem; elem += unit_bytes; for(size_type i = 0; i != num_units-1; ++i, elem += unit_bytes){ - ::new (container_detail::to_raw_pointer(prev_elem)) void_pointer(elem); + ::new (boost::movelib::to_raw_pointer(prev_elem)) void_pointer(elem); prev_elem = elem; } slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(prev_elem), num_units); diff --git a/include/boost/container/detail/node_alloc_holder.hpp b/include/boost/container/detail/node_alloc_holder.hpp index 7ef5d28..0341ce1 100644 --- a/include/boost/container/detail/node_alloc_holder.hpp +++ b/include/boost/container/detail/node_alloc_holder.hpp @@ -30,10 +30,10 @@ #include #include #include -#include +#include #include #include -#include +#include #include #include // intrusive @@ -171,7 +171,7 @@ struct node_alloc_holder node_deallocator.release(); //This does not throw typedef typename Node::hook_type hook_type; - ::new(static_cast(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type; + ::new(static_cast(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type; return (p); } @@ -189,7 +189,7 @@ struct node_alloc_holder BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ node_deallocator.release();\ typedef typename Node::hook_type hook_type;\ - ::new(static_cast(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;\ + ::new(static_cast(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type;\ return (p);\ }\ // @@ -207,7 +207,7 @@ struct node_alloc_holder node_deallocator.release(); //This does not throw typedef typename Node::hook_type hook_type; - ::new(static_cast(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type; + ::new(static_cast(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type; return (p); } @@ -230,13 +230,13 @@ struct node_alloc_holder node_deallocator.release(); //This does not throw typedef typename Node::hook_type hook_type; - ::new(static_cast(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type; + ::new(static_cast(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type; return (p); } void destroy_node(const NodePtr &nodep) { - allocator_traits::destroy(this->node_alloc(), container_detail::to_raw_pointer(nodep)); + allocator_traits::destroy(this->node_alloc(), boost::movelib::to_raw_pointer(nodep)); this->deallocate_one(nodep); } @@ -266,7 +266,7 @@ struct node_alloc_holder Deallocator node_deallocator(NodePtr(), nalloc); container_detail::scoped_destructor sdestructor(nalloc, 0); while(n--){ - p = container_detail::iterator_to_raw_pointer(itbeg); + p = boost::movelib::iterator_to_raw_pointer(itbeg); node_deallocator.set(p); ++itbeg; //This can throw diff --git a/include/boost/container/detail/node_pool_impl.hpp b/include/boost/container/detail/node_pool_impl.hpp index 4febf19..024bf30 100644 --- a/include/boost/container/detail/node_pool_impl.hpp +++ b/include/boost/container/detail/node_pool_impl.hpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -92,7 +92,7 @@ class private_node_pool_impl //!Returns the segment manager. Never throws segment_manager_base_type* get_segment_manager_base()const - { return container_detail::to_raw_pointer(mp_segment_mngr_base); } + { return boost::movelib::to_raw_pointer(mp_segment_mngr_base); } void *allocate_node() { return this->priv_alloc_node(); } diff --git a/include/boost/container/detail/pair.hpp b/include/boost/container/detail/pair.hpp index 4abff4b..4755e56 100644 --- a/include/boost/container/detail/pair.hpp +++ b/include/boost/container/detail/pair.hpp @@ -35,16 +35,62 @@ #include //pair #include -#include +#include namespace boost { namespace tuples { struct null_type; +template < + class T0, class T1, class T2, + class T3, class T4, class T5, + class T6, class T7, class T8, + class T9> +class tuple; + } //namespace tuples { } //namespace boost { +namespace boost { +namespace container { +namespace pair_impl { + +template +struct is_boost_tuple +{ + static const bool value = false; +}; + +template < + class T0, class T1, class T2, + class T3, class T4, class T5, + class T6, class T7, class T8, + class T9> +struct is_boost_tuple< boost::tuples::tuple > +{ + static const bool value = true; +}; + +template +struct disable_if_boost_tuple + : boost::container::container_detail::disable_if< is_boost_tuple > +{}; + +template +struct is_tuple_null +{ + static const bool value = false; +}; + +template<> +struct is_tuple_null +{ + static const bool value = true; +}; + +}}} + #if defined(BOOST_MSVC) && (_CPPLIB_VER == 520) //MSVC 2010 tuple marker namespace std { namespace tr1 { struct _Nil; }} @@ -236,7 +282,12 @@ struct pair BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ pair( piecewise_construct_t\ , BoostTuple p\ - , BoostTuple q)\ + , BoostTuple q\ + , typename container_detail::enable_if_c\ + < pair_impl::is_boost_tuple< BoostTuple >::value &&\ + !(pair_impl::is_tuple_null::value || pair_impl::is_tuple_null::value) \ + >::type* = 0\ + )\ : first(BOOST_MOVE_TMPL_GET##N), second(BOOST_MOVE_TMPL_GETQ##M)\ { (void)p; (void)q; }\ // @@ -254,7 +305,8 @@ struct pair { (void) t1; (void)t2; } public: - template class Tuple, class... Args1, class... Args2> + template< template class Tuple, class... Args1, class... Args2 + , class = typename pair_impl::disable_if_boost_tuple< Tuple >::type> pair(piecewise_construct_t, Tuple t1, Tuple t2) : pair(t1, t2, typename build_number_seq::type(), typename build_number_seq::type()) {} @@ -270,7 +322,8 @@ struct pair { (void)t; return T(::boost::forward(get(t))...); } public: - template class Tuple, class... Args1, class... Args2> + template< template class Tuple, class... Args1, class... Args2 + , class = typename pair_impl::disable_if_boost_tuple< Tuple >::type> pair(piecewise_construct_t, Tuple t1, Tuple t2) : first (build_from_args (::boost::move(t1))) , second (build_from_args(::boost::move(t2))) diff --git a/include/boost/container/detail/pair_key_mapped_of_value.hpp b/include/boost/container/detail/pair_key_mapped_of_value.hpp new file mode 100644 index 0000000..6112b87 --- /dev/null +++ b/include/boost/container/detail/pair_key_mapped_of_value.hpp @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_PAIR_KEY_MAPPED_OF_VALUE_HPP +#define BOOST_CONTAINER_PAIR_KEY_MAPPED_OF_VALUE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +namespace boost { +namespace container { + +template +struct pair_key_mapped_of_value +{ + typedef Key key_type; + typedef Mapped mapped_type; + + template + const key_type & key_of_value(const Pair &p) const + { return p.first; } + + template + const mapped_type & mapped_of_value(const Pair &p) const + { return p.second; } + + template + key_type & key_of_value(Pair &p) const + { return const_cast(p.first); } + + template + mapped_type & mapped_of_value(Pair &p) const + { return p.second; } + +}; + +}} + +#include + +#endif // BOOST_CONTAINER_PAIR_KEY_MAPPED_OF_VALUE_HPP diff --git a/include/boost/container/detail/tree.hpp b/include/boost/container/detail/tree.hpp index 853d0ad..7b29467 100644 --- a/include/boost/container/detail/tree.hpp +++ b/include/boost/container/detail/tree.hpp @@ -493,7 +493,7 @@ class tree typedef boost::container::reverse_iterator const_reverse_iterator; typedef node_handle - < Node, value_type, allocator_type, void> node_type; + < NodeAlloc, void> node_type; typedef insert_return_type_base insert_return_type; @@ -1142,7 +1142,7 @@ class tree this->insert_unique_check(hint, KeyOfValue()(nh.value()), data); if(ret.second){ irt.inserted = true; - irt.position = iterator(this->icont().insert_unique_commit(*nh.get_node_pointer(), data)); + irt.position = iterator(this->icont().insert_unique_commit(*nh.get(), data)); nh.release(); } else{ diff --git a/include/boost/container/flat_map.hpp b/include/boost/container/flat_map.hpp index b842101..ebfd44e 100644 --- a/include/boost/container/flat_map.hpp +++ b/include/boost/container/flat_map.hpp @@ -144,8 +144,10 @@ class flat_map ::pointer>::reverse_iterator reverse_iterator_impl; typedef typename container_detail::get_flat_tree_iterators ::pointer>::const_reverse_iterator const_reverse_iterator_impl; + public: typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type; + typedef typename impl_tree_t::sequence_type impl_sequence_type; impl_tree_t &tree() { return m_flat_tree; } @@ -182,6 +184,7 @@ class flat_map typedef BOOST_CONTAINER_IMPDEF(reverse_iterator_impl) reverse_iterator; typedef BOOST_CONTAINER_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator; typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type; public: ////////////////////////////////////////////// @@ -1243,6 +1246,39 @@ class flat_map std::pair equal_range(const key_type& x) const { return container_detail::force_copy >(m_flat_tree.lower_bound_range(x)); } + //! Effects: Extracts the internal sequence container. + //! + //! Complexity: Same as the move constructor of sequence_type, usually constant. + //! + //! Postcondition: this->empty() + //! + //! Throws: If secuence_type's move constructor throws + sequence_type extract_sequence() + { + return boost::move(container_detail::force(m_flat_tree.get_sequence_ref())); + } + + //! Effects: Discards the internally hold sequence container and adopts the + //! one passed externally using the move assignment. Erases non-unique elements. + //! + //! Complexity: Assuming O(1) move assignment, O(NlogN) with N = seq.size() + //! + //! Throws: If the comparison or the move constructor throws + void adopt_sequence(BOOST_RV_REF(sequence_type) seq) + { this->m_flat_tree.adopt_sequence_unique(boost::move(container_detail::force(seq))); } + + //! Requires: seq shall be ordered according to this->compare() + //! and shall contain unique elements. + //! + //! Effects: Discards the internally hold sequence container and adopts the + //! one passed externally using the move assignment. + //! + //! Complexity: Assuming O(1) move assignment, O(1) + //! + //! Throws: If the move assignment throws + void adopt_sequence(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq) + { this->m_flat_tree.adopt_sequence_unique(ordered_unique_range_t(), boost::move(container_detail::force(seq))); } + //! Effects: Returns true if x and y are equal //! //! Complexity: Linear to the number of elements in the container. @@ -1401,6 +1437,7 @@ class flat_multimap ::pointer>::const_reverse_iterator const_reverse_iterator_impl; public: typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type; + typedef typename impl_tree_t::sequence_type impl_sequence_type; impl_tree_t &tree() { return m_flat_tree; } @@ -1437,6 +1474,7 @@ class flat_multimap typedef BOOST_CONTAINER_IMPDEF(reverse_iterator_impl) reverse_iterator; typedef BOOST_CONTAINER_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator; typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type; + typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type; ////////////////////////////////////////////// // @@ -2070,7 +2108,7 @@ class flat_multimap void merge(flat_map& source) { m_flat_tree.merge_equal(source.tree()); } - //! @copydoc ::boost::container::flat_multimap::merge(flat_multimap&) + //! @copydoc ::boost::container::flat_multimap::merge(flat_map&) template void merge(BOOST_RV_REF_BEG flat_map BOOST_RV_REF_END source) { return this->merge(static_cast&>(source)); } @@ -2219,6 +2257,38 @@ class flat_multimap std::pair equal_range(const key_type& x) const { return container_detail::force_copy >(m_flat_tree.equal_range(x)); } + //! Effects: Extracts the internal sequence container. + //! + //! Complexity: Same as the move constructor of sequence_type, usually constant. + //! + //! Postcondition: this->empty() + //! + //! Throws: If secuence_type's move constructor throws + sequence_type extract_sequence() + { + return boost::move(container_detail::force(m_flat_tree.get_sequence_ref())); + } + + //! Effects: Discards the internally hold sequence container and adopts the + //! one passed externally using the move assignment. + //! + //! Complexity: Assuming O(1) move assignment, O(NlogN) with N = seq.size() + //! + //! Throws: If the comparison or the move constructor throws + void adopt_sequence(BOOST_RV_REF(sequence_type) seq) + { this->m_flat_tree.adopt_sequence_equal(boost::move(container_detail::force(seq))); } + + //! Requires: seq shall be ordered according to this->compare(). + //! + //! Effects: Discards the internally hold sequence container and adopts the + //! one passed externally using the move assignment. + //! + //! Complexity: Assuming O(1) move assignment, O(1) + //! + //! Throws: If the move assignment throws + void adopt_sequence(ordered_range_t, BOOST_RV_REF(sequence_type) seq) + { this->m_flat_tree.adopt_sequence_equal(ordered_range_t(), boost::move(container_detail::force(seq))); } + //! Effects: Returns true if x and y are equal //! //! Complexity: Linear to the number of elements in the container. diff --git a/include/boost/container/flat_set.hpp b/include/boost/container/flat_set.hpp index fa27006..1068734 100644 --- a/include/boost/container/flat_set.hpp +++ b/include/boost/container/flat_set.hpp @@ -114,6 +114,7 @@ class flat_set typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::sequence_type) sequence_type; public: ////////////////////////////////////////////// @@ -623,7 +624,7 @@ class flat_set BOOST_CONTAINER_FORCEINLINE void merge(flat_set& source) { this->base_t::merge_unique(source.tree()); } - //! @copydoc ::boost::container::flat_map::merge(flat_set&) + //! @copydoc ::boost::container::flat_set::merge(flat_set&) template BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_set BOOST_RV_REF_END source) { return this->merge(static_cast&>(source)); } @@ -633,7 +634,7 @@ class flat_set BOOST_CONTAINER_FORCEINLINE void merge(flat_multiset& source) { this->base_t::merge_unique(source.tree()); } - //! @copydoc ::boost::container::flat_map::merge(flat_multiset&) + //! @copydoc ::boost::container::flat_set::merge(flat_multiset&) template BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multiset BOOST_RV_REF_END source) { return this->merge(static_cast&>(source)); } @@ -844,8 +845,38 @@ class flat_set //! Complexity: Constant. friend void swap(flat_set& x, flat_set& y); + //! Effects: Extracts the internal sequence container. + //! + //! Complexity: Same as the move constructor of sequence_type, usually constant. + //! + //! Postcondition: this->empty() + //! + //! Throws: If secuence_type's move constructor throws + sequence_type extract_sequence(); + #endif //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED + //! Effects: Discards the internally hold sequence container and adopts the + //! one passed externally using the move assignment. Erases non-unique elements. + //! + //! Complexity: Assuming O(1) move assignment, O(NlogN) with N = seq.size() + //! + //! Throws: If the comparison or the move constructor throws + void adopt_sequence(BOOST_RV_REF(sequence_type) seq) + { this->base_t::adopt_sequence_unique(boost::move(seq)); } + + //! Requires: seq shall be ordered according to this->compare() + //! and shall contain unique elements. + //! + //! Effects: Discards the internally hold sequence container and adopts the + //! one passed externally using the move assignment. + //! + //! Complexity: Assuming O(1) move assignment, O(1) + //! + //! Throws: If the move assignment throws + void adopt_sequence(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq) + { this->base_t::adopt_sequence_unique(ordered_unique_range_t(), boost::move(seq)); } + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: template @@ -939,6 +970,7 @@ class flat_multiset typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::sequence_type) sequence_type; //! @copydoc ::boost::container::flat_set::flat_set() explicit flat_multiset() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible::value && @@ -1392,8 +1424,37 @@ class flat_multiset //! Complexity: Constant. friend void swap(flat_multiset& x, flat_multiset& y); + //! Effects: Extracts the internal sequence container. + //! + //! Complexity: Same as the move constructor of sequence_type, usually constant. + //! + //! Postcondition: this->empty() + //! + //! Throws: If secuence_type's move constructor throws + sequence_type extract_sequence(); + #endif //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED + //! Effects: Discards the internally hold sequence container and adopts the + //! one passed externally using the move assignment. + //! + //! Complexity: Assuming O(1) move assignment, O(NlogN) with N = seq.size() + //! + //! Throws: If the comparison or the move constructor throws + void adopt_sequence(BOOST_RV_REF(sequence_type) seq) + { this->base_t::adopt_sequence_equal(boost::move(seq)); } + + //! Requires: seq shall be ordered according to this->compare() + //! + //! Effects: Discards the internally hold sequence container and adopts the + //! one passed externally using the move assignment. + //! + //! Complexity: Assuming O(1) move assignment, O(1) + //! + //! Throws: If the move assignment throws + void adopt_sequence(ordered_range_t, BOOST_RV_REF(sequence_type) seq) + { this->base_t::adopt_sequence_equal(ordered_range_t(), boost::move(seq)); } + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: template diff --git a/include/boost/container/map.hpp b/include/boost/container/map.hpp index 5520fb4..56aefa4 100644 --- a/include/boost/container/map.hpp +++ b/include/boost/container/map.hpp @@ -31,6 +31,8 @@ #include #include #include +#include + // move #include #include @@ -53,34 +55,6 @@ namespace boost { namespace container { -///@cond - -template -struct pair_key_mapped_of_value -{ - typedef Key key_type; - typedef Mapped mapped_type; - - template - const key_type & key_of_value(const Pair &p) const - { return p.first; } - - template - const mapped_type & mapped_of_value(const Pair &p) const - { return p.second; } - - template - key_type & key_of_value(Pair &p) const - { return const_cast(p.first); } - - template - mapped_type & mapped_of_value(Pair &p) const - { return p.second; } - -}; - -///@endcond - #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED //! A map is a kind of associative container that supports unique keys (contains at @@ -150,9 +124,7 @@ class map typedef std::pair nonconst_value_type; typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; typedef BOOST_CONTAINER_IMPDEF(node_handle< - typename base_t::node_type::container_node_type - BOOST_MOVE_I value_type - BOOST_MOVE_I allocator_type + typename base_t::stored_allocator_type BOOST_MOVE_I pair_key_mapped_of_value >) node_type; typedef BOOST_CONTAINER_IMPDEF @@ -1243,9 +1215,7 @@ class multimap typedef std::pair nonconst_value_type; typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; typedef BOOST_CONTAINER_IMPDEF(node_handle< - typename base_t::node_type::container_node_type - BOOST_MOVE_I value_type - BOOST_MOVE_I allocator_type + typename base_t::stored_allocator_type BOOST_MOVE_I pair_key_mapped_of_value >) node_type; diff --git a/include/boost/container/node_handle.hpp b/include/boost/container/node_handle.hpp index c46313c..594a09c 100644 --- a/include/boost/container/node_handle.hpp +++ b/include/boost/container/node_handle.hpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include @@ -40,20 +40,34 @@ namespace container { ///@cond -template::value> +template struct node_handle_keymapped_traits +{ + typedef typename KeyMapped::key_type key_type; + typedef typename KeyMapped::mapped_type mapped_type; +}; + +template +struct node_handle_keymapped_traits { typedef Value key_type; typedef Value mapped_type; }; -template -struct node_handle_keymapped_traits +class node_handle_friend { - typedef typename KeyMapped::key_type key_type; - typedef typename KeyMapped::mapped_type mapped_type; + public: + + template + BOOST_CONTAINER_FORCEINLINE static void destroy_alloc(NH &nh) BOOST_NOEXCEPT + { nh.destroy_alloc(); } + + template + BOOST_CONTAINER_FORCEINLINE static typename NH::node_pointer &get_node_pointer(NH &nh) BOOST_NOEXCEPT + { return nh.get_node_pointer(); } }; + ///@endcond //! A node_handle is an object that accepts ownership of a single element from an associative container. @@ -73,76 +87,63 @@ struct node_handle_keymapped_traits //! //! If a node handle is not empty, then it contains an allocator that is equal to the allocator of the container //! when the element was extracted. If a node handle is empty, it contains no allocator. -template +template class node_handle { - typedef node_handle_keymapped_traits keymapped_t; + typedef NodeAllocator nallocator_type; + typedef allocator_traits nator_traits; + typedef typename nator_traits::value_type priv_node_t; + typedef typename priv_node_t::value_type priv_value_t; + typedef node_handle_keymapped_traits keymapped_t; public: - typedef Value value_type; + typedef priv_value_t value_type; typedef typename keymapped_t::key_type key_type; typedef typename keymapped_t::mapped_type mapped_type; - typedef Allocator allocator_type; - typedef NodeType container_node_type; + typedef typename nator_traits::template portable_rebind_alloc + ::type allocator_type; + + typedef priv_node_t container_node_type; + friend class node_handle_friend; ///@cond private: BOOST_MOVABLE_BUT_NOT_COPYABLE(node_handle) - typedef allocator_traits ator_traits; - typedef typename ator_traits::template portable_rebind_alloc - ::type nallocator_type; - typedef allocator_traits node_ator_traits; - typedef typename node_ator_traits::pointer node_pointer; + typedef typename nator_traits::pointer node_pointer; typedef ::boost::aligned_storage - ::value> nalloc_storage_t; + < sizeof(nallocator_type) + , boost::alignment_of::value> nalloc_storage_t; node_pointer m_ptr; nalloc_storage_t m_nalloc_storage; void move_construct_alloc(nallocator_type &al) - { ::new(m_nalloc_storage.address(), boost_container_new_t()) allocator_type(::boost::move(al)); } + { ::new(m_nalloc_storage.address(), boost_container_new_t()) nallocator_type(::boost::move(al)); } - void destroy_node() + void destroy_deallocate_node() { - node_ator_traits::destroy(this->node_alloc(), container_detail::to_raw_pointer(m_ptr)); - node_ator_traits::deallocate(this->node_alloc(), m_ptr, 1u); + nator_traits::destroy(this->node_alloc(), boost::movelib::to_raw_pointer(m_ptr)); + nator_traits::deallocate(this->node_alloc(), m_ptr, 1u); } template void move_construct_end(OtherNodeHandle &nh) { if(m_ptr){ - ::new (m_nalloc_storage.address(), boost_container_new_t()) allocator_type(::boost::move(nh.node_alloc())); - nh.destroy_alloc(); - nh.get_node_pointer() = node_pointer(); + ::new (m_nalloc_storage.address(), boost_container_new_t()) nallocator_type(::boost::move(nh.node_alloc())); + node_handle_friend::destroy_alloc(nh); + node_handle_friend::get_node_pointer(nh) = node_pointer(); } BOOST_ASSERT(nh.empty()); } - public: + void destroy_alloc() BOOST_NOEXCEPT + { static_cast(m_nalloc_storage.address())->~nallocator_type(); } - void destroy_alloc() - { static_cast(m_nalloc_storage.address())->~allocator_type(); } - - node_pointer &get_node_pointer() + node_pointer &get_node_pointer() BOOST_NOEXCEPT { return m_ptr; } - nallocator_type &node_alloc() - { return *static_cast(m_nalloc_storage.address()); } - - const nallocator_type &node_alloc() const - { return *static_cast(m_nalloc_storage.address()); } - - node_pointer release() - { - node_pointer p(m_ptr); - m_ptr = node_pointer(); - if(p) - this->destroy_alloc(); - return p; - } - ///@endcond public: @@ -150,13 +151,13 @@ class node_handle //! //! Postcondition: this->empty() BOOST_CXX14_CONSTEXPR node_handle() BOOST_NOEXCEPT - : m_ptr(), m_nalloc_storage() - { BOOST_ASSERT(this->empty()); } + : m_ptr() + { } //! Effects: Constructs a node_handle object initializing internal pointer with p. - //! If p != nullptr copy constructs internal allocator al. + //! If p != nullptr copy constructs internal allocator from al. node_handle(node_pointer p, const nallocator_type &al) BOOST_NOEXCEPT - : m_ptr(p), m_nalloc_storage() + : m_ptr(p) { if(m_ptr){ ::new (m_nalloc_storage.address(), boost_container_new_t()) nallocator_type(al); @@ -172,12 +173,12 @@ class node_handle //! Note: Two node_handle's are related if only one of KeyMapped template parameter //! of a node handle is void. template - node_handle( BOOST_RV_REF_BEG node_handle BOOST_RV_REF_END nh + node_handle( BOOST_RV_REF_BEG node_handle BOOST_RV_REF_END nh , typename container_detail::enable_if_c < ((unsigned)container_detail::is_same::value + (unsigned)container_detail::is_same::value) == 1u - >::type* = 0) - : m_ptr(nh.get_node_pointer()), m_nalloc_storage() + >::type* = 0) BOOST_NOEXCEPT + : m_ptr(nh.get()) { this->move_construct_end(nh); } //! Effects: Constructs a node_handle object initializing internal pointer with nh's internal pointer @@ -186,43 +187,44 @@ class node_handle //! //! Postcondition: nh.empty() node_handle (BOOST_RV_REF(node_handle) nh) BOOST_NOEXCEPT - : m_ptr(nh.m_ptr), m_nalloc_storage() + : m_ptr(nh.m_ptr) { this->move_construct_end(nh); } //! Effects: If !this->empty(), destroys the value_type subobject in the container_node_type object //! pointed to by c by calling allocator_traits::destroy, then deallocates m_ptr by calling - //! ator_traits::rebind_traits::deallocate. - ~node_handle () BOOST_NOEXCEPT + //! nator_traits::rebind_traits::deallocate. + ~node_handle() BOOST_NOEXCEPT { if(!this->empty()){ - this->destroy_node(); + this->destroy_deallocate_node(); this->destroy_alloc(); } } - //! Requires: Either this->empty(), or ator_traits::propagate_on_container_move_assignment is true, or + //! Requires: Either this->empty(), or nator_traits::propagate_on_container_move_assignment is true, or //! node_alloc() == nh.node_alloc(). //! //! Effects: If m_ptr != nullptr, destroys the value_type subobject in the container_node_type object - //! pointed to by m_ptr by calling ator_traits::destroy, then deallocates m_ptr by calling ator_- - //! traits::rebind_traits::deallocate. Assigns nh.m_ptr to m_ptr. If this->empty() - //! or ator_traits::propagate_on_container_move_assignment is true, move assigns nh.node_alloc() to + //! pointed to by m_ptr by calling nator_traits::destroy, then deallocates m_ptr by calling + //! nator_traits::deallocate. Assigns nh.m_ptr to m_ptr. If this->empty() + //! or nator_traits::propagate_on_container_move_assignment is true, move assigns nh.node_alloc() to //! node_alloc(). Assigns nullptr to nh.m_ptr and assigns nullopt to nh.node_alloc(). + //! //! Returns: *this. //! //! Throws: Nothing. - node_handle & operator=(BOOST_RV_REF(node_handle) nh) + node_handle & operator=(BOOST_RV_REF(node_handle) nh) BOOST_NOEXCEPT { - BOOST_ASSERT(this->empty() || nh.empty() || ator_traits::propagate_on_container_move_assignment::value - || ator_traits::equal(node_alloc(), nh.node_alloc())); + BOOST_ASSERT(this->empty() || nator_traits::propagate_on_container_move_assignment::value + || nator_traits::equal(node_alloc(), nh.node_alloc())); bool const was_this_non_null = !this->empty(); bool const was_nh_non_null = !nh.empty(); if(was_nh_non_null){ if(was_this_non_null){ - this->destroy_node(); - if(ator_traits::propagate_on_container_move_assignment::value){ + this->destroy_deallocate_node(); + if(nator_traits::propagate_on_container_move_assignment::value){ this->node_alloc() = ::boost::move(nh.node_alloc()); } } @@ -234,7 +236,7 @@ class node_handle nh.destroy_alloc(); } else if(was_this_non_null){ - this->destroy_node(); + this->destroy_deallocate_node(); this->destroy_alloc(); m_ptr = node_pointer(); } @@ -310,23 +312,23 @@ class node_handle return !this->m_ptr; } - //! Requires: this->empty(), or nh.empty(), or ator_traits::propagate_on_container_swap is true, or + //! Requires: this->empty(), or nh.empty(), or nator_traits::propagate_on_container_swap is true, or //! node_alloc() == nh.node_alloc(). //! - //! Effects: Calls swap(m_ptr, nh.m_ptr). If this->empty(), or nh.empty(), or ator_traits::propagate_on_- + //! Effects: Calls swap(m_ptr, nh.m_ptr). If this->empty(), or nh.empty(), or nator_traits::propagate_on_- //! container_swap is true calls swap(node_alloc(), nh.node_alloc()). void swap(node_handle &nh) - BOOST_NOEXCEPT_IF(ator_traits::propagate_on_container_swap::value || ator_traits::is_always_equal::value) + BOOST_NOEXCEPT_IF(nator_traits::propagate_on_container_swap::value || nator_traits::is_always_equal::value) { - BOOST_ASSERT(this->empty() || nh.empty() || ator_traits::propagate_on_container_swap::value - || ator_traits::equal(node_alloc(), nh.node_alloc())); + BOOST_ASSERT(this->empty() || nh.empty() || nator_traits::propagate_on_container_swap::value + || nator_traits::equal(node_alloc(), nh.node_alloc())); bool const was_this_non_null = !this->empty(); bool const was_nh_non_null = !nh.empty(); if(was_nh_non_null){ if(was_this_non_null){ - if(ator_traits::propagate_on_container_swap::value){ + if(nator_traits::propagate_on_container_swap::value){ ::boost::adl_move_swap(this->node_alloc(), nh.node_alloc()); } } @@ -337,11 +339,53 @@ class node_handle } else if(was_this_non_null){ nh.move_construct_alloc(this->node_alloc()); - nh.destroy_alloc(); + this->destroy_alloc(); } ::boost::adl_move_swap(m_ptr, nh.m_ptr); } + //! Effects: If this->empty() returns nullptr, otherwise returns m_ptr + //! resets m_ptr to nullptr and destroys the internal allocator. + //! + //! Postcondition: this->empty() + //! + //! Note: Non-standard extensions + node_pointer release() BOOST_NOEXCEPT + { + node_pointer p(m_ptr); + m_ptr = node_pointer(); + if(p) + this->destroy_alloc(); + return p; + } + + //! Effects: Returns m_ptr. + //! + //! Note: Non-standard extensions + node_pointer get() const BOOST_NOEXCEPT + { + return m_ptr; + } + + //! Effects: Returns a reference to the internal node allocator. + //! + //! Note: Non-standard extensions + nallocator_type &node_alloc() BOOST_NOEXCEPT + { + BOOST_ASSERT(!empty()); + return *static_cast(m_nalloc_storage.address()); + } + + + //! Effects: Returns a reference to the internal node allocator. + //! + //! Note: Non-standard extensions + const nallocator_type &node_alloc() const BOOST_NOEXCEPT + { + BOOST_ASSERT(!empty()); + return *static_cast(m_nalloc_storage.address()); + } + //! Effects: x.swap(y). //! friend void swap(node_handle & x, node_handle & y) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y))) diff --git a/include/boost/container/small_vector.hpp b/include/boost/container/small_vector.hpp index 1444624..804740c 100644 --- a/include/boost/container/small_vector.hpp +++ b/include/boost/container/small_vector.hpp @@ -387,8 +387,8 @@ class small_vector_base this->steal_resources(x); } else{ - this->assign( boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.begin())) - , boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.end ())) + this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin())) + , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.end ())) ); } } diff --git a/include/boost/container/stable_vector.hpp b/include/boost/container/stable_vector.hpp index 5d6dc0f..cf156e0 100644 --- a/include/boost/container/stable_vector.hpp +++ b/include/boost/container/stable_vector.hpp @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include // intrusive #include @@ -1975,7 +1975,7 @@ class stable_vector , container_detail::addressof(p->value) , it); //This does not throw - ::new(static_cast(container_detail::to_raw_pointer(p)), boost_container_new_t()) + ::new(static_cast(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) node_base_type(index_traits_type::ptr_to_node_base_ptr(*up_index)); } @@ -1988,7 +1988,7 @@ class stable_vector , container_detail::addressof(p->value) , ::boost::forward(value_convertible)); //This does not throw - ::new(static_cast(container_detail::to_raw_pointer(p)), boost_container_new_t()) node_base_type; + ::new(static_cast(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) node_base_type; } void priv_swap_members(stable_vector &x) diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp index 7b780fd..915fb58 100644 --- a/include/boost/container/string.hpp +++ b/include/boost/container/string.hpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include #include @@ -308,14 +308,14 @@ class basic_string_base { allocator_traits_type::construct ( this->alloc() - , container_detail::to_raw_pointer(p) + , boost::movelib::to_raw_pointer(p) , value ); } void destroy(pointer p, size_type n) { - value_type *raw_p = container_detail::to_raw_pointer(p); + value_type *raw_p = boost::movelib::to_raw_pointer(p); for(; n--; ++raw_p){ allocator_traits_type::destroy( this->alloc(), raw_p); } @@ -325,7 +325,7 @@ class basic_string_base { allocator_traits_type::destroy ( this->alloc() - , container_detail::to_raw_pointer(p) + , boost::movelib::to_raw_pointer(p) ); } @@ -1158,8 +1158,8 @@ class basic_string size_type long_storage = this->priv_long_storage(); size_type long_size = this->priv_long_size(); //Shrink from allocated buffer to the internal one, including trailing null - Traits::copy( container_detail::to_raw_pointer(this->priv_short_addr()) - , container_detail::to_raw_pointer(long_addr) + Traits::copy( boost::movelib::to_raw_pointer(this->priv_short_addr()) + , boost::movelib::to_raw_pointer(long_addr) , long_size+1); this->is_short(true); this->alloc().deallocate(long_addr, long_storage); @@ -1492,7 +1492,7 @@ class basic_string { size_type n = static_cast(last - first); this->reserve(n); - CharT* ptr = container_detail::to_raw_pointer(this->priv_addr()); + CharT* ptr = boost::movelib::to_raw_pointer(this->priv_addr()); Traits::copy(ptr, first, n); this->priv_construct_null(ptr + n); this->priv_size(n); @@ -1511,7 +1511,7 @@ class basic_string { size_type cur = 0; const pointer addr = this->priv_addr(); - CharT *ptr = container_detail::to_raw_pointer(addr); + CharT *ptr = boost::movelib::to_raw_pointer(addr); const size_type old_size = this->priv_size(); while (first != last && cur != old_size) { Traits::assign(*ptr, *first); @@ -1570,7 +1570,7 @@ class basic_string size_type len = container_detail::min_value(n, str_size - pos2); if (sz > this->max_size() - len) throw_length_error("basic_string::insert max_size() exceeded"); - const CharT *beg_ptr = container_detail::to_raw_pointer(s.begin()) + pos2; + const CharT *beg_ptr = boost::movelib::to_raw_pointer(s.begin()) + pos2; const CharT *end_ptr = beg_ptr + len; this->insert(this->priv_addr() + pos1, beg_ptr, end_ptr); return *this; @@ -1730,10 +1730,10 @@ class basic_string pointer_past_last, pointer_past_last); this->priv_size(old_size+n); - Traits::move(const_cast(container_detail::to_raw_pointer(p + n)), - container_detail::to_raw_pointer(p), + Traits::move(const_cast(boost::movelib::to_raw_pointer(p + n)), + boost::movelib::to_raw_pointer(p), (elems_after - n) + 1); - this->priv_copy(first, last, const_cast(container_detail::to_raw_pointer(p))); + this->priv_copy(first, last, const_cast(boost::movelib::to_raw_pointer(p))); } else { ForwardIter mid = first; @@ -1746,7 +1746,7 @@ class basic_string (p, const_iterator(old_start + old_length + 1), old_start + newer_size); this->priv_size(newer_size + elems_after); - this->priv_copy(first, mid, const_cast(container_detail::to_raw_pointer(p))); + this->priv_copy(first, mid, const_cast(boost::movelib::to_raw_pointer(p))); } } else{ @@ -1773,9 +1773,9 @@ class basic_string else{ //value_type is POD, so backwards expansion is much easier //than with vector - value_type * const oldbuf = container_detail::to_raw_pointer(old_start); - value_type * const newbuf = container_detail::to_raw_pointer(new_start); - const value_type *const pos = container_detail::to_raw_pointer(p); + value_type * const oldbuf = boost::movelib::to_raw_pointer(old_start); + value_type * const newbuf = boost::movelib::to_raw_pointer(new_start); + const value_type *const pos = boost::movelib::to_raw_pointer(p); const size_type before = pos - oldbuf; //First move old data @@ -1847,10 +1847,10 @@ class basic_string iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW { // The move includes the terminating null. - CharT * const ptr = const_cast(container_detail::to_raw_pointer(p)); + CharT * const ptr = const_cast(boost::movelib::to_raw_pointer(p)); const size_type old_size = this->priv_size(); Traits::move(ptr, - container_detail::to_raw_pointer(p + 1), + boost::movelib::to_raw_pointer(p + 1), old_size - (p - this->priv_addr())); this->priv_size(old_size-1); return iterator(ptr); @@ -1866,12 +1866,12 @@ class basic_string //! the other elements being erased. If no such element exists, end() is returned. iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW { - CharT * f = const_cast(container_detail::to_raw_pointer(first)); + CharT * f = const_cast(boost::movelib::to_raw_pointer(first)); if (first != last) { // The move includes the terminating null. const size_type num_erased = last - first; const size_type old_size = this->priv_size(); Traits::move(f, - container_detail::to_raw_pointer(last), + boost::movelib::to_raw_pointer(last), (old_size + 1)-(last - this->priv_addr())); const size_type new_length = old_size - num_erased; this->priv_size(new_length); @@ -2059,11 +2059,11 @@ class basic_string { const size_type len = static_cast(i2 - i1); if (len >= n) { - Traits::assign(const_cast(container_detail::to_raw_pointer(i1)), n, c); + Traits::assign(const_cast(boost::movelib::to_raw_pointer(i1)), n, c); erase(i1 + n, i2); } else { - Traits::assign(const_cast(container_detail::to_raw_pointer(i1)), len, c); + Traits::assign(const_cast(boost::movelib::to_raw_pointer(i1)), len, c); insert(i2, n - len, c); } return *this; @@ -2088,7 +2088,7 @@ class basic_string ) { for ( ; i1 != i2 && j1 != j2; ++i1, ++j1){ - Traits::assign(*const_cast(container_detail::to_raw_pointer(i1)), *j1); + Traits::assign(*const_cast(boost::movelib::to_raw_pointer(i1)), *j1); } if (j1 == j2) @@ -2111,13 +2111,13 @@ class basic_string difference_type n = boost::container::iterator_distance(j1, j2); const difference_type len = i2 - i1; if (len >= n) { - this->priv_copy(j1, j2, const_cast(container_detail::to_raw_pointer(i1))); + this->priv_copy(j1, j2, const_cast(boost::movelib::to_raw_pointer(i1))); this->erase(i1 + n, i2); } else { ForwardIter m = j1; boost::container::iterator_advance(m, len); - this->priv_copy(j1, m, const_cast(container_detail::to_raw_pointer(i1))); + this->priv_copy(j1, m, const_cast(boost::movelib::to_raw_pointer(i1))); this->insert(i2, m, j2); } return *this; @@ -2128,7 +2128,7 @@ class basic_string //! //! Effects: Calls `replace(i1 - begin(), i2 - i1, sv).`. //! - //! : *this. + //! Returns: *this. template