forked from boostorg/container
Merge from trunk
[SVN r80689]
This commit is contained in:
@@ -70,41 +70,41 @@ struct allocator_traits
|
||||
typedef unspecified pointer;
|
||||
//! Alloc::const_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const
|
||||
//!
|
||||
typedef unspecified const_pointer;
|
||||
typedef see_documentation const_pointer;
|
||||
//! Non-standard extension
|
||||
//! Alloc::reference if such a type exists; otherwise, value_type&
|
||||
typedef unspecified reference;
|
||||
typedef see_documentation reference;
|
||||
//! Non-standard extension
|
||||
//! Alloc::const_reference if such a type exists ; otherwise, const value_type&
|
||||
typedef unspecified const_reference;
|
||||
typedef see_documentation const_reference;
|
||||
//! Alloc::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>.
|
||||
//!
|
||||
typedef unspecified void_pointer;
|
||||
typedef see_documentation void_pointer;
|
||||
//! Alloc::const_void_pointer if such a type exists ; otherwis e, pointer_traits<pointer>::rebind<const
|
||||
//!
|
||||
typedef unspecified const_void_pointer;
|
||||
typedef see_documentation const_void_pointer;
|
||||
//! Alloc::difference_type if such a type exists ; otherwise, pointer_traits<pointer>::difference_type.
|
||||
//!
|
||||
typedef unspecified difference_type;
|
||||
typedef see_documentation difference_type;
|
||||
//! Alloc::size_type if such a type exists ; otherwise, make_unsigned<difference_type>::type
|
||||
//!
|
||||
typedef unspecified size_type;
|
||||
typedef see_documentation size_type;
|
||||
//! Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant
|
||||
//! type with internal constant static member `value` == false.
|
||||
typedef unspecified propagate_on_container_copy_assignment;
|
||||
typedef see_documentation propagate_on_container_copy_assignment;
|
||||
//! Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant
|
||||
//! type with internal constant static member `value` == false.
|
||||
typedef unspecified propagate_on_container_move_assignment;
|
||||
typedef see_documentation propagate_on_container_move_assignment;
|
||||
//! Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant
|
||||
//! type with internal constant static member `value` == false.
|
||||
typedef unspecified propagate_on_container_swap;
|
||||
typedef see_documentation propagate_on_container_swap;
|
||||
//! Defines an allocator: Alloc::rebind<T>::other if such a type exists; otherwise, Alloc<T, Args>
|
||||
//! if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or
|
||||
//! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed.
|
||||
//!
|
||||
//! In C++03 compilers `rebind_alloc` is a struct derived from an allocator
|
||||
//! deduced by previously detailed rules.
|
||||
template <class T> using rebind_alloc = unspecified;
|
||||
template <class T> using rebind_alloc = see_documentation;
|
||||
|
||||
//! In C++03 compilers `rebind_traits` is a struct derived from
|
||||
//! `allocator_traits<OtherAlloc>`, where `OtherAlloc` is
|
||||
@@ -115,7 +115,7 @@ struct allocator_traits
|
||||
//! `type` is an allocator related to Alloc deduced deduced by rules explained in `rebind_alloc`.
|
||||
template <class T>
|
||||
struct portable_rebind_alloc
|
||||
{ typedef unspecified_type type; };
|
||||
{ typedef see_documentation type; };
|
||||
#else
|
||||
//pointer
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
|
||||
|
||||
+664
-682
File diff suppressed because it is too large
Load Diff
@@ -348,8 +348,7 @@ class private_adaptive_node_pool_impl
|
||||
{
|
||||
block_iterator block_it(m_block_multiset.end());
|
||||
while(n--){
|
||||
void *pElem = container_detail::to_raw_pointer(chain.front());
|
||||
chain.pop_front();
|
||||
void *pElem = container_detail::to_raw_pointer(chain.pop_front());
|
||||
priv_invariants();
|
||||
block_info_t *block_info = this->priv_block_from_node(pElem);
|
||||
BOOST_ASSERT(block_info->free_nodes.size() < m_real_num_node);
|
||||
|
||||
@@ -173,7 +173,6 @@ struct default_construct_aux_proxy
|
||||
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
|
||||
#include <boost/container/detail/variadic_templates_tools.hpp>
|
||||
#include <boost/container/detail/stored_ref.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <typeinfo>
|
||||
//#include <iostream> //For debugging purposes
|
||||
@@ -227,8 +226,7 @@ struct advanced_insert_aux_non_movable_emplace
|
||||
if(!this->used_){
|
||||
alloc_traits::construct( this->a_
|
||||
, container_detail::to_raw_pointer(&*p)
|
||||
, ::boost::container::container_detail::
|
||||
stored_ref<Args>::forward(get<IdxPack>(this->args_))...
|
||||
, ::boost::forward<Args>(get<IdxPack>(this->args_))...
|
||||
);
|
||||
this->used_ = true;
|
||||
}
|
||||
@@ -241,8 +239,7 @@ struct advanced_insert_aux_non_movable_emplace
|
||||
if(!this->used_){
|
||||
alloc_traits::construct( this->a_
|
||||
, container_detail::to_raw_pointer(&*p)
|
||||
, ::boost::container::container_detail::
|
||||
stored_ref<Args>::forward(get<IdxPack>(this->args_))...
|
||||
, ::boost::forward<Args>(get<IdxPack>(this->args_))...
|
||||
);
|
||||
this->used_ = true;
|
||||
}
|
||||
@@ -288,7 +285,7 @@ struct advanced_insert_aux_emplace
|
||||
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
|
||||
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
|
||||
alloc_traits::construct(this->a_, vp,
|
||||
::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...);
|
||||
::boost::forward<Args>(get<IdxPack>(this->args_))...);
|
||||
scoped_destructor<A> d(this->a_, vp);
|
||||
*p = ::boost::move(*vp);
|
||||
d.release();
|
||||
@@ -305,7 +302,7 @@ struct advanced_insert_aux_emplace
|
||||
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
|
||||
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
|
||||
alloc_traits::construct(this->a_, vp,
|
||||
::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...);
|
||||
::boost::forward<Args>(get<IdxPack>(this->args_))...);
|
||||
try {
|
||||
*p = ::boost::move(*vp);
|
||||
} catch (...) {
|
||||
@@ -413,7 +410,7 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)
|
||||
alloc_traits::construct(this->a_, vp \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
|
||||
scoped_destructor<A> d(this->a_, vp); \
|
||||
*p = ::boost::move(*vp); \
|
||||
*p = ::boost::move(*vp); \
|
||||
d.release(); \
|
||||
this->used_ = true; \
|
||||
} \
|
||||
@@ -430,7 +427,7 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)
|
||||
alloc_traits::construct(this->a_, vp \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
|
||||
scoped_destructor<A> d(this->a_, vp); \
|
||||
*p = ::boost::move(*vp); \
|
||||
*p = ::boost::move(*vp); \
|
||||
d.release(); \
|
||||
this->used_ = true; \
|
||||
} \
|
||||
|
||||
@@ -34,6 +34,30 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
template<class It>
|
||||
struct is_default_construct_iterator
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class U, class D>
|
||||
struct is_default_construct_iterator<default_construct_iterator<U, D> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<class It>
|
||||
struct is_emplace_iterator
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class U, class EF, class D>
|
||||
struct is_emplace_iterator<emplace_iterator<U, EF, D> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<class A, class T, class InpIt>
|
||||
inline void construct_in_place(A &a, T* dest, InpIt source)
|
||||
{ boost::container::allocator_traits<A>::construct(a, dest, *source); }
|
||||
|
||||
@@ -27,6 +27,68 @@ namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
//!A deleter for scoped_ptr that deallocates the memory
|
||||
//!allocated for an object using a STL allocator.
|
||||
template <class A>
|
||||
struct scoped_deallocator
|
||||
{
|
||||
typedef allocator_traits<A> allocator_traits_type;
|
||||
typedef typename allocator_traits_type::pointer pointer;
|
||||
typedef container_detail::integral_constant<unsigned,
|
||||
boost::container::container_detail::
|
||||
version<A>::value> alloc_version;
|
||||
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
|
||||
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
|
||||
|
||||
private:
|
||||
void priv_deallocate(allocator_v1)
|
||||
{ m_alloc.deallocate(m_ptr, 1); }
|
||||
|
||||
void priv_deallocate(allocator_v2)
|
||||
{ m_alloc.deallocate_one(m_ptr); }
|
||||
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
|
||||
|
||||
public:
|
||||
|
||||
pointer m_ptr;
|
||||
A& m_alloc;
|
||||
|
||||
scoped_deallocator(pointer p, A& a)
|
||||
: m_ptr(p), m_alloc(a)
|
||||
{}
|
||||
|
||||
~scoped_deallocator()
|
||||
{ if (m_ptr)priv_deallocate(alloc_version()); }
|
||||
|
||||
scoped_deallocator(BOOST_RV_REF(scoped_deallocator) o)
|
||||
: m_ptr(o.m_ptr), m_alloc(o.m_alloc)
|
||||
{ o.release(); }
|
||||
|
||||
pointer get() const
|
||||
{ return m_ptr; }
|
||||
|
||||
void release()
|
||||
{ m_ptr = 0; }
|
||||
};
|
||||
|
||||
template <class Allocator>
|
||||
struct null_scoped_deallocator
|
||||
{
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
||||
typedef typename AllocTraits::pointer pointer;
|
||||
typedef typename AllocTraits::size_type size_type;
|
||||
|
||||
null_scoped_deallocator(pointer, Allocator&, size_type)
|
||||
{}
|
||||
|
||||
void release()
|
||||
{}
|
||||
|
||||
pointer get() const
|
||||
{ return pointer(); }
|
||||
};
|
||||
|
||||
//!A deleter for scoped_ptr that deallocates the memory
|
||||
//!allocated for an array of objects using a STL allocator.
|
||||
template <class Allocator>
|
||||
@@ -239,10 +301,57 @@ class allocator_destroyer
|
||||
void operator()(const pointer &p)
|
||||
{
|
||||
AllocTraits::destroy(a_, container_detail::to_raw_pointer(p));
|
||||
priv_deallocate(p, alloc_version());
|
||||
this->priv_deallocate(p, alloc_version());
|
||||
}
|
||||
};
|
||||
|
||||
template <class A>
|
||||
class allocator_destroyer_and_chain_builder
|
||||
{
|
||||
typedef allocator_traits<A> allocator_traits_type;
|
||||
typedef typename allocator_traits_type::value_type value_type;
|
||||
typedef typename A::multiallocation_chain multiallocation_chain;
|
||||
|
||||
A & a_;
|
||||
multiallocation_chain &c_;
|
||||
|
||||
public:
|
||||
allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c)
|
||||
: a_(a), c_(c)
|
||||
{}
|
||||
|
||||
void operator()(const typename A::pointer &p)
|
||||
{
|
||||
allocator_traits<A>::destroy(a_, container_detail::to_raw_pointer(p));
|
||||
c_.push_front(p);
|
||||
}
|
||||
};
|
||||
|
||||
template <class A>
|
||||
class allocator_multialloc_chain_node_deallocator
|
||||
{
|
||||
typedef allocator_traits<A> allocator_traits_type;
|
||||
typedef typename allocator_traits_type::value_type value_type;
|
||||
typedef typename A::multiallocation_chain multiallocation_chain;
|
||||
typedef allocator_destroyer_and_chain_builder<A> chain_builder;
|
||||
|
||||
A & a_;
|
||||
multiallocation_chain c_;
|
||||
|
||||
public:
|
||||
allocator_multialloc_chain_node_deallocator(A &a)
|
||||
: a_(a), c_()
|
||||
{}
|
||||
|
||||
chain_builder get_chain_builder()
|
||||
{ return chain_builder(a_, c_); }
|
||||
|
||||
~allocator_multialloc_chain_node_deallocator()
|
||||
{
|
||||
if(!c_.empty())
|
||||
a_.deallocate_individual(boost::move(c_));
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
|
||||
@@ -214,6 +214,21 @@ class flat_tree
|
||||
: m_data(comp, a)
|
||||
{ this->m_data.m_vect.insert(this->m_data.m_vect.end(), first, last); }
|
||||
|
||||
template <class InputIterator>
|
||||
flat_tree( bool unique_insertion
|
||||
, InputIterator first, InputIterator last
|
||||
, const Compare& comp = Compare()
|
||||
, const allocator_type& a = allocator_type())
|
||||
: m_data(comp, a)
|
||||
{
|
||||
if(unique_insertion){
|
||||
this->insert_unique(first, last);
|
||||
}
|
||||
else{
|
||||
this->insert_equal(first, last);
|
||||
}
|
||||
}
|
||||
|
||||
~flat_tree()
|
||||
{ }
|
||||
|
||||
@@ -290,9 +305,9 @@ class flat_tree
|
||||
std::pair<iterator,bool> insert_unique(const value_type& val)
|
||||
{
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data);
|
||||
std::pair<iterator,bool> ret = this->priv_insert_unique_prepare(val, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, val);
|
||||
ret.first = this->priv_insert_commit(data, val);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -300,9 +315,9 @@ class flat_tree
|
||||
std::pair<iterator,bool> insert_unique(BOOST_RV_REF(value_type) val)
|
||||
{
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data);
|
||||
std::pair<iterator,bool> ret = this->priv_insert_unique_prepare(val, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, boost::move(val));
|
||||
ret.first = this->priv_insert_commit(data, boost::move(val));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -324,9 +339,9 @@ class flat_tree
|
||||
iterator insert_unique(const_iterator pos, const value_type& val)
|
||||
{
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, val, data);
|
||||
std::pair<iterator,bool> ret = this->priv_insert_unique_prepare(pos, val, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, val);
|
||||
ret.first = this->priv_insert_commit(data, val);
|
||||
}
|
||||
return ret.first;
|
||||
}
|
||||
@@ -334,9 +349,9 @@ class flat_tree
|
||||
iterator insert_unique(const_iterator pos, BOOST_RV_REF(value_type) mval)
|
||||
{
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, mval, data);
|
||||
std::pair<iterator,bool> ret = this->priv_insert_unique_prepare(pos, mval, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, boost::move(mval));
|
||||
ret.first = this->priv_insert_commit(data, boost::move(mval));
|
||||
}
|
||||
return ret.first;
|
||||
}
|
||||
@@ -345,45 +360,164 @@ class flat_tree
|
||||
{
|
||||
insert_commit_data data;
|
||||
this->priv_insert_equal_prepare(pos, val, data);
|
||||
return priv_insert_commit(data, val);
|
||||
return this->priv_insert_commit(data, val);
|
||||
}
|
||||
|
||||
iterator insert_equal(const_iterator pos, BOOST_RV_REF(value_type) mval)
|
||||
{
|
||||
insert_commit_data data;
|
||||
this->priv_insert_equal_prepare(pos, mval, data);
|
||||
return priv_insert_commit(data, boost::move(mval));
|
||||
return this->priv_insert_commit(data, boost::move(mval));
|
||||
}
|
||||
|
||||
template <class InIt>
|
||||
void insert_unique(InIt first, InIt last)
|
||||
{ this->priv_insert_unique_loop(first, last); }
|
||||
|
||||
template <class InIt>
|
||||
void insert_equal(InIt first, InIt last
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
< container_detail::is_input_iterator<InIt>::value
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{ this->priv_insert_equal_loop(first, last); }
|
||||
|
||||
template <class InIt>
|
||||
void insert_equal(InIt first, InIt last
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
< !container_detail::is_input_iterator<InIt>::value
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
for ( ; first != last; ++first)
|
||||
this->insert_unique(*first);
|
||||
const size_type len = static_cast<size_type>(std::distance(first, last));
|
||||
this->reserve(this->size()+len);
|
||||
this->priv_insert_equal_loop(first, last);
|
||||
}
|
||||
|
||||
//Ordered
|
||||
|
||||
template <class InIt>
|
||||
void insert_equal(ordered_range_t, InIt first, InIt last
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
< container_detail::is_input_iterator<InIt>::value
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{ this->priv_insert_equal_loop_ordered(first, last); }
|
||||
|
||||
template <class FwdIt>
|
||||
void insert_equal(ordered_range_t, FwdIt first, FwdIt last
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
< container_detail::is_forward_iterator<FwdIt>::value
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
const size_type len = static_cast<size_type>(std::distance(first, last));
|
||||
this->reserve(this->size()+len);
|
||||
this->priv_insert_equal_loop_ordered(first, last);
|
||||
}
|
||||
|
||||
template <class BidirIt>
|
||||
void insert_equal(ordered_range_t, BidirIt first, BidirIt last
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
< !container_detail::is_input_iterator<BidirIt>::value &&
|
||||
!container_detail::is_forward_iterator<BidirIt>::value
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
size_type len = static_cast<size_type>(std::distance(first, last));
|
||||
const size_type BurstSize = 16;
|
||||
size_type positions[BurstSize];
|
||||
|
||||
//Prereserve all memory so that iterators are not invalidated
|
||||
this->reserve(this->size()+len);
|
||||
const const_iterator beg(this->cbegin());
|
||||
const_iterator pos(beg);
|
||||
//Loop in burst sizes
|
||||
while(len){
|
||||
const size_type burst = len < BurstSize ? len : BurstSize;
|
||||
const const_iterator cend(this->cend());
|
||||
len -= burst;
|
||||
for(size_type i = 0; i != burst; ++i){
|
||||
//Get the insertion position for each key
|
||||
pos = const_cast<const flat_tree&>(*this).priv_upper_bound(pos, cend, KeyOfValue()(*first));
|
||||
positions[i] = static_cast<size_type>(pos - beg);
|
||||
++first;
|
||||
}
|
||||
//Insert all in a single step in the precalculated positions
|
||||
this->m_data.m_vect.insert_ordered_at(burst, positions + burst, first);
|
||||
//Next search position updated
|
||||
pos += burst;
|
||||
}
|
||||
}
|
||||
|
||||
template <class InIt>
|
||||
void insert_equal(InIt first, InIt last)
|
||||
{
|
||||
typedef typename
|
||||
std::iterator_traits<InIt>::iterator_category ItCat;
|
||||
this->priv_insert_equal(first, last, ItCat());
|
||||
}
|
||||
void insert_unique(ordered_unique_range_t, InIt first, InIt last
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
< container_detail::is_input_iterator<InIt>::value ||
|
||||
container_detail::is_forward_iterator<InIt>::value
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{ this->priv_insert_unique_loop_hint(first, last); }
|
||||
|
||||
template <class InIt>
|
||||
void insert_equal(ordered_range_t, InIt first, InIt last)
|
||||
template <class BidirIt>
|
||||
void insert_unique(ordered_unique_range_t, BidirIt first, BidirIt last
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
< !(container_detail::is_input_iterator<BidirIt>::value ||
|
||||
container_detail::is_forward_iterator<BidirIt>::value)
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
typedef typename
|
||||
std::iterator_traits<InIt>::iterator_category ItCat;
|
||||
this->priv_insert_equal(ordered_range_t(), first, last, ItCat());
|
||||
}
|
||||
size_type len = static_cast<size_type>(std::distance(first, last));
|
||||
const size_type BurstSize = 16;
|
||||
size_type positions[BurstSize];
|
||||
size_type skips[BurstSize];
|
||||
|
||||
template <class InIt>
|
||||
void insert_unique(ordered_unique_range_t, InIt first, InIt last)
|
||||
{
|
||||
typedef typename
|
||||
std::iterator_traits<InIt>::iterator_category ItCat;
|
||||
this->priv_insert_unique(ordered_unique_range_t(), first, last, ItCat());
|
||||
//Prereserve all memory so that iterators are not invalidated
|
||||
this->reserve(this->size()+len);
|
||||
const const_iterator beg(this->cbegin());
|
||||
const_iterator pos(beg);
|
||||
const value_compare &value_comp = this->m_data;
|
||||
//Loop in burst sizes
|
||||
while(len){
|
||||
skips[0u] = 0u;
|
||||
const size_type burst = len < BurstSize ? len : BurstSize;
|
||||
size_type unique_burst = 0u;
|
||||
const const_iterator cend(this->cend());
|
||||
while(unique_burst < burst && len > 0){
|
||||
//Get the insertion position for each key
|
||||
const value_type & val = *first++;
|
||||
--len;
|
||||
pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, cend, KeyOfValue()(val));
|
||||
//Check if already present
|
||||
if(pos != cend && !value_comp(*pos, val)){
|
||||
++skips[unique_burst];
|
||||
continue;
|
||||
}
|
||||
|
||||
//If not present, calculate position
|
||||
positions[unique_burst] = static_cast<size_type>(pos - beg);
|
||||
if(++unique_burst < burst)
|
||||
skips[unique_burst] = 0u;
|
||||
}
|
||||
//Insert all in a single step in the precalculated positions
|
||||
this->m_data.m_vect.insert_ordered_at(unique_burst, positions + unique_burst, skips + unique_burst, first);
|
||||
//Next search position updated
|
||||
pos += unique_burst;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
@@ -398,9 +532,9 @@ class flat_tree
|
||||
value_destructor<stored_allocator_type> d(a, val);
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret =
|
||||
priv_insert_unique_prepare(val, data);
|
||||
this->priv_insert_unique_prepare(val, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, boost::move(val));
|
||||
ret.first = this->priv_insert_commit(data, boost::move(val));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -414,9 +548,9 @@ class flat_tree
|
||||
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
|
||||
value_destructor<stored_allocator_type> d(a, val);
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
|
||||
std::pair<iterator,bool> ret = this->priv_insert_unique_prepare(hint, val, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, boost::move(val));
|
||||
ret.first = this->priv_insert_commit(data, boost::move(val));
|
||||
}
|
||||
return ret.first;
|
||||
}
|
||||
@@ -444,7 +578,7 @@ class flat_tree
|
||||
value_destructor<stored_allocator_type> d(a, val);
|
||||
insert_commit_data data;
|
||||
this->priv_insert_equal_prepare(hint, val, data);
|
||||
iterator i = priv_insert_commit(data, boost::move(val));
|
||||
iterator i = this->priv_insert_commit(data, boost::move(val));
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -462,9 +596,9 @@ class flat_tree
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
|
||||
value_destructor<stored_allocator_type> d(a, val); \
|
||||
insert_commit_data data; \
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data); \
|
||||
std::pair<iterator,bool> ret = this->priv_insert_unique_prepare(val, data); \
|
||||
if(ret.second){ \
|
||||
ret.first = priv_insert_commit(data, boost::move(val)); \
|
||||
ret.first = this->priv_insert_commit(data, boost::move(val)); \
|
||||
} \
|
||||
return ret; \
|
||||
} \
|
||||
@@ -480,9 +614,9 @@ class flat_tree
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
|
||||
value_destructor<stored_allocator_type> d(a, val); \
|
||||
insert_commit_data data; \
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data); \
|
||||
std::pair<iterator,bool> ret = this->priv_insert_unique_prepare(hint, val, data); \
|
||||
if(ret.second){ \
|
||||
ret.first = priv_insert_commit(data, boost::move(val)); \
|
||||
ret.first = this->priv_insert_commit(data, boost::move(val)); \
|
||||
} \
|
||||
return ret.first; \
|
||||
} \
|
||||
@@ -513,7 +647,7 @@ class flat_tree
|
||||
value_destructor<stored_allocator_type> d(a, val); \
|
||||
insert_commit_data data; \
|
||||
this->priv_insert_equal_prepare(hint, val, data); \
|
||||
iterator i = priv_insert_commit(data, boost::move(val)); \
|
||||
iterator i = this->priv_insert_commit(data, boost::move(val)); \
|
||||
return i; \
|
||||
} \
|
||||
|
||||
@@ -653,7 +787,7 @@ class flat_tree
|
||||
|
||||
std::pair<iterator,bool> priv_insert_unique_prepare
|
||||
(const value_type& val, insert_commit_data &commit_data)
|
||||
{ return priv_insert_unique_prepare(this->begin(), this->end(), val, commit_data); }
|
||||
{ return this->priv_insert_unique_prepare(this->begin(), this->end(), val, commit_data); }
|
||||
|
||||
std::pair<iterator,bool> priv_insert_unique_prepare
|
||||
(const_iterator pos, const value_type& val, insert_commit_data &commit_data)
|
||||
@@ -794,102 +928,38 @@ class flat_tree
|
||||
return std::pair<RanIt, RanIt>(first, first);
|
||||
}
|
||||
|
||||
template <class BidirIt>
|
||||
void priv_insert_equal(ordered_range_t, BidirIt first, BidirIt last, std::bidirectional_iterator_tag)
|
||||
template<class InIt>
|
||||
void priv_insert_equal_loop(InIt first, InIt last)
|
||||
{
|
||||
size_type len = static_cast<size_type>(std::distance(first, last));
|
||||
const size_type BurstSize = 16;
|
||||
size_type positions[BurstSize];
|
||||
|
||||
//Prereserve all memory so that iterators are not invalidated
|
||||
this->reserve(this->size()+len);
|
||||
const const_iterator beg(this->cbegin());
|
||||
const_iterator pos(beg);
|
||||
//Loop in burst sizes
|
||||
while(len){
|
||||
const size_type burst = len < BurstSize ? len : BurstSize;
|
||||
const const_iterator cend(this->cend());
|
||||
len -= burst;
|
||||
for(size_type i = 0; i != burst; ++i){
|
||||
//Get the insertion position for each key
|
||||
pos = const_cast<const flat_tree&>(*this).priv_upper_bound(pos, cend, KeyOfValue()(*first));
|
||||
positions[i] = static_cast<size_type>(pos - beg);
|
||||
++first;
|
||||
}
|
||||
//Insert all in a single step in the precalculated positions
|
||||
this->m_data.m_vect.insert_ordered_at(burst, positions + burst, first);
|
||||
//Next search position updated
|
||||
pos += burst;
|
||||
}
|
||||
}
|
||||
|
||||
template <class BidirIt>
|
||||
void priv_insert_unique(ordered_unique_range_t, BidirIt first, BidirIt last, std::bidirectional_iterator_tag)
|
||||
{
|
||||
size_type len = static_cast<size_type>(std::distance(first, last));
|
||||
const size_type BurstSize = 16;
|
||||
size_type positions[BurstSize];
|
||||
size_type skips[BurstSize];
|
||||
|
||||
//Prereserve all memory so that iterators are not invalidated
|
||||
this->reserve(this->size()+len);
|
||||
const const_iterator beg(this->cbegin());
|
||||
const_iterator pos(beg);
|
||||
const value_compare &value_comp = this->m_data;
|
||||
//Loop in burst sizes
|
||||
while(len){
|
||||
skips[0u] = 0u;
|
||||
const size_type burst = len < BurstSize ? len : BurstSize;
|
||||
size_type unique_burst = 0u;
|
||||
const const_iterator cend(this->cend());
|
||||
while(unique_burst < burst && len > 0){
|
||||
//Get the insertion position for each key
|
||||
const value_type & val = *first++;
|
||||
--len;
|
||||
pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, cend, KeyOfValue()(val));
|
||||
//Check if already present
|
||||
if(pos != cend && !value_comp(*pos, val)){
|
||||
++skips[unique_burst];
|
||||
continue;
|
||||
}
|
||||
|
||||
//If not present, calculate position
|
||||
positions[unique_burst] = static_cast<size_type>(pos - beg);
|
||||
if(++unique_burst < burst)
|
||||
skips[unique_burst] = 0u;
|
||||
}
|
||||
//Insert all in a single step in the precalculated positions
|
||||
this->m_data.m_vect.insert_ordered_at(unique_burst, positions + unique_burst, skips + unique_burst, first);
|
||||
//Next search position updated
|
||||
pos += unique_burst;
|
||||
}
|
||||
}
|
||||
/*
|
||||
template <class FwdIt>
|
||||
void priv_insert_equal_forward(ordered_range_t, FwdIt first, FwdIt last, std::forward_iterator_tag)
|
||||
{ this->priv_insert_equal(first, last, std::forward_iterator_tag()); }
|
||||
*/
|
||||
template <class InIt>
|
||||
void priv_insert_equal(ordered_range_t, InIt first, InIt last, std::input_iterator_tag)
|
||||
{ this->priv_insert_equal(first, last, std::input_iterator_tag()); }
|
||||
|
||||
template <class InIt>
|
||||
void priv_insert_unique(ordered_unique_range_t, InIt first, InIt last, std::input_iterator_tag)
|
||||
{ this->priv_insert_unique(first, last, std::input_iterator_tag()); }
|
||||
/*
|
||||
template <class FwdIt>
|
||||
void priv_insert_equal_forward(FwdIt first, FwdIt last, std::forward_iterator_tag)
|
||||
{
|
||||
const size_type len = static_cast<size_type>(std::distance(first, last));
|
||||
this->reserve(this->size()+len);
|
||||
this->priv_insert_equal(first, last, std::input_iterator_tag());
|
||||
}
|
||||
*/
|
||||
template <class InIt>
|
||||
void priv_insert_equal(InIt first, InIt last, std::input_iterator_tag)
|
||||
{
|
||||
for ( ; first != last; ++first)
|
||||
for ( ; first != last; ++first){
|
||||
this->insert_equal(*first);
|
||||
}
|
||||
}
|
||||
|
||||
template<class InIt>
|
||||
void priv_insert_equal_loop_ordered(InIt first, InIt last)
|
||||
{
|
||||
const_iterator pos(this->cend());
|
||||
for ( ; first != last; ++first){
|
||||
pos = this->insert_equal(pos, *first);
|
||||
}
|
||||
}
|
||||
|
||||
template<class InIt>
|
||||
void priv_insert_unique_loop(InIt first, InIt last)
|
||||
{
|
||||
for ( ; first != last; ++first){
|
||||
this->insert_unique(*first);
|
||||
}
|
||||
}
|
||||
|
||||
template<class InIt>
|
||||
void priv_insert_unique_loop_ordered(InIt first, InIt last)
|
||||
{
|
||||
const_iterator pos(this->cend());
|
||||
for ( ; first != last; ++first){
|
||||
pos = this->insert_unique(pos, *first);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
#include <boost/container/detail/variadic_templates_tools.hpp>
|
||||
#include <boost/container/detail/stored_ref.hpp>
|
||||
#else
|
||||
#include <boost/container/detail/preprocessor.hpp>
|
||||
#endif
|
||||
@@ -222,14 +222,12 @@ class default_construct_iterator
|
||||
default_construct_iterator operator-(Difference off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
const T& operator*() const
|
||||
{ return dereference(); }
|
||||
|
||||
const T* operator->() const
|
||||
{ return &(dereference()); }
|
||||
|
||||
const T& operator[] (Difference n) const
|
||||
{ return dereference(); }
|
||||
//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;
|
||||
|
||||
private:
|
||||
Difference m_num;
|
||||
@@ -445,14 +443,12 @@ class emplace_iterator
|
||||
this_type operator-(difference_type off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
const T& operator*() const
|
||||
{ return dereference(); }
|
||||
|
||||
const T& operator[](difference_type) const
|
||||
{ return dereference(); }
|
||||
|
||||
const T* operator->() const
|
||||
{ return &(dereference()); }
|
||||
//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;
|
||||
|
||||
template<class A>
|
||||
void construct_in_place(A &a, T* ptr)
|
||||
@@ -506,8 +502,7 @@ struct emplace_functor
|
||||
void inplace_impl(A &a, T* ptr, const container_detail::index_tuple<IdxPack...>&)
|
||||
{
|
||||
allocator_traits<A>::construct
|
||||
(a, ptr, container_detail::stored_ref<Args>::forward
|
||||
(container_detail::get<IdxPack>(args_))...);
|
||||
(a, ptr, ::boost::forward<Args>(container_detail::get<IdxPack>(args_))...);
|
||||
}
|
||||
|
||||
container_detail::tuple<Args&...> args_;
|
||||
@@ -539,10 +534,78 @@ struct emplace_functor
|
||||
|
||||
#endif
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
template<class T>
|
||||
struct has_iterator_category
|
||||
{
|
||||
template <typename X>
|
||||
static char test(int, typename X::iterator_category*);
|
||||
|
||||
template <typename X>
|
||||
static int test(int, ...);
|
||||
|
||||
static const bool value = (1 == sizeof(test<T>(0, 0)));
|
||||
};
|
||||
|
||||
|
||||
template<class T, bool = has_iterator_category<T>::value >
|
||||
struct is_input_iterator
|
||||
{
|
||||
static const bool value = is_same<typename T::iterator_category, std::input_iterator_tag>::value;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_input_iterator<T, false>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T, bool = has_iterator_category<T>::value >
|
||||
struct is_forward_iterator
|
||||
{
|
||||
static const bool value = is_same<typename T::iterator_category, std::forward_iterator_tag>::value;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_forward_iterator<T, false>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T, bool = has_iterator_category<T>::value >
|
||||
struct is_bidirectional_iterator
|
||||
{
|
||||
static const bool value = is_same<typename T::iterator_category, std::bidirectional_iterator_tag>::value;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_bidirectional_iterator<T, false>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T, class IIterator>
|
||||
struct iiterator_types
|
||||
{
|
||||
typedef typename std::iterator_traits<IIterator>::pointer it_pointer;
|
||||
typedef typename std::iterator_traits<IIterator>::difference_type difference_type;
|
||||
typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
|
||||
template rebind_pointer<T>::type pointer;
|
||||
typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
|
||||
template rebind_pointer<const T>::type const_pointer;
|
||||
typedef typename ::boost::intrusive::
|
||||
pointer_traits<pointer>::reference reference;
|
||||
typedef typename ::boost::intrusive::
|
||||
pointer_traits<const_pointer>::reference const_reference;
|
||||
};
|
||||
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
||||
|
||||
|
||||
@@ -45,14 +45,30 @@ class basic_multiallocation_chain
|
||||
> slist_impl_t;
|
||||
slist_impl_t slist_impl_;
|
||||
|
||||
static node & to_node(VoidPointer p)
|
||||
{ return *static_cast<node*>(static_cast<void*>(container_detail::to_raw_pointer(p))); }
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<VoidPointer>::template rebind_pointer<node>::type node_ptr;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<node_ptr> node_ptr_traits;
|
||||
|
||||
static node & build_node(const VoidPointer &p)
|
||||
{
|
||||
return *::new (static_cast<node*>(static_cast<void*>(container_detail::to_raw_pointer(p)))) node;
|
||||
}
|
||||
|
||||
static VoidPointer destroy_node(node &n)
|
||||
{
|
||||
VoidPointer retptr = node_ptr_traits::pointer_to(n);
|
||||
n.~node();
|
||||
return retptr;
|
||||
}
|
||||
|
||||
static node_ptr to_node_ptr(VoidPointer p)
|
||||
{ return node_ptr_traits::static_cast_from(p); }
|
||||
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain)
|
||||
|
||||
public:
|
||||
|
||||
|
||||
typedef VoidPointer void_pointer;
|
||||
typedef typename slist_impl_t::iterator iterator;
|
||||
typedef typename slist_impl_t::size_type size_type;
|
||||
@@ -94,19 +110,21 @@ class basic_multiallocation_chain
|
||||
{ slist_impl_.clear(); }
|
||||
|
||||
iterator insert_after(iterator it, void_pointer m)
|
||||
{ return slist_impl_.insert_after(it, to_node(m)); }
|
||||
{ return slist_impl_.insert_after(it, build_node(m)); }
|
||||
|
||||
void push_front(void_pointer m)
|
||||
{ return slist_impl_.push_front(to_node(m)); }
|
||||
{ return slist_impl_.push_front(build_node(m)); }
|
||||
|
||||
void push_back(void_pointer m)
|
||||
{ return slist_impl_.push_back(to_node(m)); }
|
||||
{ return slist_impl_.push_back(build_node(m)); }
|
||||
|
||||
void pop_front()
|
||||
{ return slist_impl_.pop_front(); }
|
||||
|
||||
void *front()
|
||||
{ return &*slist_impl_.begin(); }
|
||||
void_pointer pop_front()
|
||||
{
|
||||
node & n = slist_impl_.front();
|
||||
void_pointer ret = destroy_node(n);
|
||||
slist_impl_.pop_front();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin, iterator before_end)
|
||||
{ slist_impl_.splice_after(after_this, x.slist_impl_, before_begin, before_end); }
|
||||
@@ -118,10 +136,12 @@ class basic_multiallocation_chain
|
||||
{ slist_impl_.splice_after(after_this, x.slist_impl_); }
|
||||
|
||||
void incorporate_after(iterator after_this, void_pointer begin , iterator before_end)
|
||||
{ slist_impl_.incorporate_after(after_this, &to_node(begin), &to_node(before_end)); }
|
||||
{
|
||||
slist_impl_.incorporate_after(after_this, to_node_ptr(begin), to_node_ptr(before_end));
|
||||
}
|
||||
|
||||
void incorporate_after(iterator after_this, void_pointer begin, void_pointer before_end, size_type n)
|
||||
{ slist_impl_.incorporate_after(after_this, &to_node(begin), &to_node(before_end), n); }
|
||||
{ slist_impl_.incorporate_after(after_this, to_node_ptr(begin), to_node_ptr(before_end), n); }
|
||||
|
||||
void swap(basic_multiallocation_chain &x)
|
||||
{ slist_impl_.swap(x.slist_impl_); }
|
||||
@@ -157,18 +177,20 @@ class transform_multiallocation_chain
|
||||
MultiallocationChain holder_;
|
||||
typedef typename MultiallocationChain::void_pointer void_pointer;
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<void_pointer>::template rebind_pointer<T>::type pointer;
|
||||
<void_pointer> void_pointer_traits;
|
||||
typedef typename void_pointer_traits::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<pointer> pointer_traits;
|
||||
|
||||
static pointer cast(void_pointer p)
|
||||
{
|
||||
return pointer(static_cast<T*>(container_detail::to_raw_pointer(p)));
|
||||
}
|
||||
static pointer cast(const void_pointer &p)
|
||||
{ return pointer_traits::static_cast_from(p); }
|
||||
|
||||
public:
|
||||
typedef transform_iterator
|
||||
< typename MultiallocationChain::iterator
|
||||
, container_detail::cast_functor <T> > iterator;
|
||||
typedef typename MultiallocationChain::size_type size_type;
|
||||
, container_detail::cast_functor <T> > iterator;
|
||||
typedef typename MultiallocationChain::size_type size_type;
|
||||
|
||||
transform_multiallocation_chain()
|
||||
: holder_()
|
||||
@@ -198,14 +220,11 @@ class transform_multiallocation_chain
|
||||
void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_begin, iterator before_end, size_type n)
|
||||
{ holder_.splice_after(after_this.base(), x.holder_, before_begin.base(), before_end.base(), n); }
|
||||
|
||||
void incorporate_after(iterator after_this, void_pointer begin, void_pointer before_end, size_type n)
|
||||
void incorporate_after(iterator after_this, pointer begin, pointer before_end, size_type n)
|
||||
{ holder_.incorporate_after(after_this.base(), begin, before_end, n); }
|
||||
|
||||
void pop_front()
|
||||
{ holder_.pop_front(); }
|
||||
|
||||
pointer front()
|
||||
{ return cast(holder_.front()); }
|
||||
pointer pop_front()
|
||||
{ return cast(holder_.pop_front()); }
|
||||
|
||||
bool empty() const
|
||||
{ return holder_.empty(); }
|
||||
@@ -234,8 +253,11 @@ class transform_multiallocation_chain
|
||||
static iterator iterator_to(pointer p)
|
||||
{ return iterator(MultiallocationChain::iterator_to(p)); }
|
||||
|
||||
std::pair<void_pointer, void_pointer> extract_data()
|
||||
{ return holder_.extract_data(); }
|
||||
std::pair<pointer, pointer> extract_data()
|
||||
{
|
||||
std::pair<void_pointer, void_pointer> data(holder_.extract_data());
|
||||
return std::pair<pointer, pointer>(cast(data.first), cast(data.second));
|
||||
}
|
||||
|
||||
MultiallocationChain extract_multiallocation_chain()
|
||||
{
|
||||
|
||||
@@ -43,99 +43,6 @@ namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
//!A deleter for scoped_ptr that deallocates the memory
|
||||
//!allocated for an object using a STL allocator.
|
||||
template <class A>
|
||||
struct scoped_deallocator
|
||||
{
|
||||
typedef allocator_traits<A> allocator_traits_type;
|
||||
typedef typename allocator_traits_type::pointer pointer;
|
||||
typedef container_detail::integral_constant<unsigned,
|
||||
boost::container::container_detail::
|
||||
version<A>::value> alloc_version;
|
||||
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
|
||||
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
|
||||
|
||||
private:
|
||||
void priv_deallocate(allocator_v1)
|
||||
{ m_alloc.deallocate(m_ptr, 1); }
|
||||
|
||||
void priv_deallocate(allocator_v2)
|
||||
{ m_alloc.deallocate_one(m_ptr); }
|
||||
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
|
||||
|
||||
public:
|
||||
|
||||
pointer m_ptr;
|
||||
A& m_alloc;
|
||||
|
||||
scoped_deallocator(pointer p, A& a)
|
||||
: m_ptr(p), m_alloc(a)
|
||||
{}
|
||||
|
||||
~scoped_deallocator()
|
||||
{ if (m_ptr)priv_deallocate(alloc_version()); }
|
||||
|
||||
scoped_deallocator(BOOST_RV_REF(scoped_deallocator) o)
|
||||
: m_ptr(o.m_ptr), m_alloc(o.m_alloc)
|
||||
{ o.release(); }
|
||||
|
||||
pointer get() const
|
||||
{ return m_ptr; }
|
||||
|
||||
void release()
|
||||
{ m_ptr = 0; }
|
||||
};
|
||||
|
||||
template <class A>
|
||||
class allocator_destroyer_and_chain_builder
|
||||
{
|
||||
typedef allocator_traits<A> allocator_traits_type;
|
||||
typedef typename allocator_traits_type::value_type value_type;
|
||||
typedef typename A::multiallocation_chain multiallocation_chain;
|
||||
|
||||
A & a_;
|
||||
multiallocation_chain &c_;
|
||||
|
||||
public:
|
||||
allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c)
|
||||
: a_(a), c_(c)
|
||||
{}
|
||||
|
||||
void operator()(const typename A::pointer &p)
|
||||
{
|
||||
allocator_traits<A>::destroy(a_, container_detail::to_raw_pointer(p));
|
||||
c_.push_front(p);
|
||||
}
|
||||
};
|
||||
|
||||
template <class A>
|
||||
class allocator_multialloc_chain_node_deallocator
|
||||
{
|
||||
typedef allocator_traits<A> allocator_traits_type;
|
||||
typedef typename allocator_traits_type::value_type value_type;
|
||||
typedef typename A::multiallocation_chain multiallocation_chain;
|
||||
typedef allocator_destroyer_and_chain_builder<A> chain_builder;
|
||||
|
||||
A & a_;
|
||||
multiallocation_chain c_;
|
||||
|
||||
public:
|
||||
allocator_multialloc_chain_node_deallocator(A &a)
|
||||
: a_(a), c_()
|
||||
{}
|
||||
|
||||
chain_builder get_chain_builder()
|
||||
{ return chain_builder(a_, c_); }
|
||||
|
||||
~allocator_multialloc_chain_node_deallocator()
|
||||
{
|
||||
if(!c_.empty())
|
||||
a_.deallocate_individual(boost::move(c_));
|
||||
}
|
||||
};
|
||||
|
||||
template<class ValueCompare, class Node>
|
||||
struct node_compare
|
||||
: private ValueCompare
|
||||
@@ -340,8 +247,7 @@ struct node_alloc_holder
|
||||
Node *p = 0;
|
||||
BOOST_TRY{
|
||||
for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
|
||||
p = container_detail::to_raw_pointer(mem.front());
|
||||
mem.pop_front();
|
||||
p = container_detail::to_raw_pointer(mem.pop_front());
|
||||
//This can throw
|
||||
constructed = 0;
|
||||
boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), beg);
|
||||
|
||||
@@ -16,11 +16,6 @@
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#include <boost/container/detail/stored_ref.hpp>
|
||||
#endif //#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
@@ -78,19 +73,10 @@ const BOOST_PP_CAT(Q, n) & BOOST_PP_CAT(q, n) \
|
||||
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
|
||||
#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
|
||||
|
||||
#define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
|
||||
BOOST_PP_CAT(m_p, n) (static_cast<BOOST_PP_CAT(P, n)>( BOOST_PP_CAT(p, n) )) \
|
||||
|
||||
#else //#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
|
||||
|
||||
#define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
|
||||
BOOST_PP_CAT(m_p, n) (::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
|
||||
//!
|
||||
|
||||
#endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
|
||||
#else //BOOST_NO_RVALUE_REFERENCES
|
||||
|
||||
#define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
|
||||
@@ -102,8 +88,68 @@ const BOOST_PP_CAT(Q, n) & BOOST_PP_CAT(q, n) \
|
||||
|
||||
#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
template<class T>
|
||||
struct ref_holder;
|
||||
|
||||
template<class T>
|
||||
struct ref_holder<T &>
|
||||
{
|
||||
ref_holder(T &t)
|
||||
: t_(t)
|
||||
{}
|
||||
T &t_;
|
||||
T & get() { return t_; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ref_holder<const T>
|
||||
{
|
||||
ref_holder(const T &t)
|
||||
: t_(t)
|
||||
{}
|
||||
const T &t_;
|
||||
const T & get() { return t_; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ref_holder<const T &&>
|
||||
{
|
||||
ref_holder(const T &t)
|
||||
: t_(t)
|
||||
{}
|
||||
const T &t_;
|
||||
const T & get() { return t_; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ref_holder
|
||||
{
|
||||
ref_holder(T &&t)
|
||||
: t_(t)
|
||||
{}
|
||||
T &t_;
|
||||
T && get() { return ::boost::move(t_); }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ref_holder<T &&>
|
||||
{
|
||||
ref_holder(T &&t)
|
||||
: t(t)
|
||||
{}
|
||||
T &t;
|
||||
T && get() { return ::boost::move(t_); }
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data) \
|
||||
BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
|
||||
::boost::container::container_detail::ref_holder<BOOST_PP_CAT(P, n)> BOOST_PP_CAT(m_p, n); \
|
||||
//!
|
||||
|
||||
#else //BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
|
||||
@@ -123,8 +169,7 @@ const BOOST_PP_CAT(Q, n) & BOOST_PP_CAT(q, n) \
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
|
||||
|
||||
#define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) \
|
||||
::boost::container::container_detail::stored_ref< BOOST_PP_CAT(P, n) >::forward( BOOST_PP_CAT(this->m_p, n) ) \
|
||||
#define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) BOOST_PP_CAT(this->m_p, n).get() \
|
||||
//!
|
||||
|
||||
#else //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. 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_STORED_REF_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_STORED_REF_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
|
||||
namespace boost{
|
||||
namespace container{
|
||||
namespace container_detail{
|
||||
|
||||
template<class T>
|
||||
struct stored_ref
|
||||
{
|
||||
|
||||
static T && forward(T &t)
|
||||
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
{ return t; }
|
||||
#else
|
||||
{ return boost::move(t); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct stored_ref<const T>
|
||||
{
|
||||
static const T && forward(const T &t)
|
||||
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
{ return t; }
|
||||
#else
|
||||
{ return static_cast<const T&&>(t); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct stored_ref<T&&>
|
||||
{
|
||||
static T && forward(T &t)
|
||||
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
{ return t; }
|
||||
#else
|
||||
{ return boost::move(t); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct stored_ref<const T&&>
|
||||
{
|
||||
static const T && forward(const T &t)
|
||||
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
{ return t; }
|
||||
#else
|
||||
{ return static_cast<const T &&>(t); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct stored_ref<const T&>
|
||||
{
|
||||
static const T & forward(const T &t)
|
||||
{ return t; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct stored_ref<T&>
|
||||
{
|
||||
static T & forward(T &t)
|
||||
{ return t; }
|
||||
};
|
||||
|
||||
} //namespace container_detail{
|
||||
} //namespace container{
|
||||
} //namespace boost{
|
||||
|
||||
#else
|
||||
#error "This header can be included only for compiler with rvalue references"
|
||||
#endif //BOOST_NO_RVALUE_REFERENCES
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_STORED_REF_HPP
|
||||
@@ -476,21 +476,77 @@ class rbtree
|
||||
{}
|
||||
|
||||
template <class InputIterator>
|
||||
rbtree(InputIterator first, InputIterator last, const key_compare& comp,
|
||||
const allocator_type& a, bool unique_insertion)
|
||||
rbtree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
|
||||
const allocator_type& a
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
< container_detail::is_input_iterator<InputIterator>::value
|
||||
|| container_detail::is_same<alloc_version, allocator_v1>::value
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
: AllocHolder(a, comp)
|
||||
{
|
||||
typedef typename std::iterator_traits<InputIterator>::iterator_category ItCat;
|
||||
priv_create_and_insert_nodes(first, last, unique_insertion, alloc_version(), ItCat());
|
||||
if(unique_insertion){
|
||||
this->insert_unique(first, last);
|
||||
}
|
||||
else{
|
||||
this->insert_equal(first, last);
|
||||
}
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
rbtree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
|
||||
const allocator_type& a
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
< !(container_detail::is_input_iterator<InputIterator>::value
|
||||
|| container_detail::is_same<alloc_version, allocator_v1>::value)
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
: AllocHolder(a, comp)
|
||||
{
|
||||
if(unique_insertion){
|
||||
this->insert_unique(first, last);
|
||||
}
|
||||
else{
|
||||
//Optimized allocation and construction
|
||||
this->allocate_many_and_construct
|
||||
(first, std::distance(first, last), insert_equal_end_hint_functor(this->icont()));
|
||||
}
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
rbtree( ordered_range_t, InputIterator first, InputIterator last
|
||||
, const key_compare& comp = key_compare(), const allocator_type& a = allocator_type())
|
||||
, const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
< container_detail::is_input_iterator<InputIterator>::value
|
||||
|| container_detail::is_same<alloc_version, allocator_v1>::value
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
: AllocHolder(a, comp)
|
||||
{
|
||||
typedef typename std::iterator_traits<InputIterator>::iterator_category ItCat;
|
||||
priv_create_and_insert_ordered_nodes(first, last, alloc_version(), ItCat());
|
||||
this->insert_equal(first, last);
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
rbtree( ordered_range_t, InputIterator first, InputIterator last
|
||||
, const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename container_detail::enable_if_c
|
||||
< !(container_detail::is_input_iterator<InputIterator>::value
|
||||
|| container_detail::is_same<alloc_version, allocator_v1>::value)
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
: AllocHolder(a, comp)
|
||||
{
|
||||
//Optimized allocation and construction
|
||||
this->allocate_many_and_construct
|
||||
(first, std::distance(first, last), push_back_functor(this->icont()));
|
||||
}
|
||||
|
||||
rbtree(const rbtree& x)
|
||||
@@ -943,14 +999,14 @@ class rbtree
|
||||
{ return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
|
||||
|
||||
std::pair<iterator,iterator> equal_range(const key_type& k)
|
||||
{
|
||||
{
|
||||
std::pair<iiterator, iiterator> ret =
|
||||
this->icont().equal_range(k, KeyNodeCompare(value_comp()));
|
||||
return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
|
||||
{
|
||||
{
|
||||
std::pair<iiterator, iiterator> ret =
|
||||
this->non_const_icont().equal_range(k, KeyNodeCompare(value_comp()));
|
||||
return std::pair<const_iterator,const_iterator>
|
||||
@@ -958,108 +1014,39 @@ class rbtree
|
||||
}
|
||||
|
||||
private:
|
||||
//Iterator range version
|
||||
template<class InpIterator>
|
||||
void priv_create_and_insert_nodes
|
||||
(InpIterator beg, InpIterator end, bool unique, allocator_v1, std::input_iterator_tag)
|
||||
{
|
||||
if(unique){
|
||||
for (; beg != end; ++beg){
|
||||
this->insert_unique(*beg);
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (; beg != end; ++beg){
|
||||
this->insert_equal(*beg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class InpIterator>
|
||||
void priv_create_and_insert_nodes
|
||||
(InpIterator beg, InpIterator end, bool unique, allocator_v2, std::input_iterator_tag)
|
||||
{ //Just forward to the default one
|
||||
priv_create_and_insert_nodes(beg, end, unique, allocator_v1(), std::input_iterator_tag());
|
||||
}
|
||||
class insert_equal_end_hint_functor;
|
||||
friend class insert_equal_end_hint_functor;
|
||||
|
||||
class insertion_functor;
|
||||
friend class insertion_functor;
|
||||
|
||||
class insertion_functor
|
||||
class insert_equal_end_hint_functor
|
||||
{
|
||||
Icont &icont_;
|
||||
const iconst_iterator cend_;
|
||||
|
||||
public:
|
||||
insertion_functor(Icont &icont)
|
||||
: icont_(icont)
|
||||
insert_equal_end_hint_functor(Icont &icont)
|
||||
: icont_(icont), cend_(this->icont_.cend())
|
||||
{}
|
||||
|
||||
void operator()(Node &n)
|
||||
{ this->icont_.insert_equal(this->icont_.cend(), n); }
|
||||
{ this->icont_.insert_equal(cend_, n); }
|
||||
};
|
||||
|
||||
class push_back_functor;
|
||||
friend class push_back_functor;
|
||||
|
||||
template<class FwdIterator>
|
||||
void priv_create_and_insert_nodes
|
||||
(FwdIterator beg, FwdIterator end, bool unique, allocator_v2, std::forward_iterator_tag)
|
||||
{
|
||||
if(beg != end){
|
||||
if(unique){
|
||||
priv_create_and_insert_nodes(beg, end, unique, allocator_v2(), std::input_iterator_tag());
|
||||
}
|
||||
else{
|
||||
//Optimized allocation and construction
|
||||
this->allocate_many_and_construct
|
||||
(beg, std::distance(beg, end), insertion_functor(this->icont()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Iterator range version
|
||||
template<class InpIterator>
|
||||
void priv_create_and_insert_ordered_nodes
|
||||
(InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
|
||||
{
|
||||
const_iterator cend_n(this->cend());
|
||||
for (; beg != end; ++beg){
|
||||
this->insert_before(cend_n, *beg);
|
||||
}
|
||||
}
|
||||
|
||||
template<class InpIterator>
|
||||
void priv_create_and_insert_ordered_nodes
|
||||
(InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
|
||||
{ //Just forward to the default one
|
||||
priv_create_and_insert_ordered_nodes(beg, end, allocator_v1(), std::input_iterator_tag());
|
||||
}
|
||||
|
||||
class back_insertion_functor;
|
||||
friend class back_insertion_functor;
|
||||
|
||||
class back_insertion_functor
|
||||
class push_back_functor
|
||||
{
|
||||
Icont &icont_;
|
||||
|
||||
public:
|
||||
back_insertion_functor(Icont &icont)
|
||||
push_back_functor(Icont &icont)
|
||||
: icont_(icont)
|
||||
{}
|
||||
|
||||
void operator()(Node &n)
|
||||
{ this->icont_.push_back(n); }
|
||||
};
|
||||
|
||||
|
||||
template<class FwdIterator>
|
||||
void priv_create_and_insert_ordered_nodes
|
||||
(FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
|
||||
{
|
||||
if(beg != end){
|
||||
//Optimized allocation and construction
|
||||
this->allocate_many_and_construct
|
||||
(beg, std::distance(beg, end), back_insertion_functor(this->icont()));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
#define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
|
||||
#endif
|
||||
|
||||
//Macros for documentation purposes. For code, expands to the argument
|
||||
#define BOOST_CONTAINER_IMPDEF(TYPE) TYPE
|
||||
#define BOOST_CONTAINER_SEEDOC(TYPE) TYPE
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
|
||||
@@ -39,11 +39,7 @@ namespace container {
|
||||
|
||||
/// @cond
|
||||
// Forward declarations of operators == and <, needed for friend declarations.
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class T, class Pred = std::less< std::pair< Key, T> >, class A = std::allocator<T> >
|
||||
#else
|
||||
template <class Key, class T, class Pred, class A>
|
||||
#endif
|
||||
class flat_map;
|
||||
|
||||
template <class Key, class T, class Pred, class A>
|
||||
@@ -94,7 +90,7 @@ static D force_copy(S s)
|
||||
//! Erasing an element of a flat_map invalidates iterators and references
|
||||
//! pointing to elements that come after (their keys are bigger) the erased element.
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class T, class Pred = std::less< std::pair< Key, T> >, class A = std::allocator<T> >
|
||||
template <class Key, class T, class Pred = std::less<Key>, class A = std::allocator< std::pair< Key, T> > >
|
||||
#else
|
||||
template <class Key, class T, class Pred, class A>
|
||||
#endif
|
||||
@@ -194,8 +190,8 @@ class flat_map
|
||||
template <class InputIterator>
|
||||
flat_map(InputIterator first, InputIterator last, const Pred& comp = Pred(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
|
||||
{ m_flat_tree.insert_unique(first, last); }
|
||||
: m_flat_tree(true, first, last, comp, container_detail::force<impl_allocator_type>(a))
|
||||
{}
|
||||
|
||||
//! <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
|
||||
@@ -870,11 +866,7 @@ struct has_trivial_destructor_after_move<boost::container::flat_map<K, T, C, A>
|
||||
namespace container {
|
||||
|
||||
// Forward declaration of operators < and ==, needed for friend declaration.
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class T, class Pred = std::less< std::pair< Key, T> >, class A = std::allocator<T> >
|
||||
#else
|
||||
template <class Key, class T, class Pred, class A>
|
||||
#endif
|
||||
class flat_multimap;
|
||||
|
||||
template <class Key, class T, class Pred, class A>
|
||||
@@ -901,7 +893,7 @@ inline bool operator<(const flat_multimap<Key,T,Pred,A>& x,
|
||||
//! A is the allocator to allocate the value_types
|
||||
//! (e.g. <i>allocator< std::pair<Key, T> ></i>).
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class T, class Pred = std::less< std::pair< Key, T> >, class A = std::allocator<T> >
|
||||
template <class Key, class T, class Pred = std::less<Key>, class A = std::allocator< std::pair< Key, T> > >
|
||||
#else
|
||||
template <class Key, class T, class Pred, class A>
|
||||
#endif
|
||||
@@ -996,8 +988,8 @@ class flat_multimap
|
||||
flat_multimap(InputIterator first, InputIterator last,
|
||||
const Pred& comp = Pred(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
|
||||
{ m_flat_tree.insert_equal(first, last); }
|
||||
: m_flat_tree(false, first, last, comp, container_detail::force<impl_allocator_type>(a))
|
||||
{}
|
||||
|
||||
//! <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
|
||||
|
||||
@@ -125,8 +125,8 @@ class flat_set
|
||||
flat_set(InputIterator first, InputIterator last,
|
||||
const Pred& comp = Pred(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(comp, a)
|
||||
{ m_flat_tree.insert_unique(first, last); }
|
||||
: m_flat_tree(true, first, last, comp, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_set using the specified comparison object and
|
||||
//! allocator, and inserts elements from the ordered unique range [first ,last). This function
|
||||
@@ -777,8 +777,8 @@ class flat_multiset
|
||||
flat_multiset(InputIterator first, InputIterator last,
|
||||
const Pred& comp = Pred(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_flat_tree(comp, a)
|
||||
{ m_flat_tree.insert_equal(first, last); }
|
||||
: m_flat_tree(false, first, last, comp, a)
|
||||
{}
|
||||
|
||||
//! <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
|
||||
|
||||
+618
-494
File diff suppressed because it is too large
Load Diff
@@ -68,7 +68,7 @@ inline bool operator<(const map<Key,T,Pred,A>& x,
|
||||
//! A is the allocator to allocate the value_types
|
||||
//! (e.g. <i>allocator< std::pair<const Key, T> > </i>).
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class T, class Pred = std::less< std::pair< const Key, T> >, class A = std::allocator<T> >
|
||||
template <class Key, class T, class Pred = std::less<Key>, class A = std::allocator< std::pair< const Key, T> > >
|
||||
#else
|
||||
template <class Key, class T, class Pred, class A>
|
||||
#endif
|
||||
@@ -155,7 +155,7 @@ class map
|
||||
template <class InputIterator>
|
||||
map(InputIterator first, InputIterator last, const Pred& comp = Pred(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_tree(first, last, comp, a, true)
|
||||
: m_tree(true, first, last, comp, a)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
@@ -814,7 +814,7 @@ namespace container {
|
||||
//! A is the allocator to allocate the value_types
|
||||
//!(e.g. <i>allocator< std::pair<<b>const</b> Key, T> ></i>).
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class T, class Pred = std::less< std::pair< const Key, T> >, class A = std::allocator<T> >
|
||||
template <class Key, class T, class Pred = std::less<Key>, class A = std::allocator< std::pair< const Key, T> > >
|
||||
#else
|
||||
template <class Key, class T, class Pred, class A>
|
||||
#endif
|
||||
@@ -902,7 +902,7 @@ class multimap
|
||||
multimap(InputIterator first, InputIterator last,
|
||||
const Pred& comp = Pred(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_tree(first, last, comp, a, false)
|
||||
: m_tree(false, first, last, comp, a)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
|
||||
@@ -118,7 +118,7 @@ class set
|
||||
template <class InputIterator>
|
||||
set(InputIterator first, InputIterator last, const Pred& comp = Pred(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_tree(first, last, comp, a, true)
|
||||
: m_tree(true, first, last, comp, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty set using the specified comparison object and
|
||||
@@ -705,7 +705,7 @@ class multiset
|
||||
multiset(InputIterator first, InputIterator last,
|
||||
const Pred& comp = Pred(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_tree(first, last, comp, a, false)
|
||||
: m_tree(false, first, last, comp, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty multiset using the specified comparison object and
|
||||
|
||||
+789
-621
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+430
-416
File diff suppressed because it is too large
Load Diff
+433
-557
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user