Default initialization for vector-like containers

Complexity guarantees for associative container constructors and ordered input ranges
Fix for #9166
Added benchmark for associative containers
Removed check for old MSVC compilers and #pragma once.

[SVN r85970]
This commit is contained in:
Ion Gaztañaga
2013-09-26 21:35:57 +00:00
parent 11ba31a353
commit 254095432e
57 changed files with 1489 additions and 281 deletions
+6 -1
View File
@@ -17,12 +17,13 @@
#ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
#define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/memory_util.hpp>
#include <boost/container/detail/memory_util.hpp>
@@ -387,6 +388,10 @@ struct allocator_traits
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T>
static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p, ::boost::container::default_init_t)
{ ::new((void*)p) T; }
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
///@endcond
+14 -5
View File
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP
#define BOOST_CONTAINER_CONTAINER_FWD_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -135,20 +135,28 @@ class basic_string;
struct ordered_range_t
{};
//! Value used to tag that the input range is
//! guaranteed to be ordered
static const ordered_range_t ordered_range = ordered_range_t();
//! Type used to tag that the input range is
//! guaranteed to be ordered and unique
struct ordered_unique_range_t
: public ordered_range_t
{};
//! Value used to tag that the input range is
//! guaranteed to be ordered
static const ordered_range_t ordered_range = ordered_range_t();
//! Value used to tag that the input range is
//! guaranteed to be ordered and unique
static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t();
//! Type used to tag that the input range is
//! guaranteed to be ordered and unique
struct default_init_t
{};
//! Value used to tag that the input range is
//! guaranteed to be ordered and unique
static const default_init_t default_init = default_init_t();
/// @cond
namespace detail_really_deep_namespace {
@@ -161,6 +169,7 @@ struct dummy
{
(void)ordered_range;
(void)ordered_unique_range;
(void)default_init;
}
};
+43 -6
View File
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_DEQUE_HPP
#define BOOST_CONTAINER_DEQUE_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -540,7 +540,7 @@ class deque : protected deque_base<Allocator>
{}
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
//! and inserts n default contructed values.
//! and inserts n value initialized values.
//!
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
//! throws or T's default or copy constructor throws.
@@ -549,7 +549,24 @@ class deque : protected deque_base<Allocator>
explicit deque(size_type n)
: Base(n, allocator_type())
{
container_detail::insert_default_constructed_n_proxy<Allocator, iterator> proxy(this->alloc());
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
proxy.uninitialized_copy_n_and_update(this->begin(), n);
//deque_base will deallocate in case of exception...
}
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
//! and inserts n default initialized values.
//!
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
//! throws or T's default or copy constructor throws.
//!
//! <b>Complexity</b>: Linear to n.
//!
//! <b>Note</b>: Non-standard extension
deque(size_type n, default_init_t)
: Base(n, allocator_type())
{
container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
proxy.uninitialized_copy_n_and_update(this->begin(), n);
//deque_base will deallocate in case of exception...
}
@@ -949,9 +966,9 @@ class deque : protected deque_base<Allocator>
{ return allocator_traits_type::max_size(this->alloc()); }
//! <b>Effects</b>: Inserts or erases elements at the end such that
//! the size becomes n. New elements are default constructed.
//! the size becomes n. New elements are value initialized.
//!
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
//!
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
void resize(size_type new_size)
@@ -961,7 +978,27 @@ class deque : protected deque_base<Allocator>
this->priv_erase_last_n(len - new_size);
else{
const size_type n = new_size - this->size();
container_detail::insert_default_constructed_n_proxy<Allocator, iterator> proxy(this->alloc());
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
priv_insert_back_aux_impl(n, proxy);
}
}
//! <b>Effects</b>: Inserts or erases elements at the end such that
//! the size becomes n. New elements are default initialized.
//!
//! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
//!
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
//!
//! <b>Note</b>: Non-standard extension
void resize(size_type new_size, default_init_t)
{
const size_type len = size();
if (new_size < len)
this->priv_erase_last_n(len - new_size);
else{
const size_type n = new_size - this->size();
container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
priv_insert_back_aux_impl(n, proxy);
}
}
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
#define BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
#define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -99,19 +99,43 @@ struct insert_n_copies_proxy
};
template<class A, class Iterator>
struct insert_default_constructed_n_proxy
struct insert_value_initialized_n_proxy
{
typedef ::boost::container::allocator_traits<A> alloc_traits;
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
explicit insert_default_constructed_n_proxy(A &a)
explicit insert_value_initialized_n_proxy(A &a)
: a_(a)
{}
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
{ boost::container::uninitialized_default_alloc_n(this->a_, n, p); }
{ boost::container::uninitialized_value_init_alloc_n(this->a_, n, p); }
void copy_n_and_update(Iterator, size_type) const
{
BOOST_ASSERT(false);
}
private:
A &a_;
};
template<class A, class Iterator>
struct insert_default_initialized_n_proxy
{
typedef ::boost::container::allocator_traits<A> alloc_traits;
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
explicit insert_default_initialized_n_proxy(A &a)
: a_(a)
{}
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
{ boost::container::uninitialized_default_init_alloc_n(this->a_, n, p); }
void copy_n_and_update(Iterator, size_type) const
{
+10 -4
View File
@@ -13,7 +13,7 @@
#ifndef BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
#define BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -35,13 +35,13 @@ namespace boost {
namespace container {
template<class It>
struct is_default_construct_iterator
struct is_value_init_construct_iterator
{
static const bool value = false;
};
template<class U, class D>
struct is_default_construct_iterator<default_construct_iterator<U, D> >
struct is_value_init_construct_iterator<value_init_construct_iterator<U, D> >
{
static const bool value = true;
};
@@ -64,11 +64,17 @@ inline void construct_in_place(A &a, T* dest, InpIt source)
//#endif
template<class A, class T, class U, class D>
inline void construct_in_place(A &a, T *dest, default_construct_iterator<U, D>)
inline void construct_in_place(A &a, T *dest, value_init_construct_iterator<U, D>)
{
boost::container::allocator_traits<A>::construct(a, dest);
}
template<class A, class T, class U, class D>
inline void construct_in_place(A &a, T *dest, default_init_construct_iterator<U, D>)
{
boost::container::allocator_traits<A>::construct(a, dest, default_init);
}
template<class A, class T, class U, class EF, class D>
inline void construct_in_place(A &a, T *dest, emplace_iterator<U, EF, D> ei)
{
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_ALLOCATION_TYPE_HPP
#define BOOST_CONTAINER_ALLOCATION_TYPE_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
#define BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -92,8 +92,12 @@ struct allocator_version_traits<Allocator, 1>
static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
{
while(!holder.empty()){
a.deallocate(holder.pop_front(), 1);
size_type n = holder.size();
typename multiallocation_chain::iterator it = holder.begin();
while(n--){
pointer p = boost::intrusive::pointer_traits<pointer>::pointer_to(*it);
++it;
a.deallocate(p, 1);
}
}
@@ -46,4 +46,5 @@
#pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
#pragma warning (disable : 4671) // the copy constructor is inaccessible
#pragma warning (disable : 4584) // X is already a base-class of Y
#pragma warning (disable : 4510) // default constructor could not be generated
#endif //BOOST_MSVC
+12 -1
View File
@@ -13,7 +13,7 @@
#ifndef BOOST_CONTAINER_DESTROYERS_HPP
#define BOOST_CONTAINER_DESTROYERS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -68,6 +68,9 @@ struct scoped_deallocator
pointer get() const
{ return m_ptr; }
void set(const pointer &p)
{ m_ptr = p; }
void release()
{ m_ptr = 0; }
};
@@ -87,6 +90,9 @@ struct null_scoped_deallocator
pointer get() const
{ return pointer(); }
void set(const pointer &)
{}
};
//!A deleter for scoped_ptr that deallocates the memory
@@ -249,6 +255,11 @@ class scoped_destructor
void release()
{ pv_ = 0; }
void set(value_type *ptr) { pv_ = ptr; }
value_type *get() const { return pv_; }
private:
value_type *pv_;
A &a_;
+52 -48
View File
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_FLAT_TREE_HPP
#define BOOST_CONTAINER_FLAT_TREE_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -240,16 +240,24 @@ class flat_tree
, const allocator_type& a = allocator_type())
: m_data(comp, a)
{
//Use cend() as hint to achieve linear time for
//ordered ranges as required by the standard
//for the constructor
//Call end() every iteration as reallocation might have invalidated iterators
if(unique_insertion){
this->insert_unique(first, last);
for ( ; first != last; ++first){
this->insert_unique(this->cend(), *first);
}
}
else{
this->insert_equal(first, last);
for ( ; first != last; ++first){
this->insert_equal(this->cend(), *first);
}
}
}
~flat_tree()
{ }
{}
flat_tree& operator=(BOOST_COPY_ASSIGN_REF(flat_tree) x)
{ m_data = x.m_data; return *this; }
@@ -389,7 +397,11 @@ class flat_tree
template <class InIt>
void insert_unique(InIt first, InIt last)
{ this->priv_insert_unique_loop(first, last); }
{
for ( ; first != last; ++first){
this->insert_unique(*first);
}
}
template <class InIt>
void insert_equal(InIt first, InIt last
@@ -487,7 +499,13 @@ class flat_tree
>::type * = 0
#endif
)
{ this->priv_insert_unique_loop_hint(first, last); }
{
const_iterator pos(this->cend());
for ( ; first != last; ++first){
pos = this->insert_unique(pos, *first);
++pos;
}
}
template <class BidirIt>
void insert_unique(ordered_unique_range_t, BidirIt first, BidirIt last
@@ -677,22 +695,21 @@ class flat_tree
// set operations:
iterator find(const key_type& k)
{
const Compare &key_cmp = this->m_data.get_comp();
iterator i = this->lower_bound(k);
if (i != this->end() && key_cmp(k, KeyOfValue()(*i))){
i = this->end();
iterator end_it = this->end();
if (i != end_it && this->m_data.get_comp()(k, KeyOfValue()(*i))){
i = end_it;
}
return i;
}
const_iterator find(const key_type& k) const
{
const Compare &key_cmp = this->m_data.get_comp();
const_iterator i = this->lower_bound(k);
if (i != this->end() && key_cmp(k, KeyOfValue()(*i))){
i = this->end();
const_iterator end_it = this->cend();
if (i != end_it && this->m_data.get_comp()(k, KeyOfValue()(*i))){
i = end_it;
}
return i;
}
@@ -708,19 +725,19 @@ class flat_tree
{ return this->priv_lower_bound(this->begin(), this->end(), k); }
const_iterator lower_bound(const key_type& k) const
{ return this->priv_lower_bound(this->begin(), this->end(), k); }
{ return this->priv_lower_bound(this->cbegin(), this->cend(), k); }
iterator upper_bound(const key_type& k)
{ return this->priv_upper_bound(this->begin(), this->end(), k); }
const_iterator upper_bound(const key_type& k) const
{ return this->priv_upper_bound(this->begin(), this->end(), k); }
{ return this->priv_upper_bound(this->cbegin(), this->cend(), k); }
std::pair<iterator,iterator> equal_range(const key_type& k)
{ return this->priv_equal_range(this->begin(), this->end(), k); }
std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
{ return this->priv_equal_range(this->begin(), this->end(), k); }
{ return this->priv_equal_range(this->cbegin(), this->cend(), k); }
size_type capacity() const
{ return this->m_data.m_vect.capacity(); }
@@ -817,7 +834,6 @@ class flat_tree
//in the remaining range [pos, end)
return this->priv_insert_unique_prepare(pos, cend_it, val, commit_data);
}
//return priv_insert_unique_prepare(val, commit_data);
}
template<class Convertible>
@@ -835,11 +851,11 @@ class flat_tree
{
const Compare &key_cmp = this->m_data.get_comp();
KeyOfValue key_extract;
difference_type len = last - first, half;
size_type len = static_cast<size_type>(last - first);
RanIt middle;
while (len > 0) {
half = len >> 1;
while (len) {
size_type half = len >> 1;
middle = first;
middle += half;
@@ -854,17 +870,18 @@ class flat_tree
return first;
}
template <class RanIt>
RanIt priv_upper_bound(RanIt first, RanIt last,
const key_type & key) const
{
const Compare &key_cmp = this->m_data.get_comp();
KeyOfValue key_extract;
difference_type len = last - first, half;
size_type len = static_cast<size_type>(last - first);
RanIt middle;
while (len > 0) {
half = len >> 1;
while (len) {
size_type half = len >> 1;
middle = first;
middle += half;
@@ -885,11 +902,11 @@ class flat_tree
{
const Compare &key_cmp = this->m_data.get_comp();
KeyOfValue key_extract;
difference_type len = last - first, half;
RanIt middle, left, right;
size_type len = static_cast<size_type>(last - first);
RanIt middle;
while (len > 0) {
half = len >> 1;
while (len) {
size_type half = len >> 1;
middle = first;
middle += half;
@@ -902,10 +919,11 @@ class flat_tree
len = half;
}
else {
left = this->priv_lower_bound(first, middle, key);
first += len;
right = this->priv_upper_bound(++middle, first, key);
return std::pair<RanIt, RanIt>(left, right);
//Middle is equal to key
last = first;
last += len;
first = this->priv_lower_bound(first, middle, key);
return std::pair<RanIt, RanIt> (first, this->priv_upper_bound(++middle, last, key));
}
}
return std::pair<RanIt, RanIt>(first, first);
@@ -924,24 +942,10 @@ class flat_tree
{
const_iterator pos(this->cend());
for ( ; first != last; ++first){
//If ordered, then try hint version
//to achieve constant-time complexity per insertion
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);
++pos;
}
}
};
+136 -24
View File
@@ -14,7 +14,7 @@
#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
#define BOOST_CONTAINER_DETAIL_ITERATORS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -148,79 +148,79 @@ class constant_iterator
};
template <class T, class Difference = std::ptrdiff_t>
class default_construct_iterator
class value_init_construct_iterator
: public std::iterator
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
{
typedef default_construct_iterator<T, Difference> this_type;
typedef value_init_construct_iterator<T, Difference> this_type;
public:
explicit default_construct_iterator(Difference range_size)
explicit value_init_construct_iterator(Difference range_size)
: m_num(range_size){}
//Constructors
default_construct_iterator()
value_init_construct_iterator()
: m_num(0){}
default_construct_iterator& operator++()
value_init_construct_iterator& operator++()
{ increment(); return *this; }
default_construct_iterator operator++(int)
value_init_construct_iterator operator++(int)
{
default_construct_iterator result (*this);
value_init_construct_iterator result (*this);
increment();
return result;
}
default_construct_iterator& operator--()
value_init_construct_iterator& operator--()
{ decrement(); return *this; }
default_construct_iterator operator--(int)
value_init_construct_iterator operator--(int)
{
default_construct_iterator result (*this);
value_init_construct_iterator result (*this);
decrement();
return result;
}
friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2)
friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
{ return i.equal(i2); }
friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2)
friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
{ return !(i == i2); }
friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2)
friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
{ return i.less(i2); }
friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2)
friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
{ return i2 < i; }
friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2)
friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
{ return !(i > i2); }
friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2)
friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
{ return !(i < i2); }
friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2)
friend Difference operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
{ return i2.distance_to(i); }
//Arithmetic
default_construct_iterator& operator+=(Difference off)
value_init_construct_iterator& operator+=(Difference off)
{ this->advance(off); return *this; }
default_construct_iterator operator+(Difference off) const
value_init_construct_iterator operator+(Difference off) const
{
default_construct_iterator other(*this);
value_init_construct_iterator other(*this);
other.advance(off);
return other;
}
friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right)
friend value_init_construct_iterator operator+(Difference off, const value_init_construct_iterator& right)
{ return right + off; }
default_construct_iterator& operator-=(Difference off)
value_init_construct_iterator& operator-=(Difference off)
{ this->advance(-off); return *this; }
default_construct_iterator operator-(Difference off) const
value_init_construct_iterator operator-(Difference off) const
{ return *this + (-off); }
//This pseudo-iterator's dereference operations have no sense since value is not
@@ -258,6 +258,118 @@ class default_construct_iterator
{ return m_num - other.m_num; }
};
template <class T, class Difference = std::ptrdiff_t>
class default_init_construct_iterator
: public std::iterator
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
{
typedef default_init_construct_iterator<T, Difference> this_type;
public:
explicit default_init_construct_iterator(Difference range_size)
: m_num(range_size){}
//Constructors
default_init_construct_iterator()
: m_num(0){}
default_init_construct_iterator& operator++()
{ increment(); return *this; }
default_init_construct_iterator operator++(int)
{
default_init_construct_iterator result (*this);
increment();
return result;
}
default_init_construct_iterator& operator--()
{ decrement(); return *this; }
default_init_construct_iterator operator--(int)
{
default_init_construct_iterator result (*this);
decrement();
return result;
}
friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
{ return i.equal(i2); }
friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
{ return !(i == i2); }
friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
{ return i.less(i2); }
friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
{ return i2 < i; }
friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
{ return !(i > i2); }
friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
{ return !(i < i2); }
friend Difference operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
{ return i2.distance_to(i); }
//Arithmetic
default_init_construct_iterator& operator+=(Difference off)
{ this->advance(off); return *this; }
default_init_construct_iterator operator+(Difference off) const
{
default_init_construct_iterator other(*this);
other.advance(off);
return other;
}
friend default_init_construct_iterator operator+(Difference off, const default_init_construct_iterator& right)
{ return right + off; }
default_init_construct_iterator& operator-=(Difference off)
{ this->advance(-off); return *this; }
default_init_construct_iterator operator-(Difference off) const
{ return *this + (-off); }
//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;
void increment()
{ --m_num; }
void decrement()
{ ++m_num; }
bool equal(const this_type &other) const
{ return m_num == other.m_num; }
bool less(const this_type &other) const
{ return other.m_num < m_num; }
const T & dereference() const
{
static T dummy;
return dummy;
}
void advance(Difference n)
{ m_num -= n; }
Difference distance_to(const this_type &other)const
{ return m_num - other.m_num; }
};
template <class T, class Difference = std::ptrdiff_t>
class repeat_iterator
: public std::iterator
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP
#define BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
+1 -1
View File
@@ -13,7 +13,7 @@
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
#define BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -243,10 +243,10 @@ class transform_multiallocation_chain
iterator before_begin()
{ return iterator(holder_.before_begin()); }
*/
iterator begin()
{ return iterator(holder_.begin()); }
{ return iterator(this->MultiallocationChain::begin()); }
/*
iterator end()
{ return iterator(holder_.end()); }
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
#define BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -28,6 +28,7 @@
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/allocator_version_traits.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/destroyers.hpp>
#include <boost/container/detail/allocator_version_traits.hpp>
@@ -80,6 +81,7 @@ struct node_alloc_holder
typedef typename allocator_traits_type::template
portable_rebind_alloc<Node>::type NodeAlloc;
typedef allocator_traits<NodeAlloc> node_allocator_traits_type;
typedef container_detail::allocator_version_traits<NodeAlloc> node_allocator_version_traits_type;
typedef A ValAlloc;
typedef typename node_allocator_traits_type::pointer NodePtr;
typedef container_detail::scoped_deallocator<NodeAlloc> Deallocator;
@@ -233,45 +235,41 @@ struct node_alloc_holder
(FwdIterator beg, difference_type n, Inserter inserter)
{
if(n){
/*
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
::boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), it);
node_deallocator.release();
//This does not throw
typedef typename Node::hook_type hook_type;
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
return (p);
*/
typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
typedef typename node_allocator_version_traits_type::multiallocation_chain multiallocation_chain;
//Try to allocate memory in a single block
typedef typename multiallocation_chain::iterator multialloc_iterator;
multiallocation_chain mem;
this->node_alloc().allocate_individual(n, mem);
NodeAlloc &nalloc = this->node_alloc();
node_allocator_version_traits_type::allocate_individual(nalloc, n, mem);
multialloc_iterator itbeg(mem.begin()), itlast(mem.last());
mem.clear();
Node *p = 0;
NodeAlloc &nalloc = this->node_alloc();
BOOST_TRY{
Deallocator node_deallocator(NodePtr(), nalloc);
container_detail::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0);
while(n--){
p = container_detail::to_raw_pointer(&*itbeg);
node_deallocator.set(p);
++itbeg;
//This can throw
Deallocator node_deallocator(p, nalloc);
boost::container::construct_in_place(nalloc, container_detail::addressof(p->m_data), beg);
sdestructor.set(p);
++beg;
node_deallocator.release();
//This does not throw
typedef typename Node::hook_type hook_type;
::new(static_cast<hook_type*>(p)) hook_type;
//This can throw in some containers (predicate might throw)
//This can throw in some containers (predicate might throw).
//(sdestructor will destruct the node and node_deallocator will deallocate it in case of exception)
inserter(*p);
sdestructor.set(0);
}
sdestructor.release();
node_deallocator.release();
}
BOOST_CATCH(...){
mem.incorporate_after(mem.last(), &*itbeg, &*itlast, n);
this->node_alloc().deallocate_individual(mem);
node_allocator_version_traits_type::deallocate_individual(this->node_alloc(), mem);
BOOST_RETHROW
}
BOOST_CATCH_END
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
#define BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
+1 -1
View File
@@ -13,7 +13,7 @@
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
#define BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
#define BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
#define BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -14,7 +14,7 @@
#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
#define BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
+121 -85
View File
@@ -178,6 +178,34 @@ struct rbtree_node
{ m_data = ::boost::move(v); }
};
template<class Node, class Icont>
class insert_equal_end_hint_functor
{
Icont &icont_;
public:
insert_equal_end_hint_functor(Icont &icont)
: icont_(icont)
{}
void operator()(Node &n)
{ this->icont_.insert_equal(this->icont_.cend(), n); }
};
template<class Node, class Icont>
class push_back_functor
{
Icont &icont_;
public:
push_back_functor(Icont &icont)
: icont_(icont)
{}
void operator()(Node &n)
{ this->icont_.push_back(n); }
};
}//namespace container_detail {
namespace container_detail {
@@ -405,11 +433,19 @@ class rbtree
)
: AllocHolder(a, value_compare(comp))
{
//Use cend() as hint to achieve linear time for
//ordered ranges as required by the standard
//for the constructor
const const_iterator end_it(this->cend());
if(unique_insertion){
this->insert_unique(first, last);
for ( ; first != last; ++first){
this->insert_unique(end_it, *first);
}
}
else{
this->insert_equal(first, last);
for ( ; first != last; ++first){
this->insert_equal(end_it, *first);
}
}
}
@@ -426,12 +462,19 @@ class rbtree
: AllocHolder(a, value_compare(comp))
{
if(unique_insertion){
this->insert_unique(first, last);
//Use cend() as hint to achieve linear time for
//ordered ranges as required by the standard
//for the constructor
const const_iterator end_it(this->cend());
for ( ; first != last; ++first){
this->insert_unique(end_it, *first);
}
}
else{
//Optimized allocation and construction
this->allocate_many_and_construct
(first, std::distance(first, last), insert_equal_end_hint_functor(this->icont()));
( first, std::distance(first, last)
, insert_equal_end_hint_functor<Node, Icont>(this->icont()));
}
}
@@ -447,7 +490,9 @@ class rbtree
)
: AllocHolder(a, value_compare(comp))
{
this->insert_equal(first, last);
for ( ; first != last; ++first){
this->push_back_impl(*first);
}
}
template <class InputIterator>
@@ -464,7 +509,8 @@ class rbtree
{
//Optimized allocation and construction
this->allocate_many_and_construct
(first, std::distance(first, last), push_back_functor(this->icont()));
( first, std::distance(first, last)
, container_detail::push_back_functor<Node, Icont>(this->icont()));
}
rbtree(const rbtree& x)
@@ -534,8 +580,8 @@ class rbtree
rbtree& operator=(BOOST_RV_REF(rbtree) x)
{
if (&x != this){
NodeAlloc &this_alloc = this->node_alloc();
NodeAlloc &x_alloc = x.node_alloc();
NodeAlloc &this_alloc = this->get_stored_allocator();
const NodeAlloc &x_alloc = x.get_stored_allocator();
//If allocators are equal we can just swap pointers
if(this_alloc == x_alloc){
//Destroy and swap pointers
@@ -678,8 +724,10 @@ class rbtree
iterator insert_unique_commit(const value_type& v, insert_commit_data &data)
{
NodePtr tmp = AllocHolder::create_node(v);
iiterator it(this->icont().insert_unique_commit(*tmp, data));
return iterator(it);
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_unique_commit(*tmp, data));
destroy_deallocator.release();
return ret;
}
template<class MovableConvertible>
@@ -687,8 +735,10 @@ class rbtree
(BOOST_FWD_REF(MovableConvertible) mv, insert_commit_data &data)
{
NodePtr tmp = AllocHolder::create_node(boost::forward<MovableConvertible>(mv));
iiterator it(this->icont().insert_unique_commit(*tmp, data));
return iterator(it);
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_unique_commit(*tmp, data));
destroy_deallocator.release();
return ret;
}
std::pair<iterator,bool> insert_unique(const value_type& v)
@@ -696,10 +746,10 @@ class rbtree
insert_commit_data data;
std::pair<iterator,bool> ret =
this->insert_unique_check(KeyOfValue()(v), data);
if(!ret.second)
return ret;
return std::pair<iterator,bool>
(this->insert_unique_commit(v, data), true);
if(ret.second){
ret.first = this->insert_unique_commit(v, data);
}
return ret;
}
template<class MovableConvertible>
@@ -708,13 +758,22 @@ class rbtree
insert_commit_data data;
std::pair<iterator,bool> ret =
this->insert_unique_check(KeyOfValue()(mv), data);
if(!ret.second)
return ret;
return std::pair<iterator,bool>
(this->insert_unique_commit(boost::forward<MovableConvertible>(mv), data), true);
if(ret.second){
ret.first = this->insert_unique_commit(boost::forward<MovableConvertible>(mv), data);
}
return ret;
}
private:
template<class MovableConvertible>
void push_back_impl(BOOST_FWD_REF(MovableConvertible) mv)
{
NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
//push_back has no-throw guarantee so avoid any deallocator/destroyer
this->icont().push_back(*tmp);
}
std::pair<iterator, bool> emplace_unique_impl(NodePtr p)
{
value_type &v = p->get_data();
@@ -760,15 +819,21 @@ class rbtree
template <class... Args>
iterator emplace_equal(Args&&... args)
{
NodePtr p(AllocHolder::create_node(boost::forward<Args>(args)...));
return iterator(this->icont().insert_equal(this->icont().end(), *p));
NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
destroy_deallocator.release();
return ret;
}
template <class... Args>
iterator emplace_hint_equal(const_iterator hint, Args&&... args)
{
NodePtr p(AllocHolder::create_node(boost::forward<Args>(args)...));
return iterator(this->icont().insert_equal(hint.get(), *p));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
destroy_deallocator.release();
return ret;
}
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
@@ -792,16 +857,22 @@ class rbtree
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
return iterator(this->icont().insert_equal(this->icont().end(), *p)); \
NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); \
iterator ret(this->icont().insert_equal(this->icont().end(), *tmp)); \
destroy_deallocator.release(); \
return ret; \
} \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint_equal(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
return iterator(this->icont().insert_equal(hint.get(), *p)); \
NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); \
iterator ret(this->icont().insert_equal(hint.get(), *tmp)); \
destroy_deallocator.release(); \
return ret; \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
@@ -833,53 +904,53 @@ class rbtree
template <class InputIterator>
void insert_unique(InputIterator first, InputIterator last)
{
if(this->empty()){
//Insert with end hint, to achieve linear
//complexity if [first, last) is ordered
const_iterator hint(this->cend());
for( ; first != last; ++first)
hint = this->insert_unique(hint, *first);
}
else{
for( ; first != last; ++first)
this->insert_unique(*first);
}
for( ; first != last; ++first)
this->insert_unique(*first);
}
iterator insert_equal(const value_type& v)
{
NodePtr p(AllocHolder::create_node(v));
return iterator(this->icont().insert_equal(this->icont().end(), *p));
NodePtr tmp(AllocHolder::create_node(v));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
destroy_deallocator.release();
return ret;
}
template<class MovableConvertible>
iterator insert_equal(BOOST_FWD_REF(MovableConvertible) mv)
{
NodePtr p(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
return iterator(this->icont().insert_equal(this->icont().end(), *p));
NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
destroy_deallocator.release();
return ret;
}
iterator insert_equal(const_iterator hint, const value_type& v)
{
NodePtr p(AllocHolder::create_node(v));
return iterator(this->icont().insert_equal(hint.get(), *p));
NodePtr tmp(AllocHolder::create_node(v));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
destroy_deallocator.release();
return ret;
}
template<class MovableConvertible>
iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv)
{
NodePtr p(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
return iterator(this->icont().insert_equal(hint.get(), *p));
NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
destroy_deallocator.release();
return ret;
}
template <class InputIterator>
void insert_equal(InputIterator first, InputIterator last)
{
//Insert with end hint, to achieve linear
//complexity if [first, last) is ordered
const_iterator hint(this->cend());
for( ; first != last; ++first)
hint = this->insert_equal(hint, *first);
this->insert_equal(*first);
}
iterator erase(const_iterator position)
@@ -930,41 +1001,6 @@ class rbtree
return std::pair<const_iterator,const_iterator>
(const_iterator(ret.first), const_iterator(ret.second));
}
private:
class insert_equal_end_hint_functor;
friend class insert_equal_end_hint_functor;
class insert_equal_end_hint_functor
{
Icont &icont_;
const iconst_iterator cend_;
public:
insert_equal_end_hint_functor(Icont &icont)
: icont_(icont), cend_(this->icont_.cend())
{}
void operator()(Node &n)
{ this->icont_.insert_equal(cend_, n); }
};
class push_back_functor;
friend class push_back_functor;
class push_back_functor
{
Icont &icont_;
public:
push_back_functor(Icont &icont)
: icont_(icont)
{}
void operator()(Node &n)
{ this->icont_.push_back(n); }
};
};
template <class Key, class Value, class KeyOfValue,
@@ -15,7 +15,7 @@
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
#define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
+37 -2
View File
@@ -622,7 +622,7 @@ inline typename container_detail::enable_if_memcpy_copy_constructible<I, F, I>::
//////////////////////////////////////////////////////////////////////////////
//
// uninitialized_default_alloc_n
// uninitialized_value_init_alloc_n
//
//////////////////////////////////////////////////////////////////////////////
@@ -636,7 +636,7 @@ inline typename container_detail::enable_if_memcpy_copy_constructible<I, F, I>::
template
<typename A,
typename F> // F models ForwardIterator
inline F uninitialized_default_alloc_n(A &a, typename allocator_traits<A>::difference_type n, F r)
inline F uninitialized_value_init_alloc_n(A &a, typename allocator_traits<A>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
@@ -655,6 +655,41 @@ inline F uninitialized_default_alloc_n(A &a, typename allocator_traits<A>::diffe
return r;
}
//////////////////////////////////////////////////////////////////////////////
//
// uninitialized_default_init_alloc_n
//
//////////////////////////////////////////////////////////////////////////////
//! <b>Effects</b>:
//! \code
//! for (; n--; ++r, ++f)
//! allocator_traits::construct(a, &*r);
//! \endcode
//!
//! <b>Returns</b>: r
template
<typename A,
typename F> // F models ForwardIterator
inline F uninitialized_default_init_alloc_n(A &a, typename allocator_traits<A>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), default_init);
++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
}
BOOST_RETHROW;
}
BOOST_CATCH_END
return r;
}
//////////////////////////////////////////////////////////////////////////////
//
// uninitialized_fill_alloc
@@ -13,7 +13,7 @@
#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
#define BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
#define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
+6 -2
View File
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_FLAT_MAP_HPP
#define BOOST_CONTAINER_FLAT_MAP_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -694,6 +694,8 @@ class flat_map
//! search time plus N*size() insertion time.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
void insert(ordered_unique_range_t, InputIterator first, InputIterator last)
{ m_flat_tree.insert_unique(ordered_unique_range, first, last); }
@@ -798,7 +800,7 @@ class flat_map
//!
//! <b>Complexity</b>: log(size())+count(k)
size_type count(const key_type& x) const
{ return m_flat_tree.find(x) == m_flat_tree.end() ? 0 : 1; }
{ return static_cast<size_type>(m_flat_tree.find(x) != m_flat_tree.end()); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
@@ -1487,6 +1489,8 @@ class flat_multimap
//! search time plus N*size() insertion time.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
void insert(ordered_range_t, InputIterator first, InputIterator last)
{ m_flat_tree.insert_equal(ordered_range, first, last); }
+2 -2
View File
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_FLAT_SET_HPP
#define BOOST_CONTAINER_FLAT_SET_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -636,7 +636,7 @@ class flat_set
//!
//! <b>Complexity</b>: log(size())+count(k)
size_type count(const key_type& x) const
{ return m_flat_tree.find(x) == m_flat_tree.end() ? 0 : 1; }
{ return static_cast<size_type>(m_flat_tree.find(x) != m_flat_tree.end()); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
+4 -4
View File
@@ -10,7 +10,7 @@
#ifndef BOOST_CONTAINER_LIST_HPP
#define BOOST_CONTAINER_LIST_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -563,7 +563,7 @@ class list
{ return AllocHolder::max_size(); }
//! <b>Effects</b>: Inserts or erases elements at the end such that
//! the size becomes n. New elements are default constructed.
//! the size becomes n. New elements are value initialized.
//!
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//!
@@ -571,8 +571,8 @@ class list
void resize(size_type new_size)
{
if(!priv_try_shrink(new_size)){
typedef default_construct_iterator<value_type, difference_type> default_iterator;
this->insert(this->cend(), default_iterator(new_size - this->size()), default_iterator());
typedef value_init_construct_iterator<value_type, difference_type> value_init_iterator;
this->insert(this->cend(), value_init_iterator(new_size - this->size()), value_init_iterator());
}
}
+6 -2
View File
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_MAP_HPP
#define BOOST_CONTAINER_MAP_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -170,6 +170,8 @@ class map
//! unique values.
//!
//! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
map( ordered_unique_range_t, InputIterator first, InputIterator last
, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
@@ -711,7 +713,7 @@ class map
//!
//! <b>Complexity</b>: log(size())+count(k)
size_type count(const key_type& x) const
{ return m_tree.find(x) == m_tree.end() ? 0 : 1; }
{ return static_cast<size_type>(m_tree.find(x) != m_tree.end()); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
@@ -971,6 +973,8 @@ class multimap
//! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
//!
//! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(),
const allocator_type& a = allocator_type())
+1 -1
View File
@@ -17,7 +17,7 @@
#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
#if (defined MSC_VER) && (_MSC_VER >= 1200)
#if defined (_MSC_VER)
# pragma once
#endif
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
#if (defined MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
+6 -2
View File
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_SET_HPP
#define BOOST_CONTAINER_SET_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -139,6 +139,8 @@ class set
//! unique values.
//!
//! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
set( ordered_unique_range_t, InputIterator first, InputIterator last
, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
@@ -556,7 +558,7 @@ class set
//!
//! <b>Complexity</b>: log(size())+count(k)
size_type count(const key_type& x) const
{ return m_tree.find(x) == m_tree.end() ? 0 : 1; }
{ return static_cast<size_type>(m_tree.find(x) != m_tree.end()); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
@@ -770,6 +772,8 @@ class multiset
//! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
//!
//! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
multiset( ordered_range_t, InputIterator first, InputIterator last
, const Compare& comp = Compare()
+4 -4
View File
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_SLIST_HPP
#define BOOST_CONTAINER_SLIST_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -588,7 +588,7 @@ class slist
{ return AllocHolder::max_size(); }
//! <b>Effects</b>: Inserts or erases elements at the end such that
//! the size becomes n. New elements are default constructed.
//! the size becomes n. New elements are value initialized.
//!
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//!
@@ -597,8 +597,8 @@ class slist
{
const_iterator last_pos;
if(!priv_try_shrink(new_size, last_pos)){
typedef default_construct_iterator<value_type, difference_type> default_iterator;
this->insert_after(last_pos, default_iterator(new_size - this->size()), default_iterator());
typedef value_init_construct_iterator<value_type, difference_type> value_init_iterator;
this->insert_after(last_pos, value_init_iterator(new_size - this->size()), value_init_iterator());
}
}
+44 -8
View File
@@ -19,7 +19,7 @@
#ifndef BOOST_CONTAINER_STABLE_VECTOR_HPP
#define BOOST_CONTAINER_STABLE_VECTOR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -123,8 +123,8 @@ struct node
rebind_pointer<void>::type
>
{
private:
node();
// private:
// node();
public:
typename ::boost::intrusive::pointer_traits<Pointer>::element_type value;
@@ -568,7 +568,7 @@ class stable_vector
}
//! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
//! and inserts n default contructed values.
//! and inserts n value initialized values.
//!
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
//! throws or T's default or copy constructor throws.
@@ -583,6 +583,24 @@ class stable_vector
cod.release();
}
//! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
//! and inserts n default initialized values.
//!
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
//! throws or T's default or copy constructor throws.
//!
//! <b>Complexity</b>: Linear to n.
//!
//! <b>Note</b>: Non-standard extension
stable_vector(size_type n, default_init_t)
: internal_data(), index()
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->resize(n, default_init);
STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
//! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
//! and inserts n copies of value.
//!
@@ -960,17 +978,35 @@ class stable_vector
{ return this->index.max_size() - ExtraPointers; }
//! <b>Effects</b>: Inserts or erases elements at the end such that
//! the size becomes n. New elements are default constructed.
//! the size becomes n. New elements are value initialized.
//!
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//! <b>Throws</b>: If memory allocation throws, or T's default constructor throws.
//!
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
void resize(size_type n)
{
typedef default_construct_iterator<value_type, difference_type> default_iterator;
typedef value_init_construct_iterator<value_type, difference_type> value_init_iterator;
STABLE_VECTOR_CHECK_INVARIANT;
if(n > this->size())
this->insert(this->cend(), default_iterator(n - this->size()), default_iterator());
this->insert(this->cend(), value_init_iterator(n - this->size()), value_init_iterator());
else if(n < this->size())
this->erase(this->cbegin() + n, this->cend());
}
//! <b>Effects</b>: Inserts or erases elements at the end such that
//! the size becomes n. New elements are default initialized.
//!
//! <b>Throws</b>: If memory allocation throws, or T's default constructor throws.
//!
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
//!
//! <b>Note</b>: Non-standard extension
void resize(size_type n, default_init_t)
{
typedef default_init_construct_iterator<value_type, difference_type> default_init_iterator;
STABLE_VECTOR_CHECK_INVARIANT;
if(n > this->size())
this->insert(this->cend(), default_init_iterator(n - this->size()), default_init_iterator());
else if(n < this->size())
this->erase(this->cbegin() + n, this->cend());
}
+38 -3
View File
@@ -10,7 +10,7 @@
#ifndef BOOST_CONTAINER_STATIC_VECTOR_HPP
#define BOOST_CONTAINER_STATIC_VECTOR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -138,7 +138,7 @@ public:
//! @pre <tt>count <= capacity()</tt>
//!
//! @brief Constructs a static_vector containing count default constructed Values.
//! @brief Constructs a static_vector containing count value initialized values.
//!
//! @param count The number of values which will be contained in the container.
//!
@@ -151,6 +151,24 @@ public:
: base_t(count)
{}
//! @pre <tt>count <= capacity()</tt>
//!
//! @brief Constructs a static_vector containing count value initialized values.
//!
//! @param count The number of values which will be contained in the container.
//!
//! @par Throws
//! If Value's default constructor throws.
//!
//! @par Complexity
//! Linear O(N).
//!
//! @par Note
//! Non-standard extension
static_vector(size_type count, default_init_t)
: base_t(count, default_init_t())
{}
//! @pre <tt>count <= capacity()</tt>
//!
//! @brief Constructs a static_vector containing count copies of value.
@@ -358,7 +376,7 @@ public:
//! @pre <tt>count <= capacity()</tt>
//!
//! @brief Inserts or erases elements at the end such that
//! the size becomes count. New elements are default constructed.
//! the size becomes count. New elements are value initialized.
//!
//! @param count The number of elements which will be stored in the container.
//!
@@ -369,6 +387,23 @@ public:
//! Linear O(N).
void resize(size_type count);
//! @pre <tt>count <= capacity()</tt>
//!
//! @brief Inserts or erases elements at the end such that
//! the size becomes count. New elements are default initialized.
//!
//! @param count The number of elements which will be stored in the container.
//!
//! @par Throws
//! If Value's default constructor throws.
//!
//! @par Complexity
//! Linear O(N).
//!
//! @par Note
//! Non-standard extension
void resize(size_type count, default_init_t);
//! @pre <tt>count <= capacity()</tt>
//!
//! @brief Inserts or erases elements at the end such that
+1 -1
View File
@@ -937,7 +937,7 @@ class basic_string
}
//! <b>Effects</b>: Inserts or erases elements at the end such that
//! the size becomes n. New elements are default constructed.
//! the size becomes n. New elements are value initialized.
//!
//! <b>Throws</b>: If memory allocation throws
//!
+1 -1
View File
@@ -14,7 +14,7 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
+64 -13
View File
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_CONTAINER_VECTOR_HPP
#define BOOST_CONTAINER_CONTAINER_VECTOR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@@ -293,18 +293,26 @@ struct vector_alloc_holder
template<class AllocConvertible>
explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a, size_type initial_size)
: Allocator(boost::forward<AllocConvertible>(a))
, m_start()
, m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this
, m_capacity()
{
m_start = this->allocation_command(allocate_new, initial_size, initial_size, m_capacity, m_start).first;
if(initial_size){
m_start = this->allocation_command(allocate_new, initial_size, initial_size, m_capacity, m_start).first;
}
}
//Constructor, does not throw
explicit vector_alloc_holder(size_type initial_size)
: Allocator()
, m_start()
, m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this
, m_capacity()
{
m_start = this->allocation_command
(allocate_new, initial_size, initial_size, m_capacity, m_start).first;
if(initial_size){
m_start = this->allocation_command
(allocate_new, initial_size, initial_size, m_capacity, m_start).first;
}
}
vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_CONTAINER_NOEXCEPT
@@ -319,8 +327,10 @@ struct vector_alloc_holder
void first_allocation(size_type cap)
{
m_start = this->allocation_command
(allocate_new, cap, cap, m_capacity, m_start).first;
if(cap){
m_start = this->allocation_command
(allocate_new, cap, cap, m_capacity, m_start).first;
}
}
void first_allocation_same_allocator_type(size_type cap)
@@ -417,16 +427,18 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
template<class AllocConvertible>
explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a, size_type initial_size)
: Allocator(boost::forward<AllocConvertible>(a))
, m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this
, m_size(initial_size) //Size is initialized here...
{
//... and capacity here, so vector, must call uninitialized_xxx in the derived constructor
this->first_allocation(initial_size);
}
//Constructor, does not throw
explicit vector_alloc_holder(size_type initial_size)
: Allocator()
, m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this
, m_size(initial_size) //Size is initialized here...
{
//... and capacity here, so vector, must call uninitialized_xxx in the derived constructor
this->first_allocation(initial_size);
}
@@ -611,7 +623,7 @@ class vector
{}
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
//! and inserts n default contructed values.
//! and inserts n value initialized values.
//!
//! <b>Throws</b>: If allocator_type's default constructor or allocation
//! throws or T's default constructor throws.
@@ -620,7 +632,24 @@ class vector
explicit vector(size_type n)
: m_holder(n)
{
boost::container::uninitialized_default_alloc_n(this->m_holder.alloc(), n, container_detail::to_raw_pointer(this->m_holder.start()));
boost::container::uninitialized_value_init_alloc_n
(this->m_holder.alloc(), n, container_detail::to_raw_pointer(this->m_holder.start()));
}
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
//! and inserts n default initialized values.
//!
//! <b>Throws</b>: If allocator_type's default constructor or allocation
//! throws or T's default constructor throws.
//!
//! <b>Complexity</b>: Linear to n.
//!
//! <b>Note</b>: Non-standard extension
explicit vector(size_type n, default_init_t)
: m_holder(n)
{
boost::container::uninitialized_default_init_alloc_n
(this->m_holder.alloc(), n, container_detail::to_raw_pointer(this->m_holder.start()));
}
//! <b>Effects</b>: Constructs a vector
@@ -1030,9 +1059,9 @@ class vector
{ return allocator_traits_type::max_size(this->m_holder.alloc()); }
//! <b>Effects</b>: Inserts or erases elements at the end such that
//! the size becomes n. New elements are default constructed.
//! the size becomes n. New elements are value initialized.
//!
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
//!
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
void resize(size_type new_size)
@@ -1044,7 +1073,29 @@ class vector
}
else{
const size_type n = new_size - this->size();
container_detail::insert_default_constructed_n_proxy<Allocator, T*> proxy(this->m_holder.alloc());
container_detail::insert_value_initialized_n_proxy<Allocator, T*> proxy(this->m_holder.alloc());
this->priv_forward_range_insert_at_end(n, proxy, alloc_version());
}
}
//! <b>Effects</b>: Inserts or erases elements at the end such that
//! the size becomes n. New elements are value initialized.
//!
//! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
//!
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
//!
//! <b>Note</b>: Non-standard extension
void resize(size_type new_size, default_init_t)
{
const size_type sz = this->size();
if (new_size < sz){
//Destroy last elements
this->priv_destroy_last_n(sz - new_size);
}
else{
const size_type n = new_size - this->size();
container_detail::insert_default_initialized_n_proxy<Allocator, T*> proxy(this->m_holder.alloc());
this->priv_forward_range_insert_at_end(n, proxy, alloc_version());
}
}