summaryrefslogtreecommitdiff
path: root/boost/container
diff options
context:
space:
mode:
Diffstat (limited to 'boost/container')
-rw-r--r--boost/container/allocator_traits.hpp2
-rw-r--r--boost/container/deque.hpp20
-rw-r--r--boost/container/detail/adaptive_node_pool_impl.hpp16
-rw-r--r--boost/container/detail/advanced_insert_int.hpp10
-rw-r--r--boost/container/detail/algorithm.hpp122
-rw-r--r--boost/container/detail/copy_move_algo.hpp69
-rw-r--r--boost/container/detail/destroyers.hpp10
-rw-r--r--boost/container/detail/flat_tree.hpp332
-rw-r--r--boost/container/detail/iterator_to_raw_pointer.hpp29
-rw-r--r--boost/container/detail/multiallocation_chain.hpp6
-rw-r--r--boost/container/detail/node_alloc_holder.hpp34
-rw-r--r--boost/container/detail/node_pool_impl.hpp4
-rw-r--r--boost/container/detail/pair.hpp61
-rw-r--r--boost/container/detail/pair_key_mapped_of_value.hpp55
-rw-r--r--boost/container/detail/to_raw_pointer.hpp33
-rw-r--r--boost/container/detail/tree.hpp145
-rw-r--r--boost/container/flat_map.hpp830
-rw-r--r--boost/container/flat_set.hpp409
-rw-r--r--boost/container/map.hpp528
-rw-r--r--boost/container/node_handle.hpp188
-rw-r--r--boost/container/set.hpp349
-rw-r--r--boost/container/small_vector.hpp4
-rw-r--r--boost/container/stable_vector.hpp6
-rw-r--r--boost/container/string.hpp116
-rw-r--r--boost/container/vector.hpp149
25 files changed, 2296 insertions, 1231 deletions
diff --git a/boost/container/allocator_traits.hpp b/boost/container/allocator_traits.hpp
index d6621f614a..b08f601461 100644
--- a/boost/container/allocator_traits.hpp
+++ b/boost/container/allocator_traits.hpp
@@ -347,7 +347,7 @@ struct allocator_traits
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: calls <code>a.construct(p, std::forward<Args>(args)...)</code> if that call is well-formed;
- //! otherwise, invokes <code>::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)</code>
+ //! otherwise, invokes <code>`placement new` (static_cast<void*>(p)) T(std::forward<Args>(args)...)</code>
template <class T, class ...Args>
BOOST_CONTAINER_FORCEINLINE static void construct(Allocator & a, T* p, BOOST_FWD_REF(Args)... args)
{
diff --git a/boost/container/deque.hpp b/boost/container/deque.hpp
index 255cd9399d..b838f6e4eb 100644
--- a/boost/container/deque.hpp
+++ b/boost/container/deque.hpp
@@ -31,11 +31,11 @@
#include <boost/container/detail/alloc_helpers.hpp>
#include <boost/container/detail/copy_move_algo.hpp>
#include <boost/container/detail/iterator.hpp>
-#include <boost/container/detail/iterator_to_raw_pointer.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/min_max.hpp>
#include <boost/container/detail/mpl.hpp>
-#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
#include <boost/container/detail/type_traits.hpp>
// move
#include <boost/move/adl_move_swap.hpp>
@@ -1649,7 +1649,7 @@ class deque : protected deque_base<Allocator>
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<Allocator>
--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<Allocator>
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<Allocator>
}
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<Allocator>
{
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<Allocator>
{
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<Allocator>
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>
{
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/boost/container/detail/adaptive_node_pool_impl.hpp b/boost/container/detail/adaptive_node_pool_impl.hpp
index 24c81dda3b..54db19dff2 100644
--- a/boost/container/detail/adaptive_node_pool_impl.hpp
+++ b/boost/container/detail/adaptive_node_pool_impl.hpp
@@ -28,10 +28,10 @@
// container/detail
#include <boost/container/detail/pool_common.hpp>
#include <boost/container/detail/iterator.hpp>
-#include <boost/container/detail/iterator_to_raw_pointer.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
#include <boost/container/detail/math_functions.hpp>
#include <boost/container/detail/mpl.hpp>
-#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
#include <boost/container/detail/type_traits.hpp>
// intrusive
#include <boost/intrusive/pointer_traits.hpp>
@@ -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<char *>(container_detail::to_raw_pointer
+ mem_address = static_cast<char *>(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/boost/container/detail/advanced_insert_int.hpp b/boost/container/detail/advanced_insert_int.hpp
index 1050857c46..20adb523a6 100644
--- a/boost/container/detail/advanced_insert_int.hpp
+++ b/boost/container/detail/advanced_insert_int.hpp
@@ -31,7 +31,7 @@
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/iterators.hpp>
-#include <boost/container/detail/iterator_to_raw_pointer.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#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<IdxPack...>&, Iterator p, size_type n)
{
BOOST_ASSERT(n == 1); (void)n;
- alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::forward<Args>(get<IdxPack>(this->args_))... );
+ alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::forward<Args>(get<IdxPack>(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/boost/container/detail/algorithm.hpp b/boost/container/detail/algorithm.hpp
index 67e7876345..11844220e1 100644
--- a/boost/container/detail/algorithm.hpp
+++ b/boost/container/detail/algorithm.hpp
@@ -29,6 +29,128 @@ namespace container {
using boost::intrusive::algo_equal;
using boost::intrusive::algo_lexicographical_compare;
+template<class Func>
+class binder1st
+{
+ public:
+ typedef typename Func::second_argument_type argument_type;
+ typedef typename Func::result_type result_type;
+
+ binder1st(const Func& func, const typename Func::first_argument_type& arg)
+ : op(func), value(arg)
+ {}
+
+ result_type operator()(const argument_type& arg) const
+ { return op(value, arg); }
+
+ result_type operator()(argument_type& arg) const
+ { return op(value, arg); }
+
+ private:
+ Func op;
+ typename Func::first_argument_type value;
+};
+
+template<class Func, class T>
+inline binder1st<Func> bind1st(const Func& func, const T& arg)
+{ return boost::container::binder1st<Func>(func, arg); }
+
+template<class Func>
+class binder2nd
+{
+ public:
+ typedef typename Func::first_argument_type argument_type;
+ typedef typename Func::result_type result_type;
+
+ binder2nd(const Func& func, const typename Func::second_argument_type& arg)
+ : op(func), value(arg)
+ {}
+
+ result_type operator()(const argument_type& arg) const
+ { return op(arg, value); }
+
+ result_type operator()(argument_type& arg) const
+ { return op(arg, value); }
+
+ private:
+ Func op;
+ typename Func::second_argument_type value;
+};
+
+template<class Func, class T>
+inline binder2nd<Func> bind2nd(const Func& func, const T& arg)
+{
+ return (boost::container::binder2nd<Func>(func, arg));
+}
+
+template<class Func>
+class unary_negate
+{
+ public:
+ typedef typename Func::argument_type argument_type;
+ typedef typename Func::result_type result_type;
+
+ explicit unary_negate(const Func& func)
+ : m_func(func)
+ {}
+
+ bool operator()(const typename Func::argument_type& arg) const
+ { return !m_func(arg); }
+
+ private:
+ Func m_func;
+};
+
+template<class Func> inline
+unary_negate<Func> not1(const Func& func)
+{
+ return boost::container::unary_negate<Func>(func);
+}
+
+template<class InputIt, class UnaryPredicate>
+InputIt find_if(InputIt first, InputIt last, UnaryPredicate p)
+{
+ for (; first != last; ++first) {
+ if (p(*first)) {
+ return first;
+ }
+ }
+ return last;
+}
+
+template<class InputIt, class ForwardIt, class BinaryPredicate>
+InputIt find_first_of(InputIt first1, InputIt last1, ForwardIt first2, ForwardIt last2, BinaryPredicate p)
+{
+ for (; first1 != last1; ++first1) {
+ for (ForwardIt it = first2; it != last2; ++it) {
+ if (p(*first1, *it)) {
+ return first1;
+ }
+ }
+ }
+ return last1;
+}
+
+template<class ForwardIt1, class ForwardIt2, class BinaryPredicate>
+ForwardIt1 search(ForwardIt1 first1, ForwardIt1 last1,
+ ForwardIt2 first2, ForwardIt2 last2, BinaryPredicate p)
+{
+ for (; ; ++first1) {
+ ForwardIt1 it = first1;
+ for (ForwardIt2 it2 = first2; ; ++it, ++it2) {
+ if (it2 == last2) {
+ return first1;
+ }
+ if (it == last1) {
+ return last1;
+ }
+ if (!p(*it, *it2)) {
+ break;
+ }
+ }
+ }
+}
+
} //namespace container {
} //namespace boost {
diff --git a/boost/container/detail/copy_move_algo.hpp b/boost/container/detail/copy_move_algo.hpp
index dda311aa33..9044960e79 100644
--- a/boost/container/detail/copy_move_algo.hpp
+++ b/boost/container/detail/copy_move_algo.hpp
@@ -22,7 +22,7 @@
#include <boost/container/allocator_traits.hpp>
// container/detail
#include <boost/container/detail/iterator.hpp>
-#include <boost/container/detail/iterator_to_raw_pointer.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/construct_in_place.hpp>
@@ -178,7 +178,7 @@ inline F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
typedef typename boost::container::iterator_traits<I>::value_type value_type;
typename boost::container::iterator_traits<I>::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<I>::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<I>::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<I>::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<I, F
F back = r;
BOOST_TRY{
while (f != l) {
- allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
+ allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f));
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -340,13 +340,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
F back = r;
BOOST_TRY{
while (n--) {
- allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
+ allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f));
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -385,13 +385,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
F back = r;
BOOST_TRY{
while (n--) {
- allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
+ allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f));
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -430,13 +430,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
F back = r;
BOOST_TRY{
while (f != l) {
- allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
+ allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f);
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -475,13 +475,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
F back = r;
BOOST_TRY{
while (n--) {
- allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
+ allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f);
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -520,13 +520,13 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
F back = r;
BOOST_TRY{
while (n--) {
- boost::container::construct_in_place(a, container_detail::iterator_to_raw_pointer(r), f);
+ boost::container::construct_in_place(a, boost::movelib::iterator_to_raw_pointer(r), f);
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -564,13 +564,13 @@ inline typename container_detail::disable_if_memzero_initializable<F, F>::type
F back = r;
BOOST_TRY{
while (n--) {
- allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r));
+ allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r));
++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -585,7 +585,7 @@ inline typename container_detail::enable_if_memzero_initializable<F, F>::type
uninitialized_value_init_alloc_n(Allocator &, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
{
typedef typename boost::container::iterator_traits<F>::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<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), default_init);
+ allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), default_init);
++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::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<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(f), t);
+ allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(f), t);
++f;
}
}
BOOST_CATCH(...){
for (; back != l; ++back){
- allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::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<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), v);
+ allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), v);
++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -890,7 +890,7 @@ inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>
typedef typename boost::container::iterator_traits<I>::value_type value_type;
const typename boost::container::iterator_traits<I>::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;
}
@@ -963,8 +963,9 @@ template
inline typename container_detail::disable_if_trivially_destructible<I, void>::type
destroy_alloc_n(Allocator &a, I f, U n)
{
- while(n--){
- allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(f));
+ while(n){
+ --n;
+ allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(f));
++f;
}
}
@@ -1021,9 +1022,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<void*>(container_detail::iterator_to_raw_pointer(large_range_f));
- void *const short_ptr = static_cast<void*>(container_detail::iterator_to_raw_pointer(short_range_f));
- void *const stora_ptr = static_cast<void*>(container_detail::iterator_to_raw_pointer(storage));
+ void *const large_ptr = static_cast<void*>(boost::movelib::iterator_to_raw_pointer(large_range_f));
+ void *const short_ptr = static_cast<void*>(boost::movelib::iterator_to_raw_pointer(short_range_f));
+ void *const stora_ptr = static_cast<void*>(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 +1053,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<char*>(static_cast<void*>(container_detail::iterator_to_raw_pointer(large_range_f)));
- char *short_ptr = static_cast<char*>(static_cast<void*>(container_detail::iterator_to_raw_pointer(short_range_f)));
+ char *large_ptr = static_cast<char*>(static_cast<void*>(boost::movelib::iterator_to_raw_pointer(large_range_f)));
+ char *short_ptr = static_cast<char*>(static_cast<void*>(boost::movelib::iterator_to_raw_pointer(short_range_f)));
char *stora_ptr = static_cast<char*>(static_cast<void*>(&storage));
std::size_t szt_times = n_i_bytes/sizeof_storage;
diff --git a/boost/container/detail/destroyers.hpp b/boost/container/detail/destroyers.hpp
index 52b44c0363..b110561a4a 100644
--- a/boost/container/detail/destroyers.hpp
+++ b/boost/container/detail/destroyers.hpp
@@ -25,7 +25,7 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/container/allocator_traits.hpp>
-#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
#include <boost/container/detail/version_type.hpp>
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<Allocator>::destroy(a_, container_detail::to_raw_pointer(p));
+ allocator_traits<Allocator>::destroy(a_, boost::movelib::to_raw_pointer(p));
c_.push_back(p);
}
};
diff --git a/boost/container/detail/flat_tree.hpp b/boost/container/detail/flat_tree.hpp
index 93984d18e5..9aab87308a 100644
--- a/boost/container/detail/flat_tree.hpp
+++ b/boost/container/detail/flat_tree.hpp
@@ -28,25 +28,30 @@
#include <boost/container/detail/pair.hpp>
#include <boost/container/vector.hpp>
+#include <boost/container/allocator_traits.hpp>
+
#include <boost/container/detail/value_init.hpp>
#include <boost/container/detail/destroyers.hpp>
#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/is_sorted.hpp>
-#include <boost/container/allocator_traits.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/iterators.hpp>
+
#ifdef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
#include <boost/intrusive/pointer_traits.hpp>
#endif
-#include <boost/container/detail/type_traits.hpp>
-#include <boost/container/detail/iterators.hpp>
+#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
+
#include <boost/move/make_unique.hpp>
+#include <boost/move/iterator.hpp>
#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/algo/adaptive_sort.hpp>
+
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
-#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
-#include <boost/move/iterator.hpp>
namespace boost {
namespace container {
@@ -105,14 +110,17 @@ template <class Value, class KeyOfValue,
class Compare, class Allocator>
class flat_tree
{
- typedef boost::container::vector<Value, Allocator> vector_t;
+ public:
+ typedef boost::container::vector<Value, Allocator> sequence_type;
+
+ private:
typedef Allocator allocator_t;
typedef allocator_traits<Allocator> allocator_traits_type;
public:
typedef flat_tree_value_compare<Compare, Value, KeyOfValue> 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<const value_compare&>(d)), m_vect(d.m_vect)
+ explicit Data(const allocator_t &alloc)
+ : value_compare(), m_seq(alloc)
{}
- Data(BOOST_RV_REF(Data) d)
- : value_compare(boost::move(static_cast<value_compare&>(d))), m_vect(boost::move(d.m_vect))
+ explicit Data(const Compare &comp)
+ : value_compare(comp), m_seq()
{}
- Data(const Data &d, const Allocator &a)
- : value_compare(static_cast<const value_compare&>(d)), m_vect(d.m_vect, a)
+ Data(const Compare &comp, const allocator_t &alloc)
+ : value_compare(comp), m_seq(alloc)
{}
- Data(BOOST_RV_REF(Data) d, const Allocator &a)
- : value_compare(boost::move(static_cast<value_compare&>(d))), m_vect(boost::move(d.m_vect), a)
+ explicit Data(const Data &d)
+ : value_compare(static_cast<const value_compare&>(d)), m_seq(d.m_seq)
{}
- explicit Data(const Compare &comp)
- : value_compare(comp), m_vect()
+ Data(BOOST_RV_REF(Data) d)
+ : value_compare(boost::move(static_cast<value_compare&>(d))), m_seq(boost::move(d.m_seq))
{}
- Data(const Compare &comp, const allocator_t &alloc)
- : value_compare(comp), m_vect(alloc)
+ Data(const Data &d, const Allocator &a)
+ : value_compare(static_cast<const value_compare&>(d)), m_seq(d.m_seq, a)
{}
- explicit Data(const allocator_t &alloc)
- : value_compare(), m_vect(alloc)
+ Data(BOOST_RV_REF(Data) d, const Allocator &a)
+ : value_compare(boost::move(static_cast<value_compare&>(d))), m_seq(boost::move(d.m_seq), a)
{}
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<value_compare &>(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_type> stored_allocator_traits;
@@ -211,14 +219,14 @@ class flat_tree
: m_data(comp)
{ }
- BOOST_CONTAINER_FORCEINLINE flat_tree(const Compare& comp, const allocator_type& a)
- : m_data(comp, a)
- { }
-
BOOST_CONTAINER_FORCEINLINE explicit flat_tree(const allocator_type& a)
: m_data(a)
{ }
+ BOOST_CONTAINER_FORCEINLINE flat_tree(const Compare& comp, const allocator_type& a)
+ : m_data(comp, a)
+ { }
+
BOOST_CONTAINER_FORCEINLINE flat_tree(const flat_tree& x)
: m_data(x.m_data)
{ }
@@ -237,46 +245,92 @@ class flat_tree
{ }
template <class InputIterator>
- flat_tree( ordered_range_t, InputIterator first, InputIterator last
- , const Compare& comp = Compare()
- , const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE
+ flat_tree( ordered_range_t, InputIterator first, InputIterator last)
+ : m_data()
+ {
+ 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 <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_tree( ordered_range_t, InputIterator first, InputIterator last, const Compare& comp)
+ : m_data(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 <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_tree( ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
: 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 <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_tree( ordered_unique_range_t, InputIterator first, InputIterator last)
+ : m_data()
+ {
+ 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 <class InputIterator>
- flat_tree( ordered_unique_range_t, InputIterator first, InputIterator last
- , const Compare& comp = Compare()
- , const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE
+ flat_tree( ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp)
+ : m_data(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 <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_tree( ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
: 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 <class InputIterator>
- flat_tree( bool unique_insertion
- , InputIterator first, InputIterator last
- , const Compare& comp = Compare()
- , const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE
+ flat_tree( bool unique_insertion, InputIterator first, InputIterator last)
+ : m_data()
+ {
+ this->priv_range_insertion_construct(unique_insertion, first, last);
+ }
+
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_tree( bool unique_insertion, InputIterator first, InputIterator last
+ , const Compare& comp)
+ : m_data(comp)
+ {
+ this->priv_range_insertion_construct(unique_insertion, first, last);
+ }
+
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_tree( bool unique_insertion, InputIterator first, InputIterator last
+ , const allocator_type& a)
+ : m_data(a)
+ {
+ this->priv_range_insertion_construct(unique_insertion, first, last);
+ }
+
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_tree( bool unique_insertion, InputIterator first, InputIterator last
+ , const Compare& comp, const allocator_type& a)
: m_data(comp, a)
{
- //Use cend() as hint to achieve linear time for
- //ordered ranges as required by the standard
- //for the constructor
- //Call end() every iteration as reallocation might have invalidated iterators
- if(unique_insertion){
- for ( ; first != last; ++first){
- this->insert_unique(this->cend(), *first);
- }
- }
- else{
- for ( ; first != last; ++first){
- this->insert_equal(this->cend(), *first);
- }
- }
+ this->priv_range_insertion_construct(unique_insertion, first, last);
}
BOOST_CONTAINER_FORCEINLINE ~flat_tree()
@@ -312,31 +366,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 +411,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 +449,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 +563,7 @@ class flat_tree
>::type * = 0
#endif
)
- { this->m_data.m_vect.merge(first, last, static_cast<const value_compare &>(this->m_data)); }
+ { this->m_data.m_seq.merge(first, last, static_cast<const value_compare &>(this->m_data)); }
template <class InIt>
void insert_unique(ordered_unique_range_t, InIt first, InIt last
@@ -538,7 +592,7 @@ class flat_tree
>::type * = 0
#endif
)
- { this->m_data.m_vect.merge_unique(first, last, static_cast<const value_compare &>(this->m_data)); }
+ { this->m_data.m_seq.merge_unique(first, last, static_cast<const value_compare &>(this->m_data)); }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
@@ -606,7 +660,7 @@ class flat_tree
typedef typename emplace_functor_type<try_emplace_t, KeyType, Args...>::type func_t;
typedef emplace_iterator<value_type, func_t, difference_type> it_t;
func_t func(try_emplace_t(), ::boost::forward<KeyType>(key), ::boost::forward<Args>(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 +729,7 @@ class flat_tree
typedef typename emplace_functor_type<try_emplace_t, KeyType BOOST_MOVE_I##N BOOST_MOVE_TARG##N>::type func_t;\
typedef emplace_iterator<value_type, func_t, difference_type> it_t;\
func_t func(try_emplace_t(), ::boost::forward<KeyType>(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 +756,29 @@ class flat_tree
typedef typename emplace_functor_type<KeyType, M>::type func_t;
typedef emplace_iterator<value_type, func_t, difference_type> it_t;
func_t func(boost::forward<KeyType>(key), boost::forward<M>(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<iterator,iterator > itp = this->equal_range(k);
size_type ret = static_cast<size_type>(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(); }
//! <b>Effects</b>: Tries to deallocate the excess of memory created
// with previous allocations. The size of the vector is unchanged
@@ -733,19 +787,19 @@ class flat_tree
//!
//! <b>Complexity</b>: 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 +847,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<const value_compare &>(this->m_data));
@@ -801,7 +855,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<const value_compare &>(this->m_data));
@@ -832,10 +886,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<value_compare>(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)
{
@@ -864,6 +969,25 @@ class flat_tree
private:
+ template <class InputIterator>
+ void priv_range_insertion_construct( bool unique_insertion, InputIterator first, InputIterator last)
+ {
+ //Use cend() as hint to achieve linear time for
+ //ordered ranges as required by the standard
+ //for the constructor
+ //Call end() every iteration as reallocation might have invalidated iterators
+ if(unique_insertion){
+ for ( ; first != last; ++first){
+ this->insert_unique(this->cend(), *first);
+ }
+ }
+ else{
+ for ( ; first != last; ++first){
+ this->insert_equal(this->cend(), *first);
+ }
+ }
+ }
+
BOOST_CONTAINER_FORCEINLINE bool priv_in_range_or_end(const_iterator pos) const
{
return (this->begin() <= pos) && (pos <= this->end());
@@ -963,7 +1087,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>(convertible));
}
diff --git a/boost/container/detail/iterator_to_raw_pointer.hpp b/boost/container/detail/iterator_to_raw_pointer.hpp
index 83736d8bb1..8c7c880035 100644
--- a/boost/container/detail/iterator_to_raw_pointer.hpp
+++ b/boost/container/detail/iterator_to_raw_pointer.hpp
@@ -18,38 +18,13 @@
# pragma once
#endif
-#include <boost/container/detail/iterator.hpp>
-#include <boost/container/detail/to_raw_pointer.hpp>
-#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
namespace boost {
namespace container {
namespace container_detail {
-template <class T>
-inline T* iterator_to_pointer(T* i)
-{ return i; }
-
-template <class Iterator>
-inline typename boost::container::iterator_traits<Iterator>::pointer
- iterator_to_pointer(const Iterator &i)
-{ return i.operator->(); }
-
-template <class Iterator>
-struct iterator_to_element_ptr
-{
- typedef typename boost::container::iterator_traits<Iterator>::pointer pointer;
- typedef typename boost::intrusive::pointer_traits<pointer>::element_type element_type;
- typedef element_type* type;
-};
-
-template <class Iterator>
-inline typename iterator_to_element_ptr<Iterator>::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/boost/container/detail/multiallocation_chain.hpp b/boost/container/detail/multiallocation_chain.hpp
index 32f87c8ae9..bce1b8651f 100644
--- a/boost/container/detail/multiallocation_chain.hpp
+++ b/boost/container/detail/multiallocation_chain.hpp
@@ -24,7 +24,7 @@
// container
#include <boost/container/container_fwd.hpp>
// container/detail
-#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
#include <boost/container/detail/transform_iterator.hpp>
#include <boost/container/detail/type_traits.hpp>
// intrusive
@@ -63,7 +63,7 @@ class basic_multiallocation_chain
pointer_traits<node_ptr> node_ptr_traits;
static node & to_node(const VoidPointer &p)
- { return *static_cast<node*>(static_cast<void*>(container_detail::to_raw_pointer(p))); }
+ { return *static_cast<node*>(static_cast<void*>(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/boost/container/detail/node_alloc_holder.hpp b/boost/container/detail/node_alloc_holder.hpp
index 7ef5d2883e..b6e602e884 100644
--- a/boost/container/detail/node_alloc_holder.hpp
+++ b/boost/container/detail/node_alloc_holder.hpp
@@ -30,10 +30,10 @@
#include <boost/container/detail/allocator_version_traits.hpp>
#include <boost/container/detail/construct_in_place.hpp>
#include <boost/container/detail/destroyers.hpp>
-#include <boost/container/detail/iterator_to_raw_pointer.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/placement_new.hpp>
-#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/version_type.hpp>
// intrusive
@@ -106,23 +106,23 @@ struct node_alloc_holder
: members_(a)
{}
+ //Constructors for associative containers
+ node_alloc_holder(const value_compare &c, const ValAlloc &a)
+ : members_(a, c)
+ {}
+
explicit node_alloc_holder(const node_alloc_holder &x)
: members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
{}
+ node_alloc_holder(const node_alloc_holder &x, const value_compare &c)
+ : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c)
+ {}
+
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x)
: members_(boost::move(x.node_alloc()))
{ this->icont().swap(x.icont()); }
- //Constructors for associative containers
- explicit node_alloc_holder(const value_compare &c, const ValAlloc &a)
- : members_(a, c)
- {}
-
- explicit node_alloc_holder(const value_compare &c, const node_alloc_holder &x)
- : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c)
- {}
-
explicit node_alloc_holder(const value_compare &c)
: members_(c)
{}
@@ -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<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+ ::new(static_cast<hook_type*>(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<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;\
+ ::new(static_cast<hook_type*>(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<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+ ::new(static_cast<hook_type*>(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<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+ ::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type;
return (p);
}
void destroy_node(const NodePtr &nodep)
{
- allocator_traits<NodeAlloc>::destroy(this->node_alloc(), container_detail::to_raw_pointer(nodep));
+ allocator_traits<NodeAlloc>::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<NodeAlloc> 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/boost/container/detail/node_pool_impl.hpp b/boost/container/detail/node_pool_impl.hpp
index 4febf19e90..024bf306c5 100644
--- a/boost/container/detail/node_pool_impl.hpp
+++ b/boost/container/detail/node_pool_impl.hpp
@@ -25,7 +25,7 @@
#include <boost/container/detail/math_functions.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/pool_common.hpp>
-#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/intrusive/pointer_traits.hpp>
@@ -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/boost/container/detail/pair.hpp b/boost/container/detail/pair.hpp
index 4abff4b4d8..4755e569b2 100644
--- a/boost/container/detail/pair.hpp
+++ b/boost/container/detail/pair.hpp
@@ -35,16 +35,62 @@
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
#include <boost/move/utility_core.hpp>
-#include<boost/move/detail/fwd_macros.hpp>
+#include <boost/move/detail/fwd_macros.hpp>
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 <class TupleClass>
+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<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
+{
+ static const bool value = true;
+};
+
+template<class Tuple>
+struct disable_if_boost_tuple
+ : boost::container::container_detail::disable_if< is_boost_tuple<Tuple> >
+{};
+
+template<class T>
+struct is_tuple_null
+{
+ static const bool value = false;
+};
+
+template<>
+struct is_tuple_null<boost::tuples::null_type>
+{
+ 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<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> p\
- , BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q)\
+ , BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q\
+ , typename container_detail::enable_if_c\
+ < pair_impl::is_boost_tuple< BoostTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> >::value &&\
+ !(pair_impl::is_tuple_null<BOOST_MOVE_LAST_TARG##N>::value || pair_impl::is_tuple_null<BOOST_MOVE_LAST_TARGQ##M>::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<template<class ...> class Tuple, class... Args1, class... Args2>
+ template< template<class ...> class Tuple, class... Args1, class... Args2
+ , class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type>
pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
: pair(t1, t2, typename build_number_seq<sizeof...(Args1)>::type(), typename build_number_seq<sizeof...(Args2)>::type())
{}
@@ -270,7 +322,8 @@ struct pair
{ (void)t; return T(::boost::forward<Args>(get<Indexes>(t))...); }
public:
- template<template<class ...> class Tuple, class... Args1, class... Args2>
+ template< template<class ...> class Tuple, class... Args1, class... Args2
+ , class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type>
pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
: first (build_from_args<first_type> (::boost::move(t1)))
, second (build_from_args<second_type>(::boost::move(t2)))
diff --git a/boost/container/detail/pair_key_mapped_of_value.hpp b/boost/container/detail/pair_key_mapped_of_value.hpp
new file mode 100644
index 0000000000..6112b87826
--- /dev/null
+++ b/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 <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+namespace boost {
+namespace container {
+
+template<class Key, class Mapped>
+struct pair_key_mapped_of_value
+{
+ typedef Key key_type;
+ typedef Mapped mapped_type;
+
+ template<class Pair>
+ const key_type & key_of_value(const Pair &p) const
+ { return p.first; }
+
+ template<class Pair>
+ const mapped_type & mapped_of_value(const Pair &p) const
+ { return p.second; }
+
+ template<class Pair>
+ key_type & key_of_value(Pair &p) const
+ { return const_cast<key_type&>(p.first); }
+
+ template<class Pair>
+ mapped_type & mapped_of_value(Pair &p) const
+ { return p.second; }
+
+};
+
+}}
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINER_PAIR_KEY_MAPPED_OF_VALUE_HPP
diff --git a/boost/container/detail/to_raw_pointer.hpp b/boost/container/detail/to_raw_pointer.hpp
deleted file mode 100644
index 0b4445a942..0000000000
--- a/boost/container/detail/to_raw_pointer.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2014-2015. 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_DETAIL_TO_RAW_POINTER_HPP
-#define BOOST_CONTAINER_DETAIL_TO_RAW_POINTER_HPP
-
-#ifndef BOOST_CONFIG_HPP
-# include <boost/config.hpp>
-#endif
-
-#if defined(BOOST_HAS_PRAGMA_ONCE)
-# pragma once
-#endif
-
-#include <boost/intrusive/detail/to_raw_pointer.hpp>
-
-namespace boost {
-namespace container {
-namespace container_detail {
-
-using ::boost::intrusive::detail::to_raw_pointer;
-
-} //namespace container_detail {
-} //namespace container {
-} //namespace boost {
-
-#endif //#ifndef BOOST_CONTAINER_DETAIL_TO_RAW_POINTER_HPP
diff --git a/boost/container/detail/tree.hpp b/boost/container/detail/tree.hpp
index 853d0ad843..99baf3a257 100644
--- a/boost/container/detail/tree.hpp
+++ b/boost/container/detail/tree.hpp
@@ -493,7 +493,7 @@ class tree
typedef boost::container::reverse_iterator
<const_iterator> const_reverse_iterator;
typedef node_handle
- < Node, value_type, allocator_type, void> node_type;
+ < NodeAlloc, void> node_type;
typedef insert_return_type_base
<iterator, node_type> insert_return_type;
@@ -509,7 +509,11 @@ class tree
: AllocHolder()
{}
- BOOST_CONTAINER_FORCEINLINE explicit tree(const key_compare& comp, const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE explicit tree(const key_compare& comp)
+ : AllocHolder(ValComp(comp))
+ {}
+
+ BOOST_CONTAINER_FORCEINLINE explicit tree(const key_compare& comp, const allocator_type& a)
: AllocHolder(ValComp(comp), a)
{}
@@ -518,85 +522,110 @@ class tree
{}
template <class InputIterator>
- tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
- const allocator_type& a
- #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_or
- < void
- , container_detail::is_same<alloc_version, version_1>
- , container_detail::is_input_iterator<InputIterator>
- >::type * = 0
- #endif
- )
+ tree(bool unique_insertion, InputIterator first, InputIterator last)
+ : AllocHolder(value_compare(key_compare()))
+ {
+ this->tree_construct(unique_insertion, first, last);
+ //AllocHolder clears in case of exception
+ }
+
+ template <class InputIterator>
+ tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp)
+ : AllocHolder(value_compare(comp))
+ {
+ this->tree_construct(unique_insertion, first, last);
+ //AllocHolder clears in case of exception
+ }
+
+ template <class InputIterator>
+ tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp, const allocator_type& a)
: AllocHolder(value_compare(comp), a)
{
+ this->tree_construct(unique_insertion, first, last);
+ //AllocHolder clears in case of exception
+ }
+
+ //construct with ordered range
+ template <class InputIterator>
+ tree( ordered_range_t, InputIterator first, InputIterator last)
+ : AllocHolder(value_compare(key_compare()))
+ {
+ this->tree_construct(ordered_range_t(), first, last);
+ }
+
+ template <class InputIterator>
+ tree( ordered_range_t, InputIterator first, InputIterator last, const key_compare& comp)
+ : AllocHolder(value_compare(comp))
+ {
+ this->tree_construct(ordered_range_t(), first, last);
+ }
+
+ template <class InputIterator>
+ tree( ordered_range_t, InputIterator first, InputIterator last
+ , const key_compare& comp, const allocator_type& a)
+ : AllocHolder(value_compare(comp), a)
+ {
+ this->tree_construct(ordered_range_t(), first, last);
+ }
+
+ private:
+
+ template <class InputIterator>
+ void tree_construct(bool unique_insertion, InputIterator first, InputIterator last)
+ {
//Use cend() as hint to achieve linear time for
//ordered ranges as required by the standard
//for the constructor
- const const_iterator end_it(this->cend());
if(unique_insertion){
+ const const_iterator end_it(this->cend());
for ( ; first != last; ++first){
this->insert_unique_convertible(end_it, *first);
}
}
else{
- for ( ; first != last; ++first){
- this->insert_equal_convertible(end_it, *first);
- }
+ this->tree_construct_non_unique(first, last);
}
}
template <class InputIterator>
- tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
- const allocator_type& a
+ void tree_construct_non_unique(InputIterator first, InputIterator last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::disable_if_or
+ , typename container_detail::enable_if_or
< void
, container_detail::is_same<alloc_version, version_1>
, container_detail::is_input_iterator<InputIterator>
>::type * = 0
#endif
)
- : AllocHolder(value_compare(comp), a)
{
- if(unique_insertion){
- //Use cend() as hint to achieve linear time for
- //ordered ranges as required by the standard
- //for the constructor
- const const_iterator end_it(this->cend());
- for ( ; first != last; ++first){
- this->insert_unique_convertible(end_it, *first);
- }
- }
- else{
- //Optimized allocation and construction
- this->allocate_many_and_construct
- ( first, boost::container::iterator_distance(first, last)
- , insert_equal_end_hint_functor<Node, Icont>(this->icont()));
+ //Use cend() as hint to achieve linear time for
+ //ordered ranges as required by the standard
+ //for the constructor
+ const const_iterator end_it(this->cend());
+ for ( ; first != last; ++first){
+ this->insert_equal_convertible(end_it, *first);
}
}
template <class InputIterator>
- tree( ordered_range_t, InputIterator first, InputIterator last
- , const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
- #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_or
+ void tree_construct_non_unique(InputIterator first, InputIterator last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::disable_if_or
< void
, container_detail::is_same<alloc_version, version_1>
, container_detail::is_input_iterator<InputIterator>
>::type * = 0
- #endif
+ #endif
)
- : AllocHolder(value_compare(comp), a)
{
- for ( ; first != last; ++first){
- this->push_back_impl(*first);
- }
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ ( first, boost::container::iterator_distance(first, last)
+ , insert_equal_end_hint_functor<Node, Icont>(this->icont()));
}
template <class InputIterator>
- tree( ordered_range_t, InputIterator first, InputIterator last
- , const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
+ void tree_construct( ordered_range_t, InputIterator first, InputIterator last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename container_detail::disable_if_or
< void
@@ -605,16 +634,34 @@ class tree
>::type * = 0
#endif
)
- : AllocHolder(value_compare(comp), a)
{
//Optimized allocation and construction
this->allocate_many_and_construct
( first, boost::container::iterator_distance(first, last)
, container_detail::push_back_functor<Node, Icont>(this->icont()));
+ //AllocHolder clears in case of exception
+ }
+
+ template <class InputIterator>
+ void tree_construct( ordered_range_t, InputIterator first, InputIterator last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_or
+ < void
+ , container_detail::is_same<alloc_version, version_1>
+ , container_detail::is_input_iterator<InputIterator>
+ >::type * = 0
+ #endif
+ )
+ {
+ for ( ; first != last; ++first){
+ this->push_back_impl(*first);
+ }
}
+ public:
+
BOOST_CONTAINER_FORCEINLINE tree(const tree& x)
- : AllocHolder(x.value_comp(), x)
+ : AllocHolder(x, x.value_comp())
{
this->icont().clone_from
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
@@ -630,6 +677,7 @@ class tree
{
this->icont().clone_from
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
+ //AllocHolder clears in case of exception
}
tree(BOOST_RV_REF(tree) x, const allocator_type &a)
@@ -642,6 +690,7 @@ class tree
this->icont().clone_from
(boost::move(x.icont()), typename AllocHolder::move_cloner(*this), Destroyer(this->node_alloc()));
}
+ //AllocHolder clears in case of exception
}
BOOST_CONTAINER_FORCEINLINE ~tree()
@@ -1142,7 +1191,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/boost/container/flat_map.hpp b/boost/container/flat_map.hpp
index b842101feb..56f12ecbe8 100644
--- a/boost/container/flat_map.hpp
+++ b/boost/container/flat_map.hpp
@@ -59,14 +59,15 @@ class flat_multimap;
namespace container_detail{
template<class D, class S>
-BOOST_CONTAINER_FORCEINLINE static D &force(const S &s)
-{ return *const_cast<D*>((reinterpret_cast<const D*>(&s))); }
+BOOST_CONTAINER_FORCEINLINE static D &force(S &s)
+{ return *reinterpret_cast<D*>(&s); }
template<class D, class S>
-BOOST_CONTAINER_FORCEINLINE static D force_copy(S s)
+BOOST_CONTAINER_FORCEINLINE static D force_copy(const S &s)
{
- D *vp = reinterpret_cast<D *>(&s);
- return D(*vp);
+ const D *const vp = reinterpret_cast<const D *>(&s);
+ D ret_val(*vp);
+ return ret_val;
}
} //namespace container_detail{
@@ -144,13 +145,15 @@ class flat_map
<typename allocator_traits<Allocator>::pointer>::reverse_iterator reverse_iterator_impl;
typedef typename container_detail::get_flat_tree_iterators
<typename allocator_traits<Allocator>::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()
+ BOOST_CONTAINER_FORCEINLINE impl_tree_t &tree()
{ return m_flat_tree; }
- const impl_tree_t &tree() const
+ BOOST_CONTAINER_FORCEINLINE const impl_tree_t &tree() const
{ return m_flat_tree; }
private:
@@ -182,8 +185,11 @@ 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;
+
+ //Allocator::value_type must be std::pair<Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- public:
//////////////////////////////////////////////
//
// construct/copy/destroy
@@ -193,106 +199,183 @@ class flat_map
//! <b>Effects</b>: Default constructs an empty flat_map.
//!
//! <b>Complexity</b>: Constant.
- flat_map() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
- container_detail::is_nothrow_default_constructible<Compare>::value)
+ flat_map() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
+ container_detail::is_nothrow_default_constructible<Compare>::value)
: m_flat_tree()
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE explicit flat_map(const allocator_type& a)
+ : m_flat_tree(container_detail::force<const impl_allocator_type>(a))
+ {}
//! <b>Effects</b>: Constructs an empty flat_map using the specified
- //! comparison object and allocator.
+ //! comparison object.
//!
//! <b>Complexity</b>: Constant.
- explicit flat_map(const Compare& comp, const allocator_type& a = allocator_type())
- : m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ BOOST_CONTAINER_FORCEINLINE explicit flat_map(const Compare& comp)
+ : m_flat_tree(comp)
+ {}
- //! <b>Effects</b>: Constructs an empty flat_map using the specified allocator.
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified
+ //! comparison object and allocator.
//!
//! <b>Complexity</b>: Constant.
- explicit flat_map(const allocator_type& a)
- : m_flat_tree(container_detail::force<impl_allocator_type>(a))
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ BOOST_CONTAINER_FORCEINLINE flat_map(const Compare& comp, const allocator_type& a)
+ : m_flat_tree(comp, container_detail::force<const impl_allocator_type>(a))
+ {}
- //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
- //! allocator, and inserts elements from the range [first ,last ).
+ //! <b>Effects</b>: Constructs an empty flat_map and
+ //! and inserts elements from the range [first ,last ).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
+ //! the predicate and otherwise N logN, where N is last - first.
template <class InputIterator>
- flat_map(InputIterator first, InputIterator last, const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
- : m_flat_tree(true, first, last, comp, container_detail::force<impl_allocator_type>(a))
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last)
+ : m_flat_tree(true, first, last)
+ {}
//! <b>Effects</b>: Constructs an empty flat_map using the specified
//! allocator, and inserts elements from the range [first ,last ).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
+ //! the predicate and otherwise N logN, where N is last - first.
template <class InputIterator>
- flat_map(InputIterator first, InputIterator last, const allocator_type& a)
- : m_flat_tree(true, first, last, Compare(), container_detail::force<impl_allocator_type>(a))
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last, const allocator_type& a)
+ : m_flat_tree(true, first, last, container_detail::force<const impl_allocator_type>(a))
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+ //! and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! the predicate and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last, const Compare& comp)
+ : m_flat_tree(true, first, last, comp)
+ {}
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
- //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! the predicate and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE flat_map(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+ : m_flat_tree(true, first, last, comp, container_detail::force<const impl_allocator_type>(a))
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_map
+ //! and inserts elements from the ordered range [first ,last). This function
//! is more efficient than the normal range creation for ordered ranges.
//!
- //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
- //! unique values.
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
//!
//! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
- flat_map( ordered_unique_range_t, InputIterator first, InputIterator last
- , const Compare& comp = Compare(), const allocator_type& a = allocator_type())
- : m_flat_tree(ordered_unique_range, first, last, comp, a)
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ BOOST_CONTAINER_FORCEINLINE
+ flat_map(ordered_unique_range_t, InputIterator first, InputIterator last)
+ : m_flat_tree(ordered_range, first, last)
+ {}
-#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
- //! allocator, and inserts elements from the range [il.begin() ,il.end()).
+ //! inserts elements from the ordered range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_map(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp)
+ : m_flat_tree(ordered_range, first, last, comp)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+ //! allocator, and inserts elements from the ordered range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_map(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+ : m_flat_tree(ordered_range, first, last, comp, a)
+ {}
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ //! <b>Effects</b>: Constructs an empty flat_map and
+ //! inserts elements from the range [il.begin() ,il.end()).
//!
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
- flat_map(std::initializer_list<value_type> il, const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
- : m_flat_tree(true, il.begin(), il.end(), comp, container_detail::force<impl_allocator_type>(a))
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ //! the predicate and otherwise N logN, where N is last - first.
+ BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il)
+ : m_flat_tree(true, il.begin(), il.end())
+ {}
//! <b>Effects</b>: Constructs an empty flat_map using the specified
//! allocator, and inserts elements from the range [il.begin() ,il.end()).
//!
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
- flat_map(std::initializer_list<value_type> il, const allocator_type& a)
- : m_flat_tree(true, il.begin(), il.end(), Compare(), container_detail::force<impl_allocator_type>(a))
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ //! the predicate and otherwise N logN, where N is last - first.
+ BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il, const allocator_type& a)
+ : m_flat_tree(true, il.begin(), il.end(), container_detail::force<const impl_allocator_type>(a))
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+ //! inserts elements from the range [il.begin() ,il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+ //! the predicate and otherwise N logN, where N is last - first.
+ BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il, const Compare& comp)
+ : m_flat_tree(true, il.begin(), il.end(), comp)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+ //! allocator, and inserts elements from the range [il.begin() ,il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+ //! the predicate and otherwise N logN, where N is last - first.
+ BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+ : m_flat_tree(true, il.begin(), il.end(), comp, container_detail::force<const impl_allocator_type>(a))
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_map using and
+ //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list<value_type> il)
+ : m_flat_tree(ordered_unique_range, il.begin(), il.end())
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+ //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp)
+ : m_flat_tree(ordered_unique_range, il.begin(), il.end(), comp)
+ {}
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
//! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
@@ -304,24 +387,17 @@ class flat_map
//! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
- flat_map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
: m_flat_tree(ordered_unique_range, il.begin(), il.end(), comp, a)
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ {}
#endif
//! <b>Effects</b>: Copy constructs a flat_map.
//!
//! <b>Complexity</b>: Linear in x.size().
- flat_map(const flat_map& x)
+ BOOST_CONTAINER_FORCEINLINE flat_map(const flat_map& x)
: m_flat_tree(x.m_flat_tree)
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Move constructs a flat_map.
//! Constructs *this using x's resources.
@@ -329,39 +405,30 @@ class flat_map
//! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
- flat_map(BOOST_RV_REF(flat_map) x)
+ BOOST_CONTAINER_FORCEINLINE flat_map(BOOST_RV_REF(flat_map) x)
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
: m_flat_tree(boost::move(x.m_flat_tree))
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Copy constructs a flat_map using the specified allocator.
//!
//! <b>Complexity</b>: Linear in x.size().
- flat_map(const flat_map& x, const allocator_type &a)
+ BOOST_CONTAINER_FORCEINLINE flat_map(const flat_map& x, const allocator_type &a)
: m_flat_tree(x.m_flat_tree, a)
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Move constructs a flat_map using the specified allocator.
//! Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Constant if x.get_allocator() == a, linear otherwise.
- flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a)
+ BOOST_CONTAINER_FORCEINLINE flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a)
: m_flat_tree(boost::move(x.m_flat_tree), a)
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().
- flat_map& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
+ BOOST_CONTAINER_FORCEINLINE flat_map& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
{ m_flat_tree = x.m_flat_tree; return *this; }
//! <b>Effects</b>: Move constructs a flat_map.
@@ -373,7 +440,7 @@ class flat_map
//! <b>Complexity</b>: Constant if allocator_traits_type::
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
- flat_map& operator=(BOOST_RV_REF(flat_map) x)
+ BOOST_CONTAINER_FORCEINLINE flat_map& operator=(BOOST_RV_REF(flat_map) x)
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
allocator_traits_type::is_always_equal::value) &&
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
@@ -393,7 +460,7 @@ class flat_map
//! was passed to the object's constructor.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -403,7 +470,7 @@ class flat_map
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -413,8 +480,8 @@ class flat_map
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
- { return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
+ BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
+ { return container_detail::force<const stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
//////////////////////////////////////////////
//
@@ -427,7 +494,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<iterator>(m_flat_tree.begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -435,7 +502,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.begin()); }
//! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -443,7 +510,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end() BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE iterator end() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<iterator>(m_flat_tree.end()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -451,7 +518,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -460,7 +527,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -469,7 +536,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -478,7 +545,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -487,7 +554,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -495,7 +562,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -503,7 +570,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -512,7 +579,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -521,7 +588,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
//////////////////////////////////////////////
@@ -535,7 +602,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.empty(); }
//! <b>Effects</b>: Returns the number of the elements contained in the container.
@@ -543,7 +610,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.size(); }
//! <b>Effects</b>: Returns the largest possible size of the container.
@@ -551,7 +618,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.max_size(); }
//! <b>Effects</b>: Number of elements for which memory has been allocated.
@@ -560,7 +627,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.capacity(); }
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -572,7 +639,7 @@ class flat_map
//!
//! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
//! to values might be invalidated.
- void reserve(size_type cnt)
+ BOOST_CONTAINER_FORCEINLINE void reserve(size_type cnt)
{ m_flat_tree.reserve(cnt); }
//! <b>Effects</b>: Tries to deallocate the excess of memory created
@@ -581,7 +648,7 @@ class flat_map
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to size().
- void shrink_to_fit()
+ BOOST_CONTAINER_FORCEINLINE void shrink_to_fit()
{ m_flat_tree.shrink_to_fit(); }
//////////////////////////////////////////////
@@ -608,8 +675,8 @@ class flat_map
mapped_type &operator[](key_type &&k) ;
#elif defined(BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN)
//in compilers like GCC 3.4, we can't catch temporaries
- mapped_type& operator[](const key_type &k) { return this->priv_subscript(k); }
- mapped_type& operator[](BOOST_RV_REF(key_type) k) { return this->priv_subscript(::boost::move(k)); }
+ BOOST_CONTAINER_FORCEINLINE mapped_type& operator[](const key_type &k) { return this->priv_subscript(k); }
+ BOOST_CONTAINER_FORCEINLINE mapped_type& operator[](BOOST_RV_REF(key_type) k) { return this->priv_subscript(::boost::move(k)); }
#else
BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript)
#endif
@@ -705,19 +772,19 @@ class flat_map
}
//! @copydoc ::boost::container::flat_set::nth(size_type)
- iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
//! @copydoc ::boost::container::flat_set::nth(size_type) const
- const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
//! @copydoc ::boost::container::flat_set::index_of(iterator)
- size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.index_of(container_detail::force_copy<impl_iterator>(p)); }
//! @copydoc ::boost::container::flat_set::index_of(const_iterator) const
- size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.index_of(container_detail::force_copy<impl_const_iterator>(p)); }
//! Returns: A reference to the element whose key is equivalent to x.
@@ -769,7 +836,7 @@ class flat_map
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
- std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
+ BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
{ return container_detail::force_copy< std::pair<iterator, bool> >(m_flat_tree.emplace_unique(boost::forward<Args>(args)...)); }
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -785,7 +852,7 @@ class flat_map
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
- iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
+ BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
return container_detail::force_copy<iterator>
(m_flat_tree.emplace_hint_unique( container_detail::force_copy<impl_const_iterator>(hint)
@@ -869,14 +936,14 @@ class flat_map
#define BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
- std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
+ BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
{\
return container_detail::force_copy< std::pair<iterator, bool> >\
(m_flat_tree.emplace_unique(BOOST_MOVE_FWD##N));\
}\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
- iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_unique\
(container_detail::force_copy<impl_const_iterator>(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
@@ -921,9 +988,9 @@ class flat_map
//! to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- std::pair<iterator,bool> insert(const value_type& x)
+ BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(const value_type& x)
{ return container_detail::force_copy<std::pair<iterator,bool> >(
- m_flat_tree.insert_unique(container_detail::force<impl_value_type>(x))); }
+ m_flat_tree.insert_unique(container_detail::force<const impl_value_type>(x))); }
//! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
//! only if there is no element in the container with key equivalent to the key of x.
@@ -936,7 +1003,7 @@ class flat_map
//! to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
+ BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
{ return container_detail::force_copy<std::pair<iterator,bool> >(
m_flat_tree.insert_unique(boost::move(container_detail::force<impl_value_type>(x)))); }
@@ -951,7 +1018,7 @@ class flat_map
//! to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x)
+ BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x)
{
return container_detail::force_copy<std::pair<iterator,bool> >
(m_flat_tree.insert_unique(boost::move(x)));
@@ -968,11 +1035,11 @@ class flat_map
//! right before p) plus insertion linear to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- iterator insert(const_iterator p, const value_type& x)
+ BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x)
{
return container_detail::force_copy<iterator>(
m_flat_tree.insert_unique( container_detail::force_copy<impl_const_iterator>(p)
- , container_detail::force<impl_value_type>(x)));
+ , container_detail::force<const impl_value_type>(x)));
}
//! <b>Effects</b>: Inserts an element move constructed from x in the container.
@@ -984,7 +1051,7 @@ class flat_map
//! right before p) plus insertion linear to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
+ BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
{
return container_detail::force_copy<iterator>
(m_flat_tree.insert_unique( container_detail::force_copy<impl_const_iterator>(p)
@@ -1000,7 +1067,7 @@ class flat_map
//! right before p) plus insertion linear to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x)
+ BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x)
{
return container_detail::force_copy<iterator>(
m_flat_tree.insert_unique(container_detail::force_copy<impl_const_iterator>(p), boost::move(x)));
@@ -1016,7 +1083,7 @@ class flat_map
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
+ BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
{ m_flat_tree.insert_unique(first, last); }
//! <b>Requires</b>: first, last are not iterators into *this.
@@ -1035,7 +1102,7 @@ class flat_map
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
- void insert(ordered_unique_range_t, InputIterator first, InputIterator last)
+ BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, InputIterator first, InputIterator last)
{ m_flat_tree.insert_unique(ordered_unique_range, first, last); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -1046,7 +1113,7 @@ class flat_map
//! search time plus N*size() insertion time.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- void insert(std::initializer_list<value_type> il)
+ BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
{ m_flat_tree.insert_unique(il.begin(), il.end()); }
//! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
@@ -1062,7 +1129,7 @@ class flat_map
//! <b>Note</b>: If an element is inserted it might invalidate elements.
//!
//! <b>Note</b>: Non-standard extension.
- void insert(ordered_unique_range_t, std::initializer_list<value_type> il)
+ BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, std::initializer_list<value_type> il)
{ m_flat_tree.insert_unique(ordered_unique_range, il.begin(), il.end()); }
#endif
@@ -1109,7 +1176,7 @@ class flat_map
//!
//! <b>Note</b>: Invalidates elements with keys
//! not less than the erased element.
- iterator erase(const_iterator p)
+ BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator p)
{
return container_detail::force_copy<iterator>
(m_flat_tree.erase(container_detail::force_copy<impl_const_iterator>(p)));
@@ -1121,7 +1188,7 @@ class flat_map
//!
//! <b>Complexity</b>: Logarithmic search time plus erasure time
//! linear to the elements with bigger keys.
- size_type erase(const key_type& x)
+ BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x)
{ return m_flat_tree.erase(x); }
//! <b>Effects</b>: Erases all the elements in the range [first, last).
@@ -1132,7 +1199,7 @@ class flat_map
//!
//! <b>Complexity</b>: Logarithmic search time plus erasure time
//! linear to the elements with bigger keys.
- iterator erase(const_iterator first, const_iterator last)
+ BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last)
{
return container_detail::force_copy<iterator>(
m_flat_tree.erase( container_detail::force_copy<impl_const_iterator>(first)
@@ -1144,7 +1211,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- void swap(flat_map& x)
+ BOOST_CONTAINER_FORCEINLINE void swap(flat_map& x)
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
&& boost::container::container_detail::is_nothrow_swappable<Compare>::value )
{ m_flat_tree.swap(x.m_flat_tree); }
@@ -1154,7 +1221,7 @@ class flat_map
//! <b>Postcondition</b>: size() == 0.
//!
//! <b>Complexity</b>: linear in size().
- void clear() BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW
{ m_flat_tree.clear(); }
//////////////////////////////////////////////
@@ -1167,14 +1234,14 @@ class flat_map
//! of which a was constructed.
//!
//! <b>Complexity</b>: Constant.
- key_compare key_comp() const
+ BOOST_CONTAINER_FORCEINLINE key_compare key_comp() const
{ return container_detail::force_copy<key_compare>(m_flat_tree.key_comp()); }
//! <b>Effects</b>: Returns an object of value_compare constructed out
//! of the comparison object.
//!
//! <b>Complexity</b>: Constant.
- value_compare value_comp() const
+ BOOST_CONTAINER_FORCEINLINE value_compare value_comp() const
{ return value_compare(container_detail::force_copy<key_compare>(m_flat_tree.key_comp())); }
//////////////////////////////////////////////
@@ -1187,102 +1254,135 @@ class flat_map
//! equivalent to x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
- iterator find(const key_type& x)
+ BOOST_CONTAINER_FORCEINLINE iterator find(const key_type& x)
{ return container_detail::force_copy<iterator>(m_flat_tree.find(x)); }
//! <b>Returns</b>: A const_iterator pointing to an element with the key
//! equivalent to x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
- const_iterator find(const key_type& x) const
+ BOOST_CONTAINER_FORCEINLINE const_iterator find(const key_type& x) const
{ return container_detail::force_copy<const_iterator>(m_flat_tree.find(x)); }
//! <b>Returns</b>: The number of elements with key equivalent to x.
//!
//! <b>Complexity</b>: log(size())+count(k)
- size_type count(const key_type& x) const
+ BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) const
{ return static_cast<size_type>(m_flat_tree.find(x) != m_flat_tree.end()); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
- iterator lower_bound(const key_type& x)
+ BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& x)
{ return container_detail::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
//! <b>Returns</b>: A const iterator pointing to the first element with key not
//! less than k, or a.end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
- const_iterator lower_bound(const key_type& x) const
+ BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& x) const
{ return container_detail::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
- iterator upper_bound(const key_type& x)
+ BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const key_type& x)
{ return container_detail::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
//! <b>Returns</b>: A const iterator pointing to the first element with key not
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
- const_iterator upper_bound(const key_type& x) const
+ BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& x) const
{ return container_detail::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic.
- std::pair<iterator,iterator> equal_range(const key_type& x)
+ BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& x)
{ return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.lower_bound_range(x)); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic.
- std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
+ BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.lower_bound_range(x)); }
+ //! <b>Effects</b>: Extracts the internal sequence container.
+ //!
+ //! <b>Complexity</b>: Same as the move constructor of sequence_type, usually constant.
+ //!
+ //! <b>Postcondition</b>: this->empty()
+ //!
+ //! <b>Throws</b>: If secuence_type's move constructor throws
+ BOOST_CONTAINER_FORCEINLINE sequence_type extract_sequence()
+ {
+ return boost::move(container_detail::force<sequence_type>(m_flat_tree.get_sequence_ref()));
+ }
+
+ //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+ //! one passed externally using the move assignment. Erases non-unique elements.
+ //!
+ //! <b>Complexity</b>: Assuming O(1) move assignment, O(NlogN) with N = seq.size()
+ //!
+ //! <b>Throws</b>: If the comparison or the move constructor throws
+ BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
+ { this->m_flat_tree.adopt_sequence_unique(boost::move(container_detail::force<impl_sequence_type>(seq))); }
+
+ //! <b>Requires</b>: seq shall be ordered according to this->compare()
+ //! and shall contain unique elements.
+ //!
+ //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+ //! one passed externally using the move assignment.
+ //!
+ //! <b>Complexity</b>: Assuming O(1) move assignment, O(1)
+ //!
+ //! <b>Throws</b>: If the move assignment throws
+ BOOST_CONTAINER_FORCEINLINE 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<impl_sequence_type>(seq))); }
+
//! <b>Effects</b>: Returns true if x and y are equal
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
- friend bool operator==(const flat_map& x, const flat_map& y)
+ BOOST_CONTAINER_FORCEINLINE friend bool operator==(const flat_map& x, const flat_map& y)
{ return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
//! <b>Effects</b>: Returns true if x and y are unequal
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
- friend bool operator!=(const flat_map& x, const flat_map& y)
+ BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const flat_map& x, const flat_map& y)
{ return !(x == y); }
//! <b>Effects</b>: Returns true if x is less than y
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
- friend bool operator<(const flat_map& x, const flat_map& y)
+ BOOST_CONTAINER_FORCEINLINE friend bool operator<(const flat_map& x, const flat_map& y)
{ return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
//! <b>Effects</b>: Returns true if x is greater than y
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
- friend bool operator>(const flat_map& x, const flat_map& y)
+ BOOST_CONTAINER_FORCEINLINE friend bool operator>(const flat_map& x, const flat_map& y)
{ return y < x; }
//! <b>Effects</b>: Returns true if x is equal or less than y
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
- friend bool operator<=(const flat_map& x, const flat_map& y)
+ BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const flat_map& x, const flat_map& y)
{ return !(y < x); }
//! <b>Effects</b>: Returns true if x is equal or greater than y
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
- friend bool operator>=(const flat_map& x, const flat_map& y)
+ BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const flat_map& x, const flat_map& y)
{ return !(x < y); }
//! <b>Effects</b>: x.swap(y)
//!
//! <b>Complexity</b>: Constant.
- friend void swap(flat_map& x, flat_map& y)
+ BOOST_CONTAINER_FORCEINLINE friend void swap(flat_map& x, flat_map& y)
{ x.swap(y); }
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -1401,11 +1501,12 @@ class flat_multimap
<typename allocator_traits<Allocator>::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()
+ BOOST_CONTAINER_FORCEINLINE impl_tree_t &tree()
{ return m_flat_tree; }
- const impl_tree_t &tree() const
+ BOOST_CONTAINER_FORCEINLINE const impl_tree_t &tree() const
{ return m_flat_tree; }
private:
@@ -1437,6 +1538,10 @@ 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;
+
+ //Allocator::value_type must be std::pair<Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
//////////////////////////////////////////////
//
@@ -1447,63 +1552,109 @@ class flat_multimap
//! <b>Effects</b>: Default constructs an empty flat_map.
//!
//! <b>Complexity</b>: Constant.
- flat_multimap() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
- container_detail::is_nothrow_default_constructible<Compare>::value)
+ BOOST_CONTAINER_FORCEINLINE flat_multimap()
+ BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
+ container_detail::is_nothrow_default_constructible<Compare>::value)
: m_flat_tree()
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_multimap using the specified allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE explicit flat_multimap(const allocator_type& a)
+ : m_flat_tree(container_detail::force<const impl_allocator_type>(a))
+ {}
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison
- //! object and allocator.
+ //! object .
//!
//! <b>Complexity</b>: Constant.
- explicit flat_multimap(const Compare& comp,
- const allocator_type& a = allocator_type())
- : m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ BOOST_CONTAINER_FORCEINLINE explicit flat_multimap(const Compare& comp)
+ : m_flat_tree(comp)
+ {}
- //! <b>Effects</b>: Constructs an empty flat_multimap using the specified allocator.
+ //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison
+ //! object and allocator.
//!
//! <b>Complexity</b>: Constant.
- explicit flat_multimap(const allocator_type& a)
- : m_flat_tree(container_detail::force<impl_allocator_type>(a))
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ BOOST_CONTAINER_FORCEINLINE
+ flat_multimap(const Compare& comp, const allocator_type& a)
+ : m_flat_tree(comp, container_detail::force<const impl_allocator_type>(a))
+ {}
- //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
- //! and allocator, and inserts elements from the range [first ,last ).
+ //! <b>Effects</b>: Constructs an empty flat_multimap
+ //! and inserts elements from the range [first ,last ).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
+ //! the predicate and otherwise N logN, where N is last - first.
template <class InputIterator>
- flat_multimap(InputIterator first, InputIterator last,
- const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
- : m_flat_tree(false, first, last, comp, container_detail::force<impl_allocator_type>(a))
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ BOOST_CONTAINER_FORCEINLINE
+ flat_multimap(InputIterator first, InputIterator last)
+ : m_flat_tree(false, first, last)
+ {}
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified
//! allocator, and inserts elements from the range [first ,last ).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
+ //! the predicate and otherwise N logN, where N is last - first.
template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
flat_multimap(InputIterator first, InputIterator last, const allocator_type& a)
- : m_flat_tree(false, first, last, Compare(), container_detail::force<impl_allocator_type>(a))
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ : m_flat_tree(false, first, last, container_detail::force<const impl_allocator_type>(a))
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
+ //! and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! the predicate and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_multimap(InputIterator first, InputIterator last, const Compare& comp)
+ : m_flat_tree(false, first, last, comp)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
+ //! and allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! the predicate and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_multimap(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+ : m_flat_tree(false, first, last, comp, container_detail::force<const impl_allocator_type>(a))
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_multimap
+ //! and inserts elements from the ordered range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_multimap(ordered_range_t, InputIterator first, InputIterator last)
+ : m_flat_tree(ordered_range, first, last)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
+ //! inserts elements from the ordered range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp)
+ : m_flat_tree(ordered_range, first, last, comp)
+ {}
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
//! allocator, and inserts elements from the ordered range [first ,last). This function
@@ -1515,39 +1666,79 @@ class flat_multimap
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
- flat_multimap(ordered_range_t, InputIterator first, InputIterator last,
- const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE
+ flat_multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
: m_flat_tree(ordered_range, first, last, comp, a)
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ {}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
- //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
- //! allocator, and inserts elements from the range [il.begin(), il.end()).
+ //! <b>Effects</b>: Constructs an empty flat_map and
+ //! inserts elements from the range [il.begin(), il.end()).
//!
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
- flat_multimap(std::initializer_list<value_type> il, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
- : m_flat_tree(false, il.begin(), il.end(), comp, container_detail::force<impl_allocator_type>(a))
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ //! the predicate and otherwise N logN, where N is last - first.
+ BOOST_CONTAINER_FORCEINLINE
+ flat_multimap(std::initializer_list<value_type> il)
+ : m_flat_tree(false, il.begin(), il.end())
+ {}
//! <b>Effects</b>: Constructs an empty flat_map using the specified
//! allocator, and inserts elements from the range [il.begin(), il.end()).
//!
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
+ //! the predicate and otherwise N logN, where N is last - first.
+ BOOST_CONTAINER_FORCEINLINE
flat_multimap(std::initializer_list<value_type> il, const allocator_type& a)
- : m_flat_tree(false, il.begin(), il.end(), Compare(), container_detail::force<impl_allocator_type>(a))
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ : m_flat_tree(false, il.begin(), il.end(), container_detail::force<const impl_allocator_type>(a))
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+ //! inserts elements from the range [il.begin(), il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+ //! the predicate and otherwise N logN, where N is last - first.
+ BOOST_CONTAINER_FORCEINLINE
+ flat_multimap(std::initializer_list<value_type> il, const Compare& comp)
+ : m_flat_tree(false, il.begin(), il.end(), comp)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+ //! allocator, and inserts elements from the range [il.begin(), il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+ //! the predicate and otherwise N logN, where N is last - first.
+ BOOST_CONTAINER_FORCEINLINE
+ flat_multimap(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+ : m_flat_tree(false, il.begin(), il.end(), comp, container_detail::force<const impl_allocator_type>(a))
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_multimap and
+ //! inserts elements from the ordered range [il.begin(), il.end()). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE
+ flat_multimap(ordered_range_t, std::initializer_list<value_type> il)
+ : m_flat_tree(ordered_range, il.begin(), il.end())
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
+ //! inserts elements from the ordered range [il.begin(), il.end()). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE
+ flat_multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp)
+ : m_flat_tree(ordered_range, il.begin(), il.end(), comp)
+ {}
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
//! allocator, and inserts elements from the ordered range [il.begin(), il.end()). This function
@@ -1558,68 +1749,59 @@ class flat_multimap
//! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
- flat_multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE
+ flat_multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
: m_flat_tree(ordered_range, il.begin(), il.end(), comp, a)
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ {}
#endif
//! <b>Effects</b>: Copy constructs a flat_multimap.
//!
//! <b>Complexity</b>: Linear in x.size().
+ BOOST_CONTAINER_FORCEINLINE
flat_multimap(const flat_multimap& x)
: m_flat_tree(x.m_flat_tree)
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
+ BOOST_CONTAINER_FORCEINLINE
flat_multimap(BOOST_RV_REF(flat_multimap) x)
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
: m_flat_tree(boost::move(x.m_flat_tree))
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Copy constructs a flat_multimap using the specified allocator.
//!
//! <b>Complexity</b>: Linear in x.size().
+ BOOST_CONTAINER_FORCEINLINE
flat_multimap(const flat_multimap& x, const allocator_type &a)
: m_flat_tree(x.m_flat_tree, a)
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Move constructs a flat_multimap using the specified allocator.
//! Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+ BOOST_CONTAINER_FORCEINLINE
flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a)
: m_flat_tree(boost::move(x.m_flat_tree), a)
- {
- //value_type must be std::pair<Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().
+ BOOST_CONTAINER_FORCEINLINE
flat_multimap& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x)
{ m_flat_tree = x.m_flat_tree; return *this; }
//! <b>Effects</b>: this->swap(x.get()).
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
flat_multimap& operator=(BOOST_RV_REF(flat_multimap) x)
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
allocator_traits_type::is_always_equal::value) &&
@@ -1630,6 +1812,7 @@ class flat_multimap
//! <b>Effects</b>: Assign content of il to *this
//!
//! <b>Complexity</b>: Linear in il.size().
+ BOOST_CONTAINER_FORCEINLINE
flat_multimap& operator=(std::initializer_list<value_type> il)
{
this->clear();
@@ -1642,6 +1825,7 @@ class flat_multimap
//! was passed to the object's constructor.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
@@ -1652,6 +1836,7 @@ class flat_multimap
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE
stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
@@ -1662,8 +1847,9 @@ class flat_multimap
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE
const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
- { return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
+ { return container_detail::force<const stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
//////////////////////////////////////////////
//
@@ -1676,6 +1862,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<iterator>(m_flat_tree.begin()); }
@@ -1684,6 +1871,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.begin()); }
@@ -1692,6 +1880,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
iterator end() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<iterator>(m_flat_tree.end()); }
@@ -1700,6 +1889,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
@@ -1709,6 +1899,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
@@ -1718,6 +1909,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
@@ -1727,6 +1919,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
@@ -1736,6 +1929,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
@@ -1744,6 +1938,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
@@ -1752,6 +1947,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
@@ -1761,6 +1957,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
@@ -1770,6 +1967,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
@@ -1784,6 +1982,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.empty(); }
@@ -1792,6 +1991,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.size(); }
@@ -1800,6 +2000,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.max_size(); }
@@ -1809,6 +2010,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.capacity(); }
@@ -1821,6 +2023,7 @@ class flat_multimap
//!
//! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
//! to values might be invalidated.
+ BOOST_CONTAINER_FORCEINLINE
void reserve(size_type cnt)
{ m_flat_tree.reserve(cnt); }
@@ -1830,22 +2033,27 @@ class flat_multimap
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to size().
+ BOOST_CONTAINER_FORCEINLINE
void shrink_to_fit()
{ m_flat_tree.shrink_to_fit(); }
//! @copydoc ::boost::container::flat_set::nth(size_type)
+ BOOST_CONTAINER_FORCEINLINE
iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
//! @copydoc ::boost::container::flat_set::nth(size_type) const
+ BOOST_CONTAINER_FORCEINLINE
const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
//! @copydoc ::boost::container::flat_set::index_of(iterator)
+ BOOST_CONTAINER_FORCEINLINE
size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.index_of(container_detail::force_copy<impl_iterator>(p)); }
//! @copydoc ::boost::container::flat_set::index_of(const_iterator) const
+ BOOST_CONTAINER_FORCEINLINE
size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.index_of(container_detail::force_copy<impl_const_iterator>(p)); }
@@ -1860,6 +2068,7 @@ class flat_multimap
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
+ BOOST_CONTAINER_FORCEINLINE
iterator emplace(BOOST_FWD_REF(Args)... args)
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal(boost::forward<Args>(args)...)); }
@@ -1876,6 +2085,7 @@ class flat_multimap
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
+ BOOST_CONTAINER_FORCEINLINE
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal
@@ -1886,11 +2096,11 @@ class flat_multimap
#define BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
- iterator emplace(BOOST_MOVE_UREF##N)\
+ BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal(BOOST_MOVE_FWD##N)); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
- iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal\
(container_detail::force_copy<impl_const_iterator>(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
@@ -1908,10 +2118,10 @@ class flat_multimap
//! to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- iterator insert(const value_type& x)
+ BOOST_CONTAINER_FORCEINLINE iterator insert(const value_type& x)
{
return container_detail::force_copy<iterator>(
- m_flat_tree.insert_equal(container_detail::force<impl_value_type>(x)));
+ m_flat_tree.insert_equal(container_detail::force<const impl_value_type>(x)));
}
//! <b>Effects</b>: Inserts a new value move-constructed from x and returns
@@ -1921,7 +2131,7 @@ class flat_multimap
//! to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- iterator insert(BOOST_RV_REF(value_type) x)
+ BOOST_CONTAINER_FORCEINLINE iterator insert(BOOST_RV_REF(value_type) x)
{ return container_detail::force_copy<iterator>(m_flat_tree.insert_equal(boost::move(x))); }
//! <b>Effects</b>: Inserts a new value move-constructed from x and returns
@@ -1931,7 +2141,7 @@ class flat_multimap
//! to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- iterator insert(BOOST_RV_REF(impl_value_type) x)
+ BOOST_CONTAINER_FORCEINLINE iterator insert(BOOST_RV_REF(impl_value_type) x)
{ return container_detail::force_copy<iterator>(m_flat_tree.insert_equal(boost::move(x))); }
//! <b>Effects</b>: Inserts a copy of x in the container.
@@ -1945,11 +2155,11 @@ class flat_multimap
//! to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- iterator insert(const_iterator p, const value_type& x)
+ BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x)
{
return container_detail::force_copy<iterator>
(m_flat_tree.insert_equal( container_detail::force_copy<impl_const_iterator>(p)
- , container_detail::force<impl_value_type>(x)));
+ , container_detail::force<const impl_value_type>(x)));
}
//! <b>Effects</b>: Inserts a value move constructed from x in the container.
@@ -1963,7 +2173,7 @@ class flat_multimap
//! to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
+ BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
{
return container_detail::force_copy<iterator>
(m_flat_tree.insert_equal(container_detail::force_copy<impl_const_iterator>(p)
@@ -1981,7 +2191,7 @@ class flat_multimap
//! to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- iterator insert(const_iterator p, BOOST_RV_REF(impl_value_type) x)
+ BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(impl_value_type) x)
{
return container_detail::force_copy<iterator>(
m_flat_tree.insert_equal(container_detail::force_copy<impl_const_iterator>(p), boost::move(x)));
@@ -1996,7 +2206,7 @@ class flat_multimap
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
+ BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
{ m_flat_tree.insert_equal(first, last); }
//! <b>Requires</b>: first, last are not iterators into *this.
@@ -2014,7 +2224,7 @@ class flat_multimap
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
- void insert(ordered_range_t, InputIterator first, InputIterator last)
+ BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, InputIterator first, InputIterator last)
{ m_flat_tree.insert_equal(ordered_range, first, last); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -2024,7 +2234,7 @@ class flat_multimap
//! search time plus N*size() insertion time.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- void insert(std::initializer_list<value_type> il)
+ BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
{ m_flat_tree.insert_equal(il.begin(), il.end()); }
//! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
@@ -2039,7 +2249,7 @@ class flat_multimap
//! <b>Note</b>: If an element is inserted it might invalidate elements.
//!
//! <b>Note</b>: Non-standard extension.
- void insert(ordered_range_t, std::initializer_list<value_type> il)
+ BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, std::initializer_list<value_type> il)
{ m_flat_tree.insert_equal(ordered_range, il.begin(), il.end()); }
#endif
@@ -2057,22 +2267,22 @@ class flat_multimap
//!
//! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
template<class C2>
- void merge(flat_multimap<Key, T, C2, Allocator>& source)
+ BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap<Key, T, C2, Allocator>& source)
{ m_flat_tree.merge_equal(source.tree()); }
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, Allocator>&)
template<class C2>
- void merge(BOOST_RV_REF_BEG flat_multimap<Key, T, C2, Allocator> BOOST_RV_REF_END source)
+ BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multimap<Key, T, C2, Allocator> BOOST_RV_REF_END source)
{ return this->merge(static_cast<flat_multimap<Key, T, C2, Allocator>&>(source)); }
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, Allocator>&)
template<class C2>
- void merge(flat_map<Key, T, C2, Allocator>& source)
+ BOOST_CONTAINER_FORCEINLINE void merge(flat_map<Key, T, C2, Allocator>& source)
{ m_flat_tree.merge_equal(source.tree()); }
- //! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, Allocator>&)
+ //! @copydoc ::boost::container::flat_multimap::merge(flat_map<Key, T, C2, Allocator>&)
template<class C2>
- void merge(BOOST_RV_REF_BEG flat_map<Key, T, C2, Allocator> BOOST_RV_REF_END source)
+ BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_map<Key, T, C2, Allocator> BOOST_RV_REF_END source)
{ return this->merge(static_cast<flat_map<Key, T, C2, Allocator>&>(source)); }
//! <b>Effects</b>: Erases the element pointed to by p.
@@ -2085,7 +2295,7 @@ class flat_multimap
//!
//! <b>Note</b>: Invalidates elements with keys
//! not less than the erased element.
- iterator erase(const_iterator p)
+ BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator p)
{
return container_detail::force_copy<iterator>(
m_flat_tree.erase(container_detail::force_copy<impl_const_iterator>(p)));
@@ -2097,7 +2307,7 @@ class flat_multimap
//!
//! <b>Complexity</b>: Logarithmic search time plus erasure time
//! linear to the elements with bigger keys.
- size_type erase(const key_type& x)
+ BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x)
{ return m_flat_tree.erase(x); }
//! <b>Effects</b>: Erases all the elements in the range [first, last).
@@ -2108,7 +2318,7 @@ class flat_multimap
//!
//! <b>Complexity</b>: Logarithmic search time plus erasure time
//! linear to the elements with bigger keys.
- iterator erase(const_iterator first, const_iterator last)
+ BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last)
{
return container_detail::force_copy<iterator>
(m_flat_tree.erase( container_detail::force_copy<impl_const_iterator>(first)
@@ -2120,7 +2330,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- void swap(flat_multimap& x)
+ BOOST_CONTAINER_FORCEINLINE void swap(flat_multimap& x)
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
&& boost::container::container_detail::is_nothrow_swappable<Compare>::value )
{ m_flat_tree.swap(x.m_flat_tree); }
@@ -2130,7 +2340,7 @@ class flat_multimap
//! <b>Postcondition</b>: size() == 0.
//!
//! <b>Complexity</b>: linear in size().
- void clear() BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW
{ m_flat_tree.clear(); }
//////////////////////////////////////////////
@@ -2143,14 +2353,14 @@ class flat_multimap
//! of which a was constructed.
//!
//! <b>Complexity</b>: Constant.
- key_compare key_comp() const
+ BOOST_CONTAINER_FORCEINLINE key_compare key_comp() const
{ return container_detail::force_copy<key_compare>(m_flat_tree.key_comp()); }
//! <b>Effects</b>: Returns an object of value_compare constructed out
//! of the comparison object.
//!
//! <b>Complexity</b>: Constant.
- value_compare value_comp() const
+ BOOST_CONTAINER_FORCEINLINE value_compare value_comp() const
{ return value_compare(container_detail::force_copy<key_compare>(m_flat_tree.key_comp())); }
//////////////////////////////////////////////
@@ -2163,102 +2373,134 @@ class flat_multimap
//! equivalent to x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
- iterator find(const key_type& x)
+ BOOST_CONTAINER_FORCEINLINE iterator find(const key_type& x)
{ return container_detail::force_copy<iterator>(m_flat_tree.find(x)); }
//! <b>Returns</b>: An const_iterator pointing to an element with the key
//! equivalent to x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
- const_iterator find(const key_type& x) const
+ BOOST_CONTAINER_FORCEINLINE const_iterator find(const key_type& x) const
{ return container_detail::force_copy<const_iterator>(m_flat_tree.find(x)); }
//! <b>Returns</b>: The number of elements with key equivalent to x.
//!
//! <b>Complexity</b>: log(size())+count(k)
- size_type count(const key_type& x) const
+ BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) const
{ return m_flat_tree.count(x); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
- iterator lower_bound(const key_type& x)
+ BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& x)
{ return container_detail::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
//! <b>Returns</b>: A const iterator pointing to the first element with key
//! not less than k, or a.end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
- const_iterator lower_bound(const key_type& x) const
+ BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& x) const
{ return container_detail::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
- iterator upper_bound(const key_type& x)
+ BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const key_type& x)
{return container_detail::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
//! <b>Returns</b>: A const iterator pointing to the first element with key
//! not less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
- const_iterator upper_bound(const key_type& x) const
+ BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& x) const
{ return container_detail::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic
- std::pair<iterator,iterator> equal_range(const key_type& x)
+ BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& x)
{ return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic
- std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
+ BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
+ //! <b>Effects</b>: Extracts the internal sequence container.
+ //!
+ //! <b>Complexity</b>: Same as the move constructor of sequence_type, usually constant.
+ //!
+ //! <b>Postcondition</b>: this->empty()
+ //!
+ //! <b>Throws</b>: If secuence_type's move constructor throws
+ BOOST_CONTAINER_FORCEINLINE sequence_type extract_sequence()
+ {
+ return boost::move(container_detail::force<sequence_type>(m_flat_tree.get_sequence_ref()));
+ }
+
+ //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+ //! one passed externally using the move assignment.
+ //!
+ //! <b>Complexity</b>: Assuming O(1) move assignment, O(NlogN) with N = seq.size()
+ //!
+ //! <b>Throws</b>: If the comparison or the move constructor throws
+ BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
+ { this->m_flat_tree.adopt_sequence_equal(boost::move(container_detail::force<impl_sequence_type>(seq))); }
+
+ //! <b>Requires</b>: seq shall be ordered according to this->compare().
+ //!
+ //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+ //! one passed externally using the move assignment.
+ //!
+ //! <b>Complexity</b>: Assuming O(1) move assignment, O(1)
+ //!
+ //! <b>Throws</b>: If the move assignment throws
+ BOOST_CONTAINER_FORCEINLINE 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<impl_sequence_type>(seq))); }
+
//! <b>Effects</b>: Returns true if x and y are equal
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
- friend bool operator==(const flat_multimap& x, const flat_multimap& y)
+ BOOST_CONTAINER_FORCEINLINE friend bool operator==(const flat_multimap& x, const flat_multimap& y)
{ return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
//! <b>Effects</b>: Returns true if x and y are unequal
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
- friend bool operator!=(const flat_multimap& x, const flat_multimap& y)
+ BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const flat_multimap& x, const flat_multimap& y)
{ return !(x == y); }
//! <b>Effects</b>: Returns true if x is less than y
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
- friend bool operator<(const flat_multimap& x, const flat_multimap& y)
+ BOOST_CONTAINER_FORCEINLINE friend bool operator<(const flat_multimap& x, const flat_multimap& y)
{ return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
//! <b>Effects</b>: Returns true if x is greater than y
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
- friend bool operator>(const flat_multimap& x, const flat_multimap& y)
+ BOOST_CONTAINER_FORCEINLINE friend bool operator>(const flat_multimap& x, const flat_multimap& y)
{ return y < x; }
//! <b>Effects</b>: Returns true if x is equal or less than y
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
- friend bool operator<=(const flat_multimap& x, const flat_multimap& y)
+ BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const flat_multimap& x, const flat_multimap& y)
{ return !(y < x); }
//! <b>Effects</b>: Returns true if x is equal or greater than y
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
- friend bool operator>=(const flat_multimap& x, const flat_multimap& y)
+ BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const flat_multimap& x, const flat_multimap& y)
{ return !(x < y); }
//! <b>Effects</b>: x.swap(y)
//!
//! <b>Complexity</b>: Constant.
- friend void swap(flat_multimap& x, flat_multimap& y)
+ BOOST_CONTAINER_FORCEINLINE friend void swap(flat_multimap& x, flat_multimap& y)
{ x.swap(y); }
};
diff --git a/boost/container/flat_set.hpp b/boost/container/flat_set.hpp
index fa27006177..9e39be8e78 100644
--- a/boost/container/flat_set.hpp
+++ b/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:
//////////////////////////////////////////////
@@ -125,37 +126,47 @@ class flat_set
//! <b>Effects</b>: Default constructs an empty container.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
explicit flat_set() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
container_detail::is_nothrow_default_constructible<Compare>::value)
: base_t()
{}
//! <b>Effects</b>: Constructs an empty container using the specified
- //! comparison object and allocator.
+ //! comparison object.
//!
//! <b>Complexity</b>: Constant.
- explicit flat_set(const Compare& comp,
- const allocator_type& a = allocator_type())
- : base_t(comp, a)
+ BOOST_CONTAINER_FORCEINLINE
+ explicit flat_set(const Compare& comp)
+ : base_t(comp)
{}
//! <b>Effects</b>: Constructs an empty container using the specified allocator.
//!
//! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
explicit flat_set(const allocator_type& a)
: base_t(a)
{}
- //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
- //! allocator, and inserts elements from the range [first ,last ).
+ //! <b>Effects</b>: Constructs an empty container using the specified
+ //! comparison object and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE
+ flat_set(const Compare& comp, const allocator_type& a)
+ : base_t(comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty container and
+ //! inserts elements from the range [first ,last ).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
//! comp and otherwise N logN, where N is last - first.
template <class InputIterator>
- flat_set(InputIterator first, InputIterator last,
- const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
- : base_t(true, first, last, comp, a)
+ BOOST_CONTAINER_FORCEINLINE
+ flat_set(InputIterator first, InputIterator last)
+ : base_t(true, first, last)
{}
//! <b>Effects</b>: Constructs an empty container using the specified
@@ -164,8 +175,63 @@ class flat_set
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
//! comp and otherwise N logN, where N is last - first.
template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
flat_set(InputIterator first, InputIterator last, const allocator_type& a)
- : base_t(true, first, last, Compare(), a)
+ : base_t(true, first, last, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+ //! inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_set(InputIterator first, InputIterator last, const Compare& comp)
+ : base_t(true, first, last, comp)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_set(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+ : base_t(true, first, last, comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty container and
+ //! inserts elements from the ordered unique range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_set(ordered_unique_range_t, InputIterator first, InputIterator last)
+ : base_t(ordered_unique_range, first, last)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+ //! inserts elements from the ordered unique range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE
+ flat_set(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp)
+ : base_t(ordered_unique_range, first, last, comp)
{}
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
@@ -179,21 +245,19 @@ class flat_set
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
- flat_set(ordered_unique_range_t, InputIterator first, InputIterator last,
- const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE
+ flat_set(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
: base_t(ordered_unique_range, first, last, comp, a)
{}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
- //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
- //! allocator, and inserts elements from the range [il.begin(), il.end()).
+ //! <b>Effects</b>: Constructs an empty container and
+ //! inserts elements from the range [il.begin(), il.end()).
//!
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
//! comp and otherwise N logN, where N is il.begin() - il.end().
- flat_set(std::initializer_list<value_type> il, const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
- : base_t(true, il.begin(), il.end(), comp, a)
+ BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list<value_type> il)
+ : base_t(true, il.begin(), il.end())
{}
//! <b>Effects</b>: Constructs an empty container using the specified
@@ -201,8 +265,54 @@ class flat_set
//!
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
//! comp and otherwise N logN, where N is il.begin() - il.end().
- flat_set(std::initializer_list<value_type> il, const allocator_type& a)
- : base_t(true, il.begin(), il.end(), Compare(), a)
+ BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list<value_type> il, const allocator_type& a)
+ : base_t(true, il.begin(), il.end(), a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+ //! inserts elements from the range [il.begin(), il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+ //! comp and otherwise N logN, where N is il.begin() - il.end().
+ BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list<value_type> il, const Compare& comp)
+ : base_t(true, il.begin(), il.end(), comp)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+ //! allocator, and inserts elements from the range [il.begin(), il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+ //! comp and otherwise N logN, where N is il.begin() - il.end().
+ BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+ : base_t(true, il.begin(), il.end(), comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+ //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE flat_set(ordered_unique_range_t, std::initializer_list<value_type> il)
+ : base_t(ordered_unique_range, il.begin(), il.end())
+ {}
+
+ //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+ //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE flat_set(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp)
+ : base_t(ordered_unique_range, il.begin(), il.end(), comp)
{}
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
@@ -215,8 +325,7 @@ class flat_set
//! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
- flat_set(ordered_unique_range_t, std::initializer_list<value_type> il,
- const Compare& comp = Compare(), const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE flat_set(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
: base_t(ordered_unique_range, il.begin(), il.end(), comp, a)
{}
#endif
@@ -224,7 +333,7 @@ class flat_set
//! <b>Effects</b>: Copy constructs the container.
//!
//! <b>Complexity</b>: Linear in x.size().
- flat_set(const flat_set& x)
+ BOOST_CONTAINER_FORCEINLINE flat_set(const flat_set& x)
: base_t(static_cast<const base_t&>(x))
{}
@@ -233,7 +342,7 @@ class flat_set
//! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
- flat_set(BOOST_RV_REF(flat_set) x)
+ BOOST_CONTAINER_FORCEINLINE flat_set(BOOST_RV_REF(flat_set) x)
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
: base_t(BOOST_MOVE_BASE(base_t, x))
{}
@@ -241,7 +350,7 @@ class flat_set
//! <b>Effects</b>: Copy constructs a container using the specified allocator.
//!
//! <b>Complexity</b>: Linear in x.size().
- flat_set(const flat_set& x, const allocator_type &a)
+ BOOST_CONTAINER_FORCEINLINE flat_set(const flat_set& x, const allocator_type &a)
: base_t(static_cast<const base_t&>(x), a)
{}
@@ -249,14 +358,14 @@ class flat_set
//! Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise
- flat_set(BOOST_RV_REF(flat_set) x, const allocator_type &a)
+ BOOST_CONTAINER_FORCEINLINE flat_set(BOOST_RV_REF(flat_set) x, const allocator_type &a)
: base_t(BOOST_MOVE_BASE(base_t, x), a)
{}
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().
- flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
+ BOOST_CONTAINER_FORCEINLINE flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
{ return static_cast<flat_set&>(this->base_t::operator=(static_cast<const base_t&>(x))); }
//! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
@@ -265,7 +374,7 @@ class flat_set
//! <b>Complexity</b>: Constant if allocator_traits_type::
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
- flat_set& operator=(BOOST_RV_REF(flat_set) x)
+ BOOST_CONTAINER_FORCEINLINE flat_set& operator=(BOOST_RV_REF(flat_set) x)
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
allocator_traits_type::is_always_equal::value) &&
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
@@ -469,7 +578,7 @@ class flat_set
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
- std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
+ BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_unique(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type Key constructed with
@@ -485,18 +594,18 @@ class flat_set
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
- iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
+ BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_unique(p, boost::forward<Args>(args)...); }
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
- std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
+ BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
- iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE)
@@ -575,7 +684,7 @@ class flat_set
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
+ BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
{ this->base_t::insert_unique(first, last); }
//! <b>Requires</b>: first, last are not iterators into *this and
@@ -590,7 +699,7 @@ class flat_set
//!
//! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements.
template <class InputIterator>
- void insert(ordered_unique_range_t, InputIterator first, InputIterator last)
+ BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, InputIterator first, InputIterator last)
{ this->base_t::insert_unique(ordered_unique_range, first, last); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -601,7 +710,7 @@ class flat_set
//! search time plus N*size() insertion time.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- void insert(std::initializer_list<value_type> il)
+ BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
{ this->base_t::insert_unique(il.begin(), il.end()); }
//! <b>Requires</b>: Range [il.begin(), il.end()) must be ordered according to the predicate
@@ -614,7 +723,7 @@ class flat_set
//! search time plus N*size() insertion time.
//!
//! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements.
- void insert(ordered_unique_range_t, std::initializer_list<value_type> il)
+ BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, std::initializer_list<value_type> il)
{ this->base_t::insert_unique(ordered_unique_range, il.begin(), il.end()); }
#endif
@@ -623,7 +732,7 @@ class flat_set
BOOST_CONTAINER_FORCEINLINE void merge(flat_set<Key, C2, Allocator>& source)
{ this->base_t::merge_unique(source.tree()); }
- //! @copydoc ::boost::container::flat_map::merge(flat_set<Key, C2, Allocator>&)
+ //! @copydoc ::boost::container::flat_set::merge(flat_set<Key, C2, Allocator>&)
template<class C2>
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_set<Key, C2, Allocator> BOOST_RV_REF_END source)
{ return this->merge(static_cast<flat_set<Key, C2, Allocator>&>(source)); }
@@ -633,7 +742,7 @@ class flat_set
BOOST_CONTAINER_FORCEINLINE void merge(flat_multiset<Key, C2, Allocator>& source)
{ this->base_t::merge_unique(source.tree()); }
- //! @copydoc ::boost::container::flat_map::merge(flat_multiset<Key, C2, Allocator>&)
+ //! @copydoc ::boost::container::flat_set::merge(flat_multiset<Key, C2, Allocator>&)
template<class C2>
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multiset<Key, C2, Allocator> BOOST_RV_REF_END source)
{ return this->merge(static_cast<flat_multiset<Key, C2, Allocator>&>(source)); }
@@ -765,7 +874,7 @@ class flat_set
//! <b>Returns</b>: The number of elements with key equivalent to x.
//!
//! <b>Complexity</b>: log(size())+count(k)
- size_type count(const key_type& x) const
+ BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) const
{ return static_cast<size_type>(this->base_t::find(x) != this->base_t::cend()); }
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -798,13 +907,13 @@ class flat_set
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic
- std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
+ BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
{ return this->base_t::lower_bound_range(x); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic
- std::pair<iterator,iterator> equal_range(const key_type& x)
+ BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& x)
{ return this->base_t::lower_bound_range(x); }
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -844,16 +953,46 @@ class flat_set
//! <b>Complexity</b>: Constant.
friend void swap(flat_set& x, flat_set& y);
+ //! <b>Effects</b>: Extracts the internal sequence container.
+ //!
+ //! <b>Complexity</b>: Same as the move constructor of sequence_type, usually constant.
+ //!
+ //! <b>Postcondition</b>: this->empty()
+ //!
+ //! <b>Throws</b>: If secuence_type's move constructor throws
+ sequence_type extract_sequence();
+
#endif //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+ //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+ //! one passed externally using the move assignment. Erases non-unique elements.
+ //!
+ //! <b>Complexity</b>: Assuming O(1) move assignment, O(NlogN) with N = seq.size()
+ //!
+ //! <b>Throws</b>: If the comparison or the move constructor throws
+ BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
+ { this->base_t::adopt_sequence_unique(boost::move(seq)); }
+
+ //! <b>Requires</b>: seq shall be ordered according to this->compare()
+ //! and shall contain unique elements.
+ //!
+ //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+ //! one passed externally using the move assignment.
+ //!
+ //! <b>Complexity</b>: Assuming O(1) move assignment, O(1)
+ //!
+ //! <b>Throws</b>: If the move assignment throws
+ BOOST_CONTAINER_FORCEINLINE 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<class KeyType>
- std::pair<iterator, bool> priv_insert(BOOST_FWD_REF(KeyType) x)
+ BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> priv_insert(BOOST_FWD_REF(KeyType) x)
{ return this->base_t::insert_unique(::boost::forward<KeyType>(x)); }
template<class KeyType>
- iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
+ BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
{ return this->base_t::insert_unique(p, ::boost::forward<KeyType>(x)); }
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
@@ -939,40 +1078,83 @@ 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<Allocator>::value &&
+ BOOST_CONTAINER_FORCEINLINE explicit flat_multiset() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
container_detail::is_nothrow_default_constructible<Compare>::value)
: base_t()
{}
- //! @copydoc ::boost::container::flat_set::flat_set(const Compare&, const allocator_type&)
- explicit flat_multiset(const Compare& comp,
- const allocator_type& a = allocator_type())
- : base_t(comp, a)
+ //! @copydoc ::boost::container::flat_set::flat_set(const Compare&)
+ BOOST_CONTAINER_FORCEINLINE explicit flat_multiset(const Compare& comp)
+ : base_t(comp)
{}
//! @copydoc ::boost::container::flat_set::flat_set(const allocator_type&)
- explicit flat_multiset(const allocator_type& a)
+ BOOST_CONTAINER_FORCEINLINE explicit flat_multiset(const allocator_type& a)
: base_t(a)
{}
+ //! @copydoc ::boost::container::flat_set::flat_set(const Compare&, const allocator_type&)
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(const Compare& comp, const allocator_type& a)
+ : base_t(comp, a)
+ {}
+
+ //! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator)
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last)
+ : base_t(false, first, last)
+ {}
+
+ //! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator, const allocator_type&)
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last, const allocator_type& a)
+ : base_t(false, first, last, a)
+ {}
+
+ //! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator, const Compare& comp)
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last, const Compare& comp)
+ : base_t(false, first, last, comp)
+ {}
+
//! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator, const Compare& comp, const allocator_type&)
template <class InputIterator>
- flat_multiset(InputIterator first, InputIterator last,
- const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
: base_t(false, first, last, comp, a)
{}
- //! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator, const allocator_type&)
+ //! <b>Effects</b>: Constructs an empty flat_multiset and
+ //! inserts elements from the ordered range [first ,last ). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, InputIterator first, InputIterator last)
+ : base_t(ordered_range, first, last)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty flat_multiset using the specified comparison object and
+ //! inserts elements from the ordered range [first ,last ). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
template <class InputIterator>
- flat_multiset(InputIterator first, InputIterator last, const allocator_type& a)
- : base_t(false, first, last, Compare(), a)
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp)
+ : base_t(ordered_range, first, last, comp)
{}
//! <b>Effects</b>: Constructs an empty flat_multiset using the specified comparison object and
- //! allocator, and inserts elements from the ordered range [first ,last ). This function
+ //! allocator, and inserts elements from the ordered range [first, last ). This function
//! is more efficient than the normal range creation for ordered ranges.
//!
//! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
@@ -981,22 +1163,55 @@ class flat_multiset
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
- flat_multiset(ordered_range_t, InputIterator first, InputIterator last,
- const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
: base_t(ordered_range, first, last, comp, a)
{}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ //! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list<value_type)
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(std::initializer_list<value_type> il)
+ : base_t(false, il.begin(), il.end())
+ {}
+
+ //! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list<value_type>, const allocator_type&)
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(std::initializer_list<value_type> il, const allocator_type& a)
+ : base_t(false, il.begin(), il.end(), a)
+ {}
+
+ //! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list<value_type>, const Compare& comp)
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(std::initializer_list<value_type> il, const Compare& comp)
+ : base_t(false, il.begin(), il.end(), comp)
+ {}
+
//! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list<value_type>, const Compare& comp, const allocator_type&)
- flat_multiset(std::initializer_list<value_type> il, const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
: base_t(false, il.begin(), il.end(), comp, a)
{}
- //! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list<value_type>, const allocator_type&)
- flat_multiset(std::initializer_list<value_type> il, const allocator_type& a)
- : base_t(false, il.begin(), il.end(), Compare(), a)
+ //! <b>Effects</b>: Constructs an empty containerand
+ //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, std::initializer_list<value_type> il)
+ : base_t(ordered_range, il.begin(), il.end())
+ {}
+
+ //! <b>Effects</b>: Constructs an empty container using the specified comparison object and
+ //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp)
+ : base_t(ordered_range, il.begin(), il.end(), comp)
{}
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
@@ -1008,39 +1223,38 @@ class flat_multiset
//! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
- flat_multiset(ordered_range_t, std::initializer_list<value_type> il,
- const Compare& comp = Compare(), const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
: base_t(ordered_range, il.begin(), il.end(), comp, a)
{}
#endif
//! @copydoc ::boost::container::flat_set::flat_set(const flat_set &)
- flat_multiset(const flat_multiset& x)
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(const flat_multiset& x)
: base_t(static_cast<const base_t&>(x))
{}
//! @copydoc ::boost::container::flat_set::flat_set(flat_set &&)
- flat_multiset(BOOST_RV_REF(flat_multiset) x)
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(BOOST_RV_REF(flat_multiset) x)
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
: base_t(boost::move(static_cast<base_t&>(x)))
{}
//! @copydoc ::boost::container::flat_set::flat_set(const flat_set &, const allocator_type &)
- flat_multiset(const flat_multiset& x, const allocator_type &a)
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(const flat_multiset& x, const allocator_type &a)
: base_t(static_cast<const base_t&>(x), a)
{}
//! @copydoc ::boost::container::flat_set::flat_set(flat_set &&, const allocator_type &)
- flat_multiset(BOOST_RV_REF(flat_multiset) x, const allocator_type &a)
+ BOOST_CONTAINER_FORCEINLINE flat_multiset(BOOST_RV_REF(flat_multiset) x, const allocator_type &a)
: base_t(BOOST_MOVE_BASE(base_t, x), a)
{}
//! @copydoc ::boost::container::flat_set::operator=(const flat_set &)
- flat_multiset& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x)
+ BOOST_CONTAINER_FORCEINLINE flat_multiset& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x)
{ return static_cast<flat_multiset&>(this->base_t::operator=(static_cast<const base_t&>(x))); }
//! @copydoc ::boost::container::flat_set::operator=(flat_set &&)
- flat_multiset& operator=(BOOST_RV_REF(flat_multiset) x)
+ BOOST_CONTAINER_FORCEINLINE flat_multiset& operator=(BOOST_RV_REF(flat_multiset) x)
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
allocator_traits_type::is_always_equal::value) &&
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
@@ -1140,7 +1354,7 @@ class flat_multiset
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
- iterator emplace(BOOST_FWD_REF(Args)... args)
+ BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_equal(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type Key constructed with
@@ -1155,18 +1369,18 @@ class flat_multiset
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
- iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
+ BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_equal(p, boost::forward<Args>(args)...); }
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
- iterator emplace(BOOST_MOVE_UREF##N)\
+ BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
- iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE)
@@ -1233,7 +1447,7 @@ class flat_multiset
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
+ BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
{ this->base_t::insert_equal(first, last); }
//! <b>Requires</b>: first, last are not iterators into *this and
@@ -1247,7 +1461,7 @@ class flat_multiset
//!
//! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements.
template <class InputIterator>
- void insert(ordered_range_t, InputIterator first, InputIterator last)
+ BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, InputIterator first, InputIterator last)
{ this->base_t::insert_equal(ordered_range, first, last); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -1257,7 +1471,7 @@ class flat_multiset
//! search time plus N*size() insertion time.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- void insert(std::initializer_list<value_type> il)
+ BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
{ this->base_t::insert_equal(il.begin(), il.end()); }
//! <b>Requires</b>: Range [il.begin(), il.end()) must be ordered according to the predicate.
@@ -1269,7 +1483,7 @@ class flat_multiset
//! search time plus N*size() insertion time.
//!
//! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements.
- void insert(ordered_range_t, std::initializer_list<value_type> il)
+ BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, std::initializer_list<value_type> il)
{ this->base_t::insert_equal(ordered_range, il.begin(), il.end()); }
#endif
@@ -1392,16 +1606,45 @@ class flat_multiset
//! <b>Complexity</b>: Constant.
friend void swap(flat_multiset& x, flat_multiset& y);
+ //! <b>Effects</b>: Extracts the internal sequence container.
+ //!
+ //! <b>Complexity</b>: Same as the move constructor of sequence_type, usually constant.
+ //!
+ //! <b>Postcondition</b>: this->empty()
+ //!
+ //! <b>Throws</b>: If secuence_type's move constructor throws
+ sequence_type extract_sequence();
+
#endif //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+ //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+ //! one passed externally using the move assignment.
+ //!
+ //! <b>Complexity</b>: Assuming O(1) move assignment, O(NlogN) with N = seq.size()
+ //!
+ //! <b>Throws</b>: If the comparison or the move constructor throws
+ BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
+ { this->base_t::adopt_sequence_equal(boost::move(seq)); }
+
+ //! <b>Requires</b>: seq shall be ordered according to this->compare()
+ //!
+ //! <b>Effects</b>: Discards the internally hold sequence container and adopts the
+ //! one passed externally using the move assignment.
+ //!
+ //! <b>Complexity</b>: Assuming O(1) move assignment, O(1)
+ //!
+ //! <b>Throws</b>: If the move assignment throws
+ BOOST_CONTAINER_FORCEINLINE 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 <class KeyType>
- iterator priv_insert(BOOST_FWD_REF(KeyType) x)
+ BOOST_CONTAINER_FORCEINLINE iterator priv_insert(BOOST_FWD_REF(KeyType) x)
{ return this->base_t::insert_equal(::boost::forward<KeyType>(x)); }
template <class KeyType>
- iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
+ BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
{ return this->base_t::insert_equal(p, ::boost::forward<KeyType>(x)); }
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
diff --git a/boost/container/map.hpp b/boost/container/map.hpp
index 5520fb45ba..33e0331eb0 100644
--- a/boost/container/map.hpp
+++ b/boost/container/map.hpp
@@ -31,6 +31,8 @@
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/value_init.hpp>
#include <boost/container/detail/pair.hpp>
+#include <boost/container/detail/pair_key_mapped_of_value.hpp>
+
// move
#include <boost/move/traits.hpp>
#include <boost/move/utility_core.hpp>
@@ -53,34 +55,6 @@
namespace boost {
namespace container {
-///@cond
-
-template<class Key, class Mapped>
-struct pair_key_mapped_of_value
-{
- typedef Key key_type;
- typedef Mapped mapped_type;
-
- template<class Pair>
- const key_type & key_of_value(const Pair &p) const
- { return p.first; }
-
- template<class Pair>
- const mapped_type & mapped_of_value(const Pair &p) const
- { return p.second; }
-
- template<class Pair>
- key_type & key_of_value(Pair &p) const
- { return const_cast<key_type&>(p.first); }
-
- template<class Pair>
- 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
@@ -132,7 +106,7 @@ class map
typedef Key key_type;
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef T mapped_type;
- typedef std::pair<const Key, T> value_type;
+ typedef typename boost::container::allocator_traits<Allocator>::value_type value_type;
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<Allocator>::reference reference;
@@ -150,14 +124,15 @@ class map
typedef std::pair<key_type, mapped_type> 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
<key_type BOOST_MOVE_I mapped_type> >) node_type;
typedef BOOST_CONTAINER_IMPDEF
(insert_return_type_base<iterator BOOST_MOVE_I node_type>) insert_return_type;
+ //allocator_type::value_type type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<typename allocator_type::value_type, std::pair<const Key, T> >::value));
+
//////////////////////////////////////////////
//
// construct/copy/destroy
@@ -171,62 +146,99 @@ class map
map() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
container_detail::is_nothrow_default_constructible<Compare>::value)
: base_t()
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Constructs an empty map using the specified comparison object
//! and allocator.
//!
//! <b>Complexity</b>: Constant.
- BOOST_CONTAINER_FORCEINLINE
- explicit map(const Compare& comp, const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE map(const Compare& comp, const allocator_type& a)
: base_t(comp, a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
+
+ //! <b>Effects</b>: Constructs an empty map using the specified comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE explicit map(const Compare& comp)
+ : base_t(comp)
+ {}
//! <b>Effects</b>: Constructs an empty map using the specified allocator.
//!
//! <b>Complexity</b>: Constant.
- BOOST_CONTAINER_FORCEINLINE
- explicit map(const allocator_type& a)
+ BOOST_CONTAINER_FORCEINLINE explicit map(const allocator_type& a)
: base_t(a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
- //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
- //! allocator, and inserts elements from the range [first ,last ).
+ //! <b>Effects</b>: Constructs an empty map and
+ //! inserts elements from the range [first ,last ).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
+ //! the predicate and otherwise N logN, where N is last - first.
template <class InputIterator>
- BOOST_CONTAINER_FORCEINLINE
- map(InputIterator first, InputIterator last, const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
- : base_t(true, first, last, comp, a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ BOOST_CONTAINER_FORCEINLINE map(InputIterator first, InputIterator last)
+ : base_t(true, first, last)
+ {}
//! <b>Effects</b>: Constructs an empty map using the specified
//! allocator, and inserts elements from the range [first ,last ).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
+ //! the predicate and otherwise N logN, where N is last - first.
template <class InputIterator>
- BOOST_CONTAINER_FORCEINLINE
- map(InputIterator first, InputIterator last, const allocator_type& a)
+ BOOST_CONTAINER_FORCEINLINE map(InputIterator first, InputIterator last, const allocator_type& a)
: base_t(true, first, last, Compare(), a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
+
+ //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+ //! inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! the predicate and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE map(InputIterator first, InputIterator last, const Compare& comp)
+ : base_t(true, first, last, comp)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! the predicate and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE map(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+ : base_t(true, first, last, comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty map and
+ //! inserts elements from the ordered unique range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE map( ordered_unique_range_t, InputIterator first, InputIterator last)
+ : base_t(ordered_range, first, last)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+ //! inserts elements from the ordered unique range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE map( ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp)
+ : base_t(ordered_range, first, last, comp)
+ {}
//! <b>Effects</b>: Constructs an empty map using the specified comparison object and
//! allocator, and inserts elements from the ordered unique range [first ,last). This function
@@ -239,43 +251,76 @@ class map
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
- BOOST_CONTAINER_FORCEINLINE
- map( ordered_unique_range_t, InputIterator first, InputIterator last
- , const Compare& comp = Compare(), const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE map( ordered_unique_range_t, InputIterator first, InputIterator last
+ , const Compare& comp, const allocator_type& a)
: base_t(ordered_range, first, last, comp, a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ //! <b>Effects</b>: Constructs an empty map and
+ //! inserts elements from the range [il.begin(), il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted according
+ //! to the predicate and otherwise N logN, where N is il.first() - il.end().
+ BOOST_CONTAINER_FORCEINLINE map(std::initializer_list<value_type> il)
+ : base_t(true, il.begin(), il.end())
+ {}
+
//! <b>Effects</b>: Constructs an empty map using the specified comparison object and
- //! allocator, and inserts elements from the range [il.begin(), il.end()).
+ //! inserts elements from the range [il.begin(), il.end()).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is il.first() - il.end().
- BOOST_CONTAINER_FORCEINLINE
- map(std::initializer_list<value_type> il, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
- : base_t(true, il.begin(), il.end(), comp, a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ //! the predicate and otherwise N logN, where N is il.first() - il.end().
+ BOOST_CONTAINER_FORCEINLINE map(std::initializer_list<value_type> il, const Compare& comp)
+ : base_t(true, il.begin(), il.end(), comp)
+ {}
//! <b>Effects</b>: Constructs an empty map using the specified
//! allocator, and inserts elements from the range [il.begin(), il.end()).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is il.first() - il.end().
- BOOST_CONTAINER_FORCEINLINE
- map(std::initializer_list<value_type> il, const allocator_type& a)
+ //! the predicate and otherwise N logN, where N is il.first() - il.end().
+ BOOST_CONTAINER_FORCEINLINE map(std::initializer_list<value_type> il, const allocator_type& a)
: base_t(true, il.begin(), il.end(), Compare(), a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
- //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+ //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+ //! allocator, and inserts elements from the range [il.begin(), il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! the predicate and otherwise N logN, where N is il.first() - il.end().
+ BOOST_CONTAINER_FORCEINLINE map(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+ : base_t(true, il.begin(), il.end(), comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty map and inserts elements from the ordered unique range [il.begin(), il.end()).
+ //! This function is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE map(ordered_unique_range_t, std::initializer_list<value_type> il)
+ : base_t(ordered_range, il.begin(), il.end())
+ {}
+
+ //! <b>Effects</b>: Constructs an empty map using the specified comparison object,
+ //! and inserts elements from the ordered unique range [il.begin(), il.end()). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp)
+ : base_t(ordered_range, il.begin(), il.end(), comp)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
//! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
//! is more efficient than the normal range creation for ordered ranges.
//!
@@ -285,51 +330,36 @@ class map
//! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
- BOOST_CONTAINER_FORCEINLINE
- map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE map( ordered_unique_range_t, std::initializer_list<value_type> il
+ , const Compare& comp, const allocator_type& a)
: base_t(ordered_range, il.begin(), il.end(), comp, a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
+
#endif
//! <b>Effects</b>: Copy constructs a map.
//!
//! <b>Complexity</b>: Linear in x.size().
- BOOST_CONTAINER_FORCEINLINE
- map(const map& x)
+ BOOST_CONTAINER_FORCEINLINE map(const map& x)
: base_t(static_cast<const base_t&>(x))
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
- BOOST_CONTAINER_FORCEINLINE
- map(BOOST_RV_REF(map) x)
+ BOOST_CONTAINER_FORCEINLINE map(BOOST_RV_REF(map) x)
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
: base_t(BOOST_MOVE_BASE(base_t, x))
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Copy constructs a map using the specified allocator.
//!
//! <b>Complexity</b>: Linear in x.size().
- BOOST_CONTAINER_FORCEINLINE
- map(const map& x, const allocator_type &a)
+ BOOST_CONTAINER_FORCEINLINE map(const map& x, const allocator_type &a)
: base_t(static_cast<const base_t&>(x), a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Move constructs a map using the specified allocator.
//! Constructs *this using x's resources.
@@ -337,19 +367,14 @@ class map
//! <b>Complexity</b>: Constant if x == x.get_allocator(), linear otherwise.
//!
//! <b>Postcondition</b>: x is emptied.
- BOOST_CONTAINER_FORCEINLINE
- map(BOOST_RV_REF(map) x, const allocator_type &a)
+ BOOST_CONTAINER_FORCEINLINE map(BOOST_RV_REF(map) x, const allocator_type &a)
: base_t(BOOST_MOVE_BASE(base_t, x), a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().
- BOOST_CONTAINER_FORCEINLINE
- map& operator=(BOOST_COPY_ASSIGN_REF(map) x)
+ BOOST_CONTAINER_FORCEINLINE map& operator=(BOOST_COPY_ASSIGN_REF(map) x)
{ return static_cast<map&>(this->base_t::operator=(static_cast<const base_t&>(x))); }
//! <b>Effects</b>: this->swap(x.get()).
@@ -360,8 +385,7 @@ class map
//! <b>Complexity</b>: Constant if allocator_traits_type::
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
- BOOST_CONTAINER_FORCEINLINE
- map& operator=(BOOST_RV_REF(map) x)
+ BOOST_CONTAINER_FORCEINLINE map& operator=(BOOST_RV_REF(map) x)
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
allocator_traits_type::is_always_equal::value) &&
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
@@ -370,8 +394,7 @@ class map
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! <b>Effects</b>: Assign content of il to *this.
//!
- BOOST_CONTAINER_FORCEINLINE
- map& operator=(std::initializer_list<value_type> il)
+ BOOST_CONTAINER_FORCEINLINE map& operator=(std::initializer_list<value_type> il)
{
this->clear();
insert(il.begin(), il.end());
@@ -716,7 +739,7 @@ class map
//!
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
- iterator insert(const_iterator p, BOOST_RV_REF(nonconst_value_type) x)
+ BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(nonconst_value_type) x)
{ return this->try_emplace(p, boost::move(x.first), boost::move(x.second)); }
//! <b>Effects</b>: Move constructs a new value from x if and only if there is
@@ -728,7 +751,7 @@ class map
//!
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
- iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x)
+ BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x)
{ return this->try_emplace(p, boost::move(x.first), boost::move(x.second)); }
//! <b>Effects</b>: Inserts a copy of x in the container.
@@ -746,7 +769,7 @@ class map
//! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
//!
//! <b>Complexity</b>: Logarithmic.
- iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
+ BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
{ return this->base_t::insert_unique(p, boost::move(x)); }
//! <b>Requires</b>: first, last are not iterators into *this.
@@ -1225,7 +1248,7 @@ class multimap
typedef Key key_type;
typedef T mapped_type;
- typedef std::pair<const Key, T> value_type;
+ typedef typename boost::container::allocator_traits<Allocator>::value_type value_type;
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<Allocator>::reference reference;
@@ -1243,12 +1266,13 @@ class multimap
typedef std::pair<key_type, mapped_type> 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
<key_type BOOST_MOVE_I mapped_type> >) node_type;
+ //allocator_type::value_type type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<typename allocator_type::value_type, std::pair<const Key, T> >::value));
+
//////////////////////////////////////////////
//
// construct/copy/destroy
@@ -1258,66 +1282,102 @@ class multimap
//! <b>Effects</b>: Default constructs an empty multimap.
//!
//! <b>Complexity</b>: Constant.
- BOOST_CONTAINER_FORCEINLINE
- multimap() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
- container_detail::is_nothrow_default_constructible<Compare>::value)
+ BOOST_CONTAINER_FORCEINLINE multimap()
+ BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
+ container_detail::is_nothrow_default_constructible<Compare>::value)
: base_t()
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
- //! <b>Effects</b>: Constructs an empty multimap using the specified allocator.
+ //! <b>Effects</b>: Constructs an empty multimap using the specified allocator
+ //! object and allocator.
//!
//! <b>Complexity</b>: Constant.
- BOOST_CONTAINER_FORCEINLINE
- explicit multimap(const Compare& comp, const allocator_type& a = allocator_type())
- : base_t(comp, a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ BOOST_CONTAINER_FORCEINLINE explicit multimap(const allocator_type& a)
+ : base_t(a)
+ {}
- //! <b>Effects</b>: Constructs an empty multimap using the specified comparison
- //! object and allocator.
+ //! <b>Effects</b>: Constructs an empty multimap using the specified comparison.
//!
//! <b>Complexity</b>: Constant.
- BOOST_CONTAINER_FORCEINLINE
- explicit multimap(const allocator_type& a)
- : base_t(a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ BOOST_CONTAINER_FORCEINLINE explicit multimap(const Compare& comp)
+ : base_t(comp)
+ {}
- //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object
- //! and allocator, and inserts elements from the range [first ,last ).
+ //! <b>Effects</b>: Constructs an empty multimap using the specified comparison and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE multimap(const Compare& comp, const allocator_type& a)
+ : base_t(comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty multimap and
+ //! inserts elements from the range [first ,last ).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
+ //! the predicate and otherwise N logN, where N is last - first.
template <class InputIterator>
- BOOST_CONTAINER_FORCEINLINE
- multimap(InputIterator first, InputIterator last,
- const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
- : base_t(false, first, last, comp, a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ BOOST_CONTAINER_FORCEINLINE multimap(InputIterator first, InputIterator last)
+ : base_t(false, first, last)
+ {}
//! <b>Effects</b>: Constructs an empty multimap using the specified
//! allocator, and inserts elements from the range [first ,last ).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
+ //! the predicate and otherwise N logN, where N is last - first.
template <class InputIterator>
BOOST_CONTAINER_FORCEINLINE multimap(InputIterator first, InputIterator last, const allocator_type& a)
: base_t(false, first, last, Compare(), a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
+
+ //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
+ //! inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! the predicate and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE multimap(InputIterator first, InputIterator last, const Compare& comp)
+ : base_t(false, first, last, comp)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object
+ //! and allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! the predicate and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE multimap(InputIterator first, InputIterator last,
+ const Compare& comp, const allocator_type& a)
+ : base_t(false, first, last, comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty multimap and
+ //! inserts elements from the ordered range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last)
+ : base_t(ordered_range, first, last)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
+ //! inserts elements from the ordered range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp)
+ : base_t(ordered_range, first, last, comp)
+ {}
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
//! allocator, and inserts elements from the ordered range [first ,last). This function
@@ -1329,41 +1389,51 @@ class multimap
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
- BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp,
+ const allocator_type& a)
: base_t(ordered_range, first, last, comp, a)
{}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
- //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
- //! allocator, and inserts elements from the range [il.begin(), il.end()).
+ //! <b>Effects</b>: Constructs an empty multimap and
+ //! and inserts elements from the range [il.begin(), il.end()).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is il.first() - il.end().
- BOOST_CONTAINER_FORCEINLINE
- multimap(std::initializer_list<value_type> il, const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
- : base_t(false, il.begin(), il.end(), comp, a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ //! the predicate and otherwise N logN, where N is il.first() - il.end().
+ BOOST_CONTAINER_FORCEINLINE multimap(std::initializer_list<value_type> il)
+ : base_t(false, il.begin(), il.end())
+ {}
//! <b>Effects</b>: Constructs an empty multimap using the specified
//! allocator, and inserts elements from the range [il.begin(), il.end()).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is il.first() - il.end().
- BOOST_CONTAINER_FORCEINLINE
- multimap(std::initializer_list<value_type> il, const allocator_type& a)
+ //! the predicate and otherwise N logN, where N is il.first() - il.end().
+ BOOST_CONTAINER_FORCEINLINE multimap(std::initializer_list<value_type> il, const allocator_type& a)
: base_t(false, il.begin(), il.end(), Compare(), a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
+
+ //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
+ //! inserts elements from the range [il.begin(), il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! the predicate and otherwise N logN, where N is il.first() - il.end().
+ BOOST_CONTAINER_FORCEINLINE multimap(std::initializer_list<value_type> il, const Compare& comp)
+ : base_t(false, il.begin(), il.end(), comp)
+ {}
- //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
- //! allocator, and inserts elements from the ordered range [il.begin(), il.end()). This function
+ //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
+ //! allocator, and inserts elements from the range [il.begin(), il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! the predicate and otherwise N logN, where N is il.first() - il.end().
+ BOOST_CONTAINER_FORCEINLINE multimap(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+ : base_t(false, il.begin(), il.end(), comp, a)
+ {}
+
+
+ //! <b>Effects</b>: Constructs an empty map and
+ //! inserts elements from the ordered range [il.begin(), il.end()). This function
//! is more efficient than the normal range creation for ordered ranges.
//!
//! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
@@ -1371,14 +1441,36 @@ class multimap
//! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
- BOOST_CONTAINER_FORCEINLINE
- multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, std::initializer_list<value_type> il)
+ : base_t(ordered_range, il.begin(), il.end())
+ {}
+
+ //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+ //! inserts elements from the ordered range [il.begin(), il.end()). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp)
+ : base_t(ordered_range, il.begin(), il.end(), comp)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty map and
+ //! inserts elements from the ordered range [il.begin(), il.end()). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
: base_t(ordered_range, il.begin(), il.end(), comp, a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
+
#endif
//! <b>Effects</b>: Copy constructs a multimap.
@@ -1386,10 +1478,7 @@ class multimap
//! <b>Complexity</b>: Linear in x.size().
BOOST_CONTAINER_FORCEINLINE multimap(const multimap& x)
: base_t(static_cast<const base_t&>(x))
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Move constructs a multimap. Constructs *this using x's resources.
//!
@@ -1399,20 +1488,14 @@ class multimap
BOOST_CONTAINER_FORCEINLINE multimap(BOOST_RV_REF(multimap) x)
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
: base_t(BOOST_MOVE_BASE(base_t, x))
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Copy constructs a multimap.
//!
//! <b>Complexity</b>: Linear in x.size().
BOOST_CONTAINER_FORCEINLINE multimap(const multimap& x, const allocator_type &a)
: base_t(static_cast<const base_t&>(x), a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Move constructs a multimap using the specified allocator.
//! Constructs *this using x's resources.
@@ -1421,10 +1504,7 @@ class multimap
//! <b>Postcondition</b>: x is emptied.
BOOST_CONTAINER_FORCEINLINE multimap(BOOST_RV_REF(multimap) x, const allocator_type &a)
: base_t(BOOST_MOVE_BASE(base_t, x), a)
- {
- //A type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
- }
+ {}
//! <b>Effects</b>: Makes *this a copy of x.
//!
@@ -1708,7 +1788,7 @@ class multimap
//!
//! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
template<class C2>
- void merge(multimap<Key, T, C2, Allocator, Options>& source)
+ BOOST_CONTAINER_FORCEINLINE void merge(multimap<Key, T, C2, Allocator, Options>& source)
{
typedef container_detail::tree
<value_type_impl, select_1st_t, C2, Allocator, Options> base2_t;
@@ -1717,12 +1797,12 @@ class multimap
//! @copydoc ::boost::container::multimap::merge(multimap<Key, T, C2, Allocator, Options>&)
template<class C2>
- void merge(BOOST_RV_REF_BEG multimap<Key, T, C2, Allocator, Options> BOOST_RV_REF_END source)
+ BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multimap<Key, T, C2, Allocator, Options> BOOST_RV_REF_END source)
{ return this->merge(static_cast<multimap<Key, T, C2, Allocator, Options>&>(source)); }
//! @copydoc ::boost::container::multimap::merge(multimap<Key, T, C2, Allocator, Options>&)
template<class C2>
- void merge(map<Key, T, C2, Allocator, Options>& source)
+ BOOST_CONTAINER_FORCEINLINE void merge(map<Key, T, C2, Allocator, Options>& source)
{
typedef container_detail::tree
<value_type_impl, select_1st_t, C2, Allocator, Options> base2_t;
@@ -1731,7 +1811,7 @@ class multimap
//! @copydoc ::boost::container::multimap::merge(multimap<Key, T, C2, Allocator, Options>&)
template<class C2>
- void merge(BOOST_RV_REF_BEG map<Key, T, C2, Allocator, Options> BOOST_RV_REF_END source)
+ BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG map<Key, T, C2, Allocator, Options> BOOST_RV_REF_END source)
{ return this->merge(static_cast<map<Key, T, C2, Allocator, Options>&>(source)); }
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
diff --git a/boost/container/node_handle.hpp b/boost/container/node_handle.hpp
index c46313cc4f..594a09c99e 100644
--- a/boost/container/node_handle.hpp
+++ b/boost/container/node_handle.hpp
@@ -23,7 +23,7 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/static_assert.hpp>
#include <boost/container/detail/placement_new.hpp>
-#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/mpl.hpp>
@@ -40,20 +40,34 @@ namespace container {
///@cond
-template<class Value, class KeyMapped, bool keymapped_is_void = container_detail::is_same<KeyMapped, void>::value>
+template<class Value, class KeyMapped>
struct node_handle_keymapped_traits
{
+ typedef typename KeyMapped::key_type key_type;
+ typedef typename KeyMapped::mapped_type mapped_type;
+};
+
+template<class Value>
+struct node_handle_keymapped_traits<Value, void>
+{
typedef Value key_type;
typedef Value mapped_type;
};
-template<class Value, class KeyMapped>
-struct node_handle_keymapped_traits<Value, KeyMapped, false>
+class node_handle_friend
{
- typedef typename KeyMapped::key_type key_type;
- typedef typename KeyMapped::mapped_type mapped_type;
+ public:
+
+ template<class NH>
+ BOOST_CONTAINER_FORCEINLINE static void destroy_alloc(NH &nh) BOOST_NOEXCEPT
+ { nh.destroy_alloc(); }
+
+ template<class NH>
+ 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<Value, KeyMapped, false>
//!
//! 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 <class NodeType, class Value, class Allocator, class KeyMapped = void>
+template <class NodeAllocator, class KeyMapped = void>
class node_handle
{
- typedef node_handle_keymapped_traits<Value, KeyMapped> keymapped_t;
+ typedef NodeAllocator nallocator_type;
+ typedef allocator_traits<NodeAllocator> 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<priv_value_t, KeyMapped> 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
+ <value_type>::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<allocator_type> ator_traits;
- typedef typename ator_traits::template portable_rebind_alloc
- <container_node_type>::type nallocator_type;
- typedef allocator_traits<nallocator_type> node_ator_traits;
- typedef typename node_ator_traits::pointer node_pointer;
+ typedef typename nator_traits::pointer node_pointer;
typedef ::boost::aligned_storage
- <sizeof(allocator_type), boost::alignment_of<nallocator_type>::value> nalloc_storage_t;
+ < sizeof(nallocator_type)
+ , boost::alignment_of<nallocator_type>::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<class OtherNodeHandle>
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()
- { static_cast<allocator_type*>(m_nalloc_storage.address())->~allocator_type(); }
+ void destroy_alloc() BOOST_NOEXCEPT
+ { static_cast<nallocator_type*>(m_nalloc_storage.address())->~nallocator_type(); }
- node_pointer &get_node_pointer()
+ node_pointer &get_node_pointer() BOOST_NOEXCEPT
{ return m_ptr; }
- nallocator_type &node_alloc()
- { return *static_cast<nallocator_type*>(m_nalloc_storage.address()); }
-
- const nallocator_type &node_alloc() const
- { return *static_cast<const nallocator_type*>(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
//!
//! <b>Postcondition</b>: this->empty()
BOOST_CXX14_CONSTEXPR node_handle() BOOST_NOEXCEPT
- : m_ptr(), m_nalloc_storage()
- { BOOST_ASSERT(this->empty()); }
+ : m_ptr()
+ { }
//! <b>Effects</b>: 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
//! <b>Note</b>: Two node_handle's are related if only one of KeyMapped template parameter
//! of a node handle is void.
template<class KeyMapped2>
- node_handle( BOOST_RV_REF_BEG node_handle<NodeType, Value, Allocator, KeyMapped2> BOOST_RV_REF_END nh
+ node_handle( BOOST_RV_REF_BEG node_handle<NodeAllocator, KeyMapped2> BOOST_RV_REF_END nh
, typename container_detail::enable_if_c
< ((unsigned)container_detail::is_same<KeyMapped, void>::value +
(unsigned)container_detail::is_same<KeyMapped2, void>::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); }
//! <b>Effects</b>: Constructs a node_handle object initializing internal pointer with nh's internal pointer
@@ -186,43 +187,44 @@ class node_handle
//!
//! <b>Postcondition</b>: 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); }
//! <b>Effects</b>: If !this->empty(), destroys the value_type subobject in the container_node_type object
//! pointed to by c by calling allocator_traits<impl_defined>::destroy, then deallocates m_ptr by calling
- //! ator_traits::rebind_traits<container_node_type>::deallocate.
- ~node_handle () BOOST_NOEXCEPT
+ //! nator_traits::rebind_traits<container_node_type>::deallocate.
+ ~node_handle() BOOST_NOEXCEPT
{
if(!this->empty()){
- this->destroy_node();
+ this->destroy_deallocate_node();
this->destroy_alloc();
}
}
- //! <b>Requires</b>: Either this->empty(), or ator_traits::propagate_on_container_move_assignment is true, or
+ //! <b>Requires</b>: Either this->empty(), or nator_traits::propagate_on_container_move_assignment is true, or
//! node_alloc() == nh.node_alloc().
//!
//! <b>Effects</b>: 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<container_node_type>::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().
+ //!
//! <b>Returns</b>: *this.
//!
//! <b>Throws</b>: 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;
}
- //! <b>Requires</b>: this->empty(), or nh.empty(), or ator_traits::propagate_on_container_swap is true, or
+ //! <b>Requires</b>: this->empty(), or nh.empty(), or nator_traits::propagate_on_container_swap is true, or
//! node_alloc() == nh.node_alloc().
//!
- //! <b>Effects</b>: Calls swap(m_ptr, nh.m_ptr). If this->empty(), or nh.empty(), or ator_traits::propagate_on_-
+ //! <b>Effects</b>: 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);
}
+ //! <b>Effects</b>: If this->empty() returns nullptr, otherwise returns m_ptr
+ //! resets m_ptr to nullptr and destroys the internal allocator.
+ //!
+ //! <b>Postcondition</b>: this->empty()
+ //!
+ //! <b>Note</b>: Non-standard extensions
+ node_pointer release() BOOST_NOEXCEPT
+ {
+ node_pointer p(m_ptr);
+ m_ptr = node_pointer();
+ if(p)
+ this->destroy_alloc();
+ return p;
+ }
+
+ //! <b>Effects</b>: Returns m_ptr.
+ //!
+ //! <b>Note</b>: Non-standard extensions
+ node_pointer get() const BOOST_NOEXCEPT
+ {
+ return m_ptr;
+ }
+
+ //! <b>Effects</b>: Returns a reference to the internal node allocator.
+ //!
+ //! <b>Note</b>: Non-standard extensions
+ nallocator_type &node_alloc() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(!empty());
+ return *static_cast<nallocator_type*>(m_nalloc_storage.address());
+ }
+
+
+ //! <b>Effects</b>: Returns a reference to the internal node allocator.
+ //!
+ //! <b>Note</b>: Non-standard extensions
+ const nallocator_type &node_alloc() const BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(!empty());
+ return *static_cast<const nallocator_type*>(m_nalloc_storage.address());
+ }
+
//! <b>Effects</b>: x.swap(y).
//!
friend void swap(node_handle & x, node_handle & y) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y)))
diff --git a/boost/container/set.hpp b/boost/container/set.hpp
index 5cf0f964a5..8730b1c89a 100644
--- a/boost/container/set.hpp
+++ b/boost/container/set.hpp
@@ -112,46 +112,103 @@ class set
//! <b>Effects</b>: Default constructs an empty set.
//!
//! <b>Complexity</b>: Constant.
- set() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
- container_detail::is_nothrow_default_constructible<Compare>::value)
+
+ BOOST_CONTAINER_FORCEINLINE set()
+ BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
+ container_detail::is_nothrow_default_constructible<Compare>::value)
: base_t()
{}
+ //! <b>Effects</b>: Constructs an empty set using the specified allocator object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE explicit set(const allocator_type& a)
+ : base_t(a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ BOOST_CONTAINER_FORCEINLINE explicit set(const Compare& comp)
+ : base_t(comp)
+ {}
+
//! <b>Effects</b>: Constructs an empty set using the specified comparison object
//! and allocator.
//!
//! <b>Complexity</b>: Constant.
- explicit set(const Compare& comp,
- const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE set(const Compare& comp, const allocator_type& a)
: base_t(comp, a)
{}
- //! <b>Effects</b>: Constructs an empty set using the specified allocator object.
+ //! <b>Effects</b>: Constructs an empty set using and
+ //! inserts elements from the range [first ,last ).
//!
- //! <b>Complexity</b>: Constant.
- explicit set(const allocator_type& a)
- : base_t(a)
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! the predicate and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last)
+ : base_t(true, first, last)
{}
- //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+ //! <b>Effects</b>: Constructs an empty set using the specified
//! allocator, and inserts elements from the range [first ,last ).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
+ //! the predicate and otherwise N logN, where N is last - first.
template <class InputIterator>
- set(InputIterator first, InputIterator last, const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
- : base_t(true, first, last, comp, a)
+ BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last, const allocator_type& a)
+ : base_t(true, first, last, key_compare(), a)
{}
- //! <b>Effects</b>: Constructs an empty set using the specified
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+ //! inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! the predicate and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last, const Compare& comp)
+ : base_t(true, first, last, comp)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
//! allocator, and inserts elements from the range [first ,last ).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
+ //! the predicate and otherwise N logN, where N is last - first.
template <class InputIterator>
- set(InputIterator first, InputIterator last, const allocator_type& a)
- : base_t(true, first, last, key_compare(), a)
+ BOOST_CONTAINER_FORCEINLINE set(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
+ : base_t(true, first, last, comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty set and
+ //! inserts elements from the ordered unique range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, InputIterator first, InputIterator last)
+ : base_t(ordered_range, first, last)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+ //! inserts elements from the ordered unique range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp )
+ : base_t(ordered_range, first, last, comp)
{}
//! <b>Effects</b>: Constructs an empty set using the specified comparison object and
@@ -165,31 +222,77 @@ class set
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
- set( ordered_unique_range_t, InputIterator first, InputIterator last
- , const Compare& comp = Compare(), const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, InputIterator first, InputIterator last
+ , const Compare& comp, const allocator_type& a)
: base_t(ordered_range, first, last, comp, a)
{}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
- //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
- //! allocator, and inserts elements from the range [il.begin(), il.end()).
+ //! <b>Effects</b>: Constructs an empty set and
+ //! inserts elements from the range [il.begin(), il.end()).
//!
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
- //! comp and otherwise N logN, where N is il.begin() - il.end().
- set(std::initializer_list<value_type> il, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
- : base_t(true, il.begin(), il.end(), comp, a)
+ //! the predicate and otherwise N logN, where N is il.begin() - il.end().
+ BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il)
+ : base_t(true, il.begin(), il.end())
{}
//! <b>Effects</b>: Constructs an empty set using the specified
//! allocator, and inserts elements from the range [il.begin(), il.end()).
//!
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
- //! comp and otherwise N logN, where N is il.begin() - il.end().
- set(std::initializer_list<value_type> il, const allocator_type& a)
+ //! the predicate and otherwise N logN, where N is il.begin() - il.end().
+ BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il, const allocator_type& a)
: base_t(true, il.begin(), il.end(), Compare(), a)
{}
//! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+ //! inserts elements from the range [il.begin(), il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+ //! the predicate and otherwise N logN, where N is il.begin() - il.end().
+ BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il, const Compare& comp )
+ : base_t(true, il.begin(), il.end(), comp)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+ //! allocator, and inserts elements from the range [il.begin(), il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+ //! the predicate and otherwise N logN, where N is il.begin() - il.end().
+ BOOST_CONTAINER_FORCEINLINE set(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+ : base_t(true, il.begin(), il.end(), comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty set and
+ //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, std::initializer_list<value_type> il)
+ : base_t(ordered_range, il.begin(), il.end())
+ {}
+
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+ //! inserts elements from the ordered unique range [il.begin(), il.end()). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp)
+ : base_t(ordered_range, il.begin(), il.end(), comp)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
//! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
//! is more efficient than the normal range creation for ordered ranges.
//!
@@ -199,8 +302,7 @@ class set
//! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
- set( ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare()
- , const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE set( ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
: base_t(ordered_range, il.begin(), il.end(), comp, a)
{}
#endif
@@ -208,7 +310,7 @@ class set
//! <b>Effects</b>: Copy constructs a set.
//!
//! <b>Complexity</b>: Linear in x.size().
- set(const set& x)
+ BOOST_CONTAINER_FORCEINLINE set(const set& x)
: base_t(static_cast<const base_t&>(x))
{}
@@ -217,7 +319,7 @@ class set
//! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
- set(BOOST_RV_REF(set) x)
+ BOOST_CONTAINER_FORCEINLINE set(BOOST_RV_REF(set) x)
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
: base_t(BOOST_MOVE_BASE(base_t, x))
{}
@@ -225,7 +327,7 @@ class set
//! <b>Effects</b>: Copy constructs a set using the specified allocator.
//!
//! <b>Complexity</b>: Linear in x.size().
- set(const set& x, const allocator_type &a)
+ BOOST_CONTAINER_FORCEINLINE set(const set& x, const allocator_type &a)
: base_t(static_cast<const base_t&>(x), a)
{}
@@ -233,14 +335,14 @@ class set
//! Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
- set(BOOST_RV_REF(set) x, const allocator_type &a)
+ BOOST_CONTAINER_FORCEINLINE set(BOOST_RV_REF(set) x, const allocator_type &a)
: base_t(BOOST_MOVE_BASE(base_t, x), a)
{}
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().
- set& operator=(BOOST_COPY_ASSIGN_REF(set) x)
+ BOOST_CONTAINER_FORCEINLINE set& operator=(BOOST_COPY_ASSIGN_REF(set) x)
{ return static_cast<set&>(this->base_t::operator=(static_cast<const base_t&>(x))); }
//! <b>Effects</b>: this->swap(x.get()).
@@ -251,7 +353,7 @@ class set
//! <b>Complexity</b>: Constant if allocator_traits_type::
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
- set& operator=(BOOST_RV_REF(set) x)
+ BOOST_CONTAINER_FORCEINLINE set& operator=(BOOST_RV_REF(set) x)
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
allocator_traits_type::is_always_equal::value) &&
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
@@ -424,7 +526,7 @@ class set
//!
//! <b>Complexity</b>: Logarithmic.
template <class... Args>
- std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
+ BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_unique(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type Key constructed with
@@ -437,18 +539,18 @@ class set
//!
//! <b>Complexity</b>: Logarithmic.
template <class... Args>
- iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
+ BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_unique(p, boost::forward<Args>(args)...); }
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_CONTAINER_SET_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
- std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
+ BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
- iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SET_EMPLACE_CODE)
@@ -513,7 +615,7 @@ class set
//!
//! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
+ BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
{ this->base_t::insert_unique(first, last); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -521,16 +623,16 @@ class set
//! if there is no element with key equivalent to the key of that element.
//!
//! <b>Complexity</b>: At most N log(size()+N) (N is the distance from il.begin() to il.end())
- void insert(std::initializer_list<value_type> il)
+ BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
{ this->base_t::insert_unique(il.begin(), il.end()); }
#endif
//! @copydoc ::boost::container::map::insert(node_type&&)
- insert_return_type insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+ BOOST_CONTAINER_FORCEINLINE insert_return_type insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
{ return this->base_t::insert_unique_node(boost::move(nh)); }
//! @copydoc ::boost::container::map::insert(const_iterator, node_type&&)
- insert_return_type insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+ BOOST_CONTAINER_FORCEINLINE insert_return_type insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
{ return this->base_t::insert_unique_node(hint, boost::move(nh)); }
//! @copydoc ::boost::container::map::merge(map<Key, T, C2, Allocator, Options>&)
@@ -586,6 +688,12 @@ class set
//! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
iterator erase(const_iterator first, const_iterator last);
+ //! @copydoc ::boost::container::map::extract(const_iterator)
+ node_type extract(const_iterator p);
+
+ //! @copydoc ::boost::container::map::extract(const key_type&)
+ node_type extract(const key_type& x);
+
//! <b>Effects</b>: Swaps the contents of *this and x.
//!
//! <b>Throws</b>: Nothing.
@@ -631,13 +739,13 @@ class set
//! <b>Returns</b>: The number of elements with key equivalent to x.
//!
//! <b>Complexity</b>: log(size())+count(k)
- size_type count(const key_type& x) const
+ BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) const
{ return static_cast<size_type>(this->base_t::find(x) != this->base_t::cend()); }
//! <b>Returns</b>: The number of elements with key equivalent to x.
//!
//! <b>Complexity</b>: log(size())+count(k)
- size_type count(const key_type& x)
+ BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x)
{ return static_cast<size_type>(this->base_t::find(x) != this->base_t::end()); }
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -671,13 +779,13 @@ class set
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic
- std::pair<iterator,iterator> equal_range(const key_type& x)
+ BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& x)
{ return this->base_t::lower_bound_range(x); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic
- std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
+ BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
{ return this->base_t::lower_bound_range(x); }
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -737,11 +845,11 @@ class set
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
template <class KeyType>
- std::pair<iterator, bool> priv_insert(BOOST_FWD_REF(KeyType) x)
+ BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> priv_insert(BOOST_FWD_REF(KeyType) x)
{ return this->base_t::insert_unique(::boost::forward<KeyType>(x)); }
template <class KeyType>
- iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
+ BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
{ return this->base_t::insert_unique(p, ::boost::forward<KeyType>(x)); }
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
@@ -829,34 +937,77 @@ class multiset
//////////////////////////////////////////////
//! @copydoc ::boost::container::set::set()
- multiset() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
- container_detail::is_nothrow_default_constructible<Compare>::value)
+ BOOST_CONTAINER_FORCEINLINE multiset()
+ BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
+ container_detail::is_nothrow_default_constructible<Compare>::value)
: base_t()
{}
+ //! @copydoc ::boost::container::set::set(const allocator_type&)
+ BOOST_CONTAINER_FORCEINLINE explicit multiset(const allocator_type& a)
+ : base_t(a)
+ {}
+
+ //! @copydoc ::boost::container::set::set(const Compare&)
+ BOOST_CONTAINER_FORCEINLINE explicit multiset(const Compare& comp)
+ : base_t(comp)
+ {}
+
//! @copydoc ::boost::container::set::set(const Compare&, const allocator_type&)
- explicit multiset(const Compare& comp,
- const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE multiset(const Compare& comp, const allocator_type& a)
: base_t(comp, a)
{}
- //! @copydoc ::boost::container::set::set(const allocator_type&)
- explicit multiset(const allocator_type& a)
- : base_t(a)
+ //! @copydoc ::boost::container::set::set(InputIterator, InputIterator)
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last)
+ : base_t(false, first, last)
+ {}
+
+ //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const allocator_type&)
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last, const allocator_type& a)
+ : base_t(false, first, last, key_compare(), a)
{}
- //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const Compare& comp, const allocator_type&)
+ //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const Compare&)
template <class InputIterator>
- multiset(InputIterator first, InputIterator last,
- const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last, const Compare& comp)
+ : base_t(false, first, last, comp)
+ {}
+
+ //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const Compare&, const allocator_type&)
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE multiset(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
: base_t(false, first, last, comp, a)
{}
- //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const allocator_type&)
+ //! <b>Effects</b>: Constructs an empty multiset and
+ //! and inserts elements from the ordered range [first ,last ). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
template <class InputIterator>
- multiset(InputIterator first, InputIterator last, const allocator_type& a)
- : base_t(false, first, last, key_compare(), a)
+ BOOST_CONTAINER_FORCEINLINE multiset( ordered_range_t, InputIterator first, InputIterator last )
+ : base_t(ordered_range, first, last)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty multiset using the specified comparison object and
+ //! inserts elements from the ordered range [first ,last ). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ template <class InputIterator>
+ BOOST_CONTAINER_FORCEINLINE multiset( ordered_range_t, InputIterator first, InputIterator last, const Compare& comp)
+ : base_t(ordered_range, first, last, comp)
{}
//! <b>Effects</b>: Constructs an empty multiset using the specified comparison object and
@@ -869,56 +1020,74 @@ class multiset
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
- multiset( ordered_range_t, InputIterator first, InputIterator last
- , const Compare& comp = Compare()
- , const allocator_type& a = allocator_type())
+ BOOST_CONTAINER_FORCEINLINE multiset( ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
: base_t(ordered_range, first, last, comp, a)
{}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
- //! @copydoc ::boost::container::set::set(std::initializer_list<value_type>, const Compare& comp, const allocator_type&)
- multiset(std::initializer_list<value_type> il, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
- : base_t(false, il.begin(), il.end(), comp, a)
+ //! @copydoc ::boost::container::set::set(std::initializer_list<value_type>)
+ BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il)
+ : base_t(false, il.begin(), il.end())
{}
//! @copydoc ::boost::container::set::set(std::initializer_list<value_type>, const allocator_type&)
- multiset(std::initializer_list<value_type> il, const allocator_type& a)
+ BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il, const allocator_type& a)
: base_t(false, il.begin(), il.end(), Compare(), a)
{}
- //! @copydoc ::boost::container::set::set(ordered_unique_range_t, std::initializer_list<value_type>, const Compare& comp, const allocator_type&)
- multiset(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
+ //! @copydoc ::boost::container::set::set(std::initializer_list<value_type>, const Compare&)
+ BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il, const Compare& comp)
+ : base_t(false, il.begin(), il.end(), comp)
+ {}
+
+ //! @copydoc ::boost::container::set::set(std::initializer_list<value_type>, const Compare&, const allocator_type&)
+ BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
+ : base_t(false, il.begin(), il.end(), comp, a)
+ {}
+
+ //! @copydoc ::boost::container::set::set(ordered_unique_range_t, std::initializer_list<value_type>)
+ BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, std::initializer_list<value_type> il)
+ : base_t(ordered_range, il.begin(), il.end())
+ {}
+
+ //! @copydoc ::boost::container::set::set(ordered_unique_range_t, std::initializer_list<value_type>, const Compare&)
+ BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp)
+ : base_t(ordered_range, il.begin(), il.end(), comp)
+ {}
+
+ //! @copydoc ::boost::container::set::set(ordered_unique_range_t, std::initializer_list<value_type>, const Compare&, const allocator_type&)
+ BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
: base_t(ordered_range, il.begin(), il.end(), comp, a)
{}
#endif
//! @copydoc ::boost::container::set::set(const set &)
- multiset(const multiset& x)
+ BOOST_CONTAINER_FORCEINLINE multiset(const multiset& x)
: base_t(static_cast<const base_t&>(x))
{}
//! @copydoc ::boost::container::set::set(set &&)
- multiset(BOOST_RV_REF(multiset) x)
+ BOOST_CONTAINER_FORCEINLINE multiset(BOOST_RV_REF(multiset) x)
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
: base_t(BOOST_MOVE_BASE(base_t, x))
{}
//! @copydoc ::boost::container::set::set(const set &, const allocator_type &)
- multiset(const multiset& x, const allocator_type &a)
+ BOOST_CONTAINER_FORCEINLINE multiset(const multiset& x, const allocator_type &a)
: base_t(static_cast<const base_t&>(x), a)
{}
//! @copydoc ::boost::container::set::set(set &&, const allocator_type &)
- multiset(BOOST_RV_REF(multiset) x, const allocator_type &a)
+ BOOST_CONTAINER_FORCEINLINE multiset(BOOST_RV_REF(multiset) x, const allocator_type &a)
: base_t(BOOST_MOVE_BASE(base_t, x), a)
{}
//! @copydoc ::boost::container::set::operator=(const set &)
- multiset& operator=(BOOST_COPY_ASSIGN_REF(multiset) x)
+ BOOST_CONTAINER_FORCEINLINE multiset& operator=(BOOST_COPY_ASSIGN_REF(multiset) x)
{ return static_cast<multiset&>(this->base_t::operator=(static_cast<const base_t&>(x))); }
//! @copydoc ::boost::container::set::operator=(set &&)
- multiset& operator=(BOOST_RV_REF(multiset) x)
+ BOOST_CONTAINER_FORCEINLINE multiset& operator=(BOOST_RV_REF(multiset) x)
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
allocator_traits_type::is_always_equal::value) &&
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
@@ -999,7 +1168,7 @@ class multiset
//!
//! <b>Complexity</b>: Logarithmic.
template <class... Args>
- iterator emplace(BOOST_FWD_REF(Args)... args)
+ BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_equal(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type Key constructed with
@@ -1011,18 +1180,18 @@ class multiset
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
template <class... Args>
- iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
+ BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_equal(p, boost::forward<Args>(args)...); }
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_CONTAINER_MULTISET_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
- iterator emplace(BOOST_MOVE_UREF##N)\
+ BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
- iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{ return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MULTISET_EMPLACE_CODE)
@@ -1079,21 +1248,21 @@ class multiset
//!
//! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
+ BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
{ this->base_t::insert_equal(first, last); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! @copydoc ::boost::container::set::insert(std::initializer_list<value_type>)
- void insert(std::initializer_list<value_type> il)
+ BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
{ this->base_t::insert_equal(il.begin(), il.end()); }
#endif
//! @copydoc ::boost::container::multimap::insert(node_type&&)
- iterator insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+ BOOST_CONTAINER_FORCEINLINE iterator insert(BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
{ return this->base_t::insert_equal_node(boost::move(nh)); }
//! @copydoc ::boost::container::multimap::insert(const_iterator, node_type&&)
- iterator insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
+ BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
{ return this->base_t::insert_equal_node(hint, boost::move(nh)); }
//! @copydoc ::boost::container::multimap::merge(multimap<Key, T, C2, Allocator, Options>&)
@@ -1135,6 +1304,12 @@ class multiset
//! @copydoc ::boost::container::set::erase(const_iterator,const_iterator)
iterator erase(const_iterator first, const_iterator last);
+ //! @copydoc ::boost::container::multimap::extract(const_iterator)
+ node_type extract(const_iterator p);
+
+ //! @copydoc ::boost::container::multimap::extract(const key_type&)
+ node_type extract(const key_type& x);
+
//! @copydoc ::boost::container::set::swap
void swap(multiset& x)
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
@@ -1219,11 +1394,11 @@ class multiset
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
template <class KeyType>
- iterator priv_insert(BOOST_FWD_REF(KeyType) x)
+ BOOST_CONTAINER_FORCEINLINE iterator priv_insert(BOOST_FWD_REF(KeyType) x)
{ return this->base_t::insert_equal(::boost::forward<KeyType>(x)); }
template <class KeyType>
- iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
+ BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
{ return this->base_t::insert_equal(p, ::boost::forward<KeyType>(x)); }
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
diff --git a/boost/container/small_vector.hpp b/boost/container/small_vector.hpp
index 14446247ac..804740cc72 100644
--- a/boost/container/small_vector.hpp
+++ b/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/boost/container/stable_vector.hpp b/boost/container/stable_vector.hpp
index 5d6dc0f228..cf156e04de 100644
--- a/boost/container/stable_vector.hpp
+++ b/boost/container/stable_vector.hpp
@@ -44,7 +44,7 @@
#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/placement_new.hpp>
-#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
#include <boost/container/detail/type_traits.hpp>
// intrusive
#include <boost/intrusive/pointer_traits.hpp>
@@ -1975,7 +1975,7 @@ class stable_vector
, container_detail::addressof(p->value)
, it);
//This does not throw
- ::new(static_cast<node_base_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t())
+ ::new(static_cast<node_base_type*>(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<ValueConvertible>(value_convertible));
//This does not throw
- ::new(static_cast<node_base_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) node_base_type;
+ ::new(static_cast<node_base_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) node_base_type;
}
void priv_swap_members(stable_vector &x)
diff --git a/boost/container/string.hpp b/boost/container/string.hpp
index 7b780fd588..24056781c9 100644
--- a/boost/container/string.hpp
+++ b/boost/container/string.hpp
@@ -35,10 +35,11 @@
#include <boost/container/detail/min_max.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/next_capacity.hpp>
-#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/minimal_char_traits_header.hpp>
+#include <boost/container/detail/algorithm.hpp>
#include <boost/intrusive/pointer_traits.hpp>
@@ -51,7 +52,6 @@
#include <boost/functional/hash.hpp>
#include <algorithm>
-#include <functional> //bind2nd, etc.
#include <iosfwd>
#include <istream>
#include <ostream>
@@ -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)
);
}
@@ -541,8 +541,8 @@ class basic_string
bool operator()(const typename Tr::char_type& x) const
{
- return std::find_if(m_first, m_last,
- std::bind1st(Eq_traits<Tr>(), x)) == m_last;
+ return boost::container::find_if(m_first, m_last,
+ boost::container::bind1st(Eq_traits<Tr>(), x)) == m_last;
}
};
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -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<size_type>(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<CharT*>(container_detail::to_raw_pointer(p + n)),
- container_detail::to_raw_pointer(p),
+ Traits::move(const_cast<CharT*>(boost::movelib::to_raw_pointer(p + n)),
+ boost::movelib::to_raw_pointer(p),
(elems_after - n) + 1);
- this->priv_copy(first, last, const_cast<CharT*>(container_detail::to_raw_pointer(p)));
+ this->priv_copy(first, last, const_cast<CharT*>(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<CharT*>(container_detail::to_raw_pointer(p)));
+ this->priv_copy(first, mid, const_cast<CharT*>(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<T>
- 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<CharT*>(container_detail::to_raw_pointer(p));
+ CharT * const ptr = const_cast<CharT*>(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<CharT*>(container_detail::to_raw_pointer(first));
+ CharT * f = const_cast<CharT*>(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<size_type>(i2 - i1);
if (len >= n) {
- Traits::assign(const_cast<CharT*>(container_detail::to_raw_pointer(i1)), n, c);
+ Traits::assign(const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)), n, c);
erase(i1 + n, i2);
}
else {
- Traits::assign(const_cast<CharT*>(container_detail::to_raw_pointer(i1)), len, c);
+ Traits::assign(const_cast<CharT*>(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<CharT*>(container_detail::to_raw_pointer(i1)), *j1);
+ Traits::assign(*const_cast<CharT*>(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<CharT*>(container_detail::to_raw_pointer(i1)));
+ this->priv_copy(j1, j2, const_cast<CharT*>(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<CharT*>(container_detail::to_raw_pointer(i1)));
+ this->priv_copy(j1, m, const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)));
this->insert(i2, m, j2);
}
return *this;
@@ -2128,7 +2128,7 @@ class basic_string
//!
//! <b>Effects</b>: Calls `replace(i1 - begin(), i2 - i1, sv).`.
//!
- //! <bReturns</b>: *this.
+ //! <b>Returns</b>: *this.
template<template <class, class> class BasicStringView>
basic_string& replace(const_iterator i1, const_iterator i2, BasicStringView<CharT, Traits> sv)
{
@@ -2141,7 +2141,7 @@ class basic_string
//!
//! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, il.begin(), il.size()).
//!
- //! <bReturns</b>: *this.
+ //! <b>Returns</b>: *this.
basic_string& replace(const_iterator i1, const_iterator i2, std::initializer_list<CharT> il)
{
return this->replace( static_cast<size_type>(i1 - this->cbegin())
@@ -2166,7 +2166,7 @@ class basic_string
if (pos > this->size())
throw_out_of_range("basic_string::copy out of range position");
const size_type len = container_detail::min_value(n, this->size() - pos);
- Traits::copy(s, container_detail::to_raw_pointer(this->priv_addr() + pos), len);
+ Traits::copy(s, boost::movelib::to_raw_pointer(this->priv_addr() + pos), len);
return len;
}
@@ -2195,7 +2195,7 @@ class basic_string
//!
//! <b>Complexity</b>: constant time.
const CharT* c_str() const BOOST_NOEXCEPT_OR_NOTHROW
- { return container_detail::to_raw_pointer(this->priv_addr()); }
+ { return boost::movelib::to_raw_pointer(this->priv_addr()); }
//! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
//!
@@ -2203,13 +2203,13 @@ class basic_string
//!
//! <b>Complexity</b>: constant time.
const CharT* data() const BOOST_NOEXCEPT_OR_NOTHROW
- { return container_detail::to_raw_pointer(this->priv_addr()); }
+ { return boost::movelib::to_raw_pointer(this->priv_addr()); }
//! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
//!
//! <b>Complexity</b>: constant time.
CharT* data() BOOST_NOEXCEPT_OR_NOTHROW
- { return container_detail::to_raw_pointer(this->priv_addr()); }
+ { return boost::movelib::to_raw_pointer(this->priv_addr()); }
#ifndef BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN
//! <b>Returns</b>: a string_view to the characters in the string.
@@ -2272,8 +2272,8 @@ class basic_string
const pointer addr = this->priv_addr();
pointer finish = addr + this->priv_size();
const const_iterator result =
- std::search(container_detail::to_raw_pointer(addr + pos),
- container_detail::to_raw_pointer(finish),
+ boost::container::search(boost::movelib::to_raw_pointer(addr + pos),
+ boost::movelib::to_raw_pointer(finish),
s, s + n, Eq_traits<Traits>());
return result != finish ? result - begin() : npos;
}
@@ -2299,8 +2299,8 @@ class basic_string
const pointer addr = this->priv_addr();
pointer finish = addr + sz;
const const_iterator result =
- std::find_if(addr + pos, finish,
- std::bind2nd(Eq_traits<Traits>(), c));
+ boost::container::find_if(addr + pos, finish,
+ boost::container::bind2nd(Eq_traits<Traits>(), c));
return result != finish ? result - begin() : npos;
}
}
@@ -2371,8 +2371,8 @@ class basic_string
else {
const const_iterator last = begin() + container_detail::min_value(len - 1, pos) + 1;
const_reverse_iterator rresult =
- std::find_if(const_reverse_iterator(last), rend(),
- std::bind2nd(Eq_traits<Traits>(), c));
+ boost::container::find_if(const_reverse_iterator(last), rend(),
+ boost::container::bind2nd(Eq_traits<Traits>(), c));
return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
}
}
@@ -2385,7 +2385,7 @@ class basic_string
//!
//! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
size_type find_first_of(const basic_string& str, size_type pos = 0) const
- { return find_first_of(str.c_str(), pos, str.size()); }
+ { return this->find_first_of(str.c_str(), pos, str.size()); }
//! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both of the
//! following conditions obtain: a) pos <= xpos and xpos < size();
@@ -2396,7 +2396,7 @@ class basic_string
//! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
template<template <class, class> class BasicStringView>
size_type find_first_of(BasicStringView<CharT, Traits> sv, size_type pos = 0) const
- { return find_first_of(sv.data(), pos, sv.size()); }
+ { return this->find_first_of(sv.data(), pos, sv.size()); }
//! <b>Requires</b>: s points to an array of at least n elements of CharT.
//!
@@ -2411,7 +2411,7 @@ class basic_string
else {
const pointer addr = this->priv_addr();
pointer finish = addr + sz;
- const_iterator result = std::find_first_of
+ const_iterator result = boost::container::find_first_of
(addr + pos, finish, s, s + n, Eq_traits<Traits>());
return result != finish ? result - this->begin() : npos;
}
@@ -2423,7 +2423,7 @@ class basic_string
//!
//! <b>Returns</b>: find_first_of(basic_string(s), pos).
size_type find_first_of(const CharT* s, size_type pos = 0) const
- { return find_first_of(s, pos, Traits::length(s)); }
+ { return this->find_first_of(s, pos, Traits::length(s)); }
//! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
//!
@@ -2431,7 +2431,7 @@ class basic_string
//!
//! <b>Returns</b>: find_first_of(basic_string<CharT,traits,Allocator>(1,c), pos).
size_type find_first_of(CharT c, size_type pos = 0) const
- { return find(c, pos); }
+ { return this->find(c, pos); }
//! <b>Effects</b>: Determines the highest position xpos, if possible, such that both of
//! the following conditions obtain: a) xpos <= pos and xpos < size(); b)
@@ -2441,7 +2441,7 @@ class basic_string
//!
//! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
size_type find_last_of(const basic_string& str, size_type pos = npos) const
- { return find_last_of(str.c_str(), pos, str.size()); }
+ { return this->find_last_of(str.c_str(), pos, str.size()); }
//! <b>Effects</b>: Determines the highest position xpos, if possible, such that both of
//! the following conditions obtain: a) xpos <= pos and xpos < size(); b)
@@ -2452,7 +2452,7 @@ class basic_string
//! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
template<template <class, class> class BasicStringView>
size_type find_last_of(BasicStringView<CharT, Traits> sv, size_type pos = npos) const
- { return find_last_of(sv.data(), pos, sv.size()); }
+ { return this->find_last_of(sv.data(), pos, sv.size()); }
//! <b>Requires</b>: s points to an array of at least n elements of CharT.
//!
@@ -2469,7 +2469,7 @@ class basic_string
const pointer addr = this->priv_addr();
const const_iterator last = addr + container_detail::min_value(len - 1, pos) + 1;
const const_reverse_iterator rresult =
- std::find_first_of(const_reverse_iterator(last), rend(),
+ boost::container::find_first_of(const_reverse_iterator(last), rend(),
s, s + n, Eq_traits<Traits>());
return rresult != rend() ? (rresult.base() - 1) - addr : npos;
}
@@ -2524,7 +2524,7 @@ class basic_string
else {
const pointer addr = this->priv_addr();
const pointer finish = addr + this->priv_size();
- const const_iterator result = std::find_if
+ const const_iterator result = boost::container::find_if
(addr + pos, finish, Not_within_traits<Traits>(s, s + n));
return result != finish ? result - addr : npos;
}
@@ -2549,8 +2549,8 @@ class basic_string
const pointer addr = this->priv_addr();
const pointer finish = addr + this->priv_size();
const const_iterator result
- = std::find_if(addr + pos, finish,
- std::not1(std::bind2nd(Eq_traits<Traits>(), c)));
+ = boost::container::find_if(addr + pos, finish,
+ boost::container::not1(boost::container::bind2nd(Eq_traits<Traits>(), c)));
return result != finish ? result - begin() : npos;
}
}
@@ -2590,7 +2590,7 @@ class basic_string
else {
const const_iterator last = begin() + container_detail::min_value(len - 1, pos) + 1;
const const_reverse_iterator rresult =
- std::find_if(const_reverse_iterator(last), rend(),
+ boost::container::find_if(const_reverse_iterator(last), rend(),
Not_within_traits<Traits>(s, s + n));
return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
}
@@ -2616,8 +2616,8 @@ class basic_string
else {
const const_iterator last = begin() + container_detail::min_value(len - 1, pos) + 1;
const const_reverse_iterator rresult =
- std::find_if(const_reverse_iterator(last), rend(),
- std::not1(std::bind2nd(Eq_traits<Traits>(), c)));
+ boost::container::find_if(const_reverse_iterator(last), rend(),
+ boost::container::not1(boost::container::bind2nd(Eq_traits<Traits>(), c)));
return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
}
}
@@ -2804,8 +2804,8 @@ class basic_string
{
const difference_type n1 = l1 - f1;
const difference_type n2 = l2 - f2;
- const int cmp = Traits::compare(container_detail::to_raw_pointer(f1),
- container_detail::to_raw_pointer(f2),
+ const int cmp = Traits::compare(boost::movelib::to_raw_pointer(f1),
+ boost::movelib::to_raw_pointer(f2),
container_detail::min_value(n1, n2));
return cmp != 0 ? cmp : (n1 < n2 ? -1 : (n1 > n2 ? 1 : 0));
}
@@ -2826,8 +2826,8 @@ class basic_string
real_cap = long_size+1;
const pointer ret = this->allocation_command(allocate_new, long_size+1, real_cap, reuse);
//Copy and update
- Traits::copy( container_detail::to_raw_pointer(ret)
- , container_detail::to_raw_pointer(this->priv_long_addr())
+ Traits::copy( boost::movelib::to_raw_pointer(ret)
+ , boost::movelib::to_raw_pointer(this->priv_long_addr())
, long_size+1);
this->priv_long_addr(ret);
this->priv_storage(real_cap);
diff --git a/boost/container/vector.hpp b/boost/container/vector.hpp
index 336d616007..5ec669ba99 100644
--- a/boost/container/vector.hpp
+++ b/boost/container/vector.hpp
@@ -36,10 +36,10 @@
#include <boost/container/detail/destroyers.hpp>
#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/iterators.hpp>
-#include <boost/container/detail/iterator_to_raw_pointer.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/next_capacity.hpp>
-#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/version_type.hpp>
// intrusive
@@ -54,6 +54,10 @@
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <boost/move/detail/move_helpers.hpp>
+// move/algo
+#include <boost/move/algo/adaptive_merge.hpp>
+#include <boost/move/algo/unique.hpp>
+#include <boost/move/algo/predicate.hpp>
// other
#include <boost/core/no_exceptions_support.hpp>
#include <boost/assert.hpp>
@@ -609,7 +613,7 @@ struct vector_alloc_holder<Allocator, version_0>
, m_size(holder.m_size) //Size is initialized here so vector should only call uninitialized_xxx after this
{
::boost::container::uninitialized_move_alloc_n
- (this->alloc(), container_detail::to_raw_pointer(holder.start()), m_size, container_detail::to_raw_pointer(this->start()));
+ (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), m_size, boost::movelib::to_raw_pointer(this->start()));
}
template<class OtherAllocator, class OtherAllocatorVersion>
@@ -621,7 +625,7 @@ struct vector_alloc_holder<Allocator, version_0>
const size_type n = holder.m_size;
this->priv_first_allocation(n);
::boost::container::uninitialized_move_alloc_n
- (this->alloc(), container_detail::to_raw_pointer(holder.start()), n, container_detail::to_raw_pointer(this->start()));
+ (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), n, boost::movelib::to_raw_pointer(this->start()));
}
BOOST_CONTAINER_FORCEINLINE void priv_first_allocation(size_type cap)
@@ -675,8 +679,8 @@ struct vector_alloc_holder<Allocator, version_0>
void priv_deep_swap(vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> &x)
{
const size_type MaxTmpStorage = sizeof(value_type)*Allocator::internal_capacity;
- value_type *const first_this = container_detail::to_raw_pointer(this->start());
- value_type *const first_x = container_detail::to_raw_pointer(x.start());
+ value_type *const first_this = boost::movelib::to_raw_pointer(this->start());
+ value_type *const first_x = boost::movelib::to_raw_pointer(x.start());
if(this->m_size < x.m_size){
boost::container::deep_swap_alloc_n<MaxTmpStorage>(this->alloc(), first_this, this->m_size, first_x, x.m_size);
@@ -1186,7 +1190,7 @@ class vector
if (first == last){
//There are no more elements in the sequence, erase remaining
T* const end_pos = this->priv_raw_end();
- const size_type n = static_cast<size_type>(end_pos - container_detail::iterator_to_raw_pointer(cur));
+ const size_type n = static_cast<size_type>(end_pos - boost::movelib::iterator_to_raw_pointer(cur));
this->priv_destroy_last_n(n);
}
else{
@@ -2005,7 +2009,7 @@ class vector
{
BOOST_ASSERT(this->priv_in_range(position));
const pointer p = vector_iterator_get_ptr(position);
- T *const pos_ptr = container_detail::to_raw_pointer(p);
+ T *const pos_ptr = boost::movelib::to_raw_pointer(p);
T *const beg_ptr = this->priv_raw_begin();
T *const new_end_ptr = ::boost::container::move(pos_ptr + 1, beg_ptr + this->m_holder.m_size, pos_ptr);
//Move elements forward and destroy last
@@ -2025,9 +2029,9 @@ class vector
(first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last)));
if (first != last){
T* const old_end_ptr = this->priv_raw_end();
- T* const first_ptr = container_detail::to_raw_pointer(vector_iterator_get_ptr(first));
- T* const last_ptr = container_detail::to_raw_pointer(vector_iterator_get_ptr(last));
- T* const ptr = container_detail::to_raw_pointer(boost::container::move(last_ptr, old_end_ptr, first_ptr));
+ T* const first_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(first));
+ T* const last_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(last));
+ T* const ptr = boost::movelib::to_raw_pointer(boost::container::move(last_ptr, old_end_ptr, first_ptr));
this->priv_destroy_last_n(old_end_ptr - ptr);
}
return iterator(vector_iterator_get_ptr(first));
@@ -2240,37 +2244,15 @@ class vector
p = this->m_holder.allocation_command(allocate_new, new_size, new_cap, p);
this->priv_merge_in_new_buffer(UniqueBool(), first, n, comp, p, new_cap);
}
- else if(!UniqueBool::value && free_c >= n){
- typedef container_detail::vector_merge_cursor<T, size_type, BidirIt, Compare> inserter_t;
- T* const pbeg = this->priv_raw_begin();
- return this->priv_insert_ordered_at(n, inserter_t(pbeg, pbeg + s, last, comp));
- }
- else{ //UniqueBool::value == true and free_c >= n
- std::size_t remaining = n;
- static const std::size_t PosCount = 64u;
- size_type positions[PosCount];
- size_type *indexes = 0;
- while(remaining){
- //Query for room to store indexes in the remaining buffer
- boost::uintptr_t const szt_align_mask = container_detail::alignment_of<size_type>::value - 1;
- boost::uintptr_t const addr = boost::uintptr_t(this->priv_raw_begin() + s + n);
- boost::uintptr_t const capaddr = boost::uintptr_t(this->priv_raw_begin() + c);
- boost::uintptr_t const aligned_addr = (addr + szt_align_mask) & ~szt_align_mask;
- indexes = reinterpret_cast<size_type *>(aligned_addr);
- std::size_t index_capacity = (aligned_addr >= capaddr) ? 0u : (capaddr - aligned_addr)/sizeof(size_type);
-
- //Capacity is constant, we're not going to change it
- if(index_capacity < PosCount){
- indexes = positions;
- index_capacity = PosCount;
- }
- if(index_capacity > remaining)
- index_capacity = remaining;
- BidirIt limit = first;
- boost::container::iterator_advance(limit, index_capacity);
- this->priv_insert_ordered_range(UniqueBool(), index_capacity, first, limit, indexes, comp);
- first = limit;
- remaining -= index_capacity;
+ else{
+ T *raw_pos = boost::movelib::iterator_to_raw_pointer(this->insert(this->cend(), first, last));
+ T *raw_beg = this->priv_raw_begin();
+ T *raw_end = this->priv_raw_end();
+ boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, free_c - n);
+ if(UniqueBool::value){
+ size_type const count =
+ static_cast<size_type>(raw_end - boost::movelib::unique(raw_beg, raw_end, boost::movelib::negate<Compare>(comp)));
+ this->priv_destroy_last_n(count);
}
}
}
@@ -2279,53 +2261,6 @@ class vector
}
}
- template <class UniqueBool, class BidirIt, class Compare>
- void priv_insert_ordered_range
- (UniqueBool, size_type const n, BidirIt first, BidirIt const last, size_type positions[], Compare comp)
- {
- //Linear: at most N + M -1 comparisons
- //Log: MlogN
- //Average
- //Linear: N + M - 2
- //Log: MlogN
- //N+M - 2
- //N
- //(N+M)/2 < MlogN
- //(N/M+1)/2 <= logN
- //bool const linear = !s || !n || (s <= n) || ((s+n)/n/2 < logN);
- size_type const s = this->size();
- size_type remaining = n;
- T* const pbeg = this->priv_raw_begin();
- T* const pend = pbeg + s;
- T* pcur = pbeg;
- size_type *position = positions;
- size_type added_in_middle = 0;
- if(first != last && pcur != pend){
- while(1){
- //maintain stability moving external values only if they are strictly less
- if(comp(*first, *pcur)) {
- *position = static_cast<size_type>(pcur - pbeg);
- BOOST_ASSERT((position == positions) || (*(position-1) == size_type(-1)) || (*(position-1) <= *position));
- ++position;
- ++added_in_middle;
- --remaining;
- if(++first == last) break;
- }
- else if(UniqueBool::value && !comp(*pcur, *first)){
- *position = size_type(-1);
- ++position;
- --remaining;
- if(++first == last) break;
- }
- else{
- if(++pcur == pend) break;
- }
- }
- }
- this->insert_ordered_at(added_in_middle, position, first);
- this->insert(this->cend(), remaining, first, last);
- }
-
template<class UniqueBool, class FwdIt, class Compare>
void priv_merge_in_new_buffer
(UniqueBool, FwdIt first, size_type n, Compare comp, pointer new_storage, size_type const new_cap)
@@ -2337,7 +2272,7 @@ class vector
T* pbeg = this->priv_raw_begin();
size_type const old_size = this->size();
T* const pend = pbeg + old_size;
- T* d_first = container_detail::to_raw_pointer(new_storage);
+ T* d_first = boost::movelib::to_raw_pointer(new_storage);
size_type added = n;
//Merge in new buffer loop
while(1){
@@ -2373,7 +2308,7 @@ class vector
//Nothrow operations
pointer const old_p = this->m_holder.start();
size_type const old_cap = this->m_holder.capacity();
- boost::container::destroy_alloc_n(a, container_detail::to_raw_pointer(old_p), old_size);
+ boost::container::destroy_alloc_n(a, boost::movelib::to_raw_pointer(old_p), old_size);
a.deallocate(old_p, old_cap);
this->m_holder.m_size = old_size + added;
this->m_holder.start(new_storage);
@@ -2444,8 +2379,8 @@ class vector
}
//Else do a one by one move
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() ))
);
}
//Move allocator if needed
@@ -2514,8 +2449,8 @@ class vector
}
//... and move-insert the remaining range
sml.insert( sml.cend()
- , boost::make_move_iterator(container_detail::iterator_to_raw_pointer(big.nth(common_elements)))
- , boost::make_move_iterator(container_detail::iterator_to_raw_pointer(big.end()))
+ , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.nth(common_elements)))
+ , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.end()))
);
//Destroy remaining elements
big.erase(big.nth(common_elements), big.cend());
@@ -2540,7 +2475,7 @@ class vector
pointer const p = allocator_traits_type::allocate(this->m_holder.alloc(), new_cap, this->m_holder.m_start);
//We will reuse insert code, so create a dummy input iterator
this->priv_forward_range_insert_new_allocation
- ( container_detail::to_raw_pointer(p), new_cap, this->priv_raw_end(), 0, this->priv_dummy_empty_proxy());
+ ( boost::movelib::to_raw_pointer(p), new_cap, this->priv_raw_end(), 0, this->priv_dummy_empty_proxy());
}
void priv_reserve_no_capacity(size_type new_cap, version_2)
@@ -2561,7 +2496,7 @@ class vector
this->m_holder.capacity(real_cap);
}
else{ //If there is no forward expansion, move objects, we will reuse insertion code
- T * const new_mem = container_detail::to_raw_pointer(ret);
+ T * const new_mem = boost::movelib::to_raw_pointer(ret);
T * const ins_pos = this->priv_raw_end();
if(reuse){ //Backwards (and possibly forward) expansion
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
@@ -2691,7 +2626,7 @@ class vector
++this->num_alloc;
#endif
this->priv_forward_range_insert_new_allocation
- ( container_detail::to_raw_pointer(p), sz
+ ( boost::movelib::to_raw_pointer(p), sz
, this->priv_raw_begin(), 0, this->priv_dummy_empty_proxy());
}
}
@@ -2735,11 +2670,11 @@ class vector
{
//Check if we have enough memory or try to expand current memory
const size_type n_pos = pos - this->m_holder.start();
- T *const raw_pos = container_detail::to_raw_pointer(pos);
+ T *const raw_pos = boost::movelib::to_raw_pointer(pos);
const size_type new_cap = this->m_holder.next_capacity(n);
//Pass the hint so that allocators can take advantage of this.
- T * const new_buf = container_detail::to_raw_pointer
+ T * const new_buf = boost::movelib::to_raw_pointer
(allocator_traits_type::allocate(this->m_holder.alloc(), new_cap, this->m_holder.m_start));
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
++this->num_alloc;
@@ -2754,7 +2689,7 @@ class vector
(const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, version_2)
{
//Check if we have enough memory or try to expand current memory
- T *const raw_pos = container_detail::to_raw_pointer(pos);
+ T *const raw_pos = boost::movelib::to_raw_pointer(pos);
const size_type n_pos = raw_pos - this->priv_raw_begin();
//There is not enough memory, allocate a new
@@ -2781,7 +2716,7 @@ class vector
++this->num_expand_bwd;
#endif
this->priv_forward_range_insert_expand_backwards
- (container_detail::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
+ (boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
}
}
//New buffer
@@ -2790,7 +2725,7 @@ class vector
++this->num_alloc;
#endif
this->priv_forward_range_insert_new_allocation
- ( container_detail::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
+ ( boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
}
return iterator(this->m_holder.start() + n_pos);
@@ -2810,7 +2745,7 @@ class vector
}
else{
//Expand forward
- T *const raw_pos = container_detail::to_raw_pointer(pos);
+ T *const raw_pos = boost::movelib::to_raw_pointer(pos);
const size_type n_pos = raw_pos - this->priv_raw_begin();
this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
return iterator(this->m_holder.start() + n_pos);
@@ -2926,10 +2861,10 @@ class vector
}
private:
- T *priv_raw_begin() const
- { return container_detail::to_raw_pointer(m_holder.start()); }
+ BOOST_CONTAINER_FORCEINLINE T *priv_raw_begin() const
+ { return boost::movelib::to_raw_pointer(m_holder.start()); }
- T* priv_raw_end() const
+ BOOST_CONTAINER_FORCEINLINE T* priv_raw_end() const
{ return this->priv_raw_begin() + this->m_holder.m_size; }
template <class InsertionProxy>