mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 14:04:26 +02:00
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=&&\" \\
|
||||
|
@@ -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,
|
||||
|
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
|
||||
|
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
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
120
proj/to-do.txt
120
proj/to-do.txt
@@ -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;
|
||||
|
@@ -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);
|
||||
|
80
test/input_from_forward_iterator.hpp
Normal file
80
test/input_from_forward_iterator.hpp
Normal file
@@ -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
|
@@ -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);
|
||||
}
|
||||
|
@@ -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> >;
|
||||
|
||||
}}
|
||||
|
@@ -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