forked from boostorg/container
Merge from trunk
[SVN r80689]
This commit is contained in:
@@ -27,6 +27,8 @@ doxygen autodoc
|
||||
<doxygen:param>MACRO_EXPANSION=YES
|
||||
<doxygen:param>"PREDEFINED=\"insert_const_ref_type= const T&\" \\
|
||||
\"BOOST_CONTAINER_DOXYGEN_INVOKED\" \\
|
||||
\"BOOST_CONTAINER_IMPDEF(T)=implementation_defined\" \\
|
||||
\"BOOST_CONTAINER_SEEDOC(T)=see_documentation\" \\
|
||||
\"BOOST_RV_REF(T)=T &&\" \\
|
||||
\"BOOST_RV_REF_BEG=\" \\
|
||||
\"BOOST_RV_REF_END=&&\" \\
|
||||
|
||||
+17
-4
@@ -38,7 +38,7 @@ In short, what does [*Boost.Container] offer?
|
||||
* The library offers new useful containers:
|
||||
* [classref boost::container::flat_map flat_map],
|
||||
[classref boost::container::flat_set flat_set],
|
||||
[classref boost::container::flat_multiset flat_multiset] and
|
||||
[classref boost::container::flat_multimap flat_multimap] and
|
||||
[classref boost::container::flat_multiset flat_multiset]: drop-in
|
||||
replacements for standard associative containers but more memory friendly and with faster
|
||||
searches.
|
||||
@@ -614,6 +614,21 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
|
||||
[section:release_notes Release Notes]
|
||||
|
||||
[section:release_notes_boost_1_52_00 Boost 1.52 Release]
|
||||
|
||||
* Improved `stable_vector`'s template code bloat and type safety.
|
||||
* Changed typedefs and reordered functions of sequence containers to improve doxygen documentation.
|
||||
* Fixed bugs
|
||||
[@https://svn.boost.org/trac/boost/ticket/6615 #6615],
|
||||
[@https://svn.boost.org/trac/boost/ticket/7139 #7139],
|
||||
[@https://svn.boost.org/trac/boost/ticket/7215 #7215],
|
||||
[@https://svn.boost.org/trac/boost/ticket/7232 #7232],
|
||||
[@https://svn.boost.org/trac/boost/ticket/7269 #7269].
|
||||
* Implemented LWG Issue #149 (range insertion now returns an iterator) & cleaned up insertion code in most containers
|
||||
* Corrected aliasing errors.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:release_notes_boost_1_51_00 Boost 1.51 Release]
|
||||
|
||||
* Fixed bugs
|
||||
@@ -623,7 +638,6 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
[@https://svn.boost.org/trac/boost/ticket/7103 #7103].
|
||||
[@https://svn.boost.org/trac/boost/ticket/7123 #7123],
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:release_notes_boost_1_50_00 Boost 1.50 Release]
|
||||
@@ -631,12 +645,11 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
* Added Scoped Allocator Model support.
|
||||
|
||||
* Fixed bugs
|
||||
[@https://svn.boost.org/trac/boost/ticket/6606 #6606],
|
||||
[@https://svn.boost.org/trac/boost/ticket/6533 #6533],
|
||||
[@https://svn.boost.org/trac/boost/ticket/6536 #6536],
|
||||
[@https://svn.boost.org/trac/boost/ticket/6566 #6566],
|
||||
[@https://svn.boost.org/trac/boost/ticket/6575 #6575],
|
||||
[@https://svn.boost.org/trac/boost/ticket/6606 #6606],
|
||||
[@https://svn.boost.org/trac/boost/ticket/6615 #6615],
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -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
+119
-1
@@ -34,10 +34,128 @@ Write forward_list
|
||||
|
||||
check move if noexcept conditions in vector, deque and stable_vector
|
||||
|
||||
Add noexcept testing using static_assert (Howard Hinnants's suggestion):
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
struct A
|
||||
{
|
||||
void foo() noexcept;
|
||||
};
|
||||
|
||||
static_assert(noexcept(std::declval<A&>().foo()), "A::foo() should be noexcept");
|
||||
|
||||
Detect always equal or unequal allocators at compiler time. operator== returns true_type or false_type
|
||||
|
||||
change virtual functions with pointers to avoid template instantiation for every type
|
||||
|
||||
Add hash for containers
|
||||
|
||||
Add std:: hashing support
|
||||
Add std:: hashing support
|
||||
|
||||
Take out from class definition iterators in slist & list
|
||||
|
||||
Fix trivial destructor after move and other optimizing traits
|
||||
|
||||
Define typedefs exactly like the standard to generate better documentation. for implementation defined types:
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
#define BOOST_CONTAINER_IMPLDEF(TYPE) TYPE
|
||||
#else
|
||||
#define BOOST_CONTAINER_IMPLDEF(TYPE) implementation_defined
|
||||
#endif
|
||||
Mark previous() in slist/and forward_list as non-standard
|
||||
|
||||
Replace all insert_const_ref_type with BOOST_MOVE_CONVERSION_AWARE_CATCH_XXX
|
||||
|
||||
|
||||
|
||||
Function order:
|
||||
|
||||
----------type------------
|
||||
value_type;
|
||||
pointer;
|
||||
const_pointer;
|
||||
reference;
|
||||
const_reference;
|
||||
size_type;
|
||||
difference_type;
|
||||
allocator_type;
|
||||
stored_allocator_type;
|
||||
iterator;
|
||||
const_iterator;
|
||||
reverse_iterator;
|
||||
const_reverse_iterator;
|
||||
----------func------------
|
||||
container()
|
||||
container(allocator_type)
|
||||
container(size_type)
|
||||
container(size_type, value_type, allocator_type = ())
|
||||
container(InpIt, InpIt)
|
||||
container(const container &)
|
||||
container(container &&)
|
||||
container(const container &, allocator_type)
|
||||
container(container &&, allocator_type)
|
||||
container(initializer_list<T>, allocator)
|
||||
~container()
|
||||
container operator=(const container &)
|
||||
container operator=(container &&)
|
||||
container operator=(initializer_list<T>)
|
||||
assign(size_type, const T &)
|
||||
|
||||
assign(InpIt, InptIt)
|
||||
assign(initializer_list)
|
||||
get_allocator()
|
||||
|
||||
begin()
|
||||
begin() const
|
||||
end()
|
||||
end() const
|
||||
rbegin()
|
||||
rbegin() const
|
||||
rend()
|
||||
rend() const
|
||||
|
||||
cbegin() const
|
||||
cend() const
|
||||
crbegin() const
|
||||
crend() const
|
||||
|
||||
empty()
|
||||
size()
|
||||
max_size()
|
||||
resize(size_type)
|
||||
resize(size_type, cont T&)
|
||||
capacity()
|
||||
reserve(size_type)
|
||||
shrink_to_fit()
|
||||
|
||||
front()
|
||||
front() const
|
||||
back()
|
||||
back() const
|
||||
operator[] ()
|
||||
operator[] ()const
|
||||
at()
|
||||
at() const
|
||||
|
||||
|
||||
data()
|
||||
data() const
|
||||
|
||||
emplace_front()
|
||||
emplace_back()
|
||||
emplace()
|
||||
push_front(const T&)
|
||||
push_front(T&&)
|
||||
push_back(const T&)
|
||||
push_back(T&&)
|
||||
insert(iterator, const T &)
|
||||
insert(iterator, T &&)
|
||||
insert(size_type, const T &)
|
||||
insert(InpIt, InpIt)
|
||||
pop_front()
|
||||
pop_back()
|
||||
erase(const_iterator)
|
||||
erase(const_iterator, const_iterator)
|
||||
swap(container &)
|
||||
clear()
|
||||
@@ -132,6 +132,9 @@
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93815995-89BD-b043-5E8B-65FBE52E2AFB}">
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\detail\node_alloc_holder.hpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
|
||||
@@ -51,6 +51,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scoped_allocator_usage_test
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hash_table_test", "hash_table_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792606}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
@@ -111,6 +115,10 @@ Global
|
||||
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Debug.Build.0 = Debug|Win32
|
||||
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.ActiveCfg = Release|Win32
|
||||
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
|
||||
@@ -145,6 +145,9 @@
|
||||
<File
|
||||
RelativePath="..\..\test\expand_bwd_test_template.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\forward_to_input_iterator.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\heap_allocator_v1.hpp">
|
||||
</File>
|
||||
@@ -261,7 +264,7 @@
|
||||
RelativePath="..\..\..\..\boost\container\detail\math_functions.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\allocator\memory_util.hpp">
|
||||
RelativePath="..\..\..\..\boost\container\detail\memory_util.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\detail\mpl.hpp">
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#define BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINER_HPP
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/pair.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
@@ -20,6 +22,24 @@ namespace boost{
|
||||
namespace container {
|
||||
namespace test{
|
||||
|
||||
template< class T1, class T2>
|
||||
bool CheckEqual( const T1 &t1, const T2 &t2
|
||||
, typename boost::container::container_detail::enable_if_c
|
||||
<!boost::container::container_detail::is_pair<T1>::value &&
|
||||
!boost::container::container_detail::is_pair<T2>::value
|
||||
>::type* = 0)
|
||||
{ return t1 == t2; }
|
||||
|
||||
template< class Pair1, class Pair2>
|
||||
bool CheckEqual( const Pair1 &pair1, const Pair2 &pair2
|
||||
, typename boost::container::container_detail::enable_if_c
|
||||
<boost::container::container_detail::is_pair<Pair1>::value &&
|
||||
boost::container::container_detail::is_pair<Pair2>::value
|
||||
>::type* = 0)
|
||||
{
|
||||
return CheckEqual(pair1.first, pair2.first) && CheckEqual(pair1.second, pair2.second);
|
||||
}
|
||||
|
||||
//Function to check if both containers are equal
|
||||
template<class MyBoostCont
|
||||
,class MyStdCont>
|
||||
@@ -38,9 +58,7 @@ bool CheckEqualContainers(const MyBoostCont *boostcont, const MyStdCont *stdcont
|
||||
}
|
||||
std::size_t i = 0;
|
||||
for(; itboost != itboostend; ++itboost, ++itstd, ++i){
|
||||
value_type val(*itstd);
|
||||
const value_type &v = *itboost;
|
||||
if(v != val)
|
||||
if(!CheckEqual(*itstd, *itboost))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ bool deque_copyable_only(V1 *cntdeque, V2 *stddeque, container_detail::true_type
|
||||
typedef typename V1::value_type IntType;
|
||||
std::size_t size = cntdeque->size();
|
||||
stddeque->insert(stddeque->end(), 50, 1);
|
||||
cntdeque->insert(cntdeque->end(), 50, 1);
|
||||
cntdeque->insert(cntdeque->end(), 50, IntType(1));
|
||||
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
|
||||
{
|
||||
IntType move_me(1);
|
||||
|
||||
@@ -111,7 +111,7 @@ class dummy_test_allocator
|
||||
dummy_test_allocator(const dummy_test_allocator<T2> &)
|
||||
{}
|
||||
|
||||
pointer address(reference value)
|
||||
pointer address(reference value)
|
||||
{ return pointer(container_detail::addressof(value)); }
|
||||
|
||||
const_pointer address(const_reference value) const
|
||||
|
||||
@@ -108,7 +108,7 @@ class expand_bwd_test_allocator
|
||||
{ return m_size; }
|
||||
|
||||
friend void swap(self_t &alloc1, self_t &alloc2)
|
||||
{
|
||||
{
|
||||
container_detail::do_swap(alloc1.mp_buffer, alloc2.mp_buffer);
|
||||
container_detail::do_swap(alloc1.m_size, alloc2.m_size);
|
||||
container_detail::do_swap(alloc1.m_offset, alloc2.m_offset);
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2012-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_TEST_FORWARD_TO_INPUT_ITERATOR_HPP
|
||||
#define BOOST_CONTAINER_TEST_FORWARD_TO_INPUT_ITERATOR_HPP
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace boost{
|
||||
namespace container {
|
||||
namespace test{
|
||||
|
||||
template<class FwdIterator>
|
||||
class input_iterator_wrapper
|
||||
: public std::iterator< std::input_iterator_tag
|
||||
, typename std::iterator_traits<FwdIterator>::value_type
|
||||
, typename std::iterator_traits<FwdIterator>::difference_type
|
||||
, typename std::iterator_traits<FwdIterator>::pointer
|
||||
, typename std::iterator_traits<FwdIterator>::reference
|
||||
>
|
||||
{
|
||||
FwdIterator m_it;
|
||||
|
||||
public:
|
||||
input_iterator_wrapper()
|
||||
: m_it(0)
|
||||
{}
|
||||
|
||||
explicit input_iterator_wrapper(FwdIterator it)
|
||||
: m_it(it)
|
||||
{}
|
||||
|
||||
//Default copy constructor...
|
||||
//input_iterator_wrapper(const input_iterator_wrapper&);
|
||||
|
||||
//Default assignment...
|
||||
//input_iterator_wrapper &operator=(const input_iterator_wrapper&);
|
||||
|
||||
//Default destructor...
|
||||
//~input_iterator_wrapper();
|
||||
|
||||
typename std::iterator_traits<FwdIterator>::reference operator*() const
|
||||
{ return *m_it; }
|
||||
|
||||
typename std::iterator_traits<FwdIterator>::pointer operator->() const
|
||||
{ return m_it.operator->(); }
|
||||
|
||||
input_iterator_wrapper& operator++()
|
||||
{ ++m_it; return *this; }
|
||||
|
||||
input_iterator_wrapper operator++(int )
|
||||
{
|
||||
input_iterator_wrapper tmp(m_it);
|
||||
++m_it;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
friend bool operator==(const input_iterator_wrapper &left, const input_iterator_wrapper &right)
|
||||
{ return left.m_it == right.m_it; }
|
||||
|
||||
friend bool operator!=(const input_iterator_wrapper &left, const input_iterator_wrapper &right)
|
||||
{ return left.m_it != right.m_it; }
|
||||
};
|
||||
|
||||
template<class FwdIterator>
|
||||
input_iterator_wrapper<FwdIterator> make_input_from_forward_iterator(const FwdIterator &it)
|
||||
{ return input_iterator_wrapper<FwdIterator>(it); }
|
||||
|
||||
} //namespace test{
|
||||
} //namespace container {
|
||||
} //namespace boost{
|
||||
|
||||
#endif //BOOST_CONTAINER_TEST_FORWARD_TO_INPUT_ITERATOR_HPP
|
||||
+42
-2
@@ -18,6 +18,7 @@
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include "print_container.hpp"
|
||||
#include "input_from_forward_iterator.hpp"
|
||||
#include <boost/move/move.hpp>
|
||||
#include <string>
|
||||
|
||||
@@ -177,7 +178,20 @@ int list_test (bool copied_allocators_equal = true)
|
||||
aux_vect2[i] = -1;
|
||||
}
|
||||
boostlist->assign(boost::make_move_iterator(&aux_vect[0])
|
||||
,boost::make_move_iterator(&aux_vect[50]));
|
||||
,boost::make_move_iterator(&aux_vect[50]));
|
||||
stdlist->assign(&aux_vect2[0], &aux_vect2[50]);
|
||||
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
|
||||
|
||||
for(int i = 0; i < 50; ++i){
|
||||
IntType move_me(-1);
|
||||
aux_vect[i] = boost::move(move_me);
|
||||
}
|
||||
|
||||
for(int i = 0; i < 50; ++i){
|
||||
aux_vect2[i] = -1;
|
||||
}
|
||||
boostlist->assign(boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[0]))
|
||||
,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[50])));
|
||||
stdlist->assign(&aux_vect2[0], &aux_vect2[50]);
|
||||
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
|
||||
}
|
||||
@@ -206,10 +220,36 @@ int list_test (bool copied_allocators_equal = true)
|
||||
for(int i = 0; i < 50; ++i){
|
||||
aux_vect2[i] = -1;
|
||||
}
|
||||
boostlist->insert(boostlist->begin()
|
||||
typename MyBoostList::iterator old_begin = boostlist->begin();
|
||||
typename MyBoostList::iterator it_insert =
|
||||
boostlist->insert(boostlist->begin()
|
||||
,boost::make_move_iterator(&aux_vect[0])
|
||||
,boost::make_move_iterator(&aux_vect[50]));
|
||||
if(it_insert != boostlist->begin() || std::distance(it_insert, old_begin) != 50)
|
||||
return 1;
|
||||
|
||||
stdlist->insert(stdlist->begin(), &aux_vect2[0], &aux_vect2[50]);
|
||||
if(!CheckEqualContainers(boostlist, stdlist))
|
||||
return 1;
|
||||
|
||||
for(int i = 0; i < 50; ++i){
|
||||
IntType move_me(-1);
|
||||
aux_vect[i] = boost::move(move_me);
|
||||
}
|
||||
|
||||
for(int i = 0; i < 50; ++i){
|
||||
aux_vect2[i] = -1;
|
||||
}
|
||||
|
||||
old_begin = boostlist->begin();
|
||||
it_insert = boostlist->insert(boostlist->end()
|
||||
,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[0]))
|
||||
,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[50])));
|
||||
if(std::distance(it_insert, boostlist->end()) != 50)
|
||||
return 1;
|
||||
stdlist->insert(stdlist->end(), &aux_vect2[0], &aux_vect2[50]);
|
||||
if(!CheckEqualContainers(boostlist, stdlist))
|
||||
return 1;
|
||||
}
|
||||
|
||||
boostlist->unique();
|
||||
|
||||
@@ -73,6 +73,12 @@ class movable_int
|
||||
int get_int() const
|
||||
{ return m_int; }
|
||||
|
||||
friend bool operator==(const movable_int &l, int r)
|
||||
{ return l.get_int() == r; }
|
||||
|
||||
friend bool operator==(int l, const movable_int &r)
|
||||
{ return l == r.get_int(); }
|
||||
|
||||
private:
|
||||
int m_int;
|
||||
};
|
||||
@@ -144,6 +150,12 @@ class movable_and_copyable_int
|
||||
int get_int() const
|
||||
{ return m_int; }
|
||||
|
||||
friend bool operator==(const movable_and_copyable_int &l, int r)
|
||||
{ return l.get_int() == r; }
|
||||
|
||||
friend bool operator==(int l, const movable_and_copyable_int &r)
|
||||
{ return l == r.get_int(); }
|
||||
|
||||
private:
|
||||
int m_int;
|
||||
};
|
||||
@@ -202,6 +214,12 @@ class copyable_int
|
||||
int get_int() const
|
||||
{ return m_int; }
|
||||
|
||||
friend bool operator==(const copyable_int &l, int r)
|
||||
{ return l.get_int() == r; }
|
||||
|
||||
friend bool operator==(int l, const copyable_int &r)
|
||||
{ return l == r.get_int(); }
|
||||
|
||||
private:
|
||||
int m_int;
|
||||
};
|
||||
@@ -256,10 +274,17 @@ class non_copymovable_int
|
||||
int get_int() const
|
||||
{ return m_int; }
|
||||
|
||||
friend bool operator==(const non_copymovable_int &l, int r)
|
||||
{ return l.get_int() == r; }
|
||||
|
||||
friend bool operator==(int l, const non_copymovable_int &r)
|
||||
{ return l == r.get_int(); }
|
||||
|
||||
private:
|
||||
int m_int;
|
||||
};
|
||||
|
||||
|
||||
} //namespace test {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
@@ -20,8 +20,6 @@ class SimpleAllocator
|
||||
{
|
||||
public:
|
||||
typedef Ty value_type;
|
||||
typedef typename std::allocator<Ty>::pointer pointer;
|
||||
typedef typename std::allocator<Ty>::size_type size_type;
|
||||
|
||||
SimpleAllocator(int value)
|
||||
: m_state(value)
|
||||
@@ -32,12 +30,12 @@ public:
|
||||
: m_state(other.m_state)
|
||||
{}
|
||||
|
||||
pointer allocate(size_type n)
|
||||
Ty* allocate(std::size_t n)
|
||||
{
|
||||
return m_allocator.allocate(n);
|
||||
}
|
||||
|
||||
void deallocate(pointer p, size_type n)
|
||||
void deallocate(Ty* p, std::size_t n)
|
||||
{
|
||||
m_allocator.deallocate(p, n);
|
||||
}
|
||||
|
||||
+8
-8
@@ -88,13 +88,13 @@ int set_test ()
|
||||
IntType move_me(i);
|
||||
aux_vect3[i] = boost::move(move_me);
|
||||
}
|
||||
/*
|
||||
MyBoostSet *boostset3 = MyBoostSet
|
||||
|
||||
MyBoostSet *boostset3 = new MyBoostSet
|
||||
( ordered_unique_range
|
||||
, boost::make_move_iterator(&aux_vect[0])
|
||||
, boost::make_move_iterator(aux_vect + 50));
|
||||
MyStdSet *stdset3 = new MyStdSet(aux_vect2, aux_vect2 + 50);
|
||||
MyBoostMultiSet *boostmultiset3 = MyBoostMultiSet
|
||||
MyBoostMultiSet *boostmultiset3 = new MyBoostMultiSet
|
||||
( ordered_range
|
||||
, boost::make_move_iterator(&aux_vect3[0])
|
||||
, boost::make_move_iterator(aux_vect3 + 50));
|
||||
@@ -108,15 +108,15 @@ int set_test ()
|
||||
std::cout << "Error in construct<MyBoostMultiSet>(MyBoostMultiSet3)" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
delete boostset2;
|
||||
delete boostmultiset2;
|
||||
delete stdset2;
|
||||
delete stdmultiset2;
|
||||
//delete boostset3;
|
||||
//delete boostmultiset3;
|
||||
//delete stdset3;
|
||||
//delete stdmultiset3;
|
||||
delete boostset3;
|
||||
delete boostmultiset3;
|
||||
delete stdset3;
|
||||
delete stdmultiset3;
|
||||
}
|
||||
|
||||
int i, j;
|
||||
|
||||
@@ -30,13 +30,13 @@ namespace boost {
|
||||
namespace container {
|
||||
|
||||
//Explicit instantiation to detect compilation errors
|
||||
template class stable_vector<test::movable_and_copyable_int,
|
||||
template class stable_vector<test::movable_and_copyable_int,
|
||||
test::dummy_test_allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class stable_vector<test::movable_and_copyable_int,
|
||||
template class stable_vector<test::movable_and_copyable_int,
|
||||
test::simple_allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
template class stable_vector<test::movable_and_copyable_int,
|
||||
template class stable_vector<test::movable_and_copyable_int,
|
||||
std::allocator<test::movable_and_copyable_int> >;
|
||||
|
||||
}}
|
||||
|
||||
+65
-10
@@ -8,6 +8,9 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_TEST_VECTOR_TEST_HEADER
|
||||
#define BOOST_CONTAINER_TEST_VECTOR_TEST_HEADER
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
@@ -24,6 +27,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "emplace_test.hpp"
|
||||
#include "input_from_forward_iterator.hpp"
|
||||
|
||||
namespace boost{
|
||||
namespace container {
|
||||
@@ -133,10 +137,11 @@ int vector_test()
|
||||
for(int i = 0; i < 50; ++i){
|
||||
aux_vect2[i] = -1;
|
||||
}
|
||||
|
||||
boostvector->insert(boostvector->end()
|
||||
typename MyBoostVector::iterator insert_it =
|
||||
boostvector->insert(boostvector->end()
|
||||
,boost::make_move_iterator(&aux_vect[0])
|
||||
,boost::make_move_iterator(aux_vect + 50));
|
||||
if(std::size_t(std::distance(insert_it, boostvector->end())) != 50) return 1;
|
||||
stdvector->insert(stdvector->end(), aux_vect2, aux_vect2 + 50);
|
||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
|
||||
|
||||
@@ -147,22 +152,47 @@ int vector_test()
|
||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
|
||||
}
|
||||
{
|
||||
boostvector->resize(100);
|
||||
stdvector->resize(100);
|
||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
|
||||
|
||||
IntType aux_vect[50];
|
||||
for(int i = 0; i < 50; ++i){
|
||||
IntType new_int(-1);
|
||||
IntType new_int(-2);
|
||||
aux_vect[i] = boost::move(new_int);
|
||||
}
|
||||
int aux_vect2[50];
|
||||
for(int i = 0; i < 50; ++i){
|
||||
aux_vect2[i] = -1;
|
||||
aux_vect2[i] = -2;
|
||||
}
|
||||
boostvector->insert(boostvector->begin()
|
||||
typename MyBoostVector::size_type old_size = boostvector->size();
|
||||
typename MyBoostVector::iterator insert_it =
|
||||
boostvector->insert(boostvector->begin() + old_size
|
||||
,boost::make_move_iterator(&aux_vect[0])
|
||||
,boost::make_move_iterator(aux_vect + 50));
|
||||
stdvector->insert(stdvector->begin(), aux_vect2, aux_vect2 + 50);
|
||||
if(boostvector->begin() + old_size != insert_it) return 1;
|
||||
stdvector->insert(stdvector->begin() + old_size, aux_vect2, aux_vect2 + 50);
|
||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
|
||||
|
||||
for(int i = 0; i < 50; ++i){
|
||||
IntType new_int(-3);
|
||||
aux_vect[i] = boost::move(new_int);
|
||||
}
|
||||
|
||||
for(int i = 0; i < 50; ++i){
|
||||
aux_vect2[i] = -3;
|
||||
}
|
||||
old_size = boostvector->size();
|
||||
//Now try with input iterators instead
|
||||
insert_it = boostvector->insert(boostvector->begin() + old_size
|
||||
,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[0]))
|
||||
,boost::make_move_iterator(make_input_from_forward_iterator(aux_vect + 50))
|
||||
);
|
||||
if(boostvector->begin() + old_size != insert_it) return 1;
|
||||
stdvector->insert(stdvector->begin() + old_size, aux_vect2, aux_vect2 + 50);
|
||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
|
||||
}
|
||||
/*
|
||||
/* //deque has no reserve
|
||||
boostvector->reserve(boostvector->size()*2);
|
||||
stdvector->reserve(stdvector->size()*2);
|
||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
|
||||
@@ -175,13 +205,27 @@ int vector_test()
|
||||
MyStdVector(*stdvector).swap(*stdvector);
|
||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
|
||||
|
||||
{ //push_back with not enough capacity
|
||||
IntType push_back_this(1);
|
||||
boostvector->push_back(boost::move(push_back_this));
|
||||
stdvector->push_back(int(1));
|
||||
boostvector->push_back(IntType(1));
|
||||
stdvector->push_back(int(1));
|
||||
|
||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
|
||||
}
|
||||
{ //push_back with enough capacity
|
||||
boostvector->pop_back();
|
||||
boostvector->pop_back();
|
||||
stdvector->pop_back();
|
||||
stdvector->pop_back();
|
||||
|
||||
IntType push_back_this(1);
|
||||
boostvector->push_back(boost::move(push_back_this));
|
||||
stdvector->push_back(int(1));
|
||||
boostvector->push_back(IntType(1));
|
||||
stdvector->push_back(int(1));
|
||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
|
||||
}
|
||||
|
||||
if(!vector_copyable_only(boostvector, stdvector
|
||||
,container_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
|
||||
@@ -204,14 +248,22 @@ int vector_test()
|
||||
//Test insertion from list
|
||||
{
|
||||
std::list<int> l(50, int(1));
|
||||
boostvector->insert(boostvector->begin(), l.begin(), l.end());
|
||||
typename MyBoostVector::iterator it_insert =
|
||||
boostvector->insert(boostvector->begin(), l.begin(), l.end());
|
||||
if(boostvector->begin() != it_insert) return 1;
|
||||
stdvector->insert(stdvector->begin(), l.begin(), l.end());
|
||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
|
||||
boostvector->assign(l.begin(), l.end());
|
||||
stdvector->assign(l.begin(), l.end());
|
||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
|
||||
|
||||
boostvector->clear();
|
||||
stdvector->clear();
|
||||
boostvector->assign(make_input_from_forward_iterator(l.begin()), make_input_from_forward_iterator(l.end()));
|
||||
stdvector->assign(l.begin(), l.end());
|
||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
|
||||
}
|
||||
/*
|
||||
/* deque has no reserve or capacity
|
||||
std::size_t cap = boostvector->capacity();
|
||||
boostvector->reserve(cap*2);
|
||||
stdvector->reserve(cap*2);
|
||||
@@ -252,3 +304,6 @@ int vector_test()
|
||||
} //namespace boost{
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_TEST_VECTOR_TEST_HEADER
|
||||
|
||||
|
||||
Reference in New Issue
Block a user