forked from boostorg/container
Introducing allocator_traits and pointer_traits changes into several libraries.
[SVN r76106]
This commit is contained in:
@@ -27,15 +27,14 @@
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/container/detail/utilities.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/algorithms.hpp>
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
#include <boost/get_pointer.hpp>
|
||||
#include <boost/container/allocator/allocator_traits.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
@@ -79,7 +78,7 @@ struct smart_ptr_type<T*>
|
||||
};
|
||||
|
||||
template<class Ptr>
|
||||
inline typename smart_ptr_type<Ptr>::pointer get_pointer(const Ptr &ptr)
|
||||
inline typename smart_ptr_type<Ptr>::pointer to_raw_pointer(const Ptr &ptr)
|
||||
{ return smart_ptr_type<Ptr>::get(ptr); }
|
||||
|
||||
template <class C>
|
||||
@@ -126,33 +125,29 @@ template<typename VoidPointer, typename T>
|
||||
struct node_type
|
||||
: public node_type_base<VoidPointer>
|
||||
{
|
||||
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
node_type()
|
||||
: value()
|
||||
{}
|
||||
|
||||
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
template<class ...Args>
|
||||
node_type(Args &&...args)
|
||||
: value(boost::forward<Args>(args)...)
|
||||
{}
|
||||
|
||||
#else //BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
#else //BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
|
||||
node_type()
|
||||
: value()
|
||||
{}
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
|
||||
node_type(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
|
||||
: value(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
|
||||
{} \
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
|
||||
node_type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
||||
: value(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
|
||||
{} \
|
||||
//!
|
||||
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
#endif//BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
#endif//BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
|
||||
void set_pointer(VoidPointer p)
|
||||
{ node_type_base<VoidPointer>::set_pointer(p); }
|
||||
@@ -163,33 +158,38 @@ struct node_type
|
||||
template<typename T, typename Reference, typename Pointer>
|
||||
class iterator
|
||||
: public std::iterator< std::random_access_iterator_tag
|
||||
, typename std::iterator_traits<Pointer>::value_type
|
||||
, typename std::iterator_traits<Pointer>::difference_type
|
||||
, T
|
||||
, typename boost::intrusive::
|
||||
pointer_traits<Pointer>::difference_type
|
||||
, Pointer
|
||||
, Reference>
|
||||
{
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<Pointer>::template
|
||||
rebind_pointer<void>::type void_ptr;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<Pointer>::template
|
||||
rebind_pointer<const void>::type const_void_ptr;
|
||||
typedef node_type<void_ptr, T> node_type_t;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<Pointer>::template
|
||||
rebind_pointer<node_type_t>::type node_type_ptr_t;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<Pointer>::template
|
||||
rebind_pointer<const node_type_t>::type const_node_type_ptr_t;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<Pointer>::template
|
||||
rebind_pointer<void_ptr>::type void_ptr_ptr;
|
||||
|
||||
typedef typename boost::pointer_to_other
|
||||
<Pointer, void>::type void_ptr;
|
||||
typedef typename boost::pointer_to_other
|
||||
<Pointer, const void>::type const_void_ptr;
|
||||
typedef node_type<void_ptr, T> node_type_t;
|
||||
typedef typename boost::pointer_to_other
|
||||
<void_ptr, node_type_t>::type node_type_ptr_t;
|
||||
typedef typename boost::pointer_to_other
|
||||
<void_ptr, const node_type_t>::type const_node_type_ptr_t;
|
||||
typedef typename boost::pointer_to_other
|
||||
<void_ptr, void_ptr>::type void_ptr_ptr;
|
||||
|
||||
friend class iterator<T, const T, typename boost::pointer_to_other<Pointer, T>::type>;
|
||||
friend class iterator<T, const T, typename boost::intrusive::pointer_traits<Pointer>::template rebind_pointer<T>::type>;
|
||||
|
||||
public:
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef T value_type;
|
||||
typedef typename std::iterator_traits
|
||||
<Pointer>::difference_type difference_type;
|
||||
typedef Pointer pointer;
|
||||
typedef Reference reference;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef T value_type;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<Pointer>::difference_type difference_type;
|
||||
typedef Pointer pointer;
|
||||
typedef Reference reference;
|
||||
|
||||
iterator()
|
||||
{}
|
||||
@@ -198,27 +198,24 @@ class iterator
|
||||
: pn(pn)
|
||||
{}
|
||||
|
||||
iterator(const iterator<T, T&, typename boost::pointer_to_other<Pointer, T>::type >& x)
|
||||
iterator(const iterator<T, T&, typename boost::intrusive::pointer_traits<Pointer>::template rebind_pointer<T>::type>& x)
|
||||
: pn(x.pn)
|
||||
{}
|
||||
|
||||
private:
|
||||
static node_type_ptr_t node_ptr_cast(const void_ptr &p)
|
||||
{
|
||||
using boost::get_pointer;
|
||||
return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::get_pointer(p)));
|
||||
return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
|
||||
}
|
||||
|
||||
static const_node_type_ptr_t node_ptr_cast(const const_void_ptr &p)
|
||||
{
|
||||
using boost::get_pointer;
|
||||
return const_node_type_ptr_t(static_cast<const node_type_t*>(stable_vector_detail::get_pointer(p)));
|
||||
return const_node_type_ptr_t(static_cast<const node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
|
||||
}
|
||||
|
||||
static void_ptr_ptr void_ptr_ptr_cast(const void_ptr &p)
|
||||
{
|
||||
using boost::get_pointer;
|
||||
return void_ptr_ptr(static_cast<void_ptr*>(stable_vector_detail::get_pointer(p)));
|
||||
return void_ptr_ptr(static_cast<void_ptr*>(stable_vector_detail::to_raw_pointer(p)));
|
||||
}
|
||||
|
||||
reference dereference() const
|
||||
@@ -325,12 +322,15 @@ struct select_multiallocation_chain
|
||||
template<class A>
|
||||
struct select_multiallocation_chain<A, 1>
|
||||
{
|
||||
typedef typename A::template
|
||||
rebind<void>::other::pointer void_ptr;
|
||||
typedef containers_detail::basic_multiallocation_chain
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<typename allocator_traits<A>::pointer>::
|
||||
template rebind_pointer<void>::type void_ptr;
|
||||
typedef container_detail::basic_multiallocation_chain
|
||||
<void_ptr> multialloc_cached_counted;
|
||||
typedef boost::container::containers_detail::transform_multiallocation_chain
|
||||
<multialloc_cached_counted, typename A::value_type> type;
|
||||
typedef boost::container::container_detail::
|
||||
transform_multiallocation_chain
|
||||
< multialloc_cached_counted
|
||||
, typename allocator_traits<A>::value_type> type;
|
||||
};
|
||||
|
||||
} //namespace stable_vector_detail
|
||||
@@ -389,59 +389,82 @@ template <class T, class A>
|
||||
class stable_vector
|
||||
{
|
||||
///@cond
|
||||
typedef typename containers_detail::
|
||||
move_const_ref_type<T>::type insert_const_ref_type;
|
||||
typedef typename A::template
|
||||
rebind<void>::other::pointer void_ptr;
|
||||
typedef typename boost::pointer_to_other
|
||||
<void_ptr, const void>::type const_void_ptr;
|
||||
typedef typename A::template
|
||||
rebind<void_ptr>::other::pointer void_ptr_ptr;
|
||||
typedef typename boost::pointer_to_other
|
||||
<void_ptr, const void_ptr>::type const_void_ptr_ptr;
|
||||
typedef allocator_traits<A> allocator_traits_type;
|
||||
typedef typename container_detail::
|
||||
move_const_ref_type<T>::type insert_const_ref_type;
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<typename allocator_traits_type::pointer>::
|
||||
template rebind_pointer<void>::type void_ptr;
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<void_ptr>::template
|
||||
rebind_pointer<const void>::type const_void_ptr;
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<void_ptr>::template
|
||||
rebind_pointer<void_ptr>::type void_ptr_ptr;
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<void_ptr>::template
|
||||
rebind_pointer<const void_ptr>::type const_void_ptr_ptr;
|
||||
typedef stable_vector_detail::node_type
|
||||
<void_ptr, T> node_type_t;
|
||||
typedef typename A::template
|
||||
rebind<node_type_t>::other::pointer node_type_ptr_t;
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<void_ptr>::template
|
||||
rebind_pointer<node_type_t>::type node_type_ptr_t;
|
||||
typedef stable_vector_detail::node_type_base
|
||||
<void_ptr> node_type_base_t;
|
||||
typedef typename A::template
|
||||
rebind<node_type_base_t>::other::pointer node_type_base_ptr_t;
|
||||
typedef
|
||||
::boost::container::vector<void_ptr,
|
||||
typename A::
|
||||
template rebind<void_ptr>::other
|
||||
> impl_type;
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<void_ptr>::template
|
||||
rebind_pointer<node_type_base_t>::type node_type_base_ptr_t;
|
||||
typedef ::boost::container::vector<void_ptr,
|
||||
typename allocator_traits_type::
|
||||
template portable_rebind_alloc
|
||||
<void_ptr>::type> impl_type;
|
||||
typedef typename impl_type::iterator impl_iterator;
|
||||
typedef typename impl_type::const_iterator const_impl_iterator;
|
||||
|
||||
typedef ::boost::container::containers_detail::
|
||||
typedef ::boost::container::container_detail::
|
||||
integral_constant<unsigned, 1> allocator_v1;
|
||||
typedef ::boost::container::containers_detail::
|
||||
typedef ::boost::container::container_detail::
|
||||
integral_constant<unsigned, 2> allocator_v2;
|
||||
typedef ::boost::container::containers_detail::integral_constant
|
||||
<unsigned, boost::container::containers_detail::
|
||||
version<A>::value> alloc_version;
|
||||
typedef typename A::
|
||||
template rebind<node_type_t>::other node_allocator_type;
|
||||
typedef ::boost::container::container_detail::integral_constant
|
||||
<unsigned, boost::container::container_detail::
|
||||
version<A>::value> alloc_version;
|
||||
typedef typename allocator_traits_type::
|
||||
template portable_rebind_alloc
|
||||
<node_type_t>::type node_allocator_type;
|
||||
|
||||
node_type_ptr_t allocate_one()
|
||||
{ return this->allocate_one(alloc_version()); }
|
||||
|
||||
node_type_ptr_t allocate_one(allocator_v1)
|
||||
{ return get_al().allocate(1); }
|
||||
template<class AllocatorVersion>
|
||||
node_type_ptr_t allocate_one(AllocatorVersion,
|
||||
typename boost::container::container_detail::enable_if_c
|
||||
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
|
||||
::value>::type * = 0)
|
||||
{ return node_alloc().allocate(1); }
|
||||
|
||||
node_type_ptr_t allocate_one(allocator_v2)
|
||||
{ return get_al().allocate_one(); }
|
||||
template<class AllocatorVersion>
|
||||
node_type_ptr_t allocate_one(AllocatorVersion,
|
||||
typename boost::container::container_detail::enable_if_c
|
||||
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v2>
|
||||
::value>::type * = 0)
|
||||
{ return node_alloc().allocate_one(); }
|
||||
|
||||
void deallocate_one(node_type_ptr_t p)
|
||||
{ return this->deallocate_one(p, alloc_version()); }
|
||||
|
||||
void deallocate_one(node_type_ptr_t p, allocator_v1)
|
||||
{ get_al().deallocate(p, 1); }
|
||||
template<class AllocatorVersion>
|
||||
void deallocate_one(node_type_ptr_t p, AllocatorVersion,
|
||||
typename boost::container::container_detail::enable_if_c
|
||||
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
|
||||
::value>::type * = 0)
|
||||
{ node_alloc().deallocate(p, 1); }
|
||||
|
||||
void deallocate_one(node_type_ptr_t p, allocator_v2)
|
||||
{ get_al().deallocate_one(p); }
|
||||
template<class AllocatorVersion>
|
||||
void deallocate_one(node_type_ptr_t p, AllocatorVersion,
|
||||
typename boost::container::container_detail::enable_if_c
|
||||
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v2>
|
||||
::value>::type * = 0)
|
||||
{ node_alloc().deallocate_one(p); }
|
||||
|
||||
friend class stable_vector_detail::clear_on_destroy<stable_vector>;
|
||||
///@endcond
|
||||
@@ -450,10 +473,10 @@ class stable_vector
|
||||
|
||||
// types:
|
||||
|
||||
typedef typename A::reference reference;
|
||||
typedef typename A::const_reference const_reference;
|
||||
typedef typename A::pointer pointer;
|
||||
typedef typename A::const_pointer const_pointer;
|
||||
typedef typename allocator_traits_type::reference reference;
|
||||
typedef typename allocator_traits_type::const_reference const_reference;
|
||||
typedef typename allocator_traits_type::pointer pointer;
|
||||
typedef typename allocator_traits_type::const_pointer const_pointer;
|
||||
typedef stable_vector_detail::iterator
|
||||
<T,T&, pointer> iterator;
|
||||
typedef stable_vector_detail::iterator
|
||||
@@ -461,9 +484,10 @@ class stable_vector
|
||||
typedef typename impl_type::size_type size_type;
|
||||
typedef typename iterator::difference_type difference_type;
|
||||
typedef T value_type;
|
||||
typedef A allocator_type;
|
||||
typedef A allocator_type;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef node_allocator_type stored_allocator_type;
|
||||
|
||||
///@cond
|
||||
private:
|
||||
@@ -483,13 +507,24 @@ class stable_vector
|
||||
///@endcond
|
||||
public:
|
||||
|
||||
//! <b>Effects</b>: Default constructs a stable_vector.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocator_type's default constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
stable_vector()
|
||||
: internal_data(), impl()
|
||||
{
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a stable_vector taking the allocator as parameter.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocator_type's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
explicit stable_vector(const A& al=A())
|
||||
: internal_data(al),impl(al)
|
||||
explicit stable_vector(const A& al)
|
||||
: internal_data(al),impl(al)
|
||||
{
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
}
|
||||
@@ -502,7 +537,7 @@ class stable_vector
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to n.
|
||||
explicit stable_vector(size_type n)
|
||||
: internal_data(A()),impl(A())
|
||||
: internal_data(A()),impl(A())
|
||||
{
|
||||
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
|
||||
this->resize(n);
|
||||
@@ -518,7 +553,7 @@ class stable_vector
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to n.
|
||||
stable_vector(size_type n, const T& t, const A& al=A())
|
||||
: internal_data(al),impl(al)
|
||||
: internal_data(al),impl(al)
|
||||
{
|
||||
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
|
||||
this->insert(this->cbegin(), n, t);
|
||||
@@ -549,7 +584,10 @@ class stable_vector
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the elements x contains.
|
||||
stable_vector(const stable_vector& x)
|
||||
: internal_data(x.get_al()),impl(x.get_al())
|
||||
: internal_data(allocator_traits<node_allocator_type>::
|
||||
select_on_container_copy_construction(x.node_alloc()))
|
||||
, impl(allocator_traits<allocator_type>::
|
||||
select_on_container_copy_construction(x.impl.get_stored_allocator()))
|
||||
{
|
||||
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
|
||||
this->insert(this->cbegin(), x.begin(), x.end());
|
||||
@@ -562,9 +600,11 @@ class stable_vector
|
||||
//! <b>Throws</b>: If allocator_type's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
stable_vector(BOOST_RV_REF(stable_vector) x)
|
||||
: internal_data(x.get_al()),impl(x.get_al())
|
||||
{ this->swap(x); }
|
||||
stable_vector(BOOST_RV_REF(stable_vector) x)
|
||||
: internal_data(boost::move(x.node_alloc())), impl(boost::move(x.impl))
|
||||
{
|
||||
this->priv_swap_members(x);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Destroys the stable_vector. All stored values are destroyed
|
||||
//! and used memory is deallocated.
|
||||
@@ -589,7 +629,17 @@ class stable_vector
|
||||
stable_vector& operator=(BOOST_COPY_ASSIGN_REF(stable_vector) x)
|
||||
{
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
if (this != &x) {
|
||||
if (&x != this){
|
||||
node_allocator_type &this_alloc = this->node_alloc();
|
||||
const node_allocator_type &x_alloc = x.node_alloc();
|
||||
container_detail::bool_<allocator_traits_type::
|
||||
propagate_on_container_copy_assignment::value> flag;
|
||||
if(flag && this_alloc != x_alloc){
|
||||
this->clear();
|
||||
this->shrink_to_fit();
|
||||
}
|
||||
container_detail::assign_alloc(this->node_alloc(), x.node_alloc(), flag);
|
||||
container_detail::assign_alloc(this->impl.get_stored_allocator(), x.impl.get_stored_allocator(), flag);
|
||||
this->assign(x.begin(), x.end());
|
||||
}
|
||||
return *this;
|
||||
@@ -606,8 +656,25 @@ class stable_vector
|
||||
stable_vector& operator=(BOOST_RV_REF(stable_vector) x)
|
||||
{
|
||||
if (&x != this){
|
||||
this->swap(x);
|
||||
x.clear();
|
||||
node_allocator_type &this_alloc = this->node_alloc();
|
||||
node_allocator_type &x_alloc = x.node_alloc();
|
||||
//If allocators are equal we can just swap pointers
|
||||
if(this_alloc == x_alloc){
|
||||
//Destroy objects but retain memory
|
||||
this->clear();
|
||||
this->impl = boost::move(x.impl);
|
||||
this->priv_swap_members(x);
|
||||
//Move allocator if needed
|
||||
container_detail::bool_<allocator_traits_type::
|
||||
propagate_on_container_move_assignment::value> flag;
|
||||
container_detail::move_alloc(this->node_alloc(), x.node_alloc(), flag);
|
||||
}
|
||||
//If unequal allocators, then do a one by one move
|
||||
else{
|
||||
typedef typename std::iterator_traits<iterator>::iterator_category ItCat;
|
||||
this->assign( boost::make_move_iterator(x.begin())
|
||||
, boost::make_move_iterator(x.end()));
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -641,7 +708,27 @@ class stable_vector
|
||||
//! <b>Throws</b>: If allocator's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
allocator_type get_allocator()const {return get_al();}
|
||||
allocator_type get_allocator()const {return node_alloc();}
|
||||
|
||||
//! <b>Effects</b>: Returns a reference to the internal allocator.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
|
||||
{ return node_alloc(); }
|
||||
|
||||
//! <b>Effects</b>: Returns a reference to the internal allocator.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
|
||||
{ return node_alloc(); }
|
||||
|
||||
|
||||
//! <b>Effects</b>: Returns an iterator to the first element contained in the stable_vector.
|
||||
@@ -946,7 +1033,8 @@ class stable_vector
|
||||
void push_back(T &x) { push_back(const_cast<const T &>(x)); }
|
||||
|
||||
template<class U>
|
||||
void push_back(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
|
||||
void push_back(const U &u, typename container_detail::enable_if_c
|
||||
<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
|
||||
{ return priv_push_back(u); }
|
||||
#endif
|
||||
|
||||
@@ -982,7 +1070,8 @@ class stable_vector
|
||||
iterator insert(const_iterator position, T &x) { return this->insert(position, const_cast<const T &>(x)); }
|
||||
|
||||
template<class U>
|
||||
iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
|
||||
iterator insert(const_iterator position, const U &u, typename container_detail::enable_if_c
|
||||
<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
|
||||
{ return this->priv_insert(position, u); }
|
||||
#endif
|
||||
|
||||
@@ -1035,7 +1124,7 @@ class stable_vector
|
||||
boost::mpl::not_<boost::is_integral<InputIterator> >());
|
||||
}
|
||||
|
||||
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! <b>Effects</b>: Inserts an object of type T constructed with
|
||||
//! std::forward<Args>(args)... in the end of the stable_vector.
|
||||
@@ -1046,7 +1135,7 @@ class stable_vector
|
||||
template<class ...Args>
|
||||
void emplace_back(Args &&...args)
|
||||
{
|
||||
typedef emplace_functor<node_type_t, Args...> EmplaceFunctor;
|
||||
typedef emplace_functor<Args...> EmplaceFunctor;
|
||||
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
|
||||
EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
|
||||
this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
|
||||
@@ -1066,7 +1155,7 @@ class stable_vector
|
||||
{
|
||||
//Just call more general insert(pos, size, value) and return iterator
|
||||
size_type pos_n = position - cbegin();
|
||||
typedef emplace_functor<node_type_t, Args...> EmplaceFunctor;
|
||||
typedef emplace_functor<Args...> EmplaceFunctor;
|
||||
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
|
||||
EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
|
||||
this->insert(position, EmplaceIterator(ef), EmplaceIterator());
|
||||
@@ -1075,51 +1164,40 @@ class stable_vector
|
||||
|
||||
#else
|
||||
|
||||
void emplace_back()
|
||||
{
|
||||
typedef emplace_functor<node_type_t> EmplaceFunctor;
|
||||
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
|
||||
EmplaceFunctor ef;
|
||||
this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
|
||||
}
|
||||
|
||||
iterator emplace(const_iterator position)
|
||||
{
|
||||
typedef emplace_functor<node_type_t> EmplaceFunctor;
|
||||
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
|
||||
EmplaceFunctor ef;
|
||||
size_type pos_n = position - this->cbegin();
|
||||
this->insert(position, EmplaceIterator(ef), EmplaceIterator());
|
||||
return iterator(this->begin() + pos_n);
|
||||
}
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
|
||||
void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
|
||||
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
|
||||
void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
||||
{ \
|
||||
typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
|
||||
<node_type_t, BOOST_PP_ENUM_PARAMS(n, P)> EmplaceFunctor; \
|
||||
BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
|
||||
EmplaceFunctor; \
|
||||
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator; \
|
||||
EmplaceFunctor ef(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
|
||||
this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator()); \
|
||||
EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
|
||||
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
|
||||
BOOST_PP_RPAREN_IF(n); \
|
||||
this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator()); \
|
||||
} \
|
||||
\
|
||||
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
|
||||
iterator emplace(const_iterator pos, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
|
||||
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
|
||||
iterator emplace(const_iterator pos \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
||||
{ \
|
||||
typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
|
||||
<node_type_t, BOOST_PP_ENUM_PARAMS(n, P)> EmplaceFunctor; \
|
||||
BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
|
||||
EmplaceFunctor; \
|
||||
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator; \
|
||||
EmplaceFunctor ef(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
|
||||
EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
|
||||
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
|
||||
BOOST_PP_RPAREN_IF(n); \
|
||||
size_type pos_n = pos - this->cbegin(); \
|
||||
this->insert(pos, EmplaceIterator(ef), EmplaceIterator()); \
|
||||
return iterator(this->begin() + pos_n); \
|
||||
} \
|
||||
//!
|
||||
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
|
||||
//! <b>Effects</b>: Erases the element at position pos.
|
||||
//!
|
||||
@@ -1157,7 +1235,11 @@ class stable_vector
|
||||
void swap(stable_vector & x)
|
||||
{
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
this->swap_impl(*this,x);
|
||||
container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
|
||||
container_detail::swap_alloc(this->node_alloc(), x.node_alloc(), flag);
|
||||
//vector's allocator is swapped here
|
||||
this->impl.swap(x.impl);
|
||||
this->priv_swap_members(x);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Erases all the elements of the stable_vector.
|
||||
@@ -1181,7 +1263,8 @@ class stable_vector
|
||||
this->clear_pool();
|
||||
//If empty completely destroy the index, let's recover default-constructed state
|
||||
if(this->empty()){
|
||||
impl_type().swap(this->impl);
|
||||
this->impl.clear();
|
||||
this->impl.shrink_to_fit();
|
||||
this->internal_data.set_end_pointer_to_default_constructed();
|
||||
}
|
||||
//Otherwise, try to shrink-to-fit the index and readjust pointers if necessary
|
||||
@@ -1209,7 +1292,11 @@ class stable_vector
|
||||
void priv_push_back(const value_type &t)
|
||||
{ this->insert(end(), t); }
|
||||
|
||||
void clear_pool(allocator_v1)
|
||||
template<class AllocatorVersion>
|
||||
void clear_pool(AllocatorVersion,
|
||||
typename boost::container::container_detail::enable_if_c
|
||||
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
|
||||
::value>::type * = 0)
|
||||
{
|
||||
if(!impl.empty() && impl.back()){
|
||||
void_ptr &pool_first_ref = impl.end()[-2];
|
||||
@@ -1227,15 +1314,18 @@ class stable_vector
|
||||
}
|
||||
}
|
||||
|
||||
void clear_pool(allocator_v2)
|
||||
template<class AllocatorVersion>
|
||||
void clear_pool(AllocatorVersion,
|
||||
typename boost::container::container_detail::enable_if_c
|
||||
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v2>
|
||||
::value>::type * = 0)
|
||||
{
|
||||
|
||||
if(!impl.empty() && impl.back()){
|
||||
void_ptr &pool_first_ref = impl.end()[-2];
|
||||
void_ptr &pool_last_ref = impl.back();
|
||||
multiallocation_chain holder;
|
||||
holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
|
||||
get_al().deallocate_individual(boost::move(holder));
|
||||
node_alloc().deallocate_individual(boost::move(holder));
|
||||
pool_first_ref = pool_last_ref = 0;
|
||||
this->internal_data.pool_size = 0;
|
||||
}
|
||||
@@ -1251,7 +1341,11 @@ class stable_vector
|
||||
this->add_to_pool(n, alloc_version());
|
||||
}
|
||||
|
||||
void add_to_pool(size_type n, allocator_v1)
|
||||
template<class AllocatorVersion>
|
||||
void add_to_pool(size_type n, AllocatorVersion,
|
||||
typename boost::container::container_detail::enable_if_c
|
||||
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
|
||||
::value>::type * = 0)
|
||||
{
|
||||
size_type remaining = n;
|
||||
while(remaining--){
|
||||
@@ -1259,14 +1353,18 @@ class stable_vector
|
||||
}
|
||||
}
|
||||
|
||||
void add_to_pool(size_type n, allocator_v2)
|
||||
template<class AllocatorVersion>
|
||||
void add_to_pool(size_type n, AllocatorVersion,
|
||||
typename boost::container::container_detail::enable_if_c
|
||||
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v2>
|
||||
::value>::type * = 0)
|
||||
{
|
||||
void_ptr &pool_first_ref = impl.end()[-2];
|
||||
void_ptr &pool_last_ref = impl.back();
|
||||
multiallocation_chain holder;
|
||||
holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
|
||||
//BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled<multiallocation_chain>::value == true));
|
||||
multiallocation_chain m (get_al().allocate_individual(n));
|
||||
multiallocation_chain m (node_alloc().allocate_individual(n));
|
||||
holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n);
|
||||
this->internal_data.pool_size += n;
|
||||
std::pair<void_ptr, void_ptr> data(holder.extract_data());
|
||||
@@ -1375,8 +1473,8 @@ class stable_vector
|
||||
|
||||
template<class AllocatorVersion>
|
||||
iterator priv_erase(const_iterator first, const_iterator last, AllocatorVersion,
|
||||
typename boost::container::containers_detail::enable_if_c
|
||||
<boost::container::containers_detail::is_same<AllocatorVersion, allocator_v2>
|
||||
typename boost::container::container_detail::enable_if_c
|
||||
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v2>
|
||||
::value>::type * = 0)
|
||||
{
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
@@ -1385,14 +1483,12 @@ class stable_vector
|
||||
|
||||
static node_type_ptr_t node_ptr_cast(const void_ptr &p)
|
||||
{
|
||||
using boost::get_pointer;
|
||||
return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::get_pointer(p)));
|
||||
return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
|
||||
}
|
||||
|
||||
static node_type_base_ptr_t node_base_ptr_cast(const void_ptr &p)
|
||||
{
|
||||
using boost::get_pointer;
|
||||
return node_type_base_ptr_t(static_cast<node_type_base_t*>(stable_vector_detail::get_pointer(p)));
|
||||
return node_type_base_ptr_t(static_cast<node_type_base_t*>(stable_vector_detail::to_raw_pointer(p)));
|
||||
}
|
||||
|
||||
static value_type& value(const void_ptr &p)
|
||||
@@ -1434,7 +1530,7 @@ class stable_vector
|
||||
{
|
||||
node_type_ptr_t p = this->allocate_one();
|
||||
try{
|
||||
boost::container::construct_in_place(&*p, it);
|
||||
boost::container::construct_in_place(this->node_alloc(), &*p, it);
|
||||
p->set_pointer(up);
|
||||
}
|
||||
catch(...){
|
||||
@@ -1516,7 +1612,7 @@ class stable_vector
|
||||
template <class FwdIterator>
|
||||
void insert_iter_fwd_alloc(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n, allocator_v2)
|
||||
{
|
||||
multiallocation_chain mem(get_al().allocate_individual(n));
|
||||
multiallocation_chain mem(node_alloc().allocate_individual(n));
|
||||
|
||||
size_type i = 0;
|
||||
node_type_ptr_t p = 0;
|
||||
@@ -1525,7 +1621,7 @@ class stable_vector
|
||||
p = mem.front();
|
||||
mem.pop_front();
|
||||
//This can throw
|
||||
boost::container::construct_in_place(&*p, first);
|
||||
boost::container::construct_in_place(this->node_alloc(), &*p, first);
|
||||
p->set_pointer(void_ptr_ptr(&it[i]));
|
||||
++first;
|
||||
it[i] = p;
|
||||
@@ -1533,8 +1629,8 @@ class stable_vector
|
||||
}
|
||||
}
|
||||
catch(...){
|
||||
get_al().deallocate_one(p);
|
||||
get_al().deallocate_many(boost::move(mem));
|
||||
node_alloc().deallocate_one(p);
|
||||
node_alloc().deallocate_many(boost::move(mem));
|
||||
impl_iterator e = impl.erase(it+i, it+n);
|
||||
this->align_nodes(e, get_last_align());
|
||||
throw;
|
||||
@@ -1548,13 +1644,13 @@ class stable_vector
|
||||
node_type_ptr_t p = 0;
|
||||
try{
|
||||
while(first != last){
|
||||
p = get_from_pool();
|
||||
p = this->get_from_pool();
|
||||
if(!p){
|
||||
insert_iter_fwd_alloc(it+i, first, last, n-i, alloc_version());
|
||||
break;
|
||||
}
|
||||
//This can throw
|
||||
boost::container::construct_in_place(&*p, first);
|
||||
boost::container::construct_in_place(this->node_alloc(), &*p, first);
|
||||
p->set_pointer(void_ptr_ptr(&it[i]));
|
||||
++first;
|
||||
it[i]=p;
|
||||
@@ -1575,16 +1671,6 @@ class stable_vector
|
||||
this->insert_not_iter(position, first, last);
|
||||
}
|
||||
|
||||
static void swap_impl(stable_vector& x,stable_vector& y)
|
||||
{
|
||||
using std::swap;
|
||||
swap(x.get_al(),y.get_al());
|
||||
swap(x.impl,y.impl);
|
||||
swap(x.internal_data.pool_size, y.internal_data.pool_size);
|
||||
x.readjust_end_node();
|
||||
y.readjust_end_node();
|
||||
}
|
||||
|
||||
#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
|
||||
bool invariant()const
|
||||
{
|
||||
@@ -1609,9 +1695,12 @@ class stable_vector
|
||||
return n >= num_pool;
|
||||
}
|
||||
|
||||
class invariant_checker:private boost::noncopyable
|
||||
class invariant_checker
|
||||
{
|
||||
invariant_checker(const invariant_checker &);
|
||||
invariant_checker & operator=(const invariant_checker &);
|
||||
const stable_vector* p;
|
||||
|
||||
public:
|
||||
invariant_checker(const stable_vector& v):p(&v){}
|
||||
~invariant_checker(){BOOST_ASSERT(p->invariant());}
|
||||
@@ -1619,11 +1708,32 @@ class stable_vector
|
||||
};
|
||||
#endif
|
||||
|
||||
struct ebo_holder
|
||||
: node_allocator_type
|
||||
class ebo_holder
|
||||
: public node_allocator_type
|
||||
{
|
||||
ebo_holder(const allocator_type &a)
|
||||
: node_allocator_type(a), pool_size(0), end_node()
|
||||
private:
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(ebo_holder)
|
||||
public:
|
||||
/*
|
||||
explicit ebo_holder(BOOST_RV_REF(ebo_holder) x)
|
||||
: node_allocator_type(boost::move(static_cast<node_allocator_type&>(x)))
|
||||
, pool_size(0)
|
||||
, end_node()
|
||||
{}
|
||||
*/
|
||||
template<class AllocatorRLValue>
|
||||
explicit ebo_holder(BOOST_FWD_REF(AllocatorRLValue) a)
|
||||
: node_allocator_type(boost::forward<AllocatorRLValue>(a))
|
||||
, pool_size(0)
|
||||
, end_node()
|
||||
{
|
||||
this->set_end_pointer_to_default_constructed();
|
||||
}
|
||||
|
||||
ebo_holder()
|
||||
: node_allocator_type()
|
||||
, pool_size(0)
|
||||
, end_node()
|
||||
{
|
||||
this->set_end_pointer_to_default_constructed();
|
||||
}
|
||||
@@ -1637,8 +1747,15 @@ class stable_vector
|
||||
node_type_base_t end_node;
|
||||
} internal_data;
|
||||
|
||||
node_allocator_type &get_al() { return internal_data; }
|
||||
const node_allocator_type &get_al() const { return internal_data; }
|
||||
void priv_swap_members(stable_vector &x)
|
||||
{
|
||||
container_detail::do_swap(this->internal_data.pool_size, x.internal_data.pool_size);
|
||||
this->readjust_end_node();
|
||||
x.readjust_end_node();
|
||||
}
|
||||
|
||||
node_allocator_type &node_alloc() { return internal_data; }
|
||||
const node_allocator_type &node_alloc() const { return internal_data; }
|
||||
|
||||
impl_type impl;
|
||||
/// @endcond
|
||||
|
||||
Reference in New Issue
Block a user