mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 05:54:28 +02:00
Implemented "insert_or_assign" for map-like containers.
This commit is contained in:
@@ -1230,6 +1230,7 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
* [@https://svn.boost.org/trac/boost/ticket/12319 Trac #12319: ['"flat_set` should be nothrow move constructible"]].
|
||||
|
||||
* Revised noexcept expressions of default and move constructors in all containers.
|
||||
* Implemented `insert_or_assign` for [classref boost::container::map map] and [classref boost::container::flat_map flat_map].
|
||||
|
||||
[endsect]
|
||||
|
||||
|
@@ -23,16 +23,19 @@
|
||||
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/value_init.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//In place construction
|
||||
|
||||
template<class Allocator, class T, class InpIt>
|
||||
inline void construct_in_place(Allocator &a, T* dest, InpIt source)
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T* dest, InpIt source)
|
||||
{ boost::container::allocator_traits<Allocator>::construct(a, dest, *source); }
|
||||
|
||||
template<class Allocator, class T, class U, class D>
|
||||
inline void construct_in_place(Allocator &a, T *dest, value_init_construct_iterator<U, D>)
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, value_init_construct_iterator<U, D>)
|
||||
{
|
||||
boost::container::allocator_traits<Allocator>::construct(a, dest);
|
||||
}
|
||||
@@ -41,7 +44,7 @@ template <class T, class Difference>
|
||||
class default_init_construct_iterator;
|
||||
|
||||
template<class Allocator, class T, class U, class D>
|
||||
inline void construct_in_place(Allocator &a, T *dest, default_init_construct_iterator<U, D>)
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, default_init_construct_iterator<U, D>)
|
||||
{
|
||||
boost::container::allocator_traits<Allocator>::construct(a, dest, default_init);
|
||||
}
|
||||
@@ -50,13 +53,44 @@ template <class T, class EmplaceFunctor, class Difference>
|
||||
class emplace_iterator;
|
||||
|
||||
template<class Allocator, class T, class U, class EF, class D>
|
||||
inline void construct_in_place(Allocator &a, T *dest, emplace_iterator<U, EF, D> ei)
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, emplace_iterator<U, EF, D> ei)
|
||||
{
|
||||
ei.construct_in_place(a, dest);
|
||||
}
|
||||
|
||||
//Assignment
|
||||
|
||||
template<class DstIt, class InpIt>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, InpIt source)
|
||||
{ *dest = *source; }
|
||||
|
||||
template<class DstIt, class U, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, value_init_construct_iterator<U, D>)
|
||||
{
|
||||
container_detail::value_init<U> val;
|
||||
*dest = boost::move(val.get());
|
||||
}
|
||||
|
||||
template <class DstIt, class Difference>
|
||||
class default_init_construct_iterator;
|
||||
|
||||
template<class DstIt, class U, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, default_init_construct_iterator<U, D>)
|
||||
{
|
||||
U u;
|
||||
*dest = boost::move(u);
|
||||
}
|
||||
|
||||
template <class T, class EmplaceFunctor, class Difference>
|
||||
class emplace_iterator;
|
||||
|
||||
template<class DstIt, class U, class EF, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, emplace_iterator<U, EF, D> ei)
|
||||
{
|
||||
ei.assign_in_place(dest);
|
||||
}
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP
|
||||
|
||||
|
@@ -25,6 +25,8 @@
|
||||
#include <boost/container/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>
|
||||
|
||||
// move
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
#include <boost/move/iterator.hpp>
|
||||
@@ -515,7 +517,7 @@ 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);
|
||||
boost::container::construct_in_place(a, container_detail::iterator_to_raw_pointer(r), f);
|
||||
++f; ++r;
|
||||
}
|
||||
}
|
||||
@@ -757,7 +759,7 @@ inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I
|
||||
copy_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
||||
{
|
||||
while (n--) {
|
||||
*r = *f;
|
||||
boost::container::assign_in_place(r, f);
|
||||
++f; ++r;
|
||||
}
|
||||
return f;
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#endif
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/move/make_unique.hpp>
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
@@ -201,36 +202,36 @@ class flat_tree
|
||||
typedef allocator_traits<stored_allocator_type> stored_allocator_traits;
|
||||
|
||||
public:
|
||||
flat_tree()
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree()
|
||||
: m_data()
|
||||
{ }
|
||||
|
||||
explicit flat_tree(const Compare& comp)
|
||||
BOOST_CONTAINER_FORCEINLINE explicit flat_tree(const Compare& comp)
|
||||
: m_data(comp)
|
||||
{ }
|
||||
|
||||
flat_tree(const Compare& comp, const allocator_type& a)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree(const Compare& comp, const allocator_type& a)
|
||||
: m_data(comp, a)
|
||||
{ }
|
||||
|
||||
explicit flat_tree(const allocator_type& a)
|
||||
BOOST_CONTAINER_FORCEINLINE explicit flat_tree(const allocator_type& a)
|
||||
: m_data(a)
|
||||
{ }
|
||||
|
||||
flat_tree(const flat_tree& x)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree(const flat_tree& x)
|
||||
: m_data(x.m_data)
|
||||
{ }
|
||||
|
||||
flat_tree(BOOST_RV_REF(flat_tree) x)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree(BOOST_RV_REF(flat_tree) x)
|
||||
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
|
||||
: m_data(boost::move(x.m_data))
|
||||
{ }
|
||||
|
||||
flat_tree(const flat_tree& x, const allocator_type &a)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree(const flat_tree& x, const allocator_type &a)
|
||||
: m_data(x.m_data, a)
|
||||
{ }
|
||||
|
||||
flat_tree(BOOST_RV_REF(flat_tree) x, const allocator_type &a)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree(BOOST_RV_REF(flat_tree) x, const allocator_type &a)
|
||||
: m_data(boost::move(x.m_data), a)
|
||||
{ }
|
||||
|
||||
@@ -277,13 +278,13 @@ class flat_tree
|
||||
}
|
||||
}
|
||||
|
||||
~flat_tree()
|
||||
BOOST_CONTAINER_FORCEINLINE ~flat_tree()
|
||||
{}
|
||||
|
||||
flat_tree& operator=(BOOST_COPY_ASSIGN_REF(flat_tree) x)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree& operator=(BOOST_COPY_ASSIGN_REF(flat_tree) x)
|
||||
{ m_data = x.m_data; return *this; }
|
||||
|
||||
flat_tree& operator=(BOOST_RV_REF(flat_tree) x)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree& operator=(BOOST_RV_REF(flat_tree) 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)
|
||||
@@ -295,69 +296,75 @@ class flat_tree
|
||||
BOOST_CONTAINER_FORCEINLINE value_compare &priv_value_comp()
|
||||
{ return static_cast<value_compare &>(this->m_data); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const key_compare &priv_key_comp() const
|
||||
{ return this->priv_value_comp().get_comp(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE key_compare &priv_key_comp()
|
||||
{ return this->priv_value_comp().get_comp(); }
|
||||
|
||||
public:
|
||||
// accessors:
|
||||
Compare key_comp() const
|
||||
BOOST_CONTAINER_FORCEINLINE Compare key_comp() const
|
||||
{ return this->m_data.get_comp(); }
|
||||
|
||||
value_compare value_comp() const
|
||||
BOOST_CONTAINER_FORCEINLINE value_compare value_comp() const
|
||||
{ return this->m_data; }
|
||||
|
||||
allocator_type get_allocator() const
|
||||
BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const
|
||||
{ return this->m_data.m_vect.get_allocator(); }
|
||||
|
||||
const stored_allocator_type &get_stored_allocator() const
|
||||
BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const
|
||||
{ return this->m_data.m_vect.get_stored_allocator(); }
|
||||
|
||||
stored_allocator_type &get_stored_allocator()
|
||||
BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator()
|
||||
{ return this->m_data.m_vect.get_stored_allocator(); }
|
||||
|
||||
iterator begin()
|
||||
BOOST_CONTAINER_FORCEINLINE iterator begin()
|
||||
{ return this->m_data.m_vect.begin(); }
|
||||
|
||||
const_iterator begin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator begin() const
|
||||
{ return this->cbegin(); }
|
||||
|
||||
const_iterator cbegin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const
|
||||
{ return this->m_data.m_vect.begin(); }
|
||||
|
||||
iterator end()
|
||||
BOOST_CONTAINER_FORCEINLINE iterator end()
|
||||
{ return this->m_data.m_vect.end(); }
|
||||
|
||||
const_iterator end() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator end() const
|
||||
{ return this->cend(); }
|
||||
|
||||
const_iterator cend() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator cend() const
|
||||
{ return this->m_data.m_vect.end(); }
|
||||
|
||||
reverse_iterator rbegin()
|
||||
BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin()
|
||||
{ return reverse_iterator(this->end()); }
|
||||
|
||||
const_reverse_iterator rbegin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const
|
||||
{ return this->crbegin(); }
|
||||
|
||||
const_reverse_iterator crbegin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const
|
||||
{ return const_reverse_iterator(this->cend()); }
|
||||
|
||||
reverse_iterator rend()
|
||||
BOOST_CONTAINER_FORCEINLINE reverse_iterator rend()
|
||||
{ return reverse_iterator(this->begin()); }
|
||||
|
||||
const_reverse_iterator rend() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const
|
||||
{ return this->crend(); }
|
||||
|
||||
const_reverse_iterator crend() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const
|
||||
{ return const_reverse_iterator(this->cbegin()); }
|
||||
|
||||
bool empty() const
|
||||
BOOST_CONTAINER_FORCEINLINE bool empty() const
|
||||
{ return this->m_data.m_vect.empty(); }
|
||||
|
||||
size_type size() const
|
||||
BOOST_CONTAINER_FORCEINLINE size_type size() const
|
||||
{ return this->m_data.m_vect.size(); }
|
||||
|
||||
size_type max_size() const
|
||||
BOOST_CONTAINER_FORCEINLINE size_type max_size() const
|
||||
{ return this->m_data.m_vect.max_size(); }
|
||||
|
||||
void swap(flat_tree& other)
|
||||
BOOST_CONTAINER_FORCEINLINE void swap(flat_tree& other)
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
||||
&& boost::container::container_detail::is_nothrow_swappable<Compare>::value )
|
||||
{ this->m_data.swap(other.m_data); }
|
||||
@@ -368,7 +375,7 @@ class flat_tree
|
||||
{
|
||||
std::pair<iterator,bool> ret;
|
||||
insert_commit_data data;
|
||||
ret.second = this->priv_insert_unique_prepare(val, data);
|
||||
ret.second = this->priv_insert_unique_prepare(KeyOfValue()(val), data);
|
||||
ret.first = ret.second ? this->priv_insert_commit(data, val)
|
||||
: iterator(vector_iterator_get_ptr(data.position));
|
||||
return ret;
|
||||
@@ -378,7 +385,7 @@ class flat_tree
|
||||
{
|
||||
std::pair<iterator,bool> ret;
|
||||
insert_commit_data data;
|
||||
ret.second = this->priv_insert_unique_prepare(val, data);
|
||||
ret.second = this->priv_insert_unique_prepare(KeyOfValue()(val), data);
|
||||
ret.first = ret.second ? this->priv_insert_commit(data, boost::move(val))
|
||||
: iterator(vector_iterator_get_ptr(data.position));
|
||||
return ret;
|
||||
@@ -403,7 +410,7 @@ class flat_tree
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(hint));
|
||||
std::pair<iterator,bool> ret;
|
||||
insert_commit_data data;
|
||||
return this->priv_insert_unique_prepare(hint, val, data)
|
||||
return this->priv_insert_unique_prepare(hint, KeyOfValue()(val), data)
|
||||
? this->priv_insert_commit(data, val)
|
||||
: iterator(vector_iterator_get_ptr(data.position));
|
||||
}
|
||||
@@ -413,7 +420,7 @@ class flat_tree
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(hint));
|
||||
std::pair<iterator,bool> ret;
|
||||
insert_commit_data data;
|
||||
return this->priv_insert_unique_prepare(hint, val, data)
|
||||
return this->priv_insert_unique_prepare(hint, KeyOfValue()(val), data)
|
||||
? this->priv_insert_commit(data, boost::move(val))
|
||||
: iterator(vector_iterator_get_ptr(data.position));
|
||||
}
|
||||
@@ -634,7 +641,29 @@ class flat_tree
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
template<class KeyType, class M>
|
||||
std::pair<iterator, bool> insert_or_assign(const_iterator hint, BOOST_FWD_REF(KeyType) key, BOOST_FWD_REF(M) obj)
|
||||
{
|
||||
const key_type& k = key;
|
||||
std::pair<iterator,bool> ret;
|
||||
insert_commit_data data;
|
||||
ret.second = hint == const_iterator()
|
||||
? this->priv_insert_unique_prepare(k, data)
|
||||
: this->priv_insert_unique_prepare(hint, k, data);
|
||||
if(!ret.second){
|
||||
ret.first = this->nth(data.position - this->cbegin());
|
||||
ret.first->second = boost::forward<M>(obj);
|
||||
}
|
||||
else{
|
||||
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());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator position)
|
||||
{ return this->m_data.m_vect.erase(position); }
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
@@ -647,10 +676,10 @@ class flat_tree
|
||||
return ret;
|
||||
}
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator first, const_iterator last)
|
||||
{ return this->m_data.m_vect.erase(first, last); }
|
||||
|
||||
void clear()
|
||||
BOOST_CONTAINER_FORCEINLINE void clear()
|
||||
{ this->m_data.m_vect.clear(); }
|
||||
|
||||
//! <b>Effects</b>: Tries to deallocate the excess of memory created
|
||||
@@ -659,19 +688,19 @@ class flat_tree
|
||||
//! <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()
|
||||
{ this->m_data.m_vect.shrink_to_fit(); }
|
||||
|
||||
iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_data.m_vect.nth(n); }
|
||||
|
||||
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 this->m_data.m_vect.nth(n); }
|
||||
|
||||
size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
BOOST_CONTAINER_FORCEINLINE size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_data.m_vect.index_of(p); }
|
||||
|
||||
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 this->m_data.m_vect.index_of(p); }
|
||||
|
||||
// set operations:
|
||||
@@ -704,64 +733,64 @@ class flat_tree
|
||||
return n;
|
||||
}
|
||||
|
||||
iterator lower_bound(const key_type& k)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& k)
|
||||
{ return this->priv_lower_bound(this->begin(), this->end(), k); }
|
||||
|
||||
const_iterator lower_bound(const key_type& k) const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& k) const
|
||||
{ return this->priv_lower_bound(this->cbegin(), this->cend(), k); }
|
||||
|
||||
iterator upper_bound(const key_type& k)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const key_type& k)
|
||||
{ return this->priv_upper_bound(this->begin(), this->end(), k); }
|
||||
|
||||
const_iterator upper_bound(const key_type& k) const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& k) const
|
||||
{ return this->priv_upper_bound(this->cbegin(), this->cend(), k); }
|
||||
|
||||
std::pair<iterator,iterator> equal_range(const key_type& k)
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& k)
|
||||
{ return this->priv_equal_range(this->begin(), this->end(), k); }
|
||||
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
|
||||
{ return this->priv_equal_range(this->cbegin(), this->cend(), k); }
|
||||
|
||||
std::pair<iterator, iterator> lower_bound_range(const key_type& k)
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, iterator> lower_bound_range(const key_type& k)
|
||||
{ return this->priv_lower_bound_range(this->begin(), this->end(), k); }
|
||||
|
||||
std::pair<const_iterator, const_iterator> lower_bound_range(const key_type& k) const
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> lower_bound_range(const key_type& k) const
|
||||
{ return this->priv_lower_bound_range(this->cbegin(), this->cend(), k); }
|
||||
|
||||
size_type capacity() const
|
||||
BOOST_CONTAINER_FORCEINLINE size_type capacity() const
|
||||
{ return this->m_data.m_vect.capacity(); }
|
||||
|
||||
void reserve(size_type cnt)
|
||||
BOOST_CONTAINER_FORCEINLINE void reserve(size_type cnt)
|
||||
{ this->m_data.m_vect.reserve(cnt); }
|
||||
|
||||
friend bool operator==(const flat_tree& x, const flat_tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator==(const flat_tree& x, const flat_tree& y)
|
||||
{
|
||||
return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());
|
||||
}
|
||||
|
||||
friend bool operator<(const flat_tree& x, const flat_tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<(const flat_tree& x, const flat_tree& y)
|
||||
{
|
||||
return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
|
||||
}
|
||||
|
||||
friend bool operator!=(const flat_tree& x, const flat_tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const flat_tree& x, const flat_tree& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
friend bool operator>(const flat_tree& x, const flat_tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>(const flat_tree& x, const flat_tree& y)
|
||||
{ return y < x; }
|
||||
|
||||
friend bool operator<=(const flat_tree& x, const flat_tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const flat_tree& x, const flat_tree& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
friend bool operator>=(const flat_tree& x, const flat_tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const flat_tree& x, const flat_tree& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
friend void swap(flat_tree& x, flat_tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend void swap(flat_tree& x, flat_tree& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
private:
|
||||
|
||||
bool priv_in_range_or_end(const_iterator pos) const
|
||||
BOOST_CONTAINER_FORCEINLINE bool priv_in_range_or_end(const_iterator pos) const
|
||||
{
|
||||
return (this->begin() <= pos) && (pos <= this->end());
|
||||
}
|
||||
@@ -802,34 +831,34 @@ class flat_tree
|
||||
}
|
||||
|
||||
bool priv_insert_unique_prepare
|
||||
(const_iterator b, const_iterator e, const value_type& val, insert_commit_data &commit_data)
|
||||
(const_iterator b, const_iterator e, const key_type& k, insert_commit_data &commit_data)
|
||||
{
|
||||
const value_compare &val_cmp = this->m_data;
|
||||
commit_data.position = this->priv_lower_bound(b, e, KeyOfValue()(val));
|
||||
return commit_data.position == e || val_cmp(val, *commit_data.position);
|
||||
const key_compare &key_cmp = this->priv_key_comp();
|
||||
commit_data.position = this->priv_lower_bound(b, e, k);
|
||||
return commit_data.position == e || key_cmp(k, KeyOfValue()(*commit_data.position));
|
||||
}
|
||||
|
||||
bool priv_insert_unique_prepare
|
||||
(const value_type& val, insert_commit_data &commit_data)
|
||||
{ return this->priv_insert_unique_prepare(this->cbegin(), this->cend(), val, commit_data); }
|
||||
BOOST_CONTAINER_FORCEINLINE bool priv_insert_unique_prepare
|
||||
(const key_type& k, insert_commit_data &commit_data)
|
||||
{ return this->priv_insert_unique_prepare(this->cbegin(), this->cend(), k, commit_data); }
|
||||
|
||||
bool priv_insert_unique_prepare
|
||||
(const_iterator pos, const value_type& val, insert_commit_data &commit_data)
|
||||
(const_iterator pos, const key_type& k, insert_commit_data &commit_data)
|
||||
{
|
||||
//N1780. Props to Howard Hinnant!
|
||||
//To insert val at pos:
|
||||
//if pos == end || val <= *pos
|
||||
// if pos == begin || val >= *(pos-1)
|
||||
// insert val before pos
|
||||
//To insert k at pos:
|
||||
//if pos == end || k <= *pos
|
||||
// if pos == begin || k >= *(pos-1)
|
||||
// insert k before pos
|
||||
// else
|
||||
// insert val before upper_bound(val)
|
||||
//else if pos+1 == end || val <= *(pos+1)
|
||||
// insert val after pos
|
||||
// insert k before upper_bound(k)
|
||||
//else if pos+1 == end || k <= *(pos+1)
|
||||
// insert k after pos
|
||||
//else
|
||||
// insert val before lower_bound(val)
|
||||
const value_compare &val_cmp = this->m_data;
|
||||
// insert k before lower_bound(k)
|
||||
const key_compare &key_cmp = this->priv_key_comp();
|
||||
const const_iterator cend_it = this->cend();
|
||||
if(pos == cend_it || val_cmp(val, *pos)){ //Check if val should go before end
|
||||
if(pos == cend_it || key_cmp(k, KeyOfValue()(*pos))){ //Check if k should go before end
|
||||
const const_iterator cbeg = this->cbegin();
|
||||
commit_data.position = pos;
|
||||
if(pos == cbeg){ //If container is empty then insert it in the beginning
|
||||
@@ -837,27 +866,27 @@ class flat_tree
|
||||
}
|
||||
const_iterator prev(pos);
|
||||
--prev;
|
||||
if(val_cmp(*prev, val)){ //If previous element was less, then it should go between prev and pos
|
||||
if(key_cmp(KeyOfValue()(*prev), k)){ //If previous element was less, then it should go between prev and pos
|
||||
return true;
|
||||
}
|
||||
else if(!val_cmp(val, *prev)){ //If previous was equal then insertion should fail
|
||||
else if(!key_cmp(k, KeyOfValue()(*prev))){ //If previous was equal then insertion should fail
|
||||
commit_data.position = prev;
|
||||
return false;
|
||||
}
|
||||
else{ //Previous was bigger so insertion hint was pointless, dispatch to hintless insertion
|
||||
//but reduce the search between beg and prev as prev is bigger than val
|
||||
return this->priv_insert_unique_prepare(cbeg, prev, val, commit_data);
|
||||
//but reduce the search between beg and prev as prev is bigger than k
|
||||
return this->priv_insert_unique_prepare(cbeg, prev, k, commit_data);
|
||||
}
|
||||
}
|
||||
else{
|
||||
//The hint is before the insertion position, so insert it
|
||||
//in the remaining range [pos, end)
|
||||
return this->priv_insert_unique_prepare(pos, cend_it, val, commit_data);
|
||||
return this->priv_insert_unique_prepare(pos, cend_it, k, commit_data);
|
||||
}
|
||||
}
|
||||
|
||||
template<class Convertible>
|
||||
iterator priv_insert_commit
|
||||
BOOST_CONTAINER_FORCEINLINE iterator priv_insert_commit
|
||||
(insert_commit_data &commit_data, BOOST_FWD_REF(Convertible) convertible)
|
||||
{
|
||||
return this->m_data.m_vect.insert
|
||||
|
@@ -560,17 +560,23 @@ class emplace_iterator
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator-(difference_type off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
private:
|
||||
//This pseudo-iterator's dereference operations have no sense since value is not
|
||||
//constructed until ::boost::container::construct_in_place is called.
|
||||
//So comment them to catch bad uses
|
||||
//const T& operator*() const;
|
||||
//const T& operator[](difference_type) const;
|
||||
//const T* operator->() const;
|
||||
const T& operator*() const;
|
||||
const T& operator[](difference_type) const;
|
||||
const T* operator->() const;
|
||||
|
||||
public:
|
||||
template<class Allocator>
|
||||
void construct_in_place(Allocator &a, T* ptr)
|
||||
{ (*m_pe)(a, ptr); }
|
||||
|
||||
template<class DestIt>
|
||||
void assign_in_place(DestIt dest)
|
||||
{ (*m_pe)(dest); }
|
||||
|
||||
private:
|
||||
difference_type m_num;
|
||||
EmplaceFunctor * m_pe;
|
||||
@@ -612,9 +618,14 @@ struct emplace_functor
|
||||
{}
|
||||
|
||||
template<class Allocator, class T>
|
||||
void operator()(Allocator &a, T *ptr)
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(Allocator &a, T *ptr)
|
||||
{ emplace_functor::inplace_impl(a, ptr, index_tuple_t()); }
|
||||
|
||||
template<class DestIt>
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(DestIt dest)
|
||||
{ emplace_functor::inplace_impl(dest, index_tuple_t()); }
|
||||
|
||||
private:
|
||||
template<class Allocator, class T, int ...IdxPack>
|
||||
BOOST_CONTAINER_FORCEINLINE void inplace_impl(Allocator &a, T* ptr, const container_detail::index_tuple<IdxPack...>&)
|
||||
{
|
||||
@@ -622,11 +633,29 @@ struct emplace_functor
|
||||
(a, ptr, ::boost::forward<Args>(container_detail::get<IdxPack>(args_))...);
|
||||
}
|
||||
|
||||
template<class DestIt, int ...IdxPack>
|
||||
BOOST_CONTAINER_FORCEINLINE void inplace_impl(DestIt dest, const container_detail::index_tuple<IdxPack...>&)
|
||||
{
|
||||
typedef typename boost::container::iterator_traits<DestIt>::value_type value_type;
|
||||
value_type && tmp= value_type(::boost::forward<Args>(container_detail::get<IdxPack>(args_))...);
|
||||
*dest = ::boost::move(tmp);
|
||||
}
|
||||
|
||||
container_detail::tuple<Args&...> args_;
|
||||
};
|
||||
|
||||
template<class ...Args>
|
||||
struct emplace_functor_type
|
||||
{
|
||||
typedef emplace_functor<Args...> type;
|
||||
};
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
//Partial specializations cannot match argument list for primary template, so add an extra argument
|
||||
template <BOOST_MOVE_CLASSDFLT9, class Dummy = void>
|
||||
struct emplace_functor_type;
|
||||
|
||||
#define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
struct emplace_functor##N\
|
||||
@@ -638,10 +667,26 @@ struct emplace_functor##N\
|
||||
void operator()(Allocator &a, T *ptr)\
|
||||
{ allocator_traits<Allocator>::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\
|
||||
\
|
||||
template<class DestIt>\
|
||||
void operator()(DestIt dest)\
|
||||
{\
|
||||
typedef typename boost::container::iterator_traits<DestIt>::value_type value_type;\
|
||||
value_type tmp(BOOST_MOVE_MFWD##N);\
|
||||
*dest = ::boost::move(const_cast<value_type &>(tmp));\
|
||||
}\
|
||||
\
|
||||
BOOST_MOVE_MREF##N\
|
||||
};\
|
||||
\
|
||||
template <BOOST_MOVE_CLASS##N>\
|
||||
struct emplace_functor_type<BOOST_MOVE_TARG##N>\
|
||||
{\
|
||||
typedef emplace_functor##N BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N type;\
|
||||
};\
|
||||
//
|
||||
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE)
|
||||
|
||||
#undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE
|
||||
|
||||
#endif
|
||||
|
@@ -199,11 +199,11 @@ class insert_equal_end_hint_functor
|
||||
Icont &icont_;
|
||||
|
||||
public:
|
||||
insert_equal_end_hint_functor(Icont &icont)
|
||||
BOOST_CONTAINER_FORCEINLINE insert_equal_end_hint_functor(Icont &icont)
|
||||
: icont_(icont)
|
||||
{}
|
||||
|
||||
void operator()(Node &n)
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(Node &n)
|
||||
{ this->icont_.insert_equal(this->icont_.cend(), n); }
|
||||
};
|
||||
|
||||
@@ -213,11 +213,11 @@ class push_back_functor
|
||||
Icont &icont_;
|
||||
|
||||
public:
|
||||
push_back_functor(Icont &icont)
|
||||
BOOST_CONTAINER_FORCEINLINE push_back_functor(Icont &icont)
|
||||
: icont_(icont)
|
||||
{}
|
||||
|
||||
void operator()(Node &n)
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(Node &n)
|
||||
{ this->icont_.push_back(n); }
|
||||
};
|
||||
|
||||
@@ -328,14 +328,14 @@ template< boost::container::tree_type_enum tree_type_value
|
||||
struct intrusive_tree_proxy
|
||||
{
|
||||
template<class Icont>
|
||||
static void rebalance(Icont &) {}
|
||||
BOOST_CONTAINER_FORCEINLINE static void rebalance(Icont &) {}
|
||||
};
|
||||
|
||||
template<boost::container::tree_type_enum tree_type_value>
|
||||
struct intrusive_tree_proxy<tree_type_value, true>
|
||||
{
|
||||
template<class Icont>
|
||||
static void rebalance(Icont &c)
|
||||
BOOST_CONTAINER_FORCEINLINE static void rebalance(Icont &c)
|
||||
{ c.rebalance(); }
|
||||
};
|
||||
|
||||
@@ -359,10 +359,10 @@ class RecyclingCloner
|
||||
: m_holder(holder), m_icont(itree)
|
||||
{}
|
||||
|
||||
static void do_assign(node_ptr_type &p, const node_type &other, bool_<true>)
|
||||
BOOST_CONTAINER_FORCEINLINE static void do_assign(node_ptr_type &p, const node_type &other, bool_<true>)
|
||||
{ p->do_move_assign(const_cast<node_type &>(other).m_data); }
|
||||
|
||||
static void do_assign(node_ptr_type &p, const node_type &other, bool_<false>)
|
||||
BOOST_CONTAINER_FORCEINLINE static void do_assign(node_ptr_type &p, const node_type &other, bool_<false>)
|
||||
{ p->do_assign(other.m_data); }
|
||||
|
||||
node_ptr_type operator()(const node_type &other) const
|
||||
@@ -398,7 +398,7 @@ template<class KeyValueCompare, class Node>
|
||||
struct key_node_compare
|
||||
: private KeyValueCompare
|
||||
{
|
||||
explicit key_node_compare(const KeyValueCompare &comp)
|
||||
BOOST_CONTAINER_FORCEINLINE explicit key_node_compare(const KeyValueCompare &comp)
|
||||
: KeyValueCompare(comp)
|
||||
{}
|
||||
|
||||
@@ -409,20 +409,20 @@ struct key_node_compare
|
||||
};
|
||||
|
||||
template<class T>
|
||||
typename enable_if_c<is_node<T>::value, const typename KeyValueCompare::value_type &>::type
|
||||
BOOST_CONTAINER_FORCEINLINE typename enable_if_c<is_node<T>::value, const typename KeyValueCompare::value_type &>::type
|
||||
key_forward(const T &node) const
|
||||
{ return node.get_data(); }
|
||||
|
||||
template<class T>
|
||||
#if defined(BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN)
|
||||
const T &key_forward(const T &key, typename enable_if_c<!is_node<T>::value>::type* =0) const
|
||||
BOOST_CONTAINER_FORCEINLINE const T &key_forward(const T &key, typename enable_if_c<!is_node<T>::value>::type* =0) const
|
||||
#else
|
||||
typename enable_if_c<!is_node<T>::value, const T &>::type key_forward(const T &key) const
|
||||
BOOST_CONTAINER_FORCEINLINE typename enable_if_c<!is_node<T>::value, const T &>::type key_forward(const T &key) const
|
||||
#endif
|
||||
{ return key; }
|
||||
|
||||
template<class KeyType, class KeyType2>
|
||||
bool operator()(const KeyType &key1, const KeyType2 &key2) const
|
||||
BOOST_CONTAINER_FORCEINLINE bool operator()(const KeyType &key1, const KeyType2 &key2) const
|
||||
{ return KeyValueCompare::operator()(this->key_forward(key1), this->key_forward(key2)); }
|
||||
};
|
||||
|
||||
@@ -496,15 +496,15 @@ class tree
|
||||
typedef boost::container::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef boost::container::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
tree()
|
||||
BOOST_CONTAINER_FORCEINLINE tree()
|
||||
: AllocHolder()
|
||||
{}
|
||||
|
||||
explicit tree(const key_compare& comp, const allocator_type& a = allocator_type())
|
||||
BOOST_CONTAINER_FORCEINLINE explicit tree(const key_compare& comp, const allocator_type& a = allocator_type())
|
||||
: AllocHolder(ValComp(comp), a)
|
||||
{}
|
||||
|
||||
explicit tree(const allocator_type& a)
|
||||
BOOST_CONTAINER_FORCEINLINE explicit tree(const allocator_type& a)
|
||||
: AllocHolder(a)
|
||||
{}
|
||||
|
||||
@@ -604,19 +604,19 @@ class tree
|
||||
, container_detail::push_back_functor<Node, Icont>(this->icont()));
|
||||
}
|
||||
|
||||
tree(const tree& x)
|
||||
BOOST_CONTAINER_FORCEINLINE tree(const tree& x)
|
||||
: AllocHolder(x.value_comp(), x)
|
||||
{
|
||||
this->icont().clone_from
|
||||
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
|
||||
}
|
||||
|
||||
tree(BOOST_RV_REF(tree) x)
|
||||
BOOST_CONTAINER_FORCEINLINE tree(BOOST_RV_REF(tree) x)
|
||||
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
|
||||
: AllocHolder(BOOST_MOVE_BASE(AllocHolder, x), x.value_comp())
|
||||
{}
|
||||
|
||||
tree(const tree& x, const allocator_type &a)
|
||||
BOOST_CONTAINER_FORCEINLINE tree(const tree& x, const allocator_type &a)
|
||||
: AllocHolder(x.value_comp(), a)
|
||||
{
|
||||
this->icont().clone_from
|
||||
@@ -635,7 +635,7 @@ class tree
|
||||
}
|
||||
}
|
||||
|
||||
~tree()
|
||||
BOOST_CONTAINER_FORCEINLINE ~tree()
|
||||
{} //AllocHolder clears the tree
|
||||
|
||||
tree& operator=(BOOST_COPY_ASSIGN_REF(tree) x)
|
||||
@@ -714,43 +714,43 @@ class tree
|
||||
|
||||
public:
|
||||
// accessors:
|
||||
value_compare value_comp() const
|
||||
BOOST_CONTAINER_FORCEINLINE value_compare value_comp() const
|
||||
{ return this->icont().value_comp().predicate(); }
|
||||
|
||||
key_compare key_comp() const
|
||||
BOOST_CONTAINER_FORCEINLINE key_compare key_comp() const
|
||||
{ return this->icont().value_comp().predicate().key_comp(); }
|
||||
|
||||
allocator_type get_allocator() const
|
||||
BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const
|
||||
{ return allocator_type(this->node_alloc()); }
|
||||
|
||||
const stored_allocator_type &get_stored_allocator() const
|
||||
BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const
|
||||
{ return this->node_alloc(); }
|
||||
|
||||
stored_allocator_type &get_stored_allocator()
|
||||
BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator()
|
||||
{ return this->node_alloc(); }
|
||||
|
||||
iterator begin()
|
||||
BOOST_CONTAINER_FORCEINLINE iterator begin()
|
||||
{ return iterator(this->icont().begin()); }
|
||||
|
||||
const_iterator begin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator begin() const
|
||||
{ return this->cbegin(); }
|
||||
|
||||
iterator end()
|
||||
BOOST_CONTAINER_FORCEINLINE iterator end()
|
||||
{ return iterator(this->icont().end()); }
|
||||
|
||||
const_iterator end() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator end() const
|
||||
{ return this->cend(); }
|
||||
|
||||
reverse_iterator rbegin()
|
||||
BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin()
|
||||
{ return reverse_iterator(end()); }
|
||||
|
||||
const_reverse_iterator rbegin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const
|
||||
{ return this->crbegin(); }
|
||||
|
||||
reverse_iterator rend()
|
||||
BOOST_CONTAINER_FORCEINLINE reverse_iterator rend()
|
||||
{ return reverse_iterator(begin()); }
|
||||
|
||||
const_reverse_iterator rend() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const
|
||||
{ return this->crend(); }
|
||||
|
||||
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
|
||||
@@ -758,7 +758,7 @@ class tree
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_iterator cbegin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const
|
||||
{ return const_iterator(this->non_const_icont().begin()); }
|
||||
|
||||
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
|
||||
@@ -766,7 +766,7 @@ class tree
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_iterator cend() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator cend() const
|
||||
{ return const_iterator(this->non_const_icont().end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
|
||||
@@ -775,7 +775,7 @@ class tree
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reverse_iterator crbegin() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const
|
||||
{ return const_reverse_iterator(cend()); }
|
||||
|
||||
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
|
||||
@@ -784,19 +784,19 @@ class tree
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reverse_iterator crend() const
|
||||
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const
|
||||
{ return const_reverse_iterator(cbegin()); }
|
||||
|
||||
bool empty() const
|
||||
BOOST_CONTAINER_FORCEINLINE bool empty() const
|
||||
{ return !this->size(); }
|
||||
|
||||
size_type size() const
|
||||
BOOST_CONTAINER_FORCEINLINE size_type size() const
|
||||
{ return this->icont().size(); }
|
||||
|
||||
size_type max_size() const
|
||||
BOOST_CONTAINER_FORCEINLINE size_type max_size() const
|
||||
{ return AllocHolder::max_size(); }
|
||||
|
||||
void swap(ThisType& x)
|
||||
BOOST_CONTAINER_FORCEINLINE void swap(ThisType& x)
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
|
||||
&& boost::container::container_detail::is_nothrow_swappable<Compare>::value )
|
||||
{ AllocHolder::swap(x); }
|
||||
@@ -868,6 +868,28 @@ class tree
|
||||
|
||||
private:
|
||||
|
||||
template<class KeyConvertible>
|
||||
iterator priv_insert_unique_key_commit
|
||||
(BOOST_FWD_REF(KeyConvertible) key, insert_commit_data &data)
|
||||
{
|
||||
NodePtr tmp = AllocHolder::create_node_from_key(boost::forward<KeyConvertible>(key));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_unique_commit(*tmp, data));
|
||||
destroy_deallocator.release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class KeyConvertible, class M>
|
||||
iiterator priv_insert_or_assign_commit
|
||||
(BOOST_FWD_REF(KeyConvertible) key, BOOST_FWD_REF(M) obj, insert_commit_data &data)
|
||||
{
|
||||
NodePtr tmp = AllocHolder::create_node(boost::forward<KeyConvertible>(key), boost::forward<M>(obj));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iiterator ret(this->icont().insert_unique_commit(*tmp, data));
|
||||
destroy_deallocator.release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool priv_is_linked(const_iterator const position) const
|
||||
{
|
||||
iiterator const cur(position.get());
|
||||
@@ -921,11 +943,11 @@ class tree
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template <class... Args>
|
||||
std::pair<iterator, bool> emplace_unique(BOOST_FWD_REF(Args)... args)
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> emplace_unique(BOOST_FWD_REF(Args)... args)
|
||||
{ return this->emplace_unique_impl(AllocHolder::create_node(boost::forward<Args>(args)...)); }
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{ return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(boost::forward<Args>(args)...)); }
|
||||
|
||||
template <class... Args>
|
||||
@@ -1054,19 +1076,25 @@ class tree
|
||||
std::pair<iiterator, bool> ret =
|
||||
this->icont().insert_unique_check(k, KeyNodeCompare(value_comp()), data);
|
||||
return ret.second
|
||||
? this->insert_unique_key_commit(boost::forward<KeyConvertible>(key), data)
|
||||
? this->priv_insert_unique_key_commit(boost::forward<KeyConvertible>(key), data)
|
||||
: iterator(ret.first);
|
||||
}
|
||||
|
||||
template<class KeyConvertible>
|
||||
iterator insert_unique_key_commit
|
||||
(BOOST_FWD_REF(KeyConvertible) key, insert_commit_data &data)
|
||||
template<class KeyType, class M>
|
||||
std::pair<iterator, bool> insert_or_assign(const_iterator hint, BOOST_FWD_REF(KeyType) key, BOOST_FWD_REF(M) obj)
|
||||
{
|
||||
NodePtr tmp = AllocHolder::create_node_from_key(boost::forward<KeyConvertible>(key));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_unique_commit(*tmp, data));
|
||||
destroy_deallocator.release();
|
||||
return ret;
|
||||
insert_commit_data data;
|
||||
const key_type & k = key; //Support emulated rvalue references
|
||||
std::pair<iiterator, bool> ret =
|
||||
hint == const_iterator() ? this->icont().insert_unique_check(k, KeyNodeCompare(value_comp()), data)
|
||||
: this->icont().insert_unique_check(hint.get(), k, KeyNodeCompare(value_comp()), data);
|
||||
if(ret.second){
|
||||
ret.first = this->priv_insert_or_assign_commit(boost::forward<KeyType>(key), boost::forward<M>(obj), data);
|
||||
}
|
||||
else{
|
||||
ret.first->get_data().second = boost::forward<M>(obj);
|
||||
}
|
||||
return std::pair<iterator, bool>(iterator(ret.first), ret.second);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
@@ -1075,7 +1103,7 @@ class tree
|
||||
return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc())));
|
||||
}
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& k)
|
||||
{ return AllocHolder::erase_key(k, KeyNodeCompare(value_comp()), alloc_version()); }
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
@@ -1085,30 +1113,30 @@ class tree
|
||||
return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version()));
|
||||
}
|
||||
|
||||
void clear()
|
||||
BOOST_CONTAINER_FORCEINLINE void clear()
|
||||
{ AllocHolder::clear(alloc_version()); }
|
||||
|
||||
// search operations. Const and non-const overloads even if no iterator is returned
|
||||
// so splay implementations can to their rebalancing when searching in non-const versions
|
||||
iterator find(const key_type& k)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator find(const key_type& k)
|
||||
{ return iterator(this->icont().find(k, KeyNodeCompare(value_comp()))); }
|
||||
|
||||
const_iterator find(const key_type& k) const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator find(const key_type& k) const
|
||||
{ return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(value_comp()))); }
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& k) const
|
||||
{ return size_type(this->icont().count(k, KeyNodeCompare(value_comp()))); }
|
||||
|
||||
iterator lower_bound(const key_type& k)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& k)
|
||||
{ return iterator(this->icont().lower_bound(k, KeyNodeCompare(value_comp()))); }
|
||||
|
||||
const_iterator lower_bound(const key_type& k) const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& k) const
|
||||
{ return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(value_comp()))); }
|
||||
|
||||
iterator upper_bound(const key_type& k)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const key_type& k)
|
||||
{ return iterator(this->icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
|
||||
|
||||
const_iterator upper_bound(const key_type& k) const
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& k) const
|
||||
{ return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
|
||||
|
||||
std::pair<iterator,iterator> equal_range(const key_type& k)
|
||||
@@ -1141,28 +1169,28 @@ class tree
|
||||
(const_iterator(ret.first), const_iterator(ret.second));
|
||||
}
|
||||
|
||||
void rebalance()
|
||||
BOOST_CONTAINER_FORCEINLINE void rebalance()
|
||||
{ intrusive_tree_proxy_t::rebalance(this->icont()); }
|
||||
|
||||
friend bool operator==(const tree& x, const tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator==(const tree& x, const tree& y)
|
||||
{ return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
friend bool operator<(const tree& x, const tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<(const tree& x, const tree& y)
|
||||
{ return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
friend bool operator!=(const tree& x, const tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const tree& x, const tree& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
friend bool operator>(const tree& x, const tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>(const tree& x, const tree& y)
|
||||
{ return y < x; }
|
||||
|
||||
friend bool operator<=(const tree& x, const tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const tree& x, const tree& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
friend bool operator>=(const tree& x, const tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const tree& x, const tree& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
friend void swap(tree& x, tree& y)
|
||||
BOOST_CONTAINER_FORCEINLINE friend void swap(tree& x, tree& y)
|
||||
{ x.swap(y); }
|
||||
};
|
||||
|
||||
|
@@ -37,6 +37,8 @@ struct value_init
|
||||
|
||||
operator T &() { return m_t; }
|
||||
|
||||
T &get() { return m_t; }
|
||||
|
||||
T m_t;
|
||||
};
|
||||
|
||||
|
@@ -56,11 +56,11 @@ namespace container {
|
||||
namespace container_detail{
|
||||
|
||||
template<class D, class S>
|
||||
static D &force(const S &s)
|
||||
BOOST_CONTAINER_FORCEINLINE static D &force(const S &s)
|
||||
{ return *const_cast<D*>((reinterpret_cast<const D*>(&s))); }
|
||||
|
||||
template<class D, class S>
|
||||
static D force_copy(S s)
|
||||
BOOST_CONTAINER_FORCEINLINE static D force_copy(S s)
|
||||
{
|
||||
D *vp = reinterpret_cast<D *>(&s);
|
||||
return D(*vp);
|
||||
@@ -604,6 +604,98 @@ class flat_map
|
||||
BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript)
|
||||
#endif
|
||||
|
||||
//! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
|
||||
//! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
|
||||
//! as if by insert, constructing it from value_type(k, forward<M>(obj)).
|
||||
//!
|
||||
//! No iterators or references are invalidated. If the insertion is successful, pointers and references
|
||||
//! to the element obtained while it is held in the node handle are invalidated, and pointers and
|
||||
//! references obtained to that element before it was extracted become valid.
|
||||
//!
|
||||
//! Returns: The bool component is true if the insertion took place and false if the assignment
|
||||
//! took place. The iterator component is pointing at the element that was inserted or updated.
|
||||
//!
|
||||
//! Complexity: Logarithmic in the size of the container.
|
||||
template <class M>
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> insert_or_assign(const key_type& k, BOOST_FWD_REF(M) obj)
|
||||
{
|
||||
return container_detail::force_copy< std::pair<iterator, bool> >
|
||||
(this->m_flat_tree.insert_or_assign
|
||||
( container_detail::force_copy<impl_const_iterator>(const_iterator())
|
||||
, k, ::boost::forward<M>(obj))
|
||||
);
|
||||
}
|
||||
|
||||
//! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
|
||||
//! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
|
||||
//! as if by insert, constructing it from value_type(k, move(obj)).
|
||||
//!
|
||||
//! No iterators or references are invalidated. If the insertion is successful, pointers and references
|
||||
//! to the element obtained while it is held in the node handle are invalidated, and pointers and
|
||||
//! references obtained to that element before it was extracted become valid.
|
||||
//!
|
||||
//! Returns: The bool component is true if the insertion took place and false if the assignment
|
||||
//! took place. The iterator component is pointing at the element that was inserted or updated.
|
||||
//!
|
||||
//! Complexity: Logarithmic in the size of the container.
|
||||
template <class M>
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> insert_or_assign(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
|
||||
{
|
||||
return container_detail::force_copy< std::pair<iterator, bool> >
|
||||
(this->m_flat_tree.insert_or_assign
|
||||
( container_detail::force_copy<impl_const_iterator>(const_iterator())
|
||||
, ::boost::move(k), ::boost::forward<M>(obj))
|
||||
);
|
||||
}
|
||||
|
||||
//! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
|
||||
//! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
|
||||
//! as if by insert, constructing it from value_type(k, forward<M>(obj)) and the new element
|
||||
//! to the container as close as possible to the position just before hint.
|
||||
//!
|
||||
//! No iterators or references are invalidated. If the insertion is successful, pointers and references
|
||||
//! to the element obtained while it is held in the node handle are invalidated, and pointers and
|
||||
//! references obtained to that element before it was extracted become valid.
|
||||
//!
|
||||
//! Returns: The bool component is true if the insertion took place and false if the assignment
|
||||
//! took place. The iterator component is pointing at the element that was inserted or updated.
|
||||
//!
|
||||
//! Complexity: Logarithmic in the size of the container in general, but amortized constant if
|
||||
//! the new element is inserted just before hint.
|
||||
template <class M>
|
||||
BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, const key_type& k, BOOST_FWD_REF(M) obj)
|
||||
{
|
||||
return container_detail::force_copy< std::pair<iterator, bool> >
|
||||
(this->m_flat_tree.insert_or_assign
|
||||
( container_detail::force_copy<impl_const_iterator>(hint)
|
||||
, k, ::boost::forward<M>(obj))
|
||||
);
|
||||
}
|
||||
|
||||
//! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
|
||||
//! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
|
||||
//! as if by insert, constructing it from value_type(k, move(obj)) and the new element
|
||||
//! to the container as close as possible to the position just before hint.
|
||||
//!
|
||||
//! No iterators or references are invalidated. If the insertion is successful, pointers and references
|
||||
//! to the element obtained while it is held in the node handle are invalidated, and pointers and
|
||||
//! references obtained to that element before it was extracted become valid.
|
||||
//!
|
||||
//! Returns: The bool component is true if the insertion took place and false if the assignment
|
||||
//! took place. The iterator component is pointing at the element that was inserted or updated.
|
||||
//!
|
||||
//! Complexity: Logarithmic in the size of the container in general, but amortized constant if
|
||||
//! the new element is inserted just before hint.
|
||||
template <class M>
|
||||
BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
|
||||
{
|
||||
return container_detail::force_copy< std::pair<iterator, bool> >
|
||||
(this->m_flat_tree.insert_or_assign
|
||||
( container_detail::force_copy<impl_const_iterator>(hint)
|
||||
, ::boost::move(k), ::boost::forward<M>(obj))
|
||||
);
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::nth(size_type)
|
||||
iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
|
||||
|
@@ -132,6 +132,7 @@ class map
|
||||
//! <b>Effects</b>: Default constructs an empty map.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
map() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
|
||||
container_detail::is_nothrow_default_constructible<Compare>::value)
|
||||
: base_t()
|
||||
@@ -144,6 +145,7 @@ class map
|
||||
//! and allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
explicit map(const Compare& comp, const allocator_type& a = allocator_type())
|
||||
: base_t(comp, a)
|
||||
{
|
||||
@@ -154,6 +156,7 @@ class map
|
||||
//! <b>Effects</b>: Constructs an empty map using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
explicit map(const allocator_type& a)
|
||||
: base_t(a)
|
||||
{
|
||||
@@ -167,6 +170,7 @@ class map
|
||||
//! <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
|
||||
map(InputIterator first, InputIterator last, const Compare& comp = Compare(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: base_t(true, first, last, comp, a)
|
||||
@@ -181,6 +185,7 @@ class map
|
||||
//! <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
|
||||
map(InputIterator first, InputIterator last, const allocator_type& a)
|
||||
: base_t(true, first, last, Compare(), a)
|
||||
{
|
||||
@@ -199,6 +204,7 @@ 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())
|
||||
: base_t(ordered_range, first, last, comp, a)
|
||||
@@ -213,6 +219,7 @@ class map
|
||||
//!
|
||||
//! <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)
|
||||
{
|
||||
@@ -225,6 +232,7 @@ class map
|
||||
//!
|
||||
//! <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)
|
||||
: base_t(true, il.begin(), il.end(), Compare(), a)
|
||||
{
|
||||
@@ -242,6 +250,7 @@ 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())
|
||||
: base_t(ordered_range, il.begin(), il.end(), comp, a)
|
||||
@@ -254,6 +263,7 @@ class map
|
||||
//! <b>Effects</b>: Copy constructs a map.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
map(const map& x)
|
||||
: base_t(static_cast<const base_t&>(x))
|
||||
{
|
||||
@@ -266,6 +276,7 @@ class map
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
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))
|
||||
@@ -277,6 +288,7 @@ class map
|
||||
//! <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)
|
||||
: base_t(static_cast<const base_t&>(x), a)
|
||||
{
|
||||
@@ -290,6 +302,7 @@ 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)
|
||||
: base_t(BOOST_MOVE_BASE(base_t, x), a)
|
||||
{
|
||||
@@ -300,6 +313,7 @@ class map
|
||||
//! <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)
|
||||
{ return static_cast<map&>(this->base_t::operator=(static_cast<const base_t&>(x))); }
|
||||
|
||||
@@ -311,6 +325,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_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
|
||||
allocator_traits_type::is_always_equal::value) &&
|
||||
@@ -320,6 +335,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)
|
||||
{
|
||||
this->clear();
|
||||
@@ -485,12 +501,80 @@ class 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
|
||||
|
||||
//! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
|
||||
//! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
|
||||
//! as if by insert, constructing it from value_type(k, forward<M>(obj)).
|
||||
//!
|
||||
//! No iterators or references are invalidated. If the insertion is successful, pointers and references
|
||||
//! to the element obtained while it is held in the node handle are invalidated, and pointers and
|
||||
//! references obtained to that element before it was extracted become valid.
|
||||
//!
|
||||
//! Returns: The bool component is true if the insertion took place and false if the assignment
|
||||
//! took place. The iterator component is pointing at the element that was inserted or updated.
|
||||
//!
|
||||
//! Complexity: Logarithmic in the size of the container.
|
||||
template <class M>
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> insert_or_assign(const key_type& k, BOOST_FWD_REF(M) obj)
|
||||
{ return this->base_t::insert_or_assign(const_iterator(), k, ::boost::forward<M>(obj)); }
|
||||
|
||||
//! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
|
||||
//! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
|
||||
//! as if by insert, constructing it from value_type(k, move(obj)).
|
||||
//!
|
||||
//! No iterators or references are invalidated. If the insertion is successful, pointers and references
|
||||
//! to the element obtained while it is held in the node handle are invalidated, and pointers and
|
||||
//! references obtained to that element before it was extracted become valid.
|
||||
//!
|
||||
//! Returns: The bool component is true if the insertion took place and false if the assignment
|
||||
//! took place. The iterator component is pointing at the element that was inserted or updated.
|
||||
//!
|
||||
//! Complexity: Logarithmic in the size of the container.
|
||||
template <class M>
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> insert_or_assign(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
|
||||
{ return this->base_t::insert_or_assign(const_iterator(), ::boost::move(k), ::boost::forward<M>(obj)); }
|
||||
|
||||
//! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
|
||||
//! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
|
||||
//! as if by insert, constructing it from value_type(k, forward<M>(obj)) and the new element
|
||||
//! to the container as close as possible to the position just before hint.
|
||||
//!
|
||||
//! No iterators or references are invalidated. If the insertion is successful, pointers and references
|
||||
//! to the element obtained while it is held in the node handle are invalidated, and pointers and
|
||||
//! references obtained to that element before it was extracted become valid.
|
||||
//!
|
||||
//! Returns: The bool component is true if the insertion took place and false if the assignment
|
||||
//! took place. The iterator component is pointing at the element that was inserted or updated.
|
||||
//!
|
||||
//! Complexity: Logarithmic in the size of the container in general, but amortized constant if
|
||||
//! the new element is inserted just before hint.
|
||||
template <class M>
|
||||
BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, const key_type& k, BOOST_FWD_REF(M) obj)
|
||||
{ return this->base_t::insert_or_assign(hint, k, ::boost::forward<M>(obj)); }
|
||||
|
||||
//! Effects: If a key equivalent to k already exists in the container, assigns forward<M>(obj)
|
||||
//! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value
|
||||
//! as if by insert, constructing it from value_type(k, move(obj)) and the new element
|
||||
//! to the container as close as possible to the position just before hint.
|
||||
//!
|
||||
//! No iterators or references are invalidated. If the insertion is successful, pointers and references
|
||||
//! to the element obtained while it is held in the node handle are invalidated, and pointers and
|
||||
//! references obtained to that element before it was extracted become valid.
|
||||
//!
|
||||
//! Returns: The bool component is true if the insertion took place and false if the assignment
|
||||
//! took place. The iterator component is pointing at the element that was inserted or updated.
|
||||
//!
|
||||
//! Complexity: Logarithmic in the size of the container in general, but amortized constant if
|
||||
//! the new element is inserted just before hint.
|
||||
template <class M>
|
||||
BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj)
|
||||
{ return this->base_t::insert_or_assign(hint, ::boost::move(k), ::boost::forward<M>(obj)); }
|
||||
|
||||
//! Returns: A reference to the element whose key is equivalent to x.
|
||||
//! Throws: An exception object of type out_of_range if no such element is present.
|
||||
//! Complexity: logarithmic.
|
||||
@@ -529,7 +613,7 @@ class map
|
||||
//! points to the element with key equivalent to the key of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
std::pair<iterator,bool> insert(const value_type& x)
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(const value_type& x)
|
||||
{ return this->base_t::insert_unique(x); }
|
||||
|
||||
//! <b>Effects</b>: Inserts a new value_type created from the pair if and only if
|
||||
@@ -540,7 +624,7 @@ class map
|
||||
//! points to the element with key equivalent to the key of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
std::pair<iterator,bool> insert(const nonconst_value_type& x)
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(const nonconst_value_type& x)
|
||||
{ return this->base_t::insert_unique(x); }
|
||||
|
||||
//! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
|
||||
@@ -551,7 +635,7 @@ class map
|
||||
//! points to the element with key equivalent to the key of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
std::pair<iterator,bool> insert(BOOST_RV_REF(nonconst_value_type) x)
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(BOOST_RV_REF(nonconst_value_type) x)
|
||||
{ return this->base_t::insert_unique(boost::move(x)); }
|
||||
|
||||
//! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
|
||||
@@ -562,7 +646,7 @@ class map
|
||||
//! points to the element with key equivalent to the key of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
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 this->base_t::insert_unique(boost::move(x)); }
|
||||
|
||||
//! <b>Effects</b>: Move constructs a new value from x if and only if there is
|
||||
@@ -573,7 +657,7 @@ class map
|
||||
//! points to the element with key equivalent to the key of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
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 this->base_t::insert_unique(boost::move(x)); }
|
||||
|
||||
//! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
|
||||
@@ -585,7 +669,7 @@ class map
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
|
||||
//! is inserted right before p.
|
||||
iterator insert(const_iterator p, const value_type& x)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x)
|
||||
{ return this->base_t::insert_unique(p, x); }
|
||||
|
||||
//! <b>Effects</b>: Move constructs a new value from x if and only if there is
|
||||
@@ -637,7 +721,7 @@ class map
|
||||
//!
|
||||
//! <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)
|
||||
@@ -645,7 +729,7 @@ class map
|
||||
//! 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
|
||||
|
||||
@@ -663,7 +747,7 @@ class map
|
||||
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
|
||||
//! is inserted right before p.
|
||||
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 T constructed with
|
||||
@@ -677,18 +761,18 @@ class map
|
||||
//! <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_unique(p, boost::forward<Args>(args)...); }
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_CONTAINER_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 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_MAP_EMPLACE_CODE)
|
||||
@@ -766,7 +850,7 @@ class map
|
||||
//! <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->find(x) != this->cend()); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
@@ -850,11 +934,10 @@ class map
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
template<class KeyConvertible>
|
||||
mapped_type& priv_subscript(BOOST_FWD_REF(KeyConvertible) k)
|
||||
BOOST_CONTAINER_FORCEINLINE mapped_type& priv_subscript(BOOST_FWD_REF(KeyConvertible) k)
|
||||
{
|
||||
return this->insert_from_key(boost::forward<KeyConvertible>(k))->second;
|
||||
}
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
@@ -959,6 +1042,7 @@ 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)
|
||||
: base_t()
|
||||
@@ -970,6 +1054,7 @@ class multimap
|
||||
//! <b>Effects</b>: Constructs an empty multimap using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
explicit multimap(const Compare& comp, const allocator_type& a = allocator_type())
|
||||
: base_t(comp, a)
|
||||
{
|
||||
@@ -981,6 +1066,7 @@ class multimap
|
||||
//! object and allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
explicit multimap(const allocator_type& a)
|
||||
: base_t(a)
|
||||
{
|
||||
@@ -994,6 +1080,7 @@ class multimap
|
||||
//! <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
|
||||
multimap(InputIterator first, InputIterator last,
|
||||
const Compare& comp = Compare(),
|
||||
const allocator_type& a = allocator_type())
|
||||
@@ -1009,7 +1096,7 @@ class multimap
|
||||
//! <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>
|
||||
multimap(InputIterator first, InputIterator last, const allocator_type& a)
|
||||
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>
|
||||
@@ -1026,7 +1113,7 @@ class multimap
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
template <class InputIterator>
|
||||
multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(),
|
||||
BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: base_t(ordered_range, first, last, comp, a)
|
||||
{}
|
||||
@@ -1037,6 +1124,7 @@ class multimap
|
||||
//!
|
||||
//! <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)
|
||||
@@ -1050,6 +1138,7 @@ class multimap
|
||||
//!
|
||||
//! <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)
|
||||
: base_t(false, il.begin(), il.end(), Compare(), a)
|
||||
{
|
||||
@@ -1066,6 +1155,7 @@ 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())
|
||||
: base_t(ordered_range, il.begin(), il.end(), comp, a)
|
||||
@@ -1078,7 +1168,7 @@ class multimap
|
||||
//! <b>Effects</b>: Copy constructs a multimap.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
multimap(const multimap& x)
|
||||
BOOST_CONTAINER_FORCEINLINE multimap(const multimap& x)
|
||||
: base_t(static_cast<const base_t&>(x))
|
||||
{
|
||||
//A type must be std::pair<CONST Key, T>
|
||||
@@ -1090,7 +1180,7 @@ class multimap
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
multimap(BOOST_RV_REF(multimap) x)
|
||||
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))
|
||||
{
|
||||
@@ -1101,7 +1191,7 @@ class multimap
|
||||
//! <b>Effects</b>: Copy constructs a multimap.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
multimap(const multimap& x, const allocator_type &a)
|
||||
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>
|
||||
@@ -1113,7 +1203,7 @@ class multimap
|
||||
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
multimap(BOOST_RV_REF(multimap) x, const allocator_type &a)
|
||||
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>
|
||||
@@ -1123,13 +1213,13 @@ class multimap
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
multimap& operator=(BOOST_COPY_ASSIGN_REF(multimap) x)
|
||||
BOOST_CONTAINER_FORCEINLINE multimap& operator=(BOOST_COPY_ASSIGN_REF(multimap) x)
|
||||
{ return static_cast<multimap&>(this->base_t::operator=(static_cast<const base_t&>(x))); }
|
||||
|
||||
//! <b>Effects</b>: this->swap(x.get()).
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
multimap& operator=(BOOST_RV_REF(multimap) x)
|
||||
BOOST_CONTAINER_FORCEINLINE multimap& operator=(BOOST_RV_REF(multimap) 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)
|
||||
@@ -1138,7 +1228,7 @@ class multimap
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
//! <b>Effects</b>: Assign content of il to *this.
|
||||
//!
|
||||
multimap& operator=(std::initializer_list<value_type> il)
|
||||
BOOST_CONTAINER_FORCEINLINE multimap& operator=(std::initializer_list<value_type> il)
|
||||
{
|
||||
this->clear();
|
||||
insert(il.begin(), il.end());
|
||||
@@ -1216,7 +1306,7 @@ class multimap
|
||||
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
|
||||
//! is inserted right before p.
|
||||
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 T constructed with
|
||||
@@ -1229,18 +1319,18 @@ class multimap
|
||||
//! <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_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 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_MULTIMAP_EMPLACE_CODE)
|
||||
@@ -1252,21 +1342,21 @@ class multimap
|
||||
//! newly inserted element.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
iterator insert(const value_type& x)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator insert(const value_type& x)
|
||||
{ return this->base_t::insert_equal(x); }
|
||||
|
||||
//! <b>Effects</b>: Inserts a new value constructed from x and returns
|
||||
//! the iterator pointing to the newly inserted element.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
iterator insert(const nonconst_value_type& x)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator insert(const nonconst_value_type& x)
|
||||
{ return this->base_t::insert_equal(x); }
|
||||
|
||||
//! <b>Effects</b>: Inserts a new value move-constructed from x and returns
|
||||
//! the iterator pointing to the newly inserted element.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
iterator insert(BOOST_RV_REF(nonconst_value_type) x)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator insert(BOOST_RV_REF(nonconst_value_type) x)
|
||||
{ return this->base_t::insert_equal(boost::move(x)); }
|
||||
|
||||
//! <b>Effects</b>: Inserts a new value move-constructed from x and returns
|
||||
@@ -1284,7 +1374,7 @@ class multimap
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
|
||||
//! is inserted right before p.
|
||||
iterator insert(const_iterator p, const value_type& x)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x)
|
||||
{ return this->base_t::insert_equal(p, x); }
|
||||
|
||||
//! <b>Effects</b>: Inserts a new value constructed from x in the container.
|
||||
@@ -1295,7 +1385,7 @@ class multimap
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
|
||||
//! is inserted right before p.
|
||||
iterator insert(const_iterator p, const nonconst_value_type& x)
|
||||
BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const nonconst_value_type& x)
|
||||
{ return this->base_t::insert_equal_convertible(p, x); }
|
||||
|
||||
//! <b>Effects</b>: Inserts a new value move constructed from x in the container.
|
||||
@@ -1306,7 +1396,7 @@ class multimap
|
||||
//!
|
||||
//! <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->base_t::insert_equal_convertible(p, boost::move(x)); }
|
||||
|
||||
//! <b>Effects</b>: Inserts a new value move constructed from x in the container.
|
||||
@@ -1317,7 +1407,7 @@ class multimap
|
||||
//!
|
||||
//! <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->base_t::insert_equal_convertible(p, boost::move(x)); }
|
||||
|
||||
//! <b>Requires</b>: first, last are not iterators into *this.
|
||||
@@ -1326,14 +1416,14 @@ class multimap
|
||||
//!
|
||||
//! <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)
|
||||
//! <b>Effects</b>: inserts each element from the range [il.begin(), il.end().
|
||||
//!
|
||||
//! <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_equal(il.begin(), il.end()); }
|
||||
#endif
|
||||
|
||||
|
@@ -250,7 +250,6 @@ int main ()
|
||||
std::pair<const pair_t,pair_t> p;
|
||||
s.insert(p);
|
||||
s.emplace(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
|
@@ -667,6 +667,65 @@ int map_test()
|
||||
}
|
||||
}
|
||||
|
||||
{ //operator[] test
|
||||
boostmap.clear();
|
||||
boostmultimap.clear();
|
||||
stdmap.clear();
|
||||
stdmultimap.clear();
|
||||
|
||||
IntPairType aux_vect[max];
|
||||
for(int i = 0; i < max; ++i){
|
||||
IntType i1(i);
|
||||
IntType i2(i);
|
||||
new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
|
||||
}
|
||||
|
||||
for(int i = 0; i < max; ++i){
|
||||
boostmap[boost::move(aux_vect[i].first)] = boost::move(aux_vect[i].second);
|
||||
stdmap[i] = i;
|
||||
}
|
||||
|
||||
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
|
||||
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
|
||||
}
|
||||
|
||||
{ //insert_or_assign test
|
||||
boostmap.clear();
|
||||
boostmultimap.clear();
|
||||
stdmap.clear();
|
||||
stdmultimap.clear();
|
||||
|
||||
IntPairType aux_vect[max];
|
||||
for(int i = 0; i < max; ++i){
|
||||
IntType i1(i);
|
||||
IntType i2(i);
|
||||
new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
|
||||
}
|
||||
|
||||
IntPairType aux_vect2[max];
|
||||
for(int i = 0; i < max; ++i){
|
||||
IntType i1(i);
|
||||
IntType i2(max-i);
|
||||
new(&aux_vect2[i])IntPairType(boost::move(i1), boost::move(i2));
|
||||
}
|
||||
|
||||
for(int i = 0; i < max; ++i){
|
||||
boostmap.insert_or_assign(boost::move(aux_vect[i].first), boost::move(aux_vect[i].second));
|
||||
stdmap[i] = i;
|
||||
}
|
||||
|
||||
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
|
||||
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
|
||||
|
||||
for(int i = 0; i < max; ++i){
|
||||
boostmap.insert_or_assign(boost::move(aux_vect2[i].first), boost::move(aux_vect2[i].second));
|
||||
stdmap[i] = max-i;
|
||||
}
|
||||
|
||||
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
|
||||
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
|
||||
}
|
||||
|
||||
if(map_test_copyable<MyBoostMap, MyStdMap, MyBoostMultiMap, MyStdMultiMap>
|
||||
(container_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
|
||||
return 1;
|
||||
|
Reference in New Issue
Block a user